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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/components/Linkifier.js

Issue 2512353002: [DevTools] Refactor Linkifier to unify link processing. (Closed)
Patch Set: rebased Created 4 years 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) 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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 * @param {number=} lineNumber 88 * @param {number=} lineNumber
89 * @return {boolean} 89 * @return {boolean}
90 */ 90 */
91 static handleLink(url, lineNumber) { 91 static handleLink(url, lineNumber) {
92 if (!Components.Linkifier._linkHandler) 92 if (!Components.Linkifier._linkHandler)
93 return false; 93 return false;
94 return Components.Linkifier._linkHandler.handleLink(url, lineNumber); 94 return Components.Linkifier._linkHandler.handleLink(url, lineNumber);
95 } 95 }
96 96
97 /** 97 /**
98 * @param {!Object} revealable
99 * @param {string} text
100 * @param {string=} fallbackHref
101 * @param {number=} fallbackLineNumber
102 * @param {string=} title
103 * @param {string=} classes
104 * @return {!Element}
105 */
106 static linkifyUsingRevealer(revealable, text, fallbackHref, fallbackLineNumber , title, classes) {
107 var a = createElement('a');
108 a.className = (classes || '') + ' webkit-html-resource-link';
109 a.textContent = text.trimMiddle(Components.Linkifier.MaxLengthForDisplayedUR Ls);
110 a.title = title || text;
111 if (fallbackHref) {
112 a.href = fallbackHref;
113 a.lineNumber = fallbackLineNumber;
114 }
115
116 /**
117 * @param {!Event} event
118 * @this {Object}
119 */
120 function clickHandler(event) {
121 event.stopImmediatePropagation();
122 event.preventDefault();
123 if (fallbackHref && Components.Linkifier.handleLink(fallbackHref, fallback LineNumber))
124 return;
125
126 Common.Revealer.reveal(this);
127 }
128 a.addEventListener('click', clickHandler.bind(revealable), false);
129 return a;
130 }
131
132 /**
133 * @param {!Element} anchor 98 * @param {!Element} anchor
134 * @param {!Workspace.UILocation} uiLocation 99 * @param {!Workspace.UILocation} uiLocation
135 */ 100 */
136 static _bindUILocation(anchor, uiLocation) { 101 static _bindUILocation(anchor, uiLocation) {
137 anchor[Components.Linkifier._uiLocationSymbol] = uiLocation; 102 Components.Linkifier._linkInfo(anchor).uiLocation = uiLocation;
138 if (!uiLocation) 103 if (!uiLocation)
139 return; 104 return;
140 var uiSourceCode = uiLocation.uiSourceCode; 105 var uiSourceCode = uiLocation.uiSourceCode;
141 var sourceCodeAnchors = uiSourceCode[Components.Linkifier._sourceCodeAnchors ]; 106 var sourceCodeAnchors = uiSourceCode[Components.Linkifier._sourceCodeAnchors ];
142 if (!sourceCodeAnchors) { 107 if (!sourceCodeAnchors) {
143 sourceCodeAnchors = new Set(); 108 sourceCodeAnchors = new Set();
144 uiSourceCode[Components.Linkifier._sourceCodeAnchors] = sourceCodeAnchors; 109 uiSourceCode[Components.Linkifier._sourceCodeAnchors] = sourceCodeAnchors;
145 } 110 }
146 sourceCodeAnchors.add(anchor); 111 sourceCodeAnchors.add(anchor);
147 } 112 }
148 113
149 /** 114 /**
150 * @param {!Element} anchor 115 * @param {!Element} anchor
151 */ 116 */
152 static _unbindUILocation(anchor) { 117 static _unbindUILocation(anchor) {
153 if (!anchor[Components.Linkifier._uiLocationSymbol]) 118 var info = Components.Linkifier._linkInfo(anchor);
119 if (!info.uiLocation)
154 return; 120 return;
155 121
156 var uiSourceCode = anchor[Components.Linkifier._uiLocationSymbol].uiSourceCo de; 122 var uiSourceCode = info.uiLocation.uiSourceCode;
157 anchor[Components.Linkifier._uiLocationSymbol] = null; 123 info.uiLocation = null;
158 var sourceCodeAnchors = uiSourceCode[Components.Linkifier._sourceCodeAnchors ]; 124 var sourceCodeAnchors = uiSourceCode[Components.Linkifier._sourceCodeAnchors ];
159 if (sourceCodeAnchors) 125 if (sourceCodeAnchors)
160 sourceCodeAnchors.delete(anchor); 126 sourceCodeAnchors.delete(anchor);
161 } 127 }
162 128
163 /** 129 /**
164 * @param {!SDK.Target} target 130 * @param {!SDK.Target} target
165 * @param {string} scriptId 131 * @param {string} scriptId
166 * @param {number} lineNumber 132 * @param {number} lineNumber
167 * @param {number=} columnNumber 133 * @param {number=} columnNumber
(...skipping 24 matching lines...) Expand all
192 158
193 /** 159 /**
194 * @override 160 * @override
195 * @param {!SDK.Target} target 161 * @param {!SDK.Target} target
196 */ 162 */
197 targetRemoved(target) { 163 targetRemoved(target) {
198 var locationPool = /** @type {!Bindings.LiveLocationPool} */ (this._location PoolByTarget.remove(target)); 164 var locationPool = /** @type {!Bindings.LiveLocationPool} */ (this._location PoolByTarget.remove(target));
199 locationPool.disposeAll(); 165 locationPool.disposeAll();
200 var anchors = this._anchorsByTarget.remove(target); 166 var anchors = this._anchorsByTarget.remove(target);
201 for (var anchor of anchors) { 167 for (var anchor of anchors) {
202 delete anchor[Components.Linkifier._liveLocationSymbol]; 168 var info = Components.Linkifier._linkInfo(anchor);
169 info.liveLocation = null;
203 Components.Linkifier._unbindUILocation(anchor); 170 Components.Linkifier._unbindUILocation(anchor);
204 var fallbackAnchor = anchor[Components.Linkifier._fallbackAnchorSymbol]; 171 if (info.fallback) {
205 if (fallbackAnchor) { 172 anchor.href = info.fallback.href;
206 anchor.href = fallbackAnchor.href; 173 anchor.title = info.fallback.title;
207 anchor.lineNumber = fallbackAnchor.lineNumber; 174 anchor.className = info.fallback.className;
208 anchor.title = fallbackAnchor.title; 175 anchor.textContent = info.fallback.textContent;
209 anchor.className = fallbackAnchor.className; 176 anchor[Components.Linkifier._infoSymbol] = info.fallback[Components.Link ifier._infoSymbol];
210 anchor.textContent = fallbackAnchor.textContent;
211 delete anchor[Components.Linkifier._fallbackAnchorSymbol];
212 } 177 }
213 } 178 }
214 } 179 }
215 180
216 /** 181 /**
217 * @param {?SDK.Target} target 182 * @param {?SDK.Target} target
218 * @param {?string} scriptId 183 * @param {?string} scriptId
219 * @param {string} sourceURL 184 * @param {string} sourceURL
220 * @param {number} lineNumber 185 * @param {number} lineNumber
221 * @param {number=} columnNumber 186 * @param {number=} columnNumber
222 * @param {string=} classes 187 * @param {string=} classes
223 * @return {?Element} 188 * @return {?Element}
224 */ 189 */
225 maybeLinkifyScriptLocation(target, scriptId, sourceURL, lineNumber, columnNumb er, classes) { 190 maybeLinkifyScriptLocation(target, scriptId, sourceURL, lineNumber, columnNumb er, classes) {
226 var fallbackAnchor = 191 var fallbackAnchor =
227 sourceURL ? Components.Linkifier.linkifyURL(sourceURL, undefined, classe s, lineNumber, columnNumber) : null; 192 sourceURL ? Components.Linkifier.linkifyURL(sourceURL, undefined, classe s, lineNumber, columnNumber) : null;
228 if (!target || target.isDisposed()) 193 if (!target || target.isDisposed())
229 return fallbackAnchor; 194 return fallbackAnchor;
230 var debuggerModel = SDK.DebuggerModel.fromTarget(target); 195 var debuggerModel = SDK.DebuggerModel.fromTarget(target);
231 if (!debuggerModel) 196 if (!debuggerModel)
232 return fallbackAnchor; 197 return fallbackAnchor;
233 198
234 var rawLocation = 199 var rawLocation =
235 (scriptId ? debuggerModel.createRawLocationByScriptId(scriptId, lineNumb er, columnNumber || 0) : null) || 200 (scriptId ? debuggerModel.createRawLocationByScriptId(scriptId, lineNumb er, columnNumber || 0) : null) ||
236 debuggerModel.createRawLocationByURL(sourceURL, lineNumber, columnNumber || 0); 201 debuggerModel.createRawLocationByURL(sourceURL, lineNumber, columnNumber || 0);
237 if (!rawLocation) 202 if (!rawLocation)
238 return fallbackAnchor; 203 return fallbackAnchor;
239 204
240 var anchor = this._createAnchor(classes); 205 var anchor = Components.Linkifier._createLink('', classes || '');
241 var liveLocation = Bindings.debuggerWorkspaceBinding.createLiveLocation( 206 var info = Components.Linkifier._linkInfo(anchor);
207 info.enableDecorator = this._useLinkDecorator;
208 info.fallback = fallbackAnchor;
209 info.liveLocation = Bindings.debuggerWorkspaceBinding.createLiveLocation(
242 rawLocation, this._updateAnchor.bind(this, anchor), 210 rawLocation, this._updateAnchor.bind(this, anchor),
243 /** @type {!Bindings.LiveLocationPool} */ (this._locationPoolByTarget.ge t(rawLocation.target()))); 211 /** @type {!Bindings.LiveLocationPool} */ (this._locationPoolByTarget.ge t(rawLocation.target())));
212
244 var anchors = /** @type {!Array<!Element>} */ (this._anchorsByTarget.get(raw Location.target())); 213 var anchors = /** @type {!Array<!Element>} */ (this._anchorsByTarget.get(raw Location.target()));
245 anchors.push(anchor); 214 anchors.push(anchor);
246 anchor[Components.Linkifier._liveLocationSymbol] = liveLocation;
247 anchor[Components.Linkifier._fallbackAnchorSymbol] = fallbackAnchor;
248 return anchor; 215 return anchor;
249 } 216 }
250 217
251 /** 218 /**
252 * @param {?SDK.Target} target 219 * @param {?SDK.Target} target
253 * @param {?string} scriptId 220 * @param {?string} scriptId
254 * @param {string} sourceURL 221 * @param {string} sourceURL
255 * @param {number} lineNumber 222 * @param {number} lineNumber
256 * @param {number=} columnNumber 223 * @param {number=} columnNumber
257 * @param {string=} classes 224 * @param {string=} classes
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 var fallbackAnchor = 265 var fallbackAnchor =
299 Components.Linkifier.linkifyURL(topFrame.url, undefined, classes, topFra me.lineNumber, topFrame.columnNumber); 266 Components.Linkifier.linkifyURL(topFrame.url, undefined, classes, topFra me.lineNumber, topFrame.columnNumber);
300 if (target.isDisposed()) 267 if (target.isDisposed())
301 return fallbackAnchor; 268 return fallbackAnchor;
302 269
303 var debuggerModel = SDK.DebuggerModel.fromTarget(target); 270 var debuggerModel = SDK.DebuggerModel.fromTarget(target);
304 var rawLocations = debuggerModel.createRawLocationsByStackTrace(stackTrace); 271 var rawLocations = debuggerModel.createRawLocationsByStackTrace(stackTrace);
305 if (rawLocations.length === 0) 272 if (rawLocations.length === 0)
306 return fallbackAnchor; 273 return fallbackAnchor;
307 274
308 var anchor = this._createAnchor(classes); 275 var anchor = Components.Linkifier._createLink('', classes || '');
309 var liveLocation = Bindings.debuggerWorkspaceBinding.createStackTraceTopFram eLiveLocation( 276 var info = Components.Linkifier._linkInfo(anchor);
277 info.enableDecorator = this._useLinkDecorator;
278 info.fallback = fallbackAnchor;
279 info.liveLocation = Bindings.debuggerWorkspaceBinding.createStackTraceTopFra meLiveLocation(
310 rawLocations, this._updateAnchor.bind(this, anchor), 280 rawLocations, this._updateAnchor.bind(this, anchor),
311 /** @type {!Bindings.LiveLocationPool} */ (this._locationPoolByTarget.ge t(target))); 281 /** @type {!Bindings.LiveLocationPool} */ (this._locationPoolByTarget.ge t(target)));
282
312 var anchors = /** @type {!Array<!Element>} */ (this._anchorsByTarget.get(tar get)); 283 var anchors = /** @type {!Array<!Element>} */ (this._anchorsByTarget.get(tar get));
313 anchors.push(anchor); 284 anchors.push(anchor);
314 anchor[Components.Linkifier._liveLocationSymbol] = liveLocation;
315 anchor[Components.Linkifier._fallbackAnchorSymbol] = fallbackAnchor;
316 return anchor; 285 return anchor;
317 } 286 }
318 287
319 /** 288 /**
320 * @param {!SDK.CSSLocation} rawLocation 289 * @param {!SDK.CSSLocation} rawLocation
321 * @param {string=} classes 290 * @param {string=} classes
322 * @return {!Element} 291 * @return {!Element}
323 */ 292 */
324 linkifyCSSLocation(rawLocation, classes) { 293 linkifyCSSLocation(rawLocation, classes) {
325 var anchor = this._createAnchor(classes); 294 var anchor = Components.Linkifier._createLink('', classes || '');
326 var liveLocation = Bindings.cssWorkspaceBinding.createLiveLocation( 295 var info = Components.Linkifier._linkInfo(anchor);
296 info.enableDecorator = this._useLinkDecorator;
297 info.liveLocation = Bindings.cssWorkspaceBinding.createLiveLocation(
327 rawLocation, this._updateAnchor.bind(this, anchor), 298 rawLocation, this._updateAnchor.bind(this, anchor),
328 /** @type {!Bindings.LiveLocationPool} */ (this._locationPoolByTarget.ge t(rawLocation.target()))); 299 /** @type {!Bindings.LiveLocationPool} */ (this._locationPoolByTarget.ge t(rawLocation.target())));
300
329 var anchors = /** @type {!Array<!Element>} */ (this._anchorsByTarget.get(raw Location.target())); 301 var anchors = /** @type {!Array<!Element>} */ (this._anchorsByTarget.get(raw Location.target()));
330 anchors.push(anchor); 302 anchors.push(anchor);
331 anchor[Components.Linkifier._liveLocationSymbol] = liveLocation;
332 return anchor; 303 return anchor;
333 } 304 }
334 305
335 /** 306 /**
336 * @param {!SDK.Target} target 307 * @param {!SDK.Target} target
337 * @param {!Element} anchor 308 * @param {!Element} anchor
338 */ 309 */
339 disposeAnchor(target, anchor) { 310 disposeAnchor(target, anchor) {
340 Components.Linkifier._unbindUILocation(anchor); 311 Components.Linkifier._unbindUILocation(anchor);
341 delete anchor[Components.Linkifier._fallbackAnchorSymbol]; 312 var info = Components.Linkifier._linkInfo(anchor);
342 var liveLocation = anchor[Components.Linkifier._liveLocationSymbol]; 313 info.fallback = null;
343 if (liveLocation) 314 if (info.liveLocation) {
344 liveLocation.dispose(); 315 info.liveLocation.dispose();
345 delete anchor[Components.Linkifier._liveLocationSymbol]; 316 info.liveLocation = null;
346 }
347
348 /**
349 * @param {string=} classes
350 * @return {!Element}
351 */
352 _createAnchor(classes) {
353 var anchor = createElement('a');
354 if (this._useLinkDecorator)
355 anchor[Components.Linkifier._enableDecoratorSymbol] = true;
356 anchor.className = (classes || '') + ' webkit-html-resource-link';
357
358 /**
359 * @param {!Event} event
360 */
361 function clickHandler(event) {
362 var uiLocation = anchor[Components.Linkifier._uiLocationSymbol];
363 if (!uiLocation)
364 return;
365
366 event.consume(true);
367 if (Components.Linkifier.handleLink(uiLocation.uiSourceCode.url(), uiLocat ion.lineNumber))
368 return;
369 Common.Revealer.reveal(uiLocation);
370 } 317 }
371 anchor.addEventListener('click', clickHandler, false);
372 return anchor;
373 } 318 }
374 319
375 reset() { 320 reset() {
376 for (var target of this._anchorsByTarget.keysArray()) { 321 for (var target of this._anchorsByTarget.keysArray()) {
377 this.targetRemoved(target); 322 this.targetRemoved(target);
378 this.targetAdded(target); 323 this.targetAdded(target);
379 } 324 }
380 } 325 }
381 326
382 dispose() { 327 dispose() {
(...skipping 25 matching lines...) Expand all
408 titleText += ':' + (uiLocation.lineNumber + 1); 353 titleText += ':' + (uiLocation.lineNumber + 1);
409 anchor.title = titleText; 354 anchor.title = titleText;
410 anchor.classList.toggle('webkit-html-blackbox-link', liveLocation.isBlackbox ed()); 355 anchor.classList.toggle('webkit-html-blackbox-link', liveLocation.isBlackbox ed());
411 Components.Linkifier._updateLinkDecorations(anchor); 356 Components.Linkifier._updateLinkDecorations(anchor);
412 } 357 }
413 358
414 /** 359 /**
415 * @param {!Element} anchor 360 * @param {!Element} anchor
416 */ 361 */
417 static _updateLinkDecorations(anchor) { 362 static _updateLinkDecorations(anchor) {
418 if (!anchor[Components.Linkifier._enableDecoratorSymbol]) 363 var info = Components.Linkifier._linkInfo(anchor);
364 if (!info || !info.enableDecorator)
419 return; 365 return;
420 var uiLocation = anchor[Components.Linkifier._uiLocationSymbol]; 366 if (!Components.Linkifier._decorator || !info.uiLocation)
421 if (!Components.Linkifier._decorator || !uiLocation)
422 return; 367 return;
423 var icon = anchor[Components.Linkifier._iconSymbol]; 368 if (info.icon)
424 if (icon) 369 anchor.removeChild(info.icon);
425 icon.remove(); 370 var icon = Components.Linkifier._decorator.linkIcon(info.uiLocation.uiSource Code);
426 icon = Components.Linkifier._decorator.linkIcon(uiLocation.uiSourceCode);
427 if (icon) { 371 if (icon) {
428 icon.style.setProperty('margin-right', '2px'); 372 icon.style.setProperty('margin-right', '2px');
429 anchor.insertBefore(icon, anchor.firstChild); 373 anchor.insertBefore(icon, anchor.firstChild);
430 } 374 }
431 anchor[Components.Linkifier._iconSymbol] = icon; 375 info.icon = icon;
432 } 376 }
433 377
434 /** 378 /**
435 * @param {string} url 379 * @param {string} url
436 * @param {string=} text 380 * @param {string=} text
437 * @param {string=} className 381 * @param {string=} className
438 * @param {number=} lineNumber 382 * @param {number=} lineNumber
439 * @param {number=} columnNumber 383 * @param {number=} columnNumber
440 * @return {!Element} 384 * @return {!Element}
441 */ 385 */
442 static linkifyURL(url, text, className, lineNumber, columnNumber) { 386 static linkifyURL(url, text, className, lineNumber, columnNumber) {
443 if (!url) { 387 if (!url || url.trim().toLowerCase().startsWith('javascript:')) {
444 var element = createElementWithClass('span', className); 388 var element = createElementWithClass('span', className);
445 element.textContent = text || Common.UIString('(unknown)'); 389 element.textContent = text || url || Common.UIString('(unknown)');
446 return element; 390 return element;
447 } 391 }
448 392
449 var linkText = text || Bindings.displayNameForURL(url); 393 var linkText = text || Bindings.displayNameForURL(url);
450 if (typeof lineNumber === 'number' && !text) 394 if (typeof lineNumber === 'number' && !text)
451 linkText += ':' + (lineNumber + 1); 395 linkText += ':' + (lineNumber + 1);
396 var title = linkText !== url ? url : '';
397 var link = Components.Linkifier._createLink(linkText.trimMiddle(150), classN ame || '', title, url);
398 var info = Components.Linkifier._linkInfo(link);
399 if (typeof lineNumber === 'number')
400 info.lineNumber = lineNumber;
401 if (typeof columnNumber === 'number')
402 info.columnNumber = columnNumber;
403 return link;
404 }
452 405
406 /**
407 * @param {!Object} revealable
408 * @param {string} text
409 * @param {string=} fallbackHref
410 * @return {!Element}
411 */
412 static linkifyRevealable(revealable, text, fallbackHref) {
413 var link = Components.Linkifier._createLink(
414 text.trimMiddle(Components.Linkifier.MaxLengthForDisplayedURLs), '', und efined, fallbackHref);
415 Components.Linkifier._linkInfo(link).revealable = revealable;
416 return link;
417 }
418
419 /**
420 * @param {string} text
421 * @param {string} className
422 * @param {string=} title
423 * @param {string=} href
424 * @returns{!Element}
425 */
426 static _createLink(text, className, title, href) {
453 var link = createElementWithClass('a', className); 427 var link = createElementWithClass('a', className);
454 if (!url.trim().toLowerCase().startsWith('javascript:')) { 428 link.classList.add('webkit-html-resource-link');
455 link.href = url; 429 if (title)
456 link.classList.add('webkit-html-resource-link'); 430 link.title = title;
457 link[Components.Linkifier._linkSymbol] = true; 431 if (href)
458 link.addEventListener('click', Components.Linkifier._handleClick, false); 432 link.href = href;
459 } 433 link.textContent = text;
460 link.title = linkText !== url ? url : ''; 434 link[Components.Linkifier._infoSymbol] = {
461 link.textContent = linkText.trimMiddle(150); 435 icon: null,
462 link.lineNumber = lineNumber; 436 enableDecorator: false,
463 link.columnNumber = columnNumber; 437 uiLocation: null,
438 liveLocation: null,
439 url: href || null,
440 lineNumber: null,
441 columnNumber: null,
442 revealable: null,
443 fallback: null
444 };
445 link.addEventListener('click', Components.Linkifier._handleClick, false);
464 return link; 446 return link;
465 } 447 }
466 448
467 /** 449 /**
450 * @param {?Element} link
451 * @return {?Components._LinkInfo}
452 */
453 static _linkInfo(link) {
454 return /** @type {?Components._LinkInfo} */ (link ? link[Components.Linkifie r._infoSymbol] || null : null);
455 }
456
457 /**
468 * @param {!Event} event 458 * @param {!Event} event
469 */ 459 */
470 static _handleClick(event) { 460 static _handleClick(event) {
471 var link = /** @type {!Element} */ (event.currentTarget); 461 var link = /** @type {!Element} */ (event.currentTarget);
472 event.consume(true); 462 event.consume(true);
473 if (link.preventFollow || UI.isBeingEdited(/** @type {!Node} */ (event.targe t))) 463 if (link.preventFollow || UI.isBeingEdited(/** @type {!Node} */ (event.targe t)))
474 return; 464 return;
475 if (Components.openAnchorLocationRegistry.dispatch({url: link.href, lineNumb er: link.lineNumber})) 465 var info = Components.Linkifier._linkInfo(link);
466 if (info.uiLocation &&
467 Components.openAnchorLocationRegistry.dispatch(
468 {url: info.uiLocation.uiSourceCode.url(), lineNumber: info.uiLocatio n.lineNumber}))
476 return; 469 return;
470 if (info.url && Components.openAnchorLocationRegistry.dispatch({url: info.ur l, lineNumber: info.lineNumber}))
471 return;
472 if (info.revealable) {
473 Common.Revealer.reveal(info.revealable);
474 return;
475 }
477 var actions = Components.Linkifier._linkActions(link); 476 var actions = Components.Linkifier._linkActions(link);
478 if (actions.length) 477 if (actions.length)
479 actions[0].handler.call(null); 478 actions[0].handler.call(null);
480 } 479 }
481 480
482 /** 481 /**
483 * @param {?Element} link 482 * @param {?Element} link
484 * @return {!Array<{title: string, handler: function()}>} 483 * @return {!Array<{title: string, handler: function()}>}
485 */ 484 */
486 static _linkActions(link) { 485 static _linkActions(link) {
487 var url = null; 486 var info = Components.Linkifier._linkInfo(link);
487 var result = [];
488 if (!info)
489 return result;
490
491 var url = '';
488 var uiLocation = null; 492 var uiLocation = null;
489 var isLiveLink = false; 493 if (info.uiLocation) {
490 if (link && link[Components.Linkifier._uiLocationSymbol]) { 494 uiLocation = info.uiLocation;
491 uiLocation = /** @type {!Workspace.UILocation} */ (link[Components.Linkifi er._uiLocationSymbol]);
492 url = uiLocation.uiSourceCode.contentURL(); 495 url = uiLocation.uiSourceCode.contentURL();
493 isLiveLink = true; 496 } else if (info.url) {
494 } else if (link && link.href) { 497 url = info.url;
495 url = link.href;
496 var uiSourceCode = Workspace.workspace.uiSourceCodeForURL(url); 498 var uiSourceCode = Workspace.workspace.uiSourceCodeForURL(url);
497 uiLocation = uiSourceCode ? uiSourceCode.uiLocation(link.lineNumber || 0, link.columnNumber || 0) : null; 499 uiLocation = uiSourceCode ? uiSourceCode.uiLocation(info.lineNumber || 0, info.columnNumber || 0) : null;
498 isLiveLink = false;
499 } else {
500 return [];
501 } 500 }
502 501
503 var result = []; 502 if (info.revealable)
503 result.push({title: Common.UIString('Reveal'), handler: () => Common.Revea ler.reveal(info.revealable)});
504
504 if (uiLocation) 505 if (uiLocation)
505 result.push({title: Common.UIString('Open'), handler: () => Common.Reveale r.reveal(uiLocation)}); 506 result.push({title: Common.UIString('Open'), handler: () => Common.Reveale r.reveal(uiLocation)});
506 507
507 var resource = Bindings.resourceForURL(url); 508 var resource = url ? Bindings.resourceForURL(url) : null;
508 if (resource) { 509 if (resource) {
509 result.push({ 510 result.push({
510 title: Common.UIString.capitalize('Open ^link in Application ^panel'), 511 title: Common.UIString.capitalize('Open ^link in Application ^panel'),
511 handler: () => Common.Revealer.reveal(resource) 512 handler: () => Common.Revealer.reveal(resource)
512 }); 513 });
513 } 514 }
514 515
515 var request = SDK.NetworkLog.requestForURL(url); 516 var request = url ? SDK.NetworkLog.requestForURL(url) : null;
516 if (request) { 517 if (request) {
517 result.push({ 518 result.push({
518 title: Common.UIString.capitalize('Open ^request in Network ^panel'), 519 title: Common.UIString.capitalize('Open ^request in Network ^panel'),
519 handler: () => Common.Revealer.reveal(request) 520 handler: () => Common.Revealer.reveal(request)
520 }); 521 });
521 } 522 }
522 523
523 if (resource || !isLiveLink) { 524 if (resource || info.url) {
524 result.push({title: UI.openLinkExternallyLabel(), handler: () => Inspector FrontendHost.openInNewTab(url)}); 525 result.push({title: UI.openLinkExternallyLabel(), handler: () => Inspector FrontendHost.openInNewTab(url)});
525 result.push({title: UI.copyLinkAddressLabel(), handler: () => InspectorFro ntendHost.copyText(url)}); 526 result.push({title: UI.copyLinkAddressLabel(), handler: () => InspectorFro ntendHost.copyText(url)});
526 } 527 }
527 528
528 return result; 529 return result;
529 } 530 }
530 }; 531 };
531 532
532 /** @type {!Set<!Components.Linkifier>} */ 533 /** @type {!Set<!Components.Linkifier>} */
533 Components.Linkifier._instances = new Set(); 534 Components.Linkifier._instances = new Set();
534 /** @type {?Components.LinkDecorator} */ 535 /** @type {?Components.LinkDecorator} */
535 Components.Linkifier._decorator = null; 536 Components.Linkifier._decorator = null;
536 537
537 Components.Linkifier._iconSymbol = Symbol('Linkifier.iconSymbol');
538 Components.Linkifier._enableDecoratorSymbol = Symbol('Linkifier.enableIconsSymbo l');
539 Components.Linkifier._sourceCodeAnchors = Symbol('Linkifier.anchors'); 538 Components.Linkifier._sourceCodeAnchors = Symbol('Linkifier.anchors');
540 Components.Linkifier._uiLocationSymbol = Symbol('uiLocation'); 539 Components.Linkifier._infoSymbol = Symbol('Linkifier.info');
541 Components.Linkifier._fallbackAnchorSymbol = Symbol('fallbackAnchor'); 540
542 Components.Linkifier._liveLocationSymbol = Symbol('liveLocation'); 541 /**
543 Components.Linkifier._linkSymbol = Symbol('Linkifier.link'); 542 * @typedef {{
543 * icon: ?UI.Icon,
544 * enableDecorator: boolean,
545 * uiLocation: ?Workspace.UILocation,
546 * liveLocation: ?Bindings.LiveLocation,
547 * url: ?string,
548 * lineNumber: ?number,
549 * columnNumber: ?number,
550 * revealable: ?Object,
551 * fallback: ?Element
552 * }}
553 */
554 Components._LinkInfo;
544 555
545 /** 556 /**
546 * The maximum number of characters to display in a URL. 557 * The maximum number of characters to display in a URL.
547 * @const 558 * @const
548 * @type {number} 559 * @type {number}
549 */ 560 */
550 Components.Linkifier.MaxLengthForDisplayedURLs = 150; 561 Components.Linkifier.MaxLengthForDisplayedURLs = 150;
551 562
552 /** 563 /**
553 * 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.
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 */ 664 */
654 Components.Linkifier.LinkContextMenuProvider = class { 665 Components.Linkifier.LinkContextMenuProvider = class {
655 /** 666 /**
656 * @override 667 * @override
657 * @param {!Event} event 668 * @param {!Event} event
658 * @param {!UI.ContextMenu} contextMenu 669 * @param {!UI.ContextMenu} contextMenu
659 * @param {!Object} target 670 * @param {!Object} target
660 */ 671 */
661 appendApplicableItems(event, contextMenu, target) { 672 appendApplicableItems(event, contextMenu, target) {
662 var targetNode = /** @type {!Node} */ (target); 673 var targetNode = /** @type {!Node} */ (target);
663 while (targetNode && !targetNode[Components.Linkifier._linkSymbol] && 674 while (targetNode && !targetNode[Components.Linkifier._infoSymbol])
664 !targetNode[Components.Linkifier._uiLocationSymbol])
665 targetNode = targetNode.parentNodeOrShadowHost(); 675 targetNode = targetNode.parentNodeOrShadowHost();
666 var link = /** @type {?Element} */ (targetNode); 676 var link = /** @type {?Element} */ (targetNode);
667 var actions = Components.Linkifier._linkActions(link); 677 var actions = Components.Linkifier._linkActions(link);
668 for (var action of actions) 678 for (var action of actions)
669 contextMenu.appendItem(action.title, action.handler); 679 contextMenu.appendItem(action.title, action.handler);
670 } 680 }
671 }; 681 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698