b5dc05156a0e1239823014e40160a25bcfeadd3905b64f98e6521dedcd5a07a225e8e7b4989c5bd81039efdc9c33451182f1c3ff3f56ec6558ec481d946861 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. import * as dom from '../../dom.js';
  6. import { renderLabelWithIcons } from '../iconLabel/iconLabels.js';
  7. import * as objects from '../../../common/objects.js';
  8. /**
  9. * A widget which can render a label with substring highlights, often
  10. * originating from a filter function like the fuzzy matcher.
  11. */
  12. export class HighlightedLabel {
  13. /**
  14. * Create a new {@link HighlightedLabel}.
  15. *
  16. * @param container The parent container to append to.
  17. */
  18. constructor(container, options) {
  19. var _a;
  20. this.text = '';
  21. this.title = '';
  22. this.highlights = [];
  23. this.didEverRender = false;
  24. this.supportIcons = (_a = options === null || options === void 0 ? void 0 : options.supportIcons) !== null && _a !== void 0 ? _a : false;
  25. this.domNode = dom.append(container, dom.$('span.monaco-highlighted-label'));
  26. }
  27. /**
  28. * The label's DOM node.
  29. */
  30. get element() {
  31. return this.domNode;
  32. }
  33. /**
  34. * Set the label and highlights.
  35. *
  36. * @param text The label to display.
  37. * @param highlights The ranges to highlight.
  38. * @param title An optional title for the hover tooltip.
  39. * @param escapeNewLines Whether to escape new lines.
  40. * @returns
  41. */
  42. set(text, highlights = [], title = '', escapeNewLines) {
  43. if (!text) {
  44. text = '';
  45. }
  46. if (escapeNewLines) {
  47. // adjusts highlights inplace
  48. text = HighlightedLabel.escapeNewLines(text, highlights);
  49. }
  50. if (this.didEverRender && this.text === text && this.title === title && objects.equals(this.highlights, highlights)) {
  51. return;
  52. }
  53. this.text = text;
  54. this.title = title;
  55. this.highlights = highlights;
  56. this.render();
  57. }
  58. render() {
  59. const children = [];
  60. let pos = 0;
  61. for (const highlight of this.highlights) {
  62. if (highlight.end === highlight.start) {
  63. continue;
  64. }
  65. if (pos < highlight.start) {
  66. const substring = this.text.substring(pos, highlight.start);
  67. children.push(dom.$('span', undefined, ...this.supportIcons ? renderLabelWithIcons(substring) : [substring]));
  68. pos = highlight.end;
  69. }
  70. const substring = this.text.substring(highlight.start, highlight.end);
  71. const element = dom.$('span.highlight', undefined, ...this.supportIcons ? renderLabelWithIcons(substring) : [substring]);
  72. if (highlight.extraClasses) {
  73. element.classList.add(...highlight.extraClasses);
  74. }
  75. children.push(element);
  76. pos = highlight.end;
  77. }
  78. if (pos < this.text.length) {
  79. const substring = this.text.substring(pos);
  80. children.push(dom.$('span', undefined, ...this.supportIcons ? renderLabelWithIcons(substring) : [substring]));
  81. }
  82. dom.reset(this.domNode, ...children);
  83. if (this.title) {
  84. this.domNode.title = this.title;
  85. }
  86. else {
  87. this.domNode.removeAttribute('title');
  88. }
  89. this.didEverRender = true;
  90. }
  91. static escapeNewLines(text, highlights) {
  92. let total = 0;
  93. let extra = 0;
  94. return text.replace(/\r\n|\r|\n/g, (match, offset) => {
  95. extra = match === '\r\n' ? -1 : 0;
  96. offset += total;
  97. for (const highlight of highlights) {
  98. if (highlight.end <= offset) {
  99. continue;
  100. }
  101. if (highlight.start >= offset) {
  102. highlight.start += extra;
  103. }
  104. if (highlight.end >= offset) {
  105. highlight.end += extra;
  106. }
  107. }
  108. total += extra;
  109. return '\u23CE';
  110. });
  111. }
  112. }