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

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: unified click handler Created 4 years, 1 month 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 if (this._useLinkDecorator)
208 info.enableDecorator = true;
lushnikov 2016/11/21 20:14:07 here and below: just info.enableDecorator = this._
dgozman 2016/11/21 22:37:47 Done.
209 info.fallback = fallbackAnchor;
210 info.liveLocation = Bindings.debuggerWorkspaceBinding.createLiveLocation(
242 rawLocation, this._updateAnchor.bind(this, anchor), 211 rawLocation, this._updateAnchor.bind(this, anchor),
243 /** @type {!Bindings.LiveLocationPool} */ (this._locationPoolByTarget.ge t(rawLocation.target()))); 212 /** @type {!Bindings.LiveLocationPool} */ (this._locationPoolByTarget.ge t(rawLocation.target())));
213
244 var anchors = /** @type {!Array<!Element>} */ (this._anchorsByTarget.get(raw Location.target())); 214 var anchors = /** @type {!Array<!Element>} */ (this._anchorsByTarget.get(raw Location.target()));
245 anchors.push(anchor); 215 anchors.push(anchor);
246 anchor[Components.Linkifier._liveLocationSymbol] = liveLocation;
247 anchor[Components.Linkifier._fallbackAnchorSymbol] = fallbackAnchor;
248 return anchor; 216 return anchor;
249 } 217 }
250 218
251 /** 219 /**
252 * @param {?SDK.Target} target 220 * @param {?SDK.Target} target
253 * @param {?string} scriptId 221 * @param {?string} scriptId
254 * @param {string} sourceURL 222 * @param {string} sourceURL
255 * @param {number} lineNumber 223 * @param {number} lineNumber
256 * @param {number=} columnNumber 224 * @param {number=} columnNumber
257 * @param {string=} classes 225 * @param {string=} classes
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 var fallbackAnchor = 266 var fallbackAnchor =
299 Components.Linkifier.linkifyURL(topFrame.url, undefined, classes, topFra me.lineNumber, topFrame.columnNumber); 267 Components.Linkifier.linkifyURL(topFrame.url, undefined, classes, topFra me.lineNumber, topFrame.columnNumber);
300 if (target.isDisposed()) 268 if (target.isDisposed())
301 return fallbackAnchor; 269 return fallbackAnchor;
302 270
303 var debuggerModel = SDK.DebuggerModel.fromTarget(target); 271 var debuggerModel = SDK.DebuggerModel.fromTarget(target);
304 var rawLocations = debuggerModel.createRawLocationsByStackTrace(stackTrace); 272 var rawLocations = debuggerModel.createRawLocationsByStackTrace(stackTrace);
305 if (rawLocations.length === 0) 273 if (rawLocations.length === 0)
306 return fallbackAnchor; 274 return fallbackAnchor;
307 275
308 var anchor = this._createAnchor(classes); 276 var anchor = Components.Linkifier._createLink('', classes || '');
309 var liveLocation = Bindings.debuggerWorkspaceBinding.createStackTraceTopFram eLiveLocation( 277 var info = Components.Linkifier._linkInfo(anchor);
278 if (this._useLinkDecorator)
279 info.enableDecorator = true;
280 info.fallback = fallbackAnchor;
281 info.liveLocation = Bindings.debuggerWorkspaceBinding.createStackTraceTopFra meLiveLocation(
310 rawLocations, this._updateAnchor.bind(this, anchor), 282 rawLocations, this._updateAnchor.bind(this, anchor),
311 /** @type {!Bindings.LiveLocationPool} */ (this._locationPoolByTarget.ge t(target))); 283 /** @type {!Bindings.LiveLocationPool} */ (this._locationPoolByTarget.ge t(target)));
284
312 var anchors = /** @type {!Array<!Element>} */ (this._anchorsByTarget.get(tar get)); 285 var anchors = /** @type {!Array<!Element>} */ (this._anchorsByTarget.get(tar get));
313 anchors.push(anchor); 286 anchors.push(anchor);
314 anchor[Components.Linkifier._liveLocationSymbol] = liveLocation;
315 anchor[Components.Linkifier._fallbackAnchorSymbol] = fallbackAnchor;
316 return anchor; 287 return anchor;
317 } 288 }
318 289
319 /** 290 /**
320 * @param {!SDK.CSSLocation} rawLocation 291 * @param {!SDK.CSSLocation} rawLocation
321 * @param {string=} classes 292 * @param {string=} classes
322 * @return {!Element} 293 * @return {!Element}
323 */ 294 */
324 linkifyCSSLocation(rawLocation, classes) { 295 linkifyCSSLocation(rawLocation, classes) {
325 var anchor = this._createAnchor(classes); 296 var anchor = Components.Linkifier._createLink('', classes || '');
lushnikov 2016/11/21 20:14:07 so what is "anchor" and what is "link"? Do we diff
dgozman 2016/11/21 22:37:47 Same thing. I just think that linkifier should wor
326 var liveLocation = Bindings.cssWorkspaceBinding.createLiveLocation( 297 var info = Components.Linkifier._linkInfo(anchor);
298 if (this._useLinkDecorator)
299 info.enableDecorator = true;
300 info.liveLocation = Bindings.cssWorkspaceBinding.createLiveLocation(
327 rawLocation, this._updateAnchor.bind(this, anchor), 301 rawLocation, this._updateAnchor.bind(this, anchor),
328 /** @type {!Bindings.LiveLocationPool} */ (this._locationPoolByTarget.ge t(rawLocation.target()))); 302 /** @type {!Bindings.LiveLocationPool} */ (this._locationPoolByTarget.ge t(rawLocation.target())));
303
329 var anchors = /** @type {!Array<!Element>} */ (this._anchorsByTarget.get(raw Location.target())); 304 var anchors = /** @type {!Array<!Element>} */ (this._anchorsByTarget.get(raw Location.target()));
330 anchors.push(anchor); 305 anchors.push(anchor);
331 anchor[Components.Linkifier._liveLocationSymbol] = liveLocation;
332 return anchor; 306 return anchor;
333 } 307 }
334 308
335 /** 309 /**
336 * @param {!SDK.Target} target 310 * @param {!SDK.Target} target
337 * @param {!Element} anchor 311 * @param {!Element} anchor
338 */ 312 */
339 disposeAnchor(target, anchor) { 313 disposeAnchor(target, anchor) {
340 Components.Linkifier._unbindUILocation(anchor); 314 Components.Linkifier._unbindUILocation(anchor);
341 delete anchor[Components.Linkifier._fallbackAnchorSymbol]; 315 var info = Components.Linkifier._linkInfo(anchor);
342 var liveLocation = anchor[Components.Linkifier._liveLocationSymbol]; 316 info.fallback = null;
343 if (liveLocation) 317 if (info.liveLocation) {
344 liveLocation.dispose(); 318 info.liveLocation.dispose();
345 delete anchor[Components.Linkifier._liveLocationSymbol]; 319 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 } 320 }
371 anchor.addEventListener('click', clickHandler, false);
372 return anchor;
373 } 321 }
374 322
375 reset() { 323 reset() {
376 for (var target of this._anchorsByTarget.keysArray()) { 324 for (var target of this._anchorsByTarget.keysArray()) {
377 this.targetRemoved(target); 325 this.targetRemoved(target);
378 this.targetAdded(target); 326 this.targetAdded(target);
379 } 327 }
380 } 328 }
381 329
382 dispose() { 330 dispose() {
(...skipping 25 matching lines...) Expand all
408 titleText += ':' + (uiLocation.lineNumber + 1); 356 titleText += ':' + (uiLocation.lineNumber + 1);
409 anchor.title = titleText; 357 anchor.title = titleText;
410 anchor.classList.toggle('webkit-html-blackbox-link', liveLocation.isBlackbox ed()); 358 anchor.classList.toggle('webkit-html-blackbox-link', liveLocation.isBlackbox ed());
411 Components.Linkifier._updateLinkDecorations(anchor); 359 Components.Linkifier._updateLinkDecorations(anchor);
412 } 360 }
413 361
414 /** 362 /**
415 * @param {!Element} anchor 363 * @param {!Element} anchor
416 */ 364 */
417 static _updateLinkDecorations(anchor) { 365 static _updateLinkDecorations(anchor) {
418 if (!anchor[Components.Linkifier._enableDecoratorSymbol]) 366 var info = Components.Linkifier._linkInfo(anchor);
367 if (!info.enableDecorator)
lushnikov 2016/11/21 20:14:07 if (!info || !info.enableDecorator)
dgozman 2016/11/21 22:37:47 Done.
419 return; 368 return;
420 var uiLocation = anchor[Components.Linkifier._uiLocationSymbol]; 369 if (!Components.Linkifier._decorator || !info.uiLocation)
421 if (!Components.Linkifier._decorator || !uiLocation)
422 return; 370 return;
423 var icon = anchor[Components.Linkifier._iconSymbol]; 371 if (info.icon)
424 if (icon) 372 anchor.removeChild(info.icon);
425 icon.remove(); 373 var icon = Components.Linkifier._decorator.linkIcon(info.uiLocation.uiSource Code);
426 icon = Components.Linkifier._decorator.linkIcon(uiLocation.uiSourceCode);
427 if (icon) { 374 if (icon) {
428 icon.style.setProperty('margin-right', '2px'); 375 icon.style.setProperty('margin-right', '2px');
429 anchor.insertBefore(icon, anchor.firstChild); 376 anchor.insertBefore(icon, anchor.firstChild);
430 } 377 }
431 anchor[Components.Linkifier._iconSymbol] = icon; 378 info.icon = icon;
432 } 379 }
433 380
434 /** 381 /**
435 * @param {string} url 382 * @param {string} url
436 * @param {string=} text 383 * @param {string=} text
437 * @param {string=} className 384 * @param {string=} className
438 * @param {number=} lineNumber 385 * @param {number=} lineNumber
439 * @param {number=} columnNumber 386 * @param {number=} columnNumber
440 * @return {!Element} 387 * @return {!Element}
441 */ 388 */
442 static linkifyURL(url, text, className, lineNumber, columnNumber) { 389 static linkifyURL(url, text, className, lineNumber, columnNumber) {
443 if (!url) { 390 if (!url || url.trim().toLowerCase().startsWith('javascript:')) {
lushnikov 2016/11/21 20:14:07 this drops link.lineNumber and link.columnNumber w
dgozman 2016/11/21 22:37:47 Don't need them anymore, since we don't use extern
444 var element = createElementWithClass('span', className); 391 var element = createElementWithClass('span', className);
445 element.textContent = text || Common.UIString('(unknown)'); 392 element.textContent = text || url || Common.UIString('(unknown)');
446 return element; 393 return element;
447 } 394 }
448 395
449 var linkText = text || Bindings.displayNameForURL(url); 396 var linkText = text || Bindings.displayNameForURL(url);
450 if (typeof lineNumber === 'number' && !text) 397 if (typeof lineNumber === 'number' && !text)
451 linkText += ':' + (lineNumber + 1); 398 linkText += ':' + (lineNumber + 1);
399 var title = linkText !== url ? url : '';
400 var link = Components.Linkifier._createLink(linkText.trimMiddle(150), classN ame || '', title, url);
401 var info = Components.Linkifier._linkInfo(link);
402 if (typeof lineNumber === 'number')
403 info.lineNumber = lineNumber;
404 if (typeof columnNumber === 'number')
405 info.columnNumber = columnNumber;
406 return link;
407 }
452 408
409 /**
410 * @param {!Object} revealable
411 * @param {string} text
412 * @param {string=} fallbackHref
413 * @return {!Element}
414 */
415 static linkifyRevealable(revealable, text, fallbackHref) {
416 var link = Components.Linkifier._createLink(
417 text.trimMiddle(Components.Linkifier.MaxLengthForDisplayedURLs), '', und efined, fallbackHref);
418 Components.Linkifier._linkInfo(link).revealable = revealable;
419 return link;
420 }
421
422 /**
423 * @param {string} text
424 * @param {string} className
425 * @param {string=} title
426 * @param {string=} href
427 * @returns{!Element}
428 */
429 static _createLink(text, className, title, href) {
453 var link = createElementWithClass('a', className); 430 var link = createElementWithClass('a', className);
454 if (!url.trim().toLowerCase().startsWith('javascript:')) { 431 link.classList.add('webkit-html-resource-link');
455 link.href = url; 432 if (title)
456 link.classList.add('webkit-html-resource-link'); 433 link.title = title;
457 link[Components.Linkifier._linkSymbol] = true; 434 if (href)
458 link.addEventListener('click', Components.Linkifier._handleClick, false); 435 link.href = href;
459 } 436 link.textContent = text;
460 link.title = linkText !== url ? url : ''; 437 link[Components.Linkifier._infoSymbol] = {
461 link.textContent = linkText.trimMiddle(150); 438 icon: null,
462 link.lineNumber = lineNumber; 439 enableDecorator: false,
463 link.columnNumber = columnNumber; 440 uiLocation: null,
441 liveLocation: null,
442 url: href || null,
443 lineNumber: null,
444 columnNumber: null,
445 revealable: null,
446 fallback: null
447 };
448 link.addEventListener('click', Components.Linkifier._handleClick, false);
464 return link; 449 return link;
465 } 450 }
466 451
467 /** 452 /**
453 * @param {?Element} link
454 * @return {?Components._LinkInfo}
455 */
456 static _linkInfo(link) {
457 return /** @type {?Components._LinkInfo} */ ((link && link[Components.Linkif ier._infoSymbol]) || null);
lushnikov 2016/11/21 20:14:07 nit: we tend to not use '&&' in this way. return
dgozman 2016/11/21 22:37:47 Done.
458 }
459
460 /**
468 * @param {!Event} event 461 * @param {!Event} event
469 */ 462 */
470 static _handleClick(event) { 463 static _handleClick(event) {
471 var link = /** @type {!Element} */ (event.currentTarget); 464 var link = /** @type {!Element} */ (event.currentTarget);
472 event.consume(true); 465 event.consume(true);
473 if (link.preventFollow || UI.isBeingEdited(/** @type {!Node} */ (event.targe t))) 466 if (link.preventFollow || UI.isBeingEdited(/** @type {!Node} */ (event.targe t)))
474 return; 467 return;
475 if (Components.openAnchorLocationRegistry.dispatch({url: link.href, lineNumb er: link.lineNumber})) 468 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}))
476 return; 472 return;
473 if (info.url && Components.openAnchorLocationRegistry.dispatch({url: info.ur l, lineNumber: info.lineNumber}))
474 return;
475 if (info.revealable) {
476 Common.Revealer.reveal(info.revealable);
477 return;
478 }
477 var actions = Components.Linkifier._linkActions(link); 479 var actions = Components.Linkifier._linkActions(link);
478 if (actions.length) 480 if (actions.length)
479 actions[0].handler.call(null); 481 actions[0].handler.call(null);
480 } 482 }
481 483
482 /** 484 /**
483 * @param {?Element} link 485 * @param {?Element} link
484 * @return {!Array<{title: string, handler: function()}>} 486 * @return {!Array<{title: string, handler: function()}>}
485 */ 487 */
486 static _linkActions(link) { 488 static _linkActions(link) {
487 var url = null; 489 var info = Components.Linkifier._linkInfo(link);
490 if (info && info.revealable)
lushnikov 2016/11/21 20:14:07 let's not bail-out
dgozman 2016/11/21 22:37:47 Done.
491 return [];
492 var url = '';
488 var uiLocation = null; 493 var uiLocation = null;
489 var isLiveLink = false; 494 if (info && info.uiLocation) {
490 if (link && link[Components.Linkifier._uiLocationSymbol]) { 495 uiLocation = info.uiLocation;
491 uiLocation = /** @type {!Workspace.UILocation} */ (link[Components.Linkifi er._uiLocationSymbol]);
492 url = uiLocation.uiSourceCode.contentURL(); 496 url = uiLocation.uiSourceCode.contentURL();
493 isLiveLink = true; 497 } else if (info && info.url) {
494 } else if (link && link.href) { 498 url = info.url;
495 url = link.href;
496 var uiSourceCode = Workspace.workspace.uiSourceCodeForURL(url); 499 var uiSourceCode = Workspace.workspace.uiSourceCodeForURL(url);
497 uiLocation = uiSourceCode ? uiSourceCode.uiLocation(link.lineNumber || 0, link.columnNumber || 0) : null; 500 uiLocation = uiSourceCode ? uiSourceCode.uiLocation(info.lineNumber || 0, info.columnNumber || 0) : null;
498 isLiveLink = false;
499 } else { 501 } else {
500 return []; 502 return [];
501 } 503 }
502 504
503 var result = []; 505 var result = [];
504 if (uiLocation) 506 if (uiLocation)
505 result.push({title: Common.UIString('Open'), handler: () => Common.Reveale r.reveal(uiLocation)}); 507 result.push({title: Common.UIString('Open'), handler: () => Common.Reveale r.reveal(uiLocation)});
506 508
507 var resource = Bindings.resourceForURL(url); 509 var resource = Bindings.resourceForURL(url);
508 if (resource) { 510 if (resource) {
509 result.push({ 511 result.push({
510 title: Common.UIString.capitalize('Open ^link in Application ^panel'), 512 title: Common.UIString.capitalize('Open ^link in Application ^panel'),
511 handler: () => Common.Revealer.reveal(resource) 513 handler: () => Common.Revealer.reveal(resource)
512 }); 514 });
513 } 515 }
514 516
515 var request = SDK.NetworkLog.requestForURL(url); 517 var request = SDK.NetworkLog.requestForURL(url);
516 if (request) { 518 if (request) {
517 result.push({ 519 result.push({
518 title: Common.UIString.capitalize('Open ^request in Network ^panel'), 520 title: Common.UIString.capitalize('Open ^request in Network ^panel'),
519 handler: () => Common.Revealer.reveal(request) 521 handler: () => Common.Revealer.reveal(request)
520 }); 522 });
521 } 523 }
522 524
523 if (resource || !isLiveLink) { 525 if (resource || info.url) {
524 result.push({title: UI.openLinkExternallyLabel(), handler: () => Inspector FrontendHost.openInNewTab(url)}); 526 result.push({title: UI.openLinkExternallyLabel(), handler: () => Inspector FrontendHost.openInNewTab(url)});
525 result.push({title: UI.copyLinkAddressLabel(), handler: () => InspectorFro ntendHost.copyText(url)}); 527 result.push({title: UI.copyLinkAddressLabel(), handler: () => InspectorFro ntendHost.copyText(url)});
526 } 528 }
527 529
528 return result; 530 return result;
529 } 531 }
530 }; 532 };
531 533
532 /** @type {!Set<!Components.Linkifier>} */ 534 /** @type {!Set<!Components.Linkifier>} */
533 Components.Linkifier._instances = new Set(); 535 Components.Linkifier._instances = new Set();
534 /** @type {?Components.LinkDecorator} */ 536 /** @type {?Components.LinkDecorator} */
535 Components.Linkifier._decorator = null; 537 Components.Linkifier._decorator = null;
536 538
537 Components.Linkifier._iconSymbol = Symbol('Linkifier.iconSymbol');
538 Components.Linkifier._enableDecoratorSymbol = Symbol('Linkifier.enableIconsSymbo l');
539 Components.Linkifier._sourceCodeAnchors = Symbol('Linkifier.anchors'); 539 Components.Linkifier._sourceCodeAnchors = Symbol('Linkifier.anchors');
540 Components.Linkifier._uiLocationSymbol = Symbol('uiLocation'); 540 Components.Linkifier._infoSymbol = Symbol('Linkifier.info');
541 Components.Linkifier._fallbackAnchorSymbol = Symbol('fallbackAnchor'); 541
542 Components.Linkifier._liveLocationSymbol = Symbol('liveLocation'); 542 /**
543 Components.Linkifier._linkSymbol = Symbol('Linkifier.link'); 543 * @typedef {{
544 * icon: ?UI.Icon,
545 * enableDecorator: boolean,
546 * uiLocation: ?Workspace.UILocation,
547 * liveLocation: ?Bindings.LiveLocation,
548 * url: ?string,
549 * lineNumber: ?number,
550 * columnNumber: ?number,
551 * revealable: ?Object,
552 * fallback: ?Element
553 * }}
554 */
555 Components._LinkInfo;
544 556
545 /** 557 /**
546 * The maximum number of characters to display in a URL. 558 * The maximum number of characters to display in a URL.
547 * @const 559 * @const
548 * @type {number} 560 * @type {number}
549 */ 561 */
550 Components.Linkifier.MaxLengthForDisplayedURLs = 150; 562 Components.Linkifier.MaxLengthForDisplayedURLs = 150;
551 563
552 /** 564 /**
553 * The maximum length before strings are considered too long for finding URLs. 565 * 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 */ 665 */
654 Components.Linkifier.LinkContextMenuProvider = class { 666 Components.Linkifier.LinkContextMenuProvider = class {
655 /** 667 /**
656 * @override 668 * @override
657 * @param {!Event} event 669 * @param {!Event} event
658 * @param {!UI.ContextMenu} contextMenu 670 * @param {!UI.ContextMenu} contextMenu
659 * @param {!Object} target 671 * @param {!Object} target
660 */ 672 */
661 appendApplicableItems(event, contextMenu, target) { 673 appendApplicableItems(event, contextMenu, target) {
662 var targetNode = /** @type {!Node} */ (target); 674 var targetNode = /** @type {!Node} */ (target);
663 while (targetNode && !targetNode[Components.Linkifier._linkSymbol] && 675 while (targetNode && !targetNode[Components.Linkifier._infoSymbol])
664 !targetNode[Components.Linkifier._uiLocationSymbol])
665 targetNode = targetNode.parentNodeOrShadowHost(); 676 targetNode = targetNode.parentNodeOrShadowHost();
666 var link = /** @type {?Element} */ (targetNode); 677 var link = /** @type {?Element} */ (targetNode);
667 var actions = Components.Linkifier._linkActions(link); 678 var actions = Components.Linkifier._linkActions(link);
668 for (var action of actions) 679 for (var action of actions)
669 contextMenu.appendItem(action.title, action.handler); 680 contextMenu.appendItem(action.title, action.handler);
670 } 681 }
671 }; 682 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698