Changeset 147415 in webkit
- Timestamp:
- Apr 2, 2013 3:49:31 AM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r147414 r147415 1 2013-04-02 Andrey Lushnikov <lushnikov@chromium.org> 2 3 Web Inspector: Separate JavaScriptSourceFrame popover from knowledge of editor's DOM 4 https://bugs.webkit.org/show_bug.cgi?id=113412 5 6 Reviewed by Pavel Feldman. 7 8 - Use TextEditor.coordinatesToCursorPosition, 9 TextEditor.cursorPositionToCoordinates and TextEditor.tokenAtTextPosition to figure out 10 hovering area and create popover anchor. 11 - Use TextEditor.highlightRange/TextEditor.removeHighlight methods to 12 highlight hovering text in editor. 13 14 No new tests: no change in behaviour. 15 16 * inspector/front-end/DefaultTextEditor.js: 17 * inspector/front-end/JavaScriptSourceFrame.js: 18 (WebInspector.JavaScriptSourceFrame): 19 (WebInspector.JavaScriptSourceFrame.prototype.willHide): 20 (WebInspector.JavaScriptSourceFrame.prototype._getPopoverAnchor): 21 (WebInspector.JavaScriptSourceFrame.prototype.): 22 (WebInspector.JavaScriptSourceFrame.prototype._resolveObjectForPopover): 23 (WebInspector.JavaScriptSourceFrame.prototype._onHidePopover): 24 * inspector/front-end/inspector.css: 25 (.popover-anchor): 26 (.source-frame-eval-expression): 27 1 28 2013-04-02 Mihnea Ovidenie <mihnea@adobe.com> 2 29 -
trunk/Source/WebCore/inspector/front-end/DefaultTextEditor.js
r147322 r147415 641 641 642 642 /** 643 * @param {Element} element644 * @param {Object} skipClasses645 * @param {Object} skipTokens646 * @return {Element}647 */648 highlightExpression: function(element, skipClasses, skipTokens)649 {650 // Collect tokens belonging to evaluated expression.651 var tokens = [element];652 var token = element.previousSibling;653 while (token && (skipClasses[token.className] || skipTokens[token.textContent.trim()])) {654 tokens.push(token);655 token = token.previousSibling;656 }657 tokens.reverse();658 659 // Wrap them with highlight element.660 this._mainPanel.beginDomUpdates();661 var parentElement = element.parentElement;662 var nextElement = element.nextSibling;663 var container = document.createElement("span");664 for (var i = 0; i < tokens.length; ++i)665 container.appendChild(tokens[i]);666 parentElement.insertBefore(container, nextElement);667 this._mainPanel.endDomUpdates();668 return container;669 },670 671 /**672 * @param {Element} highlightElement673 */674 hideHighlightedExpression: function(highlightElement)675 {676 this._mainPanel.beginDomUpdates();677 var parentElement = highlightElement.parentElement;678 if (parentElement) {679 var child = highlightElement.firstChild;680 while (child) {681 var nextSibling = child.nextSibling;682 parentElement.insertBefore(child, highlightElement);683 child = nextSibling;684 }685 parentElement.removeChild(highlightElement);686 }687 this._mainPanel.endDomUpdates();688 },689 690 /**691 643 * @param {number} scrollTop 692 644 * @param {number} clientHeight -
trunk/Source/WebCore/inspector/front-end/JavaScriptSourceFrame.js
r147106 r147415 61 61 this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this); 62 62 this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this); 63 63 64 64 this._updateScriptFile(); 65 65 } … … 222 222 if (window.getSelection().type === "Range") 223 223 return null; 224 var lineElement = element.enclosingNodeOrSelfWithClass("webkit-line-content"); 225 if (!lineElement) 224 225 var textPosition = this.textEditor.coordinatesToCursorPosition(event.x, event.y); 226 if (!textPosition) 226 227 return null; 227 228 228 if (element.hasStyleClass("webkit-javascript-ident")) 229 return element; 230 231 if (element.hasStyleClass("source-frame-token")) 232 return element; 233 234 // We are interested in identifiers and "this" keyword. 235 if (element.hasStyleClass("webkit-javascript-keyword")) 236 return element.textContent === "this" ? element : null; 237 238 if (element !== lineElement || lineElement.childElementCount) 229 var token = this.textEditor.tokenAtTextPosition(textPosition.startLine, textPosition.startColumn); 230 if (!token) 239 231 return null; 240 241 // Handle non-highlighted case 242 // 1. Collect ranges of identifier suspects 243 var lineContent = lineElement.textContent; 244 var ranges = []; 245 var regex = new RegExp("[a-zA-Z_\$0-9]+", "g"); 246 var match; 247 while (regex.lastIndex < lineContent.length && (match = regex.exec(lineContent))) 248 ranges.push({offset: match.index, length: regex.lastIndex - match.index}); 249 250 // 2. 'highlight' them with artificial style to detect word boundaries 251 var changes = []; 252 this.textEditor.highlightRangesWithStyleClass(lineElement, ranges, "source-frame-token", changes); 253 var lineOffsetLeft = lineElement.totalOffsetLeft(); 254 for (var child = lineElement.firstChild; child; child = child.nextSibling) { 255 if (child.nodeType !== Node.ELEMENT_NODE || !child.hasStyleClass("source-frame-token")) 256 continue; 257 if (event.x > lineOffsetLeft + child.offsetLeft && event.x < lineOffsetLeft + child.offsetLeft + child.offsetWidth) { 258 var text = child.textContent; 259 return (text === "this" || !WebInspector.SourceJavaScriptTokenizer.Keywords[text]) ? child : null; 260 } 261 } 262 return null; 263 }, 264 265 _resolveObjectForPopover: function(element, showCallback, objectGroupName) 266 { 267 this._highlightElement = this._highlightExpression(element); 268 232 var lineNumber = textPosition.startLine; 233 var line = this.textEditor.line(lineNumber); 234 var tokenContent = line.substring(token.startColumn, token.endColumn + 1); 235 if (token.type !== "javascript-ident" && (token.type !== "javascript-keyword" || tokenContent !== "this")) 236 return null; 237 238 var leftCorner = this.textEditor.cursorPositionToCoordinates(lineNumber, token.startColumn); 239 var rightCorner = this.textEditor.cursorPositionToCoordinates(lineNumber, token.endColumn + 1); 240 var anchorBox = new AnchorBox(leftCorner.x, leftCorner.y, rightCorner.x - leftCorner.x, leftCorner.height); 241 242 anchorBox.token = token; 243 anchorBox.lineNumber = lineNumber; 244 245 return anchorBox; 246 }, 247 248 _resolveObjectForPopover: function(anchorBox, showCallback, objectGroupName) 249 { 269 250 /** 270 251 * @param {?RuntimeAgent.RemoteObject} result … … 277 258 return; 278 259 } 279 showCallback(WebInspector.RemoteObject.fromPayload(result), wasThrown, this._highlightElement); 260 this._popoverAnchorBox = anchorBox; 261 showCallback(WebInspector.RemoteObject.fromPayload(result), wasThrown, this._popoverAnchorBox); 280 262 // Popover may have been removed by showCallback(). 281 if (this._highlightElement) 282 this._highlightElement.addStyleClass("source-frame-eval-expression"); 263 if (this._popoverAnchorBox) { 264 var highlightRange = new WebInspector.TextRange(anchorBox.lineNumber, startHighlight, anchorBox.lineNumber, endHighlight); 265 this._popoverAnchorBox._highlightDescriptor = this.textEditor.highlightRange(highlightRange, "source-frame-eval-expression"); 266 } 283 267 } 284 268 … … 287 271 return; 288 272 } 273 274 var startHighlight = anchorBox.token.startColumn; 275 var endHighlight = anchorBox.token.endColumn; 276 var line = this.textEditor.line(anchorBox.lineNumber); 277 while (startHighlight > 1 && line.charAt(startHighlight - 1) === '.') 278 startHighlight = this.textEditor.tokenAtTextPosition(anchorBox.lineNumber, startHighlight - 2).startColumn; 279 var evaluationText = line.substring(startHighlight, endHighlight + 1); 280 289 281 var selectedCallFrame = WebInspector.debuggerModel.selectedCallFrame(); 290 selectedCallFrame.evaluate( this._highlightElement.textContent, objectGroupName, false, true, false, false, showObjectPopover.bind(this));282 selectedCallFrame.evaluate(evaluationText, objectGroupName, false, true, false, false, showObjectPopover.bind(this)); 291 283 }, 292 284 293 285 _onHidePopover: function() 294 286 { 295 // Replace higlight element with its contents inplace. 296 var highlightElement = this._highlightElement; 297 if (!highlightElement) 298 return; 299 // FIXME: the text editor should maintain highlight on its own. The check below is a workaround for 300 // the case when highlight element is detached from DOM by the TextEditor when re-building the DOM. 301 this.textEditor.hideHighlightedExpression(highlightElement); 302 delete this._highlightElement; 303 }, 304 305 /** 306 * @param {Element} element 307 * @return {Element} 308 */ 309 _highlightExpression: function(element) 310 { 311 return this.textEditor.highlightExpression(element, { "webkit-javascript-ident": true, "source-frame-token": true, "webkit-javascript-keyword": true }, { ".": true }); 287 if (!this._popoverAnchorBox) 288 return; 289 if (this._popoverAnchorBox._highlightDescriptor) 290 this.textEditor.removeHighlight(this._popoverAnchorBox._highlightDescriptor); 291 delete this._popoverAnchorBox; 312 292 }, 313 293 -
trunk/Source/WebCore/inspector/front-end/inspector.css
r147275 r147415 2330 2330 2331 2331 .source-frame-eval-expression { 2332 border: 1px solid rgb(163, 41, 34); 2333 margin: -1px; 2332 outline: 1px solid rgb(163, 41, 34); 2334 2333 background-color: rgb(255, 255, 194); 2335 2334 }
Note: See TracChangeset
for help on using the changeset viewer.