UNPKG

page-parser-tree

Version:

Library to find elements in a dynamic web page

139 lines (123 loc) 4.5 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = watchFilteredChildren; var _liveSet = _interopRequireDefault(require("live-set")); function watchFilteredChildren(input, condFn) { return new _liveSet["default"]({ scheduler: input.getScheduler(), read: function read() { throw new Error(); }, listen: function listen(setValues, controller) { setValues(new Set()); var inputEntries = new Map(); var outputEcs = new Map(); function newEc(ec) { function addedNode(child) { if (child.nodeType !== 1) return; /*:: if (!(child instanceof HTMLElement)) throw new Error() */ if (condFn(child)) { var childEc = { el: child, parents: ec.parents }; outputEcs.set(child, childEc); controller.add(childEc); } } function removedNode(child) { if (child.nodeType !== 1) return; /*:: if (!(child instanceof HTMLElement)) throw new Error() */ var childEc = outputEcs.get(child); if (!childEc) return; outputEcs["delete"](child); controller.remove(childEc); } function changesHandler(mutations) { if (mutations.length > 1) { // If any removals are followed by a re-add, then drop the pair. var removedEls = new Set(); var addedEls = []; mutations.forEach(function (_ref) { var addedNodes = _ref.addedNodes, removedNodes = _ref.removedNodes; for (var i = 0, len = removedNodes.length; i < len; i++) { var _el = removedNodes[i]; if (_el.nodeType !== 1) continue; removedEls.add(removedNodes[i]); } for (var _i = 0, _len = addedNodes.length; _i < _len; _i++) { var _el2 = addedNodes[_i]; if (_el2.nodeType !== 1) continue; if (removedEls.has(_el2)) { removedEls["delete"](_el2); } else { addedEls.push(_el2); } } }); addedEls.forEach(addedNode); removedEls.forEach(removedNode); } else { mutations.forEach(function (mutation) { Array.prototype.forEach.call(mutation.addedNodes, addedNode); Array.prototype.forEach.call(mutation.removedNodes, removedNode); }); } } Array.prototype.forEach.call(ec.el.children, addedNode); var observer = new MutationObserver(changesHandler); observer.observe(ec.el, { childList: true }); inputEntries.set(ec, { observer: observer, removedNode: removedNode }); } function removedEc(ec) { var entry = inputEntries.get(ec); if (!entry) throw new Error('Should not happen: Unseen ElementContext removed'); entry.observer.takeRecords().forEach(function (mutation) { Array.prototype.forEach.call(mutation.removedNodes, entry.removedNode); }); entry.observer.disconnect(); Array.prototype.forEach.call(ec.el.children, entry.removedNode); inputEntries["delete"](ec); } var sub = input.subscribe({ start: function start() { input.values().forEach(newEc); }, next: function next(changes) { changes.forEach(function (change) { if (change.type === 'add') { newEc(change.value); } else if (change.type === 'remove') { removedEc(change.value); } }); } }); return { unsubscribe: function unsubscribe() { sub.unsubscribe(); inputEntries.forEach(function (_ref2) { var observer = _ref2.observer; observer.disconnect(); }); }, pullChanges: function pullChanges() { sub.pullChanges(); // Don't bother doing observer.takeRecords(), we don't need that in // PageParserTree for how we use pullChanges(). } }; } }); } module.exports = exports.default; module.exports.default = exports.default; //# sourceMappingURL=watchFilteredChildren.js.map