UNPKG

igniteui-webcomponents

Version:

Ignite UI for Web Components is a complete library of UI components, giving you the ability to build modern web applications using encapsulation and the concept of reusable components in a dependency-free approach.

132 lines 4.35 kB
import { isServer } from 'lit'; import { escapeRegex, iterNodes, nanoid, scrollIntoView, wrap, } from '../common/util.js'; function* matchText(nodes, regexp) { for (const node of nodes) { if (node.textContent) { for (const match of node.textContent.matchAll(regexp)) { const [start, end] = match.indices[0]; yield { node, indices: [start, end] }; } } } } class HighlightService { get size() { return this._ranges.length; } get current() { return this._current; } constructor(host) { this._ranges = []; this._current = 0; this._host = host; this._host.addController(this); this._id = `igc-highlight-${nanoid()}`; this._activeId = `${this._id}-active`; this._styles = ` ::highlight(${this._id}) { background-color: var(--background, var(--ig-secondary-700)); color: var(--foreground, var(--ig-secondary-700-contrast)); } ::highlight(${this._activeId}) { background-color: var(--background-active, var(--ig-primary-500)); color: var(--foreground-active, var(--ig-primary-500-contrast)); }`; if (!isServer) { this._styleSheet = new CSSStyleSheet(); this._styleSheet.replaceSync(this._styles); } } hostConnected() { this._createHighlightEntries(); this.find(this._host.searchText); } hostDisconnected() { this._removeHighlightEntries(); this._removeStyleSheet(); } _removeStyleSheet() { const root = this._host.renderRoot; if (this._styleSheet) { root.adoptedStyleSheets = root.adoptedStyleSheets.filter((sheet) => sheet !== this._styleSheet); } } _createHighlightEntries() { this._highlight = new Highlight(); this._highlight.priority = 0; this._activeHighlight = new Highlight(); this._activeHighlight.priority = 1; CSS.highlights.set(this._id, this._highlight); CSS.highlights.set(this._activeId, this._activeHighlight); } _removeHighlightEntries() { CSS.highlights.delete(this._id); CSS.highlights.delete(this._activeId); this._ranges.length = 0; } _createRegex(value) { return new RegExp(escapeRegex(value), this._host.caseSensitive ? 'dg' : 'dgi'); } _updateActiveHighlight() { if (this.size) { this._activeHighlight.clear(); this._activeHighlight.add(this._ranges[this._current]); } } _goTo(index, options) { if (!this.size) { return; } this._current = wrap(0, this.size - 1, index); const range = this._ranges[this._current]; this._activeHighlight.clear(); this._activeHighlight.add(range); if (!options?.preventScroll) { scrollIntoView(range.commonAncestorContainer.parentElement, { block: 'center', inline: 'center', }); } } attachStylesheet() { const adoptedSheets = this._host.renderRoot .adoptedStyleSheets; if (this._styleSheet && !adoptedSheets.includes(this._styleSheet)) { adoptedSheets.push(this._styleSheet); } } find(value) { if (!value?.trim()) { return; } const iterator = matchText(iterNodes(this._host, { show: 'SHOW_TEXT' }), this._createRegex(value)); for (const { node, indices: [start, end], } of iterator) { const range = new Range(); range.setStart(node, start); range.setEnd(node, end); this._ranges.push(range); this._highlight.add(range); } this._updateActiveHighlight(); } next(options) { this._goTo(this._current + 1, options); } previous(options) { this._goTo(this._current - 1, options); } setActive(index, options) { this._goTo(index, options); } clear() { this._activeHighlight.clear(); this._highlight.clear(); this._ranges.length = 0; this._current = 0; } } export function createHighlightController(host) { return new HighlightService(host); } //# sourceMappingURL=service.js.map