Upstream version 11.39.250.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / devtools / front_end / elements / StylesSidebarPane.js
index 2d41349..be7d22d 100644 (file)
@@ -47,8 +47,13 @@ WebInspector.StylesSidebarPane = function(computedStylePane, setPseudoClassCallb
     addButton.className = "pane-title-button add";
     addButton.id = "add-style-button-test-id";
     addButton.title = WebInspector.UIString("New Style Rule");
-    addButton.addEventListener("click", this._createNewRule.bind(this), false);
+    addButton.addEventListener("click", this._createNewRuleInViaInspectorStyleSheet.bind(this), false);
     this.titleElement.appendChild(addButton);
+    addButton.createChild("div", "long-click-glyph fill");
+
+    this._addButtonLongClickController = new WebInspector.LongClickController(addButton);
+    this._addButtonLongClickController.addEventListener(WebInspector.LongClickController.Events.LongClick, this._onAddButtonLongClick.bind(this));
+    this._addButtonLongClickController.enable();
 
     this._computedStylePane = computedStylePane;
     computedStylePane.setHostingPane(this);
@@ -56,6 +61,7 @@ WebInspector.StylesSidebarPane = function(computedStylePane, setPseudoClassCallb
     this.element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true);
     WebInspector.settings.colorFormat.addChangeListener(this._colorFormatSettingChanged.bind(this));
     WebInspector.settings.showUserAgentStyles.addChangeListener(this._showUserAgentStylesSettingChanged.bind(this));
+    WebInspector.settings.showInheritedComputedStyleProperties.addChangeListener(this._showInheritedComputedStyleChanged.bind(this));
 
     this._createElementStatePane();
     this.bodyElement.appendChild(this._elementStatePane);
@@ -77,22 +83,24 @@ WebInspector.StylesSidebarPane = function(computedStylePane, setPseudoClassCallb
 // FIXME: find a way of generating this mapping or getting it from combination of RenderStyleConstants and CSSSelector.cpp at
 // runtime.
 WebInspector.StylesSidebarPane.PseudoIdNames = [
-    "", "first-line", "first-letter", "before", "after", "selection", "", "-webkit-scrollbar", "-webkit-file-upload-button",
-    "-webkit-input-placeholder", "-webkit-slider-thumb", "-webkit-search-cancel-button", "-webkit-search-decoration",
-    "-webkit-search-results-decoration", "-webkit-search-results-button", "-webkit-media-controls-panel",
-    "-webkit-media-controls-play-button", "-webkit-media-controls-mute-button", "-webkit-media-controls-timeline",
-    "-webkit-media-controls-timeline-container", "-webkit-media-controls-volume-slider",
-    "-webkit-media-controls-volume-slider-container", "-webkit-media-controls-current-time-display",
-    "-webkit-media-controls-time-remaining-display", "-webkit-media-controls-fullscreen-button",
-    "-webkit-media-controls-toggle-closed-captions-button", "-webkit-media-controls-status-display", "-webkit-scrollbar-thumb",
-    "-webkit-scrollbar-button", "-webkit-scrollbar-track", "-webkit-scrollbar-track-piece", "-webkit-scrollbar-corner",
-    "-webkit-resizer", "-webkit-inner-spin-button", "-webkit-outer-spin-button"
+    "", "first-line", "first-letter", "before", "after", "backdrop", "selection", "", "-webkit-scrollbar",
+    "-webkit-scrollbar-thumb", "-webkit-scrollbar-button", "-webkit-scrollbar-track", "-webkit-scrollbar-track-piece",
+    "-webkit-scrollbar-corner", "-webkit-resizer"
 ];
 
 WebInspector.StylesSidebarPane._colorRegex = /((?:rgb|hsl)a?\([^)]+\)|#[0-9a-fA-F]{6}|#[0-9a-fA-F]{3}|\b\w+\b(?!-))/g;
 
 /**
+ * @enum {string}
+ */
+WebInspector.StylesSidebarPane.Events = {
+    SelectorEditingStarted: "SelectorEditingStarted",
+    SelectorEditingEnded: "SelectorEditingEnded"
+};
+
+/**
  * @param {!WebInspector.CSSProperty} property
+ * @return {!Element}
  */
 WebInspector.StylesSidebarPane.createExclamationMark = function(property)
 {
@@ -161,6 +169,102 @@ WebInspector.StylesSidebarPane._ignoreErrorsForProperty = function(property) {
 }
 
 WebInspector.StylesSidebarPane.prototype = {
+    _showInheritedComputedStyleChanged: function()
+    {
+        if (!this.sections || !this.sections[0])
+            return;
+        for (var i = 0; i < this.sections[0].length; ++i) {
+            var section = this.sections[0][i];
+            if (section instanceof WebInspector.ComputedStylePropertiesSection)
+                section.onShowInheritedChanged();
+        }
+    },
+
+    /**
+     * @param {!WebInspector.Event} event
+     */
+    _onAddButtonLongClick: function(event)
+    {
+        this._addButtonLongClickController.reset();
+        var cssModel = this._target.cssModel;
+        var headers = cssModel.styleSheetHeaders().filter(styleSheetResourceHeader);
+
+        /** @type {!Array.<{text: string, handler: function()}>} */
+        var contextMenuDescriptors = [];
+        for (var i = 0; i < headers.length; ++i) {
+            var header = headers[i];
+            var handler = this._createNewRuleInStyleSheet.bind(this, header);
+            contextMenuDescriptors.push({
+                text: WebInspector.displayNameForURL(header.resourceURL()),
+                handler: handler
+            });
+        }
+
+        contextMenuDescriptors.sort(compareDescriptors);
+
+        var contextMenu = new WebInspector.ContextMenu(/** @type {!Event} */(event.data));
+        for (var i = 0; i < contextMenuDescriptors.length; ++i) {
+            var descriptor = contextMenuDescriptors[i];
+            contextMenu.appendItem(descriptor.text, descriptor.handler);
+        }
+        if (!contextMenu.isEmpty())
+            contextMenu.appendSeparator();
+        contextMenu.appendItem("inspector-stylesheet", this._createNewRuleInViaInspectorStyleSheet.bind(this));
+        contextMenu.show();
+
+        /**
+         * @param {!{text: string, handler: function()}} descriptor1
+         * @param {!{text: string, handler: function()}} descriptor2
+         * @return {number}
+         */
+        function compareDescriptors(descriptor1, descriptor2)
+        {
+            return String.naturalOrderComparator(descriptor1.text, descriptor2.text);
+        }
+
+        /**
+         * @param {!WebInspector.CSSStyleSheetHeader} header
+         */
+        function styleSheetResourceHeader(header)
+        {
+            return !header.isViaInspector() && !header.isInline && header.resourceURL();
+        }
+    },
+
+    /**
+     * @param {!WebInspector.DOMNode} node
+     */
+    updateEditingSelectorForNode: function(node)
+    {
+        var selectorText = WebInspector.DOMPresentationUtils.simpleSelector(node);
+        if (!selectorText)
+            return;
+        this._editingSelectorSection.setSelectorText(selectorText);
+    },
+
+    /**
+     * @return {boolean}
+     */
+    isEditingSelector: function()
+    {
+        return !!this._editingSelectorSection;
+    },
+
+    /**
+     * @param {!WebInspector.StylePropertiesSection} section
+     */
+    _startEditingSelector: function(section)
+    {
+        this._editingSelectorSection = section;
+        this.dispatchEventToListeners(WebInspector.StylesSidebarPane.Events.SelectorEditingStarted);
+    },
+
+    _finishEditingSelector: function()
+    {
+        delete this._editingSelectorSection;
+        this.dispatchEventToListeners(WebInspector.StylesSidebarPane.Events.SelectorEditingEnded);
+    },
+
     /**
      * @param {!WebInspector.CSSRule} editedRule
      * @param {!WebInspector.TextRange} oldRange
@@ -168,13 +272,19 @@ WebInspector.StylesSidebarPane.prototype = {
      */
     _styleSheetRuleEdited: function(editedRule, oldRange, newRange)
     {
-        var styleRuleSections = this.sections[0];
-        for (var i = 1; i < styleRuleSections.length; ++i)
-            styleRuleSections[i]._styleSheetRuleEdited(editedRule, oldRange, newRange);
+        for (var pseudoId in this.sections) {
+            var styleRuleSections = this.sections[pseudoId];
+            for (var i = 0; i < styleRuleSections.length; ++i) {
+                var section = styleRuleSections[i];
+                if (section.computedStyle)
+                    continue;
+                section._styleSheetRuleEdited(editedRule, oldRange, newRange);
+            }
+        }
     },
 
     /**
-     * @param {?Event} event
+     * @param {!Event} event
      */
     _contextMenuEventFired: function(event)
     {
@@ -397,6 +507,8 @@ WebInspector.StylesSidebarPane.prototype = {
                 this._rebuildUpdate();
                 return;
             }
+            if (matchedResult && this._node === node)
+                this._nodeStylesUpdatedForTest(node, true);
         }
 
         /**
@@ -420,7 +532,7 @@ WebInspector.StylesSidebarPane.prototype = {
         if (this._computedStylePane.isShowing())
             this._target.cssModel.getComputedStyleAsync(node.id, computedCallback);
         this._target.cssModel.getInlineStylesAsync(node.id, inlineCallback);
-        this._target.cssModel.getMatchedStylesAsync(node.id, true, true, stylesCallback.bind(this));
+        this._target.cssModel.getMatchedStylesAsync(node.id, false, false, stylesCallback.bind(this));
     },
 
     /**
@@ -523,7 +635,7 @@ WebInspector.StylesSidebarPane.prototype = {
             // Add rules in reverse order to match the cascade order.
             for (var j = pseudoElementCSSRules.rules.length - 1; j >= 0; --j) {
                 var rule = pseudoElementCSSRules.rules[j];
-                styleRules.push({ style: rule.style, selectorText: rule.selectorText, media: rule.media, sourceURL: rule.resourceURL(), rule: rule, editable: !!(rule.style && rule.style.styleSheetId) });
+                styleRules.push({ style: rule.style, selectorText: rule.selectorText, media: rule.media, rule: rule, editable: !!(rule.style && rule.style.styleSheetId) });
             }
             usedProperties = {};
             this._markUsedProperties(styleRules, usedProperties);
@@ -532,7 +644,6 @@ WebInspector.StylesSidebarPane.prototype = {
 
         if (this._filterRegex)
             this._updateFilter(false);
-        this._nodeStylesUpdatedForTest(node, true);
     },
 
     _nodeStylesUpdatedForTest: function(node, rebuild)
@@ -593,7 +704,7 @@ WebInspector.StylesSidebarPane.prototype = {
                 addedAttributesStyle = true;
                 addAttributesStyle();
             }
-            styleRules.push({ style: rule.style, selectorText: rule.selectorText, media: rule.media, sourceURL: rule.resourceURL(), rule: rule, editable: !!(rule.style && rule.style.styleSheetId) });
+            styleRules.push({ style: rule.style, selectorText: rule.selectorText, media: rule.media, rule: rule, editable: !!(rule.style && rule.style.styleSheetId) });
         }
 
         if (!addedAttributesStyle)
@@ -633,7 +744,7 @@ WebInspector.StylesSidebarPane.prototype = {
                     insertInheritedNodeSeparator(parentNode);
                     separatorInserted = true;
                 }
-                styleRules.push({ style: rule.style, selectorText: rule.selectorText, media: rule.media, sourceURL: rule.resourceURL(), rule: rule, isInherited: true, parentNode: parentNode, editable: !!(rule.style && rule.style.styleSheetId) });
+                styleRules.push({ style: rule.style, selectorText: rule.selectorText, media: rule.media, rule: rule, isInherited: true, parentNode: parentNode, editable: !!(rule.style && rule.style.styleSheetId) });
             }
             parentNode = parentNode.parentNode;
         }
@@ -729,7 +840,7 @@ WebInspector.StylesSidebarPane.prototype = {
                 separatorElement.className = "sidebar-separator";
                 if (styleRule.node) {
                     var link = WebInspector.DOMPresentationUtils.linkifyNodeReference(styleRule.node);
-                    separatorElement.appendChild(document.createTextNode(WebInspector.UIString("Inherited from") + " "));
+                    separatorElement.createTextChild(WebInspector.UIString("Inherited from") + " ");
                     separatorElement.appendChild(link);
                     if (!sections.inheritedPropertiesSeparatorElement)
                         sections.inheritedPropertiesSeparatorElement = separatorElement;
@@ -789,26 +900,52 @@ WebInspector.StylesSidebarPane.prototype = {
         }
     },
 
-    _createNewRule: function(event)
+    /**
+     * @param {?Event} event
+     */
+    _createNewRuleInViaInspectorStyleSheet: function(event)
     {
-        event.consume();
-        this.expand();
-        this.addBlankSection().startEditingSelector();
+        var cssModel = this._target.cssModel;
+        cssModel.requestViaInspectorStylesheet(this._node, this._createNewRuleInStyleSheet.bind(this));
     },
 
     /**
-     * @return {!WebInspector.BlankStylePropertiesSection}
+     * @param {?WebInspector.CSSStyleSheetHeader} styleSheetHeader
      */
-    addBlankSection: function()
+    _createNewRuleInStyleSheet: function(styleSheetHeader)
     {
-        var blankSection = new WebInspector.BlankStylePropertiesSection(this, this._node ? WebInspector.DOMPresentationUtils.simpleSelector(this._node) : "");
+        if (!styleSheetHeader)
+            return;
+        styleSheetHeader.requestContent(onStyleSheetContent.bind(this, styleSheetHeader.id));
 
-        var elementStyleSection = this.sections[0][1];
-        this._sectionsContainer.insertBefore(blankSection.element, elementStyleSection.element.nextSibling);
+        /**
+         * @param {string} styleSheetId
+         * @param {string} text
+         * @this {WebInspector.StylesSidebarPane}
+         */
+        function onStyleSheetContent(styleSheetId, text)
+        {
+            var lines = text.split("\n");
+            var range = WebInspector.TextRange.createFromLocation(lines.length - 1, lines[lines.length - 1].length);
+            this._addBlankSection(this.sections[0][1], styleSheetId, range);
+        }
+    },
 
-        this.sections[0].splice(2, 0, blankSection);
+    /**
+     * @param {!WebInspector.StylePropertiesSection} insertAfterSection
+     * @param {string} styleSheetId
+     * @param {!WebInspector.TextRange} ruleLocation
+     */
+    _addBlankSection: function(insertAfterSection, styleSheetId, ruleLocation)
+    {
+        this.expand();
+        var blankSection = new WebInspector.BlankStylePropertiesSection(this, this._node ? WebInspector.DOMPresentationUtils.simpleSelector(this._node) : "", styleSheetId, ruleLocation, insertAfterSection.rule);
+
+        this._sectionsContainer.insertBefore(blankSection.element, insertAfterSection.element.nextSibling);
 
-        return blankSection;
+        var index = this.sections[0].indexOf(insertAfterSection);
+        this.sections[0].splice(index + 1, 0, blankSection);
+        blankSection.startEditingSelector();
     },
 
     removeSection: function(section)
@@ -844,7 +981,7 @@ WebInspector.StylesSidebarPane.prototype = {
         this._elementStatePane.inputs = inputs;
 
         /**
-         * @param {?Event} event
+         * @param {!Event} event
          * @this {WebInspector.StylesSidebarPane}
          */
         function clickListener(event)
@@ -870,7 +1007,7 @@ WebInspector.StylesSidebarPane.prototype = {
             input.addEventListener("click", clickListener.bind(this), false);
             inputs.push(input);
             label.appendChild(input);
-            label.appendChild(document.createTextNode(":" + state));
+            label.createTextChild(":" + state);
             td.appendChild(label);
             return td;
         }
@@ -919,7 +1056,7 @@ WebInspector.StylesSidebarPane.prototype = {
         input.addEventListener("input", boundSearchHandler, false);
 
         /**
-         * @param {?Event} event
+         * @param {!Event} event
          */
         function keydownHandler(event)
         {
@@ -1107,6 +1244,12 @@ WebInspector.StylePropertiesSection = function(parentPane, styleRule, editable,
     closeBrace.textContent = "}";
     this.element.appendChild(closeBrace);
 
+    if (this.editable && this.rule) {
+        var newRuleButton = closeBrace.createChild("div", "sidebar-pane-button-new-rule");
+        newRuleButton.title = WebInspector.UIString("Insert Style Rule");
+        newRuleButton.addEventListener("click", this._onNewRuleClick.bind(this), false);
+    }
+
     this._selectorElement.addEventListener("click", this._handleSelectorClick.bind(this), false);
     this.element.addEventListener("mousedown", this._handleEmptySpaceMouseDown.bind(this), false);
     this.element.addEventListener("click", this._handleEmptySpaceClick.bind(this), false);
@@ -1146,6 +1289,16 @@ WebInspector.StylePropertiesSection = function(parentPane, styleRule, editable,
 
 WebInspector.StylePropertiesSection.prototype = {
     /**
+     * @param {?Event} event
+     */
+    _onNewRuleClick: function(event)
+    {
+        event.consume();
+        var range = WebInspector.TextRange.createFromLocation(this.rule.style.range.endLine, this.rule.style.range.endColumn + 1);
+        this._parentPane._addBlankSection(this, this.rule.styleSheetId, range);
+    },
+
+    /**
      * @param {!WebInspector.CSSRule} editedRule
      * @param {!WebInspector.TextRange} oldRange
      * @param {!WebInspector.TextRange} newRange
@@ -1155,20 +1308,20 @@ WebInspector.StylePropertiesSection.prototype = {
         if (!this.rule || !this.rule.styleSheetId)
             return;
         if (this.rule !== editedRule)
-            this.rule.sourceStyleSheetEdited(this.rule.styleSheetId, oldRange, newRange);
+            this.rule.sourceStyleSheetEdited(editedRule.styleSheetId, oldRange, newRange);
         this._updateMediaList();
         this._updateRuleOrigin();
     },
 
     /**
-     * @param {!Object} styleRule
+     * @param {?Array.<!WebInspector.CSSMedia>} mediaRules
      */
-    _createMediaList: function(styleRule)
+    _createMediaList: function(mediaRules)
     {
-        if (!styleRule.media)
+        if (!mediaRules)
             return;
-        for (var i = styleRule.media.length - 1; i >= 0; --i) {
-            var media = styleRule.media[i];
+        for (var i = mediaRules.length - 1; i >= 0; --i) {
+            var media = mediaRules[i];
             var mediaDataElement = this._mediaListElement.createChild("div", "media");
             var mediaText;
             switch (media.source) {
@@ -1186,25 +1339,7 @@ WebInspector.StylePropertiesSection.prototype = {
 
             if (media.sourceURL) {
                 var refElement = mediaDataElement.createChild("div", "subtitle");
-                var rawLocation;
-                var mediaHeader;
-                if (media.range) {
-                    mediaHeader = media.header();
-                    if (mediaHeader) {
-                        var lineNumber = media.lineNumberInSource();
-                        var columnNumber = media.columnNumberInSource();
-                        console.assert(typeof lineNumber !== "undefined" && typeof columnNumber !== "undefined");
-                        rawLocation = new WebInspector.CSSLocation(this._parentPane._target, media.sourceURL, lineNumber, columnNumber);
-                    }
-                }
-
-                var anchor;
-                if (rawLocation)
-                    anchor = this._parentPane._linkifier.linkifyCSSLocation(mediaHeader.id, rawLocation);
-                else {
-                    // The "linkedStylesheet" case.
-                    anchor = WebInspector.linkifyResourceAsNode(media.sourceURL, undefined, "subtitle", media.sourceURL);
-                }
+                var anchor = this._parentPane._linkifier.linkifyMedia(media);
                 anchor.style.float = "right";
                 refElement.appendChild(anchor);
             }
@@ -1218,7 +1353,7 @@ WebInspector.StylePropertiesSection.prototype = {
     _updateMediaList: function()
     {
         this._mediaListElement.removeChildren();
-        this._createMediaList(this.styleRule);
+        this._createMediaList(this.styleRule.media);
     },
 
     collapse: function()
@@ -1338,9 +1473,14 @@ WebInspector.StylePropertiesSection.prototype = {
         if (this._afterUpdate) {
             this._afterUpdate(this);
             delete this._afterUpdate;
+            this._afterUpdateFinishedForTest();
         }
     },
 
+    _afterUpdateFinishedForTest: function()
+    {
+    },
+
     onpopulate: function()
     {
         var style = this.styleRule.style;
@@ -1443,11 +1583,10 @@ WebInspector.StylePropertiesSection.prototype = {
         var currentMatch = 0;
         for (var i = 0; i < selectors.length ; ++i) {
             if (i)
-                fragment.appendChild(document.createTextNode(", "));
+                fragment.createTextChild(", ");
             var isSelectorMatching = matchingSelectors[currentMatch] === i;
             if (isSelectorMatching)
                 ++currentMatch;
-            var rawLocation = new WebInspector.CSSLocation(this._parentPane._target, rule.sourceURL, rule.lineNumberInSource(i), rule.columnNumberInSource(i));
             var matchingSelectorClass = isSelectorMatching ? " selector-matches" : "";
             var selectorElement = document.createElement("span");
             selectorElement.className = "simple-selector" + matchingSelectorClass;
@@ -1484,8 +1623,10 @@ WebInspector.StylePropertiesSection.prototype = {
     {
         if (this._checkWillCancelEditing() || !this.editable)
             return;
-        if (event.target === this._selectorContainer)
+        if (event.target === this._selectorContainer) {
             this.addNewBlankProperty(0).startEditing();
+            event.consume(true);
+        }
     },
 
     /**
@@ -1505,7 +1646,39 @@ WebInspector.StylePropertiesSection.prototype = {
         return item;
     },
 
-    _createRuleOriginNode: function()
+    /**
+     * @param {?WebInspector.CSSRule} rule
+     * @param {!WebInspector.TextRange=} ruleLocation
+     * @return {!Node}
+     */
+    _createRuleOriginNode: function(rule, ruleLocation)
+    {
+        if (!rule)
+            return document.createTextNode("");
+
+        if (!ruleLocation) {
+            var firstMatchingIndex = rule.matchingSelectors && rule.matchingSelectors.length ? rule.matchingSelectors[0] : 0;
+            ruleLocation = rule.selectors[firstMatchingIndex].range;
+        }
+
+        if (ruleLocation && rule.styleSheetId)
+            return this._linkifyRuleLocation(rule.styleSheetId, ruleLocation);
+
+        if (rule.isUserAgent)
+            return document.createTextNode(WebInspector.UIString("user agent stylesheet"));
+        if (rule.isUser)
+            return document.createTextNode(WebInspector.UIString("user stylesheet"));
+        if (rule.isViaInspector)
+            return document.createTextNode(WebInspector.UIString("via inspector"));
+        return document.createTextNode("");
+    },
+
+    /**
+     * @param {string} styleSheetId
+     * @param {!WebInspector.TextRange} ruleLocation
+     * @return {!Node}
+     */
+    _linkifyRuleLocation: function(styleSheetId, ruleLocation)
     {
         /**
          * @param {string} url
@@ -1520,22 +1693,12 @@ WebInspector.StylePropertiesSection.prototype = {
             return link;
         }
 
-        if (this.styleRule.sourceURL) {
-            var firstMatchingIndex = this.styleRule.rule.matchingSelectors && this.rule.matchingSelectors.length ? this.rule.matchingSelectors[0] : 0;
-            var matchingSelectorLocation = new WebInspector.CSSLocation(this._parentPane._target, this.styleRule.sourceURL, this.rule.lineNumberInSource(firstMatchingIndex), this.rule.columnNumberInSource(firstMatchingIndex));
-            return this._parentPane._linkifier.linkifyCSSLocation(this.rule.styleSheetId, matchingSelectorLocation) || linkifyUncopyable(this.styleRule.sourceURL, this.rule.lineNumberInSource());
-        }
-
-        if (!this.rule)
-            return document.createTextNode("");
-
-        if (this.rule.isUserAgent)
-            return document.createTextNode(WebInspector.UIString("user agent stylesheet"));
-        if (this.rule.isUser)
-            return document.createTextNode(WebInspector.UIString("user stylesheet"));
-        if (this.rule.isViaInspector)
-            return document.createTextNode(WebInspector.UIString("via inspector"));
-        return document.createTextNode("");
+        var styleSheetHeader = this._parentPane._target.cssModel.styleSheetHeaderForId(styleSheetId);
+        var sourceURL = styleSheetHeader.resourceURL();
+        var lineNumber = styleSheetHeader.lineNumberInSource(ruleLocation.startLine);
+        var columnNumber = styleSheetHeader.columnNumberInSource(ruleLocation.startLine, ruleLocation.startColumn);
+        var matchingSelectorLocation = new WebInspector.CSSLocation(this._parentPane._target, styleSheetId, sourceURL, lineNumber, columnNumber);
+        return this._parentPane._linkifier.linkifyCSSLocation(matchingSelectorLocation) || linkifyUncopyable(sourceURL, 0);
     },
 
     _handleEmptySpaceMouseDown: function()
@@ -1560,15 +1723,18 @@ WebInspector.StylePropertiesSection.prototype = {
         }
         this.expand();
         this.addNewBlankProperty().startEditing();
+        event.consume(true)
     },
 
     _handleSelectorClick: function(event)
     {
         if (WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) && this.navigable && event.target.classList.contains("simple-selector")) {
             var index = event.target._selectorIndex;
-            var styleSheetHeader = this._parentPane._target.cssModel.styleSheetHeaderForId(this.rule.styleSheetId);
-            var uiLocation = styleSheetHeader.rawLocationToUILocation(this.rule.lineNumberInSource(index), this.rule.columnNumberInSource(index));
+            var target = this._parentPane._target;
+            var rawLocation = new WebInspector.CSSLocation(target, this.rule.styleSheetId, this.rule.sourceURL, this.rule.lineNumberInSource(index), this.rule.columnNumberInSource(index));
+            var uiLocation = WebInspector.cssWorkspaceBinding.rawLocationToUILocation(rawLocation);
             WebInspector.Revealer.reveal(uiLocation);
+            event.consume(true);
             return;
         }
         this._startEditingOnMouseEvent();
@@ -1601,11 +1767,37 @@ WebInspector.StylePropertiesSection.prototype = {
         element.scrollIntoViewIfNeeded(false);
         element.textContent = element.textContent; // Reset selector marks in group.
 
-        var config = new WebInspector.InplaceEditor.Config(this.editingSelectorCommitted.bind(this), this.editingSelectorCancelled.bind(this));
+        var config = new WebInspector.InplaceEditor.Config(this.editingSelectorCommitted.bind(this), this.editingSelectorCancelled.bind(this), undefined, this._editingSelectorBlurHandler.bind(this));
         WebInspector.InplaceEditor.startEditing(this._selectorElement, config);
 
         window.getSelection().setBaseAndExtent(element, 0, element, 1);
         this._parentPane._isEditingStyle = true;
+        this._parentPane._startEditingSelector(this);
+    },
+
+    /**
+     * @param {string} text
+     */
+    setSelectorText: function(text)
+    {
+        this._selectorElement.textContent = text;
+        window.getSelection().setBaseAndExtent(this._selectorElement, 0, this._selectorElement, 1);
+    },
+
+    /**
+     * @param {!Element} editor
+     * @param {!Event} blurEvent
+     * @return {boolean}
+     */
+    _editingSelectorBlurHandler: function(editor, blurEvent)
+    {
+        if (!blurEvent.relatedTarget)
+            return true;
+        var elementTreeOutline = blurEvent.relatedTarget.enclosingNodeOrSelfWithClass("elements-tree-outline");
+        if (!elementTreeOutline)
+            return true;
+        editor.focus();
+        return false;
     },
 
     _moveEditorFromSelector: function(moveDirection)
@@ -1646,8 +1838,6 @@ WebInspector.StylePropertiesSection.prototype = {
             return;
         }
 
-        var selectedNode = this._parentPane._node;
-
         /**
          * @param {!WebInspector.CSSRule} newRule
          * @this {WebInspector.StylePropertiesSection}
@@ -1665,9 +1855,9 @@ WebInspector.StylePropertiesSection.prototype = {
 
             var oldSelectorRange = this.rule.selectorRange;
             this.rule = newRule;
-            this.styleRule = { section: this, style: newRule.style, selectorText: newRule.selectorText, media: newRule.media, sourceURL: newRule.resourceURL(), rule: newRule };
+            this.styleRule = { section: this, style: newRule.style, selectorText: newRule.selectorText, media: newRule.media, rule: newRule };
 
-            this._parentPane.update(selectedNode);
+            this._parentPane._refreshUpdate(this, false);
             this._parentPane._styleSheetRuleEdited(this.rule, oldSelectorRange, this.rule.selectorRange);
 
             finishOperationAndMoveEditor.call(this, moveDirection);
@@ -1684,18 +1874,20 @@ WebInspector.StylePropertiesSection.prototype = {
 
         // This gets deleted in finishOperationAndMoveEditor(), which is called both on success and failure.
         this._parentPane._userOperation = true;
+        var selectedNode = this._parentPane._node;
         this._parentPane._target.cssModel.setRuleSelector(this.rule, selectedNode ? selectedNode.id : 0, newContent, successCallback.bind(this), finishOperationAndMoveEditor.bind(this, moveDirection));
     },
 
     _updateRuleOrigin: function()
     {
         this._selectorRefElement.removeChildren();
-        this._selectorRefElement.appendChild(this._createRuleOriginNode());
+        this._selectorRefElement.appendChild(this._createRuleOriginNode(this.rule));
     },
 
     _editingSelectorEnded: function()
     {
         delete this._parentPane._isEditingStyle;
+        this._parentPane._finishEditingSelector();
     },
 
     editingSelectorCancelled: function()
@@ -1720,33 +1912,11 @@ WebInspector.StylePropertiesSection.prototype = {
 WebInspector.ComputedStylePropertiesSection = function(stylesPane, styleRule, usedProperties)
 {
     WebInspector.PropertiesSection.call(this, "");
-
-    var subtitle = this.headerElement.createChild("div", "sidebar-pane-subtitle vbox");
-    var showInheritedCheckbox = new WebInspector.Checkbox(WebInspector.UIString("Show inherited properties"), "hbox");
-    subtitle.appendChild(showInheritedCheckbox.element);
-
     this._hasFreshContent = false;
-
-    /**
-     * @this {WebInspector.ComputedStylePropertiesSection}
-     */
-    function showInheritedToggleFunction()
-    {
-        var showInherited = showInheritedCheckbox.checked;
-        WebInspector.settings.showInheritedComputedStyleProperties.set(showInherited);
-        if (showInherited)
-            this.element.classList.add("styles-show-inherited");
-        else
-            this.element.classList.remove("styles-show-inherited");
-    }
-
-    showInheritedCheckbox.addEventListener(showInheritedToggleFunction.bind(this));
-
     this.element.className = "styles-section monospace read-only computed-style";
-    if (WebInspector.settings.showInheritedComputedStyleProperties.get()) {
-        this.element.classList.add("styles-show-inherited");
-        showInheritedCheckbox.checked = true;
-    }
+
+    this.headerElement.appendChild(WebInspector.ComputedStylePropertiesSection._showInheritedCheckbox());
+    this.onShowInheritedChanged();
 
     this._stylesPane = stylesPane;
     this.styleRule = styleRule;
@@ -1757,7 +1927,24 @@ WebInspector.ComputedStylePropertiesSection = function(stylesPane, styleRule, us
     this._expandedPropertyNames = {};
 }
 
+/**
+ * @return {!Element}
+ */
+WebInspector.ComputedStylePropertiesSection._showInheritedCheckbox = function()
+{
+    if (!WebInspector.ComputedStylePropertiesSection._showInheritedCheckboxElement) {
+        WebInspector.ComputedStylePropertiesSection._showInheritedCheckboxElement = WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Show inherited properties"), WebInspector.settings.showInheritedComputedStyleProperties, true);
+        WebInspector.ComputedStylePropertiesSection._showInheritedCheckboxElement.classList.add("checkbox-with-label");
+    }
+    return WebInspector.ComputedStylePropertiesSection._showInheritedCheckboxElement;
+}
+
 WebInspector.ComputedStylePropertiesSection.prototype = {
+    onShowInheritedChanged: function()
+    {
+        this.element.classList.toggle("styles-show-inherited", WebInspector.settings.showInheritedComputedStyleProperties.get());
+    },
+
     collapse: function(dontRememberState)
     {
         // Overriding with empty body.
@@ -1835,10 +2022,10 @@ WebInspector.ComputedStylePropertiesSection.prototype = {
                     var selector = fragment.createChild("span");
                     selector.style.color = "gray";
                     selector.textContent = section.styleRule.selectorText;
-                    fragment.appendChild(document.createTextNode(" - " + property.value + " "));
+                    fragment.createTextChild(" - " + property.value + " ");
                     var subtitle = fragment.createChild("span");
                     subtitle.style.float = "right";
-                    subtitle.appendChild(section._createRuleOriginNode());
+                    subtitle.appendChild(section._createRuleOriginNode(section.rule));
                     var childElement = new TreeElement(fragment, null, false);
                     treeElement.appendChild(childElement);
                     if (property.inactive || section.isPropertyOverloaded(property.name))
@@ -1868,14 +2055,43 @@ WebInspector.ComputedStylePropertiesSection.prototype = {
  * @extends {WebInspector.StylePropertiesSection}
  * @param {!WebInspector.StylesSidebarPane} stylesPane
  * @param {string} defaultSelectorText
+ * @param {string} styleSheetId
+ * @param {!WebInspector.TextRange} ruleLocation
+ * @param {!WebInspector.CSSRule=} insertAfterRule
  */
-WebInspector.BlankStylePropertiesSection = function(stylesPane, defaultSelectorText)
+WebInspector.BlankStylePropertiesSection = function(stylesPane, defaultSelectorText, styleSheetId, ruleLocation, insertAfterRule)
 {
-    WebInspector.StylePropertiesSection.call(this, stylesPane, {selectorText: defaultSelectorText, rule: {isViaInspector: true}}, true, false);
+    var styleSheetHeader = WebInspector.cssModel.styleSheetHeaderForId(styleSheetId);
+    WebInspector.StylePropertiesSection.call(this, stylesPane, { selectorText: defaultSelectorText }, true, false);
+    this._ruleLocation = ruleLocation;
+    this._styleSheetId = styleSheetId;
+    this._selectorRefElement.removeChildren();
+    this._selectorRefElement.appendChild(this._linkifyRuleLocation(styleSheetId, this._actualRuleLocation()));
+    if (insertAfterRule)
+        this._createMediaList(insertAfterRule.media);
     this.element.classList.add("blank-section");
 }
 
 WebInspector.BlankStylePropertiesSection.prototype = {
+    /**
+     * @return {!WebInspector.TextRange}
+     */
+    _actualRuleLocation: function()
+    {
+        var prefix = this._rulePrefix();
+        var lines = prefix.split("\n");
+        var editRange = new WebInspector.TextRange(0, 0, lines.length - 1, lines.peekLast().length);
+        return this._ruleLocation.rebaseAfterTextEdit(WebInspector.TextRange.createFromLocation(0, 0), editRange);
+    },
+
+    /**
+     * @return {string}
+     */
+    _rulePrefix: function()
+    {
+        return this._ruleLocation.startLine === 0 && this._ruleLocation.startColumn === 0 ? "" : "\n\n";
+    },
+
     get isBlank()
     {
         return !this._normal;
@@ -1901,14 +2117,20 @@ WebInspector.BlankStylePropertiesSection.prototype = {
         function successCallback(newRule)
         {
             var doesSelectorAffectSelectedNode = newRule.matchingSelectors.length > 0;
-            var styleRule = { section: this, style: newRule.style, selectorText: newRule.selectorText, sourceURL: newRule.resourceURL(), rule: newRule };
-            this.makeNormal(styleRule);
+            var styleRule = { media: newRule.media, section: this, style: newRule.style, selectorText: newRule.selectorText, rule: newRule };
+            this._makeNormal(styleRule);
 
             if (!doesSelectorAffectSelectedNode) {
                 this.noAffect = true;
                 this.element.classList.add("no-affect");
             }
 
+            var ruleTextLines = ruleText.split("\n");
+            var startLine = this._ruleLocation.startLine;
+            var startColumn = this._ruleLocation.startColumn;
+            var newRange = new WebInspector.TextRange(startLine, startColumn, startLine + ruleTextLines.length - 1, startColumn + ruleTextLines[ruleTextLines.length - 1].length);
+            this._parentPane._styleSheetRuleEdited(newRule, this._ruleLocation, newRange);
+
             this._updateRuleOrigin();
             this.expand();
             if (this.element.parentElement) // Might have been detached already.
@@ -1924,20 +2146,8 @@ WebInspector.BlankStylePropertiesSection.prototype = {
         this._parentPane._userOperation = true;
 
         var cssModel = this._parentPane._target.cssModel;
-        cssModel.requestViaInspectorStylesheet(this._parentPane._node, viaInspectorCallback.bind(this));
-
-        /**
-         * @this {WebInspector.BlankStylePropertiesSection}
-         * @param {?WebInspector.CSSStyleSheetHeader} styleSheetHeader
-         */
-        function viaInspectorCallback(styleSheetHeader)
-        {
-            if (!styleSheetHeader) {
-                this.editingSelectorCancelled();
-                return;
-            }
-            cssModel.addRule(styleSheetHeader.id, this._parentPane._node, newContent, successCallback.bind(this), this.editingSelectorCancelled.bind(this));
-        }
+        var ruleText = this._rulePrefix() + newContent + " {}";
+        cssModel.addRule(this._styleSheetId, this._parentPane._node, ruleText, this._ruleLocation, successCallback.bind(this), this.editingSelectorCancelled.bind(this));
     },
 
     editingSelectorCancelled: function()
@@ -1952,7 +2162,7 @@ WebInspector.BlankStylePropertiesSection.prototype = {
         this._parentPane.removeSection(this);
     },
 
-    makeNormal: function(styleRule)
+    _makeNormal: function(styleRule)
     {
         this.element.classList.remove("blank-section");
         this.styleRule = styleRule;
@@ -2117,6 +2327,9 @@ WebInspector.StylePropertyTreeElementBase.prototype = {
 
         /**
          * @param {!RegExp} regex
+         * @param {function(string):!Node} processor
+         * @param {?function(string):!Node} nextProcessor
+         * @param {string} valueText
          * @return {!DocumentFragment}
          */
         function processValue(regex, processor, nextProcessor, valueText)
@@ -2129,7 +2342,7 @@ WebInspector.StylePropertyTreeElementBase.prototype = {
                     if (nextProcessor)
                         container.appendChild(nextProcessor(items[i]));
                     else
-                        container.appendChild(document.createTextNode(items[i]));
+                        container.createTextChild(items[i]);
                 } else {
                     var processedNode = processor(items[i]);
                     if (processedNode)
@@ -2152,15 +2365,15 @@ WebInspector.StylePropertyTreeElementBase.prototype = {
             if (match)
                 hrefUrl = match[1];
             var container = document.createDocumentFragment();
-            container.appendChild(document.createTextNode("url("));
-            if (this._styleRule.sourceURL)
-                hrefUrl = WebInspector.ParsedURL.completeURL(this._styleRule.sourceURL, hrefUrl);
+            container.createTextChild("url(");
+            if (this._styleRule.rule && this._styleRule.rule.resourceURL())
+                hrefUrl = WebInspector.ParsedURL.completeURL(this._styleRule.rule.resourceURL(), hrefUrl);
             else if (this.node())
                 hrefUrl = this.node().resolveURL(hrefUrl);
             var hasResource = hrefUrl && !!WebInspector.resourceForURL(hrefUrl);
             // FIXME: WebInspector.linkifyURLAsNode() should really use baseURI.
             container.appendChild(WebInspector.linkifyURLAsNode(hrefUrl || url, url, undefined, !hasResource));
-            container.appendChild(document.createTextNode(")"));
+            container.createTextChild(")");
             return container;
         }
 
@@ -2179,10 +2392,10 @@ WebInspector.StylePropertyTreeElementBase.prototype = {
         if (this.disabled)
             this.listItemElement.createChild("span", "styles-clipboard-only").createTextChild("/* ");
         this.listItemElement.appendChild(nameElement);
-        this.listItemElement.appendChild(document.createTextNode(": "));
+        this.listItemElement.createTextChild(": ");
         this.listItemElement.appendChild(this._expandElement);
         this.listItemElement.appendChild(valueElement);
-        this.listItemElement.appendChild(document.createTextNode(";"));
+        this.listItemElement.createTextChild(";");
         if (this.disabled)
             this.listItemElement.createChild("span", "styles-clipboard-only").createTextChild(" */");
 
@@ -2209,6 +2422,7 @@ WebInspector.StylePropertyTreeElementBase.prototype = {
      * @param {!Element} nameElement
      * @param {!Element} valueElement
      * @param {string} text
+     * @return {!Node}
      */
     _processColor: function(nameElement, valueElement, text)
     {
@@ -2268,7 +2482,7 @@ WebInspector.StylePropertyTreeElementBase.prototype = {
         }
 
         /**
-         * @param {?Event} e
+         * @param {!Event} e
          * @this {WebInspector.StylePropertyTreeElementBase}
          */
         function swatchClick(e)
@@ -2293,7 +2507,7 @@ WebInspector.StylePropertyTreeElementBase.prototype = {
                 spectrum.addEventListener(WebInspector.Spectrum.Events.ColorChanged, boundSpectrumChanged);
                 spectrumHelper.addEventListener(WebInspector.SpectrumPopupHelper.Events.Hidden, boundSpectrumHidden);
 
-                scrollerElement = colorSwatch.element.enclosingNodeOrSelfWithClass("scroll-target");
+                scrollerElement = colorSwatch.element.enclosingNodeOrSelfWithClass("style-panes-wrapper");
                 if (scrollerElement)
                     scrollerElement.addEventListener("scroll", repositionSpectrum, false);
                 else
@@ -2302,7 +2516,10 @@ WebInspector.StylePropertyTreeElementBase.prototype = {
         }
 
         var colorValueElement = document.createElement("span");
-        colorValueElement.textContent = color.toString(format);
+        if (format === WebInspector.Color.Format.Original)
+            colorValueElement.textContent = text;
+        else
+            colorValueElement.textContent = color.toString(format);
 
         /**
          * @param {string} curFormat
@@ -2467,8 +2684,12 @@ WebInspector.StylePropertyTreeElement = function(stylesPane, styleRule, style, p
     WebInspector.StylePropertyTreeElementBase.call(this, styleRule, style, property, inherited, overloaded, isShorthand);
     this._parentPane = stylesPane;
     this.isShorthand = isShorthand;
+    this._applyStyleThrottler = new WebInspector.Throttler(0);
 }
 
+/** @typedef {{expanded: boolean, hasChildren: boolean, isEditingName: boolean, previousContent: string}} */
+WebInspector.StylePropertyTreeElement.Context;
+
 WebInspector.StylePropertyTreeElement.prototype = {
     /**
      * @return {?WebInspector.DOMNode}
@@ -2533,7 +2754,7 @@ WebInspector.StylePropertyTreeElement.prototype = {
     },
 
     /**
-     * @param {?Event} event
+     * @param {!Event} event
      */
     toggleEnabled: function(event)
     {
@@ -2664,7 +2885,7 @@ WebInspector.StylePropertyTreeElement.prototype = {
     {
         console.assert(this.section().navigable);
         var propertyNameClicked = element === this.nameElement;
-        WebInspector.Revealer.reveal(this.property.uiLocation(propertyNameClicked));
+        WebInspector.Revealer.reveal(WebInspector.cssWorkspaceBinding.propertyUILocation(this.property, propertyNameClicked));
     },
 
     /**
@@ -2684,7 +2905,7 @@ WebInspector.StylePropertyTreeElement.prototype = {
     },
 
     /**
-     * @param {!Element=} selectElement
+     * @param {?Element=} selectElement
      */
     startEditing: function(selectElement)
     {
@@ -2731,6 +2952,7 @@ WebInspector.StylePropertyTreeElement.prototype = {
             return splitFieldValue.join("");
         }
 
+        /** @type {!WebInspector.StylePropertyTreeElement.Context} */
         var context = {
             expanded: this.expanded,
             hasChildren: this.hasChildren,
@@ -2746,6 +2968,8 @@ WebInspector.StylePropertyTreeElement.prototype = {
         selectElement.textContent = selectElement.textContent; // remove color swatch and the like
 
         /**
+         * @param {!WebInspector.StylePropertyTreeElement.Context} context
+         * @param {!Event} event
          * @this {WebInspector.StylePropertyTreeElement}
          */
         function pasteHandler(context, event)
@@ -2776,6 +3000,8 @@ WebInspector.StylePropertyTreeElement.prototype = {
         }
 
         /**
+         * @param {!WebInspector.StylePropertyTreeElement.Context} context
+         * @param {!Event} event
          * @this {WebInspector.StylePropertyTreeElement}
          */
         function blurListener(context, event)
@@ -2797,7 +3023,7 @@ WebInspector.StylePropertyTreeElement.prototype = {
         if (selectElement.parentElement)
             selectElement.parentElement.scrollIntoViewIfNeeded(false);
 
-        var applyItemCallback = !isEditingName ? this._applyFreeFlowStyleTextEdit.bind(this, true) : undefined;
+        var applyItemCallback = !isEditingName ? this._applyFreeFlowStyleTextEdit.bind(this) : undefined;
         this._prompt = new WebInspector.StylesSidebarPane.CSSPropertyPrompt(isEditingName ? WebInspector.CSSMetadata.cssPropertiesMetainfo : WebInspector.CSSMetadata.keywordsForProperty(this.nameElement.textContent), this, isEditingName);
         if (applyItemCallback) {
             this._prompt.addEventListener(WebInspector.TextPrompt.Events.ItemApplied, applyItemCallback, this);
@@ -2805,20 +3031,24 @@ WebInspector.StylePropertyTreeElement.prototype = {
         }
         var proxyElement = this._prompt.attachAndStartEditing(selectElement, blurListener.bind(this, context));
 
-        proxyElement.addEventListener("keydown", this.editingNameValueKeyDown.bind(this, context), false);
-        proxyElement.addEventListener("keypress", this.editingNameValueKeyPress.bind(this, context), false);
+        proxyElement.addEventListener("keydown", this._editingNameValueKeyDown.bind(this, context), false);
+        proxyElement.addEventListener("keypress", this._editingNameValueKeyPress.bind(this, context), false);
+        proxyElement.addEventListener("input", this._editingNameValueInput.bind(this, context), false);
         if (isEditingName)
             proxyElement.addEventListener("paste", pasteHandler.bind(this, context), false);
 
         window.getSelection().setBaseAndExtent(selectElement, 0, selectElement, 1);
     },
 
-    editingNameValueKeyDown: function(context, event)
+    /**
+     * @param {!WebInspector.StylePropertyTreeElement.Context} context
+     * @param {!Event} event
+     */
+    _editingNameValueKeyDown: function(context, event)
     {
         if (event.handled)
             return;
 
-        var isEditingName = context.isEditingName;
         var result;
 
         if (isEnterKey(event)) {
@@ -2826,7 +3056,7 @@ WebInspector.StylePropertyTreeElement.prototype = {
             result = "forward";
         } else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code || event.keyIdentifier === "U+001B")
             result = "cancel";
-        else if (!isEditingName && this._newProperty && event.keyCode === WebInspector.KeyboardShortcut.Keys.Backspace.code) {
+        else if (!context.isEditingName && this._newProperty && event.keyCode === WebInspector.KeyboardShortcut.Keys.Backspace.code) {
             // For a new property, when Backspace is pressed at the beginning of new property value, move back to the property name.
             var selection = window.getSelection();
             if (selection.isCollapsed && !selection.focusOffset) {
@@ -2852,12 +3082,13 @@ WebInspector.StylePropertyTreeElement.prototype = {
             event.consume();
             return;
         }
-
-        if (!isEditingName)
-            this._applyFreeFlowStyleTextEdit(false);
     },
 
-    editingNameValueKeyPress: function(context, event)
+    /**
+     * @param {!WebInspector.StylePropertyTreeElement.Context} context
+     * @param {!Event} event
+     */
+    _editingNameValueKeyPress: function(context, event)
     {
         function shouldCommitValueSemicolon(text, cursorPosition)
         {
@@ -2885,36 +3116,31 @@ WebInspector.StylePropertyTreeElement.prototype = {
         }
     },
 
-    _applyFreeFlowStyleTextEdit: function(now)
+    /**
+     * @param {!WebInspector.StylePropertyTreeElement.Context} context
+     * @param {!Event} event
+     */
+    _editingNameValueInput: function(context, event)
     {
-        if (this._applyFreeFlowStyleTextEditTimer)
-            clearTimeout(this._applyFreeFlowStyleTextEditTimer);
+        if (!context.isEditingName)
+            this._applyFreeFlowStyleTextEdit();
+    },
 
-        /**
-         * @this {WebInspector.StylePropertyTreeElement}
-         */
-        function apply()
-        {
-            var valueText = this.valueElement.textContent;
-            if (valueText.indexOf(";") === -1)
-                this.applyStyleText(this.nameElement.textContent + ": " + valueText, false, false, false);
-        }
-        if (now)
-            apply.call(this);
-        else
-            this._applyFreeFlowStyleTextEditTimer = setTimeout(apply.bind(this), 100);
+    _applyFreeFlowStyleTextEdit: function()
+    {
+        var valueText = this.valueElement.textContent;
+        if (valueText.indexOf(";") === -1)
+            this.applyStyleText(this.nameElement.textContent + ": " + valueText, false, false, false);
     },
 
     kickFreeFlowStyleEditForTest: function()
     {
-        this._applyFreeFlowStyleTextEdit(true);
+        this._applyFreeFlowStyleTextEdit();
     },
 
     editingEnded: function(context)
     {
         this._resetMouseDownElement();
-        if (this._applyFreeFlowStyleTextEditTimer)
-            clearTimeout(this._applyFreeFlowStyleTextEditTimer);
 
         this.hasChildren = context.hasChildren;
         if (context.expanded)
@@ -3100,12 +3326,35 @@ WebInspector.StylePropertyTreeElement.prototype = {
     {
     },
 
+    /**
+     * @param {string} styleText
+     * @param {boolean} updateInterface
+     * @param {boolean} majorChange
+     * @param {boolean} isRevert
+     */
     applyStyleText: function(styleText, updateInterface, majorChange, isRevert)
     {
+        this._applyStyleThrottler.schedule(this._innerApplyStyleText.bind(this, styleText, updateInterface, majorChange, isRevert));
+    },
+
+    /**
+     * @param {string} styleText
+     * @param {boolean} updateInterface
+     * @param {boolean} majorChange
+     * @param {boolean} isRevert
+     * @param {!WebInspector.Throttler.FinishCallback} finishedCallback
+     */
+    _innerApplyStyleText: function(styleText, updateInterface, majorChange, isRevert, finishedCallback)
+    {
+        /**
+         * @param {!WebInspector.StylesSidebarPane} parentPane
+         * @param {boolean} updateInterface
+         */
         function userOperationFinishedCallback(parentPane, updateInterface)
         {
             if (updateInterface)
                 delete parentPane._userOperation;
+            finishedCallback();
         }
 
         // Leave a way to cancel editing after incremental changes.
@@ -3146,6 +3395,7 @@ WebInspector.StylePropertyTreeElement.prototype = {
                     this._revertStyleUponEditingCanceled(originalPropertyText);
                 }
                 userCallback();
+                this.styleTextAppliedForTest();
                 return;
             }
             this._applyNewStyle(newStyle);
@@ -3172,7 +3422,11 @@ WebInspector.StylePropertyTreeElement.prototype = {
         if (styleText.length && !/;\s*$/.test(styleText))
             styleText += ";";
         var overwriteProperty = !!(!this._newProperty || this._newPropertyInStyle);
-        this.property.setText(styleText, majorChange, overwriteProperty, callback.bind(this, userOperationFinishedCallback.bind(null, this._parentPane, updateInterface), this.originalPropertyText));
+        var boundCallback = callback.bind(this, userOperationFinishedCallback.bind(null, this._parentPane, updateInterface), this.originalPropertyText);
+        if (overwriteProperty && styleText === this.property.propertyText)
+            boundCallback.call(null, this.property.ownerStyle)
+        else
+            this.property.setText(styleText, majorChange, overwriteProperty, boundCallback);
     },
 
     /**
@@ -3184,7 +3438,7 @@ WebInspector.StylePropertyTreeElement.prototype = {
     },
 
     /**
-     * @param {?Event} event
+     * @param {!Event} event
      * @return {boolean}
      */
     isEventWithinDisclosureTriangle: function(event)
@@ -3217,7 +3471,7 @@ WebInspector.StylesSidebarPane.CSSPropertyPrompt = function(cssCompletions, side
 
 WebInspector.StylesSidebarPane.CSSPropertyPrompt.prototype = {
     /**
-     * @param {?Event} event
+     * @param {!Event} event
      */
     onKeyDown: function(event)
     {
@@ -3264,7 +3518,7 @@ WebInspector.StylesSidebarPane.CSSPropertyPrompt.prototype = {
     },
 
     /**
-     * @param {?Event} event
+     * @param {!Event} event
      * @return {boolean}
      */
     _handleNameOrValueUpDown: function(event)
@@ -3280,8 +3534,22 @@ WebInspector.StylesSidebarPane.CSSPropertyPrompt.prototype = {
             this._sidebarPane.applyStyleText(this._sidebarPane.nameElement.textContent + ": " + this._sidebarPane.valueElement.textContent, false, false, false);
         }
 
+        /**
+         * @param {string} prefix
+         * @param {number} number
+         * @param {string} suffix
+         * @return {string}
+         * @this {WebInspector.StylesSidebarPane.CSSPropertyPrompt}
+         */
+        function customNumberHandler(prefix, number, suffix)
+        {
+            if (number !== 0 && !suffix.length && WebInspector.CSSMetadata.isLengthProperty(this._sidebarPane.property.name))
+                suffix = "px";
+            return prefix + number + suffix;
+        }
+
         // Handle numeric value increment/decrement only at this point.
-        if (!this._isEditingName && WebInspector.handleElementValueModifications(event, this._sidebarPane.valueElement, finishHandler.bind(this), this._isValueSuggestion.bind(this)))
+        if (!this._isEditingName && WebInspector.handleElementValueModifications(event, this._sidebarPane.valueElement, finishHandler.bind(this), this._isValueSuggestion.bind(this), customNumberHandler.bind(this)))
             return true;
 
         return false;
@@ -3314,6 +3582,11 @@ WebInspector.StylesSidebarPane.CSSPropertyPrompt.prototype = {
         }
 
         var results = this._cssCompletions.startsWith(prefix);
+        var userEnteredText = wordRange.toString().replace("-", "");
+        if (userEnteredText && (userEnteredText === userEnteredText.toUpperCase())) {
+            for (var i = 0; i < results.length; ++i)
+                results[i] = results[i].toUpperCase();
+        }
         var selectedIndex = this._cssCompletions.mostUsedOf(results);
         completionsReadyCallback(results, selectedIndex);
     },