Bug 1348005 - update grid panel on reflows;r=gl

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

--HG--
extra : rebase_source : 490befd89eb1011a02d8a99ac965b077da324067
This commit is contained in:
Julian Descottes 2017-03-29 20:51:27 +02:00
parent f4b04844e3
commit 1cc1cb498c
5 changed files with 133 additions and 24 deletions

View File

@ -6,7 +6,6 @@
const { Task } = require("devtools/shared/task");
const { getCssProperties } = require("devtools/shared/fronts/css-properties");
const { ReflowFront } = require("devtools/shared/fronts/reflow");
const { InplaceEditor } = require("devtools/client/shared/inplace-editor");
@ -60,11 +59,7 @@ BoxModel.prototype = {
this.inspector.selection.off("new-node-front", this.onNewSelection);
this.inspector.sidebar.off("select", this.onSidebarSelect);
if (this.reflowFront) {
this.untrackReflows();
this.reflowFront.destroy();
this.reflowFront = null;
}
this.untrackReflows();
this.document = null;
this.highlighters = null;
@ -109,30 +104,14 @@ BoxModel.prototype = {
* Starts listening to reflows in the current tab.
*/
trackReflows() {
if (!this.reflowFront) {
let { target } = this.inspector;
if (target.form.reflowActor) {
this.reflowFront = ReflowFront(target.client,
target.form);
} else {
return;
}
}
this.reflowFront.on("reflows", this.updateBoxModel);
this.reflowFront.start();
this.inspector.reflowTracker.trackReflows(this, this.updateBoxModel);
},
/**
* Stops listening to reflows in the current tab.
*/
untrackReflows() {
if (!this.reflowFront) {
return;
}
this.reflowFront.off("reflows", this.updateBoxModel);
this.reflowFront.stop();
this.inspector.reflowTracker.untrackReflows(this, this.updateBoxModel);
},
/**

View File

@ -47,6 +47,7 @@ function GridInspector(inspector, window) {
this.onGridLayoutChange = this.onGridLayoutChange.bind(this);
this.onHighlighterChange = this.onHighlighterChange.bind(this);
this.onMarkupMutation = this.onMarkupMutation.bind(this);
this.onReflow = this.onReflow.bind(this);
this.onSetGridOverlayColor = this.onSetGridOverlayColor.bind(this);
this.onShowGridAreaHighlight = this.onShowGridAreaHighlight.bind(this);
this.onShowGridCellHighlight = this.onShowGridCellHighlight.bind(this);
@ -101,6 +102,8 @@ GridInspector.prototype = {
this.inspector.sidebar.off("select", this.onSidebarSelect);
this.layoutInspector.off("grid-layout-changed", this.onGridLayoutChange);
this.inspector.reflowTracker.untrackReflows(this, this.onReflow);
this.swatchColorPickerTooltip.destroy();
this.document = null;
@ -294,6 +297,14 @@ GridInspector.prototype = {
this.updateGridPanel();
},
/**
* Handler for the "reflow" event fired by the inspector's reflow tracker. On reflows,
* update the grid panel content.
*/
onReflow() {
this.updateGridPanel();
},
/**
* Handler for a change in the grid overlay color picker for a grid container.
*
@ -376,9 +387,11 @@ GridInspector.prototype = {
onSidebarSelect() {
if (!this.isPanelVisible()) {
this.layoutInspector.off("grid-layout-changed", this.onGridLayoutChange);
this.inspector.reflowTracker.untrackReflows(this, this.onReflow);
return;
}
this.inspector.reflowTracker.trackReflows(this, this.onReflow);
this.layoutInspector.on("grid-layout-changed", this.onGridLayoutChange);
this.updateGridPanel();
},

View File

@ -29,6 +29,7 @@ const GridInspector = require("devtools/client/inspector/grids/grid-inspector");
const {InspectorSearch} = require("devtools/client/inspector/inspector-search");
const {RuleViewTool} = require("devtools/client/inspector/rules/rules");
const HighlightersOverlay = require("devtools/client/inspector/shared/highlighters-overlay");
const ReflowTracker = require("devtools/client/inspector/shared/reflow-tracker");
const {ToolSidebar} = require("devtools/client/inspector/toolsidebar");
const MarkupView = require("devtools/client/inspector/markup/markup");
const {CommandUtils} = require("devtools/client/shared/developer-toolbar");
@ -95,6 +96,7 @@ function Inspector(toolbox) {
this.panelWin.inspector = this;
this.highlighters = new HighlightersOverlay(this);
this.reflowTracker = new ReflowTracker(this._target);
this.store = Store();
this.telemetry = new Telemetry();
@ -967,6 +969,7 @@ Inspector.prototype = {
let markupDestroyer = this._destroyMarkup();
this.highlighters.destroy();
this.reflowTracker.destroy();
this.search.destroy();
this._toolbox = null;

View File

@ -8,6 +8,7 @@ DevToolsModules(
'dom-node-preview.js',
'highlighters-overlay.js',
'node-types.js',
'reflow-tracker.js',
'style-inspector-menu.js',
'tooltips-overlay.js',
'utils.js'

View File

@ -0,0 +1,113 @@
/* -*- 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;