Index: Source/devtools/front_end/elements/PropertyChangeHighlighter.js |
diff --git a/Source/devtools/front_end/elements/PropertyChangeHighlighter.js b/Source/devtools/front_end/elements/PropertyChangeHighlighter.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..de57722a787354922344448bd24d722324ba8977 |
--- /dev/null |
+++ b/Source/devtools/front_end/elements/PropertyChangeHighlighter.js |
@@ -0,0 +1,122 @@ |
+// Copyright (c) 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+/** |
+ * @constructor |
+ * @param {!WebInspector.StylesSidebarPane} ssp |
+ */ |
+WebInspector.PropertyChangeHighlighter = function(ssp) |
+{ |
+ this._styleSidebarPane = ssp; |
+ WebInspector.targetManager.addModelListener(WebInspector.CSSStyleModel, WebInspector.CSSStyleModel.Events.LayoutEditorChange, this._onLayoutEditorChange, this); |
+ this._animationDuration = 1400; |
+ this._requestAnimationFrame = ssp.element.window().requestAnimationFrame; |
+} |
+ |
+WebInspector.PropertyChangeHighlighter.prototype = { |
+ /** |
+ * @param {!WebInspector.Event} event |
+ */ |
+ _onLayoutEditorChange: function(event) |
+ { |
+ this._target = event.target.target(); |
+ this._styleSheetId = event.data.id; |
+ this._changeRange = event.data.range; |
+ delete this._animationStart; |
+ if (!this._nextAnimation) |
+ this._nextAnimation = this._requestAnimationFrame.call(null, this.update.bind(this)); |
+ }, |
+ |
+ /** |
+ * @param {number} now |
+ */ |
+ update: function(now) |
+ { |
+ delete this._nextAnimation; |
+ if (!this._styleSheetId) |
+ return; |
+ var node = this._styleSidebarPane.node(); |
+ if (!node || this._target !== node.target()) { |
+ this._clear(); |
+ return; |
+ } |
+ |
+ var sectionBlocks = this._styleSidebarPane.sectionBlocks(); |
+ var foundSection = null; |
+ for (var block of sectionBlocks) { |
+ for (var section of block.sections) { |
+ var declaration = section.styleRule.style(); |
+ if (declaration.styleSheetId !== this._styleSheetId) |
+ continue; |
+ |
+ if (this._checkRanges(declaration.range, this._changeRange)) { |
+ foundSection = section; |
+ break; |
+ } |
+ } |
+ if (foundSection) |
+ break; |
+ } |
+ |
+ if (!foundSection) { |
+ this._clear(); |
+ return; |
+ } |
+ |
+ var treeElement = foundSection.propertiesTreeOutline.firstChild(); |
+ var foundTreeElement = null; |
+ while (treeElement) { |
+ if (treeElement.property.range && this._checkRanges(treeElement.property.range, this._changeRange)) { |
+ foundTreeElement = treeElement; |
+ break; |
+ } |
+ treeElement = treeElement.traverseNextTreeElement(false, null, true); |
+ } |
+ |
+ if (!foundTreeElement) { |
+ this._clear(); |
+ return; |
+ } |
+ |
+ if (!this._animationStart) |
+ this._animationStart = now; |
+ |
+ var animationProgress = (now - this._animationStart) / this._animationDuration; |
+ var valueElement = foundTreeElement.valueElement; |
+ valueElement.classList.toggle("css-update-highlight", animationProgress < 1); |
+ valueElement.classList.toggle("first-part", animationProgress < 0.2); |
+ |
+ if (animationProgress > 1) { |
+ this._clear(); |
+ delete valueElement.style.backgroundColor; |
+ return; |
+ } |
+ |
+ valueElement.style.backgroundColor = "rgba(158, 54, 153, " + (1 - animationProgress) + ")"; |
+ this._nextAnimation = this._requestAnimationFrame.call(null, this.update.bind(this)); |
+ }, |
+ |
+ _clear: function() |
+ { |
+ delete this._styleSheetId; |
+ delete this._changeRange; |
+ delete this._target; |
+ delete this._animationStart; |
+ }, |
+ |
+ /** |
+ * |
+ * @param {!CSSAgent.SourceRange} outterRange |
+ * @param {!CSSAgent.SourceRange} innerRange |
+ * @return {boolean} |
+ */ |
+ _checkRanges: function(outterRange, innerRange) |
+ { |
+ var startsBefore = outterRange.startLine < innerRange.startLine || (outterRange.startLine === innerRange.startLine && outterRange.startColumn <= innerRange.startColumn); |
+ // SSP might be outdated, so inner range will a bit bigger than outter. E.g.; "padding-left: 9px" -> "padding-left: 10px" |
+ var eps = 5; |
+ var endsAfter = outterRange.endLine > innerRange.endLine || (outterRange.endLine === innerRange.endLine && outterRange.endColumn + eps >= innerRange.endColumn); |
+ return startsBefore && endsAfter; |
+ } |
+} |