au-text-highlight
Version:
3行代码实现划词相关功能、关键字高亮、选区检测等功能。附带React版本划词popover组件。专为解决划词翻译,划词评论,web文本高亮等这类需求!目前再探索完善。
2 lines (1 loc) • 8.64 kB
JavaScript
;var t=require("react/jsx-runtime"),e=require("react"),n=require("react-dom"),o=function(t,e){return o=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])},o(t,e)};var i=function(){return i=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},i.apply(this,arguments)};"function"==typeof SuppressedError&&SuppressedError;var r=0;function l(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 u=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}o(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 c(t){void 0===t&&(t={});var n=t.delay,o=void 0===n?100:n,i=t.container,r=t.selectionChange,l=e.useState(null),u=l[0],c=l[1],s=e.useState(!1),a=s[0],d=s[1],v=e.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]),p=e.useCallback((function(){c(null),d(!1),null==r||r(null)}),[r]),f=e.useCallback((function(){d(!0),c(null),null==r||r(null)}),[r]),h=e.useCallback((function(){setTimeout((function(){var t=v();t?(c(t),null==r||r(t)):(c(null),null==r||r(null)),d(!1)}),o)}),[v,o,r]),g=e.useCallback((function(){a||(v()||(c(null),null==r||r(null)))}),[v,a,r]);return e.useEffect((function(){var t=i||document;return t.addEventListener("mousedown",f),t.addEventListener("mouseup",h),document.addEventListener("selectionchange",g),function(){t.removeEventListener("mousedown",f),t.removeEventListener("mouseup",h),document.removeEventListener("selectionchange",g)}}),[i,f,h,g]),{selection:u,isSelecting:a,clearSelection:p,getTriggerPosition:v}}exports.DrawWordConstituencyPopover=u,exports.ReactAuSelectionPopover=function(o){var r,l,u=o.children,s=o.distance,a=void 0===s?10:s,d=o.className,v=void 0===d?"":d,p=o.style,f=void 0===p?{}:p,h=o.container,g=o.onShow,y=o.onHide,w=o.disabled,m=void 0!==w&&w,E=o.zIndex,x=void 0===E?9999:E,b=o.portal,C=void 0===b||b,S=e.useRef(null),R=e.useState(!1),A=R[0],L=R[1],k=e.useState({}),T=k[0],N=k[1],O=e.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]),P=c({delay:100,container:h,selectionChange:e.useCallback((function(t){if(m)L(!1);else if(t){var e=O(t);N(e),L(!0),null==g||g(t)}else L(!1),N((function(t){return i(i({},t),{opacity:0,visibility:"hidden",transform:"translateY(-4px)"})})),null==y||y()}),[m,O,g,y])}),_=P.selection,j=P.clearSelection,z=P.getTriggerPosition;e.useEffect((function(){var t=function(t){A&&S.current&&!S.current.contains(t.target)&&j()};return document.addEventListener("mousedown",t),function(){document.removeEventListener("mousedown",t)}}),[A,j]),e.useEffect((function(){if(A&&_){var t,e,n,o,i=(t=function(){var t=z();if(t){var e=O(t);N(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,_,O]);var B=t.jsx("div",{ref:S,className:"au-text-highlight-popover ".concat(v),style:i(i(i({},T),f),{position:T.position||"fixed",pointerEvents:A?"auto":"none",userSelect:"none",opacity:null!==(r=T.opacity)&&void 0!==r?r:0,visibility:null!==(l=T.visibility)&&void 0!==l?l:"hidden"}),children:u});return C?n.createPortal(B,document.body):B},exports.auExtractText=function(t){return l(t.text,t.keywords)},exports.getSelectionRange=function(t,e){r=0;var n=document.getSelection(),o=n.getRangeAt(0);!function(t,e,n){var o=1e3,i=[],l=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(l),i.length>0&&i.some((function(t){return t.textContent===e.textContent?(r+=n,!0):(t.textContent&&(r+=t.textContent.length),!1)}))}(t,o.startContainer,o.startOffset);var i=r+n.toString().trim().length;return[r,i]},exports.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")},exports.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 v=document.createElement("span");v.setAttribute("role","text"),v.setAttribute("aria-label","高亮内容"),v.className="word_comment_mark",r&&v.setAttribute("id",r);try{d.surroundContents(v)}catch(t){console.error("存在不可高亮的元素,多半由于选区交叉导致")}}))},exports.useTextSelection=c;