dom-node-iterator
Advanced tools
Comparing version
@@ -0,1 +1,3 @@ | ||
'use strict'; | ||
module.exports = require('./lib/implementation')['default']; |
34
index.js
@@ -1,4 +0,30 @@ | ||
module.exports = require('./lib')['default']; | ||
module.exports.getPolyfill = require('./polyfill'); | ||
module.exports.implementation = require('./implementation'); | ||
module.exports.shim = require('./shim'); | ||
'use strict' | ||
var implementation = require('./implementation'); | ||
var getPolyfill = require('./polyfill'); | ||
var shim = require('./shim'); | ||
var bound = Function.prototype.call.bind(implementation); | ||
Object.defineProperties(bound, { | ||
getPolyfill: { | ||
configurable: true, | ||
enumerable: false, | ||
value: getPolyfill, | ||
writeable: true | ||
}, | ||
implementation: { | ||
configurable: true, | ||
enumerable: false, | ||
value: implementation, | ||
writeable: true | ||
}, | ||
shim: { | ||
configurable: true, | ||
enumerable: false, | ||
value: shim, | ||
writeable: true | ||
} | ||
}); | ||
module.exports = bound; |
@@ -8,10 +8,11 @@ "use strict"; | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
var _Document, _Document$prototype; | ||
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } | ||
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } | ||
var _default = createNodeIterator; | ||
exports["default"] = _default; | ||
var create = Object.create.bind(Object); | ||
var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor.bind(Object); | ||
var getPrototypeOf = Object.getPrototypeOf.bind(Object); | ||
var original = (_Document = Document) === null || _Document === void 0 ? void 0 : (_Document$prototype = _Document.prototype) === null || _Document$prototype === void 0 ? void 0 : _Document$prototype.createNodeIterator; | ||
var originalBound = original && Function.prototype.call.bind(original); | ||
@@ -21,89 +22,179 @@ function createNodeIterator(root) { | ||
var filter = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; | ||
return new NodeIterator(root, whatToShow, filter); | ||
var document = this; | ||
if (typeof originalBound === 'function') { | ||
var iter = originalBound(document, root, whatToShow, filter, false); | ||
var prototype = getPrototypeOf(iter); | ||
var referenceNode = getOwnPropertyDescriptor(prototype, 'referenceNode'); | ||
return referenceNode === undefined ? wrapNodeIterator(iter) : iter; | ||
} | ||
return implementNodeIterator(root, whatToShow, filter); | ||
} | ||
var NodeIterator = /*#__PURE__*/function () { | ||
function NodeIterator(root, whatToShow, filter) { | ||
_classCallCheck(this, NodeIterator); | ||
function successor(node, root) { | ||
if (node.firstChild) return node.firstChild; | ||
this.root = root; | ||
this.whatToShow = whatToShow; | ||
this.filter = filter; | ||
this.referenceNode = root; | ||
this.pointerBeforeReferenceNode = true; | ||
while (node !== root) { | ||
if (node.nextSibling) return node.nextSibling; | ||
node = node.parentNode; | ||
} | ||
this._filter = function (node) { | ||
return filter ? filter(node) === 1 : true; | ||
}; | ||
return null; | ||
} | ||
this._show = function (node) { | ||
return whatToShow >> node.nodeType - 1 & 1 === 1; | ||
}; | ||
function predecessor(node, root) { | ||
if (node === root) return null; | ||
if (node.previousSibling) { | ||
node = node.previousSibling; | ||
while (node.lastChild) { | ||
node = node.lastChild; | ||
} | ||
return node; | ||
} | ||
_createClass(NodeIterator, [{ | ||
key: "nextNode", | ||
value: function nextNode() { | ||
var node = this.referenceNode; | ||
var before = this.pointerBeforeReferenceNode; | ||
return node.parentNode; | ||
} | ||
while (true) { | ||
if (before) { | ||
before = false; | ||
} else { | ||
if (node.firstChild) node = node.firstChild;else { | ||
do { | ||
if (node === this.root) return null; | ||
if (node.nextSibling) break; | ||
node = node.parentNode; | ||
} while (true); | ||
function implementNodeIterator(root, whatToShow, filter) { | ||
var data = { | ||
referenceNode: root, | ||
pointerBeforeReferenceNode: true | ||
}; | ||
node = node.nextSibling; | ||
} | ||
} | ||
function _filter(node) { | ||
return filter ? filter(node) === 1 : true; | ||
} | ||
if (this._show(node) && this._filter(node)) break; | ||
function _show(node) { | ||
return whatToShow >> node.nodeType - 1 & 1 === 1; | ||
} | ||
return create({}, { | ||
root: { | ||
value: root | ||
}, | ||
referenceNode: { | ||
get: function referenceNode() { | ||
return data.referenceNode; | ||
} | ||
}, | ||
pointerBeforeReferenceNode: { | ||
get: function pointerBeforeReferenceNode() { | ||
return data.pointerBeforeReferenceNode; | ||
} | ||
}, | ||
whatToShow: { | ||
value: whatToShow | ||
}, | ||
filter: { | ||
value: filter | ||
}, | ||
nextNode: { | ||
value: function nextNode() { | ||
var node = data.referenceNode; | ||
var before = data.pointerBeforeReferenceNode; | ||
this.referenceNode = node; | ||
this.pointerBeforeReferenceNode = before; | ||
return node; | ||
} | ||
}, { | ||
key: "previousNode", | ||
value: function previousNode() { | ||
var before = this.pointerBeforeReferenceNode; | ||
var node = this.referenceNode; | ||
while (true) { | ||
if (before) before = false;else node = successor(node, root); | ||
if (node === null) return null; | ||
if (_show(node) && _filter(node)) break; | ||
} | ||
while (true) { | ||
if (!before) { | ||
before = true; | ||
} else { | ||
if (node === this.root) return null; | ||
data.referenceNode = node; | ||
data.pointerBeforeReferenceNode = before; | ||
return node; | ||
} | ||
}, | ||
previousNode: { | ||
value: function previousNode() { | ||
var before = data.pointerBeforeReferenceNode; | ||
var node = data.referenceNode; | ||
if (node.previousSibling) { | ||
node = node.previousSibling; | ||
while (node.lastChild) { | ||
node = node.lastChild; | ||
} | ||
} else node = node.parentNode; | ||
while (true) { | ||
if (!before) before = true;else node = predecessor(node, data.root); | ||
if (node === null) return null; | ||
if (_show(node) && _filter(node)) break; | ||
} | ||
if (this._show(node) && this._filter(node)) break; | ||
data.referenceNode = node; | ||
data.pointerBeforeReferenceNode = before; | ||
return node; | ||
} | ||
}, | ||
detach: { | ||
value: function detach() {} | ||
}, | ||
toString: { | ||
value: function toString() { | ||
return '[object NodeIterator]'; | ||
} | ||
} | ||
}); | ||
} | ||
this.referenceNode = node; | ||
this.pointerBeforeReferenceNode = before; | ||
return node; | ||
function wrapNodeIterator(iter) { | ||
var data = { | ||
referenceNode: iter.root, | ||
pointerBeforeReferenceNode: true | ||
}; | ||
var prototype = getPrototypeOf(iter); | ||
var wrapperPrototype = create(prototype, { | ||
root: { | ||
get: function root() { | ||
return iter.root; | ||
} | ||
}, | ||
referenceNode: { | ||
get: function referenceNode() { | ||
return data.referenceNode; | ||
} | ||
}, | ||
pointerBeforeReferenceNode: { | ||
get: function pointerBeforeReferenceNode() { | ||
return data.pointerBeforeReferenceNode; | ||
} | ||
}, | ||
whatToShow: { | ||
get: function whatToShow() { | ||
return iter.whatToShow; | ||
} | ||
}, | ||
filter: { | ||
get: function filter() { | ||
return iter.filter; | ||
} | ||
}, | ||
nextNode: { | ||
value: function nextNode() { | ||
var result = iter.nextNode(); | ||
if (result === null) return null; | ||
data.referenceNode = result; | ||
data.pointerBeforeReferenceNode = false; | ||
return data.referenceNode; | ||
} | ||
}, | ||
previousNode: { | ||
value: function previousNode() { | ||
var result = iter.previousNode(); | ||
if (result === null) return null; | ||
data.referenceNode = result; | ||
data.pointerBeforeReferenceNode = true; | ||
return data.referenceNode; | ||
} | ||
}, | ||
detach: { | ||
value: function detach() {} | ||
}, | ||
toString: { | ||
value: function toString() { | ||
return '[object NodeIterator]'; | ||
} | ||
} | ||
}, { | ||
key: "toString", | ||
value: function toString() { | ||
return '[object NodeIterator]'; | ||
} | ||
}]); | ||
return NodeIterator; | ||
}(); | ||
}); | ||
return create(wrapperPrototype); | ||
} | ||
//# sourceMappingURL=implementation.js.map |
{ | ||
"name": "dom-node-iterator", | ||
"version": "4.0.0", | ||
"version": "5.0.0", | ||
"description": "A portable NodeIterator polyfill.", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -1,1 +0,7 @@ | ||
module.exports = require('./lib/polyfill')['default']; | ||
'use strict'; | ||
var implementation = require('./implementation'); | ||
module.exports = function getPolyfill() { | ||
return implementation; | ||
} |
NodeIterator | ||
============ | ||
`NodeIterator` is an interface originally specified by | ||
[DOM Level 2](http://www.w3.org/TR/DOM-Level-2-Traversal-Range/traversal.html#Iterator-overview). | ||
While it is a useful tool for seeking within the nodes of the DOM, it has | ||
[some warts](http://ejohn.org/blog/unimpressed-by-nodeiterator/) and its | ||
implementation is inconsistent across browsers. | ||
The `dom-node-iterator` package provides a spec-compliant implementation of | ||
`NodeIterator` for environments that lack an implementation or conform to an | ||
older specification. | ||
Among the problems with `NodeIterator` are that it specifies arguments that | ||
really should be optional, but are required on some browsers. Several browsers | ||
expose two additional properties not in the original specification but later | ||
added to the DOM living standard, `referenceNode` and | ||
`pointerBeforeReferenceNode`. | ||
In environments that implement an older specification or do not implement the | ||
specification at all, behavior in the presence of DOM mutation is undefined. | ||
This module attempts to modernize `NodeIterator` for use in all major browsers. | ||
It does this through the following modifications: | ||
This package implements the [es-shim API](https://github.com/es-shims/api) | ||
interface. It works in an ES5-supported environment with a DOM implementation | ||
and complies with the [spec](https://dom.spec.whatwg.org/#nodeiterator). | ||
- The `whatToShow` and `filter` arguments are optional. | ||
- The `referenceNode` and `pointerBeforeReferenceNode` properties are shimmed | ||
when they aren't available. | ||
Compatibility Note | ||
================== | ||
In browsers that implement an older specification or do not implement the | ||
specification at all, behavior in the presence of concurrent DOM mutation is | ||
undefined. | ||
Installation | ||
@@ -41,20 +25,10 @@ ============ | ||
This package implements the [es-shim API](https://github.com/es-shims/api) | ||
interface. | ||
```js | ||
// Install support, polluting the global namespace. | ||
require('dom-node-iterator/shim')(); | ||
require('dom-node-iterator/auto'); | ||
var iter = document.createNodeIterator(document.body); | ||
// Get the best implementation, without polluting the global namespace. | ||
var createNodeIterator = require('dom-node-iterator/polyfill')(); | ||
var createNodeIterator = require('dom-node-iterator'); | ||
var iter = createNodeIterator.call(document, document.body); | ||
// Get the pure JavaScript implementation. | ||
var createNodeIterator = require('dom-node-iterator/implementation'); | ||
var iter = createNodeIterator.call(document, document.body); | ||
``` | ||
See [the documentation at the Mozilla Developer Network](https://developer.mozilla.org/en-US/docs/Web/API/NodeIterator) | ||
for more information about using `NodeIterator`. |
14
shim.js
@@ -1,1 +0,13 @@ | ||
module.exports = require('./lib/shim')['default']; | ||
'use strict'; | ||
var getPolyfill = require('./polyfill'); | ||
module.exports = function shimCreateNodeIterator() { | ||
var polyfill = getPolyfill(); | ||
if (polyfill !== Document.prototype.createNodeIterator) { | ||
Document.prototype.createNodeIterator = polyfill; | ||
} | ||
return polyfill; | ||
} |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
30173
37.07%20
5.26%334
59.81%0
-100%34
-43.33%