@nextcloud/vue
Version:
Nextcloud vue components
175 lines (174 loc) • 4.73 kB
JavaScript
import { n as normalizeComponent } from "./_plugin-vue2_normalizer-DU4iP6Vu.mjs";
const FindRanges = (text, search) => {
const ranges = [];
let currentIndex = 0;
let index = text.toLowerCase().indexOf(search.toLowerCase(), currentIndex);
let i = 0;
while (index > -1 && i < text.length) {
currentIndex = index + search.length;
ranges.push({ start: index, end: currentIndex });
index = text.toLowerCase().indexOf(search.toLowerCase(), currentIndex);
i++;
}
return ranges;
};
const _sfc_main = {
name: "NcHighlight",
props: {
/**
* The string to display
*/
text: {
type: String,
default: ""
},
/**
* The string to match and highlight
*/
search: {
type: String,
default: ""
},
/**
* The ranges to highlight, takes precedence over the search prop.
*/
highlight: {
type: Array,
default: () => []
}
},
computed: {
/**
* The indice ranges which should be highlighted.
* If an array with ranges is provided, we use it. Otherwise
* we calculate it based on the provided substring to highlight.
*
* @return {Array} The array of ranges to highlight
*/
ranges() {
let ranges = [];
if (!this.search && this.highlight.length === 0) {
return ranges;
}
if (this.highlight.length > 0) {
ranges = this.highlight;
} else {
ranges = FindRanges(this.text, this.search);
}
ranges.forEach((range, i) => {
if (range.end < range.start) {
ranges[i] = {
start: range.end,
end: range.start
};
}
});
ranges = ranges.reduce((validRanges, range) => {
if (range.start < this.text.length && range.end > 0) {
validRanges.push({
start: range.start < 0 ? 0 : range.start,
end: range.end > this.text.length ? this.text.length : range.end
});
}
return validRanges;
}, []);
ranges.sort((a, b) => {
return a.start - b.start;
});
ranges = ranges.reduce((mergedRanges, range) => {
if (!mergedRanges.length) {
mergedRanges.push(range);
} else {
const idx = mergedRanges.length - 1;
if (mergedRanges[idx].end >= range.start) {
mergedRanges[idx] = {
start: mergedRanges[idx].start,
end: Math.max(mergedRanges[idx].end, range.end)
};
} else {
mergedRanges.push(range);
}
}
return mergedRanges;
}, []);
return ranges;
},
/**
* Calculate the different chunks to show based on the ranges to highlight.
*
* @return {Array} The chunks
*/
chunks() {
if (this.ranges.length === 0) {
return [{
start: 0,
end: this.text.length,
highlight: false,
text: this.text
}];
}
const chunks = [];
let currentIndex = 0;
let currentRange = 0;
while (currentIndex < this.text.length) {
const range = this.ranges[currentRange];
if (range.start === currentIndex) {
chunks.push({
...range,
highlight: true,
text: this.text.slice(range.start, range.end)
});
currentRange++;
currentIndex = range.end;
if (currentRange >= this.ranges.length && currentIndex < this.text.length) {
chunks.push({
start: currentIndex,
end: this.text.length,
highlight: false,
text: this.text.slice(currentIndex)
});
currentIndex = this.text.length;
}
continue;
}
chunks.push({
start: currentIndex,
end: range.start,
highlight: false,
text: this.text.slice(currentIndex, range.start)
});
currentIndex = range.start;
}
return chunks;
}
},
/**
* The render function to display the component
*
* @param {Function} h The function to create VNodes
* @return {object} The created VNode
*/
render(h) {
if (!this.ranges.length) {
return h("span", {}, this.text);
}
return h("span", {}, this.chunks.map((chunk) => {
return chunk.highlight ? h("strong", {}, chunk.text) : chunk.text;
}));
}
};
const _sfc_render = null;
const _sfc_staticRenderFns = null;
var __component__ = /* @__PURE__ */ normalizeComponent(
_sfc_main,
_sfc_render,
_sfc_staticRenderFns,
false,
null,
null
);
const NcHighlight = __component__.exports;
export {
FindRanges as F,
NcHighlight as N
};