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 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 }; |
| OLD | NEW |