UNPKG

react-highlight-search

Version:

Text highlight with deep search through DOM elements.

2 lines (1 loc) 3.02 kB
var e=require("react");const t=(e,t,n,o)=>{var r,l;let s=0,a=0,d=-1,i=-1,c=0,u=0;for(let h=0;h<e.length&&(a=s+((null===(l=null===(r=e[h])||void 0===r?void 0:r.textContent)||void 0===l?void 0:l.length)||1)-1,t>=s&&t<=a&&(d=h,c=t-s),n>=s&&n<=a&&(i=h,u=n-s+1),d!==h&&i!==h||o({index:h,node:e[h],startPos:d===h?c:0,endPos:i===h?u:a+1}),s=a+1,!(i>-1));h++);};!function(e,t){void 0===t&&(t={});var n=t.insertAt;if("undefined"!=typeof document){var o=document.head||document.getElementsByTagName("head")[0],r=document.createElement("style");r.type="text/css","top"===n&&o.firstChild?o.insertBefore(r,o.firstChild):o.appendChild(r),r.styleSheet?r.styleSheet.cssText=e:r.appendChild(document.createTextNode(e))}}(".hlsearch-span-el{background-color:#7ec9ff}");var n=e.memo((({searchString:n,setTriggerSearch:o,searchMinLength:r=1,onMatchData:l,children:s,spanClassName:a="hlsearch-span-el",ignoreCase:d=!0,index:i=0})=>{const c=e.useRef(null),u=e.useRef(null),[h,f]=e.useState(),p=function(t){const n=e.useRef();return e.useEffect((()=>{n.current=t}),[t]),n.current}(n),v=e.useCallback((e=>{null==l||l({wrapperIndex:i,matchesFound:e,matchParentElement:e?c.current:null})}),[i,l]),m=e.useCallback((e=>{var n,o;if(v(0),void 0!==(o=h)&&o.forEach((({newNodes:e,oldNode:t,parentNode:n})=>{const o=e[e.length-1].nextSibling||null;null==n||n.insertBefore(t,o),e.forEach((e=>{e.remove()}))})),(null==e?void 0:e.length)<(r>0?r:1))return void f(void 0);const l=[],s=e=>{null==e||e.forEach((e=>{e.nodeType===e.ELEMENT_NODE?s(e.childNodes):e.nodeType===e.TEXT_NODE&&l.push(e)}))};if(s(null===(n=u.current)||void 0===n?void 0:n.childNodes),!l.length)return;let i="";l.forEach((e=>{i+=e.textContent}));const c=new RegExp(e,d?"ig":"g"),p=i.matchAll(c);let m=0;const{matchData:E,matchDataController:g}=(()=>{const e=[];return{matchData:e,matchDataController:({index:t,node:n,startPos:o,endPos:r})=>{var l;e[t]?null===(l=e[t].positionsArr)||void 0===l||l.push({startPos:o,endPos:r}):e[t]={node:n,positionsArr:[{startPos:o,endPos:r}]}}}})();for(const e of p){if(void 0===e.index)return;m++,t(l,e.index,e.index+e[0].length-1,g)}v(m),((e,t,n)=>{const o=[];e.forEach((({node:e,positionsArr:t})=>{const r=e.parentNode,l=e.nextSibling||null,s=e.textContent,a=[],d=[];t.forEach((({startPos:e,endPos:n},o)=>{var r;e!==n&&(o<1&&a.push((null==s?void 0:s.slice(0,e))||""),a.push((null==s?void 0:s.slice(e,n))||""),a.push((null==s?void 0:s.slice(n,(null===(r=t[o+1])||void 0===r?void 0:r.startPos)||s.length))||""))})),e.remove(),a.forEach(((e,t)=>{if(e){let o=document.createTextNode(e);if(t%2!=0){const e=document.createElement("span");n&&e.classList.add(n),e.appendChild(o),d.push(e),null==r||r.insertBefore(e,l)}else d.push(o),null==r||r.insertBefore(o,l)}})),o.push({newNodes:d,oldNode:e,parentNode:r})})),t(o)})(E,f,a)}),[d,h,r,v,a]);return e.useEffect((()=>{void 0!==n&&n!==p&&m(n)}),[p,n,m]),e.useEffect((()=>{null==o||o((()=>e=>m(e)))}),[o,m]),e.createElement("div",{ref:c},e.createElement("div",{ref:u},s))}));exports.HighlightSearchWrapper=n;