Changeset 53941 in webkit
- Timestamp:
- Jan 27, 2010 10:36:54 AM (14 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 1 deleted
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r53940 r53941 1 2010-01-27 Pavel Feldman <pfeldman@chromium.org> 2 3 Reviewed by Timothy Hatcher. 4 5 Web Inspector: migrate from SourceFrame to SourceFrame2. 6 7 https://bugs.webkit.org/show_bug.cgi?id=34171 8 9 * WebCore.gypi: 10 * WebCore.vcproj/WebCore.vcproj: 11 * bindings/js/JSInspectorFrontendHostCustom.cpp: 12 * bindings/v8/custom/V8InspectorFrontendHostCustom.cpp: 13 * inspector/InspectorFrontendHost.cpp: 14 * inspector/InspectorFrontendHost.h: 15 * inspector/InspectorFrontendHost.idl: 16 * inspector/front-end/InspectorBackendStub.js: 17 * inspector/front-end/InspectorFrontendHostStub.js: 18 * inspector/front-end/ResourceView.js: 19 (WebInspector.ResourceView.prototype._innerSelectContentTab): 20 * inspector/front-end/ResourcesPanel.js: 21 (WebInspector.getResourceContent): 22 * inspector/front-end/ScriptView.js: 23 (WebInspector.ScriptView): 24 (WebInspector.ScriptView.prototype.setupSourceFrameIfNeeded): 25 * inspector/front-end/ScriptsPanel.js: 26 (WebInspector.ScriptsPanel.prototype._sidebarResizeDrag): 27 * inspector/front-end/SourceFrame.js: 28 (WebInspector.SourceFrame): 29 (WebInspector.SourceFrame.prototype.set executionLine): 30 (WebInspector.SourceFrame.prototype.revealLine): 31 (WebInspector.SourceFrame.prototype.addBreakpoint): 32 (WebInspector.SourceFrame.prototype.removeBreakpoint): 33 (WebInspector.SourceFrame.prototype.addMessage): 34 (WebInspector.SourceFrame.prototype.clearMessages): 35 (WebInspector.SourceFrame.prototype.sizeToFitContentHeight): 36 (WebInspector.SourceFrame.prototype.setContent): 37 (WebInspector.SourceFrame.prototype.findSearchMatches): 38 (WebInspector.SourceFrame.prototype._collectRegexMatches): 39 (WebInspector.SourceFrame.prototype.setSelection): 40 (WebInspector.SourceFrame.prototype._incrementMessageRepeatCount): 41 (WebInspector.SourceFrame.prototype._addExistingMessagesToSource): 42 (WebInspector.SourceFrame.prototype._addMessageToSource): 43 (WebInspector.SourceFrame.prototype._addExistingBreakpointsToSource): 44 (WebInspector.SourceFrame.prototype._addBreakpointToSource): 45 (WebInspector.SourceFrame.prototype._removeBreakpointFromSource): 46 (WebInspector.SourceFrame.prototype._contextMenu.addConditionalBreakpoint): 47 (WebInspector.SourceFrame.prototype._contextMenu): 48 (WebInspector.SourceFrame.prototype._toggleBreakpoint): 49 (WebInspector.SourceFrame.prototype._editBreakpointCondition.committed): 50 (WebInspector.SourceFrame.prototype._editBreakpointCondition.dismissed): 51 (WebInspector.SourceFrame.prototype._editBreakpointCondition): 52 (WebInspector.SourceFrame.prototype._showBreakpointConditionPopup): 53 (WebInspector.SourceFrame.prototype._createConditionElement): 54 (WebInspector.SourceFrame.prototype._keyDown): 55 (WebInspector.SourceFrame.prototype._evalSelectionInCallFrame): 56 (WebInspector.SourceFrame.prototype._breakpointChanged): 57 (WebInspector.SourceFrame.prototype.resize): 58 (WebInspector.BreakpointLineNumberDecorator): 59 (WebInspector.BreakpointLineNumberDecorator.prototype.decorate): 60 (WebInspector.BreakpointLineNumberDecorator.prototype._paintBreakpoint): 61 (WebInspector.BreakpointLineNumberDecorator.prototype._paintProgramCounter): 62 (WebInspector.BreakpointLineNumberDecorator.prototype.mouseDown): 63 (WebInspector.BreakpointLineNumberDecorator.prototype.contextMenu): 64 (WebInspector.ExecutionLineDecorator): 65 (WebInspector.ExecutionLineDecorator.prototype.decorate): 66 * inspector/front-end/SourceFrame2.js: Removed. 67 * inspector/front-end/SourceView.js: 68 (WebInspector.SourceView): 69 (WebInspector.SourceView.prototype.show): 70 (WebInspector.SourceView.prototype.resize): 71 (WebInspector.SourceView.prototype.setupSourceFrameIfNeeded): 72 (WebInspector.SourceView.prototype._contentLoaded): 73 (WebInspector.SourceView.prototype.performSearch.findSearchMatches): 74 (WebInspector.SourceView.prototype.performSearch): 75 (WebInspector.SourceView.prototype._jumpToSearchResult): 76 (WebInspector.SourceView.prototype._sourceFrameSetupFinished): 77 * inspector/front-end/TextEditor.js: 78 (WebInspector.TextEditor.prototype._mouseDown): 79 (WebInspector.TextEditor.prototype._copy.delayCopy): 80 (WebInspector.TextEditor.prototype._copy): 81 (WebInspector.TextEditor.prototype._cut): 82 * inspector/front-end/WebKit.qrc: 83 * inspector/front-end/inspector.html: 84 1 85 2010-01-27 Dominik Röttsches <dominik.roettsches@access-company.com> 2 86 -
trunk/WebCore/WebCore.gypi
r53931 r53941 3734 3734 'inspector/front-end/SourceCSSTokenizer.js', 3735 3735 'inspector/front-end/SourceFrame.js', 3736 'inspector/front-end/SourceFrame2.js',3737 3736 'inspector/front-end/SourceHTMLTokenizer.js', 3738 3737 'inspector/front-end/SourceJavaScriptTokenizer.js', -
trunk/WebCore/WebCore.vcproj/WebCore.vcproj
r53915 r53941 42921 42921 </File> 42922 42922 <File 42923 RelativePath="..\inspector\front-end\SourceFrame2.js"42924 >42925 </File>42926 <File42927 42923 RelativePath="..\inspector\front-end\SourceHTMLTokenizer.js" 42928 42924 > -
trunk/WebCore/bindings/js/JSInspectorFrontendHostCustom.cpp
r51993 r53941 37 37 38 38 #include "ContextMenuItem.h" 39 #include "ExceptionCode.h"40 #include "Frame.h"41 39 #include "InspectorController.h" 42 40 #include "InspectorFrontendHost.h" 43 41 #include "JSEvent.h" 44 #include "JSNode.h"45 #include "JSRange.h"46 42 #include "MouseEvent.h" 47 #include "Node.h"48 #include "Page.h"49 #include "TextIterator.h"50 #include "VisiblePosition.h"51 43 #include <runtime/JSArray.h> 52 44 #include <runtime/JSLock.h> … … 57 49 58 50 namespace WebCore { 59 60 JSValue JSInspectorFrontendHost::search(ExecState* exec, const ArgList& args)61 {62 if (args.size() < 2)63 return jsUndefined();64 65 Node* node = toNode(args.at(0));66 if (!node)67 return jsUndefined();68 69 String target = args.at(1).toString(exec);70 if (exec->hadException())71 return jsUndefined();72 73 MarkedArgumentBuffer result;74 RefPtr<Range> searchRange(rangeOfContents(node));75 76 ExceptionCode ec = 0;77 do {78 RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, false));79 if (resultRange->collapsed(ec))80 break;81 82 // A non-collapsed result range can in some funky whitespace cases still not83 // advance the range's start position (4509328). Break to avoid infinite loop.84 VisiblePosition newStart = endVisiblePosition(resultRange.get(), DOWNSTREAM);85 if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM))86 break;87 88 result.append(toJS(exec, resultRange.get()));89 90 setStart(searchRange.get(), newStart);91 } while (true);92 93 return constructArray(exec, result);94 }95 51 96 52 JSValue JSInspectorFrontendHost::showContextMenu(ExecState* execState, const ArgList& args) -
trunk/WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp
r53271 r53941 32 32 #include "V8InspectorFrontendHost.h" 33 33 34 #include "ExceptionCode.h"35 34 #include "InspectorController.h" 36 35 #include "InspectorFrontendHost.h" 37 #include "Node.h"38 #include "Range.h"39 #include "Page.h"40 #include "TextIterator.h"41 #include "VisiblePosition.h"42 36 43 37 #include "V8Binding.h" 44 38 #include "V8CustomBinding.h" 45 #include "V8Node.h"46 39 #include "V8Proxy.h" 47 40 48 41 namespace WebCore { 49 50 v8::Handle<v8::Value> V8InspectorFrontendHost::searchCallback(const v8::Arguments& args)51 {52 INC_STATS("InspectorFrontendHost.search()");53 54 if (args.Length() < 2)55 return v8::Undefined();56 57 Node* node = V8Node::toNative(v8::Handle<v8::Object>::Cast(args[0]));58 if (!node)59 return v8::Undefined();60 61 String target = toWebCoreStringWithNullCheck(args[1]);62 if (target.isEmpty())63 return v8::Undefined();64 65 v8::Local<v8::Array> result = v8::Array::New();66 RefPtr<Range> searchRange(rangeOfContents(node));67 68 ExceptionCode ec = 0;69 int index = 0;70 do {71 RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, false));72 if (resultRange->collapsed(ec))73 break;74 75 // A non-collapsed result range can in some funky whitespace cases still not76 // advance the range's start position (4509328). Break to avoid infinite loop.77 VisiblePosition newStart = endVisiblePosition(resultRange.get(), DOWNSTREAM);78 if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM))79 break;80 81 result->Set(v8::Number::New(index++), V8DOMWrapper::convertToV8Object(V8ClassIndex::RANGE, resultRange.release()));82 83 setStart(searchRange.get(), newStart);84 } while (true);85 86 return result;87 }88 42 89 43 v8::Handle<v8::Value> V8InspectorFrontendHost::showContextMenuCallback(const v8::Arguments& args) -
trunk/WebCore/inspector/InspectorFrontendHost.cpp
r53855 r53941 46 46 #include "InspectorResource.h" 47 47 #include "Page.h" 48 #include "Pasteboard.h" 48 49 49 50 #include <wtf/RefPtr.h> … … 134 135 } 135 136 136 137 137 const String& InspectorFrontendHost::port() const 138 138 { … … 150 150 } 151 151 152 // FIXME: Remove this once migrated to SourceFrame2. 153 void InspectorFrontendHost::addResourceSourceToFrame(long identifier, Node* frame) 152 void InspectorFrontendHost::copyText(const String& text) 154 153 { 155 if (!m_inspectorController) 156 return; 157 RefPtr<InspectorResource> resource = m_inspectorController->resources().get(identifier); 158 if (resource) { 159 String sourceString = resource->sourceString(); 160 if (!sourceString.isEmpty()) 161 addSourceToFrame(resource->mimeType(), sourceString, frame); 162 } 163 } 164 165 // FIXME: Remove this once migrated to SourceFrame2. 166 bool InspectorFrontendHost::addSourceToFrame(const String& mimeType, const String& source, Node* frameNode) 167 { 168 ASSERT_ARG(frameNode, frameNode); 169 170 if (!frameNode) 171 return false; 172 173 if (!frameNode->attached()) { 174 ASSERT_NOT_REACHED(); 175 return false; 176 } 177 178 ASSERT(frameNode->isElementNode()); 179 if (!frameNode->isElementNode()) 180 return false; 181 182 Element* element = static_cast<Element*>(frameNode); 183 ASSERT(element->isFrameOwnerElement()); 184 if (!element->isFrameOwnerElement()) 185 return false; 186 187 HTMLFrameOwnerElement* frameOwner = static_cast<HTMLFrameOwnerElement*>(element); 188 ASSERT(frameOwner->contentFrame()); 189 if (!frameOwner->contentFrame()) 190 return false; 191 192 FrameLoader* loader = frameOwner->contentFrame()->loader(); 193 194 loader->setResponseMIMEType(mimeType); 195 loader->begin(); 196 loader->write(source); 197 loader->end(); 198 199 return true; 154 Pasteboard::generalPasteboard()->writePlainText(text); 200 155 } 201 156 -
trunk/WebCore/inspector/InspectorFrontendHost.h
r53855 r53941 74 74 const String& port() const; 75 75 76 // FIXME: Remove these once migrated to SourceFrame2. 77 void addResourceSourceToFrame(long identifier, Node* frame); 78 bool addSourceToFrame(const String& mimeType, const String& source, Node* frame); 76 void copyText(const String& text); 79 77 80 78 // Called from [Custom] implementations. -
trunk/WebCore/inspector/InspectorFrontendHost.idl
r53855 r53941 47 47 DOMString port(); 48 48 49 // FIXME: Remove these once migrated to SourceFrame2. 50 void addResourceSourceToFrame(in long identifier, in Node frame); 51 boolean addSourceToFrame(in DOMString mimeType, in DOMString sourceValue, in Node frame); 49 void copyText(in DOMString text); 52 50 53 [Custom] void search(in Node node, in DOMString query);54 51 [Custom] void showContextMenu(in MouseEvent event, in DOMObject items); 55 52 }; -
trunk/WebCore/inspector/front-end/InspectorBackendStub.js
r53855 r53941 101 101 }, 102 102 103 addResourceSourceToFrame: function(identifier, element)104 {105 },106 107 addSourceToFrame: function(mimeType, source, element)108 {109 return false;110 },111 112 // FIXME: remove once migrated to SourceFrame2.113 103 getResourceContent: function(callId, identifier) 114 104 { 115 105 WebInspector.didGetResourceContent(callId, ""); 116 },117 118 // FIXME: remove once migrated to SourceFrame2.119 getResourceDocumentNode: function(identifier)120 {121 return undefined;122 106 }, 123 107 -
trunk/WebCore/inspector/front-end/InspectorFrontendHostStub.js
r53855 r53941 72 72 }, 73 73 74 // FIXME: remove once migrated to SourceFrame2.75 addResourceSourceToFrame: function(identifier, element)76 {77 },78 79 // FIXME: remove once migrated to SourceFrame2.80 addSourceToFrame: function(mimeType, source, element)81 {82 return false;83 },84 85 74 loaded: function() 86 75 { … … 99 88 windowUnloading: function() 100 89 { 90 }, 91 92 copyText: function() 93 { 101 94 } 102 95 } -
trunk/WebCore/inspector/front-end/ResourceView.js
r53806 r53941 132 132 }, 133 133 134 show: function(parentElement) 135 { 136 WebInspector.View.prototype.show.call(this, parentElement); 137 this._selectTab(); 138 }, 139 134 140 set headersVisible(x) 135 141 { … … 137 143 return; 138 144 this._headersVisible = x; 139 if (x) {145 if (x) 140 146 this.element.addStyleClass("headers-visible"); 141 this._selectTab(); 142 } else { 147 else 143 148 this.element.removeStyleClass("headers-visible"); 149 this._selectTab(); 150 }, 151 152 _selectTab: function() 153 { 154 if (this._headersVisible) { 155 if (WebInspector.settings.resourceViewTab === "headers") 156 this._selectHeadersTab(); 157 else 158 this._selectContentTab(); 159 } else 144 160 this._innerSelectContentTab(); 145 }146 },147 148 _selectTab: function()149 {150 if (WebInspector.settings.resourceViewTab === "headers")151 this._selectHeadersTab();152 else153 this._selectContentTab();154 161 }, 155 162 … … 175 182 this.contentElement.removeStyleClass("hidden"); 176 183 this.headersElement.addStyleClass("hidden"); 184 if ("resize" in this) 185 this.resize(); 177 186 }, 178 187 -
trunk/WebCore/inspector/front-end/ResourcesPanel.js
r53806 r53941 711 711 WebInspector.ResourcesPanel.prototype.__proto__ = WebInspector.AbstractTimelinePanel.prototype; 712 712 713 WebInspector.getResourceContent = function(identifier, callback) 714 { 715 InspectorBackend.getResourceContent(WebInspector.Callback.wrap(callback), identifier); 716 } 717 718 WebInspector.didGetResourceContent = WebInspector.Callback.processCallback; 719 713 720 WebInspector.ResourceTimeCalculator = function(startAtZero) 714 721 { -
trunk/WebCore/inspector/front-end/ScriptView.js
r51528 r53941 34 34 this._frameNeedsSetup = true; 35 35 this._sourceFrameSetup = false; 36 37 this.sourceFrame = new WebInspector.SourceFrame(null, this._addBreakpoint.bind(this)); 36 this.sourceFrame = new WebInspector.SourceFrame(this._addBreakpoint.bind(this)); 38 37 39 38 this.element.appendChild(this.sourceFrame.element); … … 45 44 WebInspector.View.prototype.show.call(this, parentElement); 46 45 this.setupSourceFrameIfNeeded(); 47 }, 48 49 hide: function() 50 { 51 WebInspector.View.prototype.hide.call(this); 52 this._currentSearchResultIndex = -1; 46 this.resize(); 53 47 }, 54 48 … … 60 54 this.attach(); 61 55 62 if (!InspectorFrontendHost.addSourceToFrame("text/javascript", this.script.source, this.sourceFrame.element)) 63 return; 64 56 this.sourceFrame.setContent("text/javascript", this.script.source); 57 this._sourceFrameSetup = true; 65 58 delete this._frameNeedsSetup; 66 67 this.sourceFrame.addEventListener("syntax highlighting complete", this._syntaxHighlightingComplete, this);68 this.sourceFrame.syntaxHighlightJavascript();69 59 }, 70 60 … … 84 74 // generic and work with ScriptView just fine. 85 75 76 hide: WebInspector.SourceView.prototype.hide, 86 77 revealLine: WebInspector.SourceView.prototype.revealLine, 87 78 highlightLine: WebInspector.SourceView.prototype.highlightLine, … … 98 89 _jumpToSearchResult: WebInspector.SourceView.prototype._jumpToSearchResult, 99 90 _sourceFrameSetupFinished: WebInspector.SourceView.prototype._sourceFrameSetupFinished, 100 _syntaxHighlightingComplete: WebInspector.SourceView.prototype._syntaxHighlightingComplete91 resize: WebInspector.SourceView.prototype.resize 101 92 } 102 93 -
trunk/WebCore/inspector/front-end/ScriptsPanel.js
r53806 r53941 800 800 this.sidebarResizeElement.style.right = (newWidth - 3) + "px"; 801 801 802 this.resize(); 802 803 event.preventDefault(); 803 804 }, -
trunk/WebCore/inspector/front-end/SourceFrame.js
r53794 r53941 1 1 /* 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. 3 * Copyright (C) 2009 Joseph Pecoraro 2 * Copyright (C) 2009 Google Inc. All rights reserved. 4 3 * 5 4 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 5 * modification, are permitted provided that the following conditions are 6 * met: 13 7 * 14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 29 */ 26 30 27 WebInspector.SourceFrame = function( element,addBreakpointDelegate)31 WebInspector.SourceFrame = function(addBreakpointDelegate) 28 32 { 29 this.messages = []; 33 this._editor = new WebInspector.TextEditor(WebInspector.platform); 34 this._textModel = this._editor.textModel; 35 this._editor.lineNumberDecorator = new WebInspector.BreakpointLineNumberDecorator(this); 36 this._editor.lineDecorator = new WebInspector.ExecutionLineDecorator(this); 37 this._editor.readOnly = true; 38 this._messages = []; 39 this._rowMessages = {}; 40 this._messageBubbles = {}; 30 41 this.breakpoints = []; 31 42 this._shortcuts = {}; 43 this.element = this._editor.element; 44 this.element.addEventListener("keydown", this._keyDown.bind(this), true); 45 this._loaded = false; 32 46 33 47 this.addBreakpointDelegate = addBreakpointDelegate; 34 35 this.element = element || document.createElement("iframe");36 this.element.addStyleClass("source-view-frame");37 this.element.setAttribute("viewsource", "true");38 39 this.element.addEventListener("load", this._loaded.bind(this), false);40 48 } 41 49 42 50 WebInspector.SourceFrame.prototype = { 51 43 52 get executionLine() 44 53 { … … 50 59 if (this._executionLine === x) 51 60 return; 52 53 var previousLine = this._executionLine;54 61 this._executionLine = x; 55 56 this._updateExecutionLine(previousLine); 57 }, 58 59 sourceRow: function(lineNumber) 60 { 61 if (!lineNumber || !this.element.contentDocument) 62 return; 63 64 var table = this.element.contentDocument.getElementsByTagName("table")[0]; 65 if (!table) 66 return; 67 68 var rows = table.rows; 69 70 // Line numbers are a 1-based index, but the rows collection is 0-based. 71 --lineNumber; 72 73 return rows[lineNumber]; 74 }, 75 76 lineNumberForSourceRow: function(sourceRow) 77 { 78 // Line numbers are a 1-based index, but the rows collection is 0-based. 79 var lineNumber = 0; 80 while (sourceRow) { 81 ++lineNumber; 82 sourceRow = sourceRow.previousSibling; 83 } 84 85 return lineNumber; 62 this._editor.repaintAll(); 86 63 }, 87 64 88 65 revealLine: function(lineNumber) 89 66 { 90 if (!this._ isContentLoaded()) {67 if (!this._loaded) 91 68 this._lineNumberToReveal = lineNumber; 92 return; 93 } 94 95 var row = this.sourceRow(lineNumber); 96 if (row) 97 row.scrollIntoViewIfNeeded(true); 69 else 70 this._editor.reveal(lineNumber - 1, 0); 98 71 }, 99 72 … … 101 74 { 102 75 this.breakpoints.push(breakpoint); 103 breakpoint.addEventListener("enabled", this._breakpointEnableChanged, this); 104 breakpoint.addEventListener("disabled", this._breakpointEnableChanged, this); 76 breakpoint.addEventListener("enabled", this._breakpointChanged, this); 77 breakpoint.addEventListener("disabled", this._breakpointChanged, this); 78 breakpoint.addEventListener("condition-changed", this._breakpointChanged, this); 105 79 this._addBreakpointToSource(breakpoint); 106 80 }, … … 111 85 breakpoint.removeEventListener("enabled", null, this); 112 86 breakpoint.removeEventListener("disabled", null, this); 87 breakpoint.removeEventListener("condition-changed", null, this); 113 88 this._removeBreakpointFromSource(breakpoint); 114 89 }, … … 119 94 if (!msg.message || msg.line <= 0 || !msg.isErrorOrWarning()) 120 95 return; 121 this. messages.push(msg);96 this._messages.push(msg); 122 97 this._addMessageToSource(msg); 123 98 }, … … 125 100 clearMessages: function() 126 101 { 127 this.messages = []; 128 129 if (!this.element.contentDocument) 130 return; 131 132 var bubbles = this.element.contentDocument.querySelectorAll(".webkit-html-message-bubble"); 133 if (!bubbles) 134 return; 135 136 for (var i = 0; i < bubbles.length; ++i) { 137 var bubble = bubbles[i]; 102 for (var line in this._messageBubbles) { 103 var bubble = this._messageBubbles[line]; 138 104 bubble.parentNode.removeChild(bubble); 139 105 } 106 107 this._messages = []; 108 this._rowMessages = {}; 109 this._messageBubbles = {}; 110 this._editor.packAndRepaintAll(); 140 111 }, 141 112 142 113 sizeToFitContentHeight: function() 143 114 { 144 if (this.element.contentDocument) { 145 this.element.style.setProperty("height", this.element.contentDocument.body.offsetHeight + "px"); 146 this.element.contentDocument.body.addStyleClass("webkit-height-sized-to-fit"); 147 } 148 }, 149 150 _highlightLineEnds: function(event) 151 { 152 event.target.parentNode.removeStyleClass("webkit-highlighted-line"); 153 }, 154 155 highlightLine: function(lineNumber) 156 { 157 if (!this._isContentLoaded()) { 158 this._lineNumberToHighlight = lineNumber; 159 return; 160 } 161 162 var sourceRow = this.sourceRow(lineNumber); 163 if (!sourceRow) 164 return; 165 var line = sourceRow.getElementsByClassName('webkit-line-content')[0]; 166 // Trick to reset the animation if the user clicks on the same link 167 // Using a timeout to avoid coalesced style updates 168 line.style.setProperty("-webkit-animation-name", "none"); 169 setTimeout(function () { 170 line.style.removeProperty("-webkit-animation-name"); 171 sourceRow.addStyleClass("webkit-highlighted-line"); 172 }, 0); 173 }, 174 175 _loaded: function() 176 { 177 WebInspector.addMainEventListeners(this.element.contentDocument); 178 this.element.contentDocument.addEventListener("contextmenu", this._documentContextMenu.bind(this), true); 179 this.element.contentDocument.addEventListener("mousedown", this._documentMouseDown.bind(this), true); 180 this.element.contentDocument.addEventListener("keydown", this._documentKeyDown.bind(this), true); 181 this.element.contentDocument.addEventListener("webkitAnimationEnd", this._highlightLineEnds.bind(this), false); 182 183 // Register 'eval' shortcut. 184 var platformSpecificModifier = WebInspector.isMac() ? WebInspector.KeyboardShortcut.Modifiers.Meta : WebInspector.KeyboardShortcut.Modifiers.Ctrl; 185 var shortcut = WebInspector.KeyboardShortcut.makeKey(69 /* 'E' */, platformSpecificModifier | WebInspector.KeyboardShortcut.Modifiers.Shift); 186 this._shortcuts[shortcut] = this._evalSelectionInCallFrame.bind(this); 187 188 var headElement = this.element.contentDocument.head; 189 if (!headElement) { 190 headElement = this.element.contentDocument.createElement("head"); 191 this.element.contentDocument.documentElement.insertBefore(headElement, this.element.contentDocument.documentElement.firstChild); 192 } 193 194 var linkElement = this.element.contentDocument.createElement("link"); 195 linkElement.type = "text/css"; 196 linkElement.rel = "stylesheet"; 197 linkElement.href = "inspectorSyntaxHighlight.css"; 198 headElement.appendChild(linkElement); 199 200 var styleElement = this.element.contentDocument.createElement("style"); 201 headElement.appendChild(styleElement); 202 203 // Add these style rules here since they are specific to the Inspector. They also behave oddly and not 204 // all properties apply if added to view-source.css (because it is a user agent sheet.) 205 var styleText = ".webkit-line-number { background-repeat: no-repeat; background-position: right 1px; }\n"; 206 styleText += ".webkit-execution-line .webkit-line-number { color: transparent; background-image: -webkit-canvas(program-counter); }\n"; 207 208 styleText += ".webkit-breakpoint .webkit-line-number { color: white; background-image: -webkit-canvas(breakpoint); }\n"; 209 styleText += ".webkit-breakpoint-disabled .webkit-line-number { color: white; background-image: -webkit-canvas(breakpoint-disabled); }\n"; 210 styleText += ".webkit-breakpoint.webkit-execution-line .webkit-line-number { color: transparent; background-image: -webkit-canvas(breakpoint-program-counter); }\n"; 211 styleText += ".webkit-breakpoint-disabled.webkit-execution-line .webkit-line-number { color: transparent; background-image: -webkit-canvas(breakpoint-disabled-program-counter); }\n"; 212 213 styleText += ".webkit-breakpoint.webkit-breakpoint-conditional .webkit-line-number { color: white; background-image: -webkit-canvas(breakpoint-conditional); }\n"; 214 styleText += ".webkit-breakpoint-disabled.webkit-breakpoint-conditional .webkit-line-number { color: white; background-image: -webkit-canvas(breakpoint-disabled-conditional); }\n"; 215 styleText += ".webkit-breakpoint.webkit-breakpoint-conditional.webkit-execution-line .webkit-line-number { color: transparent; background-image: -webkit-canvas(breakpoint-conditional-program-counter); }\n"; 216 styleText += ".webkit-breakpoint-disabled.webkit-breakpoint-conditional.webkit-execution-line .webkit-line-number { color: transparent; background-image: -webkit-canvas(breakpoint-disabled-conditional-program-counter); }\n"; 217 218 styleText += ".webkit-execution-line .webkit-line-content { background-color: rgb(171, 191, 254); outline: 1px solid rgb(64, 115, 244); }\n"; 219 styleText += ".webkit-height-sized-to-fit { overflow-y: hidden }\n"; 220 styleText += ".webkit-line-content { background-color: white; }\n"; 221 styleText += "@-webkit-keyframes fadeout {from {background-color: rgb(255, 255, 120);} to { background-color: white;}}\n"; 222 styleText += ".webkit-highlighted-line .webkit-line-content { background-color: rgb(255, 255, 120); -webkit-animation: 'fadeout' 2s 500ms}\n"; 223 224 // TODO: Move these styles into inspector.css once https://bugs.webkit.org/show_bug.cgi?id=28913 is fixed and popup moved into the top frame. 225 styleText += ".popup-content { position: absolute; z-index: 10000; padding: 4px; background-color: rgb(203, 226, 255); -webkit-border-radius: 7px; border: 2px solid rgb(169, 172, 203); }"; 226 styleText += ".popup-glasspane { position: absolute; top: 0; left: 0; height: 100%; width: 100%; opacity: 0; z-index: 9900; }"; 227 styleText += ".popup-message { background-color: transparent; font-family: Lucida Grande, sans-serif; font-weight: normal; font-size: 11px; text-align: left; text-shadow: none; color: rgb(85, 85, 85); cursor: default; margin: 0 0 2px 0; }"; 228 styleText += ".popup-content.breakpoint-condition { width: 90%; }"; 229 styleText += ".popup-content input#bp-condition { font-family: monospace; margin: 0; border: 1px inset rgb(190, 190, 190) !important; width: 100%; box-shadow: none !important; outline: none !important; -webkit-user-modify: read-write; }"; 230 // This class is already in inspector.css 231 styleText += ".hidden { display: none !important; }"; 232 233 styleElement.textContent = styleText; 234 235 this._needsProgramCounterImage = true; 236 this._needsBreakpointImages = true; 237 238 this.element.contentWindow.Element.prototype.addStyleClass = Element.prototype.addStyleClass; 239 this.element.contentWindow.Element.prototype.removeStyleClass = Element.prototype.removeStyleClass; 240 this.element.contentWindow.Element.prototype.removeChildren = Element.prototype.removeChildren; 241 this.element.contentWindow.Element.prototype.positionAt = Element.prototype.positionAt; 242 this.element.contentWindow.Element.prototype.removeMatchingStyleClasses = Element.prototype.removeMatchingStyleClasses; 243 this.element.contentWindow.Element.prototype.hasStyleClass = Element.prototype.hasStyleClass; 244 this.element.contentWindow.Element.prototype.pageOffsetRelativeToWindow = Element.prototype.pageOffsetRelativeToWindow; 245 this.element.contentWindow.Element.prototype.__defineGetter__("totalOffsetLeft", Element.prototype.__lookupGetter__("totalOffsetLeft")); 246 this.element.contentWindow.Element.prototype.__defineGetter__("totalOffsetTop", Element.prototype.__lookupGetter__("totalOffsetTop")); 247 this.element.contentWindow.Node.prototype.enclosingNodeOrSelfWithNodeName = Node.prototype.enclosingNodeOrSelfWithNodeName; 248 this.element.contentWindow.Node.prototype.enclosingNodeOrSelfWithNodeNameInArray = Node.prototype.enclosingNodeOrSelfWithNodeNameInArray; 115 this._editor.packAndRepaintAll(); 116 }, 117 118 setContent: function(mimeType, content) 119 { 120 this._loaded = true; 121 this._editor.mimeType = mimeType; 122 this._editor.text = content; 249 123 250 124 this._addExistingMessagesToSource(); 251 125 this._addExistingBreakpointsToSource(); 252 this._updateExecutionLine();253 126 if (this._executionLine) 254 127 this.revealLine(this._executionLine); … … 258 131 delete this._lineNumberToReveal; 259 132 } 260 261 if (this._lineNumberToHighlight) { 262 this.highlightLine(this._lineNumberToHighlight); 263 delete this._lineNumberToHighlight; 264 } 265 266 this.dispatchEventToListeners("content loaded"); 267 }, 268 269 _isContentLoaded: function() { 270 var doc = this.element.contentDocument; 271 return doc && doc.getElementsByTagName("table")[0]; 272 }, 273 274 _documentContextMenu: function(event) 275 { 276 if (!event.target.hasStyleClass("webkit-line-number")) 277 return; 278 if (!this.addBreakpointDelegate) 279 return; 280 281 var sourceRow = event.target.enclosingNodeOrSelfWithNodeName("tr"); 282 var contextMenu = new WebInspector.ContextMenu(); 283 284 if (!sourceRow._breakpointObject && this.addBreakpointDelegate) { 285 var lineNumber = this.lineNumberForSourceRow(sourceRow); 286 // This row doesn't have a breakpoint: We want to show Add Breakpoint and Add and Edit Breakpoint. 287 contextMenu.appendItem(WebInspector.UIString("Add Breakpoint"), this.addBreakpointDelegate.bind(this, lineNumber)); 288 289 function addConditionalBreakpoint() 290 { 291 this.addBreakpointDelegate(lineNumber); 292 var breakpoint = sourceRow._breakpointObject; 293 if (breakpoint) 294 this._editBreakpointCondition(event.target, sourceRow, breakpoint); 295 } 296 297 contextMenu.appendItem(WebInspector.UIString("Add Conditional Breakpoint..."), addConditionalBreakpoint.bind(this)); 298 } else if (sourceRow._breakpointObject) { 299 // This row has a breakpoint, we want to show edit and remove breakpoint, and either disable or enable. 300 contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), WebInspector.panels.scripts.removeBreakpoint.bind(WebInspector.panels.scripts, sourceRow._breakpointObject)); 301 contextMenu.appendItem(WebInspector.UIString("Edit Breakpoint..."), this._editBreakpointCondition.bind(this, event.target, sourceRow, sourceRow._breakpointObject)); 302 if (sourceRow._breakpointObject.enabled) 303 contextMenu.appendItem(WebInspector.UIString("Disable Breakpoint"), function() { sourceRow._breakpointObject.enabled = false; }); 304 else 305 contextMenu.appendItem(WebInspector.UIString("Enable Breakpoint"), function() { sourceRow._breakpointObject.enabled = true; }); 306 } 307 308 contextMenu.show(event); 309 }, 310 311 _documentMouseDown: function(event) 312 { 313 if (!event.target.hasStyleClass("webkit-line-number")) 314 return; 315 if (event.button != 0 || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) 316 return; 317 var sourceRow = event.target.enclosingNodeOrSelfWithNodeName("tr"); 318 if (sourceRow._breakpointObject) 319 WebInspector.panels.scripts.removeBreakpoint(sourceRow._breakpointObject); 320 else if (this.addBreakpointDelegate) 321 this.addBreakpointDelegate(this.lineNumberForSourceRow(sourceRow)); 322 323 event.preventDefault(); 324 }, 325 326 _editBreakpointCondition: function(eventTarget, sourceRow, breakpoint) 327 { 328 // TODO: Migrate the popup to the top-level document and remove the blur listener from conditionElement once https://bugs.webkit.org/show_bug.cgi?id=28913 is fixed. 329 var popupDocument = this.element.contentDocument; 330 this._showBreakpointConditionPopup(eventTarget, breakpoint.line, popupDocument); 331 332 function committed(element, newText) 333 { 334 breakpoint.condition = newText; 335 if (breakpoint.condition) 336 sourceRow.addStyleClass("webkit-breakpoint-conditional"); 337 else 338 sourceRow.removeStyleClass("webkit-breakpoint-conditional"); 339 dismissed.call(this); 340 } 341 342 function dismissed() 343 { 344 this._popup.hide(); 345 delete this._conditionEditorElement; 346 } 347 348 var dismissedHandler = dismissed.bind(this); 349 this._conditionEditorElement.addEventListener("blur", dismissedHandler, false); 350 351 WebInspector.startEditing(this._conditionEditorElement, committed.bind(this), dismissedHandler); 352 this._conditionEditorElement.value = breakpoint.condition; 353 this._conditionEditorElement.select(); 354 }, 355 356 _showBreakpointConditionPopup: function(clickedElement, lineNumber, popupDocument) 357 { 358 var popupContentElement = this._createPopupElement(lineNumber, popupDocument); 359 var lineElement = clickedElement.enclosingNodeOrSelfWithNodeName("td").nextSibling; 360 if (this._popup) { 361 this._popup.hide(); 362 this._popup.element = popupContentElement; 363 } else { 364 this._popup = new WebInspector.Popup(popupContentElement); 365 this._popup.autoHide = true; 366 } 367 this._popup.anchor = lineElement; 368 this._popup.show(); 369 }, 370 371 _createPopupElement: function(lineNumber, popupDocument) 372 { 373 var popupContentElement = popupDocument.createElement("div"); 374 popupContentElement.className = "popup-content breakpoint-condition"; 375 376 var labelElement = document.createElement("label"); 377 labelElement.className = "popup-message"; 378 labelElement.htmlFor = "bp-condition"; 379 labelElement.appendChild(document.createTextNode(WebInspector.UIString("The breakpoint on line %d will stop only if this expression is true:", lineNumber))); 380 popupContentElement.appendChild(labelElement); 381 382 var editorElement = document.createElement("input"); 383 editorElement.id = "bp-condition"; 384 editorElement.type = "text" 385 popupContentElement.appendChild(editorElement); 386 this._conditionEditorElement = editorElement; 387 388 return popupContentElement; 389 }, 390 391 _documentKeyDown: function(event) 392 { 393 var shortcut = WebInspector.KeyboardShortcut.makeKeyFromEvent(event); 394 var handler = this._shortcuts[shortcut]; 395 if (handler) { 396 handler(event); 397 event.preventDefault(); 398 } else { 399 WebInspector.documentKeyDown(event); 400 } 401 }, 402 403 _evalSelectionInCallFrame: function(event) 404 { 405 if (!WebInspector.panels.scripts || !WebInspector.panels.scripts.paused) 406 return; 407 408 var selection = this.element.contentWindow.getSelection(); 409 if (!selection.rangeCount) 410 return; 411 412 var expression = selection.getRangeAt(0).toString().trim(); 413 WebInspector.panels.scripts.evaluateInSelectedCallFrame(expression, false, "console", function(result, exception) { 414 WebInspector.showConsole(); 415 var commandMessage = new WebInspector.ConsoleCommand(expression); 416 WebInspector.console.addMessage(commandMessage); 417 WebInspector.console.addMessage(new WebInspector.ConsoleCommandResult(result, exception, commandMessage)); 418 }); 419 }, 420 421 _breakpointEnableChanged: function(event) 422 { 423 var breakpoint = event.target; 424 var sourceRow = this.sourceRow(breakpoint.line); 425 if (!sourceRow) 426 return; 427 428 sourceRow.addStyleClass("webkit-breakpoint"); 429 430 if (breakpoint.enabled) 431 sourceRow.removeStyleClass("webkit-breakpoint-disabled"); 432 else 433 sourceRow.addStyleClass("webkit-breakpoint-disabled"); 434 }, 435 436 _updateExecutionLine: function(previousLine) 437 { 438 if (previousLine) { 439 var sourceRow = this.sourceRow(previousLine); 440 if (sourceRow) 441 sourceRow.removeStyleClass("webkit-execution-line"); 442 } 443 444 if (!this._executionLine) 445 return; 446 447 this._drawProgramCounterImageIfNeeded(); 448 449 var sourceRow = this.sourceRow(this._executionLine); 450 if (sourceRow) 451 sourceRow.addStyleClass("webkit-execution-line"); 452 }, 453 454 _addExistingBreakpointsToSource: function() 455 { 456 var length = this.breakpoints.length; 457 for (var i = 0; i < length; ++i) 458 this._addBreakpointToSource(this.breakpoints[i]); 459 }, 460 461 _addBreakpointToSource: function(breakpoint) 462 { 463 var sourceRow = this.sourceRow(breakpoint.line); 464 if (!sourceRow) 465 return; 466 467 breakpoint.sourceText = sourceRow.getElementsByClassName('webkit-line-content')[0].textContent; 468 469 this._drawBreakpointImagesIfNeeded(); 470 471 sourceRow._breakpointObject = breakpoint; 472 473 sourceRow.addStyleClass("webkit-breakpoint"); 474 if (!breakpoint.enabled) 475 sourceRow.addStyleClass("webkit-breakpoint-disabled"); 476 if (breakpoint.condition) 477 sourceRow.addStyleClass("webkit-breakpoint-conditional"); 478 }, 479 480 _removeBreakpointFromSource: function(breakpoint) 481 { 482 var sourceRow = this.sourceRow(breakpoint.line); 483 if (!sourceRow) 484 return; 485 486 delete sourceRow._breakpointObject; 487 488 sourceRow.removeStyleClass("webkit-breakpoint"); 489 sourceRow.removeStyleClass("webkit-breakpoint-disabled"); 490 sourceRow.removeStyleClass("webkit-breakpoint-conditional"); 133 this._editor.setCoalescingUpdate(true); 134 this._editor.updateCanvasSize(); 135 this._editor.packAndRepaintAll(); 136 this._editor.setCoalescingUpdate(false); 137 }, 138 139 findSearchMatches: function(query) 140 { 141 var ranges = []; 142 143 // First do case-insensitive search. 144 var regex = ""; 145 for (var i = 0; i < query.length; ++i) { 146 var char = query.charAt(i); 147 if (char === "]") 148 char = "\\]"; 149 regex += "[" + char + "]"; 150 } 151 var regexObject = new RegExp(regex, "i"); 152 this._collectRegexMatches(regexObject, ranges); 153 154 // Then try regex search if user knows the / / hint. 155 try { 156 if (/^\/.*\/$/.test(query)) 157 this._collectRegexMatches(new RegExp(query.substring(1, query.length - 1)), ranges); 158 } catch (e) { 159 // Silent catch. 160 } 161 return ranges; 162 }, 163 164 _collectRegexMatches: function(regexObject, ranges) 165 { 166 for (var i = 0; i < this._textModel.linesCount; ++i) { 167 var line = this._textModel.line(i); 168 var offset = 0; 169 do { 170 var match = regexObject.exec(line); 171 if (match) { 172 ranges.push(new WebInspector.TextRange(i, offset + match.index, i, offset + match.index + match[0].length)); 173 offset += match.index + 1; 174 line = line.substring(match.index + 1); 175 } 176 } while (match) 177 } 178 return ranges; 179 }, 180 181 setSelection: function(range) 182 { 183 this._editor.setSelection(range.startLine, range.startColumn, range.endLine, range.endColumn); 184 }, 185 186 clearSelection: function() 187 { 188 var range = this._editor.selection; 189 this._editor.setSelection(range.endLine, range.endColumn, range.endLine, range.endColumn); 491 190 }, 492 191 … … 508 207 _addExistingMessagesToSource: function() 509 208 { 510 var length = this. messages.length;209 var length = this._messages.length; 511 210 for (var i = 0; i < length; ++i) 512 this._addMessageToSource(this. messages[i]);211 this._addMessageToSource(this._messages[i]); 513 212 }, 514 213 515 214 _addMessageToSource: function(msg) 516 215 { 517 var row = this.sourceRow(msg.line); 518 if (!row) 519 return; 520 521 var cell = row.cells[1]; 522 if (!cell) 523 return; 524 525 var messageBubbleElement = cell.lastChild; 216 if (msg.line >= this._textModel.linesCount) 217 return; 218 219 var messageBubbleElement = this._messageBubbles[msg.line]; 526 220 if (!messageBubbleElement || messageBubbleElement.nodeType !== Node.ELEMENT_NODE || !messageBubbleElement.hasStyleClass("webkit-html-message-bubble")) { 527 messageBubbleElement = this.element.contentDocument.createElement("div");221 messageBubbleElement = document.createElement("div"); 528 222 messageBubbleElement.className = "webkit-html-message-bubble"; 529 cell.appendChild(messageBubbleElement); 530 } 531 532 if (!row.messages) 533 row.messages = []; 534 535 for (var i = 0; i < row.messages.length; ++i) { 536 if (row.messages[i].isEqual(msg, true)) { 537 this._incrementMessageRepeatCount(row.messages[i], msg.repeatDelta); 223 this._messageBubbles[msg.line] = messageBubbleElement; 224 this._editor.setDivDecoration(msg.line - 1, messageBubbleElement); 225 } 226 227 var rowMessages = this._rowMessages[msg.line]; 228 if (!rowMessages) { 229 rowMessages = []; 230 this._rowMessages[msg.line] = rowMessages; 231 } 232 233 for (var i = 0; i < rowMessages.length; ++i) { 234 if (rowMessages[i].isEqual(msg, true)) { 235 this._incrementMessageRepeatCount(rowMessages[i], msg.repeatDelta); 236 this._editor.packAndRepaintAll(); 538 237 return; 539 238 } 540 239 } 541 240 542 row .messages.push(msg);241 rowMessages.push(msg); 543 242 544 243 var imageURL; … … 554 253 } 555 254 556 var messageLineElement = this.element.contentDocument.createElement("div");255 var messageLineElement = document.createElement("div"); 557 256 messageLineElement.className = "webkit-html-message-line"; 558 257 messageBubbleElement.appendChild(messageLineElement); … … 562 261 image.src = imageURL; 563 262 image.className = "webkit-html-message-icon"; 564 565 // Adopt the image element since it wasn't created in element's contentDocument.566 image = this.element.contentDocument.adoptNode(image);567 263 messageLineElement.appendChild(image); 568 messageLineElement.appendChild( this.element.contentDocument.createTextNode(msg.message));264 messageLineElement.appendChild(document.createTextNode(msg.message)); 569 265 570 266 msg._resourceMessageLineElement = messageLineElement; 571 }, 572 573 _drawProgramCounterInContext: function(ctx, glow) 574 { 575 if (glow) 267 268 this._editor.packAndRepaintAll(); 269 }, 270 271 _addExistingBreakpointsToSource: function() 272 { 273 var length = this.breakpoints.length; 274 for (var i = 0; i < length; ++i) 275 this._addBreakpointToSource(this.breakpoints[i]); 276 }, 277 278 _addBreakpointToSource: function(breakpoint) 279 { 280 this._textModel.setAttribute(breakpoint.line - 1, "breakpoint", breakpoint); 281 this._editor.paintLineNumbers(); 282 }, 283 284 _removeBreakpointFromSource: function(breakpoint) 285 { 286 this._textModel.removeAttribute(breakpoint.line - 1, "breakpoint"); 287 this._editor.paintLineNumbers(); 288 }, 289 290 _contextMenu: function(lineNumber, event) 291 { 292 if (!this.addBreakpointDelegate) 293 return; 294 295 var contextMenu = new WebInspector.ContextMenu(); 296 297 var breakpoint = this._textModel.getAttribute(lineNumber, "breakpoint"); 298 if (!breakpoint) { 299 // This row doesn't have a breakpoint: We want to show Add Breakpoint and Add and Edit Breakpoint. 300 contextMenu.appendItem(WebInspector.UIString("Add Breakpoint"), this.addBreakpointDelegate.bind(this, lineNumber + 1)); 301 302 function addConditionalBreakpoint() 303 { 304 this.addBreakpointDelegate(lineNumber + 1); 305 var breakpoint = this._textModel.getAttribute(lineNumber, "breakpoint"); 306 if (breakpoint) 307 this._editBreakpointCondition(breakpoint); 308 } 309 310 contextMenu.appendItem(WebInspector.UIString("Add Conditional Breakpoint..."), addConditionalBreakpoint.bind(this)); 311 } else { 312 // This row has a breakpoint, we want to show edit and remove breakpoint, and either disable or enable. 313 contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), WebInspector.panels.scripts.removeBreakpoint.bind(WebInspector.panels.scripts, breakpoint)); 314 contextMenu.appendItem(WebInspector.UIString("Edit Breakpoint..."), this._editBreakpointCondition.bind(this, breakpoint)); 315 if (breakpoint.enabled) 316 contextMenu.appendItem(WebInspector.UIString("Disable Breakpoint"), function() { breakpoint.enabled = false; }); 317 else 318 contextMenu.appendItem(WebInspector.UIString("Enable Breakpoint"), function() { breakpoint.enabled = true; }); 319 } 320 contextMenu.show(event); 321 }, 322 323 _toggleBreakpoint: function(lineNumber, event) 324 { 325 if (event.button != 0 || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) 326 return; 327 var breakpoint = this._textModel.getAttribute(lineNumber, "breakpoint"); 328 if (breakpoint) 329 WebInspector.panels.scripts.removeBreakpoint(breakpoint); 330 else if (this.addBreakpointDelegate) 331 this.addBreakpointDelegate(lineNumber + 1); 332 event.preventDefault(); 333 }, 334 335 _editBreakpointCondition: function(breakpoint) 336 { 337 this._showBreakpointConditionPopup(breakpoint.line); 338 339 function committed(element, newText) 340 { 341 breakpoint.condition = newText; 342 this._editor.paintLineNumbers(); 343 dismissed.call(this); 344 } 345 346 function dismissed() 347 { 348 this._editor.setDivDecoration(breakpoint.line - 1, null); 349 delete this._conditionEditorElement; 350 } 351 352 var dismissedHandler = dismissed.bind(this); 353 this._conditionEditorElement.addEventListener("blur", dismissedHandler, false); 354 355 WebInspector.startEditing(this._conditionEditorElement, committed.bind(this), dismissedHandler); 356 this._conditionEditorElement.value = breakpoint.condition; 357 this._conditionEditorElement.select(); 358 }, 359 360 _showBreakpointConditionPopup: function(lineNumber) 361 { 362 var conditionElement = this._createConditionElement(lineNumber); 363 this._editor.setDivDecoration(lineNumber - 1, conditionElement); 364 }, 365 366 _createConditionElement: function(lineNumber) 367 { 368 var conditionElement = document.createElement("div"); 369 conditionElement.className = "source-breakpoint-condition"; 370 371 var labelElement = document.createElement("label"); 372 labelElement.className = "source-breakpoint-message"; 373 labelElement.htmlFor = "source-breakpoint-condition"; 374 labelElement.appendChild(document.createTextNode(WebInspector.UIString("The breakpoint on line %d will stop only if this expression is true:", lineNumber))); 375 conditionElement.appendChild(labelElement); 376 377 var editorElement = document.createElement("input"); 378 editorElement.id = "source-breakpoint-condition"; 379 editorElement.type = "text" 380 conditionElement.appendChild(editorElement); 381 this._conditionEditorElement = editorElement; 382 383 return conditionElement; 384 }, 385 386 _keyDown: function(event) 387 { 388 var shortcut = WebInspector.KeyboardShortcut.makeKeyFromEvent(event); 389 var handler = this._shortcuts[shortcut]; 390 if (handler) { 391 handler(event); 392 event.preventDefault(); 393 } else { 394 WebInspector.documentKeyDown(event); 395 } 396 }, 397 398 _evalSelectionInCallFrame: function(event) 399 { 400 if (!WebInspector.panels.scripts || !WebInspector.panels.scripts.paused) 401 return; 402 403 var selection = this.element.contentWindow.getSelection(); 404 if (!selection.rangeCount) 405 return; 406 407 var expression = selection.getRangeAt(0).toString().trimWhitespace(); 408 WebInspector.panels.scripts.evaluateInSelectedCallFrame(expression, false, "console", function(result, exception) { 409 WebInspector.showConsole(); 410 var commandMessage = new WebInspector.ConsoleCommand(expression); 411 WebInspector.console.addMessage(commandMessage); 412 WebInspector.console.addMessage(new WebInspector.ConsoleCommandResult(result, exception, commandMessage)); 413 }); 414 }, 415 416 _breakpointChanged: function(event) 417 { 418 this._editor.paintLineNumbers(); 419 }, 420 421 resize: function() 422 { 423 this._editor.updateCanvasSize(); 424 } 425 } 426 427 WebInspector.SourceFrame.prototype.__proto__ = WebInspector.Object.prototype; 428 429 WebInspector.BreakpointLineNumberDecorator = function(sourceFrame) 430 { 431 this._sourceFrame = sourceFrame; 432 this._textModel = sourceFrame._editor.textModel; 433 } 434 435 WebInspector.BreakpointLineNumberDecorator.prototype = { 436 decorate: function(lineNumber, ctx, x, y, width, height, lineHeight) 437 { 438 var breakpoint = this._textModel.getAttribute(lineNumber, "breakpoint"); 439 var isExecutionLine = lineNumber + 1 === this._sourceFrame._executionLine; 440 if (breakpoint || isExecutionLine) { 576 441 ctx.save(); 577 442 ctx.translate(x + 4, y + 2); 443 var breakpointWidth = width - 6; 444 var breakpointHeight = lineHeight - 4; 445 446 if (breakpoint) 447 this._paintBreakpoint(ctx, breakpointWidth, breakpointHeight, breakpoint); 448 449 if (isExecutionLine) 450 this._paintProgramCounter(ctx, breakpointWidth, breakpointHeight, false); 451 452 ctx.restore(); 453 } 454 455 if (isExecutionLine) { 456 // Override default behavior. 457 return true; 458 } 459 460 ctx.fillStyle = breakpoint ? "rgb(255,255,255)" : "rgb(155,155,155)"; 461 return false; 462 }, 463 464 _paintBreakpoint: function(ctx, width, height, breakpoint) 465 { 578 466 ctx.beginPath(); 579 ctx.moveTo(17, 2); 580 ctx.lineTo(19, 2); 581 ctx.lineTo(19, 0); 582 ctx.lineTo(21, 0); 583 ctx.lineTo(26, 5.5); 584 ctx.lineTo(21, 11); 585 ctx.lineTo(19, 11); 586 ctx.lineTo(19, 9); 587 ctx.lineTo(17, 9); 467 ctx.moveTo(0, 2); 468 ctx.lineTo(2, 0); 469 ctx.lineTo(width - 5, 0); 470 ctx.lineTo(width, height / 2); 471 ctx.lineTo(width - 5, height); 472 ctx.lineTo(2, height); 473 ctx.lineTo(0, height - 2); 588 474 ctx.closePath(); 589 ctx.fillStyle = "rgb(142, 5, 4)"; 590 591 if (glow) { 592 ctx.shadowBlur = 4; 593 ctx.shadowColor = "rgb(255, 255, 255)"; 594 ctx.shadowOffsetX = -1; 595 ctx.shadowOffsetY = 0; 596 } 597 475 ctx.fillStyle = breakpoint.condition ? "rgb(217, 142, 1)" : "rgb(1, 142, 217)"; 476 ctx.strokeStyle = breakpoint.condition ? "rgb(205, 103, 0)" : "rgb(0, 103, 205)"; 477 ctx.lineWidth = 3; 598 478 ctx.fill(); 599 ctx.fill(); // Fill twice to get a good shadow and darker anti-aliased pixels. 600 601 if (glow) 602 ctx.restore(); 603 }, 604 605 _drawProgramCounterImageIfNeeded: function() 606 { 607 if (!this._needsProgramCounterImage || !this.element.contentDocument) 608 return; 609 610 var ctx = this.element.contentDocument.getCSSCanvasContext("2d", "program-counter", 26, 11); 611 ctx.clearRect(0, 0, 26, 11); 612 this._drawProgramCounterInContext(ctx, true); 613 614 delete this._needsProgramCounterImage; 615 }, 616 617 _drawBreakpointImagesIfNeeded: function(conditional) 618 { 619 if (!this._needsBreakpointImages || !this.element.contentDocument) 620 return; 621 622 function drawBreakpoint(ctx, disabled, conditional) 623 { 624 ctx.beginPath(); 625 ctx.moveTo(0, 2); 626 ctx.lineTo(2, 0); 627 ctx.lineTo(21, 0); 628 ctx.lineTo(26, 5.5); 629 ctx.lineTo(21, 11); 630 ctx.lineTo(2, 11); 631 ctx.lineTo(0, 9); 632 ctx.closePath(); 633 ctx.fillStyle = conditional ? "rgb(217, 142, 1)" : "rgb(1, 142, 217)"; 634 ctx.strokeStyle = conditional ? "rgb(205, 103, 0)" : "rgb(0, 103, 205)"; 635 ctx.lineWidth = 3; 636 ctx.fill(); 637 ctx.save(); 638 ctx.clip(); 639 ctx.stroke(); 640 ctx.restore(); 641 642 if (!disabled) 643 return; 644 479 480 ctx.save(); 481 ctx.clip(); 482 ctx.stroke(); 483 ctx.restore(); 484 485 if (!breakpoint.enabled) { 645 486 ctx.save(); 646 487 ctx.globalCompositeOperation = "destination-out"; 647 488 ctx.fillStyle = "rgba(0, 0, 0, 0.5)"; 648 ctx.fillRect(0, 0, 26, 11);489 ctx.fillRect(0, 0, width, height); 649 490 ctx.restore(); 650 491 } 651 652 653 // Unconditional breakpoints. 654 655 var ctx = this.element.contentDocument.getCSSCanvasContext("2d", "breakpoint", 26, 11); 656 ctx.clearRect(0, 0, 26, 11); 657 drawBreakpoint(ctx); 658 659 var ctx = this.element.contentDocument.getCSSCanvasContext("2d", "breakpoint-program-counter", 26, 11); 660 ctx.clearRect(0, 0, 26, 11); 661 drawBreakpoint(ctx); 662 ctx.clearRect(20, 0, 6, 11); 663 this._drawProgramCounterInContext(ctx, true); 664 665 var ctx = this.element.contentDocument.getCSSCanvasContext("2d", "breakpoint-disabled", 26, 11); 666 ctx.clearRect(0, 0, 26, 11); 667 drawBreakpoint(ctx, true); 668 669 var ctx = this.element.contentDocument.getCSSCanvasContext("2d", "breakpoint-disabled-program-counter", 26, 11); 670 ctx.clearRect(0, 0, 26, 11); 671 drawBreakpoint(ctx, true); 672 ctx.clearRect(20, 0, 6, 11); 673 this._drawProgramCounterInContext(ctx, true); 674 675 676 // Conditional breakpoints. 677 678 var ctx = this.element.contentDocument.getCSSCanvasContext("2d", "breakpoint-conditional", 26, 11); 679 ctx.clearRect(0, 0, 26, 11); 680 drawBreakpoint(ctx, false, true); 681 682 var ctx = this.element.contentDocument.getCSSCanvasContext("2d", "breakpoint-conditional-program-counter", 26, 11); 683 ctx.clearRect(0, 0, 26, 11); 684 drawBreakpoint(ctx, false, true); 685 ctx.clearRect(20, 0, 6, 11); 686 this._drawProgramCounterInContext(ctx, true); 687 688 var ctx = this.element.contentDocument.getCSSCanvasContext("2d", "breakpoint-disabled-conditional", 26, 11); 689 ctx.clearRect(0, 0, 26, 11); 690 drawBreakpoint(ctx, true, true); 691 692 var ctx = this.element.contentDocument.getCSSCanvasContext("2d", "breakpoint-disabled-conditional-program-counter", 26, 11); 693 ctx.clearRect(0, 0, 26, 11); 694 drawBreakpoint(ctx, true, true); 695 ctx.clearRect(20, 0, 6, 11); 696 this._drawProgramCounterInContext(ctx, true); 697 698 delete this._needsBreakpointImages; 699 }, 700 701 syntaxHighlightJavascript: function() 702 { 703 var table = this.element.contentDocument.getElementsByTagName("table")[0]; 704 if (!table) 705 return; 706 707 var jsSyntaxHighlighter = new WebInspector.JavaScriptSourceSyntaxHighlighter(table, this); 708 jsSyntaxHighlighter.process(); 709 }, 710 711 syntaxHighlightCSS: function() 712 { 713 var table = this.element.contentDocument.getElementsByTagName("table")[0]; 714 if (!table) 715 return; 716 717 var cssSyntaxHighlighter = new WebInspector.CSSSourceSyntaxHighlighter(table, this); 718 cssSyntaxHighlighter.process(); 492 }, 493 494 _paintProgramCounter: function(ctx, width, height) 495 { 496 ctx.save(); 497 498 ctx.beginPath(); 499 ctx.moveTo(width - 9, 2); 500 ctx.lineTo(width - 7, 2); 501 ctx.lineTo(width - 7, 0); 502 ctx.lineTo(width - 5, 0); 503 ctx.lineTo(width, height / 2); 504 ctx.lineTo(width - 5, height); 505 ctx.lineTo(width - 7, height); 506 ctx.lineTo(width - 7, height - 2); 507 ctx.lineTo(width - 9, height - 2); 508 ctx.closePath(); 509 ctx.fillStyle = "rgb(142, 5, 4)"; 510 511 ctx.shadowBlur = 4; 512 ctx.shadowColor = "rgb(255, 255, 255)"; 513 ctx.shadowOffsetX = -1; 514 ctx.shadowOffsetY = 0; 515 516 ctx.fill(); 517 ctx.fill(); // Fill twice to get a good shadow and darker anti-aliased pixels. 518 519 ctx.restore(); 520 }, 521 522 mouseDown: function(lineNumber, e) 523 { 524 this._sourceFrame._toggleBreakpoint(lineNumber, e); 525 return true; 526 }, 527 528 contextMenu: function(lineNumber, e) 529 { 530 this._sourceFrame._contextMenu(lineNumber, e); 531 return true; 719 532 } 720 533 } 721 534 722 WebInspector.SourceFrame.prototype.__proto__ = WebInspector.Object.prototype; 535 WebInspector.ExecutionLineDecorator = function(sourceFrame) 536 { 537 this._sourceFrame = sourceFrame; 538 } 539 540 WebInspector.ExecutionLineDecorator.prototype = { 541 decorate: function(lineNumber, ctx, x, y, width, height, lineHeight) 542 { 543 if (this._sourceFrame._executionLine !== lineNumber + 1) 544 return; 545 ctx.save(); 546 ctx.fillStyle = "rgb(171, 191, 254)"; 547 ctx.fillRect(x, y, width, height); 548 549 ctx.beginPath(); 550 ctx.rect(x - 1, y, width + 2, height); 551 ctx.clip(); 552 ctx.strokeStyle = "rgb(64, 115, 244)"; 553 ctx.stroke(); 554 555 ctx.restore(); 556 } 557 } -
trunk/WebCore/inspector/front-end/SourceView.js
r53794 r53941 31 31 WebInspector.ResourceView.call(this, resource); 32 32 33 this.sourceFrame = new WebInspector.SourceFrame( null,this._addBreakpoint.bind(this));33 this.sourceFrame = new WebInspector.SourceFrame(this._addBreakpoint.bind(this)); 34 34 35 35 resource.addEventListener("finished", this._resourceLoadingFinished, this); … … 51 51 WebInspector.ResourceView.prototype.show.call(this, parentElement); 52 52 this.setupSourceFrameIfNeeded(); 53 this.resize(); 53 54 }, 54 55 … … 57 58 WebInspector.View.prototype.hide.call(this); 58 59 this._currentSearchResultIndex = -1; 60 }, 61 62 resize: function() 63 { 64 if (this._sourceFrameSetup) 65 this.sourceFrame.resize(); 59 66 }, 60 67 … … 77 84 78 85 delete this._frameNeedsSetup; 79 this.sourceFrame.addEventListener("content loaded", this._contentLoaded, this); 80 InspectorFrontendHost.addResourceSourceToFrame(this.resource.identifier, this.sourceFrame.element); 86 WebInspector.getResourceContent(this.resource.identifier, this._contentLoaded.bind(this)); 81 87 }, 82 88 83 _contentLoaded: function() 84 { 85 delete this._frameNeedsSetup; 86 this.sourceFrame.removeEventListener("content loaded", this._contentLoaded, this); 87 88 if (this.resource.type === WebInspector.Resource.Type.Script 89 || this.resource.mimeType === "application/json" 90 || this.resource.mimeType === "application/javascript" 91 || /\.js(on)?$/.test(this.resource.lastPathComponent) ) { 92 this.sourceFrame.addEventListener("syntax highlighting complete", this._syntaxHighlightingComplete, this); 93 this.sourceFrame.syntaxHighlightJavascript(); 94 } else if (this.resource.type === WebInspector.Resource.Type.Stylesheet 95 || this.resource.mimeType === "text/css" 96 || /\.css$/.test(this.resource.lastPathComponent) ) { 97 this.sourceFrame.addEventListener("syntax highlighting complete", this._syntaxHighlightingComplete, this); 98 this.sourceFrame.syntaxHighlightCSS(); 99 } else 100 this._sourceFrameSetupFinished(); 89 _contentLoaded: function(content) 90 { 91 this.sourceFrame.setContent(this.resource.mimeType, content); 92 this._sourceFrameSetupFinished(); 101 93 }, 102 94 … … 136 128 this._currentSearchResultIndex = -1; 137 129 this._searchResults = []; 130 this.sourceFrame.clearSelection(); 138 131 delete this._delayedFindSearchMatches; 139 132 }, … … 144 137 this.searchCanceled(); 145 138 146 var lineQueryRegex = /(^|\s)(?:#|line:\s*)(\d+)(\s|$)/i;147 var lineQueryMatch = query.match(lineQueryRegex);148 if (lineQueryMatch) {149 var lineToSearch = parseInt(lineQueryMatch[2]);150 151 // If there was a space before and after the line query part, replace with a space.152 // Otherwise replace with an empty string to eat the prefix or postfix space.153 var lineQueryReplacement = (lineQueryMatch[1] && lineQueryMatch[3] ? " " : "");154 var filterlessQuery = query.replace(lineQueryRegex, lineQueryReplacement);155 }156 157 139 this._searchFinishedCallback = finishedCallback; 158 140 159 141 function findSearchMatches(query, finishedCallback) 160 142 { 161 if (isNaN(lineToSearch)) { 162 // Search the whole document since there was no line to search. 163 this._searchResults = (InspectorFrontendHost.search(this.sourceFrame.element.contentDocument, query) || []); 164 } else { 165 var sourceRow = this.sourceFrame.sourceRow(lineToSearch); 166 if (sourceRow) { 167 if (filterlessQuery) { 168 // There is still a query string, so search for that string in the line. 169 this._searchResults = (InspectorFrontendHost.search(sourceRow, filterlessQuery) || []); 170 } else { 171 // Match the whole line, since there was no remaining query string to match. 172 var rowRange = this.sourceFrame.element.contentDocument.createRange(); 173 rowRange.selectNodeContents(sourceRow); 174 this._searchResults = [rowRange]; 175 } 176 } 177 178 // Attempt to search for the whole query, just incase it matches a color like "#333". 179 var wholeQueryMatches = InspectorFrontendHost.search(this.sourceFrame.element.contentDocument, query); 180 if (wholeQueryMatches) 181 this._searchResults = this._searchResults.concat(wholeQueryMatches); 182 } 183 143 this._searchResults = this.sourceFrame.findSearchMatches(query); 184 144 if (this._searchResults) 185 145 finishedCallback(this, this._searchResults.length); … … 268 228 return; 269 229 270 var selection = this.sourceFrame.element.contentWindow.getSelection(); 271 selection.removeAllRanges(); 272 selection.addRange(foundRange); 273 274 if (foundRange.startContainer.scrollIntoViewIfNeeded) 275 foundRange.startContainer.scrollIntoViewIfNeeded(true); 276 else if (foundRange.startContainer.parentNode) 277 foundRange.startContainer.parentNode.scrollIntoViewIfNeeded(true); 230 this.sourceFrame.setSelection(foundRange); 278 231 }, 279 232 … … 281 234 { 282 235 this._sourceFrameSetup = true; 236 this.resize(); 283 237 if (this._delayedFindSearchMatches) { 284 238 this._delayedFindSearchMatches(); 285 239 delete this._delayedFindSearchMatches; 286 240 } 287 },288 289 _syntaxHighlightingComplete: function(event)290 {291 this._sourceFrameSetupFinished();292 this.sourceFrame.removeEventListener("syntax highlighting complete", null, this);293 241 } 294 242 } -
trunk/WebCore/inspector/front-end/TextEditor.js
r53856 r53941 50 50 this._container.appendChild(this._sheet); 51 51 52 this._clipboard = document.createElement("textarea");53 this._clipboard.className = "text-editor-clip";54 this._container.appendChild(this._clipboard);55 56 52 var cursorElement = document.createElement("div"); 57 53 cursorElement.className = "text-editor-cursor"; … … 139 135 { 140 136 this._lineDecorator = lineDecorator; 137 }, 138 139 get selection() 140 { 141 return this._selection.range(); 141 142 }, 142 143 … … 515 516 // Hide div-based cursor first. 516 517 this._cursor._cursorElement.style.display = "none"; 517 setTimeout(this._repaintOnScroll.bind(this), 0);518 setTimeout(this._repaintOnScroll.bind(this), 10); 518 519 }, 519 520 … … 534 535 _mouseDown: function(e) 535 536 { 537 if (e.button === 2 || (this._isMac && e.ctrlKey)) 538 return; 539 536 540 var location = this._caretForMouseEvent(e); 537 541 … … 575 579 if (this._lineNumberDecorator.contextMenu(location.line, e)) 576 580 return; 581 } else { 582 var range = this._selection.range(); 583 if (!range.isEmpty()) { 584 var text = this._textModel.copyRange(range); 585 var contextMenu = new WebInspector.ContextMenu(); 586 contextMenu.appendItem(WebInspector.UIString("Copy"), this._copy.bind(this)); 587 contextMenu.show(event); 588 } 577 589 } 578 590 }, … … 582 594 var lineNumber = Math.max(0, this._offsetToLine(e.offsetY) - 1); 583 595 var line = this._textModel.line(lineNumber); 584 var offset = e.offsetX + this._scrollLeft - this._lineNumberWidth - this._digitWidth;596 var offset = e.offsetX + this._scrollLeft - this._lineNumberWidth; 585 597 return { line: lineNumber, column: this._columnForOffset(lineNumber, offset) }; 586 598 }, … … 590 602 var length = 0; 591 603 var line = this._textModel.line(lineNumber); 592 for (var column = 0; column < line.length; ++column) { 593 if (length > offset) 594 break; 595 length += this._ctx.measureText(line.charAt(column)).width; 596 } 597 return column; 604 605 // First pretend it is monospace to get a quick guess. 606 var charWidth = this._ctx.measureText("a").width; 607 var index = Math.floor(offset / charWidth); 608 var indexOffset = this._ctx.measureText(line.substring(0, index)).width; 609 if (offset >= indexOffset && index < line.length && offset < indexOffset + this._ctx.measureText(line.charAt(index)).width) 610 return index; 611 612 // Fallback to non-monospace. 613 var delta = indexOffset < offset ? 1 : -1; 614 while (index >=0 && index < line.length) { 615 index += delta; 616 indexOffset += delta * this._ctx.measureText(line.charAt(index)).width; 617 if (offset >= indexOffset && offset < indexOffset + charWidth) 618 return index; 619 } 620 return line.length; 598 621 }, 599 622 … … 848 871 var text = this._textModel.copyRange(range); 849 872 850 this._clipboard.value = text; 851 this._clipboard.select(); 873 function delayCopy() 874 { 875 InspectorFrontendHost.copyText(text); 876 } 877 878 setTimeout(delayCopy); 879 if (e) 880 e.preventDefault(); 852 881 }, 853 882 … … 860 889 _cut: function(e) 861 890 { 891 if (this._readOnly) { 892 e.preventDefault(); 893 return; 894 } 895 862 896 this._textModel.markUndoableState(); 863 897 this._copy(e); -
trunk/WebCore/inspector/front-end/WebKit.qrc
r53846 r53941 65 65 <file>SourceCSSTokenizer.js</file> 66 66 <file>SourceFrame.js</file> 67 <file>SourceFrame2.js</file>68 67 <file>SourceHTMLTokenizer.js</file> 69 68 <file>SourceJavaScriptTokenizer.js</file> -
trunk/WebCore/inspector/front-end/inspector.html
r53846 r53941 94 94 <script type="text/javascript" src="ResourceView.js"></script> 95 95 <script type="text/javascript" src="SourceFrame.js"></script> 96 <script type="text/javascript" src="SourceFrame2.js"></script>97 96 <script type="text/javascript" src="SourceSyntaxHighlighter.js"></script> 98 97 <script type="text/javascript" src="CSSSourceSyntaxHighlighter.js"></script> -
trunk/WebCore/inspector/front-end/textEditor.css
r53856 r53941 30 30 bottom:0; 31 31 overflow: auto; 32 }33 34 .text-editor-clip {35 opacity: 0;36 position: absolute;37 top:0;38 left:0;39 pointer-events: none;40 32 } 41 33
Note: See TracChangeset
for help on using the changeset viewer.