| Index: third_party/WebKit/Source/devtools/front_end/components/Linkifier.js
|
| diff --git a/third_party/WebKit/Source/devtools/front_end/components/Linkifier.js b/third_party/WebKit/Source/devtools/front_end/components/Linkifier.js
|
| index a619cb3a3301f4017ec4e940c8600be582924cc6..9a2de9ec0458fb3b55c85074a1487b5c15d71824 100644
|
| --- a/third_party/WebKit/Source/devtools/front_end/components/Linkifier.js
|
| +++ b/third_party/WebKit/Source/devtools/front_end/components/Linkifier.js
|
| @@ -95,46 +95,11 @@ Components.Linkifier = class {
|
| }
|
|
|
| /**
|
| - * @param {!Object} revealable
|
| - * @param {string} text
|
| - * @param {string=} fallbackHref
|
| - * @param {number=} fallbackLineNumber
|
| - * @param {string=} title
|
| - * @param {string=} classes
|
| - * @return {!Element}
|
| - */
|
| - static linkifyUsingRevealer(revealable, text, fallbackHref, fallbackLineNumber, title, classes) {
|
| - var a = createElement('a');
|
| - a.className = (classes || '') + ' webkit-html-resource-link';
|
| - a.textContent = text.trimMiddle(Components.Linkifier.MaxLengthForDisplayedURLs);
|
| - a.title = title || text;
|
| - if (fallbackHref) {
|
| - a.href = fallbackHref;
|
| - a.lineNumber = fallbackLineNumber;
|
| - }
|
| -
|
| - /**
|
| - * @param {!Event} event
|
| - * @this {Object}
|
| - */
|
| - function clickHandler(event) {
|
| - event.stopImmediatePropagation();
|
| - event.preventDefault();
|
| - if (fallbackHref && Components.Linkifier.handleLink(fallbackHref, fallbackLineNumber))
|
| - return;
|
| -
|
| - Common.Revealer.reveal(this);
|
| - }
|
| - a.addEventListener('click', clickHandler.bind(revealable), false);
|
| - return a;
|
| - }
|
| -
|
| - /**
|
| * @param {!Element} anchor
|
| * @param {!Workspace.UILocation} uiLocation
|
| */
|
| static _bindUILocation(anchor, uiLocation) {
|
| - anchor[Components.Linkifier._uiLocationSymbol] = uiLocation;
|
| + Components.Linkifier._linkInfo(anchor).uiLocation = uiLocation;
|
| if (!uiLocation)
|
| return;
|
| var uiSourceCode = uiLocation.uiSourceCode;
|
| @@ -150,11 +115,12 @@ Components.Linkifier = class {
|
| * @param {!Element} anchor
|
| */
|
| static _unbindUILocation(anchor) {
|
| - if (!anchor[Components.Linkifier._uiLocationSymbol])
|
| + var info = Components.Linkifier._linkInfo(anchor);
|
| + if (!info.uiLocation)
|
| return;
|
|
|
| - var uiSourceCode = anchor[Components.Linkifier._uiLocationSymbol].uiSourceCode;
|
| - anchor[Components.Linkifier._uiLocationSymbol] = null;
|
| + var uiSourceCode = info.uiLocation.uiSourceCode;
|
| + info.uiLocation = null;
|
| var sourceCodeAnchors = uiSourceCode[Components.Linkifier._sourceCodeAnchors];
|
| if (sourceCodeAnchors)
|
| sourceCodeAnchors.delete(anchor);
|
| @@ -199,16 +165,15 @@ Components.Linkifier = class {
|
| locationPool.disposeAll();
|
| var anchors = this._anchorsByTarget.remove(target);
|
| for (var anchor of anchors) {
|
| - delete anchor[Components.Linkifier._liveLocationSymbol];
|
| + var info = Components.Linkifier._linkInfo(anchor);
|
| + info.liveLocation = null;
|
| Components.Linkifier._unbindUILocation(anchor);
|
| - var fallbackAnchor = anchor[Components.Linkifier._fallbackAnchorSymbol];
|
| - if (fallbackAnchor) {
|
| - anchor.href = fallbackAnchor.href;
|
| - anchor.lineNumber = fallbackAnchor.lineNumber;
|
| - anchor.title = fallbackAnchor.title;
|
| - anchor.className = fallbackAnchor.className;
|
| - anchor.textContent = fallbackAnchor.textContent;
|
| - delete anchor[Components.Linkifier._fallbackAnchorSymbol];
|
| + if (info.fallback) {
|
| + anchor.href = info.fallback.href;
|
| + anchor.title = info.fallback.title;
|
| + anchor.className = info.fallback.className;
|
| + anchor.textContent = info.fallback.textContent;
|
| + anchor[Components.Linkifier._infoSymbol] = info.fallback[Components.Linkifier._infoSymbol];
|
| }
|
| }
|
| }
|
| @@ -237,14 +202,16 @@ Components.Linkifier = class {
|
| if (!rawLocation)
|
| return fallbackAnchor;
|
|
|
| - var anchor = this._createAnchor(classes);
|
| - var liveLocation = Bindings.debuggerWorkspaceBinding.createLiveLocation(
|
| + var anchor = Components.Linkifier._createLink('', classes || '');
|
| + var info = Components.Linkifier._linkInfo(anchor);
|
| + info.enableDecorator = this._useLinkDecorator;
|
| + info.fallback = fallbackAnchor;
|
| + info.liveLocation = Bindings.debuggerWorkspaceBinding.createLiveLocation(
|
| rawLocation, this._updateAnchor.bind(this, anchor),
|
| /** @type {!Bindings.LiveLocationPool} */ (this._locationPoolByTarget.get(rawLocation.target())));
|
| +
|
| var anchors = /** @type {!Array<!Element>} */ (this._anchorsByTarget.get(rawLocation.target()));
|
| anchors.push(anchor);
|
| - anchor[Components.Linkifier._liveLocationSymbol] = liveLocation;
|
| - anchor[Components.Linkifier._fallbackAnchorSymbol] = fallbackAnchor;
|
| return anchor;
|
| }
|
|
|
| @@ -305,14 +272,16 @@ Components.Linkifier = class {
|
| if (rawLocations.length === 0)
|
| return fallbackAnchor;
|
|
|
| - var anchor = this._createAnchor(classes);
|
| - var liveLocation = Bindings.debuggerWorkspaceBinding.createStackTraceTopFrameLiveLocation(
|
| + var anchor = Components.Linkifier._createLink('', classes || '');
|
| + var info = Components.Linkifier._linkInfo(anchor);
|
| + info.enableDecorator = this._useLinkDecorator;
|
| + info.fallback = fallbackAnchor;
|
| + info.liveLocation = Bindings.debuggerWorkspaceBinding.createStackTraceTopFrameLiveLocation(
|
| rawLocations, this._updateAnchor.bind(this, anchor),
|
| /** @type {!Bindings.LiveLocationPool} */ (this._locationPoolByTarget.get(target)));
|
| +
|
| var anchors = /** @type {!Array<!Element>} */ (this._anchorsByTarget.get(target));
|
| anchors.push(anchor);
|
| - anchor[Components.Linkifier._liveLocationSymbol] = liveLocation;
|
| - anchor[Components.Linkifier._fallbackAnchorSymbol] = fallbackAnchor;
|
| return anchor;
|
| }
|
|
|
| @@ -322,13 +291,15 @@ Components.Linkifier = class {
|
| * @return {!Element}
|
| */
|
| linkifyCSSLocation(rawLocation, classes) {
|
| - var anchor = this._createAnchor(classes);
|
| - var liveLocation = Bindings.cssWorkspaceBinding.createLiveLocation(
|
| + var anchor = Components.Linkifier._createLink('', classes || '');
|
| + var info = Components.Linkifier._linkInfo(anchor);
|
| + info.enableDecorator = this._useLinkDecorator;
|
| + info.liveLocation = Bindings.cssWorkspaceBinding.createLiveLocation(
|
| rawLocation, this._updateAnchor.bind(this, anchor),
|
| /** @type {!Bindings.LiveLocationPool} */ (this._locationPoolByTarget.get(rawLocation.target())));
|
| +
|
| var anchors = /** @type {!Array<!Element>} */ (this._anchorsByTarget.get(rawLocation.target()));
|
| anchors.push(anchor);
|
| - anchor[Components.Linkifier._liveLocationSymbol] = liveLocation;
|
| return anchor;
|
| }
|
|
|
| @@ -338,38 +309,12 @@ Components.Linkifier = class {
|
| */
|
| disposeAnchor(target, anchor) {
|
| Components.Linkifier._unbindUILocation(anchor);
|
| - delete anchor[Components.Linkifier._fallbackAnchorSymbol];
|
| - var liveLocation = anchor[Components.Linkifier._liveLocationSymbol];
|
| - if (liveLocation)
|
| - liveLocation.dispose();
|
| - delete anchor[Components.Linkifier._liveLocationSymbol];
|
| - }
|
| -
|
| - /**
|
| - * @param {string=} classes
|
| - * @return {!Element}
|
| - */
|
| - _createAnchor(classes) {
|
| - var anchor = createElement('a');
|
| - if (this._useLinkDecorator)
|
| - anchor[Components.Linkifier._enableDecoratorSymbol] = true;
|
| - anchor.className = (classes || '') + ' webkit-html-resource-link';
|
| -
|
| - /**
|
| - * @param {!Event} event
|
| - */
|
| - function clickHandler(event) {
|
| - var uiLocation = anchor[Components.Linkifier._uiLocationSymbol];
|
| - if (!uiLocation)
|
| - return;
|
| -
|
| - event.consume(true);
|
| - if (Components.Linkifier.handleLink(uiLocation.uiSourceCode.url(), uiLocation.lineNumber))
|
| - return;
|
| - Common.Revealer.reveal(uiLocation);
|
| + var info = Components.Linkifier._linkInfo(anchor);
|
| + info.fallback = null;
|
| + if (info.liveLocation) {
|
| + info.liveLocation.dispose();
|
| + info.liveLocation = null;
|
| }
|
| - anchor.addEventListener('click', clickHandler, false);
|
| - return anchor;
|
| }
|
|
|
| reset() {
|
| @@ -415,20 +360,19 @@ Components.Linkifier = class {
|
| * @param {!Element} anchor
|
| */
|
| static _updateLinkDecorations(anchor) {
|
| - if (!anchor[Components.Linkifier._enableDecoratorSymbol])
|
| + var info = Components.Linkifier._linkInfo(anchor);
|
| + if (!info || !info.enableDecorator)
|
| return;
|
| - var uiLocation = anchor[Components.Linkifier._uiLocationSymbol];
|
| - if (!Components.Linkifier._decorator || !uiLocation)
|
| + if (!Components.Linkifier._decorator || !info.uiLocation)
|
| return;
|
| - var icon = anchor[Components.Linkifier._iconSymbol];
|
| - if (icon)
|
| - icon.remove();
|
| - icon = Components.Linkifier._decorator.linkIcon(uiLocation.uiSourceCode);
|
| + if (info.icon)
|
| + anchor.removeChild(info.icon);
|
| + var icon = Components.Linkifier._decorator.linkIcon(info.uiLocation.uiSourceCode);
|
| if (icon) {
|
| icon.style.setProperty('margin-right', '2px');
|
| anchor.insertBefore(icon, anchor.firstChild);
|
| }
|
| - anchor[Components.Linkifier._iconSymbol] = icon;
|
| + info.icon = icon;
|
| }
|
|
|
| /**
|
| @@ -440,31 +384,77 @@ Components.Linkifier = class {
|
| * @return {!Element}
|
| */
|
| static linkifyURL(url, text, className, lineNumber, columnNumber) {
|
| - if (!url) {
|
| + if (!url || url.trim().toLowerCase().startsWith('javascript:')) {
|
| var element = createElementWithClass('span', className);
|
| - element.textContent = text || Common.UIString('(unknown)');
|
| + element.textContent = text || url || Common.UIString('(unknown)');
|
| return element;
|
| }
|
|
|
| var linkText = text || Bindings.displayNameForURL(url);
|
| if (typeof lineNumber === 'number' && !text)
|
| linkText += ':' + (lineNumber + 1);
|
| + var title = linkText !== url ? url : '';
|
| + var link = Components.Linkifier._createLink(linkText.trimMiddle(150), className || '', title, url);
|
| + var info = Components.Linkifier._linkInfo(link);
|
| + if (typeof lineNumber === 'number')
|
| + info.lineNumber = lineNumber;
|
| + if (typeof columnNumber === 'number')
|
| + info.columnNumber = columnNumber;
|
| + return link;
|
| + }
|
|
|
| + /**
|
| + * @param {!Object} revealable
|
| + * @param {string} text
|
| + * @param {string=} fallbackHref
|
| + * @return {!Element}
|
| + */
|
| + static linkifyRevealable(revealable, text, fallbackHref) {
|
| + var link = Components.Linkifier._createLink(
|
| + text.trimMiddle(Components.Linkifier.MaxLengthForDisplayedURLs), '', undefined, fallbackHref);
|
| + Components.Linkifier._linkInfo(link).revealable = revealable;
|
| + return link;
|
| + }
|
| +
|
| + /**
|
| + * @param {string} text
|
| + * @param {string} className
|
| + * @param {string=} title
|
| + * @param {string=} href
|
| + * @returns{!Element}
|
| + */
|
| + static _createLink(text, className, title, href) {
|
| var link = createElementWithClass('a', className);
|
| - if (!url.trim().toLowerCase().startsWith('javascript:')) {
|
| - link.href = url;
|
| - link.classList.add('webkit-html-resource-link');
|
| - link[Components.Linkifier._linkSymbol] = true;
|
| - link.addEventListener('click', Components.Linkifier._handleClick, false);
|
| - }
|
| - link.title = linkText !== url ? url : '';
|
| - link.textContent = linkText.trimMiddle(150);
|
| - link.lineNumber = lineNumber;
|
| - link.columnNumber = columnNumber;
|
| + link.classList.add('webkit-html-resource-link');
|
| + if (title)
|
| + link.title = title;
|
| + if (href)
|
| + link.href = href;
|
| + link.textContent = text;
|
| + link[Components.Linkifier._infoSymbol] = {
|
| + icon: null,
|
| + enableDecorator: false,
|
| + uiLocation: null,
|
| + liveLocation: null,
|
| + url: href || null,
|
| + lineNumber: null,
|
| + columnNumber: null,
|
| + revealable: null,
|
| + fallback: null
|
| + };
|
| + link.addEventListener('click', Components.Linkifier._handleClick, false);
|
| return link;
|
| }
|
|
|
| /**
|
| + * @param {?Element} link
|
| + * @return {?Components._LinkInfo}
|
| + */
|
| + static _linkInfo(link) {
|
| + return /** @type {?Components._LinkInfo} */ (link ? link[Components.Linkifier._infoSymbol] || null : null);
|
| + }
|
| +
|
| + /**
|
| * @param {!Event} event
|
| */
|
| static _handleClick(event) {
|
| @@ -472,8 +462,17 @@ Components.Linkifier = class {
|
| event.consume(true);
|
| if (link.preventFollow || UI.isBeingEdited(/** @type {!Node} */ (event.target)))
|
| return;
|
| - if (Components.openAnchorLocationRegistry.dispatch({url: link.href, lineNumber: link.lineNumber}))
|
| + var info = Components.Linkifier._linkInfo(link);
|
| + if (info.uiLocation &&
|
| + Components.openAnchorLocationRegistry.dispatch(
|
| + {url: info.uiLocation.uiSourceCode.url(), lineNumber: info.uiLocation.lineNumber}))
|
| + return;
|
| + if (info.url && Components.openAnchorLocationRegistry.dispatch({url: info.url, lineNumber: info.lineNumber}))
|
| return;
|
| + if (info.revealable) {
|
| + Common.Revealer.reveal(info.revealable);
|
| + return;
|
| + }
|
| var actions = Components.Linkifier._linkActions(link);
|
| if (actions.length)
|
| actions[0].handler.call(null);
|
| @@ -484,27 +483,29 @@ Components.Linkifier = class {
|
| * @return {!Array<{title: string, handler: function()}>}
|
| */
|
| static _linkActions(link) {
|
| - var url = null;
|
| + var info = Components.Linkifier._linkInfo(link);
|
| + var result = [];
|
| + if (!info)
|
| + return result;
|
| +
|
| + var url = '';
|
| var uiLocation = null;
|
| - var isLiveLink = false;
|
| - if (link && link[Components.Linkifier._uiLocationSymbol]) {
|
| - uiLocation = /** @type {!Workspace.UILocation} */ (link[Components.Linkifier._uiLocationSymbol]);
|
| + if (info.uiLocation) {
|
| + uiLocation = info.uiLocation;
|
| url = uiLocation.uiSourceCode.contentURL();
|
| - isLiveLink = true;
|
| - } else if (link && link.href) {
|
| - url = link.href;
|
| + } else if (info.url) {
|
| + url = info.url;
|
| var uiSourceCode = Workspace.workspace.uiSourceCodeForURL(url);
|
| - uiLocation = uiSourceCode ? uiSourceCode.uiLocation(link.lineNumber || 0, link.columnNumber || 0) : null;
|
| - isLiveLink = false;
|
| - } else {
|
| - return [];
|
| + uiLocation = uiSourceCode ? uiSourceCode.uiLocation(info.lineNumber || 0, info.columnNumber || 0) : null;
|
| }
|
|
|
| - var result = [];
|
| + if (info.revealable)
|
| + result.push({title: Common.UIString('Reveal'), handler: () => Common.Revealer.reveal(info.revealable)});
|
| +
|
| if (uiLocation)
|
| result.push({title: Common.UIString('Open'), handler: () => Common.Revealer.reveal(uiLocation)});
|
|
|
| - var resource = Bindings.resourceForURL(url);
|
| + var resource = url ? Bindings.resourceForURL(url) : null;
|
| if (resource) {
|
| result.push({
|
| title: Common.UIString.capitalize('Open ^link in Application ^panel'),
|
| @@ -512,7 +513,7 @@ Components.Linkifier = class {
|
| });
|
| }
|
|
|
| - var request = SDK.NetworkLog.requestForURL(url);
|
| + var request = url ? SDK.NetworkLog.requestForURL(url) : null;
|
| if (request) {
|
| result.push({
|
| title: Common.UIString.capitalize('Open ^request in Network ^panel'),
|
| @@ -520,7 +521,7 @@ Components.Linkifier = class {
|
| });
|
| }
|
|
|
| - if (resource || !isLiveLink) {
|
| + if (resource || info.url) {
|
| result.push({title: UI.openLinkExternallyLabel(), handler: () => InspectorFrontendHost.openInNewTab(url)});
|
| result.push({title: UI.copyLinkAddressLabel(), handler: () => InspectorFrontendHost.copyText(url)});
|
| }
|
| @@ -534,13 +535,23 @@ Components.Linkifier._instances = new Set();
|
| /** @type {?Components.LinkDecorator} */
|
| Components.Linkifier._decorator = null;
|
|
|
| -Components.Linkifier._iconSymbol = Symbol('Linkifier.iconSymbol');
|
| -Components.Linkifier._enableDecoratorSymbol = Symbol('Linkifier.enableIconsSymbol');
|
| Components.Linkifier._sourceCodeAnchors = Symbol('Linkifier.anchors');
|
| -Components.Linkifier._uiLocationSymbol = Symbol('uiLocation');
|
| -Components.Linkifier._fallbackAnchorSymbol = Symbol('fallbackAnchor');
|
| -Components.Linkifier._liveLocationSymbol = Symbol('liveLocation');
|
| -Components.Linkifier._linkSymbol = Symbol('Linkifier.link');
|
| +Components.Linkifier._infoSymbol = Symbol('Linkifier.info');
|
| +
|
| +/**
|
| + * @typedef {{
|
| + * icon: ?UI.Icon,
|
| + * enableDecorator: boolean,
|
| + * uiLocation: ?Workspace.UILocation,
|
| + * liveLocation: ?Bindings.LiveLocation,
|
| + * url: ?string,
|
| + * lineNumber: ?number,
|
| + * columnNumber: ?number,
|
| + * revealable: ?Object,
|
| + * fallback: ?Element
|
| + * }}
|
| + */
|
| +Components._LinkInfo;
|
|
|
| /**
|
| * The maximum number of characters to display in a URL.
|
| @@ -660,8 +671,7 @@ Components.Linkifier.LinkContextMenuProvider = class {
|
| */
|
| appendApplicableItems(event, contextMenu, target) {
|
| var targetNode = /** @type {!Node} */ (target);
|
| - while (targetNode && !targetNode[Components.Linkifier._linkSymbol] &&
|
| - !targetNode[Components.Linkifier._uiLocationSymbol])
|
| + while (targetNode && !targetNode[Components.Linkifier._infoSymbol])
|
| targetNode = targetNode.parentNodeOrShadowHost();
|
| var link = /** @type {?Element} */ (targetNode);
|
| var actions = Components.Linkifier._linkActions(link);
|
|
|