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

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

Issue 2644753002: DevTools: untruncate links on copy (Closed)
Patch Set: reset tests with zero width space Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 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 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 * @param {!Element} anchor 296 * @param {!Element} anchor
297 * @param {!Bindings.LiveLocation} liveLocation 297 * @param {!Bindings.LiveLocation} liveLocation
298 */ 298 */
299 _updateAnchor(anchor, liveLocation) { 299 _updateAnchor(anchor, liveLocation) {
300 Components.Linkifier._unbindUILocation(anchor); 300 Components.Linkifier._unbindUILocation(anchor);
301 var uiLocation = liveLocation.uiLocation(); 301 var uiLocation = liveLocation.uiLocation();
302 if (!uiLocation) 302 if (!uiLocation)
303 return; 303 return;
304 304
305 Components.Linkifier._bindUILocation(anchor, uiLocation); 305 Components.Linkifier._bindUILocation(anchor, uiLocation);
306 var text = uiLocation.linkText(); 306 var text = uiLocation.linkText(true /* skipTrim */);
307 var info = Components.Linkifier._linkInfo(anchor); 307 Components.Linkifier._setTrimmedText(anchor, text, true /* trimHashes */, th is._maxLength);
308 info.originalLinkText = text;
309 text = text.replace(/([a-f0-9]{7})[a-f0-9]{13}[a-f0-9]*/g, '$1\u2026');
310 if (this._maxLength)
311 text = text.trimMiddle(this._maxLength);
312 anchor.textContent = text;
313 308
314 var titleText = uiLocation.uiSourceCode.url(); 309 var titleText = uiLocation.uiSourceCode.url();
315 if (typeof uiLocation.lineNumber === 'number') 310 if (typeof uiLocation.lineNumber === 'number')
316 titleText += ':' + (uiLocation.lineNumber + 1); 311 titleText += ':' + (uiLocation.lineNumber + 1);
317 anchor.title = titleText; 312 anchor.title = titleText;
318 anchor.classList.toggle('webkit-html-blackbox-link', liveLocation.isBlackbox ed()); 313 anchor.classList.toggle('webkit-html-blackbox-link', liveLocation.isBlackbox ed());
319 Components.Linkifier._updateLinkDecorations(anchor); 314 Components.Linkifier._updateLinkDecorations(anchor);
320 } 315 }
321 316
322 /** 317 /**
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 * @param {boolean=} preventClick 384 * @param {boolean=} preventClick
390 * @returns{!Element} 385 * @returns{!Element}
391 */ 386 */
392 static _createLink(text, className, maxLength, title, href, preventClick) { 387 static _createLink(text, className, maxLength, title, href, preventClick) {
393 var link = createElementWithClass('span', className); 388 var link = createElementWithClass('span', className);
394 link.classList.add('devtools-link'); 389 link.classList.add('devtools-link');
395 if (title) 390 if (title)
396 link.title = title; 391 link.title = title;
397 if (href) 392 if (href)
398 link.href = href; 393 link.href = href;
399 link.textContent = text; 394 Components.Linkifier._setTrimmedText(link, text, false /* trimHashes */, max Length);
400 if (maxLength)
401 link.textContent = link.textContent.trimMiddle(maxLength);
402 link[Components.Linkifier._infoSymbol] = { 395 link[Components.Linkifier._infoSymbol] = {
403 icon: null, 396 icon: null,
404 enableDecorator: false, 397 enableDecorator: false,
405 uiLocation: null, 398 uiLocation: null,
406 liveLocation: null, 399 liveLocation: null,
407 url: href || null, 400 url: href || null,
408 lineNumber: null, 401 lineNumber: null,
409 columnNumber: null, 402 columnNumber: null,
410 revealable: null, 403 revealable: null,
411 fallback: null, 404 fallback: null
412 originalLinkText: text
413 }; 405 };
414 if (!preventClick) 406 if (!preventClick)
415 link.addEventListener('click', Components.Linkifier._handleClick, false); 407 link.addEventListener('click', Components.Linkifier._handleClick, false);
416 else 408 else
417 link.classList.add('devtools-link-prevent-click'); 409 link.classList.add('devtools-link-prevent-click');
418 return link; 410 return link;
419 } 411 }
420 412
421 /** 413 /**
422 * @param {?Element} link 414 * @param {!Element} link
423 * @return {?string} 415 * @param {string} text
416 * @param {boolean=} trimHashes
417 * @param {number=} maxLength
424 */ 418 */
425 static originalLinkText(link) { 419 static _setTrimmedText(link, text, trimHashes, maxLength) {
426 var info = this._linkInfo(link); 420 var middle = Math.floor(text.length / 2);
427 return info ? info.originalLinkText : null; 421 var hiddenIndices = maxLength ? (text.trimMiddleIndices(maxLength) || [middl e, middle]) : [middle, middle];
422
423 // Truncate from an earlier position if a hash pattern is starting, or a lat er position if a hash is ending.
424 if (trimHashes) {
lushnikov 2017/04/17 17:57:40 I don't quite follow what's going on here. I thoug
luoe 2017/04/17 22:15:07 That is correct. I'm trying to calculate the indi
425 var hashRegex = /[a-f0-9]{20,}/g;
426 var match = hashRegex.exec(text);
427 var visibleHashLength = 7;
428 while (match !== null) {
429 var hashLeftIndex = match.index + visibleHashLength;
430 var hashRightIndex = match.index + match[0].length - visibleHashLength;
431 if (hashLeftIndex < hiddenIndices[0])
432 hiddenIndices[0] = hashLeftIndex;
433 if (hashRightIndex > hiddenIndices[1])
434 hiddenIndices[1] = hashRightIndex;
435 match = hashRegex.exec(text);
436 }
437 }
438
439 if (hiddenIndices[0] !== hiddenIndices[1]) {
440 var leftText = text.substr(0, hiddenIndices[0]);
441 var hiddenText = text.substr(hiddenIndices[0], hiddenIndices[1] - hiddenIn dices[0]);
442 var rightText = text.substr(hiddenIndices[1], text.length - hiddenIndices[ 1]);
443 link.removeChildren();
444 link.createTextChild(leftText);
445 var ellipsisSpan = link.createChild('span', 'devtools-link-ellipsis');
446 var ellipsisTextNode = ellipsisSpan.createTextChild('\u200B');
447 ellipsisTextNode[Components.Linkifier._originalNodeTextSymbol] = hiddenTex t;
448 link.createTextChild(rightText);
449 } else {
450 link.textContent = text;
451 }
428 } 452 }
429 453
430 /** 454 /**
455 * @param {!Node} node
456 * @param {number} offset
457 * @return {number}
458 */
459 static selectionOffsetToOriginalTextOffset(node, offset) {
lushnikov 2017/04/17 17:57:40 you don't need this method anymore - let's inline
luoe 2017/04/17 22:15:07 Done, however inlining this still feels a little s
460 // Selecting an ellipsis text node with offset 1 should return the full orig inal text.
461 var originalText = node[Components.Linkifier._originalNodeTextSymbol];
462 if (originalText && offset === 1)
463 return originalText.length;
464 return offset;
465 }
466
467 /**
468 * @param {!Node} node
469 * @return {string}
470 */
471 static originalNodeText(node) {
lushnikov 2017/04/17 17:57:40 untruncatedNodeText
luoe 2017/04/17 22:15:07 Done.
472 return node[Components.Linkifier._originalNodeTextSymbol] || node.textConten t;
473 }
474
475 /**
431 * @param {?Element} link 476 * @param {?Element} link
432 * @return {?Components._LinkInfo} 477 * @return {?Components._LinkInfo}
433 */ 478 */
434 static _linkInfo(link) { 479 static _linkInfo(link) {
435 return /** @type {?Components._LinkInfo} */ (link ? link[Components.Linkifie r._infoSymbol] || null : null); 480 return /** @type {?Components._LinkInfo} */ (link ? link[Components.Linkifie r._infoSymbol] || null : null);
436 } 481 }
437 482
438 /** 483 /**
439 * @param {!Event} event 484 * @param {!Event} event
440 */ 485 */
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 } 587 }
543 }; 588 };
544 589
545 /** @type {!Set<!Components.Linkifier>} */ 590 /** @type {!Set<!Components.Linkifier>} */
546 Components.Linkifier._instances = new Set(); 591 Components.Linkifier._instances = new Set();
547 /** @type {?Components.LinkDecorator} */ 592 /** @type {?Components.LinkDecorator} */
548 Components.Linkifier._decorator = null; 593 Components.Linkifier._decorator = null;
549 594
550 Components.Linkifier._sourceCodeAnchors = Symbol('Linkifier.anchors'); 595 Components.Linkifier._sourceCodeAnchors = Symbol('Linkifier.anchors');
551 Components.Linkifier._infoSymbol = Symbol('Linkifier.info'); 596 Components.Linkifier._infoSymbol = Symbol('Linkifier.info');
597 Components.Linkifier._originalNodeTextSymbol = Symbol('Linkifier.originalNodeTex t');
552 598
553 /** 599 /**
554 * @typedef {{ 600 * @typedef {{
555 * icon: ?UI.Icon, 601 * icon: ?UI.Icon,
556 * enableDecorator: boolean, 602 * enableDecorator: boolean,
557 * uiLocation: ?Workspace.UILocation, 603 * uiLocation: ?Workspace.UILocation,
558 * liveLocation: ?Bindings.LiveLocation, 604 * liveLocation: ?Bindings.LiveLocation,
559 * url: ?string, 605 * url: ?string,
560 * lineNumber: ?number, 606 * lineNumber: ?number,
561 * columnNumber: ?number, 607 * columnNumber: ?number,
562 * revealable: ?Object, 608 * revealable: ?Object,
563 * fallback: ?Element, 609 * fallback: ?Element
564 * originalLinkText: string
565 * }} 610 * }}
566 */ 611 */
567 Components._LinkInfo; 612 Components._LinkInfo;
568 613
569 /** 614 /**
570 * The maximum length before strings are considered too long for finding URLs. 615 * The maximum length before strings are considered too long for finding URLs.
571 * @const 616 * @const
572 * @type {number} 617 * @type {number}
573 */ 618 */
574 Components.Linkifier.MaxLengthToIgnoreLinkifier = 10000; 619 Components.Linkifier.MaxLengthToIgnoreLinkifier = 10000;
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
780 contextMenu.appendSeparator(); 825 contextMenu.appendSeparator();
781 contextMenu.appendItem(Common.UIString('Save'), save.bind(null, false)); 826 contextMenu.appendItem(Common.UIString('Save'), save.bind(null, false));
782 827
783 if (contentProvider instanceof Workspace.UISourceCode) { 828 if (contentProvider instanceof Workspace.UISourceCode) {
784 var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (contentProvider ); 829 var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (contentProvider );
785 if (!uiSourceCode.project().canSetFileContent()) 830 if (!uiSourceCode.project().canSetFileContent())
786 contextMenu.appendItem(Common.UIString.capitalize('Save ^as...'), save.b ind(null, true)); 831 contextMenu.appendItem(Common.UIString.capitalize('Save ^as...'), save.b ind(null, true));
787 } 832 }
788 } 833 }
789 }; 834 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698