page-parser-tree
Version:
Library to find elements in a dynamic web page
139 lines (123 loc) • 4.5 kB
JavaScript
;
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