├── .gitignore ├── .npmignore ├── README.md ├── index.js ├── lib ├── attr.js ├── events.js ├── html.js ├── select.js ├── text.js └── value.js ├── package.json └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | test 2 | test.js 3 | example 4 | examples 5 | global.js 6 | dist 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## DomQuery 2 | 3 | jQuery-like handy DOM manipulation library composed from small modules. 4 | 5 | Example: 6 | 7 | ```js 8 | var dom = require('domquery') 9 | 10 | dom('ul.songs:last-child') 11 | .add('
  • Play: {title}
  • ', { id: 123, title: "foo" }) 12 | .show() 13 | ``` 14 | 15 | ## Install 16 | 17 | ```bash 18 | $ npm install domquery 19 | ``` 20 | 21 | ## Usage 22 | 23 | Recommended to use [browserify](http://github.com/substack/node-browserify) for bundling for client-side. Sorry, it does not work in Node. 24 | 25 | ### Selecting 26 | 27 | ```js 28 | var dom = require('domquery') 29 | 30 | dom('body .foo .bar') 31 | // => [array, of, elements] 32 | 33 | dom('.foo', '.bar', '.qux').select('*') 34 | // [all children of .foo, .bar, .qux] 35 | 36 | dom('.foo', '.bar', '.qux').parent() 37 | // [parent elements of .foo, .bar, .qux] 38 | 39 | dom('.foo', '.bar', '.qux').siblings('button.tweet') 40 | // [all siblings that matches "button.tweet"] 41 | ``` 42 | 43 | Details: [dom-select](https://github.com/npm-dom/dom-select), [siblings](http://github.com/npm-dom/siblings), [closest](https://github.com/component/closest) 44 | 45 | ### Changing Style 46 | 47 | ```js 48 | var dom = require('domquery') 49 | 50 | dom('body .foo .bar') 51 | .style('background-color', 'red') 52 | // OR 53 | .style({ 54 | 'padding': '10px', 55 | 'margin': '10px' 56 | }) 57 | ``` 58 | 59 | Other available Methods: 60 | * show 61 | * hide 62 | 63 | Details: [dom-style](https://github.com/npm-dom/dom-style) 64 | 65 | ### Adding and Removing Elements 66 | 67 | domquery embeds [dom-tree](http://github.com/npm-dom) to provide following methods; 68 | 69 | #### .insert(parent element) 70 | 71 | Insert an element to a parent element. 72 | 73 | ```js 74 | var dom = require('domquery') 75 | 76 | dom('

    {title}

    {content}', { title: 'Hello!', content: 'world' }) 77 | .insert('body') 78 | ``` 79 | 80 | #### .add(child) 81 | 82 | Add a new element to specified parent element. 83 | 84 | ```js 85 | dom('body > ul') 86 | .add('
  • Hello
  • ') 87 | ``` 88 | 89 | Or; 90 | 91 | ```js 92 | var row = dom('
  • {0}: {1}
  • ', 123, 'Hello World') 93 | dom('body > ul').add(row) 94 | ``` 95 | 96 | * `child` can be an element, array, selector or HTML. 97 | 98 | #### .addBefore(child, reference) 99 | 100 | Adds `child` before `reference` 101 | 102 | ```js 103 | dom('ul.songs') 104 | .addBefore('
  • third song
  • ', 'ul.songs li:nth-child(3)') 105 | ``` 106 | 107 | * `child` can be an element, array, selector or HTML. 108 | * `reference` can be an element, array or selector. 109 | 110 | #### .addAfter(child, reference) 111 | 112 | Adds `child` after `reference` 113 | 114 | ```js 115 | dom('ul.songs') 116 | .addAfter('
  • third song
  • ', 'ul.songs li:nth-child(2)') 117 | ``` 118 | 119 | * `child` can be an element, array, selector or HTML. 120 | * `reference` can be an element, array or selector. 121 | 122 | #### .replace(target, replacement) 123 | 124 | Replaces `target` with `replacement` 125 | 126 | ```js 127 | dom('ul.songs') 128 | .replace('li:first-child', document.createElement('textarea')) 129 | ``` 130 | 131 | or: 132 | 133 | ```js 134 | dom('ul.songs') 135 | .replace('li:first-child', '
  • {0}: {name}
  • ', 123, 'new song') 136 | ``` 137 | 138 | #### .remove(element) 139 | 140 | ```js 141 | dom('ul .songs').remove('li:first-child') 142 | ``` 143 | 144 | ### Inline CSS 145 | 146 | Methods: addClass, hasClass, removeClass, toggleClass 147 | 148 | Example: 149 | ```js 150 | var dom = require('domquery') 151 | 152 | dom('body').addClass('foobar') 153 | 154 | dom('body').hasClass('foobar') 155 | // => true 156 | 157 | dom('body').removeClass('foobar') 158 | 159 | dom('body').hasClass('foobar') 160 | // => false 161 | 162 | dom('body').toggleClass('foobar') 163 | 164 | dom('body').hasClass('foobar') 165 | // => true 166 | ``` 167 | 168 | Other Available Methods: 169 | * addClass 170 | * hasClass 171 | * removeClass 172 | * toggleClass 173 | 174 | Details: [dom-classes](https://github.com/npm-dom/dom-classes) 175 | 176 | ### Events 177 | 178 | domquery embeds [dom-event](http://github.com/npm-dom/dom-event), [key-event](http://github.com/npm-dom/key-event) and [delegate-dom](http://github.com/npm-dom/delegate-dom) modules to provide following methods; 179 | 180 | #### .on(event, callback) 181 | 182 | Add a new event 183 | 184 | ```js 185 | var dom = require('domquery') 186 | 187 | dom('body').on('click', function (event) { 188 | console.log('clicked body') 189 | }) 190 | ``` 191 | 192 | Shortcuts: 193 | 194 | ```js 195 | dom('ul li').click(function (event) { 196 | console.log('clicked a "li"') 197 | }) 198 | ``` 199 | 200 | * change 201 | * click 202 | * keydown 203 | * keyup 204 | * keypress 205 | * mousedown 206 | * mouseover 207 | * mouseup 208 | * resize 209 | 210 | ##### .off(event, callback) 211 | 212 | Remove the event listener; 213 | 214 | ```js 215 | dom('body').off('click', fn) 216 | ``` 217 | 218 | #### .on(event, selector, callback) 219 | 220 | [Delegate event](http://github.com/npm-dom/delegate-dom) handler function for `selector`: 221 | 222 | ```js 223 | dom('body ul').on('click', 'li', function (event) { 224 | console.log('clicked a list item!') 225 | }) 226 | ``` 227 | 228 | #### .onKey(event, callback) 229 | 230 | Adds a [keyboard event](http://github.com/npm-dom/key-event): 231 | 232 | ```js 233 | dom('input').onKey('alt a', function (event) { 234 | console.log('user pressed alt + a') 235 | }) 236 | ``` 237 | 238 | 239 | #### .offKey(event, callback) 240 | 241 | Removes a [keyboard event](http://github.com/npm-dom/key-event): 242 | 243 | ```js 244 | dom('input').onKey('alt a', altA) 245 | dom('input').offKey('alt a', altA) 246 | 247 | function altA (event) { 248 | console.log('user pressed alt + a') 249 | } 250 | ``` 251 | 252 | ### Attributes 253 | 254 | ```js 255 | var dom = require('domquery') 256 | 257 | dom('a.my-link').attr('href') 258 | // => http://foobar.com 259 | 260 | dom('a').attr('href', 'http://foobar.com') 261 | ``` 262 | 263 | ### Content 264 | 265 | Reading: 266 | 267 | ```js 268 | dom('.foo').html() // equivalent of `innerHTML` 269 | dom('input.my-input').val() // equivalent of `value` 270 | ``` 271 | 272 | Setting: 273 | 274 | ```js 275 | dom('.foo').html('
    new content
    ') 276 | dom('input.my-input').val('new value') 277 | ``` 278 | 279 | More info about it is at [dom-value](http://github.com/npm-dom/dom-value) 280 | 281 | ![](https://dl.dropboxusercontent.com/s/ofqr0ha1all2nbl/npmel_30.jpg) 282 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var newElement = require("new-element"); 2 | var select = require("./lib/select"); 3 | 4 | module.exports = select; 5 | module.exports.create = create; 6 | 7 | function create (tag) { 8 | if (tag.charAt(0) == '<') { // html 9 | return select(newElement(tag)); 10 | } 11 | 12 | return select(document.createElement(tag)); 13 | } 14 | -------------------------------------------------------------------------------- /lib/attr.js: -------------------------------------------------------------------------------- 1 | module.exports = attr; 2 | 3 | function attr (chain) { 4 | return function attr (element, name, value) { 5 | if (arguments.length == 2) { 6 | return element.getAttribute(name); 7 | } 8 | 9 | element.setAttribute(name, value); 10 | 11 | return chain; 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /lib/events.js: -------------------------------------------------------------------------------- 1 | var events = require("dom-event"); 2 | var delegate = require("component-delegate"); 3 | var keyEvent = require("key-event"); 4 | var trim = require("trim"); 5 | 6 | module.exports = { 7 | change: shortcut('change'), 8 | click: shortcut('click'), 9 | keydown: shortcut('keydown'), 10 | keyup: shortcut('keyup'), 11 | keypress: shortcut('keypress'), 12 | mousedown: shortcut('mousedown'), 13 | mouseover: shortcut('mouseover'), 14 | mouseup: shortcut('mouseup'), 15 | resize: shortcut('resize'), 16 | on: on, 17 | off: off, 18 | onKey: onKey, 19 | offKey: offKey 20 | }; 21 | 22 | function shortcut (type){ 23 | return function(element, callback){ 24 | return on(element, type, callback); 25 | }; 26 | } 27 | 28 | function off (element, event, selector, callback){ 29 | if (arguments.length == 4) { 30 | return delegate.unbind(element, selector, event, callback); 31 | } 32 | 33 | callback = selector; 34 | 35 | events.off(element, event, callback); 36 | } 37 | 38 | function on (element, event, selector, callback){ 39 | if (arguments.length == 3) { 40 | callback = selector; 41 | } 42 | 43 | if (arguments.length == 4) { 44 | return delegate.bind(element, selector, event, callback); 45 | } 46 | 47 | events.on(element, event, callback); 48 | } 49 | 50 | function onKey (element, key, callback) { 51 | keyEvent.on(element, key, callback); 52 | } 53 | 54 | function offKey (element, key, callback) { 55 | keyEvent.off(element, key, callback); 56 | } 57 | -------------------------------------------------------------------------------- /lib/html.js: -------------------------------------------------------------------------------- 1 | var format = require('format-text'); 2 | 3 | module.exports = html; 4 | 5 | function html (chain) { 6 | return function (element, newValue, vars){ 7 | if (arguments.length > 1) { 8 | element.innerHTML = arguments.length > 2 ? format(newValue, vars) : newValue; 9 | return chain; 10 | } 11 | 12 | return element.innerHTML; 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /lib/select.js: -------------------------------------------------------------------------------- 1 | var newChain = require("new-chain"); 2 | var format = require('format-text'); 3 | var classes = require('dom-classes'); 4 | var tree = require('dom-tree'); 5 | var newElement = require('new-element'); 6 | var selectDOM = require('dom-select').all; 7 | var style = require('dom-style'); 8 | var closest = require("discore-closest"); 9 | var siblings = require("siblings"); 10 | 11 | var attr = require('./attr'); 12 | var events = require('./events'); 13 | var html = require('./html'); 14 | var text = require('./text'); 15 | var value = require('./value'); 16 | 17 | module.exports = select; 18 | 19 | function show(e) { 20 | style(e, 'display', '') 21 | } 22 | 23 | function hide(e) { 24 | style(e, 'display', 'none') 25 | } 26 | 27 | function select (query) { 28 | var key, chain, methods, elements; 29 | var task; 30 | 31 | if (typeof query == 'string' && query.charAt(0) == '<') { 32 | // Create new element from `query` 33 | elements = [newElement(query, arguments[1])]; 34 | } else if (typeof query == 'string') { 35 | // Select given CSS query 36 | elements = Array.prototype.slice.call(selectDOM(query, arguments[1])); 37 | } else if (query == document) { 38 | elements = [document.documentElement]; 39 | } else if (arguments.length == 1 && Array.isArray(arguments[0])) { 40 | elements = arguments[0]; 41 | } else { 42 | elements = Array.prototype.slice.call(arguments); 43 | } 44 | 45 | methods = { 46 | addClass: applyEachElement(classes.add, elements), 47 | removeClass: applyEachElement(classes.remove, elements), 48 | toggleClass: applyEachElement(classes.toggle, elements), 49 | show: applyEachElement(show, elements), 50 | hide: applyEachElement(hide, elements), 51 | style: applyEachElement(style, elements) 52 | }; 53 | 54 | for (key in events) { 55 | methods[key] = applyEachElement(events[key], elements); 56 | } 57 | 58 | for (key in tree) { 59 | methods[key] = applyEachElement(tree[key], elements); 60 | } 61 | 62 | chain = newChain.from(elements)(methods); 63 | 64 | chain.attr = applyEachElement(attr(chain), elements); 65 | chain.classes = applyEachElement(classes, elements); 66 | chain.hasClass = applyEachElement(classes.has, elements), 67 | chain.html = applyEachElement(html(chain), elements); 68 | chain.text = applyEachElement(text(chain), elements); 69 | chain.val = applyEachElement(value(chain), elements); 70 | chain.value = applyEachElement(value(chain), elements); 71 | chain.parent = selectEachElement(parent, elements); 72 | chain.select = selectEachElement(selectChild, elements); 73 | chain.siblings = selectEachElement(siblings, elements); 74 | 75 | return chain; 76 | } 77 | 78 | function parent (element, selector) { 79 | if (!selector) return element.parentNode; 80 | return closest(element, selector); 81 | }; 82 | 83 | function selectChild (element, query) { 84 | return select(query, element); 85 | } 86 | 87 | function applyEachElement (fn, elements) { 88 | if (!fn) throw new Error('Undefined function.'); 89 | 90 | return function () { 91 | var i, len, ret, params, ret; 92 | 93 | len = elements.length; 94 | i = -1; 95 | params = [undefined].concat(Array.prototype.slice.call(arguments)); 96 | 97 | while (++i < len) { 98 | params[0] = elements[i]; 99 | ret = fn.apply(undefined, params); 100 | } 101 | 102 | return ret; 103 | }; 104 | } 105 | 106 | function selectEachElement (fn, els) { 107 | return function () { 108 | var result = []; 109 | var params = [undefined].concat(Array.prototype.slice.call(arguments)); 110 | 111 | var len = els.length; 112 | var i = -1; 113 | var ret; 114 | var t; 115 | var tlen; 116 | 117 | while (++i < len) { 118 | params[0] = els[i]; 119 | ret = fn.apply(undefined, params); 120 | 121 | if (Array.isArray(ret)) { 122 | tlen = ret.length; 123 | t = -1; 124 | 125 | while (++t < tlen) { 126 | if (result.indexOf(ret[t]) != -1) continue; 127 | result.push(ret[t]); 128 | } 129 | 130 | continue; 131 | } 132 | 133 | if (!ret) continue; 134 | if (result.indexOf(ret) != -1) continue; 135 | 136 | result.push(ret); 137 | } 138 | 139 | 140 | return select(result); 141 | }; 142 | } 143 | -------------------------------------------------------------------------------- /lib/text.js: -------------------------------------------------------------------------------- 1 | var format = require('format-text'); 2 | 3 | module.exports = text; 4 | 5 | function text (chain){ 6 | return function (element, newValue, vars) { 7 | if (arguments.length > 1) { 8 | element.textContent = arguments.length > 2 ? format(newValue, vars) : newValue; 9 | return chain; 10 | } 11 | 12 | return element.textContent; 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /lib/value.js: -------------------------------------------------------------------------------- 1 | var value = require("dom-value"); 2 | 3 | module.exports = withChain; 4 | 5 | function withChain (chain) { 6 | return function (el, update) { 7 | if (arguments.length == 2) { 8 | value(el, update); 9 | return chain; 10 | } 11 | 12 | return value(el); 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "domquery", 3 | "version": "3.0.0", 4 | "description": "jQuery-like Handy DOM Manipulation Library", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "browserify -d test.js | tape-run" 8 | }, 9 | "repository": { 10 | "url": "git@github.com:npm-dom/domquery.git", 11 | "type": "git" 12 | }, 13 | "keywords": [ 14 | "dom", 15 | "browser", 16 | "npm-dom", 17 | "jquery" 18 | ], 19 | "author": "Azer Koçulu ", 20 | "license": "BSD", 21 | "dependencies": { 22 | "component-delegate": "0.2.2", 23 | "discore-closest": "^0.1.3", 24 | "dom-classes": "~0.0.0", 25 | "dom-event": "~1.0.0", 26 | "dom-select": "~1.1.1", 27 | "dom-style": "~1.0.0", 28 | "dom-tree": "~1.0.0", 29 | "dom-value": "~1.0.1", 30 | "format-text": "0.0.x", 31 | "key-event": "~1.0.0", 32 | "new-chain": "azer/new-chain", 33 | "new-element": "~1.0.0", 34 | "siblings": "^1.0.1", 35 | "trim": "0.0.1" 36 | }, 37 | "devDependencies": { 38 | "browserify": "13.0.0", 39 | "random-color": "azer/random-color", 40 | "tape": "4.5.1", 41 | "tape-run": "2.1.3" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | var test = require('tape'); 2 | var dom = require("./"); 3 | var randomColor = require('random-color'); 4 | 5 | var HTML = (function(){/* 6 | 7 | 12 | */}).toString().slice(17, -4); 13 | 14 | reset(); 15 | 16 | test('returns an attr value', function (t) { 17 | t.plan(1); 18 | t.equal(dom('.fruits').attr('data-foo'), 'bar'); 19 | }); 20 | 21 | test('sets an attr value', function (t) { 22 | t.plan(3); 23 | 24 | dom('.fruit').attr('data-foo', 'bar').style('background-color', randomColor()); 25 | 26 | fruits().forEach(function(el){ 27 | t.equal(el.getAttribute('data-foo'), 'bar'); 28 | }); 29 | }); 30 | 31 | test('selects elements by css queries', function (t) { 32 | t.plan(2); 33 | 34 | var els = dom('.fruits .fruit'); 35 | var clone = document.querySelectorAll('.fruits .fruit'); 36 | 37 | t.equal(els[0], clone[0]); 38 | t.equal(els[1], clone[1]); 39 | }); 40 | 41 | test('hides els', function (t) { 42 | t.plan(3); 43 | 44 | dom('.fruit').hide(); 45 | 46 | fruits().forEach(function(el){ 47 | t.equal(el.style.display, 'none'); 48 | }); 49 | }); 50 | 51 | test('shows els', function (t) { 52 | t.plan(3); 53 | 54 | fruits().forEach(function(el){ 55 | el.style.display = 'none'; 56 | }); 57 | 58 | dom('.fruit').show(); 59 | 60 | fruits().forEach(function(el){ 61 | t.equal(el.style.display, ''); 62 | }); 63 | 64 | }); 65 | 66 | test('adds a class', function (t) { 67 | t.plan(3); 68 | 69 | dom('.fruit').addClass('foo'); 70 | 71 | fruits().forEach(function(el){ 72 | t.ok(el.classList.contains('foo')); 73 | }); 74 | }); 75 | 76 | test('removes a class', function (t) { 77 | t.plan(6); 78 | dom('.fruit').addClass('foo').addClass('bar').removeClass('foo'); 79 | 80 | fruits().forEach(function(el){ 81 | t.ok(el.classList.contains('bar')); 82 | t.notOk(el.classList.contains('foo')); 83 | }); 84 | }); 85 | 86 | test('checks an element if it has a class', function (t) { 87 | t.plan(9); 88 | 89 | dom('.fruit').removeClass('foo').removeClass('bar'); 90 | 91 | fruits().forEach(function(el){ 92 | t.notOk(el.classList.contains('foo')); 93 | t.notOk(el.classList.contains('bar')); 94 | t.ok(el.classList.contains('fruit')); 95 | }); 96 | }); 97 | 98 | test('toggles a class', function (t) { 99 | t.plan(6); 100 | dom('.fruit').addClass('foo').removeClass('bar').toggleClass('foo').toggleClass('bar'); 101 | 102 | fruits().forEach(function(el){ 103 | t.notOk(el.classList.contains('foo')); 104 | t.ok(el.classList.contains('bar')); 105 | }); 106 | 107 | }); 108 | 109 | test('styles an element', function (t) { 110 | t.plan(9); 111 | 112 | dom('.fruit').style({ color: 'red', 'background-color': 'yellow' }).style('border', '1px solid green'); 113 | 114 | fruits().forEach(function(el){ 115 | t.equal(el.style.color, 'red'); 116 | t.equal(el.style.backgroundColor, 'yellow'); 117 | t.equal(el.style.border, '1px solid green'); 118 | }); 119 | }); 120 | 121 | test('adds an event', function (t) { 122 | dom('.fruit').click(function(event){ 123 | dom(event.target).style({ 'background-color': randomColor(), 'color': randomColor() }); 124 | }); 125 | 126 | dom('textarea').keydown(function(){ 127 | dom('textarea').style('background-color', randomColor()); 128 | }); 129 | 130 | t.end(); 131 | }); 132 | 133 | test('returns the value of an element', function (t) { 134 | t.plan(1); 135 | dom('textarea')[0].value = 'hello'; 136 | t.equal(dom('textarea').val(), 'hello'); 137 | }); 138 | 139 | test('sets the value of an element', function (t) { 140 | t.plan(1); 141 | dom('textarea').val('foobar').style('background-color', randomColor()); 142 | t.equal(dom('textarea').val(), 'foobar'); 143 | }); 144 | 145 | test('returns the text content of an element', function (t) { 146 | t.plan(1); 147 | dom('.fruit:first-child')[0].innerText = 'grape'; 148 | t.equal(dom('.fruit:first-child').text(), 'grape'); 149 | }); 150 | 151 | test('sets the text content of an element', function (t) { 152 | t.plan(2); 153 | dom('.fruit:first-child').text('a delicious {fruit}', { fruit: 'cherry' }).style('background-color', randomColor()); 154 | t.equal(dom('.fruit:first-child').text(), 'a delicious cherry'); 155 | 156 | dom('.fruit:first-child').text('tasty cherries').style('background-color', randomColor()); 157 | t.equal(dom('.fruit:first-child').text(), 'tasty cherries'); 158 | }); 159 | 160 | test('returns the html content of an element', function (t) { 161 | t.plan(1); 162 | dom('.fruit:first-child')[0].innerHTML = 'kiwi'; 163 | t.equal(dom('.fruit:first-child').html(), 'kiwi'); 164 | }); 165 | 166 | test('sets the html content of an element', function (t) { 167 | t.plan(2); 168 | dom('.fruit:first-child').html('a delicious {fruit}', { fruit: 'melon' }).style('background-color', randomColor()); 169 | t.equal(dom('.fruit:first-child').html(), 'a delicious melon'); 170 | dom('.fruit:first-child').html('a tasty melon').style('background-color', randomColor()); 171 | t.equal(dom('.fruit:first-child').html(), 'a tasty melon'); 172 | }); 173 | 174 | test('creates a new element', function (t) { 175 | t.plan(2); 176 | var parent = dom.create('div').addClass('parent'); 177 | var child1 = dom.create('

    child 1

    '); 178 | var child2 = dom.create('span').html('child 2'); 179 | var child3 = dom.create(''); 180 | var child4 = dom.create('strong').html('child 4'); 181 | 182 | parent.add(child1).add(child2).replace(child1, child3).add(child4).remove('span'); 183 | 184 | t.equal(parent.html(), 'child 4'); 185 | t.ok(parent.hasClass('parent')); 186 | }); 187 | 188 | test('adds a child element', function (t) { 189 | t.plan(1); 190 | var child = dom(document.createElement('li')).addClass('fruit').addClass('new').html('yo'); 191 | dom('.fruits').add(child); 192 | t.equal(dom('.fruit:last-child')[0], child[0]); 193 | }); 194 | 195 | test('adds HTML', function (t) { 196 | t.plan(6); 197 | dom('.fruits').add('
  • a fresh {fruit}
  • ', { fruit: 'watermelon' }); 198 | t.ok(dom('.fruit:last-child').hasClass('new')); 199 | t.ok(dom('.fruit:last-child').hasClass('fruit')); 200 | t.equal(dom('.fruit:last-child').text(), 'a fresh watermelon'); 201 | 202 | dom('.fruits').add('
  • a very fresh apple
  • '); 203 | t.ok(dom('.fruit:last-child').hasClass('new')); 204 | t.ok(dom('.fruit:last-child').hasClass('fruit')); 205 | t.equal(dom('.fruit:last-child').text(), 'a very fresh apple'); 206 | }); 207 | 208 | test('creates and inserts HTML', function (t) { 209 | t.plan(4); 210 | dom('
  • very fresh {fruit}
  • ', { fruit: 'peach' }).insert('.fruits'); 211 | t.ok(dom('.fruit:last-child').hasClass('new')); 212 | t.ok(dom('.fruit:last-child').hasClass('very-new')); 213 | t.ok(dom('.fruit:last-child').hasClass('fruit')); 214 | t.equal(dom('.fruit:last-child').text(), 'very fresh peach'); 215 | }); 216 | 217 | test('removes itself', function (t) { 218 | t.plan(2); 219 | var last = dom('.fruit:last-child').text(); 220 | dom('
  • to be removed
  • ').insert('.fruits'); 221 | t.equal(dom('.fruit:last-child').text(), 'to be removed'); 222 | dom('.fruit:last-child').remove(); 223 | t.equal(dom('.fruit:last-child').text(), last); 224 | }); 225 | 226 | test('selects the children', function (t) { 227 | t.plan(1); 228 | var newf = dom('.fruits').select('.new'); 229 | var clone = dom('.fruits .new'); 230 | t.equal(newf.length, clone.length); 231 | }); 232 | 233 | test('selects children of multiple elements', function (t) { 234 | var all = dom('body > *'); 235 | var children = all.select('*'); 236 | t.plan(1); 237 | t.equal(children.length, dom('ul li').length); 238 | }); 239 | 240 | test('initializes a chain with given elements', function (t) { 241 | t.plan(7); 242 | 243 | dom.apply(undefined, Array.prototype.slice.call(document.querySelectorAll('.fruit'))).removeClass('corge').addClass('corge'); 244 | 245 | fruits().forEach(function(el){ 246 | t.ok(el.classList.contains('corge')); 247 | }); 248 | 249 | }); 250 | 251 | test('event delegation', function (t) { 252 | t.plan(1); 253 | 254 | dom('.fruits').on('click', 'li', function () { 255 | t.ok(true); 256 | }); 257 | 258 | dom('.fruits').add('
  • yo
  • '); 259 | dom('#delegation-test-el')[0].click(); 260 | }); 261 | 262 | test('finding parents', function (t) { 263 | t.plan(4); 264 | t.equal(dom('li').parent().length, 1); 265 | t.equal(dom('li').parent()[0], dom('ul.fruits')[0]); 266 | t.equal(dom('li').parent('body')[0], dom('body')[0]); 267 | t.equal(dom('li').parent('#foo').length, 0); 268 | }); 269 | 270 | test('selecting siblings', function (t) { 271 | t.plan(3); 272 | 273 | dom('
  • cherry
  • ').insert('ul.fruits'); 274 | dom('
  • watermelon
  • ').insert('ul.fruits'); 275 | dom('
  • grapes!
  • ').insert('ul.fruits'); 276 | dom('
  • carrot
  • ').insert('ul.fruits'); 277 | 278 | var assert = ['cherry', 'watermelon', 'grapes!']; 279 | dom('.also-delicious').siblings('.delicious.fruit').forEach(function (el, ind) { 280 | t.equal(assert[ind], el.textContent); 281 | }); 282 | }); 283 | 284 | function fruits () { 285 | return Array.prototype.slice.call(document.querySelectorAll('.fruits .fruit')); 286 | } 287 | 288 | function reset (done){ 289 | document.body.innerHTML = HTML; 290 | 291 | dom('textarea').onKey('alt space', function () { 292 | dom('textarea').val(''); 293 | }); 294 | }; 295 | --------------------------------------------------------------------------------