Bug 1454317 - Reference correct shape swatch element after editing value in rule view. r=gl
MozReview-Commit-ID: LwF3XsE6yEs
--- a/devtools/client/shared/widgets/ShapesInContextEditor.js
+++ b/devtools/client/shared/widgets/ShapesInContextEditor.js
@@ -39,19 +39,19 @@ class ShapesInContextEditor {
// Reference to DOM node of the toggle icon for shapes highlighter.
this.swatch = null;
// Reference to TextProperty where shape changes will be written.
this.textProperty = null;
// Commit triggers expensive DOM changes in TextPropertyEditor.update()
// so we debounce it.
this.commit = debounce(this.commit, 200, this);
- this.onChangesApplied = this.onChangesApplied.bind(this);
this.onHighlighterEvent = this.onHighlighterEvent.bind(this);
this.onNodeFrontChanged = this.onNodeFrontChanged.bind(this);
+ this.onShapeValueUpdated = this.onShapeValueUpdated.bind(this);
this.onRuleViewChanged = this.onRuleViewChanged.bind(this);
this.highlighter.on("highlighter-event", this.onHighlighterEvent);
this.ruleView.on("ruleview-changed", this.onRuleViewChanged);
}
/**
* Called when the element style changes from the Rule view.
@@ -106,16 +106,17 @@ class ShapesInContextEditor {
async show(node, options) {
const isShown = await this.highlighter.show(node, options);
if (!isShown) {
return;
}
this.inspector.selection.on("detached-front", this.onNodeFrontChanged);
this.inspector.selection.on("new-node-front", this.onNodeFrontChanged);
+ this.ruleView.on("property-value-updated", this.onShapeValueUpdated);
this.highlighterTargetNode = node;
this.mode = options.mode;
this.emit("show", { node, options });
}
/**
* Hide the shapes highlighter.
*/
@@ -130,29 +131,32 @@ class ShapesInContextEditor {
this.swatch.classList.remove("active");
}
this.swatch = null;
this.textProperty = null;
this.emit("hide", { node: this.highlighterTargetNode });
this.inspector.selection.off("detached-front", this.onNodeFrontChanged);
this.inspector.selection.off("new-node-front", this.onNodeFrontChanged);
+ this.ruleView.off("property-value-updated", this.onShapeValueUpdated);
this.highlighterTargetNode = null;
}
/**
* Identify the swatch (aka toggle icon) DOM node from the TextPropertyEditor of the
* TextProperty we're working with. Whenever the TextPropertyEditor is updated (i.e.
* when committing the shape value to the Rule view), it rebuilds its DOM and the old
* swatch reference becomes invalid. Call this method to identify the current swatch.
*/
findSwatch() {
const valueSpan = this.textProperty.editor.valueSpan;
this.swatch = valueSpan.querySelector(".ruleview-shapeswatch");
- this.swatch.classList.add("active");
+ if (this.swatch) {
+ this.swatch.classList.add("active");
+ }
}
/**
* Handle events emitted by the highlighter.
* Find any callback assigned to the event type and call it with the given data object.
*
* @param {Object} data
* The data object sent in the event.
@@ -200,24 +204,21 @@ class ShapesInContextEditor {
*
* @param {Object} data
* Data associated with the "shape-hover" event.
* Contains:
* - {String|null} point: coordinate to highlight or null if nothing to highlight
* - {String} type: the event type ("shape-hover-on" or "shape-hover-on").
*/
onShapeHover(data) {
- if (!this.textProperty) {
+ const shapeValueEl = this.swatch && this.swatch.nextSibling;
+ if (!shapeValueEl) {
return;
}
- const shapeValueEl = this.swatch.nextSibling;
- if (!shapeValueEl) {
- return;
- }
const pointSelector = ".ruleview-shape-point";
// First, unmark all highlighted coordinate nodes from Rule view
for (const node of shapeValueEl.querySelectorAll(`${pointSelector}.active`)) {
node.classList.remove("active");
}
// Exit if there's no coordinate to highlight.
if (typeof data.point !== "string") {
@@ -238,16 +239,29 @@ class ShapesInContextEditor {
`${pointSelector}[data-point='${point}']`;
for (const node of shapeValueEl.querySelectorAll(selector)) {
node.classList.add("active");
}
}
/**
+ * Handler for "property-value-updated" event triggered by the Rule view.
+ * Called after the shape value has been written to the element's style and the Rule
+ * view updated. Emits an event on HighlightersOverlay that is expected by
+ * tests in order to check if the shape value has been correctly applied.
+ */
+ onShapeValueUpdated() {
+ // When TextPropertyEditor updates, it replaces the previous swatch DOM node.
+ // Find and store the new one.
+ this.findSwatch();
+ this.inspector.highlighters.emit("shapes-highlighter-changes-applied");
+ }
+
+ /**
* Preview a shape value on the element without committing the changes to the Rule view.
*
* @param {String} value
* The shape value to set the current property to
*/
preview(value) {
if (!this.textProperty) {
return;
@@ -266,33 +280,20 @@ class ShapesInContextEditor {
*
* @param {String} value
* The shape value for the current property
*/
commit(value) {
if (!this.textProperty) {
return;
}
- this.ruleView.once("ruleview-changed", this.onChangesApplied);
+
this.textProperty.setValue(value);
}
- /**
- * Handler for "ruleview-changed" event triggered by the Rule view.
- * Called once after the shape value has been written to the element's style and Rule
- * view updated. Triggers an event on the HighlightersOverlay that is expected by
- * tests in order to check if the shape value has been correctly applied.
- */
- onChangesApplied() {
- // When TextPropertyEditor updates it thrashes the previous swatch DOM node. Find and
- // store the new swatch node.
- this.findSwatch();
- this.inspector.highlighters.emit("shapes-highlighter-changes-applied");
- }
-
destroy() {
this.highlighter.off("highlighter-event", this.onHighlighterEvent);
this.ruleView.off("ruleview-changed", this.onRuleViewChanged);
this.highligherEventHandlers = {};
}
}
module.exports = ShapesInContextEditor;