Bug 1499049 - (Part 6) Support !important in changed CSS property values; r=pbro
authorRazvan Caliman <rcaliman@mozilla.com>
Thu, 25 Oct 2018 11:06:56 +0000
changeset 443106 f7565ed1376dc6cc9ffa6b9f054a9a4aeaa2f480
parent 443105 0b04c98133b3d22225d8aeb7c4df325ccaa0fea3
child 443107 c4f23d37432644acf51200bb418a5029e66b0a68
push id34939
push usernerli@mozilla.com
push dateFri, 26 Oct 2018 15:47:55 +0000
treeherdermozilla-central@760a16bf0d2b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspbro
bugs1499049
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1499049 - (Part 6) Support !important in changed CSS property values; r=pbro Depends on D8722 Include the "!importat" priority flag when tracking changes to CSS declarations. Differential Revision: https://phabricator.services.mozilla.com/D8967
devtools/server/actors/styles.js
devtools/shared/css/parsing-utils.js
--- a/devtools/server/actors/styles.js
+++ b/devtools/server/actors/styles.js
@@ -1484,22 +1484,27 @@ var StyleRuleActor = protocol.ActorClass
   /**
    * Take an object with instructions to modify a CSS declaration and emit a
    * "track-change" event with normalized metadata which describes the change.
    *
    * @param {Object} change
    *        Data about a modification to a rule. @see |modifyProperties()|
    */
   logChange(change) {
-    const prevValue = this._declarations[change.index]
+    let prevValue = this._declarations[change.index]
       ? this._declarations[change.index].value
       : null;
     const prevName = this._declarations[change.index]
       ? this._declarations[change.index].name
       : null;
+    const prevPriority = this._declarations[change.index]
+      ? this._declarations[change.index].priority
+      : null;
+    // Append the "!important" string if defined in the previous priority flag.
+    prevValue = (prevValue && prevPriority) ? `${prevValue} !important` : prevValue;
 
     // Metadata about a change.
     const data = {};
     // Collect information about the rule's ancestors (@media, @supports, @keyframes).
     // Used to show context for this change in the UI and to match the rule for undo/redo.
     data.ancestors = this.ancestorRules.map(rule => {
       return {
         // Rule type as number defined by CSSRule.type (ex: 4, 7, 12)
@@ -1548,18 +1553,21 @@ var StyleRuleActor = protocol.ActorClass
     }
 
     switch (change.type) {
       case "set":
         // If `change.newName` is defined, use it because the property is being renamed.
         // Otherwise, a new declaration is being created or the value of an existing
         // declaration is being updated. In that case, use the provided `change.name`.
         const name = change.newName ? change.newName : change.name;
-        // Reuse the previous value when the property is being renamed.
-        const value = change.newName ? prevValue : change.value;
+        // Append the "!important" string if defined in the incoming priority flag.
+        const newValue = change.priority ? `${change.value} !important` : change.value;
+        // Reuse the previous value string, when the property is renamed.
+        // Otherwise, use the incoming value string.
+        const value = change.newName ? prevValue : newValue;
 
         data.add = { property: name, value };
         // If there is a previous value, log its removal together with the previous
         // property name. Using the previous name handles the case for renaming a property
         // and is harmless when updating an existing value (the name stays the same).
         data.remove = prevValue ? { property: prevName, value: prevValue } : null;
         break;
 
--- a/devtools/shared/css/parsing-utils.js
+++ b/devtools/shared/css/parsing-utils.js
@@ -870,16 +870,17 @@ RuleRewriter.prototype = {
    * @param {Number} index index of the property in the rule.
    * @param {String} name current name of the property
    * @param {Boolean} isEnabled true if the property should be enabled;
    *                        false if it should be disabled
    */
   setPropertyEnabled: function(index, name, isEnabled) {
     this.completeInitialization(index);
     const decl = this.decl;
+    const priority = decl.priority;
     let copyOffset = decl.offsets[1];
     if (isEnabled) {
       // Enable it.  First see if the comment start can be deleted.
       const commentStart = decl.commentOffsets[0];
       if (EMPTY_COMMENT_START_RX.test(this.result.substring(commentStart))) {
         this.result = this.result.substring(0, commentStart);
       } else {
         this.result += "*/ ";
@@ -913,19 +914,19 @@ RuleRewriter.prototype = {
       const declText = this.inputString.substring(decl.offsets[0],
                                                 decl.offsets[1]);
       this.result += "/*" + COMMENT_PARSING_HEURISTIC_BYPASS_CHAR +
         " " + escapeCSSComment(declText) + " */";
     }
     this.completeCopying(copyOffset);
 
     if (isEnabled) {
-      this.modifications.push({ type: "set", index, name, value: decl.value });
+      this.modifications.push({ type: "set", index, name, value: decl.value, priority });
     } else {
-      this.modifications.push({ type: "remove", index, name });
+      this.modifications.push({ type: "remove", index, name, priority });
     }
   },
 
   /**
    * Return a promise that will be resolved to the default indentation
    * of the rule.  This is a helper for internalCreateProperty.
    *
    * @return {Promise} a promise that will be resolved to a string