Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

reorganise

  • Loading branch information...
commit 0d452ea90957108ee67fe33ee11fded61e885608 1 parent 0cd8926
@rvagg authored
View
30 .jshintrc
@@ -0,0 +1,30 @@
+{
+ "predef": [ "assert", "refute", "define" ]
+ , "boss": true
+ , "bitwise": false
+ , "shadow": true
+ , "trailing": true
+ , "immed": true
+ , "latedef": true
+ , "forin": false
+ , "curly": false
+ , "debug": true
+ , "devel": false
+ , "evil": true
+ , "regexp": false
+ , "undef": true
+ , "sub": true
+ , "white": false
+ , "trailing": true
+ , "asi": true
+ , "laxbreak": true
+ , "eqnull": true
+ , "browser": true
+ , "node": true
+ , "laxcomma": true
+ , "proto": true
+ , "expr": true
+ , "es5": true
+ , "strict": false
+ , "onevar": true
+}
View
7 Makefile
@@ -1,7 +1,12 @@
.PHONY: build test server
build:
- @node build.js
+ @echo -n "Minified size before: "
+ @du -b ./traversty.min.js
+ @jshint ./traversty.js
+ @uglifyjs ./traversty.js > ./traversty.min.js
+ @echo -n "Minified size after: "
+ @du -b ./traversty.min.js
test:
buster test -R
View
53 build.js
@@ -1,53 +0,0 @@
-var jshintOptions = {
- 'predef': [ 'define' ]
- , 'boss': true
- , 'bitwise': true
- , 'shadow': true
- , 'trailing': true
- , 'immed': true
- , 'latedef': true
- , 'forin': true
- , 'curly': false
- , 'debug': true
- , 'devel': false
- , 'evil': false
- , 'regexp': false
- , 'undef': true
- , 'sub': true
- , 'white': false
- , 'indent': 2
- , 'asi': true
- , 'laxbreak': true
- , 'eqeqeq': true
- , 'eqnull': true
- , 'browser': true
- , 'node': true
- , 'laxcomma': true
- , 'strict': false
-}
-require('smoosh')
- .config({
- 'JAVASCRIPT': {
- 'DIST_DIR': './'
- , 'traversty': [
- './src/copyright.js'
- , './src/traversty.js'
- ]
- }
- , 'JSHINT_OPTS': jshintOptions
- }).run().build().analyze()
- .config({
- 'JAVASCRIPT': {
- 'DIST_DIR': './'
- , 'ender': [ './src/ender.js' ]
- , 'tests': [
- './buster.js'
- , './test/common.js'
- , './test/core-test.js'
- , './test/engines-test.js'
- , './test/noconflict.js'
- , './test/setup.js'
- ]
- }
- , 'JSHINT_OPTS': jshintOptions
- }).run()
View
3  src/ender.js → ender_bridge.js
@@ -1,4 +1,5 @@
/*global ender:true*/
+
(function ($) {
var t = require('traversty')
, integrated = false
@@ -35,4 +36,4 @@
}
, true
)
-}(ender))
+}(ender))
View
4 package.json
@@ -6,7 +6,7 @@
, "author": "Rod Vagg <rod@vagg.org> @rvagg"
, "keywords": ["ender", "dom", "nodes"]
, "main": "./traversty.js"
- , "ender": "./src/ender.js"
+ , "ender": "./ender_bridge.js"
, "repository": {
"type": "git"
, "url": "https://github.com/rvagg/traversty.git"
@@ -14,4 +14,4 @@
, "devDependencies": {
"buster": "*"
}
-}
+}
View
5 src/copyright.js
@@ -1,5 +0,0 @@
-/**************************************************************
- * Traversty: DOM Traversal Utility (c) Rod Vagg (@rvagg) 2011
- * https://github.com/rvagg/traversty
- * License: MIT
- */
View
226 src/traversty.js
@@ -1,226 +0,0 @@
-!(function (name, definition) {
- if (typeof module !== 'undefined') module.exports = definition()
- else if (typeof define === 'function' && define.amd) define(name, definition)
- else this[name] = definition()
-}('traversty', function () {
-
- var context = this
- , old = context.traversty
- , doc = window.document
- , html = doc.documentElement
- , toString = Object.prototype.toString
- , slice = Array.prototype.slice
- // feature test to find native matchesSelector()
- , matchesSelector = (function (el, pfx, name, i, ms) {
- while (i < pfx.length)
- if (el[ms = pfx[i++] + name]) return ms
- }(html, [ 'msM', 'webkitM', 'mozM', 'oM', 'm' ], 'atchesSelector', 0))
-
- , isNumber = function (o) {
- return toString.call(o) === '[object Number]'
- }
-
- , isString = function (o) {
- return toString.call(o) === '[object String]'
- }
-
- , isFunction = function (o) {
- return toString.call(o) === '[object Function]'
- }
-
- , isUndefined = function (o) {
- return o === void 0
- }
-
- , isElement = function (o) {
- return o && o.nodeType === 1
- }
-
- // figure out which argument, if any, is our 'index'
- , getIndex = function (selector, index) {
- return isUndefined(selector) && !isNumber(index) ? 0 :
- isNumber(selector) ? selector : isNumber(index) ? index : null
- }
-
- // figure out which argument, if any, is our 'selector'
- , getSelector = function (selector) {
- return isString(selector) ? selector : '*'
- }
-
- , nativeSelectorFind = function (selector, el) {
- return slice.call(el.querySelectorAll(selector), 0)
- }
-
- , nativeSelectorMatches = function (selector, el) {
- return selector === '*' || el[matchesSelector](selector)
- }
-
- , selectorFind = nativeSelectorFind
-
- , selectorMatches = nativeSelectorMatches
-
- // used in the case where our selector engine does out-of-order element returns for
- // grouped selectors, e.g. '.class, tag', we need our elements in document-order
- // so we do it ourselves if need be
- , createUnorderedEngineSelectorFind = function(engineSelect, selectorMatches) {
- return function (selector, el) {
- if (/,/.test(selector)) {
- var ret = [], i = -1, els = el.getElementsByTagName('*')
- while (++i < els.length) {
- if (isElement(els[i]) && selectorMatches(selector, els[i])) ret.push(els[i])
- }
- return ret
- }
- return engineSelect(selector, el)
- }
- }
-
- , unique = function (ar) {
- var a = [], i = -1, j, has
- while (++i < ar.length) {
- j = -1
- has = false
- while (++j < a.length) {
- if (a[j] === ar[i]) {
- has = true
- break
- }
- }
- if (!has) a.push(ar[i])
- }
- return a
- }
-
- , collect = function (els, fn) {
- var ret = [], res, i = 0, j, l = els.length, l2
- while (i < l) {
- j = 0
- l2 = (res = fn(els[i++])).length
- while (j < l2) ret.push(res[j++])
- }
- return ret
- }
-
- , move = function (els, method, selector, index) {
- index = getIndex(selector, index)
- selector = getSelector(selector)
- return collect(els
- , function (el) {
- var i = index || 0, ret = []
- while (el && (index === null || i >= 0)) {
- el = el[method]
- // ignore non-elements, only consider selector-matching elements
- // handle both the index and no-index (selector-only) cases
- if (isElement(el) &&
- selectorMatches(selector, el) &&
- (index === null || i-- === 0)) {
- // this concat vs push is to make sure we add elements to the result array
- // in reverse order when doing a previous(selector) and up(selector)
- index === null && method !== 'nextSibling' ? ret = [el].concat(ret) : ret.push(el)
- }
- }
- return ret
- }
- )
- }
-
- , traversty = (function () {
- function T(els) {
- this.length = 0
- if (els) {
- els = unique(!els.nodeType && !isUndefined(els.length) ? els : [ els ])
- var i = this.length = els.length
- while (i--) this[i] = els[i]
- }
- }
-
- T.prototype = {
- down: function (selector, index) {
- index = getIndex(selector, index)
- selector = getSelector(selector)
- return traversty(collect(this
- , function (el) {
- var f = selectorFind(selector, el)
- return index === null ? f : ([ f[index] ] || [])
- }
- ))
- }
-
- , up: function (selector, index) {
- return traversty(move(this, 'parentNode', selector, index))
- }
-
- , previous: function (selector, index) {
- return traversty(move(this, 'previousSibling', selector, index))
- }
-
- , next: function (selector, index) {
- return traversty(move(this, 'nextSibling', selector, index))
- }
- }
-
- function t(els) {
- return new T(isString(els) ? selectorFind(els, doc) : els)
- }
-
- t.setSelectorEngine = function (s) {
- // feature testing the selector engine like a boss
- var ss, r, a, _selectorMatches, _selectorFind
- , e = doc.createElement('p')
- , select = s.select || s.sel || s
- e.innerHTML = '<a/><i/><b/>'
- a = e.firstChild
- try {
- // check to see how we do a matchesSelector
- _selectorMatches =
- isFunction(s.matching) ? function (selector, el) { return s.matching([el], selector).length > 0 } :
- isFunction(s.is) ? function (selector, el) { return s.is(el, selector) } :
- isFunction(s.matchesSelector) ? function (selector, el) { return s.matchesSelector(el, selector) } :
- isFunction(s.match) ? function (selector, el) { return s.match(el, selector) } : null
-
- if (!_selectorMatches) {
- // perhaps it's an selector(x).is(y) type selector?
- ss = s('a', e)
- _selectorMatches =
- isFunction(ss.matching) ? function (selector, el) { return s(el).matching(selector).length > 0 } :
- isFunction(ss.is) ? function (selector, el) { return s(el).is(selector) } :
- isFunction(ss.matchesSelector) ? function (selector, el) { return s(el).matchesSelector(selector) } :
- isFunction(ss.match) ? function (selector, el) { return s(el).match(selector) } : null
- }
-
- if (!_selectorMatches)
- throw 'Traversty: couldn\'t find selector engine\'s `matchesSelector`'
-
- // verify that we have a working `matchesSelector`
- if (_selectorMatches('x,y', e) || !_selectorMatches('a,p', e))
- throw 'Traversty: couldn\'t make selector engine\'s `matchesSelector` work'
-
- // basic select
- if ((r = select('b,a', e)).length !== 2) throw 'Traversty: don\'t know how to use this selector engine'
- // check to see if the selector engine has given us the results in document-order
- // and if not, work around it
- _selectorFind = r[0] === a ? select : createUnorderedEngineSelectorFind(select, _selectorMatches)
- // have we done enough to get a working `selectorFind`?
- if ((r = _selectorFind('b,a', e)).length !== 2 || r[0] !== a)
- throw 'Traversty: couldn\'t make selector engine work'
-
- selectorMatches = _selectorMatches
- selectorFind = _selectorFind
- } catch (ex) {
- if (isString(ex)) throw ex
- throw 'Traversty: error while figuring out how the selector engine works: ' + (ex.message || ex)
- } finally {
- e = null
- }
- }
-
- t.noConflict = function () {
- context.traversty = old
- return this
- }
-
- return t
- }())
-
- return traversty
-}))
View
372 test/traversal.js
@@ -0,0 +1,372 @@
+/*global Q:true, T:true, assert:true*/
+// note: `T` is `traversty` and `Q` is `qwery` (selector engine), see setup.js
+
+this.traversalTests = {
+ 'Simple no-arg traversal': {
+
+ 'next()': function () {
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li:nth-child(1)')).next()
+ , '#fixtures > ul > li:nth-child(2)'
+ , 'next() on two elements moved to nextSibling on both'
+ )
+ }
+
+ , 'previous()': function () {
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li:nth-child(4)')).previous()
+ , '#fixtures > ul > li:nth-child(3)'
+ , 'previous() on two elements moved to previousSibling on both'
+ )
+ }
+
+ , 'up()': function () {
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li:nth-child(3)')).up()
+ , '#fixtures > ul'
+ , 'up() on two elements moved to parentNode on both'
+ )
+ }
+
+ , 'down()': function () {
+ assert.hasExactElements(
+ T(Q('#fixtures > ul')).down()
+ , '#fixtures > ul > li:nth-child(1)'
+ , 'down() on two elements moved to the first childNode on both'
+ )
+ }
+
+ }
+
+ , 'Index argument traversal': {
+
+ 'next(index)': function () {
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li:nth-child(1)')).next(0)
+ , '#fixtures > ul > li:nth-child(2)'
+ , 'next(0) on two elements moved to 1st nextSibling element on both'
+ )
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li:nth-child(1)')).next(1)
+ , '#fixtures > ul > li:nth-child(3)'
+ , 'next(1) on two elements moved to 2nd nextSibling element on both'
+ )
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li:nth-child(1)')).next(3)
+ , '#fixtures > ul > li:nth-child(5)'
+ , 'next(3) on two elements moved to 3rd nextSibling element on both'
+ )
+ }
+
+ , 'previous(index)': function () {
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li:nth-child(5)')).previous(0)
+ , '#fixtures > ul > li:nth-child(4)'
+ , 'previous(0) on two elements moved to 1st previousSibling element on both'
+ )
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li:nth-child(5)')).previous(1)
+ , '#fixtures > ul > li:nth-child(3)'
+ , 'previous(1) on two elements moved to 2nd previousSibling element on both'
+ )
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li:nth-child(5)')).previous(3)
+ , '#fixtures > ul > li:nth-child(1)'
+ , 'previous(3) on two elements moved to 3rd previousSibling element on both'
+ )
+ }
+
+ , 'up(index)': function () {
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li > ul > li > span')).up(0)
+ , '#fixtures > ul > li > ul > li:nth-child(4)'
+ , 'up(0) on two elements moved to 1st parentNode on both'
+ )
+
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li > ul > li > span')).up(3)
+ , '#fixtures > ul'
+ , 'up(3) on two elements moved to 3rd parentNode on both'
+ )
+
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li > ul > li > span')).up(4)
+ , '#fixtures'
+ , 'up(4) on two elements moved to *single* common ancestor node for both'
+ )
+ }
+
+ , 'down(index)': function () {
+ assert.hasExactElements(
+ T(Q('#fixtures > ul')).down(0)
+ , '#fixtures > ul > li:nth-child(1)'
+ , 'down(0) on two elements moved to first childNode on both'
+ )
+
+ assert.hasExactElements(
+ T(Q('#fixtures > ul')).down(1)
+ , '#fixtures > ul > li:nth-child(2)'
+ , 'down(1) on two elements moved to second childNode on both'
+ )
+
+ assert.hasExactElements(
+ T(Q('#fixtures > ul')).down(9)
+ , '#fixtures > ul > li > ul > li > span'
+ , 'down(9) on two elements moved down to 10th descendent in document order'
+ )
+ }
+ }
+
+ , 'Selector and index argument traversal': {
+
+ 'next(selector, index)': function () {
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li:nth-child(1)')).next('li', 1)
+ , '#fixtures > ul > li:nth-child(3)'
+ , 'next("li", 1) moves to 2nd nextSibling, both elements'
+ )
+
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li:nth-child(1)')).next('.c', 1)
+ , '#fixtures > ul > li:nth-child(4)'
+ , 'next(".c", 1) moves to the second nextSibling with class "c", both elements'
+ )
+
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li:nth-child(1)')).next('li.c', 2)
+ , '#fixtures > ul > li:nth-child(5)'
+ , 'next("li.c", 2) moves to the 3rd nextSibling li with class "c", both elements'
+ )
+
+ assert.hasExactElements(
+ T(Q('#flat *:nth-child(2)')).next('div, p', 2)
+ , '#flat *:nth-child(6)'
+ , 'next("div, p", 2) matches 3rd following <div> or <p>'
+ )
+ }
+
+ , 'next(selector, index) returns unique elements': function () {
+ assert.hasExactElements(
+ T(Q('#flat *:nth-child(-n+2)')).next('div', 1)
+ , '#flat *:nth-child(6)'
+ , 'next("div", 1) on two elements matches single 2nd following <div>'
+ )
+ }
+
+ , 'previous(selector, index)': function () {
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li:nth-child(5)')).previous('li', 1)
+ , '#fixtures > ul > li:nth-child(3)'
+ , 'previous("li", 1) moves to 2nd previousSibling, both elements'
+ )
+
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li:nth-child(5)')).previous('.c', 0)
+ , '#fixtures > ul > li:nth-child(4)'
+ , 'previous(".c", 0) moves to the first previousSibling with class "c", both elements'
+ )
+
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li:nth-child(5)')).previous('li.c', 1)
+ , '#fixtures > ul > li:nth-child(2)'
+ , 'previous("li.c", 2) moves to the 2nd previousSibling li with class "c", both elements'
+ )
+
+ assert.hasExactElements(
+ T(Q('#flat *:nth-child(5)')).previous('div, p', 2)
+ , '#flat *:nth-child(1)'
+ , 'previous("div, p", 2) matches 3rd preceeding <div> or <p>'
+ )
+ }
+
+ , 'previous(selector, index) returns unique elements': function () {
+ assert.hasExactElements(
+ T(Q('#flat *:nth-child(n+5)')).previous('p', 1)
+ , '#flat *:nth-child(1)'
+ , 'previous("p", 1) on two elements matches single 2nd preceeding <p>'
+ )
+ }
+
+ , 'up(selector, index)': function () {
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li > ul > li > span')).up('li', 0)
+ , '#fixtures > ul > li > ul > li:nth-child(4)'
+ , 'up("li", 0) moves to first parentNode of both elements'
+ )
+
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li > ul > li > span')).up('li', 1)
+ , '#fixtures > ul > li:nth-child(4)'
+ , 'up("li", 1) moves to second li parentNode (3rd actual parentNode) of both elements'
+ )
+
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li > ul > li > span')).up('li.c', 1)
+ , '#fixtures > ul > li:nth-child(4)'
+ , 'up("li.c", 0) moves to second li parentNode with class "c" (3rd actual parentNode) of both elements'
+ )
+
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li > ul > li > span')).up('li, ul', 2)
+ , '#fixtures > ul > li:nth-child(4)'
+ , 'up("li, ul", 2) moves to 3rd parentNode, either <li> or <ul> of both elements'
+ )
+ }
+
+ , 'up(selector, index) returns unique elements': function () {
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li > ul > li > span')).up('#fixtures', 0)
+ , '#fixtures'
+ , 'up("#fixtures", 0) moves up to common (single) parent node of both elements'
+ )
+ }
+
+ , 'down(selector, index)': function () {
+ assert.hasExactElements(
+ T(Q('#fixtures > ul')).down('li', 0)
+ , '#fixtures > ul > li:nth-child(1)'
+ , 'down("li", 0) moves to first li element in document-order on both elements'
+ )
+
+ assert.hasExactElements(
+ T(Q('#fixtures > ul')).down('li', 2)
+ , '#fixtures > ul > li:nth-child(3)'
+ , 'down("li", 2) moves to third li element in document-order on both elements'
+ )
+
+ assert.hasExactElements(
+ T(Q('#fixtures > ul')).down('.c', 4)
+ , '#fixtures > ul > li > ul > li > span'
+ , 'down(".c", 4) moves to 4th element with class "c" in document-order on both elements'
+ )
+
+ assert.hasExactElements(
+ T(Q('#fixtures')).down('li', 0)
+ , '#fixtures > ul:nth-child(1) > li:nth-child(1)'
+ , 'down("li", 0) moves to first li element in document-order on first branch only'
+ )
+
+ assert.hasExactElements(
+ T(Q('#fixtures')).down('li', 2)
+ , '#fixtures > ul:nth-child(1) > li:nth-child(3)'
+ , 'down("li", 2) moves to third li element in document-order on first branch only'
+ )
+
+ assert.hasExactElements(
+ T(Q('#fixtures')).down('.c', 4)
+ , '#fixtures > ul:nth-child(1) > li > ul > li > span'
+ , 'down(".c", 4) moves to 4th element with class "c" in document-order on first branch only'
+ )
+
+ assert.hasExactElements(
+ T(Q('#fixtures')).down('ul, .c', 3)
+ , '#fixtures > ul:nth-child(1) > li > ul'
+ , 'down("ul, .c", 3) moves to 4th <ul> element or element with class "c" in document-order on first branch only'
+ )
+ }
+
+ , 'down(selector, index) returns unique elements': function () {
+ assert.hasExactElements(
+ T(Q('#fixtures, #fixtures > ul:nth-child(1)')).down('li', 0)
+ , '#fixtures > ul:nth-child(1) > li:nth-child(1)'
+ , 'down("li", 0) from both root and first child of root moves to first li element in document-order on first branch only'
+ )
+ }
+ }
+
+ , 'Selector argument traversal': {
+
+ 'next(selector)': function () {
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li:nth-child(1)')).next('li')
+ , '#fixtures > ul > li:nth-child(n+2)'
+ , 'next("li") on two first-elements matches all following sibling elements'
+ )
+
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li:nth-child(3)')).next('li')
+ , '#fixtures > ul > li:nth-child(n+4)'
+ , 'next("li") on two second-elements matches all following sibling elements'
+ )
+
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li:nth-child(2)')).next('.c')
+ , '#fixtures > ul > li:nth-child(n+4).c' // nth-child doesn't look for .c children but actual children, so 4 is our next .c (note we have to write our selector with the trailling .c rather than the nicer li.c cause WebKit's nth-child is garbage
+ , 'next(".c") on two second-elements matches all following sibling elements with class "c"'
+ )
+
+ assert.hasExactElements(
+ T(Q('#flat *:nth-child(2)')).next('span, p')
+ , '#flat *:nth-child(4),#flat *:nth-child(5)'
+ , 'next("span, p") matches all following <span> and <p> sibling elements'
+ )
+ }
+
+ , 'previous(selector)': function () {
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li:nth-child(5)')).previous('li')
+ , '#fixtures > ul > li:nth-child(-n+4)' // all but last
+ , 'previous("li") on two first-elements matches all preceeding sibling elements'
+ )
+
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li:nth-child(3)')).previous('li')
+ , '#fixtures > ul > li:nth-child(-n+2)' // first 2
+ , 'previous("li") on two second-elements matches all preceeding sibling elements'
+ )
+
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li:nth-child(5)')).previous('.c')
+ , '#fixtures > ul > li.c:nth-child(-n+4)' // nth-child doesn't look for .c children but actual children, so 4 is our previous .c
+ , 'previous(".c") on two second-elements matches all preceeding sibling elements with class "c"'
+ )
+
+ assert.hasExactElements(
+ T(Q('#flat *:nth-child(5)')).previous('span, p')
+ , '#flat *:nth-child(-n+2),#flat *:nth-child(4)'
+ , 'previous("span, p") matches all preceeding <span> and <p> sibling elements'
+ )
+ }
+
+ , 'up(selector)': function () {
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li > ul > li > span')).up('li')
+ , '#fixtures > ul:nth-child(1) > li:nth-child(4), #fixtures > ul:nth-child(1) > li > ul > li:nth-child(4),#fixtures > ul > li:nth-child(4), #fixtures > ul > li > ul > li:nth-child(4)'
+ , 'up("li") on two deep elements matches all <li> ancestor elements'
+ )
+
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li > ul > li > span')).up('*')
+ , 'html, body, #fixtures, #fixtures > ul:nth-child(1), #fixtures > ul:nth-child(1) > li:nth-child(4), #fixtures > ul:nth-child(1) > li:nth-child(4) > ul, #fixtures > ul:nth-child(1) > li > ul > li:nth-child(4), #fixtures > ul, #fixtures > ul > li:nth-child(4), #fixtures > ul > li:nth-child(4) > ul, #fixtures > ul > li > ul > li:nth-child(4)'
+ , 'up("*") on two deep elements matches all ancestor elements up to <html>'
+ )
+
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li > ul > li > span')).up('ul, li')
+ , '#fixtures > ul:nth-child(1), #fixtures > ul:nth-child(1) > li:nth-child(4), #fixtures > ul:nth-child(1) > li:nth-child(4) > ul, #fixtures > ul:nth-child(1) > li > ul > li:nth-child(4),#fixtures > ul, #fixtures > ul > li:nth-child(4), #fixtures > ul > li > ul, #fixtures > ul > li > ul > li:nth-child(4)'
+ , 'up("ul, li") on two deep elements matches all <ul> and <li> ancestor elements'
+ )
+ }
+
+ , 'down(selector)': function () {
+ assert.hasExactElements(
+ T(Q('#fixtures')).down('li')
+ , '#fixtures li'
+ , 'down("li") selects all descendent <li> elements, same as qSA'
+ )
+
+ assert.hasExactElements(
+ T(Q('#fixtures > ul > li')).down('*')
+ , '#fixtures > ul > li *'
+ , 'down("*") selects all descendent elements, same as qSA'
+ )
+
+ assert.hasExactElements(
+ T(Q('#fixtures > ul:nth-child(1)')).down('li, span')
+ , '#fixtures > ul:nth-child(1) > li:nth-child(-n+4), #fixtures > ul:nth-child(1) > li > ul > li, #fixtures > ul:nth-child(1) > li > ul > li > span, #fixtures > ul:nth-child(1) > li.five'
+ , 'down("li, span") selects all descendent <li> and <span> elements, same as qSA'
+ )
+
+ }
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.