<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[192662] trunk/Source</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/192662">192662</a></dd>
<dt>Author</dt> <dd>bburg@apple.com</dd>
<dt>Date</dt> <dd>2015-11-19 15:00:41 -0800 (Thu, 19 Nov 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Web Inspector: yank/kill shortcuts (CTRL+Y, K) don't work in Console / QuickConsole
https://bugs.webkit.org/show_bug.cgi?id=151157

Reviewed by Joseph Pecoraro.

CodeMirror maintains its own editor buffer and implements its own
`killLine` command but doesn't implement the yank command. So, text
that is &quot;killed&quot; with CTRL-k inside a CodeMirror instance isn't
Source/WebCore:

added to Editor's kill ring. Subsequent yank commands won't match
up with the killed text, instead returning text from a prior kill
that was handled by Editor (i.e., in a contenteditable or form input).

This patch adds a host function so that the Inspector frontend can
append &quot;missed&quot; killed text to Editor's kill ring. Subsequent
yanks handled by Editor will then match the text killed by CodeMirror.

No new tests, because we need to use both InspectorFrontendHost
and TestRunner.execCommand, but the latter is not available in
the inspector context where we would need to simulate a kill.

* inspector/InspectorFrontendHost.cpp:
(WebCore::InspectorFrontendHost::killText):

    Added. This appends the killed text to the kill ring, starting
    a new sequence if necessary. Unlike Editor, Inspector waits
    until the next kill command to clear the existing sequence.

* inspector/InspectorFrontendHost.h:
* inspector/InspectorFrontendHost.idl:

Source/WebInspectorUI:

added to WebCore's kill ring. Subsequent yank commands won't match
up with the killed text, instead returning text from a prior kill
that was handled by WebCore (i.e., in a contenteditable or form input).

This patch adds a host function so that the Inspector frontend can
append &quot;missed&quot; killed text to WebCore's kill ring. Subsequent
yanks handled by WebCore will then match the text killed by CodeMirror.

In the frontend, we implement our own key binding handler for
CTRL-k that captures killed text, detects whether the kill
should start a new sequence, and sends it to WebCore. Because this
involves several flags and listeners, and we want this behavior for
all editable CodeMirror instances, the text kill handling is
factored into its own CodeMirrorTextKillController.

To add this behavior to all instances, this patch centralizes the
code that constructs a base CodeMirror instance, and attaches the
CodeMirrorTextKillController to all instances. The shortcut
does nothing when its CodeMirror instance is read-only.

The particulars of the kill controller are documented inline.

No new tests, because we need to use both InspectorFrontendHost
and TestRunner.execCommand, but the latter is not available in
the inspector context where we would need to simulate a kill.

* UserInterface/Controllers/CodeMirrorTextKillController.js: Added.
(WebInspector.CodeMirrorTextKillController):
(WebInspector.CodeMirrorTextKillController.prototype._handleKillLine):
(WebInspector.CodeMirrorTextKillController.prototype._handleTextChange):
(WebInspector.CodeMirrorTextKillController.prototype._handleEditorBlur):
(WebInspector.CodeMirrorTextKillController.prototype._handleSelectionOrCaretChange):
* UserInterface/Main.html:
* UserInterface/Protocol/InspectorFrontendHostStub.js:
(window.InspectorFrontendHost.WebInspector.InspectorFrontendHostStub.prototype.killText): Add a stub to avoid check-before-use.
* UserInterface/Views/BreakpointActionView.js:
(WebInspector.BreakpointActionView.prototype._updateBody):
* UserInterface/Views/CSSStyleDeclarationTextEditor.js:
(WebInspector.CSSStyleDeclarationTextEditor):
* UserInterface/Views/CodeMirrorEditor.js: Added.
(WebInspector.CodeMirrorEditor.create):
(WebInspector.CodeMirrorEditor):
* UserInterface/Views/ConsolePrompt.js:
(WebInspector.ConsolePrompt):
* UserInterface/Views/ScopeChainDetailsSidebarPanel.js:
* UserInterface/Views/TextEditor.js:
(WebInspector.TextEditor):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorFrontendHostcpp">trunk/Source/WebCore/inspector/InspectorFrontendHost.cpp</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorFrontendHosth">trunk/Source/WebCore/inspector/InspectorFrontendHost.h</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorFrontendHostidl">trunk/Source/WebCore/inspector/InspectorFrontendHost.idl</a></li>
<li><a href="#trunkSourceWebInspectorUIChangeLog">trunk/Source/WebInspectorUI/ChangeLog</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceControllersBreakpointPopoverControllerjs">trunk/Source/WebInspectorUI/UserInterface/Controllers/BreakpointPopoverController.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceMainhtml">trunk/Source/WebInspectorUI/UserInterface/Main.html</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceProtocolInspectorFrontendHostStubjs">trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorFrontendHostStub.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsBreakpointActionViewjs">trunk/Source/WebInspectorUI/UserInterface/Views/BreakpointActionView.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsCSSStyleDeclarationTextEditorjs">trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationTextEditor.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsConsolePromptjs">trunk/Source/WebInspectorUI/UserInterface/Views/ConsolePrompt.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsScopeChainDetailsSidebarPaneljs">trunk/Source/WebInspectorUI/UserInterface/Views/ScopeChainDetailsSidebarPanel.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsTextEditorjs">trunk/Source/WebInspectorUI/UserInterface/Views/TextEditor.js</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceControllersCodeMirrorTextKillControllerjs">trunk/Source/WebInspectorUI/UserInterface/Controllers/CodeMirrorTextKillController.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsCodeMirrorEditorjs">trunk/Source/WebInspectorUI/UserInterface/Views/CodeMirrorEditor.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (192661 => 192662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-11-19 22:54:46 UTC (rev 192661)
+++ trunk/Source/WebCore/ChangeLog        2015-11-19 23:00:41 UTC (rev 192662)
</span><span class="lines">@@ -1,3 +1,35 @@
</span><ins>+2015-11-19  Brian Burg  &lt;bburg@apple.com&gt;
+
+        Web Inspector: yank/kill shortcuts (CTRL+Y, K) don't work in Console / QuickConsole
+        https://bugs.webkit.org/show_bug.cgi?id=151157
+
+        Reviewed by Joseph Pecoraro.
+
+        CodeMirror maintains its own editor buffer and implements its own
+        `killLine` command but doesn't implement the yank command. So, text
+        that is &quot;killed&quot; with CTRL-k inside a CodeMirror instance isn't
+        added to Editor's kill ring. Subsequent yank commands won't match
+        up with the killed text, instead returning text from a prior kill
+        that was handled by Editor (i.e., in a contenteditable or form input).
+
+        This patch adds a host function so that the Inspector frontend can
+        append &quot;missed&quot; killed text to Editor's kill ring. Subsequent
+        yanks handled by Editor will then match the text killed by CodeMirror.
+
+        No new tests, because we need to use both InspectorFrontendHost
+        and TestRunner.execCommand, but the latter is not available in
+        the inspector context where we would need to simulate a kill.
+
+        * inspector/InspectorFrontendHost.cpp:
+        (WebCore::InspectorFrontendHost::killText):
+
+            Added. This appends the killed text to the kill ring, starting
+            a new sequence if necessary. Unlike Editor, Inspector waits
+            until the next kill command to clear the existing sequence.
+
+        * inspector/InspectorFrontendHost.h:
+        * inspector/InspectorFrontendHost.idl:
+
</ins><span class="cx"> 2015-11-19  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Simple line layout: Add word-spacing support.
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorFrontendHostcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorFrontendHost.cpp (192661 => 192662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorFrontendHost.cpp        2015-11-19 22:54:46 UTC (rev 192661)
+++ trunk/Source/WebCore/inspector/InspectorFrontendHost.cpp        2015-11-19 23:00:41 UTC (rev 192662)
</span><span class="lines">@@ -36,7 +36,9 @@
</span><span class="cx"> #include &quot;ContextMenuProvider.h&quot;
</span><span class="cx"> #include &quot;DOMWrapperWorld.h&quot;
</span><span class="cx"> #include &quot;Document.h&quot;
</span><ins>+#include &quot;Editor.h&quot;
</ins><span class="cx"> #include &quot;Event.h&quot;
</span><ins>+#include &quot;FocusController.h&quot;
</ins><span class="cx"> #include &quot;HitTestResult.h&quot;
</span><span class="cx"> #include &quot;InspectorFrontendClient.h&quot;
</span><span class="cx"> #include &quot;JSMainThreadExecState.h&quot;
</span><span class="lines">@@ -182,12 +184,16 @@
</span><span class="cx"> 
</span><span class="cx"> void InspectorFrontendHost::setZoomFactor(float zoom)
</span><span class="cx"> {
</span><del>-    m_frontendPage-&gt;mainFrame().setPageAndTextZoomFactors(zoom, 1);
</del><ins>+    if (m_frontendPage)
+        m_frontendPage-&gt;mainFrame().setPageAndTextZoomFactors(zoom, 1);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> float InspectorFrontendHost::zoomFactor()
</span><span class="cx"> {
</span><del>-    return m_frontendPage-&gt;mainFrame().pageZoomFactor();
</del><ins>+    if (m_frontendPage)
+        return m_frontendPage-&gt;mainFrame().pageZoomFactor();
+
+    return 1.0;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void InspectorFrontendHost::setAttachedWindowHeight(unsigned height)
</span><span class="lines">@@ -265,6 +271,17 @@
</span><span class="cx">     Pasteboard::createForCopyAndPaste()-&gt;writePlainText(text, Pasteboard::CannotSmartReplace);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void InspectorFrontendHost::killText(const String&amp; text, bool shouldPrependToKillRing, bool shouldStartNewSequence)
+{
+    if (!m_frontendPage)
+        return;
+
+    Editor&amp; editor = m_frontendPage-&gt;focusController().focusedOrMainFrame().editor();
+    editor.setStartNewKillRingSequence(shouldStartNewSequence);
+    Editor::KillRingInsertionMode insertionMode = shouldPrependToKillRing ? Editor::KillRingInsertionMode::PrependText : Editor::KillRingInsertionMode::AppendText;
+    editor.addTextToKillRing(text, insertionMode);
+}
+
</ins><span class="cx"> void InspectorFrontendHost::openInNewTab(const String&amp; url)
</span><span class="cx"> {
</span><span class="cx">     if (m_client)
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorFrontendHosth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorFrontendHost.h (192661 => 192662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorFrontendHost.h        2015-11-19 22:54:46 UTC (rev 192661)
+++ trunk/Source/WebCore/inspector/InspectorFrontendHost.h        2015-11-19 23:00:41 UTC (rev 192662)
</span><span class="lines">@@ -76,6 +76,7 @@
</span><span class="cx">     String port();
</span><span class="cx"> 
</span><span class="cx">     void copyText(const String&amp; text);
</span><ins>+    void killText(const String&amp; text, bool shouldPrependToKillRing, bool shouldStartNewSequence);
</ins><span class="cx">     void openInNewTab(const String&amp; url);
</span><span class="cx">     bool canSave();
</span><span class="cx">     void save(const String&amp; url, const String&amp; content, bool base64Encoded, bool forceSaveAs);
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorFrontendHostidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorFrontendHost.idl (192661 => 192662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorFrontendHost.idl        2015-11-19 22:54:46 UTC (rev 192661)
+++ trunk/Source/WebCore/inspector/InspectorFrontendHost.idl        2015-11-19 23:00:41 UTC (rev 192662)
</span><span class="lines">@@ -55,6 +55,7 @@
</span><span class="cx">     DOMString debuggableType();
</span><span class="cx"> 
</span><span class="cx">     void copyText(DOMString text);
</span><ins>+    void killText(DOMString text, boolean shouldPrependToKillRing, boolean shouldStartNewSequence);
</ins><span class="cx">     void openInNewTab(DOMString url);
</span><span class="cx">     boolean canSave();
</span><span class="cx">     void save(DOMString url, DOMString content, boolean base64Encoded, boolean forceSaveAs);
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (192661 => 192662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog        2015-11-19 22:54:46 UTC (rev 192661)
+++ trunk/Source/WebInspectorUI/ChangeLog        2015-11-19 23:00:41 UTC (rev 192662)
</span><span class="lines">@@ -1,3 +1,61 @@
</span><ins>+2015-11-19  Brian Burg  &lt;bburg@apple.com&gt;
+
+        Web Inspector: yank/kill shortcuts (CTRL+Y, K) don't work in Console / QuickConsole
+        https://bugs.webkit.org/show_bug.cgi?id=151157
+
+        Reviewed by Joseph Pecoraro.
+
+        CodeMirror maintains its own editor buffer and implements its own
+        `killLine` command but doesn't implement the yank command. So, text
+        that is &quot;killed&quot; with CTRL-k inside a CodeMirror instance isn't
+        added to WebCore's kill ring. Subsequent yank commands won't match
+        up with the killed text, instead returning text from a prior kill
+        that was handled by WebCore (i.e., in a contenteditable or form input).
+
+        This patch adds a host function so that the Inspector frontend can
+        append &quot;missed&quot; killed text to WebCore's kill ring. Subsequent
+        yanks handled by WebCore will then match the text killed by CodeMirror.
+
+        In the frontend, we implement our own key binding handler for
+        CTRL-k that captures killed text, detects whether the kill
+        should start a new sequence, and sends it to WebCore. Because this
+        involves several flags and listeners, and we want this behavior for
+        all editable CodeMirror instances, the text kill handling is
+        factored into its own CodeMirrorTextKillController.
+
+        To add this behavior to all instances, this patch centralizes the
+        code that constructs a base CodeMirror instance, and attaches the
+        CodeMirrorTextKillController to all instances. The shortcut
+        does nothing when its CodeMirror instance is read-only.
+
+        The particulars of the kill controller are documented inline.
+
+        No new tests, because we need to use both InspectorFrontendHost
+        and TestRunner.execCommand, but the latter is not available in
+        the inspector context where we would need to simulate a kill.
+
+        * UserInterface/Controllers/CodeMirrorTextKillController.js: Added.
+        (WebInspector.CodeMirrorTextKillController):
+        (WebInspector.CodeMirrorTextKillController.prototype._handleKillLine):
+        (WebInspector.CodeMirrorTextKillController.prototype._handleTextChange):
+        (WebInspector.CodeMirrorTextKillController.prototype._handleEditorBlur):
+        (WebInspector.CodeMirrorTextKillController.prototype._handleSelectionOrCaretChange):
+        * UserInterface/Main.html:
+        * UserInterface/Protocol/InspectorFrontendHostStub.js:
+        (window.InspectorFrontendHost.WebInspector.InspectorFrontendHostStub.prototype.killText): Add a stub to avoid check-before-use.
+        * UserInterface/Views/BreakpointActionView.js:
+        (WebInspector.BreakpointActionView.prototype._updateBody):
+        * UserInterface/Views/CSSStyleDeclarationTextEditor.js:
+        (WebInspector.CSSStyleDeclarationTextEditor):
+        * UserInterface/Views/CodeMirrorEditor.js: Added.
+        (WebInspector.CodeMirrorEditor.create):
+        (WebInspector.CodeMirrorEditor):
+        * UserInterface/Views/ConsolePrompt.js:
+        (WebInspector.ConsolePrompt):
+        * UserInterface/Views/ScopeChainDetailsSidebarPanel.js:
+        * UserInterface/Views/TextEditor.js:
+        (WebInspector.TextEditor):
+
</ins><span class="cx"> 2015-11-19  Matt Baker  &lt;mattbaker@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: Convert remaining timeline views to use View base class
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceControllersBreakpointPopoverControllerjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/BreakpointPopoverController.js (192661 => 192662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Controllers/BreakpointPopoverController.js        2015-11-19 22:54:46 UTC (rev 192661)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/BreakpointPopoverController.js        2015-11-19 23:00:41 UTC (rev 192662)
</span><span class="lines">@@ -139,7 +139,7 @@
</span><span class="cx">         let conditionEditorElement = conditionData.appendChild(document.createElement(&quot;div&quot;));
</span><span class="cx">         conditionEditorElement.classList.add(&quot;edit-breakpoint-popover-condition&quot;, WebInspector.SyntaxHighlightedStyleClassName);
</span><span class="cx"> 
</span><del>-        this._conditionCodeMirror = CodeMirror(conditionEditorElement, {
</del><ins>+        this._conditionCodeMirror = WebInspector.CodeMirrorEditor.create(conditionEditorElement, {
</ins><span class="cx">             extraKeys: {Tab: false},
</span><span class="cx">             lineWrapping: false,
</span><span class="cx">             mode: &quot;text/javascript&quot;,
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceControllersCodeMirrorTextKillControllerjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Controllers/CodeMirrorTextKillController.js (0 => 192662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Controllers/CodeMirrorTextKillController.js                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/CodeMirrorTextKillController.js        2015-11-19 23:00:41 UTC (rev 192662)
</span><span class="lines">@@ -0,0 +1,121 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.CodeMirrorTextKillController = class CodeMirrorTextKillController extends WebInspector.Object
+{
+    constructor(codeMirror)
+    {
+        super();
+
+        console.assert(codeMirror);
+
+        this._codeMirror = codeMirror;
+        this._expectingChangeEventForKill = false;
+        this._nextKillStartsNewSequence = true;
+
+        this._handleTextChangeListener = this._handleTextChange.bind(this);
+        this._handleEditorBlurListener = this._handleEditorBlur.bind(this);
+        this._handleSelectionOrCaretChangeListener = this._handleSelectionOrCaretChange.bind(this);
+
+        this._codeMirror.addKeyMap({
+            &quot;Ctrl-K&quot;: this._handleKillLine.bind(this),
+        });
+    }
+
+    _handleKillLine(codeMirror)
+    {
+        // Read-only mode is dynamic in some editors, so check every time
+        // and ignore the shortcut if in read-only mode.
+        if (this._codeMirror.getOption(&quot;readOnly&quot;))
+            return;
+
+        // Don't add the listener if it's still registered because
+        // a previous empty kill didn't generate change events.
+        if (!this._expectingChangeEventForKill)
+            codeMirror.on(&quot;changes&quot;, this._handleTextChangeListener);
+
+        this._expectingChangeEventForKill = true;
+        codeMirror.execCommand(&quot;killLine&quot;);
+    }
+
+    _handleTextChange(codeMirror, changes)
+    {
+        this._codeMirror.off(&quot;changes&quot;, this._handleTextChangeListener);
+
+        // Sometimes a second change event fires after removing the listener
+        // if you perform an &quot;empty kill&quot; and type after moving the caret.
+        if (!this._expectingChangeEventForKill)
+            return;
+
+        this._expectingChangeEventForKill = false;
+
+        // It doesn't make sense to get more than one change per kill.
+        console.assert(changes.length === 1);
+        let change = changes[0];
+
+        // If an &quot;empty kill&quot; is followed by up/down or typing,
+        // the empty kill won't fire a change event, then we'll get an
+        // unrelated change event that shouldn't be treated as a kill.
+        if (change.origin !== &quot;+delete&quot;)
+            return;
+
+        // Killing a newline by itself is reported as deletion of two
+        // empty strings, so check the change's ranges to detect this.
+        let killedText;
+        if (change.to.line === change.from.line + 1)
+            killedText = &quot;\n&quot;;
+        else {
+            console.assert(change.removed.length === 1);
+            killedText = change.removed[0];
+        }
+
+        const shouldPrependToKillRing = false;
+        InspectorFrontendHost.killText(killedText, shouldPrependToKillRing, this._nextKillStartsNewSequence);
+
+        // If the editor loses focus or the caret / selection changes
+        // (not as a result of the kill), then the next kill should
+        // start a new kill ring sequence.
+        this._nextKillStartsNewSequence = false;
+        this._codeMirror.on(&quot;blur&quot;, this._handleEditorBlurListener);
+        this._codeMirror.on(&quot;cursorActivity&quot;, this._handleSelectionOrCaretChangeListener);
+    }
+
+    _handleEditorBlur(codeMirror)
+    {
+        this._nextKillStartsNewSequence = true;
+        this._codeMirror.off(&quot;blur&quot;, this._handleEditorBlurListener);
+        this._codeMirror.off(&quot;cursorActivity&quot;, this._handleSelectionOrCaretChangeListener);
+    }
+
+    _handleSelectionOrCaretChange(codeMirror)
+    {
+        if (this._expectingChangeEventForKill)
+            return;
+
+        this._nextKillStartsNewSequence = true;
+        this._codeMirror.off(&quot;blur&quot;, this._handleEditorBlurListener);
+        this._codeMirror.off(&quot;cursorActivity&quot;, this._handleSelectionOrCaretChangeListener);
+    }
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceMainhtml"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (192661 => 192662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Main.html        2015-11-19 22:54:46 UTC (rev 192661)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html        2015-11-19 23:00:41 UTC (rev 192662)
</span><span class="lines">@@ -417,6 +417,7 @@
</span><span class="cx">     &lt;script src=&quot;Views/ChartDetailsSectionRow.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Views/ClusterContentView.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Views/CodeMirrorAdditions.js&quot;&gt;&lt;/script&gt;
</span><ins>+    &lt;script src=&quot;Views/CodeMirrorEditor.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx">     &lt;script src=&quot;Views/CodeMirrorFormatters.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Views/CodeMirrorTextMarkers.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Views/ColorPicker.js&quot;&gt;&lt;/script&gt;
</span><span class="lines">@@ -599,6 +600,7 @@
</span><span class="cx">     &lt;script src=&quot;Controllers/CodeMirrorDragToAdjustNumberController.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Controllers/CodeMirrorGradientEditingController.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Controllers/CodeMirrorTokenTrackingController.js&quot;&gt;&lt;/script&gt;
</span><ins>+    &lt;script src=&quot;Controllers/CodeMirrorTextKillController.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx">     &lt;script src=&quot;Controllers/DOMTreeManager.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Controllers/DashboardManager.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Controllers/DebuggerManager.js&quot;&gt;&lt;/script&gt;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceProtocolInspectorFrontendHostStubjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorFrontendHostStub.js (192661 => 192662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorFrontendHostStub.js        2015-11-19 22:54:46 UTC (rev 192661)
+++ trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorFrontendHostStub.js        2015-11-19 23:00:41 UTC (rev 192662)
</span><span class="lines">@@ -122,6 +122,10 @@
</span><span class="cx">                 console.error(&quot;Clipboard access is denied&quot;);
</span><span class="cx">         },
</span><span class="cx"> 
</span><ins>+        killText: function(text, shouldStartNewSequence)
+        {
+        },
+
</ins><span class="cx">         openInNewTab: function(url)
</span><span class="cx">         {
</span><span class="cx">             window.open(url, &quot;_blank&quot;);
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsBreakpointActionViewjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/BreakpointActionView.js (192661 => 192662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/BreakpointActionView.js        2015-11-19 22:54:46 UTC (rev 192661)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/BreakpointActionView.js        2015-11-19 23:00:41 UTC (rev 192662)
</span><span class="lines">@@ -149,7 +149,7 @@
</span><span class="cx">             editorElement.classList.add(&quot;breakpoint-action-eval-editor&quot;);
</span><span class="cx">             editorElement.classList.add(WebInspector.SyntaxHighlightedStyleClassName);
</span><span class="cx"> 
</span><del>-            this._codeMirror = CodeMirror(editorElement, {
</del><ins>+            this._codeMirror = WebInspector.CodeMirrorEditor.create(editorElement, {
</ins><span class="cx">                 lineWrapping: true,
</span><span class="cx">                 mode: &quot;text/javascript&quot;,
</span><span class="cx">                 indentWithTabs: true,
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsCSSStyleDeclarationTextEditorjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationTextEditor.js (192661 => 192662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationTextEditor.js        2015-11-19 22:54:46 UTC (rev 192661)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationTextEditor.js        2015-11-19 23:00:41 UTC (rev 192662)
</span><span class="lines">@@ -49,7 +49,7 @@
</span><span class="cx"> 
</span><span class="cx">         this._delegate = delegate || null;
</span><span class="cx"> 
</span><del>-        this._codeMirror = CodeMirror(this.element, {
</del><ins>+        this._codeMirror = WebInspector.CodeMirrorEditor.create(this.element, {
</ins><span class="cx">             readOnly: true,
</span><span class="cx">             lineWrapping: true,
</span><span class="cx">             mode: &quot;css-rule&quot;,
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsCodeMirrorEditorjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Views/CodeMirrorEditor.js (0 => 192662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/CodeMirrorEditor.js                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/CodeMirrorEditor.js        2015-11-19 23:00:41 UTC (rev 192662)
</span><span class="lines">@@ -0,0 +1,38 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.CodeMirrorEditor = class CodeMirrorEditor
+{
+    static create(place, options)
+    {
+        let codeMirror = new CodeMirror(place, options);
+
+        // Set up default controllers that should be present for
+        // all CodeMirror editor instances.
+        new WebInspector.CodeMirrorTextKillController(codeMirror);
+
+        return codeMirror;
+    }
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsConsolePromptjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ConsolePrompt.js (192661 => 192662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/ConsolePrompt.js        2015-11-19 22:54:46 UTC (rev 192661)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ConsolePrompt.js        2015-11-19 23:00:41 UTC (rev 192662)
</span><span class="lines">@@ -35,7 +35,7 @@
</span><span class="cx"> 
</span><span class="cx">         this._delegate = delegate || null;
</span><span class="cx"> 
</span><del>-        this._codeMirror = CodeMirror(this.element, {
</del><ins>+        this._codeMirror = WebInspector.CodeMirrorEditor.create(this.element, {
</ins><span class="cx">             lineWrapping: true,
</span><span class="cx">             mode: mimeType,
</span><span class="cx">             indentWithTabs: true,
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsScopeChainDetailsSidebarPaneljs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ScopeChainDetailsSidebarPanel.js (192661 => 192662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/ScopeChainDetailsSidebarPanel.js        2015-11-19 22:54:46 UTC (rev 192661)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ScopeChainDetailsSidebarPanel.js        2015-11-19 23:00:41 UTC (rev 192662)
</span><span class="lines">@@ -316,7 +316,7 @@
</span><span class="cx">         let editorElement = content.appendChild(document.createElement(&quot;div&quot;));
</span><span class="cx">         editorElement.classList.add(&quot;watch-expression-editor&quot;, WebInspector.SyntaxHighlightedStyleClassName);
</span><span class="cx"> 
</span><del>-        this._codeMirror = CodeMirror(editorElement, {
</del><ins>+        this._codeMirror = WebInspector.CodeMirrorEditor.create(editorElement, {
</ins><span class="cx">             lineWrapping: true,
</span><span class="cx">             mode: &quot;text/javascript&quot;,
</span><span class="cx">             indentWithTabs: true,
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsTextEditorjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TextEditor.js (192661 => 192662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/TextEditor.js        2015-11-19 22:54:46 UTC (rev 192661)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TextEditor.js        2015-11-19 23:00:41 UTC (rev 192662)
</span><span class="lines">@@ -32,7 +32,7 @@
</span><span class="cx">         this.element.classList.add(&quot;text-editor&quot;, WebInspector.SyntaxHighlightedStyleClassName);
</span><span class="cx"> 
</span><span class="cx">         // FIXME: &lt;https://webkit.org/b/149120&gt; Web Inspector: Preferences for Text Editor behavior
</span><del>-        this._codeMirror = CodeMirror(this.element, {
</del><ins>+        this._codeMirror = WebInspector.CodeMirrorEditor.create(this.element, {
</ins><span class="cx">             readOnly: true,
</span><span class="cx">             indentWithTabs: true,
</span><span class="cx">             indentUnit: 4,
</span></span></pre>
</div>
</div>

</body>
</html>