Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 70 } | 70 } |
| 71 | 71 |
| 72 _updateAllAnchorDecorations() { | 72 _updateAllAnchorDecorations() { |
| 73 for (var anchors of this._anchorsByTarget.values()) { | 73 for (var anchors of this._anchorsByTarget.values()) { |
| 74 for (var anchor of anchors) | 74 for (var anchor of anchors) |
| 75 Components.Linkifier._updateLinkDecorations(anchor); | 75 Components.Linkifier._updateLinkDecorations(anchor); |
| 76 } | 76 } |
| 77 } | 77 } |
| 78 | 78 |
| 79 /** | 79 /** |
| 80 * @param {?Components.Linkifier.LinkHandler} handler | |
| 81 */ | |
| 82 static setLinkHandler(handler) { | |
| 83 Components.Linkifier._linkHandler = handler; | |
| 84 } | |
| 85 | |
| 86 /** | |
| 87 * @param {string} url | |
| 88 * @param {number=} lineNumber | |
| 89 * @return {boolean} | |
| 90 */ | |
| 91 static handleLink(url, lineNumber) { | |
| 92 if (!Components.Linkifier._linkHandler) | |
| 93 return false; | |
| 94 return Components.Linkifier._linkHandler.handleLink(url, lineNumber); | |
| 95 } | |
| 96 | |
| 97 /** | |
| 98 * @param {!Element} anchor | 80 * @param {!Element} anchor |
| 99 * @param {!Workspace.UILocation} uiLocation | 81 * @param {!Workspace.UILocation} uiLocation |
| 100 */ | 82 */ |
| 101 static _bindUILocation(anchor, uiLocation) { | 83 static _bindUILocation(anchor, uiLocation) { |
| 102 Components.Linkifier._linkInfo(anchor).uiLocation = uiLocation; | 84 Components.Linkifier._linkInfo(anchor).uiLocation = uiLocation; |
| 103 if (!uiLocation) | 85 if (!uiLocation) |
| 104 return; | 86 return; |
| 105 var uiSourceCode = uiLocation.uiSourceCode; | 87 var uiSourceCode = uiLocation.uiSourceCode; |
| 106 var sourceCodeAnchors = uiSourceCode[Components.Linkifier._sourceCodeAnchors ]; | 88 var sourceCodeAnchors = uiSourceCode[Components.Linkifier._sourceCodeAnchors ]; |
| 107 if (!sourceCodeAnchors) { | 89 if (!sourceCodeAnchors) { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 120 return; | 102 return; |
| 121 | 103 |
| 122 var uiSourceCode = info.uiLocation.uiSourceCode; | 104 var uiSourceCode = info.uiLocation.uiSourceCode; |
| 123 info.uiLocation = null; | 105 info.uiLocation = null; |
| 124 var sourceCodeAnchors = uiSourceCode[Components.Linkifier._sourceCodeAnchors ]; | 106 var sourceCodeAnchors = uiSourceCode[Components.Linkifier._sourceCodeAnchors ]; |
| 125 if (sourceCodeAnchors) | 107 if (sourceCodeAnchors) |
| 126 sourceCodeAnchors.delete(anchor); | 108 sourceCodeAnchors.delete(anchor); |
| 127 } | 109 } |
| 128 | 110 |
| 129 /** | 111 /** |
| 130 * @param {!SDK.Target} target | |
| 131 * @param {string} scriptId | |
| 132 * @param {number} lineNumber | |
| 133 * @param {number=} columnNumber | |
| 134 * @return {string} | |
| 135 */ | |
| 136 static liveLocationText(target, scriptId, lineNumber, columnNumber) { | |
| 137 var debuggerModel = SDK.DebuggerModel.fromTarget(target); | |
| 138 if (!debuggerModel) | |
| 139 return ''; | |
| 140 var script = debuggerModel.scriptForId(scriptId); | |
| 141 if (!script) | |
| 142 return ''; | |
| 143 var location = /** @type {!SDK.DebuggerModel.Location} */ ( | |
| 144 debuggerModel.createRawLocation(script, lineNumber, columnNumber || 0)); | |
| 145 var uiLocation = | |
| 146 /** @type {!Workspace.UILocation} */ (Bindings.debuggerWorkspaceBinding. rawLocationToUILocation(location)); | |
| 147 return uiLocation.linkText(); | |
| 148 } | |
| 149 | |
| 150 /** | |
| 151 * @override | 112 * @override |
| 152 * @param {!SDK.Target} target | 113 * @param {!SDK.Target} target |
| 153 */ | 114 */ |
| 154 targetAdded(target) { | 115 targetAdded(target) { |
| 155 this._anchorsByTarget.set(target, []); | 116 this._anchorsByTarget.set(target, []); |
| 156 this._locationPoolByTarget.set(target, new Bindings.LiveLocationPool()); | 117 this._locationPoolByTarget.set(target, new Bindings.LiveLocationPool()); |
| 157 } | 118 } |
| 158 | 119 |
| 159 /** | 120 /** |
| 160 * @override | 121 * @override |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 459 | 420 |
| 460 /** | 421 /** |
| 461 * @param {!Event} event | 422 * @param {!Event} event |
| 462 */ | 423 */ |
| 463 static _handleClick(event) { | 424 static _handleClick(event) { |
| 464 var link = /** @type {!Element} */ (event.currentTarget); | 425 var link = /** @type {!Element} */ (event.currentTarget); |
| 465 event.consume(true); | 426 event.consume(true); |
| 466 if (link.preventFollow || UI.isBeingEdited(/** @type {!Node} */ (event.targe t))) | 427 if (link.preventFollow || UI.isBeingEdited(/** @type {!Node} */ (event.targe t))) |
| 467 return; | 428 return; |
| 468 var info = Components.Linkifier._linkInfo(link); | 429 var info = Components.Linkifier._linkInfo(link); |
| 469 if (info.uiLocation && | |
| 470 Components.openAnchorLocationRegistry.dispatch( | |
| 471 {url: info.uiLocation.uiSourceCode.url(), lineNumber: info.uiLocatio n.lineNumber})) | |
| 472 return; | |
| 473 if (info.url && Components.openAnchorLocationRegistry.dispatch({url: info.ur l, lineNumber: info.lineNumber})) | |
| 474 return; | |
| 475 if (info.revealable) { | 430 if (info.revealable) { |
|
lushnikov
2016/11/21 20:51:09
this changes the order: revealable now prevails ov
dgozman
2016/11/21 23:34:50
Fixed.
| |
| 476 Common.Revealer.reveal(info.revealable); | 431 Common.Revealer.reveal(info.revealable); |
| 477 return; | 432 return; |
| 478 } | 433 } |
| 479 var actions = Components.Linkifier._linkActions(link); | 434 var actions = Components.Linkifier._linkActions(link); |
| 480 if (actions.length) | 435 if (actions.length) |
| 481 actions[0].handler.call(null); | 436 actions[0].handler.call(null); |
| 482 } | 437 } |
| 483 | 438 |
| 484 /** | 439 /** |
| 440 * @return {!Common.Setting} | |
| 441 */ | |
| 442 static _linkHandlerSetting() { | |
| 443 if (!Components.Linkifier._linkHandlerSettingInstance) { | |
| 444 Components.Linkifier._linkHandlerSettingInstance = | |
| 445 Common.settings.createSetting('openLinkHandler', Common.UIString('auto ')); | |
| 446 } | |
| 447 return Components.Linkifier._linkHandlerSettingInstance; | |
| 448 } | |
| 449 | |
| 450 /** | |
| 451 * @param {!{title: string, handler: !Components.Linkifier.LinkHandler}} entry | |
| 452 */ | |
| 453 static registerLinkHandler(entry) { | |
| 454 Components.Linkifier._linkHandlers.push(entry); | |
| 455 self.runtime.sharedInstance(Components.Linkifier.LinkHandlerSettingUI)._upda te(); | |
| 456 } | |
| 457 | |
| 458 /** | |
| 459 * @param {string} title | |
| 460 */ | |
| 461 static unregisterLinkHandler(title) { | |
| 462 Components.Linkifier._linkHandlers = Components.Linkifier._linkHandlers.filt er(entry => entry.title !== title); | |
|
caseq
2016/11/21 20:13:09
if we remove by title, this could as well be a map
dgozman
2016/11/21 23:34:50
Done.
| |
| 463 self.runtime.sharedInstance(Components.Linkifier.LinkHandlerSettingUI)._upda te(); | |
| 464 } | |
| 465 | |
| 466 /** | |
| 485 * @param {?Element} link | 467 * @param {?Element} link |
| 486 * @return {!Array<{title: string, handler: function()}>} | 468 * @return {!Array<{title: string, handler: function()}>} |
| 487 */ | 469 */ |
| 488 static _linkActions(link) { | 470 static _linkActions(link) { |
| 489 var info = Components.Linkifier._linkInfo(link); | 471 var info = Components.Linkifier._linkInfo(link); |
| 490 if (info && info.revealable) | 472 if (info && info.revealable) |
| 491 return []; | 473 return []; |
| 474 | |
| 492 var url = ''; | 475 var url = ''; |
| 493 var uiLocation = null; | 476 var uiLocation = null; |
| 477 var lineNumber = info.lineNumber || 0; | |
|
lushnikov
2016/11/21 20:51:09
let's inline this to the use-site
uiLocation ? uiL
dgozman
2016/11/21 23:34:50
Done.
| |
| 494 if (info && info.uiLocation) { | 478 if (info && info.uiLocation) { |
| 495 uiLocation = info.uiLocation; | 479 uiLocation = info.uiLocation; |
| 496 url = uiLocation.uiSourceCode.contentURL(); | 480 url = uiLocation.uiSourceCode.contentURL(); |
| 481 lineNumber = uiLocation.lineNumber; | |
| 497 } else if (info && info.url) { | 482 } else if (info && info.url) { |
| 498 url = info.url; | 483 url = info.url; |
| 499 var uiSourceCode = Workspace.workspace.uiSourceCodeForURL(url); | 484 var uiSourceCode = Workspace.workspace.uiSourceCodeForURL(url); |
| 500 uiLocation = uiSourceCode ? uiSourceCode.uiLocation(info.lineNumber || 0, info.columnNumber || 0) : null; | 485 uiLocation = uiSourceCode ? uiSourceCode.uiLocation(info.lineNumber || 0, info.columnNumber || 0) : null; |
| 501 } else { | 486 } else { |
| 502 return []; | 487 return []; |
| 503 } | 488 } |
| 504 | 489 |
| 505 var result = []; | 490 var result = []; |
| 506 if (uiLocation) | 491 var resource = Bindings.resourceForURL(url); |
| 507 result.push({title: Common.UIString('Open'), handler: () => Common.Reveale r.reveal(uiLocation)}); | 492 var request = SDK.NetworkLog.requestForURL(url); |
| 493 var contentProvider = uiLocation ? uiLocation.uiSourceCode : resource; | |
| 508 | 494 |
| 509 var resource = Bindings.resourceForURL(url); | 495 if (contentProvider) { |
|
lushnikov
2016/11/21 20:51:09
let's move this to the end.
dgozman
2016/11/21 23:34:50
Done.
| |
| 496 for (var entry of Components.Linkifier._linkHandlers) { | |
| 497 var action = { | |
| 498 title: Common.UIString.capitalize('Open using %s', entry.title), | |
| 499 handler: entry.handler.bind(null, contentProvider, lineNumber) | |
| 500 }; | |
| 501 if (entry.title === Components.Linkifier._linkHandlerSetting().get()) | |
| 502 result.unshift(action); | |
| 503 else | |
| 504 result.push(action); | |
| 505 } | |
| 506 } | |
| 507 if (uiLocation) { | |
| 508 result.push({ | |
| 509 title: Common.UIString.capitalize('Open in Sources ^panel'), | |
| 510 handler: () => Common.Revealer.reveal(uiLocation) | |
| 511 }); | |
| 512 } | |
| 510 if (resource) { | 513 if (resource) { |
| 511 result.push({ | 514 result.push({ |
| 512 title: Common.UIString.capitalize('Open ^link in Application ^panel'), | 515 title: Common.UIString.capitalize('Open in Application ^panel'), |
| 513 handler: () => Common.Revealer.reveal(resource) | 516 handler: () => Common.Revealer.reveal(resource) |
| 514 }); | 517 }); |
| 515 } | 518 } |
| 516 | |
| 517 var request = SDK.NetworkLog.requestForURL(url); | |
| 518 if (request) { | 519 if (request) { |
| 519 result.push({ | 520 result.push({ |
| 520 title: Common.UIString.capitalize('Open ^request in Network ^panel'), | 521 title: Common.UIString.capitalize('Open in Network ^panel'), |
| 521 handler: () => Common.Revealer.reveal(request) | 522 handler: () => Common.Revealer.reveal(request) |
| 522 }); | 523 }); |
| 523 } | 524 } |
| 524 | |
| 525 if (resource || info.url) { | 525 if (resource || info.url) { |
| 526 result.push({title: UI.openLinkExternallyLabel(), handler: () => Inspector FrontendHost.openInNewTab(url)}); | 526 result.push({title: UI.openLinkExternallyLabel(), handler: () => Inspector FrontendHost.openInNewTab(url)}); |
| 527 result.push({title: UI.copyLinkAddressLabel(), handler: () => InspectorFro ntendHost.copyText(url)}); | 527 result.push({title: UI.copyLinkAddressLabel(), handler: () => InspectorFro ntendHost.copyText(url)}); |
| 528 } | 528 } |
| 529 | |
| 530 return result; | 529 return result; |
| 531 } | 530 } |
| 532 }; | 531 }; |
| 533 | 532 |
| 534 /** @type {!Set<!Components.Linkifier>} */ | 533 /** @type {!Set<!Components.Linkifier>} */ |
| 535 Components.Linkifier._instances = new Set(); | 534 Components.Linkifier._instances = new Set(); |
| 536 /** @type {?Components.LinkDecorator} */ | 535 /** @type {?Components.LinkDecorator} */ |
| 537 Components.Linkifier._decorator = null; | 536 Components.Linkifier._decorator = null; |
| 538 | 537 |
| 539 Components.Linkifier._sourceCodeAnchors = Symbol('Linkifier.anchors'); | 538 Components.Linkifier._sourceCodeAnchors = Symbol('Linkifier.anchors'); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 562 Components.Linkifier.MaxLengthForDisplayedURLs = 150; | 561 Components.Linkifier.MaxLengthForDisplayedURLs = 150; |
| 563 | 562 |
| 564 /** | 563 /** |
| 565 * The maximum length before strings are considered too long for finding URLs. | 564 * The maximum length before strings are considered too long for finding URLs. |
| 566 * @const | 565 * @const |
| 567 * @type {number} | 566 * @type {number} |
| 568 */ | 567 */ |
| 569 Components.Linkifier.MaxLengthToIgnoreLinkifier = 10000; | 568 Components.Linkifier.MaxLengthToIgnoreLinkifier = 10000; |
| 570 | 569 |
| 571 /** | 570 /** |
| 572 * @interface | 571 * @typedef {function(!Common.ContentProvider, number)} |
| 573 */ | 572 */ |
| 574 Components.Linkifier.LinkHandler = function() {}; | 573 Components.Linkifier.LinkHandler; |
| 575 | 574 |
| 576 Components.Linkifier.LinkHandler.prototype = { | 575 /** @type {!Array<{title: string, handler: !Components.Linkifier.LinkHandler}>} */ |
| 577 /** | 576 Components.Linkifier._linkHandlers = []; |
| 578 * @param {string} url | |
| 579 * @param {number=} lineNumber | |
| 580 * @return {boolean} | |
| 581 */ | |
| 582 handleLink(url, lineNumber) {} | |
| 583 }; | |
| 584 | 577 |
| 585 /** | 578 /** |
| 586 * @extends {Common.EventTarget} | 579 * @extends {Common.EventTarget} |
| 587 * @interface | 580 * @interface |
| 588 */ | 581 */ |
| 589 Components.LinkDecorator = function() {}; | 582 Components.LinkDecorator = function() {}; |
| 590 | 583 |
| 591 Components.LinkDecorator.prototype = { | 584 Components.LinkDecorator.prototype = { |
| 592 /** | 585 /** |
| 593 * @param {!Workspace.UISourceCode} uiSourceCode | 586 * @param {!Workspace.UISourceCode} uiSourceCode |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 673 appendApplicableItems(event, contextMenu, target) { | 666 appendApplicableItems(event, contextMenu, target) { |
| 674 var targetNode = /** @type {!Node} */ (target); | 667 var targetNode = /** @type {!Node} */ (target); |
| 675 while (targetNode && !targetNode[Components.Linkifier._infoSymbol]) | 668 while (targetNode && !targetNode[Components.Linkifier._infoSymbol]) |
| 676 targetNode = targetNode.parentNodeOrShadowHost(); | 669 targetNode = targetNode.parentNodeOrShadowHost(); |
| 677 var link = /** @type {?Element} */ (targetNode); | 670 var link = /** @type {?Element} */ (targetNode); |
| 678 var actions = Components.Linkifier._linkActions(link); | 671 var actions = Components.Linkifier._linkActions(link); |
| 679 for (var action of actions) | 672 for (var action of actions) |
| 680 contextMenu.appendItem(action.title, action.handler); | 673 contextMenu.appendItem(action.title, action.handler); |
| 681 } | 674 } |
| 682 }; | 675 }; |
| 676 | |
| 677 /** | |
| 678 * @implements {UI.SettingUI} | |
| 679 * @unrestricted | |
| 680 */ | |
| 681 Components.Linkifier.LinkHandlerSettingUI = class { | |
|
caseq
2016/11/21 20:13:09
Does it really belong to Linkifier?
| |
| 682 constructor() { | |
| 683 this._element = createElementWithClass('select', 'chrome-select'); | |
| 684 this._element.addEventListener('change', this._onChange.bind(this), false); | |
| 685 this._update(); | |
| 686 } | |
| 687 | |
| 688 _update() { | |
| 689 this._element.removeChildren(); | |
| 690 var names = Components.Linkifier._linkHandlers.map(entry => entry.title); | |
| 691 names.unshift(Common.UIString('auto')); | |
| 692 for (var name of names) { | |
| 693 var option = createElement('option'); | |
| 694 option.textContent = name; | |
| 695 option.selected = name === Components.Linkifier._linkHandlerSetting().get( ); | |
| 696 this._element.appendChild(option); | |
| 697 } | |
| 698 this._element.disabled = names.length <= 1; | |
| 699 } | |
| 700 | |
| 701 /** | |
| 702 * @param {!Event} event | |
| 703 */ | |
| 704 _onChange(event) { | |
| 705 var value = event.target.value; | |
| 706 Components.Linkifier._linkHandlerSetting().set(value); | |
| 707 } | |
| 708 | |
| 709 /** | |
| 710 * @override | |
| 711 * @return {?Element} | |
| 712 */ | |
| 713 settingElement() { | |
| 714 return UI.SettingsUI.createCustomSetting(Common.UIString('Link handling:'), this._element); | |
| 715 } | |
| 716 }; | |
| 717 | |
| 718 /** | |
| 719 * @implements {UI.ContextMenu.Provider} | |
| 720 * @unrestricted | |
| 721 */ | |
| 722 Components.Linkifier.ContentProviderContextMenuProvider = class { | |
| 723 /** | |
| 724 * @override | |
| 725 * @param {!Event} event | |
| 726 * @param {!UI.ContextMenu} contextMenu | |
| 727 * @param {!Object} target | |
| 728 */ | |
| 729 appendApplicableItems(event, contextMenu, target) { | |
| 730 var contentProvider = /** @type {!Common.ContentProvider} */ (target); | |
| 731 if (!contentProvider.contentURL()) | |
| 732 return; | |
| 733 | |
| 734 contextMenu.appendItem( | |
| 735 UI.openLinkExternallyLabel(), () => InspectorFrontendHost.openInNewTab(c ontentProvider.contentURL())); | |
| 736 for (var entry of Components.Linkifier._linkHandlers) { | |
| 737 contextMenu.appendItem( | |
| 738 Common.UIString.capitalize('Open using %s', entry.title), entry.handle r.bind(null, contentProvider, 0)); | |
| 739 } | |
| 740 if (contentProvider instanceof SDK.NetworkRequest) | |
| 741 return; | |
| 742 | |
| 743 contextMenu.appendItem( | |
| 744 UI.copyLinkAddressLabel(), () => InspectorFrontendHost.copyText(contentP rovider.contentURL())); | |
| 745 if (!contentProvider.contentType().isDocumentOrScriptOrStyleSheet()) | |
| 746 return; | |
| 747 | |
| 748 /** | |
| 749 * @param {boolean} forceSaveAs | |
| 750 * @param {?string} content | |
| 751 */ | |
| 752 function doSave(forceSaveAs, content) { | |
| 753 var url = contentProvider.contentURL(); | |
| 754 Workspace.fileManager.save(url, /** @type {string} */ (content), forceSave As); | |
| 755 Workspace.fileManager.close(url); | |
| 756 } | |
| 757 | |
| 758 /** | |
| 759 * @param {boolean} forceSaveAs | |
| 760 */ | |
| 761 function save(forceSaveAs) { | |
| 762 if (contentProvider instanceof Workspace.UISourceCode) { | |
| 763 var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (contentProvid er); | |
| 764 if (forceSaveAs) | |
| 765 uiSourceCode.saveAs(); | |
| 766 else | |
| 767 uiSourceCode.commitWorkingCopy(); | |
| 768 return; | |
| 769 } | |
| 770 contentProvider.requestContent().then(doSave.bind(null, forceSaveAs)); | |
| 771 } | |
| 772 | |
| 773 contextMenu.appendSeparator(); | |
| 774 contextMenu.appendItem(Common.UIString('Save'), save.bind(null, false)); | |
| 775 | |
| 776 if (contentProvider instanceof Workspace.UISourceCode) { | |
| 777 var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (contentProvider ); | |
| 778 if (uiSourceCode.project().type() !== Workspace.projectTypes.FileSystem && | |
| 779 uiSourceCode.project().type() !== Workspace.projectTypes.Snippets) | |
| 780 contextMenu.appendItem(Common.UIString.capitalize('Save ^as...'), save.b ind(null, true)); | |
| 781 } | |
| 782 } | |
| 783 }; | |
| OLD | NEW |