Title: [147117] trunk
Revision
147117
Author
apav...@chromium.org
Date
2013-03-28 08:15:07 -0700 (Thu, 28 Mar 2013)

Log Message

Web Inspector: [Elements] Syntax-highlight the "Edit as HTML" editor
https://bugs.webkit.org/show_bug.cgi?id=113306

Reviewed by Vsevolod Vlasov.

Source/WebCore:

Use CodeMirror as the raw HTML editor for the "Edit as HTML" menu item
(and all multiline editors for WebInspector.startEditing()).
Drive-by fix for handling the editing when the editor has been invoked on the closing tag.

* inspector/front-end/ElementsTreeOutline.js:
(WebInspector.ElementsTreeElement.prototype.commit):
(WebInspector.ElementsTreeElement.prototype._startEditingAsHTML):
* inspector/front-end/UIUtils.js:
(WebInspector.EditingConfig.prototype.setMultiline):
(WebInspector.startEditing):
(WebInspector.CodeMirrorCSSLoadView): A bogus view to load-unload CodeMirror-related CSS on demand.
* inspector/front-end/elementsPanel.css:
(#elements-content .CodeMirror):
(#elements-content .CodeMirror pre):
(#elements-content .CodeMirror-lines):
* inspector/front-end/elementsPanel.css: CodeMirror styles for the "Edit as HTML" editor.
* inspector/front-end/externs.js: Declare CodeMirror type with some members, as it is third-party code.
* inspector/front-end/inspector.html: Fix script order (UIUtils.js requires View.js).

LayoutTests:

* inspector/elements/edit-dom-actions.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (147116 => 147117)


--- trunk/LayoutTests/ChangeLog	2013-03-28 14:53:50 UTC (rev 147116)
+++ trunk/LayoutTests/ChangeLog	2013-03-28 15:15:07 UTC (rev 147117)
@@ -1,3 +1,12 @@
+2013-03-28  Alexander Pavlov  <apav...@chromium.org>
+
+        Web Inspector: [Elements] Syntax-highlight the "Edit as HTML" editor
+        https://bugs.webkit.org/show_bug.cgi?id=113306
+
+        Reviewed by Vsevolod Vlasov.
+
+        * inspector/elements/edit-dom-actions.html:
+
 2013-03-28  Christophe Dumez  <ch.du...@sisa.samsung.com>
 
         Unreviewed EFL gardening.

Modified: trunk/LayoutTests/inspector/elements/edit-dom-actions.html (147116 => 147117)


--- trunk/LayoutTests/inspector/elements/edit-dom-actions.html	2013-03-28 14:53:50 UTC (rev 147116)
+++ trunk/LayoutTests/inspector/elements/edit-dom-actions.html	2013-03-28 15:15:07 UTC (rev 147117)
@@ -125,8 +125,8 @@
 
                 function step2()
                 {
-                    InspectorTest.addResult(treeElement._htmlEditElement.textContent);
-                    treeElement._htmlEditElement.textContent = "<div foo=\"bar-comment\">Element</div>";
+                    InspectorTest.addResult(treeElement._editing.codeMirror.getValue());
+                    treeElement._editing.codeMirror.setValue("<div foo=\"bar-comment\">Element</div>");
                     var event = InspectorTest.createKeyEvent("Enter");
                     event.isMetaOrCtrlForTest = true;
                     treeElement._htmlEditElement.dispatchEvent(event);
@@ -147,8 +147,8 @@
 
                 function step2()
                 {
-                    InspectorTest.addResult(treeElement._htmlEditElement.textContent);
-                    treeElement._htmlEditElement.textContent = "<span foo=\"bar\"><span id=\"inner-span\">Span contents</span></span>";
+                    InspectorTest.addResult(treeElement._editing.codeMirror.getValue());
+                    treeElement._editing.codeMirror.setValue("<span foo=\"bar\"><span id=\"inner-span\">Span contents</span></span>");
                     var event = InspectorTest.createKeyEvent("Enter");
                     event.isMetaOrCtrlForTest = true;
                     treeElement._htmlEditElement.dispatchEvent(event);
@@ -169,8 +169,9 @@
 
                 function step2()
                 {
-                    InspectorTest.addResult(treeElement._htmlEditElement.textContent);
-                    treeElement._htmlEditElement.textContent = treeElement._htmlEditElement.textContent.replace(/&/g, '#');
+                    var codeMirror = treeElement._editing.codeMirror;
+                    InspectorTest.addResult(codeMirror.getValue());
+                    codeMirror.setValue(codeMirror.getValue().replace(/&/g, '#'));
                     var event = InspectorTest.createKeyEvent("Enter");
                     event.isMetaOrCtrlForTest = true;
                     treeElement._htmlEditElement.dispatchEvent(event);

Modified: trunk/Source/WebCore/ChangeLog (147116 => 147117)


--- trunk/Source/WebCore/ChangeLog	2013-03-28 14:53:50 UTC (rev 147116)
+++ trunk/Source/WebCore/ChangeLog	2013-03-28 15:15:07 UTC (rev 147117)
@@ -1,3 +1,29 @@
+2013-03-28  Alexander Pavlov  <apav...@chromium.org>
+
+        Web Inspector: [Elements] Syntax-highlight the "Edit as HTML" editor
+        https://bugs.webkit.org/show_bug.cgi?id=113306
+
+        Reviewed by Vsevolod Vlasov.
+
+        Use CodeMirror as the raw HTML editor for the "Edit as HTML" menu item
+        (and all multiline editors for WebInspector.startEditing()).
+        Drive-by fix for handling the editing when the editor has been invoked on the closing tag.
+
+        * inspector/front-end/ElementsTreeOutline.js:
+        (WebInspector.ElementsTreeElement.prototype.commit):
+        (WebInspector.ElementsTreeElement.prototype._startEditingAsHTML):
+        * inspector/front-end/UIUtils.js:
+        (WebInspector.EditingConfig.prototype.setMultiline):
+        (WebInspector.startEditing):
+        (WebInspector.CodeMirrorCSSLoadView): A bogus view to load-unload CodeMirror-related CSS on demand.
+        * inspector/front-end/elementsPanel.css:
+        (#elements-content .CodeMirror):
+        (#elements-content .CodeMirror pre):
+        (#elements-content .CodeMirror-lines):
+        * inspector/front-end/elementsPanel.css: CodeMirror styles for the "Edit as HTML" editor.
+        * inspector/front-end/externs.js: Declare CodeMirror type with some members, as it is third-party code.
+        * inspector/front-end/inspector.html: Fix script order (UIUtils.js requires View.js).
+
 2013-03-28  Hajime Morrita  <morr...@google.com>
 
         Custom Elements: should support non-HTML namespaces.

Modified: trunk/Source/WebCore/inspector/front-end/ElementsTreeOutline.js (147116 => 147117)


--- trunk/Source/WebCore/inspector/front-end/ElementsTreeOutline.js	2013-03-28 14:53:50 UTC (rev 147116)
+++ trunk/Source/WebCore/inspector/front-end/ElementsTreeOutline.js	2013-03-28 15:15:07 UTC (rev 147117)
@@ -1480,7 +1480,7 @@
     {
         if (error)
             return;
-        if (this._htmlEditElement && WebInspector.isBeingEdited(this._htmlEditElement))
+        if (this._editing)
             return;
 
         function consume(event)
@@ -1491,9 +1491,10 @@
 
         initialValue = this._convertWhitespaceToEntities(initialValue);
 
+        this.select(true);
+
         this._htmlEditElement = document.createElement("div");
         this._htmlEditElement.className = "source-code elements-tree-editor";
-        this._htmlEditElement.textContent = initialValue;
 
         // Hide header items.
         var child = this.listItemElement.firstChild;
@@ -1510,9 +1511,13 @@
 
         this.updateSelection();
 
-        function commit()
+        /**
+         * @param {Element} element
+         * @param {string} newValue
+         */
+        function commit(element, newValue)
         {
-            commitCallback(initialValue, this._htmlEditElement.textContent);
+            commitCallback(initialValue, newValue);
             dispose.call(this);
         }
 
@@ -1538,7 +1543,7 @@
         }
 
         var config = new WebInspector.EditingConfig(commit.bind(this), dispose.bind(this));
-        config.setMultiline(true);
+        config.setMultilineOptions(initialValue, { name: "xml", htmlMode: true }, "web-inspector-html", true, true);
         this._editing = WebInspector.startEditing(this._htmlEditElement, config);
     },
 

Modified: trunk/Source/WebCore/inspector/front-end/UIUtils.js (147116 => 147117)


--- trunk/Source/WebCore/inspector/front-end/UIUtils.js	2013-03-28 14:53:50 UTC (rev 147116)
+++ trunk/Source/WebCore/inspector/front-end/UIUtils.js	2013-03-28 15:15:07 UTC (rev 147117)
@@ -219,9 +219,21 @@
         this.pasteHandler = pasteHandler;
     },
 
-    setMultiline: function(multiline)
+    /**
+     * @param {string} initialValue
+     * @param {Object} mode
+     * @param {string} theme
+     * @param {boolean=} lineWrapping
+     * @param {boolean=} smartIndent
+     */
+    setMultilineOptions: function(initialValue, mode, theme, lineWrapping, smartIndent)
     {
-        this.multiline = multiline;
+        this.multiline = true;
+        this.initialValue = initialValue;
+        this.mode = mode;
+        this.theme = theme;
+        this.lineWrapping = lineWrapping;
+        this.smartIndent = smartIndent;
     },
 
     setCustomFinishHandler: function(customFinishHandler)
@@ -428,24 +440,51 @@
     var cancelledCallback = config.cancelHandler;
     var pasteCallback = config.pasteHandler;
     var context = config.context;
-    var oldText = getContent(element);
+    var isMultiline = config.multiline || false;
+    var oldText = isMultiline ? config.initialValue : getContent(element);
     var moveDirection = "";
+    var oldTabIndex;
+    var codeMirror;
+    var cssLoadView;
 
-    element.addStyleClass("editing");
+    if (isMultiline) {
+        loadScript("CodeMirrorTextEditor.js");
+        cssLoadView = new WebInspector.CodeMirrorCSSLoadView();
+        cssLoadView.show(element);
+        WebInspector.setCurrentFocusElement(element);
+        codeMirror = window.CodeMirror(element, {
+            mode: config.mode,
+            lineWrapping: config.lineWrapping,
+            smartIndent: config.smartIndent,
+            autofocus: true,
+            theme: config.theme,
+            value: oldText
+        });
+    } else {
+        element.addStyleClass("editing");
 
-    var oldTabIndex = element.getAttribute("tabIndex");
-    if (typeof oldTabIndex !== "number" || oldTabIndex < 0)
-        element.tabIndex = 0;
+        oldTabIndex = element.getAttribute("tabIndex");
+        if (typeof oldTabIndex !== "number" || oldTabIndex < 0)
+            element.tabIndex = 0;
+        WebInspector.setCurrentFocusElement(element);
+    }
 
-    function blurEventListener() {
-        editingCommitted.call(element);
+    /**
+     * @param {Event=} e
+     */
+    function blurEventListener(e) {
+        if (!isMultiline || !e || !e.relatedTarget || !e.relatedTarget.isSelfOrDescendant(element))
+            editingCommitted.call(element);
     }
 
     function getContent(element) {
+        if (isMultiline)
+            return codeMirror.getValue();
+
         if (element.tagName === "INPUT" && element.type === "text")
             return element.value;
-        else
-            return element.textContent;
+
+        return element.textContent;
     }
 
     /** @this {Element} */
@@ -453,6 +492,18 @@
     {
         WebInspector.markBeingEdited(element, false);
 
+        element.removeEventListener("blur", blurEventListener, isMultiline);
+        element.removeEventListener("keydown", keyDownEventListener, true);
+        if (pasteCallback)
+            element.removeEventListener("paste", pasteEventListener, true);
+
+        WebInspector.restoreFocusFromElement(element);
+
+        if (isMultiline) {
+            cssLoadView.detach();
+            return;
+        }
+
         this.removeStyleClass("editing");
         
         if (typeof oldTabIndex !== "number")
@@ -461,22 +512,19 @@
             this.tabIndex = oldTabIndex;
         this.scrollTop = 0;
         this.scrollLeft = 0;
-
-        element.removeEventListener("blur", blurEventListener, false);
-        element.removeEventListener("keydown", keyDownEventListener, true);
-        if (pasteCallback)
-            element.removeEventListener("paste", pasteEventListener, true);
-
-        WebInspector.restoreFocusFromElement(element);
     }
 
     /** @this {Element} */
     function editingCancelled()
     {
-        if (this.tagName === "INPUT" && this.type === "text")
-            this.value = oldText;
-        else
-            this.textContent = oldText;
+        if (isMultiline)
+            codeMirror.setValue(oldText);
+        else {
+            if (this.tagName === "INPUT" && this.type === "text")
+                this.value = oldText;
+            else
+                this.textContent = oldText;
+        }
 
         cleanUpAfterEditing.call(this);
 
@@ -496,11 +544,11 @@
         var isMetaOrCtrl = WebInspector.isMac() ?
             event.metaKey && !event.shiftKey && !event.ctrlKey && !event.altKey :
             event.ctrlKey && !event.shiftKey && !event.metaKey && !event.altKey;
-        if (isEnterKey(event) && (event.isMetaOrCtrlForTest || !config.multiline || isMetaOrCtrl))
+        if (isEnterKey(event) && (event.isMetaOrCtrlForTest || !isMultiline || isMetaOrCtrl))
             return "commit";
         else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code || event.keyIdentifier === "U+001B")
             return "cancel";
-        else if (event.keyIdentifier === "U+0009") // Tab key
+        else if (!isMultiline && event.keyIdentifier === "U+0009") // Tab key
             return "move-" + (event.shiftKey ? "backward" : "forward");
     }
 
@@ -532,15 +580,15 @@
         handleEditingResult(result, event);
     }
 
-    element.addEventListener("blur", blurEventListener, false);
+    element.addEventListener("blur", blurEventListener, isMultiline);
     element.addEventListener("keydown", keyDownEventListener, true);
     if (pasteCallback)
         element.addEventListener("paste", pasteEventListener, true);
 
-    WebInspector.setCurrentFocusElement(element);
     return {
         cancel: editingCancelled.bind(element),
-        commit: editingCommitted.bind(element)
+        commit: editingCommitted.bind(element),
+        codeMirror: codeMirror // For testing.
     };
 }
 
@@ -997,6 +1045,24 @@
     methods.put(method);
 }
 
+/**
+ * This bogus view is needed to load/unload CodeMirror-related CSS on demand.
+ *
+ * @constructor
+ * @extends {WebInspector.View}
+ */
+WebInspector.CodeMirrorCSSLoadView = function()
+{
+    WebInspector.View.call(this);
+    this.element.addStyleClass("hidden");
+    this.registerRequiredCSS("cm/codemirror.css");
+    this.registerRequiredCSS("cm/cmdevtools.css");
+}
+
+WebInspector.CodeMirrorCSSLoadView.prototype = {
+    __proto__: WebInspector.View.prototype
+}
+
 ;(function() {
 
 function windowLoaded()

Modified: trunk/Source/WebCore/inspector/front-end/elementsPanel.css (147116 => 147117)


--- trunk/Source/WebCore/inspector/front-end/elementsPanel.css	2013-03-28 14:53:50 UTC (rev 147116)
+++ trunk/Source/WebCore/inspector/front-end/elementsPanel.css	2013-03-28 15:15:07 UTC (rev 147117)
@@ -55,6 +55,21 @@
     opacity: 0.5;
 }
 
+#elements-content .CodeMirror {
+    /* Consistent with the .editing class in inspector.css */
+    -webkit-box-shadow: rgba(0, 0, 0, .5) 3px 3px 4px;
+    outline: 1px solid rgb(66%, 66%, 66%) !important;
+    background-color: white;
+}
+
+#elements-content .CodeMirror pre {
+    padding: 0;
+}
+
+#elements-content .CodeMirror-lines {
+    padding: 0;
+}
+
 .elements-tree-editor {
     -webkit-user-select: text;
     -webkit-user-modify: read-write-plaintext-only;

Modified: trunk/Source/WebCore/inspector/front-end/externs.js (147116 => 147117)


--- trunk/Source/WebCore/inspector/front-end/externs.js	2013-03-28 14:53:50 UTC (rev 147116)
+++ trunk/Source/WebCore/inspector/front-end/externs.js	2013-03-28 15:15:07 UTC (rev 147117)
@@ -331,6 +331,21 @@
 /** @constructor */
 WebInspector.AceTextEditor = function(url, delegate) { }
 
+/** @constructor */
+var CodeMirror = function() { }
+CodeMirror.prototype.replaceSelection = function(str1, str2, str3) { }
+/** @return {Element} */
+CodeMirror.prototype.getInputField = function() { }
+CodeMirror.prototype.getCursor = function() { }
+CodeMirror.prototype.setCursor = function(arg) { }
+CodeMirror.prototype.getLine = function() { }
+CodeMirror.prototype.getValue = function() { }
+CodeMirror.prototype.setValue = function(arg) { }
+CodeMirror.prototype.clearGutter = function(arg) { }
+CodeMirror.prototype.setGutterMarker = function(arg1, arg2, arg3) { }
+CodeMirror.prototype.clearHistory = function() { }
+CodeMirror.prototype.markText = function(arg1, arg2, arg3) { }
+
 WebInspector.suggestReload = function() { }
 WebInspector.reload = function() { }
 

Modified: trunk/Source/WebCore/inspector/front-end/inspector.html (147116 => 147117)


--- trunk/Source/WebCore/inspector/front-end/inspector.html	2013-03-28 14:53:50 UTC (rev 147116)
+++ trunk/Source/WebCore/inspector/front-end/inspector.html	2013-03-28 15:15:07 UTC (rev 147117)
@@ -41,7 +41,6 @@
     <script type="text/_javascript_" src=""
     <script type="text/_javascript_" src=""
     <script type="text/_javascript_" src=""
-    <script type="text/_javascript_" src=""
     <script type="text/_javascript_" src=""
     <script type="text/_javascript_" src=""
     <script type="text/_javascript_" src=""
@@ -49,6 +48,7 @@
     <script type="text/_javascript_" src=""
     <script type="text/_javascript_" src=""
     <script type="text/_javascript_" src=""
+    <script type="text/_javascript_" src=""
     <script type="text/_javascript_" src=""
     <script type="text/_javascript_" src=""
     <script type="text/_javascript_" src=""
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to