UNPKG

mutation-summary

Version:
156 lines 6.74 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MutationSummary = void 0; var Summary_1 = require("./Summary"); var MutationProjection_1 = require("./MutationProjection"); var MutationSummaryOptionProcessor_1 = require("./MutationSummaryOptionProcessor"); /** * This is the main entry point class for the Mutation Summary library. When * created, a MutationSummary takes care of the details of observing the DOM * for changes, computing the "net-effect" of what's changed and then delivers * these changes to the provided callback. * * @example * ``` * * const ms = new MutationSummary({ * callback(summaries: Summary[]) { * summaries.forEach((summary: Summary) => console.log(summary)); * }, * queries: [ * { all: true } * ] * }); * ``` */ var MutationSummary = /** @class */ (function () { /** * Creates a new MutationSummary class using the specified options. * * @param opts The options that configure how the MutationSummary * instance will observe and report changes. */ function MutationSummary(opts) { var _this = this; this._connected = false; this._options = MutationSummaryOptionProcessor_1.MutationSummaryOptionProcessor.validateOptions(opts); this._observerOptions = MutationSummaryOptionProcessor_1.MutationSummaryOptionProcessor.createObserverOptions(this._options.queries); this._root = this._options.rootNode; this._callback = this._options.callback; this._elementFilter = Array.prototype.concat.apply([], this._options.queries.map(function (query) { return query.elementFilter ? query.elementFilter : []; })); if (!this._elementFilter.length) this._elementFilter = undefined; this._calcReordered = this._options.queries.some(function (query) { return query.all; }); this._queryValidators = []; // TODO(rafaelw): Shouldn't always define this. if (MutationSummary.createQueryValidator) { this._queryValidators = this._options.queries.map(function (query) { return MutationSummary.createQueryValidator(_this._root, query); }); } this._observer = new MutationObserver(function (mutations) { _this._observerCallback(mutations); }); this.reconnect(); } /** * Starts observation using an existing `MutationSummary` which has been * disconnected. Note that this function is just a convenience method for * creating a new `MutationSummary` with the same options. The next time * changes are reported, they will relative to the state of the observed * DOM at the point that `reconnect` was called. */ MutationSummary.prototype.reconnect = function () { if (this._connected) throw Error('Already connected'); this._observer.observe(this._root, this._observerOptions); this._connected = true; this._checkpointQueryValidators(); }; /** * Immediately calculates changes and returns them as an array of summaries. * If there are no changes to report, returns undefined. */ MutationSummary.prototype.takeSummaries = function () { if (!this._connected) throw Error('Not connected'); var summaries = this._createSummaries(this._observer.takeRecords()); return this._changesToReport(summaries) ? summaries : undefined; }; /** * Discontinues observation immediately. If DOM changes are pending delivery, * they will be fetched and reported as the same array of summaries which * are handed into the callback. If there is nothing to report, * this function returns undefined. * * @returns A list of changes that have not yet been delivered to a callback. */ MutationSummary.prototype.disconnect = function () { var summaries = this.takeSummaries(); this._observer.disconnect(); this._connected = false; return summaries; }; MutationSummary.prototype._observerCallback = function (mutations) { if (!this._options.observeOwnChanges) this._observer.disconnect(); var summaries = this._createSummaries(mutations); this._runQueryValidators(summaries); if (this._options.observeOwnChanges) this._checkpointQueryValidators(); if (this._changesToReport(summaries)) this._callback(summaries); // disconnect() may have been called during the callback. if (!this._options.observeOwnChanges && this._connected) { this._checkpointQueryValidators(); this._observer.observe(this._root, this._observerOptions); } }; MutationSummary.prototype._createSummaries = function (mutations) { if (!mutations || !mutations.length) return []; var projection = new MutationProjection_1.MutationProjection(this._root, mutations, this._elementFilter, this._calcReordered, this._options.oldPreviousSibling); var summaries = []; for (var i = 0; i < this._options.queries.length; i++) { summaries.push(new Summary_1.Summary(projection, this._options.queries[i])); } return summaries; }; MutationSummary.prototype._checkpointQueryValidators = function () { this._queryValidators.forEach(function (validator) { if (validator) validator.recordPreviousState(); }); }; MutationSummary.prototype._runQueryValidators = function (summaries) { this._queryValidators.forEach(function (validator, index) { if (validator) validator.validate(summaries[index]); }); }; MutationSummary.prototype._changesToReport = function (summaries) { return summaries.some(function (summary) { var summaryProps = ['added', 'removed', 'reordered', 'reparented', 'valueChanged', 'characterDataChanged']; if (summaryProps.some(function (prop) { return summary[prop] && summary[prop].length; })) return true; if (summary.attributeChanged) { var attrNames = Object.keys(summary.attributeChanged); var attrsChanged = attrNames.some(function (attrName) { return !!summary.attributeChanged[attrName].length; }); if (attrsChanged) return true; } return false; }); }; return MutationSummary; }()); exports.MutationSummary = MutationSummary; //# sourceMappingURL=MutationSummary.js.map