<!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>[164436] trunk/Source/WebInspectorUI</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/164436">164436</a></dd>
<dt>Author</dt> <dd>graouts@webkit.org</dd>
<dt>Date</dt> <dd>2014-02-20 10:48:51 -0800 (Thu, 20 Feb 2014)</dd>
</dl>
<h3>Log Message</h3>
<pre>Web Inspector: create a CodeMirrorEditingController superclass
https://bugs.webkit.org/show_bug.cgi?id=129094
Reviewed by Timothy Hatcher.
Take code that is generic to editing of any text marker out of CodeMirrorColorEditingController to
create a new CodeMirrorEditingController superclass that'll be fit to use for future editing controllers.
Additioanlly, we fix existing issues with such editing by supporting text markers spread across several
lines and more robustly handling the Esc. key being pressed to dismiss a controller's popover.
* UserInterface/CSSStyleDeclarationTextEditor.js:
(WebInspector.CSSStyleDeclarationTextEditor.prototype._createColorSwatches):
Adopt the new .createColorMarkers() method signature to provide a TextRange parameter rather than a single
line number.
* UserInterface/CodeMirrorAdditions.js:
Remove the .boundsForRange() method in favor of a .rectsForRange() method which will allow us to draw better
menus when hovering over a text range by providing tight bounds rather than a large box. We also handle any
line wrapping produced by CodeMirror and remove any leading white-space so that the rects are tight to the
actual characters in the text marker.
We also change .createColorMarkers() to take in a TextRange parameter rather than a line number in order to
better deal with text markers spread across multiple lines.
* UserInterface/CodeMirrorColorEditingController.js:
Remove any code that is adequate for any editing controller (which is moving to CodeMirrorEditingController).
We also adopt new interfaces exposed by CodeMirrorEditingController.
(WebInspector.CodeMirrorColorEditingController):
(WebInspector.CodeMirrorColorEditingController.prototype.get initialValue):
(WebInspector.CodeMirrorColorEditingController.prototype.get cssClassName):
(WebInspector.CodeMirrorColorEditingController.prototype.popoverWillPresent):
(WebInspector.CodeMirrorColorEditingController.prototype.popoverDidPresent):
(WebInspector.CodeMirrorColorEditingController.prototype._colorPickerColorChanged):
* UserInterface/CodeMirrorEditingController.js: Copied from Source/WebInspectorUI/UserInterface/CodeMirrorColorEditingController.js.
New class meant to be subclassed by any future editing controller, and already subclassed by
CodeMirrorColorEditingController. This class exposes several hooks for subclasses to customize its behavior:
.initialValue: a value we can revert to if the editing is canceled
.cssClassName: a CSS class name that can be added to the editing controller's container
.popoverPreferredEdges: a list of preferredEdges as passed to Popover.prototype.present() with a sensible default
.popoverTargetFrameWithRects: a targetFrame passed to Popover.prototype.present(), defaults to a union of provided rects
.popoverWillPresent: called as the popover is about to be presented, typically overridden to set the popover's content
.popoverDidPresent: called as the popover just was presented, typically overridden when content needs to tuned only after
being added to the DOM and setting of the necessary machinery to update the serialized value in the editor based on interaction
within the popover without changing the serialized value upon showing the popover the very first time.
Additionally, the .value property must be an object supporting .toString() and .copy() method.
Finally, the .editingControllerDidStartEditing() and .editingControllerDidFinishEditing() delegate methods are fired
as editing begins and finishes.
(WebInspector.CodeMirrorEditingController):
(WebInspector.CodeMirrorEditingController.prototype.get marker):
(WebInspector.CodeMirrorEditingController.prototype.get range):
(WebInspector.CodeMirrorEditingController.prototype.get value):
(WebInspector.CodeMirrorEditingController.prototype.set value):
(WebInspector.CodeMirrorEditingController.prototype.get delegate):
(WebInspector.CodeMirrorEditingController.prototype.set delegate):
(WebInspector.CodeMirrorEditingController.prototype.get text):
(WebInspector.CodeMirrorEditingController.prototype.set text):
(WebInspector.CodeMirrorEditingController.prototype.get initialValue):
(WebInspector.CodeMirrorEditingController.prototype.get cssClassName):
(WebInspector.CodeMirrorEditingController.prototype.get popover):
(WebInspector.CodeMirrorEditingController.prototype.get popoverPreferredEdges):
(WebInspector.CodeMirrorEditingController.prototype.popoverTargetFrameWithRects):
(WebInspector.CodeMirrorEditingController.prototype.presentHoverMenu):
(WebInspector.CodeMirrorEditingController.prototype.dismissHoverMenu):
(WebInspector.CodeMirrorEditingController.prototype.popoverWillPresent):
(WebInspector.CodeMirrorEditingController.prototype.popoverDidPresent):
(WebInspector.CodeMirrorEditingController.prototype.handleKeydownEvent):
Event handler for keydown events as registered via the new WebInspector.addWindowKeydownListener() method.
(WebInspector.CodeMirrorEditingController.prototype.hoverMenuButtonWasPressed):
(WebInspector.CodeMirrorEditingController.prototype.didDismissPopover):
* UserInterface/Geometry.js:
(WebInspector.Rect.unionOfRects):
(WebInspector.Rect.prototype.unionWithRect):
New utilities to get a Rect that is the union of the provided Rect or array of Rects.
(WebInspector.Polygon):
(WebInspector.Polygon.prototype.bounds):
New class used to store a list of points for a polygon and get its bounds, used by the HoverMenu class.
* UserInterface/HoverMenu.css:
(.hover-menu):
(.hover-menu > svg):
(.hover-menu > svg > rect):
(.hover-menu > img):
* UserInterface/HoverMenu.js:
We remove the assumption that a HoverMenu is only used to draw a single rounded rect based on a simple
Rect and instead support presentation based on an array of Rects where we either:
- draw a single rounded rectangle if there is only a single Rect provided
- draw two disconnected open-ended rects if we're provided with two non-overlapping Rects
- draw a polygon surrounding all provided Rects in all other cases
No matter how the HoverMenu is drawn, the drawing is performed in SVG with either <rect> or a <path> elements.
(WebInspector.HoverMenu):
(WebInspector.HoverMenu.prototype.present):
(WebInspector.HoverMenu.prototype.dismiss):
(WebInspector.HoverMenu.prototype.handleEvent):
(WebInspector.HoverMenu.prototype._handleClickEvent):
(WebInspector.HoverMenu.prototype._drawOutline):
(WebInspector.HoverMenu.prototype._addRect):
(WebInspector.HoverMenu.prototype._addPath):
(WebInspector.HoverMenu.prototype._drawSingleLine):
(WebInspector.HoverMenu.prototype._drawTwoNonOverlappingLines):
(WebInspector.HoverMenu.prototype._drawOverlappingLines):
* UserInterface/Main.html:
Link to the new CodeMirrorEditingController class.
* UserInterface/Main.js:
Expose a new mechanism to deal with window-level handling of keydown events in order to allow
a list of handlers to accept or reject dealing with the provided keydown event based on the order
they were registered, in most recent to oldest registered handler. This allows, for instance, for
a more graceful handling of the Esc. key being pressed in the CodeMirrorEditingController and
bypasses the DOM structure allowing for objects managing elements in different DOM hierarchies
to compete with handling of keydown events.
(WebInspector.loaded):
(WebInspector.addWindowKeydownListener):
(WebInspector.removeWindowKeydownListener):
(WebInspector._updateWindowKeydownListener):
(WebInspector._sharedWindowKeydownListener):
* UserInterface/SourceCodeTextEditor.css:
(.hover-menu.color > img):
Update the offset applied to a HoverMenu button based on the change of layout for such buttons which
are now absolutely positioned in code by HoverMenu rather than being laid out using the flex-box model.
* UserInterface/SourceCodeTextEditor.js:
Abstrct away the assumption that only a color editing controller may be used to edit text markers in
a source code text editor.
(WebInspector.SourceCodeTextEditor.prototype.hidden):
Ensure we remove any currently-displayed hover menu for an editing controller when the editor is hidden.
This would happen in the situation where a keyboard shortcut was used to jump to another part of the
Web Inspector UI without using the mouse.
(WebInspector.SourceCodeTextEditor.prototype.contentDidChange):
Since we're now working with text ranges rather than lines, remove the code where we'd work out a set of
changed lines and call ._updateEditableMarkers() with the changed range directly instead.
(WebInspector.SourceCodeTextEditor.prototype._contentDidPopulate):
(WebInspector.SourceCodeTextEditor.prototype.tokenTrackingControllerNewHighlightCandidate):
(WebInspector.SourceCodeTextEditor.prototype.tokenTrackingControllerMouseOutOfHoveredMarker):
Adopt the more generic method names rather than color-specific ones.
(WebInspector.SourceCodeTextEditor.prototype._showPopover):
When showing the popover outside of the use of a CodeMirrorEditingController, such as a JavaScript expression
when debugging, also deal with the possibility of the highlighted range containing multiple lines rather
than assume a single line.
(WebInspector.SourceCodeTextEditor.prototype._updateEditableMarkers):
More generic method name to support future, non-color editing controllers.
(WebInspector.SourceCodeTextEditor.prototype._tokenTrackingControllerHighlightedMarkedExpression):
Find the outermost marker in the list of markers provided such that a marker containing other markers
shows the UI for the containing marker. For instance, a gradient marker would contain several color
markers and it's preferable to show the editing UI for the whole gradient rather than a specific color.
Additionally, adopt more generic ivars and method names to support future, non-color editing controllers.
(WebInspector.SourceCodeTextEditor.prototype._dismissEditingController):
Support for new parameter instructing that the editing controller dismissal should be instant rather than
animated, which is the default. This is useful when, for instance, the text editor is cleared.
(WebInspector.SourceCodeTextEditor.prototype.editingControllerDidStartEditing):
(WebInspector.SourceCodeTextEditor.prototype.editingControllerDidFinishEditing):
Adopt the more generic method names rather than color-specific ones.
* UserInterface/TextEditor.js:
(WebInspector.TextEditor.prototype.rectsForRange):
Remove .boundsForRange() in favor of this new method where we return a series of rects so that we may
draw a more pleasing HoverMenu.
(WebInspector.TextEditor.prototype.createColorMarkers):
Use a TextRanger rather than a single line number to match the underlying CodeMirror extension method.
(WebInspector.TextEditor.prototype.editingControllerForMarker):
Use the provided TextMarker's type to provide the most adequate CodeMirrorEditingController class.
* UserInterface/TextMarker.js:
(WebInspector.TextMarker.prototype.get rects):
Remove the .bounds property in favor of .rects to match the underlying CodeMirror extension method.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIChangeLog">trunk/Source/WebInspectorUI/ChangeLog</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceCSSStyleDeclarationTextEditorjs">trunk/Source/WebInspectorUI/UserInterface/CSSStyleDeclarationTextEditor.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceCodeMirrorAdditionsjs">trunk/Source/WebInspectorUI/UserInterface/CodeMirrorAdditions.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceCodeMirrorColorEditingControllerjs">trunk/Source/WebInspectorUI/UserInterface/CodeMirrorColorEditingController.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceGeometryjs">trunk/Source/WebInspectorUI/UserInterface/Geometry.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceHoverMenucss">trunk/Source/WebInspectorUI/UserInterface/HoverMenu.css</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceHoverMenujs">trunk/Source/WebInspectorUI/UserInterface/HoverMenu.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceMainhtml">trunk/Source/WebInspectorUI/UserInterface/Main.html</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceMainjs">trunk/Source/WebInspectorUI/UserInterface/Main.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceSourceCodeTextEditorcss">trunk/Source/WebInspectorUI/UserInterface/SourceCodeTextEditor.css</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceSourceCodeTextEditorjs">trunk/Source/WebInspectorUI/UserInterface/SourceCodeTextEditor.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTextEditorjs">trunk/Source/WebInspectorUI/UserInterface/TextEditor.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTextMarkerjs">trunk/Source/WebInspectorUI/UserInterface/TextMarker.js</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceCodeMirrorEditingControllerjs">trunk/Source/WebInspectorUI/UserInterface/CodeMirrorEditingController.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (164435 => 164436)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog 2014-02-20 18:23:24 UTC (rev 164435)
+++ trunk/Source/WebInspectorUI/ChangeLog 2014-02-20 18:48:51 UTC (rev 164436)
</span><span class="lines">@@ -1,5 +1,200 @@
</span><span class="cx"> 2014-02-20 Antoine Quint <graouts@webkit.org>
</span><span class="cx">
</span><ins>+ Web Inspector: create a CodeMirrorEditingController superclass
+ https://bugs.webkit.org/show_bug.cgi?id=129094
+
+ Reviewed by Timothy Hatcher.
+
+ Take code that is generic to editing of any text marker out of CodeMirrorColorEditingController to
+ create a new CodeMirrorEditingController superclass that'll be fit to use for future editing controllers.
+ Additioanlly, we fix existing issues with such editing by supporting text markers spread across several
+ lines and more robustly handling the Esc. key being pressed to dismiss a controller's popover.
+
+ * UserInterface/CSSStyleDeclarationTextEditor.js:
+ (WebInspector.CSSStyleDeclarationTextEditor.prototype._createColorSwatches):
+ Adopt the new .createColorMarkers() method signature to provide a TextRange parameter rather than a single
+ line number.
+
+ * UserInterface/CodeMirrorAdditions.js:
+ Remove the .boundsForRange() method in favor of a .rectsForRange() method which will allow us to draw better
+ menus when hovering over a text range by providing tight bounds rather than a large box. We also handle any
+ line wrapping produced by CodeMirror and remove any leading white-space so that the rects are tight to the
+ actual characters in the text marker.
+
+ We also change .createColorMarkers() to take in a TextRange parameter rather than a line number in order to
+ better deal with text markers spread across multiple lines.
+
+ * UserInterface/CodeMirrorColorEditingController.js:
+ Remove any code that is adequate for any editing controller (which is moving to CodeMirrorEditingController).
+ We also adopt new interfaces exposed by CodeMirrorEditingController.
+
+ (WebInspector.CodeMirrorColorEditingController):
+ (WebInspector.CodeMirrorColorEditingController.prototype.get initialValue):
+ (WebInspector.CodeMirrorColorEditingController.prototype.get cssClassName):
+ (WebInspector.CodeMirrorColorEditingController.prototype.popoverWillPresent):
+ (WebInspector.CodeMirrorColorEditingController.prototype.popoverDidPresent):
+ (WebInspector.CodeMirrorColorEditingController.prototype._colorPickerColorChanged):
+
+ * UserInterface/CodeMirrorEditingController.js: Copied from Source/WebInspectorUI/UserInterface/CodeMirrorColorEditingController.js.
+ New class meant to be subclassed by any future editing controller, and already subclassed by
+ CodeMirrorColorEditingController. This class exposes several hooks for subclasses to customize its behavior:
+
+ .initialValue: a value we can revert to if the editing is canceled
+ .cssClassName: a CSS class name that can be added to the editing controller's container
+ .popoverPreferredEdges: a list of preferredEdges as passed to Popover.prototype.present() with a sensible default
+ .popoverTargetFrameWithRects: a targetFrame passed to Popover.prototype.present(), defaults to a union of provided rects
+ .popoverWillPresent: called as the popover is about to be presented, typically overridden to set the popover's content
+ .popoverDidPresent: called as the popover just was presented, typically overridden when content needs to tuned only after
+ being added to the DOM and setting of the necessary machinery to update the serialized value in the editor based on interaction
+ within the popover without changing the serialized value upon showing the popover the very first time.
+
+ Additionally, the .value property must be an object supporting .toString() and .copy() method.
+
+ Finally, the .editingControllerDidStartEditing() and .editingControllerDidFinishEditing() delegate methods are fired
+ as editing begins and finishes.
+
+ (WebInspector.CodeMirrorEditingController):
+ (WebInspector.CodeMirrorEditingController.prototype.get marker):
+ (WebInspector.CodeMirrorEditingController.prototype.get range):
+ (WebInspector.CodeMirrorEditingController.prototype.get value):
+ (WebInspector.CodeMirrorEditingController.prototype.set value):
+ (WebInspector.CodeMirrorEditingController.prototype.get delegate):
+ (WebInspector.CodeMirrorEditingController.prototype.set delegate):
+ (WebInspector.CodeMirrorEditingController.prototype.get text):
+ (WebInspector.CodeMirrorEditingController.prototype.set text):
+ (WebInspector.CodeMirrorEditingController.prototype.get initialValue):
+ (WebInspector.CodeMirrorEditingController.prototype.get cssClassName):
+ (WebInspector.CodeMirrorEditingController.prototype.get popover):
+ (WebInspector.CodeMirrorEditingController.prototype.get popoverPreferredEdges):
+ (WebInspector.CodeMirrorEditingController.prototype.popoverTargetFrameWithRects):
+ (WebInspector.CodeMirrorEditingController.prototype.presentHoverMenu):
+ (WebInspector.CodeMirrorEditingController.prototype.dismissHoverMenu):
+ (WebInspector.CodeMirrorEditingController.prototype.popoverWillPresent):
+ (WebInspector.CodeMirrorEditingController.prototype.popoverDidPresent):
+
+ (WebInspector.CodeMirrorEditingController.prototype.handleKeydownEvent):
+ Event handler for keydown events as registered via the new WebInspector.addWindowKeydownListener() method.
+
+ (WebInspector.CodeMirrorEditingController.prototype.hoverMenuButtonWasPressed):
+ (WebInspector.CodeMirrorEditingController.prototype.didDismissPopover):
+
+ * UserInterface/Geometry.js:
+ (WebInspector.Rect.unionOfRects):
+ (WebInspector.Rect.prototype.unionWithRect):
+ New utilities to get a Rect that is the union of the provided Rect or array of Rects.
+
+ (WebInspector.Polygon):
+ (WebInspector.Polygon.prototype.bounds):
+ New class used to store a list of points for a polygon and get its bounds, used by the HoverMenu class.
+
+ * UserInterface/HoverMenu.css:
+ (.hover-menu):
+ (.hover-menu > svg):
+ (.hover-menu > svg > rect):
+ (.hover-menu > img):
+
+ * UserInterface/HoverMenu.js:
+ We remove the assumption that a HoverMenu is only used to draw a single rounded rect based on a simple
+ Rect and instead support presentation based on an array of Rects where we either:
+
+ - draw a single rounded rectangle if there is only a single Rect provided
+ - draw two disconnected open-ended rects if we're provided with two non-overlapping Rects
+ - draw a polygon surrounding all provided Rects in all other cases
+
+ No matter how the HoverMenu is drawn, the drawing is performed in SVG with either <rect> or a <path> elements.
+
+ (WebInspector.HoverMenu):
+ (WebInspector.HoverMenu.prototype.present):
+ (WebInspector.HoverMenu.prototype.dismiss):
+ (WebInspector.HoverMenu.prototype.handleEvent):
+ (WebInspector.HoverMenu.prototype._handleClickEvent):
+ (WebInspector.HoverMenu.prototype._drawOutline):
+ (WebInspector.HoverMenu.prototype._addRect):
+ (WebInspector.HoverMenu.prototype._addPath):
+ (WebInspector.HoverMenu.prototype._drawSingleLine):
+ (WebInspector.HoverMenu.prototype._drawTwoNonOverlappingLines):
+ (WebInspector.HoverMenu.prototype._drawOverlappingLines):
+
+ * UserInterface/Main.html:
+ Link to the new CodeMirrorEditingController class.
+
+ * UserInterface/Main.js:
+ Expose a new mechanism to deal with window-level handling of keydown events in order to allow
+ a list of handlers to accept or reject dealing with the provided keydown event based on the order
+ they were registered, in most recent to oldest registered handler. This allows, for instance, for
+ a more graceful handling of the Esc. key being pressed in the CodeMirrorEditingController and
+ bypasses the DOM structure allowing for objects managing elements in different DOM hierarchies
+ to compete with handling of keydown events.
+
+ (WebInspector.loaded):
+ (WebInspector.addWindowKeydownListener):
+ (WebInspector.removeWindowKeydownListener):
+ (WebInspector._updateWindowKeydownListener):
+ (WebInspector._sharedWindowKeydownListener):
+
+ * UserInterface/SourceCodeTextEditor.css:
+ (.hover-menu.color > img):
+ Update the offset applied to a HoverMenu button based on the change of layout for such buttons which
+ are now absolutely positioned in code by HoverMenu rather than being laid out using the flex-box model.
+
+ * UserInterface/SourceCodeTextEditor.js:
+ Abstrct away the assumption that only a color editing controller may be used to edit text markers in
+ a source code text editor.
+
+ (WebInspector.SourceCodeTextEditor.prototype.hidden):
+ Ensure we remove any currently-displayed hover menu for an editing controller when the editor is hidden.
+ This would happen in the situation where a keyboard shortcut was used to jump to another part of the
+ Web Inspector UI without using the mouse.
+
+ (WebInspector.SourceCodeTextEditor.prototype.contentDidChange):
+ Since we're now working with text ranges rather than lines, remove the code where we'd work out a set of
+ changed lines and call ._updateEditableMarkers() with the changed range directly instead.
+
+ (WebInspector.SourceCodeTextEditor.prototype._contentDidPopulate):
+ (WebInspector.SourceCodeTextEditor.prototype.tokenTrackingControllerNewHighlightCandidate):
+ (WebInspector.SourceCodeTextEditor.prototype.tokenTrackingControllerMouseOutOfHoveredMarker):
+ Adopt the more generic method names rather than color-specific ones.
+
+ (WebInspector.SourceCodeTextEditor.prototype._showPopover):
+ When showing the popover outside of the use of a CodeMirrorEditingController, such as a JavaScript expression
+ when debugging, also deal with the possibility of the highlighted range containing multiple lines rather
+ than assume a single line.
+
+ (WebInspector.SourceCodeTextEditor.prototype._updateEditableMarkers):
+ More generic method name to support future, non-color editing controllers.
+
+ (WebInspector.SourceCodeTextEditor.prototype._tokenTrackingControllerHighlightedMarkedExpression):
+ Find the outermost marker in the list of markers provided such that a marker containing other markers
+ shows the UI for the containing marker. For instance, a gradient marker would contain several color
+ markers and it's preferable to show the editing UI for the whole gradient rather than a specific color.
+
+ Additionally, adopt more generic ivars and method names to support future, non-color editing controllers.
+
+ (WebInspector.SourceCodeTextEditor.prototype._dismissEditingController):
+ Support for new parameter instructing that the editing controller dismissal should be instant rather than
+ animated, which is the default. This is useful when, for instance, the text editor is cleared.
+
+ (WebInspector.SourceCodeTextEditor.prototype.editingControllerDidStartEditing):
+ (WebInspector.SourceCodeTextEditor.prototype.editingControllerDidFinishEditing):
+ Adopt the more generic method names rather than color-specific ones.
+
+ * UserInterface/TextEditor.js:
+ (WebInspector.TextEditor.prototype.rectsForRange):
+ Remove .boundsForRange() in favor of this new method where we return a series of rects so that we may
+ draw a more pleasing HoverMenu.
+
+ (WebInspector.TextEditor.prototype.createColorMarkers):
+ Use a TextRanger rather than a single line number to match the underlying CodeMirror extension method.
+
+ (WebInspector.TextEditor.prototype.editingControllerForMarker):
+ Use the provided TextMarker's type to provide the most adequate CodeMirrorEditingController class.
+
+ * UserInterface/TextMarker.js:
+ (WebInspector.TextMarker.prototype.get rects):
+ Remove the .bounds property in favor of .rects to match the underlying CodeMirror extension method.
+
+2014-02-20 Antoine Quint <graouts@webkit.org>
+
</ins><span class="cx"> Web Inspector: Popover should animate its frame to display its refreshed content
</span><span class="cx"> https://bugs.webkit.org/show_bug.cgi?id=129088
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceCSSStyleDeclarationTextEditorjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/CSSStyleDeclarationTextEditor.js (164435 => 164436)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/CSSStyleDeclarationTextEditor.js 2014-02-20 18:23:24 UTC (rev 164435)
+++ trunk/Source/WebInspectorUI/UserInterface/CSSStyleDeclarationTextEditor.js 2014-02-20 18:48:51 UTC (rev 164436)
</span><span class="lines">@@ -390,8 +390,10 @@
</span><span class="cx"> {
</span><span class="cx"> function update()
</span><span class="cx"> {
</span><ins>+ var range = typeof lineNumber === "number" ? new WebInspector.TextRange(lineNumber, 0, lineNumber + 1, 0) : null;
+
</ins><span class="cx"> // Look for color strings and add swatches in front of them.
</span><del>- this._codeMirror.createColorMarkers(lineNumber, function(marker, color, colorString) {
</del><ins>+ this._codeMirror.createColorMarkers(range, function(marker, color, colorString) {
</ins><span class="cx"> var swatchElement = document.createElement("span");
</span><span class="cx"> swatchElement.title = WebInspector.UIString("Click to open a colorpicker. Shift-click to change color format.");
</span><span class="cx"> swatchElement.className = WebInspector.CSSStyleDeclarationTextEditor.ColorSwatchElementStyleClassName;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceCodeMirrorAdditionsjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/CodeMirrorAdditions.js (164435 => 164436)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/CodeMirrorAdditions.js 2014-02-20 18:23:24 UTC (rev 164435)
+++ trunk/Source/WebInspectorUI/UserInterface/CodeMirrorAdditions.js 2014-02-20 18:48:51 UTC (rev 164436)
</span><span class="lines">@@ -418,17 +418,50 @@
</span><span class="cx"> return CodeMirror.Pass;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- CodeMirror.defineExtension("boundsForRange", function(range) {
- var firstCharCoords = this.cursorCoords(range.start);
- var lastCharCoords = this.cursorCoords(range.end);
- return new WebInspector.Rect(firstCharCoords.left, firstCharCoords.top, lastCharCoords.right - firstCharCoords.left, firstCharCoords.bottom - firstCharCoords.top);
</del><ins>+ CodeMirror.defineExtension("rectsForRange", function(range) {
+ var lineRects = [];
+
+ for (var line = range.start.line; line <= range.end.line; ++line) {
+ var lineContent = this.getLine(line);
+
+ var startChar = line === range.start.line ? range.start.ch : (lineContent.length - lineContent.trimLeft().length);
+ var endChar = line === range.end.line ? range.end.ch : lineContent.length;
+ var firstCharCoords = this.cursorCoords({ch: startChar, line: line});
+ var endCharCoords = this.cursorCoords({ch: endChar, line: line});
+
+ // Handle line wrapping.
+ if (firstCharCoords.bottom !== endCharCoords.bottom) {
+ var maxY = -Number.MAX_VALUE;
+ for (var ch = startChar; ch <= endChar; ++ch) {
+ var coords = this.cursorCoords({ch: ch, line: line});
+ if (coords.bottom > maxY) {
+ if (ch > startChar) {
+ var maxX = Math.ceil(this.cursorCoords({ch: ch - 1, line: line}).right);
+ lineRects.push(new WebInspector.Rect(minX, minY, maxX - minX, maxY - minY));
+ }
+ var minX = Math.floor(coords.left);
+ var minY = Math.floor(coords.top)
+ maxY = Math.ceil(coords.bottom);
+ }
+ }
+ maxX = Math.ceil(coords.right);
+ lineRects.push(new WebInspector.Rect(minX, minY, maxX - minX, maxY - minY));
+ } else {
+ var minX = Math.floor(firstCharCoords.left);
+ var minY = Math.floor(firstCharCoords.top);
+ var maxX = Math.ceil(endCharCoords.right);
+ var maxY = Math.ceil(endCharCoords.bottom);
+ lineRects.push(new WebInspector.Rect(minX, minY, maxX - minX, maxY - minY));
+ }
+ }
+ return lineRects;
</ins><span class="cx"> });
</span><span class="cx">
</span><del>- CodeMirror.defineExtension("createColorMarkers", function(lineNumber, callback) {
</del><ins>+ CodeMirror.defineExtension("createColorMarkers", function(range, callback) {
</ins><span class="cx"> var createdMarkers = [];
</span><span class="cx">
</span><del>- var start = typeof lineNumber === "number" ? lineNumber : 0;
- var end = typeof lineNumber === "number" ? lineNumber + 1 : this.lineCount();
</del><ins>+ var start = range instanceof WebInspector.TextRange ? range.startLine : 0;
+ var end = range instanceof WebInspector.TextRange ? range.endLine + 1 : this.lineCount();
</ins><span class="cx">
</span><span class="cx"> // Matches rgba(0, 0, 0, 0.5), rgb(0, 0, 0), hsl(), hsla(), #fff, #ffffff, white
</span><span class="cx"> const colorRegex = /((?:rgb|hsl)a?\([^)]+\)|#[0-9a-fA-F]{6}|#[0-9a-fA-F]{3}|\b\w+\b(?![-.]))/g;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceCodeMirrorColorEditingControllerjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/CodeMirrorColorEditingController.js (164435 => 164436)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/CodeMirrorColorEditingController.js 2014-02-20 18:23:24 UTC (rev 164435)
+++ trunk/Source/WebInspectorUI/UserInterface/CodeMirrorColorEditingController.js 2014-02-20 18:48:51 UTC (rev 164436)
</span><span class="lines">@@ -25,137 +25,41 @@
</span><span class="cx">
</span><span class="cx"> WebInspector.CodeMirrorColorEditingController = function(codeMirror, marker)
</span><span class="cx"> {
</span><del>- WebInspector.Object.call(this);
-
- this._codeMirror = codeMirror;
- this._marker = marker;
- this._delegate = null;
-
- this._range = marker.range;
- this._color = WebInspector.Color.fromString(this.text);
-
- this._keyboardShortcutEsc = new WebInspector.KeyboardShortcut(null, WebInspector.KeyboardShortcut.Key.Escape);
</del><ins>+ WebInspector.CodeMirrorEditingController.call(this, codeMirror, marker);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> WebInspector.CodeMirrorColorEditingController.prototype = {
</span><span class="cx"> constructor: WebInspector.CodeMirrorColorEditingController,
</span><del>- __proto__: WebInspector.Object.prototype,
</del><ins>+ __proto__: WebInspector.CodeMirrorEditingController.prototype,
</ins><span class="cx">
</span><span class="cx"> // Public
</span><del>-
- get marker()
- {
- return this._marker;
- },
-
- get range()
- {
- return this._range;
- },
</del><span class="cx">
</span><del>- get color()
</del><ins>+ get initialValue()
</ins><span class="cx"> {
</span><del>- return this._color;
</del><ins>+ return WebInspector.Color.fromString(this.text);
</ins><span class="cx"> },
</span><del>-
- set color(color)
- {
- this.text = color.toString();
- this._color = color;
- },
</del><span class="cx">
</span><del>- get delegate()
</del><ins>+ get cssClassName()
</ins><span class="cx"> {
</span><del>- return this._delegate;
</del><ins>+ return "color";
</ins><span class="cx"> },
</span><span class="cx">
</span><del>- set delegate(delegate)
</del><ins>+ popoverWillPresent: function(popover)
</ins><span class="cx"> {
</span><del>- this._delegate = delegate;
</del><ins>+ this._colorPicker = new WebInspector.ColorPicker;
+ this._colorPicker.addEventListener(WebInspector.ColorPicker.Event.ColorChanged, this._colorPickerColorChanged, this);
+ popover.content = this._colorPicker.element;
</ins><span class="cx"> },
</span><span class="cx">
</span><del>- get text()
</del><ins>+ popoverDidPresent: function(popover)
</ins><span class="cx"> {
</span><del>- var from = {line: this._range.startLine, ch: this._range.startColumn};
- var to = {line: this._range.endLine, ch: this._range.endColumn};
- return this._codeMirror.getRange(from, to);
</del><ins>+ this._colorPicker.color = this._value;
</ins><span class="cx"> },
</span><del>-
- set text(text)
- {
- var from = {line: this._range.startLine, ch: this._range.startColumn};
- var to = {line: this._range.endLine, ch: this._range.endColumn};
- this._codeMirror.replaceRange(text, from, to);
</del><span class="cx">
</span><del>- var lines = text.split("\n");
- var endLine = this._range.startLine + lines.length - 1;
- var endColumn = lines.length > 1 ? lines.lastValue.length : this._range.startColumn + text.length;
- this._range = new WebInspector.TextRange(this._range.startLine, this._range.startColumn, endLine, endColumn);
- },
-
- presentHoverMenu: function()
- {
- this._hoverMenu = new WebInspector.HoverMenu(this);
- this._hoverMenu.element.classList.add("color");
- this._bounds = this._marker.bounds;
- this._hoverMenu.present(this._bounds);
- },
-
- dismissHoverMenu: function()
- {
- this._hoverMenu.dismiss();
- },
-
- // Protected
-
- handleEvent: function(event)
- {
- if (!this._keyboardShortcutEsc.matchesEvent(event) || !this._popover.visible)
- return;
-
- this.color = this._originalColor;
- this._popover.dismiss();
-
- event.stopPropagation();
- event.preventDefault();
- },
-
- hoverMenuButtonWasPressed: function(hoverMenu)
- {
- var colorPicker = new WebInspector.ColorPicker;
- colorPicker.addEventListener(WebInspector.ColorPicker.Event.ColorChanged, this._colorPickerColorChanged, this);
-
- this._popover = new WebInspector.Popover(this);
- this._popover.content = colorPicker.element;
- this._popover.present(this._bounds.pad(2), [WebInspector.RectEdge.MAX_Y, WebInspector.RectEdge.MAX_X]);
-
- window.addEventListener("keydown", this, true);
-
- colorPicker.color = this._color;
-
- hoverMenu.dismiss();
-
- if (this._delegate && typeof this._delegate.colorEditingControllerDidStartEditing === "function")
- this._delegate.colorEditingControllerDidStartEditing(this);
-
- this._originalColor = this._color.copy();
- },
-
- didDismissPopover: function(popover)
- {
- delete this._popover;
- delete this._originalColor;
-
- window.removeEventListener("keydown", this, true);
-
- if (this._delegate && typeof this._delegate.colorEditingControllerDidFinishEditing === "function")
- this._delegate.colorEditingControllerDidFinishEditing(this);
- },
-
</del><span class="cx"> // Private
</span><span class="cx">
</span><span class="cx"> _colorPickerColorChanged: function(event)
</span><span class="cx"> {
</span><del>- this.color = event.target.color;
</del><ins>+ this.value = event.target.color;
</ins><span class="cx"> }
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceCodeMirrorEditingControllerjsfromrev164435trunkSourceWebInspectorUIUserInterfaceCodeMirrorColorEditingControllerjs"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebInspectorUI/UserInterface/CodeMirrorEditingController.js (from rev 164435, trunk/Source/WebInspectorUI/UserInterface/CodeMirrorColorEditingController.js) (0 => 164436)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/CodeMirrorEditingController.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/CodeMirrorEditingController.js 2014-02-20 18:48:51 UTC (rev 164436)
</span><span class="lines">@@ -0,0 +1,190 @@
</span><ins>+/*
+ * Copyright (C) 2014 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.CodeMirrorEditingController = function(codeMirror, marker)
+{
+ WebInspector.Object.call(this);
+
+ this._codeMirror = codeMirror;
+ this._marker = marker;
+ this._delegate = null;
+
+ this._range = marker.range;
+
+ // The value must support .toString() and .copy() methods.
+ this._value = this.initialValue;
+
+ this._keyboardShortcutEsc = new WebInspector.KeyboardShortcut(null, WebInspector.KeyboardShortcut.Key.Escape);
+}
+
+WebInspector.CodeMirrorEditingController.prototype = {
+ constructor: WebInspector.CodeMirrorEditingController,
+ __proto__: WebInspector.Object.prototype,
+
+ // Public
+
+ get marker()
+ {
+ return this._marker;
+ },
+
+ get range()
+ {
+ return this._range;
+ },
+
+ get value()
+ {
+ return this._value;
+ },
+
+ set value(value)
+ {
+ this.text = value.toString();
+ this._value = value;
+ },
+
+ get delegate()
+ {
+ return this._delegate;
+ },
+
+ set delegate(delegate)
+ {
+ this._delegate = delegate;
+ },
+
+ get text()
+ {
+ var from = {line: this._range.startLine, ch: this._range.startColumn};
+ var to = {line: this._range.endLine, ch: this._range.endColumn};
+ return this._codeMirror.getRange(from, to);
+ },
+
+ set text(text)
+ {
+ var from = {line: this._range.startLine, ch: this._range.startColumn};
+ var to = {line: this._range.endLine, ch: this._range.endColumn};
+ this._codeMirror.replaceRange(text, from, to);
+
+ var lines = text.split("\n");
+ var endLine = this._range.startLine + lines.length - 1;
+ var endColumn = lines.length > 1 ? lines.lastValue.length : this._range.startColumn + text.length;
+ this._range = new WebInspector.TextRange(this._range.startLine, this._range.startColumn, endLine, endColumn);
+ },
+
+ get initialValue()
+ {
+ // Implemented by subclasses.
+ return this.text;
+ },
+
+ get cssClassName()
+ {
+ // Implemented by subclasses.
+ return "";
+ },
+
+ get popover()
+ {
+ return this._popover;
+ },
+
+ get popoverPreferredEdges()
+ {
+ // Best to display the popover to the left or above the edited range since its end position may change, but not its start
+ // position. This way we minimize the chances of overlaying the edited range as it changes.
+ return [WebInspector.RectEdge.MIN_X, WebInspector.RectEdge.MIN_Y, WebInspector.RectEdge.MAX_Y, WebInspector.RectEdge.MAX_X];
+ },
+
+ popoverTargetFrameWithRects: function(rects)
+ {
+ return WebInspector.Rect.unionOfRects(rects);
+ },
+
+ presentHoverMenu: function()
+ {
+ this._hoverMenu = new WebInspector.HoverMenu(this);
+ this._hoverMenu.element.classList.add(this.cssClassName);
+ this._rects = this._marker.rects;
+ this._hoverMenu.present(this._rects);
+ },
+
+ dismissHoverMenu: function(discrete)
+ {
+ this._hoverMenu.dismiss(discrete);
+ },
+
+ popoverWillPresent: function(popover)
+ {
+ // Implemented by subclasses.
+ },
+
+ popoverDidPresent: function(popover)
+ {
+ // Implemented by subclasses.
+ },
+
+ // Protected
+
+ handleKeydownEvent: function(event)
+ {
+ if (!this._keyboardShortcutEsc.matchesEvent(event) || !this._popover.visible)
+ return false;
+
+ this.value = this._originalValue;
+ this._popover.dismiss();
+
+ return true;
+ },
+
+ hoverMenuButtonWasPressed: function(hoverMenu)
+ {
+ this._popover = new WebInspector.Popover(this);
+ this.popoverWillPresent(this._popover);
+ this._popover.present(this.popoverTargetFrameWithRects(this._rects).pad(2), this.popoverPreferredEdges);
+ this.popoverDidPresent(this._popover);
+
+ WebInspector.addWindowKeydownListener(this);
+
+ hoverMenu.dismiss();
+
+ if (this._delegate && typeof this._delegate.editingControllerDidStartEditing === "function")
+ this._delegate.editingControllerDidStartEditing(this);
+
+ this._originalValue = this._value.copy();
+ },
+
+ didDismissPopover: function(popover)
+ {
+ delete this._popover;
+ delete this._originalValue;
+
+ WebInspector.removeWindowKeydownListener(this);
+
+ if (this._delegate && typeof this._delegate.editingControllerDidFinishEditing === "function")
+ this._delegate.editingControllerDidFinishEditing(this);
+ }
+}
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceGeometryjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Geometry.js (164435 => 164436)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Geometry.js 2014-02-20 18:23:24 UTC (rev 164435)
+++ trunk/Source/WebInspectorUI/UserInterface/Geometry.js 2014-02-20 18:48:51 UTC (rev 164436)
</span><span class="lines">@@ -98,6 +98,14 @@
</span><span class="cx"> return new WebInspector.Rect(clientRect.left, clientRect.top, clientRect.width, clientRect.height);
</span><span class="cx"> };
</span><span class="cx">
</span><ins>+WebInspector.Rect.unionOfRects = function(rects)
+{
+ var union = rects[0];
+ for (var i = 1; i < rects.length; ++i)
+ union = union.unionWithRect(rects[i]);
+ return union;
+};
+
</ins><span class="cx"> WebInspector.Rect.prototype = {
</span><span class="cx"> constructor: WebInspector.Rect,
</span><span class="cx">
</span><span class="lines">@@ -183,7 +191,16 @@
</span><span class="cx"> intersection.size.height = y2 - y1;
</span><span class="cx"> return intersection;
</span><span class="cx"> },
</span><del>-
</del><ins>+
+ unionWithRect: function(rect)
+ {
+ var x = Math.min(this.minX(), rect.minX());
+ var y = Math.min(this.minY(), rect.minY());
+ var width = Math.max(this.maxX(), rect.maxX()) - x;
+ var height = Math.max(this.maxY(), rect.maxY()) - y;
+ return new WebInspector.Rect(x, y, width, height);
+ },
+
</ins><span class="cx"> round: function()
</span><span class="cx"> {
</span><span class="cx"> return new WebInspector.Rect(
</span><span class="lines">@@ -263,3 +280,27 @@
</span><span class="cx"> ];
</span><span class="cx"> }
</span><span class="cx"> };
</span><ins>+
+WebInspector.Polygon = function(points)
+{
+ this.points = points;
+}
+
+WebInspector.Polygon.prototype = {
+ constructor: WebInspector.Polygon,
+
+ bounds: function()
+ {
+ var minX = Number.MAX_VALUE;
+ var minY = Number.MAX_VALUE;
+ var maxX = -Number.MAX_VALUE;
+ var maxY = -Number.MAX_VALUE;
+ for (var point of this.points) {
+ minX = Math.min(minX, point.x);
+ maxX = Math.max(maxX, point.x);
+ minY = Math.min(minY, point.y);
+ maxY = Math.max(maxY, point.y);
+ }
+ return new WebInspector.Rect(minX, minY, maxX - minX, maxY - minY);
+ }
+}
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceHoverMenucss"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/HoverMenu.css (164435 => 164436)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/HoverMenu.css 2014-02-20 18:23:24 UTC (rev 164435)
+++ trunk/Source/WebInspectorUI/UserInterface/HoverMenu.css 2014-02-20 18:48:51 UTC (rev 164436)
</span><span class="lines">@@ -25,27 +25,9 @@
</span><span class="cx">
</span><span class="cx"> .hover-menu {
</span><span class="cx"> position: absolute;
</span><del>- display: -webkit-flex;
</del><span class="cx">
</span><del>- /* Exceptionally use content-box such that the frame set is that of the highlighted string
- and styling adds the required padding around it */
- box-sizing: content-box;
</del><ins>+ -webkit-transform: translate(-1px, -1px);
</ins><span class="cx">
</span><del>- /* Position the icon to the right of the menu and centered vertically */
- -webkit-justify-content: flex-end;
- -webkit-align-items: center;
-
- /* Provide extra room for the icon */
- padding-left: 2px;
- padding-right: 16px;
-
- min-height: 17px;
-
- border-radius: 4px;
- border: 2px solid rgba(0, 0, 0, 0.22);
-
- -webkit-transform: translate3d(-3px, -5px, 0);
-
</del><span class="cx"> pointer-events: none;
</span><span class="cx"> opacity: 0;
</span><span class="cx">
</span><span class="lines">@@ -56,10 +38,27 @@
</span><span class="cx"> opacity: 1;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+.hover-menu > svg {
+ position: absolute;
+ top: 0;
+ left: 0;
+}
+
+.hover-menu > svg > path,
+.hover-menu > svg > rect {
+ stroke: rgba(0, 0, 0, 0.22);
+ stroke-width: 2px;
+ fill: none;
+}
+
</ins><span class="cx"> .hover-menu > img {
</span><ins>+ position: absolute;
+
+ left: 0;
+ top: 0;
</ins><span class="cx"> width: 15px;
</span><span class="cx"> height: 13px;
</span><del>- -webkit-transform: translateX(14px);
</del><ins>+
</ins><span class="cx"> content: -webkit-image-set(url(Images/HoverMenuButton.png) 1x, url(Images/HoverMenuButton@2x.png) 2x);
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceHoverMenujs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/HoverMenu.js (164435 => 164436)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/HoverMenu.js 2014-02-20 18:23:24 UTC (rev 164435)
+++ trunk/Source/WebInspectorUI/UserInterface/HoverMenu.js 2014-02-20 18:48:51 UTC (rev 164436)
</span><span class="lines">@@ -33,6 +33,8 @@
</span><span class="cx"> this._element.className = WebInspector.HoverMenu.StyleClassName;
</span><span class="cx"> this._element.addEventListener("transitionend", this, true);
</span><span class="cx">
</span><ins>+ this._outlineElement = this._element.appendChild(document.createElementNS("http://www.w3.org/2000/svg", "svg"));
+
</ins><span class="cx"> this._button = this._element.appendChild(document.createElement("img"));
</span><span class="cx"> this._button.addEventListener("click", this);
</span><span class="cx"> }
</span><span class="lines">@@ -51,28 +53,25 @@
</span><span class="cx"> return this._element;
</span><span class="cx"> },
</span><span class="cx">
</span><del>- present: function(targetFrame)
</del><ins>+ present: function(rects)
</ins><span class="cx"> {
</span><del>- var style = this._element.style;
- style.left = Math.ceil(targetFrame.origin.x) + "px";
- style.top = Math.ceil(targetFrame.origin.y) + "px";
- style.width = Math.ceil(targetFrame.size.width) + "px";
- style.height = Math.ceil(targetFrame.size.height) + "px";
</del><ins>+ this._outlineElement.textContent = "";
</ins><span class="cx">
</span><del>- var element = this._element;
- document.body.appendChild(element);
- setTimeout(function() {
- element.classList.add(WebInspector.HoverMenu.VisibleClassName);
- });
</del><ins>+ document.body.appendChild(this._element);
+ this._drawOutline(rects);
+ this._element.classList.add(WebInspector.HoverMenu.VisibleClassName);
</ins><span class="cx">
</span><span class="cx"> window.addEventListener("scroll", this, true);
</span><span class="cx"> },
</span><span class="cx">
</span><del>- dismiss: function()
</del><ins>+ dismiss: function(discrete)
</ins><span class="cx"> {
</span><span class="cx"> if (this._element.parentNode !== document.body)
</span><span class="cx"> return;
</span><span class="cx">
</span><ins>+ if (discrete)
+ this._element.remove();
+
</ins><span class="cx"> this._element.classList.remove(WebInspector.HoverMenu.VisibleClassName);
</span><span class="cx">
</span><span class="cx"> window.removeEventListener("scroll", this, true);
</span><span class="lines">@@ -85,7 +84,7 @@
</span><span class="cx"> switch (event.type) {
</span><span class="cx"> case "scroll":
</span><span class="cx"> if (!this._element.contains(event.target))
</span><del>- this.dismiss();
</del><ins>+ this.dismiss(true);
</ins><span class="cx"> break;
</span><span class="cx"> case "click":
</span><span class="cx"> this._handleClickEvent(event);
</span><span class="lines">@@ -103,5 +102,175 @@
</span><span class="cx"> {
</span><span class="cx"> if (this.delegate && typeof this.delegate.hoverMenuButtonWasPressed === "function")
</span><span class="cx"> this.delegate.hoverMenuButtonWasPressed(this);
</span><ins>+ },
+
+ _drawOutline: function(rects)
+ {
+ var buttonWidth = this._button.width;
+ var buttonHeight = this._button.height;
+
+ // Add room for the button on the last line.
+ var lastRect = rects.pop();
+ lastRect.size.width += buttonWidth;
+ rects.push(lastRect);
+
+ if (rects.length === 1)
+ this._drawSingleLine(rects[0]);
+ else if (rects.length === 2 && rects[0].minX() >= rects[1].maxX())
+ this._drawTwoNonOverlappingLines(rects);
+ else
+ this._drawOverlappingLines(rects);
+
+ var bounds = WebInspector.Rect.unionOfRects(rects).pad(3); // padding + 1/2 stroke-width
+
+ var style = this._element.style;
+ style.left = bounds.minX() + "px";
+ style.top = bounds.minY() + "px";
+ style.width = bounds.size.width + "px";
+ style.height = bounds.size.height + "px";
+
+ this._outlineElement.style.width = bounds.size.width + "px";
+ this._outlineElement.style.height = bounds.size.height + "px";
+
+ this._button.style.left = (lastRect.maxX() - bounds.minX() - buttonWidth) + "px";
+ this._button.style.top = (lastRect.maxY() - bounds.minY() - buttonHeight) + "px";
+ },
+
+ _addRect: function(rect)
+ {
+ const r = 4;
+
+ var svgRect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
+ svgRect.setAttribute("x", 1);
+ svgRect.setAttribute("y", 1);
+ svgRect.setAttribute("width", rect.size.width);
+ svgRect.setAttribute("height", rect.size.height);
+ svgRect.setAttribute("rx", r);
+ svgRect.setAttribute("ry", r);
+ return this._outlineElement.appendChild(svgRect);
+ },
+
+ _addPath: function(commands, tx, ty)
+ {
+ var path = document.createElementNS("http://www.w3.org/2000/svg", "path");
+ path.setAttribute("d", commands.join(" "));
+ path.setAttribute("transform", "translate(" + (tx + 1) + "," + (ty + 1) + ")");
+ return this._outlineElement.appendChild(path);
+ },
+
+ _drawSingleLine: function(rect)
+ {
+ this._addRect(rect.pad(2));
+ },
+
+ _drawTwoNonOverlappingLines: function(rects)
+ {
+ const r = 4;
+
+ var firstRect = rects[0].pad(2);
+ var secondRect = rects[1].pad(2);
+
+ var tx = -secondRect.minX();
+ var ty = -firstRect.minY();
+
+ var rect = firstRect;
+ this._addPath([
+ "M", rect.maxX(), rect.minY(),
+ "H", rect.minX() + r,
+ "q", -r, 0, -r, r,
+ "V", rect.maxY() - r,
+ "q", 0, r, r, r,
+ "H", rect.maxX()
+ ], tx, ty);
+
+ rect = secondRect;
+ this._addPath([
+ "M", rect.minX(), rect.minY(),
+ "H", rect.maxX() - r,
+ "q", r, 0, r, r,
+ "V", rect.maxY() - r,
+ "q", 0, r, -r, r,
+ "H", rect.minX()
+ ], tx, ty);
+ },
+
+ _drawOverlappingLines: function(rects)
+ {
+ const PADDING = 2;
+ const r = 4;
+
+ var minX = Number.MAX_VALUE;
+ var maxX = -Number.MAX_VALUE;
+ for (var rect of rects) {
+ var minX = Math.min(rect.minX(), minX);
+ var maxX = Math.max(rect.maxX(), maxX);
+ }
+
+ minX -= PADDING;
+ maxX += PADDING;
+
+ var minY = rects[0].minY() - PADDING;
+ var maxY = rects.lastValue.maxY() + PADDING;
+ var firstLineMinX = rects[0].minX() - PADDING;
+ var lastLineMaxX = rects.lastValue.maxX() + PADDING;
+
+ if (firstLineMinX === minX && lastLineMaxX === maxX)
+ return this._addRect(new WebInspector.Rect(minX, minY, maxX - minX, maxY - minY));
+
+ var lastLineMinY = rects.lastValue.minY() + PADDING;
+ if (rects[0].minX() === minX + PADDING)
+ return this._addPath([
+ "M", minX + r, minY,
+ "H", maxX - r,
+ "q", r, 0, r, r,
+ "V", lastLineMinY - r,
+ "q", 0, r, -r, r,
+ "H", lastLineMaxX + r,
+ "q", -r, 0, -r, r,
+ "V", maxY - r,
+ "q", 0, r, -r, r,
+ "H", minX + r,
+ "q", -r, 0, -r, -r,
+ "V", minY + r,
+ "q", 0, -r, r, -r
+ ], -minX, -minY);
+
+ var firstLineMaxY = rects[0].maxY() - PADDING;
+ if (rects.lastValue.maxX() === maxX - PADDING)
+ return this._addPath([
+ "M", firstLineMinX + r, minY,
+ "H", maxX - r,
+ "q", r, 0, r, r,
+ "V", maxY - r,
+ "q", 0, r, -r, r,
+ "H", minX + r,
+ "q", -r, 0, -r, -r,
+ "V", firstLineMaxY + r,
+ "q", 0, -r, r, -r,
+ "H", firstLineMinX - r,
+ "q", r, 0, r, -r,
+ "V", minY + r,
+ "q", 0, -r, r, -r
+ ], -minX, -minY);
+
+ return this._addPath([
+ "M", firstLineMinX + r, minY,
+ "H", maxX - r,
+ "q", r, 0, r, r,
+ "V", lastLineMinY - r,
+ "q", 0, r, -r, r,
+ "H", lastLineMaxX + r,
+ "q", -r, 0, -r, r,
+ "V", maxY - r,
+ "q", 0, r, -r, r,
+ "H", minX + r,
+ "q", -r, 0, -r, -r,
+ "V", firstLineMaxY + r,
+ "q", 0, -r, r, -r,
+ "H", firstLineMinX - r,
+ "q", r, 0, r, -r,
+ "V", minY + r,
+ "q", 0, -r, r, -r
+ ], -minX, -minY);
</ins><span class="cx"> }
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceMainhtml"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (164435 => 164436)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Main.html 2014-02-20 18:23:24 UTC (rev 164435)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html 2014-02-20 18:48:51 UTC (rev 164436)
</span><span class="lines">@@ -445,6 +445,7 @@
</span><span class="cx"> <script src="GoToLineDialog.js"></script>
</span><span class="cx"> <script src="ContentFlowDOMTreeContentView.js"></script>
</span><span class="cx"> <script src="HoverMenu.js"></script>
</span><ins>+ <script src="CodeMirrorEditingController.js"></script>
</ins><span class="cx"> <script src="CodeMirrorColorEditingController.js"></script>
</span><span class="cx"> <script src="Main.js"></script>
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceMainjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Main.js (164435 => 164436)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Main.js 2014-02-20 18:23:24 UTC (rev 164435)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.js 2014-02-20 18:48:51 UTC (rev 164436)
</span><span class="lines">@@ -175,6 +175,8 @@
</span><span class="cx"> x: 0,
</span><span class="cx"> y: 0
</span><span class="cx"> };
</span><ins>+
+ this._windowKeydownListeners = [];
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> WebInspector.contentLoaded = function()
</span><span class="lines">@@ -1785,3 +1787,39 @@
</span><span class="cx">
</span><span class="cx"> return WebInspector.Resource.Type.fromMIMEType(WebInspector.frameResourceManager.mainFrame.mainResource.mimeType) === WebInspector.Resource.Type.Document;
</span><span class="cx"> }
</span><ins>+
+WebInspector.addWindowKeydownListener = function(listener)
+{
+ if (typeof listener.handleKeydownEvent !== "function")
+ return;
+
+ this._windowKeydownListeners.push(listener);
+
+ this._updateWindowKeydownListener();
+};
+
+WebInspector.removeWindowKeydownListener = function(listener)
+{
+ this._windowKeydownListeners.remove(listener);
+
+ this._updateWindowKeydownListener();
+};
+
+WebInspector._updateWindowKeydownListener = function()
+{
+ if (this._windowKeydownListeners.length > 0)
+ window.addEventListener("keydown", WebInspector._sharedWindowKeydownListener, true);
+ else
+ window.removeEventListener("keydown", WebInspector._sharedWindowKeydownListener, true);
+}
+
+WebInspector._sharedWindowKeydownListener = function(event)
+{
+ for (var i = WebInspector._windowKeydownListeners.length - 1; i >= 0; --i) {
+ if (WebInspector._windowKeydownListeners[i].handleKeydownEvent(event)) {
+ event.stopImmediatePropagation();
+ event.preventDefault();
+ break;
+ }
+ }
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceSourceCodeTextEditorcss"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/SourceCodeTextEditor.css (164435 => 164436)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/SourceCodeTextEditor.css 2014-02-20 18:23:24 UTC (rev 164435)
+++ trunk/Source/WebInspectorUI/UserInterface/SourceCodeTextEditor.css 2014-02-20 18:48:51 UTC (rev 164436)
</span><span class="lines">@@ -71,6 +71,7 @@
</span><span class="cx"> .hover-menu.color > img {
</span><span class="cx"> width: 16px;
</span><span class="cx"> height: 16px;
</span><del>- -webkit-transform: translateX(14px);
</del><span class="cx"> content: -webkit-image-set(url(Images/ColorIcon.png) 1x, url(Images/ColorIcon@2x.png) 2x);
</span><ins>+
+ -webkit-transform: translateY(1px);
</ins><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceSourceCodeTextEditorjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/SourceCodeTextEditor.js (164435 => 164436)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/SourceCodeTextEditor.js 2014-02-20 18:23:24 UTC (rev 164435)
+++ trunk/Source/WebInspectorUI/UserInterface/SourceCodeTextEditor.js 2014-02-20 18:48:51 UTC (rev 164436)
</span><span class="lines">@@ -107,6 +107,8 @@
</span><span class="cx"> this.tokenTrackingController.removeHighlightedRange();
</span><span class="cx">
</span><span class="cx"> this._dismissPopover();
</span><ins>+
+ this._dismissEditingController(true);
</ins><span class="cx"> },
</span><span class="cx">
</span><span class="cx"> close: function()
</span><span class="lines">@@ -226,23 +228,8 @@
</span><span class="cx"> if (this._ignoreContentDidChange > 0)
</span><span class="cx"> return;
</span><span class="cx">
</span><del>- // Gather all lines containing new text.
- var lines = new Set;
- for (var range of newRanges) {
- // If the range is on a single line, only add the line if the range is not empty.
- if (range.startLine === range.endLine) {
- if (range.endColumn > range.startColumn)
- lines.add(range.startLine);
- } else {
- // Only add the last line if the range has characters on this line.
- for (var line = range.startLine; line < range.endLine || range.endColumn > 0; ++line)
- lines.add(line);
- }
- }
-
- // Consider all new lines for new color markers.
- for (var line of lines)
- this._updateColorMarkers(line);
</del><ins>+ for (var range of newRanges)
+ this._updateEditableMarkers(range);
</ins><span class="cx"> },
</span><span class="cx">
</span><span class="cx"> // Private
</span><span class="lines">@@ -360,8 +347,7 @@
</span><span class="cx"> this._addIssue(issue);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- this._updateTokenTrackingControllerState();
- this._updateColorMarkers();
</del><ins>+ this._updateEditableMarkers();
</ins><span class="cx"> },
</span><span class="cx">
</span><span class="cx"> _populateWithContent: function(content)
</span><span class="lines">@@ -1076,13 +1062,13 @@
</span><span class="cx"> if (markers.length > 0)
</span><span class="cx"> this._tokenTrackingControllerHighlightedMarkedExpression(candidate, markers);
</span><span class="cx"> else
</span><del>- this._dismissCodeMirrorColorEditingController();
</del><ins>+ this._dismissEditingController();
</ins><span class="cx"> }
</span><span class="cx"> },
</span><span class="cx">
</span><span class="cx"> tokenTrackingControllerMouseOutOfHoveredMarker: function(tokenTrackingController, hoveredMarker)
</span><span class="cx"> {
</span><del>- this._dismissCodeMirrorColorEditingController();
</del><ins>+ this._dismissEditingController();
</ins><span class="cx"> },
</span><span class="cx">
</span><span class="cx"> _tokenTrackingControllerHighlightedJavaScriptExpression: function(candidate)
</span><span class="lines">@@ -1131,12 +1117,11 @@
</span><span class="cx"> if (!candidate)
</span><span class="cx"> return;
</span><span class="cx">
</span><del>- var bounds = this.boundsForRange(candidate.hoveredTokenRange);
- if (!bounds)
- return;
-
</del><span class="cx"> content.classList.add(WebInspector.SourceCodeTextEditor.PopoverDebuggerContentStyleClassName);
</span><span class="cx">
</span><ins>+ var rects = this.rectsForRange(candidate.hoveredTokenRange);
+ var bounds = WebInspector.Rect.unionOfRects(rects);
+
</ins><span class="cx"> this._popover = this._popover || new WebInspector.Popover(this);
</span><span class="cx"> this._popover.content = content;
</span><span class="cx"> this._popover.present(bounds.pad(5), [WebInspector.RectEdge.MIN_Y, WebInspector.RectEdge.MAX_Y, WebInspector.RectEdge.MAX_X]);
</span><span class="lines">@@ -1289,80 +1274,84 @@
</span><span class="cx"> this._mouseIsOverPopover = this._popover.element.contains(event.relatedTarget);
</span><span class="cx"> },
</span><span class="cx">
</span><del>- _updateColorMarkers: function(lineNumber)
</del><ins>+ _updateEditableMarkers: function(range)
</ins><span class="cx"> {
</span><del>- this.createColorMarkers(lineNumber);
</del><ins>+ this.createColorMarkers(range);
</ins><span class="cx">
</span><span class="cx"> this._updateTokenTrackingControllerState();
</span><span class="cx"> },
</span><del>-
</del><ins>+
</ins><span class="cx"> _tokenTrackingControllerHighlightedMarkedExpression: function(candidate, markers)
</span><span class="cx"> {
</span><del>- var colorMarker;
</del><ins>+ // Look for the outermost editable marker.
+ var editableMarker;
</ins><span class="cx"> for (var marker of markers) {
</span><del>- if (marker.type === WebInspector.TextMarker.Type.Color) {
- colorMarker = marker;
- break;
- }
</del><ins>+ if (!marker.range || marker.type !== WebInspector.TextMarker.Type.Color)
+ continue;
+
+ if (!editableMarker || (marker.range.startLine < editableMarker.range.startLine || (marker.range.startLine === editableMarker.range.startLine && marker.range.startColumn < editableMarker.range.startColumn)))
+ editableMarker = marker;
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- if (!colorMarker) {
</del><ins>+ if (!editableMarker) {
</ins><span class="cx"> this.tokenTrackingController.hoveredMarker = null;
</span><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- if (this.tokenTrackingController.hoveredMarker === colorMarker)
</del><ins>+ if (this.tokenTrackingController.hoveredMarker === editableMarker)
</ins><span class="cx"> return;
</span><span class="cx">
</span><del>- this._dismissCodeMirrorColorEditingController();
</del><ins>+ this._dismissEditingController();
</ins><span class="cx">
</span><del>- this.tokenTrackingController.hoveredMarker = colorMarker;
</del><ins>+ this.tokenTrackingController.hoveredMarker = editableMarker;
</ins><span class="cx">
</span><del>- this._colorEditingController = this.colorEditingControllerForMarker(colorMarker);
</del><ins>+ this._editingController = this.editingControllerForMarker(editableMarker);
</ins><span class="cx">
</span><del>- var color = this._colorEditingController.color;
- if (!color || !color.valid) {
- colorMarker.clear();
- delete this._colorEditingController;
- return;
</del><ins>+ if (marker.type === WebInspector.TextMarker.Type.Color) {
+ var color = this._editingController.value;
+ if (!color || !color.valid) {
+ editableMarker.clear();
+ delete this._editingController;
+ return;
+ }
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- this._colorEditingController.delegate = this;
- this._colorEditingController.presentHoverMenu();
</del><ins>+ this._editingController.delegate = this;
+ this._editingController.presentHoverMenu();
</ins><span class="cx"> },
</span><span class="cx">
</span><del>- _dismissCodeMirrorColorEditingController: function()
</del><ins>+ _dismissEditingController: function(discrete)
</ins><span class="cx"> {
</span><del>- if (this._colorEditingController)
- this._colorEditingController.dismissHoverMenu();
</del><ins>+ if (this._editingController)
+ this._editingController.dismissHoverMenu(discrete);
</ins><span class="cx">
</span><span class="cx"> this.tokenTrackingController.hoveredMarker = null;
</span><del>- delete this._colorEditingController;
</del><ins>+ delete this._editingController;
</ins><span class="cx"> },
</span><span class="cx">
</span><del>- // CodeMirrorColorEditingController Delegate
</del><ins>+ // CodeMirrorEditingController Delegate
</ins><span class="cx">
</span><del>- colorEditingControllerDidStartEditing: function(colorEditingController)
</del><ins>+ editingControllerDidStartEditing: function(editingController)
</ins><span class="cx"> {
</span><span class="cx"> // We can pause the token tracking controller during editing, it will be reset
</span><del>- // to the expected state by calling _updateColorMarkers() in the
- // colorEditingControllerDidFinishEditing delegate.
</del><ins>+ // to the expected state by calling _updateEditableMarkers() in the
+ // editingControllerDidFinishEditing delegate.
</ins><span class="cx"> this.tokenTrackingController.enabled = false;
</span><span class="cx">
</span><span class="cx"> // We clear the marker since we'll reset it after editing.
</span><del>- colorEditingController.marker.clear();
</del><ins>+ editingController.marker.clear();
</ins><span class="cx">
</span><span class="cx"> // We ignore content changes made as a result of color editing.
</span><span class="cx"> this._ignoreContentDidChange++;
</span><span class="cx"> },
</span><span class="cx">
</span><del>- colorEditingControllerDidFinishEditing: function(colorEditingController)
</del><ins>+ editingControllerDidFinishEditing: function(editingController)
</ins><span class="cx"> {
</span><del>- this._updateColorMarkers(colorEditingController.range.startLine);
</del><ins>+ this._updateEditableMarkers(editingController.range);
</ins><span class="cx">
</span><span class="cx"> this._ignoreContentDidChange--;
</span><span class="cx">
</span><del>- delete this._colorEditingController;
</del><ins>+ delete this._editingController;
</ins><span class="cx"> }
</span><span class="cx"> };
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTextEditorjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/TextEditor.js (164435 => 164436)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/TextEditor.js 2014-02-20 18:23:24 UTC (rev 164435)
+++ trunk/Source/WebInspectorUI/UserInterface/TextEditor.js 2014-02-20 18:48:51 UTC (rev 164436)
</span><span class="lines">@@ -597,9 +597,9 @@
</span><span class="cx"> // Implemented by subclasses.
</span><span class="cx"> },
</span><span class="cx">
</span><del>- boundsForRange: function(range)
</del><ins>+ rectsForRange: function(range)
</ins><span class="cx"> {
</span><del>- return this._codeMirror.boundsForRange(range);
</del><ins>+ return this._codeMirror.rectsForRange(range);
</ins><span class="cx"> },
</span><span class="cx">
</span><span class="cx"> get markers()
</span><span class="lines">@@ -616,14 +616,19 @@
</span><span class="cx"> });
</span><span class="cx"> },
</span><span class="cx">
</span><del>- createColorMarkers: function(lineNumber)
</del><ins>+ createColorMarkers: function(range)
</ins><span class="cx"> {
</span><del>- return this._codeMirror.createColorMarkers(lineNumber);
</del><ins>+ return this._codeMirror.createColorMarkers(range);
</ins><span class="cx"> },
</span><span class="cx">
</span><del>- colorEditingControllerForMarker: function(colorMarker)
</del><ins>+ editingControllerForMarker: function(editableMarker)
</ins><span class="cx"> {
</span><del>- return new WebInspector.CodeMirrorColorEditingController(this._codeMirror, colorMarker);
</del><ins>+ switch (editableMarker.type) {
+ case WebInspector.TextMarker.Type.Color:
+ return new WebInspector.CodeMirrorColorEditingController(this._codeMirror, editableMarker);
+ default:
+ return new WebInspector.CodeMirrorEditingController(this._codeMirror, editableMarker);
+ }
</ins><span class="cx"> },
</span><span class="cx">
</span><span class="cx"> // Private
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTextMarkerjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/TextMarker.js (164435 => 164436)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/TextMarker.js 2014-02-20 18:23:24 UTC (rev 164435)
+++ trunk/Source/WebInspectorUI/UserInterface/TextMarker.js 2014-02-20 18:48:51 UTC (rev 164436)
</span><span class="lines">@@ -67,12 +67,12 @@
</span><span class="cx"> return new WebInspector.TextRange(range.from.line, range.from.ch, range.to.line, range.to.ch);
</span><span class="cx"> },
</span><span class="cx">
</span><del>- get bounds()
</del><ins>+ get rects()
</ins><span class="cx"> {
</span><span class="cx"> var range = this._codeMirrorTextMarker.find();
</span><span class="cx"> if (!range)
</span><span class="cx"> return WebInspector.Rect.ZERO_RECT;
</span><del>- return this._codeMirrorTextMarker.doc.cm.boundsForRange({
</del><ins>+ return this._codeMirrorTextMarker.doc.cm.rectsForRange({
</ins><span class="cx"> start: range.from,
</span><span class="cx"> end: range.to
</span><span class="cx"> });
</span></span></pre>
</div>
</div>
</body>
</html>