Modified: trunk/Source/WebInspectorUI/ChangeLog (242321 => 242322)
--- trunk/Source/WebInspectorUI/ChangeLog 2019-03-03 00:15:11 UTC (rev 242321)
+++ trunk/Source/WebInspectorUI/ChangeLog 2019-03-03 00:18:55 UTC (rev 242322)
@@ -1,5 +1,25 @@
2019-03-02 Devin Rousso <[email protected]>
+ Web Inspector: Unexpectedly frequent flashing of DOM node attributes
+ https://bugs.webkit.org/show_bug.cgi?id=148049
+ <rdar://problem/22296830>
+
+ Reviewed by Joseph Pecoraro.
+
+ Save a timestamp of when the CSS animation began, so that if the attribute's node is replaced,
+ we can "resume" the CSS animation at the same point with the attribute's new node.
+
+ * UserInterface/Views/DOMTreeElement.js:
+ (WI.DOMTreeElement):
+ (WI.DOMTreeElement.prototype.attributeDidChange):
+ (WI.DOMTreeElement.prototype._buildAttributeDOM):
+ (WI.DOMTreeElement.prototype._createModifiedAnimation):
+ (WI.DOMTreeElement.prototype._markNodeChanged): Deleted.
+ (WI.DOMTreeElement.prototype._nodeChangedAnimationEnd): Deleted.
+ (WI.DOMTreeElement.prototype._fireDidChange): Deleted.
+
+2019-03-02 Devin Rousso <[email protected]>
+
Web Inspector: Debugger: DOM, URL, and Event breakpoints don't grey out when all breakpoints are disabled
https://bugs.webkit.org/show_bug.cgi?id=195170
<rdar://problem/48478193>
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/DOMTreeElement.js (242321 => 242322)
--- trunk/Source/WebInspectorUI/UserInterface/Views/DOMTreeElement.js 2019-03-03 00:15:11 UTC (rev 242321)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/DOMTreeElement.js 2019-03-03 00:18:55 UTC (rev 242322)
@@ -48,8 +48,7 @@
this._subtreeBreakpointCount = 0;
this._highlightedAttributes = new Set;
- this._recentlyModifiedAttributes = [];
- this._boundNodeChangedAnimationEnd = this._nodeChangedAnimationEnd.bind(this);
+ this._recentlyModifiedAttributes = new Map;
node.addEventListener(WI.DOMNode.Event.EnabledPseudoClassesChanged, this._nodePseudoClassesDidChange, this);
@@ -266,7 +265,15 @@
attributeDidChange(name)
{
- this._recentlyModifiedAttributes.push({name});
+ if (this._recentlyModifiedAttributes.has(name))
+ return;
+
+ this._recentlyModifiedAttributes.set(name, {
+ value: null,
+ timestamp: NaN,
+ element: null,
+ listener: null,
+ });
}
highlightAttribute(name)
@@ -1312,10 +1319,7 @@
if (hasText)
attrSpanElement.append("\"");
- for (let attribute of this._recentlyModifiedAttributes) {
- if (attribute.name === name)
- attribute.element = hasText ? attrValueElement : attrNameElement;
- }
+ this._createModifiedAnimation(name, value, hasText ? attrValueElement : attrNameElement);
if (this._highlightedAttributes.has(name))
attrSpanElement.classList.add("highlight");
@@ -1724,29 +1728,40 @@
WI.highlightRangesWithStyleClass(this.title, matchRanges, WI.DOMTreeElement.SearchHighlightStyleClassName, this._highlightResult);
}
- _markNodeChanged()
+ _createModifiedAnimation(key, value, element)
{
- for (let attribute of this._recentlyModifiedAttributes) {
- let element = attribute.element;
- if (!element)
- continue;
+ let existing = this._recentlyModifiedAttributes.get(key);
+ if (!existing)
+ return;
- element.classList.remove("node-state-changed");
- element.addEventListener("animationend", this._boundNodeChangedAnimationEnd);
- element.classList.add("node-state-changed");
+ if (existing.element) {
+ if (existing.listener)
+ existing.element.removeEventListener("animationend", existing.listener);
+
+ existing.element.classList.remove("node-state-changed");
+ existing.element.style.removeProperty("animation-delay");
}
- }
- _nodeChangedAnimationEnd(event)
- {
- let element = event.target;
+ existing.listener = (event) => {
+ element.classList.remove("node-state-changed");
+ element.style.removeProperty("animation-delay");
+
+ this._recentlyModifiedAttributes.delete(key);
+ };
+
element.classList.remove("node-state-changed");
- element.removeEventListener("animationend", this._boundNodeChangedAnimationEnd);
+ element.style.removeProperty("animation-delay");
- for (let i = this._recentlyModifiedAttributes.length - 1; i >= 0; --i) {
- if (this._recentlyModifiedAttributes[i].element === element)
- this._recentlyModifiedAttributes.splice(i, 1);
- }
+ if (existing.value === value)
+ element.style.setProperty("animation-delay", "-" + (performance.now() - existing.timestamp) + "ms");
+ else
+ existing.timestamp = performance.now();
+
+ existing.value = value;
+ existing.element = element;
+
+ element.addEventListener("animationend", existing.listener, {once: true});
+ element.classList.add("node-state-changed");
}
get pseudoClassesEnabled()
@@ -1769,13 +1784,6 @@
this.listItemElement.classList.toggle("pseudo-class-enabled", !!this.representedObject.enabledPseudoClasses.length);
}
- _fireDidChange()
- {
- super._fireDidChange();
-
- this._markNodeChanged();
- }
-
handleEvent(event)
{
if (event.type === "dragstart" && this._editing)