| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2011 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 */ | 37 */ |
| 38 constructor(uiSourceCode) { | 38 constructor(uiSourceCode) { |
| 39 super(uiSourceCode); | 39 super(uiSourceCode); |
| 40 this._debuggerSourceCode = uiSourceCode; | 40 this._debuggerSourceCode = uiSourceCode; |
| 41 | 41 |
| 42 this._scriptsPanel = Sources.SourcesPanel.instance(); | 42 this._scriptsPanel = Sources.SourcesPanel.instance(); |
| 43 this._breakpointManager = Bindings.breakpointManager; | 43 this._breakpointManager = Bindings.breakpointManager; |
| 44 if (uiSourceCode.project().type() === Workspace.projectTypes.Debugger) | 44 if (uiSourceCode.project().type() === Workspace.projectTypes.Debugger) |
| 45 this.element.classList.add('source-frame-debugger-script'); | 45 this.element.classList.add('source-frame-debugger-script'); |
| 46 | 46 |
| 47 this._popoverHelper = new UI.PopoverHelper(this._scriptsPanel.element, true)
; | 47 this._popoverHelper = new UI.PopoverHelper(this._scriptsPanel.element, true,
this._getPopoverContent.bind(this)); |
| 48 this._popoverHelper.initializeCallbacks( | |
| 49 this._getPopoverAnchor.bind(this), this._showObjectPopover.bind(this), t
his._onHidePopover.bind(this)); | |
| 50 this._popoverHelper.setTimeout(250, 250); | 48 this._popoverHelper.setTimeout(250, 250); |
| 51 this._popoverHelper.setHasPadding(true); | 49 this._popoverHelper.setHasPadding(true); |
| 52 this._scriptsPanel.element.addEventListener( | 50 this._scriptsPanel.element.addEventListener( |
| 53 'scroll', this._popoverHelper.hidePopover.bind(this._popoverHelper), tru
e); | 51 'scroll', this._popoverHelper.hidePopover.bind(this._popoverHelper), tru
e); |
| 54 | 52 |
| 55 this.textEditor.element.addEventListener('keydown', this._onKeyDown.bind(thi
s), true); | 53 this.textEditor.element.addEventListener('keydown', this._onKeyDown.bind(thi
s), true); |
| 56 | 54 |
| 57 this.textEditor.addEventListener( | 55 this.textEditor.addEventListener( |
| 58 SourceFrame.SourcesTextEditor.Events.GutterClick, this._handleGutterClic
k.bind(this), this); | 56 SourceFrame.SourcesTextEditor.Events.GutterClick, this._handleGutterClic
k.bind(this), this); |
| 59 | 57 |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 369 } | 367 } |
| 370 | 368 |
| 371 /** | 369 /** |
| 372 * @param {string} tokenType | 370 * @param {string} tokenType |
| 373 * @return {boolean} | 371 * @return {boolean} |
| 374 */ | 372 */ |
| 375 _isIdentifier(tokenType) { | 373 _isIdentifier(tokenType) { |
| 376 return tokenType.startsWith('js-variable') || tokenType.startsWith('js-prope
rty') || tokenType === 'js-def'; | 374 return tokenType.startsWith('js-variable') || tokenType.startsWith('js-prope
rty') || tokenType === 'js-def'; |
| 377 } | 375 } |
| 378 | 376 |
| 379 _getPopoverAnchor(element, event) { | 377 /** |
| 378 * @param {!Event} event |
| 379 * @return {?UI.PopoverContent} |
| 380 */ |
| 381 _getPopoverContent(event) { |
| 380 var target = UI.context.flavor(SDK.Target); | 382 var target = UI.context.flavor(SDK.Target); |
| 381 var debuggerModel = SDK.DebuggerModel.fromTarget(target); | 383 var debuggerModel = SDK.DebuggerModel.fromTarget(target); |
| 382 if (!debuggerModel || !debuggerModel.isPaused()) | 384 if (!debuggerModel || !debuggerModel.isPaused()) |
| 383 return; | 385 return null; |
| 384 | 386 |
| 385 var textPosition = this.textEditor.coordinatesToCursorPosition(event.x, even
t.y); | 387 var textPosition = this.textEditor.coordinatesToCursorPosition(event.x, even
t.y); |
| 386 if (!textPosition) | 388 if (!textPosition) |
| 387 return; | 389 return null; |
| 390 |
| 388 var mouseLine = textPosition.startLine; | 391 var mouseLine = textPosition.startLine; |
| 389 var mouseColumn = textPosition.startColumn; | 392 var mouseColumn = textPosition.startColumn; |
| 390 var textSelection = this.textEditor.selection().normalize(); | 393 var textSelection = this.textEditor.selection().normalize(); |
| 394 var anchorBox; |
| 395 var lineNumber; |
| 396 var startHighlight; |
| 397 var endHighlight; |
| 398 |
| 391 if (textSelection && !textSelection.isEmpty()) { | 399 if (textSelection && !textSelection.isEmpty()) { |
| 392 if (textSelection.startLine !== textSelection.endLine || textSelection.sta
rtLine !== mouseLine || | 400 if (textSelection.startLine !== textSelection.endLine || textSelection.sta
rtLine !== mouseLine || |
| 393 mouseColumn < textSelection.startColumn || mouseColumn > textSelection
.endColumn) | 401 mouseColumn < textSelection.startColumn || mouseColumn > textSelection
.endColumn) |
| 394 return; | 402 return null; |
| 395 | 403 |
| 396 var leftCorner = this.textEditor.cursorPositionToCoordinates(textSelection
.startLine, textSelection.startColumn); | 404 var leftCorner = this.textEditor.cursorPositionToCoordinates(textSelection
.startLine, textSelection.startColumn); |
| 397 var rightCorner = this.textEditor.cursorPositionToCoordinates(textSelectio
n.endLine, textSelection.endColumn); | 405 var rightCorner = this.textEditor.cursorPositionToCoordinates(textSelectio
n.endLine, textSelection.endColumn); |
| 398 var anchorBox = new AnchorBox(leftCorner.x, leftCorner.y, rightCorner.x -
leftCorner.x, leftCorner.height); | 406 anchorBox = new AnchorBox(leftCorner.x, leftCorner.y, rightCorner.x - left
Corner.x, leftCorner.height); |
| 399 anchorBox.highlight = { | 407 lineNumber = textSelection.startLine; |
| 400 lineNumber: textSelection.startLine, | 408 startHighlight = textSelection.startColumn; |
| 401 startColumn: textSelection.startColumn, | 409 endHighlight = textSelection.endColumn - 1; |
| 402 endColumn: textSelection.endColumn - 1 | 410 } else { |
| 403 }; | 411 var token = this.textEditor.tokenAtTextPosition(textPosition.startLine, te
xtPosition.startColumn); |
| 404 anchorBox.forSelection = true; | 412 if (!token || !token.type) |
| 405 return anchorBox; | 413 return null; |
| 414 lineNumber = textPosition.startLine; |
| 415 var line = this.textEditor.line(lineNumber); |
| 416 var tokenContent = line.substring(token.startColumn, token.endColumn); |
| 417 |
| 418 var isIdentifier = this._isIdentifier(token.type); |
| 419 if (!isIdentifier && (token.type !== 'js-keyword' || tokenContent !== 'thi
s')) |
| 420 return null; |
| 421 |
| 422 var leftCorner = this.textEditor.cursorPositionToCoordinates(lineNumber, t
oken.startColumn); |
| 423 var rightCorner = this.textEditor.cursorPositionToCoordinates(lineNumber,
token.endColumn - 1); |
| 424 anchorBox = new AnchorBox(leftCorner.x, leftCorner.y, rightCorner.x - left
Corner.x, leftCorner.height); |
| 425 |
| 426 startHighlight = token.startColumn; |
| 427 endHighlight = token.endColumn - 1; |
| 428 while (startHighlight > 1 && line.charAt(startHighlight - 1) === '.') { |
| 429 var tokenBefore = this.textEditor.tokenAtTextPosition(lineNumber, startH
ighlight - 2); |
| 430 if (!tokenBefore || !tokenBefore.type) |
| 431 return null; |
| 432 startHighlight = tokenBefore.startColumn; |
| 433 } |
| 406 } | 434 } |
| 407 | 435 |
| 408 var token = this.textEditor.tokenAtTextPosition(textPosition.startLine, text
Position.startColumn); | 436 var objectPopoverHelper; |
| 409 if (!token || !token.type) | 437 var highlightDescriptor; |
| 410 return; | |
| 411 var lineNumber = textPosition.startLine; | |
| 412 var line = this.textEditor.line(lineNumber); | |
| 413 var tokenContent = line.substring(token.startColumn, token.endColumn); | |
| 414 | 438 |
| 415 var isIdentifier = this._isIdentifier(token.type); | 439 return { |
| 416 if (!isIdentifier && (token.type !== 'js-keyword' || tokenContent !== 'this'
)) | 440 box: anchorBox, |
| 417 return; | 441 show: popover => { |
| 442 var selectedCallFrame = UI.context.flavor(SDK.DebuggerModel.CallFrame); |
| 443 if (!selectedCallFrame) |
| 444 return Promise.resolve(false); |
| 418 | 445 |
| 419 var leftCorner = this.textEditor.cursorPositionToCoordinates(lineNumber, tok
en.startColumn); | 446 var evaluationText = this.textEditor.line(lineNumber).substring(startHig
hlight, endHighlight + 1); |
| 420 var rightCorner = this.textEditor.cursorPositionToCoordinates(lineNumber, to
ken.endColumn - 1); | 447 return Sources.SourceMapNamesResolver |
| 421 var anchorBox = new AnchorBox(leftCorner.x, leftCorner.y, rightCorner.x - le
ftCorner.x, leftCorner.height); | 448 .resolveExpression( |
| 422 | 449 selectedCallFrame, evaluationText, this._debuggerSourceCode, lin
eNumber, startHighlight, endHighlight) |
| 423 anchorBox.highlight = {lineNumber: lineNumber, startColumn: token.startColum
n, endColumn: token.endColumn - 1}; | 450 .then(text => { |
| 424 | 451 var fulfill; |
| 425 return anchorBox; | 452 var promise = new Promise(x => fulfill = x); |
| 426 } | 453 selectedCallFrame.evaluate( |
| 427 | 454 text || evaluationText, 'popover', false, true, false, false, |
| 428 /** | 455 (result, exceptionDetails) => |
| 429 * @param {!AnchorBox} anchorBox | 456 fulfill(!result || exceptionDetails ? null : target.runtim
eModel.createRemoteObject(result))); |
| 430 * @return {!Promise<?SDK.RemoteObject>} | 457 return promise; |
| 431 */ | 458 }) |
| 432 _resolveObjectForPopover(anchorBox) { | 459 .then(remoteObject => { |
| 433 var selectedCallFrame = UI.context.flavor(SDK.DebuggerModel.CallFrame); | 460 if (!remoteObject) |
| 434 if (!selectedCallFrame) | 461 return false; |
| 435 return Promise.resolve(/** @type {?SDK.RemoteObject} */ (null)); | 462 return ObjectUI.ObjectPopoverHelper.buildObjectPopover(remoteObjec
t, popover).then(helper => { |
| 436 var lineNumber = anchorBox.highlight.lineNumber; | 463 var potentiallyUpdatedCallFrame = UI.context.flavor(SDK.Debugger
Model.CallFrame); |
| 437 var startHighlight = anchorBox.highlight.startColumn; | 464 if (!helper || selectedCallFrame !== potentiallyUpdatedCallFrame
) { |
| 438 var endHighlight = anchorBox.highlight.endColumn; | 465 target.runtimeModel.releaseObjectGroup('popover'); |
| 439 var line = this.textEditor.line(lineNumber); | 466 return false; |
| 440 if (!anchorBox.forSelection) { | 467 } |
| 441 while (startHighlight > 1 && line.charAt(startHighlight - 1) === '.') { | 468 var highlightRange = new Common.TextRange(lineNumber, startHighl
ight, lineNumber, endHighlight); |
| 442 var token = this.textEditor.tokenAtTextPosition(lineNumber, startHighlig
ht - 2); | 469 highlightDescriptor = this.textEditor.highlightRange(highlightRa
nge, 'source-frame-eval-expression'); |
| 443 if (!token || !token.type) | 470 objectPopoverHelper = helper; |
| 444 return Promise.resolve(/** @type {?SDK.RemoteObject} */ (null)); | 471 return true; |
| 445 startHighlight = token.startColumn; | 472 }); |
| 473 }); |
| 474 }, |
| 475 hide: () => { |
| 476 objectPopoverHelper.dispose(); |
| 477 target.runtimeModel.releaseObjectGroup('popover'); |
| 478 this.textEditor.removeHighlight(highlightDescriptor); |
| 446 } | 479 } |
| 447 } | 480 }; |
| 448 var evaluationText = line.substring(startHighlight, endHighlight + 1); | |
| 449 return Sources.SourceMapNamesResolver | |
| 450 .resolveExpression( | |
| 451 selectedCallFrame, evaluationText, this._debuggerSourceCode, lineNum
ber, startHighlight, endHighlight) | |
| 452 .then(onResolve.bind(this)); | |
| 453 | |
| 454 /** | |
| 455 * @param {?string=} text | |
| 456 * @return {!Promise<?SDK.RemoteObject>} | |
| 457 * @this {Sources.JavaScriptSourceFrame} | |
| 458 */ | |
| 459 function onResolve(text) { | |
| 460 var fulfill; | |
| 461 var promise = new Promise(x => fulfill = x); | |
| 462 selectedCallFrame.evaluate( | |
| 463 text || evaluationText, 'popover', false, true, false, false, showObje
ctPopover.bind(this, fulfill)); | |
| 464 return promise; | |
| 465 } | |
| 466 | |
| 467 /** | |
| 468 * @param {function(?SDK.RemoteObject)} fulfill | |
| 469 * @param {?Protocol.Runtime.RemoteObject} result | |
| 470 * @param {!Protocol.Runtime.ExceptionDetails=} exceptionDetails | |
| 471 * @this {Sources.JavaScriptSourceFrame} | |
| 472 */ | |
| 473 function showObjectPopover(fulfill, result, exceptionDetails) { | |
| 474 var target = UI.context.flavor(SDK.Target); | |
| 475 var potentiallyUpdatedCallFrame = UI.context.flavor(SDK.DebuggerModel.Call
Frame); | |
| 476 if (selectedCallFrame !== potentiallyUpdatedCallFrame || !result || except
ionDetails) { | |
| 477 fulfill(null); | |
| 478 return; | |
| 479 } | |
| 480 this._popoverAnchorBox = anchorBox; | |
| 481 this._popoverTarget = target; | |
| 482 var highlightRange = new Common.TextRange(lineNumber, startHighlight, line
Number, endHighlight); | |
| 483 this._popoverAnchorBox._highlightDescriptor = | |
| 484 this.textEditor.highlightRange(highlightRange, 'source-frame-eval-expr
ession'); | |
| 485 fulfill(target.runtimeModel.createRemoteObject(result)); | |
| 486 } | |
| 487 } | |
| 488 | |
| 489 /** | |
| 490 * @param {!AnchorBox|!Element} anchorBox | |
| 491 * @param {!UI.GlassPane} popover | |
| 492 * @return {!Promise<boolean>} | |
| 493 */ | |
| 494 _showObjectPopover(anchorBox, popover) { | |
| 495 return this._resolveObjectForPopover(/** @type {!AnchorBox} */ (anchorBox)).
then(object => { | |
| 496 if (!object) | |
| 497 return false; | |
| 498 return ObjectUI.ObjectPopoverHelper.buildObjectPopover(object, popover).th
en(objectPopoverHelper => { | |
| 499 if (!objectPopoverHelper) { | |
| 500 this._onHidePopover(); // Cleanup artifacts from _resolveObjectForPop
over. | |
| 501 return false; | |
| 502 } | |
| 503 this._objectPopoverHelper = objectPopoverHelper; | |
| 504 return true; | |
| 505 }); | |
| 506 }); | |
| 507 } | |
| 508 | |
| 509 _onHidePopover() { | |
| 510 if (this._objectPopoverHelper) { | |
| 511 this._objectPopoverHelper.dispose(); | |
| 512 delete this._objectPopoverHelper; | |
| 513 } | |
| 514 if (this._popoverTarget) { | |
| 515 this._popoverTarget.runtimeModel.releaseObjectGroup('popover'); | |
| 516 delete this._popoverTarget; | |
| 517 } | |
| 518 if (this._popoverAnchorBox) { | |
| 519 if (this._popoverAnchorBox._highlightDescriptor) | |
| 520 this.textEditor.removeHighlight(this._popoverAnchorBox._highlightDescrip
tor); | |
| 521 delete this._popoverAnchorBox; | |
| 522 } | |
| 523 } | 481 } |
| 524 | 482 |
| 525 _onKeyDown(event) { | 483 _onKeyDown(event) { |
| 526 if (event.key === 'Escape') { | 484 if (event.key === 'Escape') { |
| 527 if (this._popoverHelper.isPopoverVisible()) { | 485 if (this._popoverHelper.isPopoverVisible()) { |
| 528 this._popoverHelper.hidePopover(); | 486 this._popoverHelper.hidePopover(); |
| 529 event.consume(); | 487 event.consume(); |
| 530 } | 488 } |
| 531 } | 489 } |
| 532 } | 490 } |
| (...skipping 971 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1504 return; | 1462 return; |
| 1505 this.bookmark.clear(); | 1463 this.bookmark.clear(); |
| 1506 this.bookmark = null; | 1464 this.bookmark = null; |
| 1507 } | 1465 } |
| 1508 }; | 1466 }; |
| 1509 | 1467 |
| 1510 Sources.JavaScriptSourceFrame.BreakpointDecoration.bookmarkSymbol = Symbol('book
mark'); | 1468 Sources.JavaScriptSourceFrame.BreakpointDecoration.bookmarkSymbol = Symbol('book
mark'); |
| 1511 Sources.JavaScriptSourceFrame.BreakpointDecoration._elementSymbolForTest = Symbo
l('element'); | 1469 Sources.JavaScriptSourceFrame.BreakpointDecoration._elementSymbolForTest = Symbo
l('element'); |
| 1512 | 1470 |
| 1513 Sources.JavaScriptSourceFrame.continueToLocationDecorationSymbol = Symbol('bookm
ark'); | 1471 Sources.JavaScriptSourceFrame.continueToLocationDecorationSymbol = Symbol('bookm
ark'); |
| OLD | NEW |