Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js

Issue 2747553002: [DevTools] Rework Popover API (Closed)
Patch Set: await Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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: async popover => {
418 442 var selectedCallFrame = UI.context.flavor(SDK.DebuggerModel.CallFrame);
419 var leftCorner = this.textEditor.cursorPositionToCoordinates(lineNumber, tok en.startColumn); 443 if (!selectedCallFrame)
420 var rightCorner = this.textEditor.cursorPositionToCoordinates(lineNumber, to ken.endColumn - 1); 444 return false;
421 var anchorBox = new AnchorBox(leftCorner.x, leftCorner.y, rightCorner.x - le ftCorner.x, leftCorner.height); 445 var evaluationText = this.textEditor.line(lineNumber).substring(startHig hlight, endHighlight + 1);
422 446 var resolvedText = await Sources.SourceMapNamesResolver.resolveExpressio n(
423 anchorBox.highlight = {lineNumber: lineNumber, startColumn: token.startColum n, endColumn: token.endColumn - 1}; 447 selectedCallFrame, evaluationText, this._debuggerSourceCode, lineNum ber, startHighlight, endHighlight);
424 448 var remoteObject = await selectedCallFrame.evaluatePromise(
425 return anchorBox; 449 resolvedText || evaluationText, 'popover', false, true, false, false );
426 } 450 if (!remoteObject)
427 451 return false;
428 /** 452 objectPopoverHelper = await ObjectUI.ObjectPopoverHelper.buildObjectPopo ver(remoteObject, popover);
429 * @param {!AnchorBox} anchorBox 453 var potentiallyUpdatedCallFrame = UI.context.flavor(SDK.DebuggerModel.Ca llFrame);
430 * @return {!Promise<?SDK.RemoteObject>} 454 if (!objectPopoverHelper || selectedCallFrame !== potentiallyUpdatedCall Frame) {
431 */ 455 target.runtimeModel.releaseObjectGroup('popover');
lushnikov 2017/03/14 01:44:04 objectPopoverHelper.dispose();
dgozman 2017/03/14 21:34:01 Done.
432 _resolveObjectForPopover(anchorBox) {
433 var selectedCallFrame = UI.context.flavor(SDK.DebuggerModel.CallFrame);
434 if (!selectedCallFrame)
435 return Promise.resolve(/** @type {?SDK.RemoteObject} */ (null));
436 var lineNumber = anchorBox.highlight.lineNumber;
437 var startHighlight = anchorBox.highlight.startColumn;
438 var endHighlight = anchorBox.highlight.endColumn;
439 var line = this.textEditor.line(lineNumber);
440 if (!anchorBox.forSelection) {
441 while (startHighlight > 1 && line.charAt(startHighlight - 1) === '.') {
442 var token = this.textEditor.tokenAtTextPosition(lineNumber, startHighlig ht - 2);
443 if (!token || !token.type)
444 return Promise.resolve(/** @type {?SDK.RemoteObject} */ (null));
445 startHighlight = token.startColumn;
446 }
447 }
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; 456 return false;
502 } 457 }
503 this._objectPopoverHelper = objectPopoverHelper; 458 var highlightRange = new Common.TextRange(lineNumber, startHighlight, li neNumber, endHighlight);
459 highlightDescriptor = this.textEditor.highlightRange(highlightRange, 'so urce-frame-eval-expression');
504 return true; 460 return true;
505 }); 461 },
506 }); 462 hide: () => {
507 } 463 objectPopoverHelper.dispose();
508 464 target.runtimeModel.releaseObjectGroup('popover');
509 _onHidePopover() { 465 this.textEditor.removeHighlight(highlightDescriptor);
510 if (this._objectPopoverHelper) { 466 }
511 this._objectPopoverHelper.dispose(); 467 };
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 } 468 }
524 469
525 _onKeyDown(event) { 470 _onKeyDown(event) {
526 if (event.key === 'Escape') { 471 if (event.key === 'Escape') {
527 if (this._popoverHelper.isPopoverVisible()) { 472 if (this._popoverHelper.isPopoverVisible()) {
528 this._popoverHelper.hidePopover(); 473 this._popoverHelper.hidePopover();
529 event.consume(); 474 event.consume();
530 } 475 }
531 } 476 }
532 } 477 }
(...skipping 971 matching lines...) Expand 10 before | Expand all | Expand 10 after
1504 return; 1449 return;
1505 this.bookmark.clear(); 1450 this.bookmark.clear();
1506 this.bookmark = null; 1451 this.bookmark = null;
1507 } 1452 }
1508 }; 1453 };
1509 1454
1510 Sources.JavaScriptSourceFrame.BreakpointDecoration.bookmarkSymbol = Symbol('book mark'); 1455 Sources.JavaScriptSourceFrame.BreakpointDecoration.bookmarkSymbol = Symbol('book mark');
1511 Sources.JavaScriptSourceFrame.BreakpointDecoration._elementSymbolForTest = Symbo l('element'); 1456 Sources.JavaScriptSourceFrame.BreakpointDecoration._elementSymbolForTest = Symbo l('element');
1512 1457
1513 Sources.JavaScriptSourceFrame.continueToLocationDecorationSymbol = Symbol('bookm ark'); 1458 Sources.JavaScriptSourceFrame.continueToLocationDecorationSymbol = Symbol('bookm ark');
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698