diff --git a/src/scopedQuerySelectorShim.js b/src/scopedQuerySelectorShim.js index 357e15c..5083407 100644 --- a/src/scopedQuerySelectorShim.js +++ b/src/scopedQuerySelectorShim.js @@ -13,8 +13,9 @@ container.querySelectorAll(':scope *'); } catch (e) { - // Match usage of scope - var scopeRE = /^\s*:scope/gi; + var rxTest = /(?:^|,)\s*:scope\s+/, + rxStart = /^\s*:scope\s+/i, + rxOthers = /,\s*:scope\s+/gi; // Overrides function overrideNodeMethod(prototype, methodName) { @@ -23,13 +24,12 @@ // Override the method prototype[methodName] = function(query) { - var nodeList, - gaveId = false, - gaveContainer = false; + var nodeList, parentNode, frag, idSelector, + gaveId = false, + gaveContainer = false, + parentIsFragment = false; - if (query.match(scopeRE)) { - // Remove :scope - query = query.replace(scopeRE, ''); + if (rxTest.test(query)) { if (!this.parentNode) { // Add to temporary container @@ -37,6 +37,12 @@ gaveContainer = true; } + if (this.parentNode instanceof DocumentFragment) { + frag = this.parentNode; + while (frag.firstChild) container.appendChild(frag.firstChild); + parentIsFragment = true; + } + parentNode = this.parentNode; if (!this.id) { @@ -45,8 +51,12 @@ gaveId = true; } + // replace :scope with ID selector + idSelector = '#' + this.id + ' '; + query = query.replace(rxStart, idSelector).replace(rxOthers, ', ' + idSelector); + // Find elements against parent node - nodeList = oldMethod.call(parentNode, '#'+this.id+' '+query); + nodeList = oldMethod.call(parentNode, query); // Reset the ID if (gaveId) { @@ -54,7 +64,9 @@ } // Remove from temporary container - if (gaveContainer) { + if (parentIsFragment) { + while (container.firstChild) frag.appendChild(container.firstChild); + } else if (gaveContainer) { container.removeChild(this); } @@ -71,4 +83,4 @@ overrideNodeMethod(HTMLElement.prototype, 'querySelector'); overrideNodeMethod(HTMLElement.prototype, 'querySelectorAll'); } -}()); +}()); \ No newline at end of file diff --git a/test/testShim.js b/test/testShim.js index e632355..87102c0 100644 --- a/test/testShim.js +++ b/test/testShim.js @@ -14,21 +14,44 @@ describe('scopedQuerySelectorShim', function() { return node; } + function makeNodeAndAddToFragment(html) { + var frag, node; + frag = document.createDocumentFragment(); + node = makeNode(html); + frag.appendChild(node); + return node; + } + function testChildNode(node) { - expect(node.innerHTML).to.equal('Child'); + expect(node.innerHTML).toBe('Child'); } function testChildNodeList(nodeList) { - expect(nodeList.length).to.equal(1); + expect(nodeList.length).toBe(1); testChildNode(nodeList[0]); } + + function testComplexNodeList(nodeList) { + testGrandChildNode(nodeList[0]); + testGrandChildNode1(nodeList[1]); + testGrandChildNode2(nodeList[2]); + testGrandChildNode3(nodeList[3]); + } function testGrandChildNode(node) { - expect(node.innerHTML).to.equal('Grandchild 1'); + expect(node.innerHTML).toBe('Grandchild 1'); } function testGrandChildNode1(node) { - expect(node.innerHTML).to.equal('Grandchild 2'); + expect(node.innerHTML).toBe('Grandchild 2'); + } + + function testGrandChildNode2(node) { + expect(node.innerHTML).toBe('Grandchild 3'); + } + + function testGrandChildNode3(node) { + expect(node.innerHTML).toBe('Grandchild 4'); } function testGrandChildNodeList(nodeList) { @@ -45,7 +68,7 @@ describe('scopedQuerySelectorShim', function() {