Extracted the reflow tracking logic from the box-model to a dedicated util in inspector/shared/reflow-tracker.js to use it in both box-model and grid-inspector. MozReview-Commit-ID: DZCOH3RDY6
114 lines
2.6 KiB
JavaScript
114 lines
2.6 KiB
JavaScript
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
|
/* vim: set ts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
"use strict";
|
|
|
|
const { ReflowFront } = require("devtools/shared/fronts/reflow");
|
|
|
|
/**
|
|
* Simple utility class that listens to reflows on a given target if and only if a
|
|
* listener is actively listening to reflows.
|
|
*
|
|
* @param {Object} target
|
|
* The current target (as in toolbox target)
|
|
*/
|
|
function ReflowTracker(target) {
|
|
this.target = target;
|
|
|
|
// Hold a Map of all the listeners interested in reflows.
|
|
this.listeners = new Map();
|
|
|
|
this.reflowFront = null;
|
|
|
|
this.onReflow = this.onReflow.bind(this);
|
|
}
|
|
|
|
ReflowTracker.prototype = {
|
|
|
|
destroy() {
|
|
if (this.reflowFront) {
|
|
this.stopTracking();
|
|
this.reflowFront.destroy();
|
|
this.reflowFront = null;
|
|
}
|
|
|
|
this.listeners.clear();
|
|
},
|
|
|
|
startTracking() {
|
|
// Initialize reflow front if necessary.
|
|
if (!this.reflowFront && this.target.form.reflowActor) {
|
|
let { client, form } = this.target;
|
|
this.reflowFront = ReflowFront(client, form);
|
|
}
|
|
|
|
if (this.reflowFront) {
|
|
this.reflowFront.on("reflows", this.onReflow);
|
|
this.reflowFront.start();
|
|
}
|
|
},
|
|
|
|
stopTracking() {
|
|
if (this.reflowFront) {
|
|
this.reflowFront.off("reflows", this.onReflow);
|
|
this.reflowFront.stop();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Add a listener for reflows.
|
|
*
|
|
* @param {Object} listener
|
|
* Object/instance listening to reflows.
|
|
* @param {Function} callback
|
|
* The associated callback.
|
|
*/
|
|
trackReflows(listener, callback) {
|
|
if (this.listeners.get(listener) === callback) {
|
|
return;
|
|
}
|
|
|
|
// No listener interested in reflows yet, start tracking.
|
|
if (this.listeners.size === 0) {
|
|
this.startTracking();
|
|
}
|
|
|
|
this.listeners.set(listener, callback);
|
|
},
|
|
|
|
/**
|
|
* Remove a listener for reflows.
|
|
*
|
|
* @param {Object} listener
|
|
* Object/instance listening to reflows.
|
|
* @param {Function} callback
|
|
* The associated callback.
|
|
*/
|
|
untrackReflows(listener, callback) {
|
|
if (this.listeners.get(listener) !== callback) {
|
|
return;
|
|
}
|
|
|
|
this.listeners.delete(listener);
|
|
|
|
// No listener interested in reflows anymore, stop tracking.
|
|
if (this.listeners.size === 0) {
|
|
this.stopTracking();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Handler called when a reflow happened.
|
|
*/
|
|
onReflow() {
|
|
for (let [, callback] of this.listeners) {
|
|
callback();
|
|
}
|
|
},
|
|
};
|
|
|
|
module.exports = ReflowTracker;
|