UNPKG

au-text-highlight

Version:

3行代码实现划词相关功能、关键字高亮、选区检测等功能。附带React版本划词popover组件。专为解决划词翻译,划词评论,web文本高亮等这类需求!目前再探索完善。

2 lines (1 loc) 8.91 kB
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("react/jsx-runtime"),require("react"),require("react-dom")):"function"==typeof define&&define.amd?define(["exports","react/jsx-runtime","react","react-dom"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).AuTextHighlight={},t.jsxRuntime,t.React,t.ReactDOM)}(this,(function(t,e,n,o){"use strict";var i=function(t,e){return i=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n])},i(t,e)};var r=function(){return r=Object.assign||function(t){for(var e,n=1,o=arguments.length;n<o;n++)for(var i in e=arguments[n])Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},r.apply(this,arguments)};"function"==typeof SuppressedError&&SuppressedError;var l=0;function u(t,e){for(var n,o=function(t){var e=function(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")};if("string"==typeof t)return new RegExp("".concat(e(t)),"gi");if(Array.isArray(t)){var n=t.map(e);return new RegExp("(".concat(n.join("|"),")"),"gi")}}(e),i=[];null!==(n=o.exec(t));)i.push({keyword:n[0],start:n.index,end:n.index+n[0].length});return i}var c=function(t){function e(e,n){return void 0===n&&(n={}),t.call(this,e,n)||this}return function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Class extends value "+String(e)+" is not a constructor or null");function n(){this.constructor=t}i(t,e),t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)}(e,t),e}(function(){function t(t,e){var n;void 0===e&&(e={}),this.popoverEle=null,this.distance=5,this.distance=null!==(n=null==e?void 0:e.distance)&&void 0!==n?n:this.distance,this.init(t),this.initEvent()}return t.prototype.init=function(t){var e=document.getElementById(t);if(!e)throw new Error("popoverId is not found");this.popoverEle=e,this.popoverEle.style.visibility="hidden",this.popoverEle.style.display="none",this.popoverEle.style.position="fixed",document.body.appendChild(this.popoverEle)},t.prototype.initEvent=function(){var t=this;document.addEventListener("mouseup",(function(){setTimeout((function(){var e=t.getTriggerPosition();e?t.show(e):t.hide()}),100)}))},t.prototype.show=function(t){var e=t.x,n=void 0===e?0:e,o=t.y,i=void 0===o?0:o,r=t.width,l=void 0===r?0:r;if(this.popoverEle){var u=n+l/2-this.popoverEle.offsetWidth/2,c=i-this.popoverEle.offsetHeight-this.distance;t.height>30&&(u=n+l-this.popoverEle.offsetWidth),this.popoverEle.style.left="".concat(u,"px"),this.popoverEle.style.top="".concat(c,"px"),this.popoverEle.style.display="block",this.popoverEle.style.visibility="visible"}},t.prototype.hide=function(){this.popoverEle&&(this.popoverEle.style.display="none",this.popoverEle.style.visibility="hidden")},t.prototype.getTriggerPosition=function(){var t,e=document.getSelection();if(e){var n=null===(t=document.getSelection())||void 0===t?void 0:t.toString();if(n){var o=e.getRangeAt(0).getBoundingClientRect();return 0===o.width&&0===o.height?null:{text:n,x:o.left+window.scrollX,y:o.top+window.scrollY,width:o.width,height:o.height}}return null}console.error("no selection")},t}());function s(t){void 0===t&&(t={});var e=t.delay,o=void 0===e?100:e,i=t.container,r=t.selectionChange,l=n.useState(null),u=l[0],c=l[1],s=n.useState(!1),a=s[0],d=s[1],f=n.useCallback((function(){var t=document.getSelection();if(!t)return null;var e=t.toString();if(!e)return null;if(i)try{var n=t.getRangeAt(0);if(!i.contains(n.startContainer)||!i.contains(n.endContainer))return null}catch(t){return null}try{var o=(n=t.getRangeAt(0)).getBoundingClientRect();return 0===o.width&&0===o.height?null:{text:e,x:o.left,y:o.top,width:o.width,height:o.height}}catch(t){return console.error("获取选区位置失败:",t),null}}),[i]),v=n.useCallback((function(){c(null),d(!1),null==r||r(null)}),[r]),p=n.useCallback((function(){d(!0),c(null),null==r||r(null)}),[r]),h=n.useCallback((function(){setTimeout((function(){var t=f();t?(c(t),null==r||r(t)):(c(null),null==r||r(null)),d(!1)}),o)}),[f,o,r]),g=n.useCallback((function(){a||(f()||(c(null),null==r||r(null)))}),[f,a,r]);return n.useEffect((function(){var t=i||document;return t.addEventListener("mousedown",p),t.addEventListener("mouseup",h),document.addEventListener("selectionchange",g),function(){t.removeEventListener("mousedown",p),t.removeEventListener("mouseup",h),document.removeEventListener("selectionchange",g)}}),[i,p,h,g]),{selection:u,isSelecting:a,clearSelection:v,getTriggerPosition:f}}t.DrawWordConstituencyPopover=c,t.ReactAuSelectionPopover=function(t){var i,l,u=t.children,c=t.distance,a=void 0===c?10:c,d=t.className,f=void 0===d?"":d,v=t.style,p=void 0===v?{}:v,h=t.container,g=t.onShow,y=t.onHide,m=t.disabled,w=void 0!==m&&m,E=t.zIndex,x=void 0===E?9999:E,b=t.portal,C=void 0===b||b,S=n.useRef(null),R=n.useState(!1),A=R[0],T=R[1],L=n.useState({}),j=L[0],k=L[1],O=n.useCallback((function(t){if(!S.current)return{};var e=t.x,n=t.y,o=t.width,i=t.height,r=S.current.getBoundingClientRect(),l=e+o/2-r.width/2,u=n-r.height-a,c=window.innerWidth,s=window.scrollX,d=window.scrollY;return l<s?l=s+8:l+r.width>s+c&&(l=s+c-r.width-8),u<d&&(u=n+i+a),i>30&&(l=e+o-r.width)+r.width>s+c&&(l=s+c-r.width-8),{position:"fixed",left:"".concat(l,"px"),top:"".concat(u,"px"),zIndex:x,opacity:1,visibility:"visible",transform:"translateY(0)",transition:"opacity 0.2s ease, transform 0.2s ease"}}),[a,x]),N=s({delay:100,container:h,selectionChange:n.useCallback((function(t){if(w)T(!1);else if(t){var e=O(t);k(e),T(!0),null==g||g(t)}else T(!1),k((function(t){return r(r({},t),{opacity:0,visibility:"hidden",transform:"translateY(-4px)"})})),null==y||y()}),[w,O,g,y])}),P=N.selection,_=N.clearSelection,D=N.getTriggerPosition;n.useEffect((function(){var t=function(t){A&&S.current&&!S.current.contains(t.target)&&_()};return document.addEventListener("mousedown",t),function(){document.removeEventListener("mousedown",t)}}),[A,_]),n.useEffect((function(){if(A&&P){var t,e,n,o,i=(t=function(){var t=D();if(t){var e=O(t);k(e)}},e=50,n=null,o=0,function(){for(var i=[],r=0;r<arguments.length;r++)i[r]=arguments[r];var l=Date.now();if(l-o>e)return o=l,t.apply(void 0,i);n&&clearTimeout(n),n=window.setTimeout((function(){o=Date.now(),t.apply(void 0,i),n=null}),e-(l-o))});return window.addEventListener("resize",i),window.addEventListener("scroll",i),function(){window.removeEventListener("resize",i),window.removeEventListener("scroll",i)}}}),[A,P,O]);var z=e.jsx("div",{ref:S,className:"au-text-highlight-popover ".concat(f),style:r(r(r({},j),p),{position:j.position||"fixed",pointerEvents:A?"auto":"none",userSelect:"none",opacity:null!==(i=j.opacity)&&void 0!==i?i:0,visibility:null!==(l=j.visibility)&&void 0!==l?l:"hidden"}),children:u});return C?o.createPortal(z,document.body):z},t.auExtractText=function(t){return u(t.text,t.keywords)},t.getSelectionRange=function(t,e){l=0;var n=document.getSelection(),o=n.getRangeAt(0);!function(t,e,n){var o=1e3,i=[],r=t.childNodes,u=function(t,e){if(void 0===e&&(e=0),e>o)throw new Error("DOM tree is too deep");for(var n=0;n<t.length;n++){var r=t[n];r.textContent&&("#text"===r.nodeName?i.push(r):u(r.childNodes,e+1))}};u(r),i.length>0&&i.some((function(t){return t.textContent===e.textContent?(l+=n,!0):(t.textContent&&(l+=t.textContent.length),!1)}))}(t,o.startContainer,o.startOffset);var i=l+n.toString().trim().length;return[l,i]},t.getSelectionRangeContent=function(){if(document){var t=null===document||void 0===document?void 0:document.getSelection();if(t)return{content:t.toString(),section:t};throw new Error("selection is undefined")}throw new Error("document is undefined")},t.sectionRangeHighlight=function(t,e){var n=null===document||void 0===document?void 0:document.getSelection();if(!n)throw new Error("No selection found");n.removeAllRanges(),e.forEach((function(e){var n=e.start,o=e.end,i=e.gid,r=void 0===i?"":i,l=function(t,e,n){void 0===e&&(e=0);void 0===n&&(n=0);var o=[],i=function(t){(function(t,e,n){if(n||2===arguments.length)for(var o,i=0,r=e.length;i<r;i++)!o&&i in e||(o||(o=Array.prototype.slice.call(e,0,i)),o[i]=e[i]);return t.concat(o||Array.prototype.slice.call(e))})([],t,!0).forEach((function(t){"#text"===t.nodeName?o.push(t):t.textContent&&i(t.childNodes)}))};i(t.childNodes);var r=null,l=0,u=null,c=0,s=l;if(o.forEach((function(t){if(!r||!u){var o=t.textContent.length,i=[s,s+o];!r&&e>=i[0]&&e<i[1]&&(r=t,l=e-i[0]),!u&&n>i[0]&&n<=i[1]&&(u=t,c=n-i[0]),s+=o}})),!r||!u)return null;return[r,l,u,c]}(t,n,o),u=l[0],c=l[1],s=l[2],a=l[3],d=document.createRange();d.setStart(u,c),d.setEnd(s,a);var f=document.createElement("span");f.setAttribute("role","text"),f.setAttribute("aria-label","高亮内容"),f.className="word_comment_mark",r&&f.setAttribute("id",r);try{d.surroundContents(f)}catch(t){console.error("存在不可高亮的元素,多半由于选区交叉导致")}}))},t.useTextSelection=s}));