Web Inspector: Cursor and scroll view jumps around when modifying styles
authortimothy@apple.com <timothy@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 7 Nov 2014 22:01:59 +0000 (22:01 +0000)
committertimothy@apple.com <timothy@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 7 Nov 2014 22:01:59 +0000 (22:01 +0000)
https://bugs.webkit.org/show_bug.cgi?id=137467

This merges commit e2962a5b0df56c8ee5a4482899d308decf3d7677 from CodeMirror.

Reviewed by Joseph Pecoraro.

* UserInterface/External/CodeMirror/codemirror.js:
(maybeScrollWindow): Signal the scrollCursorIntoView event.
(signalDOMEvent): Support string events by transforming them to event objects.

* UserInterface/Views/CodeMirrorAdditions.js:
(scrollCursorIntoView): Added. Default event listener that provides our own
implementation using WebKit's scrollIntoViewIfNeeded.

* UserInterface/Views/RulesStyleDetailsPanel.js:
(WebInspector.RulesStyleDetailsPanel.prototype.refresh): Stop doing an
extra scrollIntoViewIfNeeded call, CodeMirror does this.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@175763 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/UserInterface/External/CodeMirror/codemirror.js
Source/WebInspectorUI/UserInterface/Views/CodeMirrorAdditions.js
Source/WebInspectorUI/UserInterface/Views/RulesStyleDetailsPanel.js

index 0847160..91c0682 100644 (file)
@@ -1,3 +1,24 @@
+2014-11-07  Timothy Hatcher  <timothy@apple.com>
+
+        Web Inspector: Cursor and scroll view jumps around when modifying styles
+        https://bugs.webkit.org/show_bug.cgi?id=137467
+
+        This merges commit e2962a5b0df56c8ee5a4482899d308decf3d7677 from CodeMirror.
+
+        Reviewed by Joseph Pecoraro.
+
+        * UserInterface/External/CodeMirror/codemirror.js:
+        (maybeScrollWindow): Signal the scrollCursorIntoView event.
+        (signalDOMEvent): Support string events by transforming them to event objects.
+
+        * UserInterface/Views/CodeMirrorAdditions.js:
+        (scrollCursorIntoView): Added. Default event listener that provides our own
+        implementation using WebKit's scrollIntoViewIfNeeded.
+
+        * UserInterface/Views/RulesStyleDetailsPanel.js:
+        (WebInspector.RulesStyleDetailsPanel.prototype.refresh): Stop doing an
+        extra scrollIntoViewIfNeeded call, CodeMirror does this.
+
 2014-11-07  Joseph Pecoraro  <pecoraro@apple.com>
 
         Web Inspector: Pseudo element matchedCSSRules do not include matching selector info
index 104ccd7..8612ed8 100644 (file)
   // If an editor sits on the top or bottom of the window, partially
   // scrolled out of view, this ensures that the cursor is visible.
   function maybeScrollWindow(cm, coords) {
+    if (signalDOMEvent(cm, "scrollCursorIntoView")) return;
+
     var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null;
     if (coords.top + box.top < 0) doScroll = true;
     else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false;
   // registering a (non-DOM) handler on the editor for the event name,
   // and preventDefault-ing the event in that handler.
   function signalDOMEvent(cm, e, override) {
+    if (typeof e == "string")
+      e = {type: e, preventDefault: function() { this.defaultPrevented = true; }};
     signal(cm, override || e.type, cm, e);
     return e_defaultPrevented(e) || e.codemirrorIgnore;
   }
index 0bc5883..73f588e 100644 (file)
         return state;
     }
 
+    function scrollCursorIntoView(codeMirror, event)
+    {
+        // We don't want to use the default implementation since it can cause massive jumping
+        // when the editor is contained inside overflow elements.
+        event.preventDefault();
+
+        function delayedWork()
+        {
+            // Don't try to scroll unless the editor is focused.
+            if (!codeMirror.getWrapperElement().classList.contains("CodeMirror-focused"))
+                return;
+
+            // The cursor element can contain multiple cursors. The first one is the blinky cursor,
+            // which is the one we want to scroll into view. It can be missing, so check first.
+            var cursorElement = codeMirror.getScrollerElement().getElementsByClassName("CodeMirror-cursor")[0];
+            if (cursorElement)
+                cursorElement.scrollIntoViewIfNeeded(false);
+        }
+
+        // We need to delay this because CodeMirror can fire scrollCursorIntoView as a view is being blurred
+        // and another is being focused. The blurred editor still has the focused state when this event fires.
+        // We don't want to scroll the blurred editor into view, only the focused editor.
+        setTimeout(delayedWork, 0);
+    }
+
     CodeMirror.extendMode("css", {token: extendedCSSToken});
     CodeMirror.extendMode("xml", {token: extendedXMLToken});
     CodeMirror.extendMode("javascript", {token: extendedToken});
     CodeMirror.defineMode("css-rule", CodeMirror.modes.css);
     CodeMirror.extendMode("css-rule", {token: extendedCSSToken, startState: extendedCSSRuleStartState, alternateName: "css"});
 
+    CodeMirror.defineInitHook(function(codeMirror) {
+        codeMirror.on("scrollCursorIntoView", scrollCursorIntoView);
+    });
+
     CodeMirror.defineExtension("hasLineClass", function(line, where, className) {
         // This matches the arguments to addLineClass and removeLineClass.
         var classProperty = (where === "text" ? "textClass" : (where === "background" ? "bgClass" : "wrapClass"));
index 0fd114e..a502de5 100644 (file)
@@ -216,18 +216,8 @@ WebInspector.RulesStyleDetailsPanel.prototype = {
         for (var i = 0; i < this._sections.length; ++i)
             this._sections[i].updateLayout();
 
-        if (previousFocusedSection) {
+        if (previousFocusedSection)
             previousFocusedSection.focus();
-
-            function scrollToFocusedSection()
-            {
-                previousFocusedSection.element.scrollIntoViewIfNeeded(true);
-            }
-
-            // Do the scroll on a timeout since StyleDetailsPanel restores scroll position
-            // after the refresh, and we might not need to scroll after the restore.
-            setTimeout(scrollToFocusedSection, 0);
-        }
     },
 
     // Protected