@editora/plugins
Advanced tools
| "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const w=".rte-content, .editora-content",F="[data-editora-editor], .rte-editor, .editora-editor, editora-editor",ee="__editoraCommandEditorRoot",te="rte-approval-workflow-styles",d="rte-approval-panel",h="approval",y="approvalWorkflow",g=':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)',ue={panelTitle:"Approval Workflow",panelAriaLabel:"Approval workflow panel",statusLabel:"Status",statusDraftText:"Draft",statusReviewText:"In Review",statusApprovedText:"Approved",requestReviewText:"Request Review",approveText:"Approve",reopenDraftText:"Reopen Draft",addCommentText:"Add Comment",actorLabel:"Actor",actorPlaceholder:"Reviewer name",commentLabel:"Comment",commentPlaceholder:"Add review note or sign-off context",closeText:"Close",commentsHeading:"Comments",signoffsHeading:"Sign-offs",noCommentsText:"No comments yet.",noSignoffsText:"No sign-offs yet.",summaryPrefix:"Workflow",lockedSuffix:"Locked",shortcutText:"Shortcuts: Ctrl/Cmd+Alt+Shift+A/R/P/D",approveCommentRequiredText:"Approval comment is required."},fe={draft:"statusDraftText",review:"statusReviewText",approved:"statusApprovedText"},s=new WeakMap,I=new WeakMap,k=new Map,O=new WeakMap,H=new Set;let _=0,me=0,oe=0,re=0,R=null,v=null,T=null,L=null,S=null;function p(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function be(e){return e.replace(/\u00A0/g," ").replace(/\s+/g," ").trim()}function ne(e){return e==="review"||e==="approved"?e:"draft"}function z(e={}){return{defaultStatus:ne(e.defaultStatus),lockOnApproval:e.lockOnApproval!==!1,maxHistoryEntries:Math.max(10,Math.min(500,Number(e.maxHistoryEntries??120))),requireCommentOnApprove:!!e.requireCommentOnApprove,defaultActor:(e.defaultActor||"system").trim()||"system",labels:{...ue,...e.labels||{}},normalizeText:e.normalizeText||be}}function U(e){return e.closest(F)||e}function B(e){if(!e)return null;if(e.matches(w))return e;const t=e.querySelector(w);return t instanceof HTMLElement?t:null}function ge(){if(typeof window>"u")return null;const e=window[ee];if(!(e instanceof HTMLElement))return null;window[ee]=null;const t=B(e);if(t)return t;const o=e.closest(F);if(o){const n=B(o);if(n)return n}return null}function ve(e){const t=e.closest("[data-editora-editor]");if(t&&B(t)===e)return t;let o=e;for(;o;){if(o.matches(F)&&(o===e||B(o)===e))return o;o=o.parentElement}return U(e)}function W(e){return e?(e.getAttribute("data-theme")||e.getAttribute("theme")||"").toLowerCase()==="dark"?!0:e.classList.contains("dark")||e.classList.contains("editora-theme-dark")||e.classList.contains("rte-theme-dark"):!1}function he(e){const t=U(e);if(W(t))return!0;const o=t.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark");return W(o)?!0:W(document.documentElement)||W(document.body)}function K(e,t){e.classList.remove("rte-approval-theme-dark"),he(t)&&e.classList.add("rte-approval-theme-dark")}function le(e){return e?e.nodeType===Node.ELEMENT_NODE?e:e.parentElement:null}function x(e,t=!0){if(D(),e?.contentElement instanceof HTMLElement)return e.contentElement;if(e?.editorElement instanceof HTMLElement){const a=e.editorElement;if(a.matches(w))return a;const l=a.querySelector(w);if(l instanceof HTMLElement)return l}const o=ge();if(o)return o;const n=window.getSelection();if(n&&n.rangeCount>0){const l=le(n.getRangeAt(0).startContainer)?.closest(w);if(l)return l}const r=document.activeElement;if(r){if(r.matches(w))return r;const a=r.closest(w);if(a)return a}return v&&v.isConnected?v:(v&&!v.isConnected&&(v=null),t?document.querySelector(w):null)}function D(){Array.from(H).forEach(t=>{t.isConnected||(k.get(t)?.remove(),k.delete(t),O.delete(t),s.delete(t),I.delete(t),H.delete(t),v===t&&(v=null))})}function xe(e){return e?!!(e.closest(`.${d}`)||e.closest(w)||e.closest(F)):!1}function we(){const e=window.getSelection();if(!e||e.rangeCount===0)return!1;const t=e.getRangeAt(0).startContainer;return!!le(t)?.closest(w)}function C(e,t,o){const n=ve(e);Array.from(n.querySelectorAll(`.rte-toolbar-button[data-command="${t}"], .editora-toolbar-button[data-command="${t}"]`)).forEach(a=>{a.classList.toggle("active",o),a.setAttribute("aria-pressed",o?"true":"false"),a.setAttribute("data-active",o?"true":"false")})}function ie(e,t,o){t!==null?e.setAttribute("contenteditable",t):e.setAttribute("contenteditable","true"),o!==null?e.setAttribute("data-readonly",o):e.removeAttribute("data-readonly")}function Y(e){e.dispatchEvent(new Event("input",{bubbles:!0}))}function X(e,t){if(t===e.innerHTML)return;const o=window.execEditorCommand||window.executeEditorCommand;if(typeof o=="function")try{o("recordDomTransaction",e,t,e.innerHTML)}catch{}}function J(){return oe+=1,`approval-comment-${Date.now().toString(36)}-${oe.toString(36)}`}function ke(){return re+=1,`approval-signoff-${Date.now().toString(36)}-${re.toString(36)}`}function se(e){return{status:e.status,locked:e.locked,comments:e.comments.map(t=>({...t})),signoffs:e.signoffs.map(t=>({...t})),updatedAt:e.updatedAt}}function ye(e,t){const o=fe[e];return t.labels[o]||e}function ce(e,t,o){if(e.setAttribute("data-approval-status",t.status),e.setAttribute("data-approval-locked",t.locked?"true":"false"),e.classList.toggle("rte-approval-locked-editor",t.locked),C(e,"toggleApprovalWorkflowPanel",Z(e)),C(e,"requestApprovalReview",t.status==="review"),C(e,"approveDocument",t.status==="approved"),C(e,"reopenDraft",t.status==="draft"),t.status==="approved"&&o.lockOnApproval){t.locked||(t.preApprovalContentEditable=e.getAttribute("contenteditable"),t.preApprovalReadonly=e.getAttribute("data-readonly")),e.setAttribute("contenteditable","false"),e.setAttribute("data-readonly","true"),t.locked=!0;return}t.locked=!1,ie(e,t.preApprovalContentEditable??t.originalContentEditable,t.preApprovalReadonly??t.originalReadonly),t.preApprovalContentEditable=null,t.preApprovalReadonly=null}function f(e,t){let o=I.get(e);return o||(o={status:t.defaultStatus,locked:!1,comments:[],signoffs:[],updatedAt:new Date().toISOString(),originalContentEditable:e.getAttribute("contenteditable"),originalReadonly:e.getAttribute("data-readonly"),preApprovalContentEditable:null,preApprovalReadonly:null},I.set(e,o),H.add(e),ce(e,o,t),o)}function j(e,t){return e.length<=t?e:e.slice(e.length-t)}function M(e,t){const o=e.querySelector(".rte-approval-live");o&&(o.textContent=t)}function Ae(e,t){const o=se(t);e.__approvalWorkflowState=o,e.dispatchEvent(new CustomEvent("editora:approval-state-changed",{bubbles:!0,detail:{state:o}}))}function P(e){const t=k.get(e);if(!t)return;const o=s.get(e)||R;if(!o)return;const n=f(e,o),r=t.querySelector(".rte-approval-summary"),a=t.querySelector('[data-action="request-review"]'),l=t.querySelector('[data-action="approve"]'),c=t.querySelector('[data-action="reopen-draft"]'),u=t.querySelector(".rte-approval-comments-list"),m=t.querySelector(".rte-approval-signoffs-list");if(r){const i=ye(n.status,o);r.textContent=`${o.labels.summaryPrefix}: ${i} | Comments: ${n.comments.length} | Sign-offs: ${n.signoffs.length}${n.locked?` | ${o.labels.lockedSuffix}`:""}`}a&&(a.disabled=n.status!=="draft"),l&&(l.disabled=n.status==="approved"),c&&(c.disabled=n.status==="draft"),u&&(n.comments.length===0?u.innerHTML=`<li class="rte-approval-empty">${p(o.labels.noCommentsText)}</li>`:u.innerHTML=n.comments.slice().reverse().map(i=>` | ||
| <li class="rte-approval-item rte-approval-item-${i.kind}" role="listitem"> | ||
| <div class="rte-approval-item-head"> | ||
| <span class="rte-approval-item-author">${p(i.author)}</span> | ||
| <time class="rte-approval-item-time" datetime="${p(i.createdAt)}">${p(new Date(i.createdAt).toLocaleString())}</time> | ||
| </div> | ||
| <p class="rte-approval-item-message">${p(i.message)}</p> | ||
| </li> | ||
| `).join("")),m&&(n.signoffs.length===0?m.innerHTML=`<li class="rte-approval-empty">${p(o.labels.noSignoffsText)}</li>`:m.innerHTML=n.signoffs.slice().reverse().map(i=>` | ||
| <li class="rte-approval-item" role="listitem"> | ||
| <div class="rte-approval-item-head"> | ||
| <span class="rte-approval-item-author">${p(i.author)}</span> | ||
| <time class="rte-approval-item-time" datetime="${p(i.createdAt)}">${p(new Date(i.createdAt).toLocaleString())}</time> | ||
| </div> | ||
| <p class="rte-approval-item-message">${p(i.comment||"Approved")}</p> | ||
| </li> | ||
| `).join(""))}function G(e,t,o){t.updatedAt=new Date().toISOString(),ce(e,t,o),P(e),Ae(e,t)}function ae(e,t,o,n){e.comments.push({id:J(),author:o||t.defaultActor,message:n,kind:"system",createdAt:new Date().toISOString()}),e.comments=j(e.comments,t.maxHistoryEntries)}function E(e,t,o,n){const r=f(e,o);if(r.status===t)return!1;const a=e.innerHTML;return r.status=t,t==="review"?ae(r,o,n,"Review requested."):t==="draft"&&ae(r,o,n,"Returned to draft."),G(e,r,o),Y(e),X(e,a),!0}function pe(e,t,o,n){const r=n.normalizeText(t);if(!r)return!1;const a=n.normalizeText(o)||n.defaultActor,l=f(e,n),c=e.innerHTML;return l.comments.push({id:J(),author:a,message:r,kind:"comment",createdAt:new Date().toISOString()}),l.comments=j(l.comments,n.maxHistoryEntries),G(e,l,n),Y(e),X(e,c),!0}function Q(e,t,o,n){const r=t.normalizeText(o)||t.defaultActor,a=t.normalizeText(n);if(t.requireCommentOnApprove&&!a)return!1;const l=f(e,t),c=e.innerHTML;return l.status="approved",l.signoffs.push({id:ke(),author:r,comment:a||void 0,createdAt:new Date().toISOString()}),l.signoffs=j(l.signoffs,t.maxHistoryEntries),a&&(l.comments.push({id:J(),author:r,message:a,kind:"system",createdAt:new Date().toISOString()}),l.comments=j(l.comments,t.maxHistoryEntries)),G(e,l,t),Y(e),X(e,c),!0}function N(e,t){return e.querySelector(`[data-field="${t}"]`)}function Se(e){const t=N(e,"actor")?.value||"",o=N(e,"comment")?.value||"";return{actor:t,comment:o}}function V(e,t){if(!t.classList.contains("show"))return;const n=U(e).getBoundingClientRect(),r=Math.min(window.innerWidth-20,420),a=Math.max(10,window.innerWidth-r-10),l=Math.min(Math.max(10,n.right-r),a),c=Math.max(10,Math.min(window.innerHeight-10-280,n.top+12));t.style.width=`${r}px`,t.style.left=`${l}px`,t.style.top=`${c}px`,t.style.maxHeight=`${Math.max(280,window.innerHeight-24)}px`}function $e(e){const t=k.get(e);if(t)return t;const o=s.get(e)||R||z(),n=`rte-approval-panel-${me++}`,r=document.createElement("section");return r.className=d,r.id=n,r.setAttribute("role","dialog"),r.setAttribute("aria-modal","false"),r.setAttribute("aria-label",o.labels.panelAriaLabel),r.setAttribute("tabindex","-1"),r.innerHTML=` | ||
| <header class="rte-approval-header"> | ||
| <h2 class="rte-approval-title">${p(o.labels.panelTitle)}</h2> | ||
| <button type="button" class="rte-approval-icon-btn" data-action="close" aria-label="${p(o.labels.closeText)}">✕</button> | ||
| </header> | ||
| <div class="rte-approval-body"> | ||
| <p class="rte-approval-summary" aria-live="polite"></p> | ||
| <div class="rte-approval-controls" role="toolbar" aria-label="Approval actions"> | ||
| <button type="button" class="rte-approval-btn" data-action="request-review">${p(o.labels.requestReviewText)}</button> | ||
| <button type="button" class="rte-approval-btn rte-approval-btn-primary" data-action="approve">${p(o.labels.approveText)}</button> | ||
| <button type="button" class="rte-approval-btn" data-action="reopen-draft">${p(o.labels.reopenDraftText)}</button> | ||
| </div> | ||
| <div class="rte-approval-form"> | ||
| <label class="rte-approval-label"> | ||
| ${p(o.labels.actorLabel)} | ||
| <input type="text" data-field="actor" class="rte-approval-field" autocomplete="off" placeholder="${p(o.labels.actorPlaceholder)}" /> | ||
| </label> | ||
| <label class="rte-approval-label"> | ||
| ${p(o.labels.commentLabel)} | ||
| <textarea data-field="comment" class="rte-approval-field" rows="2" placeholder="${p(o.labels.commentPlaceholder)}"></textarea> | ||
| </label> | ||
| <button type="button" class="rte-approval-btn" data-action="add-comment">${p(o.labels.addCommentText)}</button> | ||
| </div> | ||
| <section class="rte-approval-section" aria-label="${p(o.labels.commentsHeading)}"> | ||
| <h3 class="rte-approval-section-title">${p(o.labels.commentsHeading)}</h3> | ||
| <ul class="rte-approval-comments-list" role="list"></ul> | ||
| </section> | ||
| <section class="rte-approval-section" aria-label="${p(o.labels.signoffsHeading)}"> | ||
| <h3 class="rte-approval-section-title">${p(o.labels.signoffsHeading)}</h3> | ||
| <ul class="rte-approval-signoffs-list" role="list"></ul> | ||
| </section> | ||
| <p class="rte-approval-shortcut">${p(o.labels.shortcutText)}</p> | ||
| <span class="rte-approval-live" aria-live="polite"></span> | ||
| </div> | ||
| `,r.addEventListener("click",a=>{const l=a.target;if(!l)return;const c=l.closest("[data-action]");if(!c)return;const u=c.getAttribute("data-action")||"",m=s.get(e)||R||o;if(s.set(e,m),f(e,m),u==="close"){q(e,!0);return}const i=Se(r);if(u==="request-review"){E(e,"review",m,i.actor||m.defaultActor)&&M(r,"Status changed to review.");return}if(u==="reopen-draft"){E(e,"draft",m,i.actor||m.defaultActor)&&M(r,"Status changed to draft.");return}if(u==="approve"){const b=Q(e,m,i.actor,i.comment);if(!b&&m.requireCommentOnApprove){M(r,m.labels.approveCommentRequiredText);return}if(b){const $=N(r,"comment");$&&($.value=""),M(r,"Document approved and signed off.")}return}if(u==="add-comment"){if(!pe(e,i.comment,i.actor,m))return;const $=N(r,"comment");$&&($.value=""),M(r,"Comment added.");return}}),r.addEventListener("keydown",a=>{a.key==="Escape"&&(a.preventDefault(),q(e,!0))}),K(r,e),document.body.appendChild(r),k.set(e,r),O.set(e,!1),P(e),r}function Z(e){return O.get(e)===!0}function A(e){D();const t=$e(e);k.forEach((o,n)=>{n!==e&&q(n,!1)}),t.classList.add("show"),O.set(e,!0),C(e,"toggleApprovalWorkflowPanel",!0),K(t,e),V(e,t),P(e)}function q(e,t=!1){const o=k.get(e);o&&(o.classList.remove("show"),O.set(e,!1),C(e,"toggleApprovalWorkflowPanel",!1),t&&e.focus({preventScroll:!0}))}function de(e,t){const o=Z(e);return(typeof t=="boolean"?t:!o)?A(e):q(e),!0}function Ee(e){const t=e.key.toLowerCase();return(e.metaKey||e.ctrlKey)&&e.altKey&&e.shiftKey&&t==="a"}function Ce(e){const t=e.key.toLowerCase();return(e.metaKey||e.ctrlKey)&&e.altKey&&e.shiftKey&&t==="r"}function Te(e){const t=e.key.toLowerCase();return(e.metaKey||e.ctrlKey)&&e.altKey&&e.shiftKey&&t==="p"}function Le(e){const t=e.key.toLowerCase();return(e.metaKey||e.ctrlKey)&&e.altKey&&e.shiftKey&&t==="d"}function Re(e){R=e,T||(T=t=>{D();const n=t.target?.closest(w);if(!n)return;v=n;const r=s.get(n)||e;s.set(n,r),f(n,r);const a=k.get(n);a&&(K(a,n),V(n,a))},document.addEventListener("focusin",T,!0)),L||(L=t=>{if(t.defaultPrevented)return;const o=Ee(t),n=Ce(t),r=Te(t),a=Le(t),l=t.key==="Escape";if(!l&&!o&&!n&&!r&&!a)return;D();const c=t.target,u=!!c?.closest(`.${d} input, .${d} textarea, .${d} select`);if(!xe(c)&&!we())return;const i=x(void 0,!1);if(!i)return;const b=s.get(i)||R||e;s.set(i,b);const $=f(i,b);if(v=i,l&&Z(i)){t.preventDefault(),q(i,!0);return}if(!u){if(o){t.preventDefault(),t.stopPropagation(),de(i);return}if(n){t.preventDefault(),t.stopPropagation(),E(i,"review",b,b.defaultActor)&&A(i);return}if(r){t.preventDefault(),t.stopPropagation(),Q(i,b,b.defaultActor,"Approved via keyboard shortcut.")&&A(i);return}a&&(t.preventDefault(),t.stopPropagation(),$.status!=="draft"&&E(i,"draft",b,b.defaultActor)&&A(i))}},document.addEventListener("keydown",L,!0)),S||(S=()=>{D(),k.forEach((t,o)=>{!o.isConnected||!t.isConnected||(K(t,o),V(o,t))})},window.addEventListener("scroll",S,!0),window.addEventListener("resize",S))}function Me(e){const t=I.get(e);t&&(e.classList.remove("rte-approval-locked-editor"),e.removeAttribute("data-approval-status"),e.removeAttribute("data-approval-locked"),ie(e,t.preApprovalContentEditable??t.originalContentEditable,t.preApprovalReadonly??t.originalReadonly))}function De(){T&&(document.removeEventListener("focusin",T,!0),T=null),L&&(document.removeEventListener("keydown",L,!0),L=null),S&&(window.removeEventListener("scroll",S,!0),window.removeEventListener("resize",S),S=null),k.forEach(e=>e.remove()),k.clear(),H.forEach(e=>Me(e)),H.clear(),R=null,v=null}function He(){if(typeof document>"u"||document.getElementById(te))return;const e=document.createElement("style");e.id=te,e.textContent=` | ||
| .rte-toolbar-group-items.${h}, | ||
| .editora-toolbar-group-items.${h}, | ||
| .rte-toolbar-group-items.${y}, | ||
| .editora-toolbar-group-items.${y} { | ||
| display: flex; | ||
| border: 1px solid #ccc; | ||
| border-radius: 3px; | ||
| background: #fff; | ||
| } | ||
| .rte-toolbar-group-items.${h} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${h} .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${y} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${y} .editora-toolbar-button { | ||
| border: none; | ||
| border-radius: 0; | ||
| border-right: 1px solid #ccc; | ||
| } | ||
| .rte-toolbar-button[data-command="toggleApprovalWorkflowPanel"].active, | ||
| .editora-toolbar-button[data-command="toggleApprovalWorkflowPanel"].active, | ||
| .rte-toolbar-button[data-command="reopenDraft"].active, | ||
| .editora-toolbar-button[data-command="reopenDraft"].active { | ||
| background-color: #ccc; | ||
| } | ||
| ${g} .rte-toolbar-button[data-command="toggleApprovalWorkflowPanel"].active, | ||
| ${g} .editora-toolbar-button[data-command="toggleApprovalWorkflowPanel"].active, | ||
| ${g} .rte-toolbar-button[data-command="reopenDraft"].active, | ||
| ${g} .editora-toolbar-button[data-command="reopenDraft"].active { | ||
| background: linear-gradient(180deg, #5eaaf6 0%, #4a95de 100%); | ||
| } | ||
| .rte-toolbar-group-items.${h} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${h} .editora-toolbar-item:last-child .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${y} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${y} .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| ${g} .rte-toolbar-group-items.${h}, | ||
| ${g} .editora-toolbar-group-items.${h}, | ||
| ${g} .rte-toolbar-group-items.${y}, | ||
| ${g} .editora-toolbar-group-items.${y}, | ||
| .${d}.rte-approval-theme-dark { | ||
| border-color: #566275; | ||
| } | ||
| ${g} .rte-toolbar-group-items.${h} .rte-toolbar-button svg, | ||
| ${g} .editora-toolbar-group-items.${h} .editora-toolbar-button svg, | ||
| ${g} .rte-toolbar-group-items.${y} .rte-toolbar-button svg, | ||
| ${g} .editora-toolbar-group-items.${y} .editora-toolbar-button svg | ||
| { | ||
| fill: none; | ||
| } | ||
| ${g} .rte-toolbar-group-items.${h} .rte-toolbar-button, | ||
| ${g} .editora-toolbar-group-items.${h} .editora-toolbar-button | ||
| { | ||
| border-color: #566275; | ||
| } | ||
| .rte-approval-locked-editor { | ||
| background-image: repeating-linear-gradient( | ||
| -45deg, | ||
| rgba(30, 64, 175, 0.04), | ||
| rgba(30, 64, 175, 0.04) 8px, | ||
| rgba(30, 64, 175, 0.08) 8px, | ||
| rgba(30, 64, 175, 0.08) 16px | ||
| ); | ||
| } | ||
| .${d} { | ||
| position: fixed; | ||
| z-index: 1500; | ||
| right: 16px; | ||
| top: 16px; | ||
| width: min(420px, calc(100vw - 20px)); | ||
| max-height: calc(100vh - 24px); | ||
| display: none; | ||
| flex-direction: column; | ||
| border-radius: 12px; | ||
| border: 1px solid #d1d5db; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| box-shadow: 0 18px 38px rgba(15, 23, 42, 0.16); | ||
| overflow: hidden; | ||
| } | ||
| .${d}.show { | ||
| display: flex; | ||
| } | ||
| .${d}.rte-approval-theme-dark { | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| border-color: #334155; | ||
| box-shadow: 0 20px 40px rgba(2, 6, 23, 0.5); | ||
| } | ||
| .rte-approval-header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| padding: 10px 12px; | ||
| border-bottom: 1px solid #e2e8f0; | ||
| background: #f8fafc; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-header { | ||
| border-bottom-color: #334155; | ||
| background: #111827; | ||
| } | ||
| .rte-approval-title { | ||
| margin: 0; | ||
| font-size: 14px; | ||
| font-weight: 700; | ||
| } | ||
| .rte-approval-icon-btn { | ||
| border: 1px solid #cbd5e1; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| border-radius: 6px; | ||
| cursor: pointer; | ||
| min-width: 34px; | ||
| min-height: 34px; | ||
| width: 34px; | ||
| height: 34px; | ||
| padding: 0; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| font-weight: 600; | ||
| } | ||
| .rte-approval-icon-btn:hover, | ||
| .rte-approval-icon-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-icon-btn { | ||
| background: #0f172a; | ||
| border-color: #475569; | ||
| color: #e2e8f0; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-icon-btn:hover, | ||
| .${d}.rte-approval-theme-dark .rte-approval-icon-btn:focus-visible { | ||
| border-color: #60a5fa; | ||
| box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.24); | ||
| } | ||
| .rte-approval-body { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 10px; | ||
| padding: 12px; | ||
| overflow: auto; | ||
| } | ||
| .rte-approval-summary { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| color: #475569; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-summary { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-approval-controls { | ||
| display: flex; | ||
| flex-wrap: wrap; | ||
| gap: 8px; | ||
| } | ||
| .rte-approval-btn { | ||
| border: 1px solid #cbd5e1; | ||
| background: #f8fafc; | ||
| color: inherit; | ||
| border-radius: 8px; | ||
| padding: 6px 10px; | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| cursor: pointer; | ||
| } | ||
| .rte-approval-btn:disabled { | ||
| opacity: 0.5; | ||
| cursor: not-allowed; | ||
| } | ||
| .rte-approval-btn:hover:not(:disabled), | ||
| .rte-approval-btn:focus-visible:not(:disabled) { | ||
| outline: none; | ||
| border-color: #1d4ed8; | ||
| box-shadow: 0 0 0 2px rgba(29, 78, 216, 0.2); | ||
| } | ||
| .rte-approval-btn-primary { | ||
| background: #1d4ed8; | ||
| border-color: #1d4ed8; | ||
| color: #ffffff; | ||
| } | ||
| .rte-approval-btn-primary:hover:not(:disabled), | ||
| .rte-approval-btn-primary:focus-visible:not(:disabled) { | ||
| background: #1e40af; | ||
| border-color: #1e40af; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-btn { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #e2e8f0; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-btn-primary { | ||
| border-color: #2563eb; | ||
| background: #2563eb; | ||
| color: #ffffff; | ||
| } | ||
| .rte-approval-form { | ||
| display: grid; | ||
| grid-template-columns: 1fr; | ||
| gap: 8px; | ||
| border: 1px solid #e2e8f0; | ||
| border-radius: 10px; | ||
| padding: 8px; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-form { | ||
| border-color: #334155; | ||
| } | ||
| .rte-approval-label { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 4px; | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| } | ||
| .rte-approval-field { | ||
| width: 100%; | ||
| box-sizing: border-box; | ||
| min-height: 30px; | ||
| border-radius: 8px; | ||
| border: 1px solid #cbd5e1; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| font-size: 13px; | ||
| padding: 6px 8px; | ||
| } | ||
| .rte-approval-field:focus-visible { | ||
| outline: none; | ||
| border-color: #1d4ed8; | ||
| box-shadow: 0 0 0 2px rgba(29, 78, 216, 0.2); | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-field { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #e2e8f0; | ||
| } | ||
| .rte-approval-section { | ||
| border: 1px solid #e2e8f0; | ||
| border-radius: 10px; | ||
| padding: 8px; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-section { | ||
| border-color: #334155; | ||
| } | ||
| .rte-approval-section-title { | ||
| margin: 0 0 8px; | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| } | ||
| .rte-approval-comments-list, | ||
| .rte-approval-signoffs-list { | ||
| margin: 0; | ||
| padding: 0; | ||
| list-style: none; | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 6px; | ||
| max-height: 150px; | ||
| overflow: auto; | ||
| } | ||
| .rte-approval-item { | ||
| border: 1px solid #dbeafe; | ||
| background: #eff6ff; | ||
| border-radius: 8px; | ||
| padding: 6px; | ||
| } | ||
| .rte-approval-item-comment { | ||
| border-color: #e2e8f0; | ||
| background: #f8fafc; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-item { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| } | ||
| .rte-approval-item-head { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| margin-bottom: 4px; | ||
| } | ||
| .rte-approval-item-author { | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| } | ||
| .rte-approval-item-time { | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-item-time { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-approval-item-message { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| white-space: pre-wrap; | ||
| } | ||
| .rte-approval-empty { | ||
| border: 1px dashed #cbd5e1; | ||
| border-radius: 8px; | ||
| padding: 8px; | ||
| font-size: 12px; | ||
| color: #64748b; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-empty { | ||
| border-color: #334155; | ||
| color: #94a3b8; | ||
| } | ||
| .rte-approval-shortcut { | ||
| margin: 0; | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-shortcut { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-approval-live { | ||
| position: absolute; | ||
| width: 1px; | ||
| height: 1px; | ||
| margin: -1px; | ||
| padding: 0; | ||
| overflow: hidden; | ||
| clip: rect(0 0 0 0); | ||
| border: 0; | ||
| } | ||
| @media (max-width: 768px) { | ||
| .${d} { | ||
| left: 10px !important; | ||
| right: 10px; | ||
| top: 10px !important; | ||
| width: auto !important; | ||
| max-height: calc(100vh - 20px); | ||
| } | ||
| } | ||
| `,document.head.appendChild(e)}const Pe=(e={})=>{const t=z(e);return He(),{name:"approvalWorkflow",toolbar:[{id:"approvalWorkflowGroup",label:"Approval",type:"group",command:"approvalWorkflow",items:[{id:"approvalWorkflow",label:"Approval Workflow",command:"toggleApprovalWorkflowPanel",shortcut:"Mod-Alt-Shift-a",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><rect x="4" y="5" width="16" height="14" rx="2.5" stroke="currentColor" stroke-width="1.7"/><path d="M8 10h8M8 14h5" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/><path d="m16.5 16 1.8 1.8 3.2-3.2" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg>'},{id:"approvalRequestReview",label:"Request Review",command:"requestApprovalReview",shortcut:"Mod-Alt-Shift-r",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><circle cx="11" cy="11" r="6.5" stroke="currentColor" stroke-width="1.7"/><path d="M11 8v3l2 2" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/><path d="M17.5 17.5 20 20" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/></svg>'},{id:"approvalApprove",label:"Approve",command:"approveDocument",shortcut:"Mod-Alt-Shift-p",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M5 12.5 9.5 17 19 7.5" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/><rect x="3.8" y="3.8" width="16.4" height="16.4" rx="3" stroke="currentColor" stroke-width="1.4"/></svg>'},{id:"approvalReopen",label:"Reopen Draft",command:"reopenDraft",shortcut:"Mod-Alt-Shift-d",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M8 8H4v4" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/><path d="M5 12a7 7 0 1 0 2-4.95" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/></svg>'}]}],commands:{approvalWorkflow:(o,n)=>{const r=x(n);if(!r)return!1;const a=s.get(r)||t;return s.set(r,a),f(r,a),v=r,A(r),P(r),!0},toggleApprovalWorkflowPanel:(o,n)=>{const r=x(n);if(!r)return!1;const a=s.get(r)||t;return s.set(r,a),f(r,a),v=r,de(r,typeof o=="boolean"?o:void 0)},requestApprovalReview:(o,n)=>{const r=x(n);if(!r)return!1;const a=s.get(r)||t;s.set(r,a),f(r,a);const l=E(r,"review",a,a.defaultActor);return A(r),l},approveDocument:(o,n)=>{const r=x(n);if(!r)return!1;const a=s.get(r)||t;s.set(r,a),f(r,a);const l=typeof o=="object"&&o?String(o.author||""):a.defaultActor,c=typeof o=="object"&&o?String(o.comment||""):typeof o=="string"?o:"",u=Q(r,a,l,c);return u&&A(r),u},reopenDraft:(o,n)=>{const r=x(n);if(!r)return!1;const a=s.get(r)||t;s.set(r,a),f(r,a);const l=E(r,"draft",a,a.defaultActor);return l&&A(r),l},addApprovalComment:(o,n)=>{const r=x(n);if(!r)return!1;const a=s.get(r)||t;s.set(r,a),f(r,a);const l=typeof o=="object"&&o?String(o.author||""):a.defaultActor,c=typeof o=="object"&&o?String(o.message||""):typeof o=="string"?o:"",u=pe(r,c,l,a);return u&&A(r),u},setApprovalStatus:(o,n)=>{const r=x(n);if(!r||!o)return!1;const a=ne(o),l=s.get(r)||t;s.set(r,l),f(r,l);const c=E(r,a,l,l.defaultActor);return c&&A(r),c},setApprovalWorkflowOptions:(o,n)=>{const r=x(n);if(!r||!o||typeof o!="object")return!1;const a=s.get(r)||t,l=z({...a,...o,labels:{...a.labels,...o.labels||{}},normalizeText:o.normalizeText||a.normalizeText});s.set(r,l);const c=f(r,l);return G(r,c,l),!0},getApprovalWorkflowState:(o,n)=>{const r=x(n);if(!r)return!1;const a=s.get(r)||t;s.set(r,a);const l=f(r,a),c=se(l);if(typeof o=="function")try{o(c)}catch{}return r.__approvalWorkflowState=c,r.dispatchEvent(new CustomEvent("editora:approval-state",{bubbles:!0,detail:{state:c}})),!0}},keymap:{"Mod-Alt-Shift-a":"toggleApprovalWorkflowPanel","Mod-Alt-Shift-A":"toggleApprovalWorkflowPanel","Mod-Alt-Shift-r":"requestApprovalReview","Mod-Alt-Shift-R":"requestApprovalReview","Mod-Alt-Shift-p":"approveDocument","Mod-Alt-Shift-P":"approveDocument","Mod-Alt-Shift-d":"reopenDraft","Mod-Alt-Shift-D":"reopenDraft"},init:function(n){_+=1;const r=this&&typeof this.__pluginConfig=="object"?z({...t,...this.__pluginConfig}):t;Re(r);const a=x(n?.editorElement?{editorElement:n.editorElement}:void 0,!1);a&&(s.set(a,r),f(a,r),v=a,P(a))},destroy:()=>{_=Math.max(0,_-1),!(_>0)&&De()}}};exports.ApprovalWorkflowPlugin=Pe; |
| const w = ".rte-content, .editora-content", F = "[data-editora-editor], .rte-editor, .editora-editor, editora-editor", ee = "__editoraCommandEditorRoot", te = "rte-approval-workflow-styles", d = "rte-approval-panel", h = "approval", y = "approvalWorkflow", g = ':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)', ue = { | ||
| panelTitle: "Approval Workflow", | ||
| panelAriaLabel: "Approval workflow panel", | ||
| statusLabel: "Status", | ||
| statusDraftText: "Draft", | ||
| statusReviewText: "In Review", | ||
| statusApprovedText: "Approved", | ||
| requestReviewText: "Request Review", | ||
| approveText: "Approve", | ||
| reopenDraftText: "Reopen Draft", | ||
| addCommentText: "Add Comment", | ||
| actorLabel: "Actor", | ||
| actorPlaceholder: "Reviewer name", | ||
| commentLabel: "Comment", | ||
| commentPlaceholder: "Add review note or sign-off context", | ||
| closeText: "Close", | ||
| commentsHeading: "Comments", | ||
| signoffsHeading: "Sign-offs", | ||
| noCommentsText: "No comments yet.", | ||
| noSignoffsText: "No sign-offs yet.", | ||
| summaryPrefix: "Workflow", | ||
| lockedSuffix: "Locked", | ||
| shortcutText: "Shortcuts: Ctrl/Cmd+Alt+Shift+A/R/P/D", | ||
| approveCommentRequiredText: "Approval comment is required." | ||
| }, fe = { | ||
| draft: "statusDraftText", | ||
| review: "statusReviewText", | ||
| approved: "statusApprovedText" | ||
| }, s = /* @__PURE__ */ new WeakMap(), I = /* @__PURE__ */ new WeakMap(), k = /* @__PURE__ */ new Map(), O = /* @__PURE__ */ new WeakMap(), H = /* @__PURE__ */ new Set(); | ||
| let _ = 0, me = 0, oe = 0, re = 0, R = null, v = null, T = null, L = null, S = null; | ||
| function p(e) { | ||
| return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); | ||
| } | ||
| function be(e) { | ||
| return e.replace(/\u00A0/g, " ").replace(/\s+/g, " ").trim(); | ||
| } | ||
| function ne(e) { | ||
| return e === "review" || e === "approved" ? e : "draft"; | ||
| } | ||
| function z(e = {}) { | ||
| return { | ||
| defaultStatus: ne(e.defaultStatus), | ||
| lockOnApproval: e.lockOnApproval !== !1, | ||
| maxHistoryEntries: Math.max(10, Math.min(500, Number(e.maxHistoryEntries ?? 120))), | ||
| requireCommentOnApprove: !!e.requireCommentOnApprove, | ||
| defaultActor: (e.defaultActor || "system").trim() || "system", | ||
| labels: { | ||
| ...ue, | ||
| ...e.labels || {} | ||
| }, | ||
| normalizeText: e.normalizeText || be | ||
| }; | ||
| } | ||
| function U(e) { | ||
| return e.closest(F) || e; | ||
| } | ||
| function B(e) { | ||
| if (!e) return null; | ||
| if (e.matches(w)) return e; | ||
| const t = e.querySelector(w); | ||
| return t instanceof HTMLElement ? t : null; | ||
| } | ||
| function ge() { | ||
| if (typeof window > "u") return null; | ||
| const e = window[ee]; | ||
| if (!(e instanceof HTMLElement)) return null; | ||
| window[ee] = null; | ||
| const t = B(e); | ||
| if (t) return t; | ||
| const o = e.closest(F); | ||
| if (o) { | ||
| const n = B(o); | ||
| if (n) return n; | ||
| } | ||
| return null; | ||
| } | ||
| function ve(e) { | ||
| const t = e.closest("[data-editora-editor]"); | ||
| if (t && B(t) === e) | ||
| return t; | ||
| let o = e; | ||
| for (; o; ) { | ||
| if (o.matches(F) && (o === e || B(o) === e)) | ||
| return o; | ||
| o = o.parentElement; | ||
| } | ||
| return U(e); | ||
| } | ||
| function W(e) { | ||
| return e ? (e.getAttribute("data-theme") || e.getAttribute("theme") || "").toLowerCase() === "dark" ? !0 : e.classList.contains("dark") || e.classList.contains("editora-theme-dark") || e.classList.contains("rte-theme-dark") : !1; | ||
| } | ||
| function he(e) { | ||
| const t = U(e); | ||
| if (W(t)) return !0; | ||
| const o = t.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark"); | ||
| return W(o) ? !0 : W(document.documentElement) || W(document.body); | ||
| } | ||
| function K(e, t) { | ||
| e.classList.remove("rte-approval-theme-dark"), he(t) && e.classList.add("rte-approval-theme-dark"); | ||
| } | ||
| function le(e) { | ||
| return e ? e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement : null; | ||
| } | ||
| function x(e, t = !0) { | ||
| if (D(), e?.contentElement instanceof HTMLElement) return e.contentElement; | ||
| if (e?.editorElement instanceof HTMLElement) { | ||
| const a = e.editorElement; | ||
| if (a.matches(w)) return a; | ||
| const l = a.querySelector(w); | ||
| if (l instanceof HTMLElement) return l; | ||
| } | ||
| const o = ge(); | ||
| if (o) return o; | ||
| const n = window.getSelection(); | ||
| if (n && n.rangeCount > 0) { | ||
| const l = le(n.getRangeAt(0).startContainer)?.closest(w); | ||
| if (l) return l; | ||
| } | ||
| const r = document.activeElement; | ||
| if (r) { | ||
| if (r.matches(w)) return r; | ||
| const a = r.closest(w); | ||
| if (a) return a; | ||
| } | ||
| return v && v.isConnected ? v : (v && !v.isConnected && (v = null), t ? document.querySelector(w) : null); | ||
| } | ||
| function D() { | ||
| Array.from(H).forEach((t) => { | ||
| t.isConnected || (k.get(t)?.remove(), k.delete(t), O.delete(t), s.delete(t), I.delete(t), H.delete(t), v === t && (v = null)); | ||
| }); | ||
| } | ||
| function xe(e) { | ||
| return e ? !!(e.closest(`.${d}`) || e.closest(w) || e.closest(F)) : !1; | ||
| } | ||
| function we() { | ||
| const e = window.getSelection(); | ||
| if (!e || e.rangeCount === 0) return !1; | ||
| const t = e.getRangeAt(0).startContainer; | ||
| return !!le(t)?.closest(w); | ||
| } | ||
| function C(e, t, o) { | ||
| const n = ve(e); | ||
| Array.from( | ||
| n.querySelectorAll( | ||
| `.rte-toolbar-button[data-command="${t}"], .editora-toolbar-button[data-command="${t}"]` | ||
| ) | ||
| ).forEach((a) => { | ||
| a.classList.toggle("active", o), a.setAttribute("aria-pressed", o ? "true" : "false"), a.setAttribute("data-active", o ? "true" : "false"); | ||
| }); | ||
| } | ||
| function ie(e, t, o) { | ||
| t !== null ? e.setAttribute("contenteditable", t) : e.setAttribute("contenteditable", "true"), o !== null ? e.setAttribute("data-readonly", o) : e.removeAttribute("data-readonly"); | ||
| } | ||
| function Y(e) { | ||
| e.dispatchEvent(new Event("input", { bubbles: !0 })); | ||
| } | ||
| function X(e, t) { | ||
| if (t === e.innerHTML) return; | ||
| const o = window.execEditorCommand || window.executeEditorCommand; | ||
| if (typeof o == "function") | ||
| try { | ||
| o("recordDomTransaction", e, t, e.innerHTML); | ||
| } catch { | ||
| } | ||
| } | ||
| function J() { | ||
| return oe += 1, `approval-comment-${Date.now().toString(36)}-${oe.toString(36)}`; | ||
| } | ||
| function ke() { | ||
| return re += 1, `approval-signoff-${Date.now().toString(36)}-${re.toString(36)}`; | ||
| } | ||
| function se(e) { | ||
| return { | ||
| status: e.status, | ||
| locked: e.locked, | ||
| comments: e.comments.map((t) => ({ ...t })), | ||
| signoffs: e.signoffs.map((t) => ({ ...t })), | ||
| updatedAt: e.updatedAt | ||
| }; | ||
| } | ||
| function ye(e, t) { | ||
| const o = fe[e]; | ||
| return t.labels[o] || e; | ||
| } | ||
| function ce(e, t, o) { | ||
| if (e.setAttribute("data-approval-status", t.status), e.setAttribute("data-approval-locked", t.locked ? "true" : "false"), e.classList.toggle("rte-approval-locked-editor", t.locked), C(e, "toggleApprovalWorkflowPanel", Z(e)), C(e, "requestApprovalReview", t.status === "review"), C(e, "approveDocument", t.status === "approved"), C(e, "reopenDraft", t.status === "draft"), t.status === "approved" && o.lockOnApproval) { | ||
| t.locked || (t.preApprovalContentEditable = e.getAttribute("contenteditable"), t.preApprovalReadonly = e.getAttribute("data-readonly")), e.setAttribute("contenteditable", "false"), e.setAttribute("data-readonly", "true"), t.locked = !0; | ||
| return; | ||
| } | ||
| t.locked = !1, ie( | ||
| e, | ||
| t.preApprovalContentEditable ?? t.originalContentEditable, | ||
| t.preApprovalReadonly ?? t.originalReadonly | ||
| ), t.preApprovalContentEditable = null, t.preApprovalReadonly = null; | ||
| } | ||
| function f(e, t) { | ||
| let o = I.get(e); | ||
| return o || (o = { | ||
| status: t.defaultStatus, | ||
| locked: !1, | ||
| comments: [], | ||
| signoffs: [], | ||
| updatedAt: (/* @__PURE__ */ new Date()).toISOString(), | ||
| originalContentEditable: e.getAttribute("contenteditable"), | ||
| originalReadonly: e.getAttribute("data-readonly"), | ||
| preApprovalContentEditable: null, | ||
| preApprovalReadonly: null | ||
| }, I.set(e, o), H.add(e), ce(e, o, t), o); | ||
| } | ||
| function j(e, t) { | ||
| return e.length <= t ? e : e.slice(e.length - t); | ||
| } | ||
| function M(e, t) { | ||
| const o = e.querySelector(".rte-approval-live"); | ||
| o && (o.textContent = t); | ||
| } | ||
| function Ae(e, t) { | ||
| const o = se(t); | ||
| e.__approvalWorkflowState = o, e.dispatchEvent( | ||
| new CustomEvent("editora:approval-state-changed", { | ||
| bubbles: !0, | ||
| detail: { | ||
| state: o | ||
| } | ||
| }) | ||
| ); | ||
| } | ||
| function q(e) { | ||
| const t = k.get(e); | ||
| if (!t) return; | ||
| const o = s.get(e) || R; | ||
| if (!o) return; | ||
| const n = f(e, o), r = t.querySelector(".rte-approval-summary"), a = t.querySelector('[data-action="request-review"]'), l = t.querySelector('[data-action="approve"]'), c = t.querySelector('[data-action="reopen-draft"]'), u = t.querySelector(".rte-approval-comments-list"), m = t.querySelector(".rte-approval-signoffs-list"); | ||
| if (r) { | ||
| const i = ye(n.status, o); | ||
| r.textContent = `${o.labels.summaryPrefix}: ${i} | Comments: ${n.comments.length} | Sign-offs: ${n.signoffs.length}${n.locked ? ` | ${o.labels.lockedSuffix}` : ""}`; | ||
| } | ||
| a && (a.disabled = n.status !== "draft"), l && (l.disabled = n.status === "approved"), c && (c.disabled = n.status === "draft"), u && (n.comments.length === 0 ? u.innerHTML = `<li class="rte-approval-empty">${p(o.labels.noCommentsText)}</li>` : u.innerHTML = n.comments.slice().reverse().map( | ||
| (i) => ` | ||
| <li class="rte-approval-item rte-approval-item-${i.kind}" role="listitem"> | ||
| <div class="rte-approval-item-head"> | ||
| <span class="rte-approval-item-author">${p(i.author)}</span> | ||
| <time class="rte-approval-item-time" datetime="${p(i.createdAt)}">${p( | ||
| new Date(i.createdAt).toLocaleString() | ||
| )}</time> | ||
| </div> | ||
| <p class="rte-approval-item-message">${p(i.message)}</p> | ||
| </li> | ||
| ` | ||
| ).join("")), m && (n.signoffs.length === 0 ? m.innerHTML = `<li class="rte-approval-empty">${p(o.labels.noSignoffsText)}</li>` : m.innerHTML = n.signoffs.slice().reverse().map( | ||
| (i) => ` | ||
| <li class="rte-approval-item" role="listitem"> | ||
| <div class="rte-approval-item-head"> | ||
| <span class="rte-approval-item-author">${p(i.author)}</span> | ||
| <time class="rte-approval-item-time" datetime="${p(i.createdAt)}">${p( | ||
| new Date(i.createdAt).toLocaleString() | ||
| )}</time> | ||
| </div> | ||
| <p class="rte-approval-item-message">${p(i.comment || "Approved")}</p> | ||
| </li> | ||
| ` | ||
| ).join("")); | ||
| } | ||
| function G(e, t, o) { | ||
| t.updatedAt = (/* @__PURE__ */ new Date()).toISOString(), ce(e, t, o), q(e), Ae(e, t); | ||
| } | ||
| function ae(e, t, o, n) { | ||
| e.comments.push({ | ||
| id: J(), | ||
| author: o || t.defaultActor, | ||
| message: n, | ||
| kind: "system", | ||
| createdAt: (/* @__PURE__ */ new Date()).toISOString() | ||
| }), e.comments = j(e.comments, t.maxHistoryEntries); | ||
| } | ||
| function E(e, t, o, n) { | ||
| const r = f(e, o); | ||
| if (r.status === t) return !1; | ||
| const a = e.innerHTML; | ||
| return r.status = t, t === "review" ? ae(r, o, n, "Review requested.") : t === "draft" && ae(r, o, n, "Returned to draft."), G(e, r, o), Y(e), X(e, a), !0; | ||
| } | ||
| function pe(e, t, o, n) { | ||
| const r = n.normalizeText(t); | ||
| if (!r) return !1; | ||
| const a = n.normalizeText(o) || n.defaultActor, l = f(e, n), c = e.innerHTML; | ||
| return l.comments.push({ | ||
| id: J(), | ||
| author: a, | ||
| message: r, | ||
| kind: "comment", | ||
| createdAt: (/* @__PURE__ */ new Date()).toISOString() | ||
| }), l.comments = j(l.comments, n.maxHistoryEntries), G(e, l, n), Y(e), X(e, c), !0; | ||
| } | ||
| function Q(e, t, o, n) { | ||
| const r = t.normalizeText(o) || t.defaultActor, a = t.normalizeText(n); | ||
| if (t.requireCommentOnApprove && !a) return !1; | ||
| const l = f(e, t), c = e.innerHTML; | ||
| return l.status = "approved", l.signoffs.push({ | ||
| id: ke(), | ||
| author: r, | ||
| comment: a || void 0, | ||
| createdAt: (/* @__PURE__ */ new Date()).toISOString() | ||
| }), l.signoffs = j(l.signoffs, t.maxHistoryEntries), a && (l.comments.push({ | ||
| id: J(), | ||
| author: r, | ||
| message: a, | ||
| kind: "system", | ||
| createdAt: (/* @__PURE__ */ new Date()).toISOString() | ||
| }), l.comments = j(l.comments, t.maxHistoryEntries)), G(e, l, t), Y(e), X(e, c), !0; | ||
| } | ||
| function N(e, t) { | ||
| return e.querySelector(`[data-field="${t}"]`); | ||
| } | ||
| function Se(e) { | ||
| const t = N(e, "actor")?.value || "", o = N(e, "comment")?.value || ""; | ||
| return { actor: t, comment: o }; | ||
| } | ||
| function V(e, t) { | ||
| if (!t.classList.contains("show")) return; | ||
| const n = U(e).getBoundingClientRect(), r = Math.min(window.innerWidth - 20, 420), a = Math.max(10, window.innerWidth - r - 10), l = Math.min(Math.max(10, n.right - r), a), c = Math.max(10, Math.min(window.innerHeight - 10 - 280, n.top + 12)); | ||
| t.style.width = `${r}px`, t.style.left = `${l}px`, t.style.top = `${c}px`, t.style.maxHeight = `${Math.max(280, window.innerHeight - 24)}px`; | ||
| } | ||
| function $e(e) { | ||
| const t = k.get(e); | ||
| if (t) return t; | ||
| const o = s.get(e) || R || z(), n = `rte-approval-panel-${me++}`, r = document.createElement("section"); | ||
| return r.className = d, r.id = n, r.setAttribute("role", "dialog"), r.setAttribute("aria-modal", "false"), r.setAttribute("aria-label", o.labels.panelAriaLabel), r.setAttribute("tabindex", "-1"), r.innerHTML = ` | ||
| <header class="rte-approval-header"> | ||
| <h2 class="rte-approval-title">${p(o.labels.panelTitle)}</h2> | ||
| <button type="button" class="rte-approval-icon-btn" data-action="close" aria-label="${p( | ||
| o.labels.closeText | ||
| )}">✕</button> | ||
| </header> | ||
| <div class="rte-approval-body"> | ||
| <p class="rte-approval-summary" aria-live="polite"></p> | ||
| <div class="rte-approval-controls" role="toolbar" aria-label="Approval actions"> | ||
| <button type="button" class="rte-approval-btn" data-action="request-review">${p( | ||
| o.labels.requestReviewText | ||
| )}</button> | ||
| <button type="button" class="rte-approval-btn rte-approval-btn-primary" data-action="approve">${p( | ||
| o.labels.approveText | ||
| )}</button> | ||
| <button type="button" class="rte-approval-btn" data-action="reopen-draft">${p( | ||
| o.labels.reopenDraftText | ||
| )}</button> | ||
| </div> | ||
| <div class="rte-approval-form"> | ||
| <label class="rte-approval-label"> | ||
| ${p(o.labels.actorLabel)} | ||
| <input type="text" data-field="actor" class="rte-approval-field" autocomplete="off" placeholder="${p( | ||
| o.labels.actorPlaceholder | ||
| )}" /> | ||
| </label> | ||
| <label class="rte-approval-label"> | ||
| ${p(o.labels.commentLabel)} | ||
| <textarea data-field="comment" class="rte-approval-field" rows="2" placeholder="${p( | ||
| o.labels.commentPlaceholder | ||
| )}"></textarea> | ||
| </label> | ||
| <button type="button" class="rte-approval-btn" data-action="add-comment">${p( | ||
| o.labels.addCommentText | ||
| )}</button> | ||
| </div> | ||
| <section class="rte-approval-section" aria-label="${p(o.labels.commentsHeading)}"> | ||
| <h3 class="rte-approval-section-title">${p(o.labels.commentsHeading)}</h3> | ||
| <ul class="rte-approval-comments-list" role="list"></ul> | ||
| </section> | ||
| <section class="rte-approval-section" aria-label="${p(o.labels.signoffsHeading)}"> | ||
| <h3 class="rte-approval-section-title">${p(o.labels.signoffsHeading)}</h3> | ||
| <ul class="rte-approval-signoffs-list" role="list"></ul> | ||
| </section> | ||
| <p class="rte-approval-shortcut">${p(o.labels.shortcutText)}</p> | ||
| <span class="rte-approval-live" aria-live="polite"></span> | ||
| </div> | ||
| `, r.addEventListener("click", (a) => { | ||
| const l = a.target; | ||
| if (!l) return; | ||
| const c = l.closest("[data-action]"); | ||
| if (!c) return; | ||
| const u = c.getAttribute("data-action") || "", m = s.get(e) || R || o; | ||
| if (s.set(e, m), f(e, m), u === "close") { | ||
| P(e, !0); | ||
| return; | ||
| } | ||
| const i = Se(r); | ||
| if (u === "request-review") { | ||
| E(e, "review", m, i.actor || m.defaultActor) && M(r, "Status changed to review."); | ||
| return; | ||
| } | ||
| if (u === "reopen-draft") { | ||
| E(e, "draft", m, i.actor || m.defaultActor) && M(r, "Status changed to draft."); | ||
| return; | ||
| } | ||
| if (u === "approve") { | ||
| const b = Q(e, m, i.actor, i.comment); | ||
| if (!b && m.requireCommentOnApprove) { | ||
| M(r, m.labels.approveCommentRequiredText); | ||
| return; | ||
| } | ||
| if (b) { | ||
| const $ = N(r, "comment"); | ||
| $ && ($.value = ""), M(r, "Document approved and signed off."); | ||
| } | ||
| return; | ||
| } | ||
| if (u === "add-comment") { | ||
| if (!pe(e, i.comment, i.actor, m)) return; | ||
| const $ = N(r, "comment"); | ||
| $ && ($.value = ""), M(r, "Comment added."); | ||
| return; | ||
| } | ||
| }), r.addEventListener("keydown", (a) => { | ||
| a.key === "Escape" && (a.preventDefault(), P(e, !0)); | ||
| }), K(r, e), document.body.appendChild(r), k.set(e, r), O.set(e, !1), q(e), r; | ||
| } | ||
| function Z(e) { | ||
| return O.get(e) === !0; | ||
| } | ||
| function A(e) { | ||
| D(); | ||
| const t = $e(e); | ||
| k.forEach((o, n) => { | ||
| n !== e && P(n, !1); | ||
| }), t.classList.add("show"), O.set(e, !0), C(e, "toggleApprovalWorkflowPanel", !0), K(t, e), V(e, t), q(e); | ||
| } | ||
| function P(e, t = !1) { | ||
| const o = k.get(e); | ||
| o && (o.classList.remove("show"), O.set(e, !1), C(e, "toggleApprovalWorkflowPanel", !1), t && e.focus({ preventScroll: !0 })); | ||
| } | ||
| function de(e, t) { | ||
| const o = Z(e); | ||
| return (typeof t == "boolean" ? t : !o) ? A(e) : P(e), !0; | ||
| } | ||
| function Ee(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "a"; | ||
| } | ||
| function Ce(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "r"; | ||
| } | ||
| function Te(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "p"; | ||
| } | ||
| function Le(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "d"; | ||
| } | ||
| function Re(e) { | ||
| R = e, T || (T = (t) => { | ||
| D(); | ||
| const n = t.target?.closest(w); | ||
| if (!n) return; | ||
| v = n; | ||
| const r = s.get(n) || e; | ||
| s.set(n, r), f(n, r); | ||
| const a = k.get(n); | ||
| a && (K(a, n), V(n, a)); | ||
| }, document.addEventListener("focusin", T, !0)), L || (L = (t) => { | ||
| if (t.defaultPrevented) return; | ||
| const o = Ee(t), n = Ce(t), r = Te(t), a = Le(t), l = t.key === "Escape"; | ||
| if (!l && !o && !n && !r && !a) | ||
| return; | ||
| D(); | ||
| const c = t.target, u = !!c?.closest(`.${d} input, .${d} textarea, .${d} select`); | ||
| if (!xe(c) && !we()) | ||
| return; | ||
| const i = x(void 0, !1); | ||
| if (!i) return; | ||
| const b = s.get(i) || R || e; | ||
| s.set(i, b); | ||
| const $ = f(i, b); | ||
| if (v = i, l && Z(i)) { | ||
| t.preventDefault(), P(i, !0); | ||
| return; | ||
| } | ||
| if (!u) { | ||
| if (o) { | ||
| t.preventDefault(), t.stopPropagation(), de(i); | ||
| return; | ||
| } | ||
| if (n) { | ||
| t.preventDefault(), t.stopPropagation(), E(i, "review", b, b.defaultActor) && A(i); | ||
| return; | ||
| } | ||
| if (r) { | ||
| t.preventDefault(), t.stopPropagation(), Q(i, b, b.defaultActor, "Approved via keyboard shortcut.") && A(i); | ||
| return; | ||
| } | ||
| a && (t.preventDefault(), t.stopPropagation(), $.status !== "draft" && E(i, "draft", b, b.defaultActor) && A(i)); | ||
| } | ||
| }, document.addEventListener("keydown", L, !0)), S || (S = () => { | ||
| D(), k.forEach((t, o) => { | ||
| !o.isConnected || !t.isConnected || (K(t, o), V(o, t)); | ||
| }); | ||
| }, window.addEventListener("scroll", S, !0), window.addEventListener("resize", S)); | ||
| } | ||
| function Me(e) { | ||
| const t = I.get(e); | ||
| t && (e.classList.remove("rte-approval-locked-editor"), e.removeAttribute("data-approval-status"), e.removeAttribute("data-approval-locked"), ie( | ||
| e, | ||
| t.preApprovalContentEditable ?? t.originalContentEditable, | ||
| t.preApprovalReadonly ?? t.originalReadonly | ||
| )); | ||
| } | ||
| function De() { | ||
| T && (document.removeEventListener("focusin", T, !0), T = null), L && (document.removeEventListener("keydown", L, !0), L = null), S && (window.removeEventListener("scroll", S, !0), window.removeEventListener("resize", S), S = null), k.forEach((e) => e.remove()), k.clear(), H.forEach((e) => Me(e)), H.clear(), R = null, v = null; | ||
| } | ||
| function He() { | ||
| if (typeof document > "u" || document.getElementById(te)) return; | ||
| const e = document.createElement("style"); | ||
| e.id = te, e.textContent = ` | ||
| .rte-toolbar-group-items.${h}, | ||
| .editora-toolbar-group-items.${h}, | ||
| .rte-toolbar-group-items.${y}, | ||
| .editora-toolbar-group-items.${y} { | ||
| display: flex; | ||
| border: 1px solid #ccc; | ||
| border-radius: 3px; | ||
| background: #fff; | ||
| } | ||
| .rte-toolbar-group-items.${h} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${h} .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${y} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${y} .editora-toolbar-button { | ||
| border: none; | ||
| border-radius: 0; | ||
| border-right: 1px solid #ccc; | ||
| } | ||
| .rte-toolbar-button[data-command="toggleApprovalWorkflowPanel"].active, | ||
| .editora-toolbar-button[data-command="toggleApprovalWorkflowPanel"].active, | ||
| .rte-toolbar-button[data-command="reopenDraft"].active, | ||
| .editora-toolbar-button[data-command="reopenDraft"].active { | ||
| background-color: #ccc; | ||
| } | ||
| ${g} .rte-toolbar-button[data-command="toggleApprovalWorkflowPanel"].active, | ||
| ${g} .editora-toolbar-button[data-command="toggleApprovalWorkflowPanel"].active, | ||
| ${g} .rte-toolbar-button[data-command="reopenDraft"].active, | ||
| ${g} .editora-toolbar-button[data-command="reopenDraft"].active { | ||
| background: linear-gradient(180deg, #5eaaf6 0%, #4a95de 100%); | ||
| } | ||
| .rte-toolbar-group-items.${h} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${h} .editora-toolbar-item:last-child .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${y} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${y} .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| ${g} .rte-toolbar-group-items.${h}, | ||
| ${g} .editora-toolbar-group-items.${h}, | ||
| ${g} .rte-toolbar-group-items.${y}, | ||
| ${g} .editora-toolbar-group-items.${y}, | ||
| .${d}.rte-approval-theme-dark { | ||
| border-color: #566275; | ||
| } | ||
| ${g} .rte-toolbar-group-items.${h} .rte-toolbar-button svg, | ||
| ${g} .editora-toolbar-group-items.${h} .editora-toolbar-button svg, | ||
| ${g} .rte-toolbar-group-items.${y} .rte-toolbar-button svg, | ||
| ${g} .editora-toolbar-group-items.${y} .editora-toolbar-button svg | ||
| { | ||
| fill: none; | ||
| } | ||
| ${g} .rte-toolbar-group-items.${h} .rte-toolbar-button, | ||
| ${g} .editora-toolbar-group-items.${h} .editora-toolbar-button | ||
| { | ||
| border-color: #566275; | ||
| } | ||
| .rte-approval-locked-editor { | ||
| background-image: repeating-linear-gradient( | ||
| -45deg, | ||
| rgba(30, 64, 175, 0.04), | ||
| rgba(30, 64, 175, 0.04) 8px, | ||
| rgba(30, 64, 175, 0.08) 8px, | ||
| rgba(30, 64, 175, 0.08) 16px | ||
| ); | ||
| } | ||
| .${d} { | ||
| position: fixed; | ||
| z-index: 1500; | ||
| right: 16px; | ||
| top: 16px; | ||
| width: min(420px, calc(100vw - 20px)); | ||
| max-height: calc(100vh - 24px); | ||
| display: none; | ||
| flex-direction: column; | ||
| border-radius: 12px; | ||
| border: 1px solid #d1d5db; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| box-shadow: 0 18px 38px rgba(15, 23, 42, 0.16); | ||
| overflow: hidden; | ||
| } | ||
| .${d}.show { | ||
| display: flex; | ||
| } | ||
| .${d}.rte-approval-theme-dark { | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| border-color: #334155; | ||
| box-shadow: 0 20px 40px rgba(2, 6, 23, 0.5); | ||
| } | ||
| .rte-approval-header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| padding: 10px 12px; | ||
| border-bottom: 1px solid #e2e8f0; | ||
| background: #f8fafc; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-header { | ||
| border-bottom-color: #334155; | ||
| background: #111827; | ||
| } | ||
| .rte-approval-title { | ||
| margin: 0; | ||
| font-size: 14px; | ||
| font-weight: 700; | ||
| } | ||
| .rte-approval-icon-btn { | ||
| border: 1px solid #cbd5e1; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| border-radius: 6px; | ||
| cursor: pointer; | ||
| min-width: 34px; | ||
| min-height: 34px; | ||
| width: 34px; | ||
| height: 34px; | ||
| padding: 0; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| font-weight: 600; | ||
| } | ||
| .rte-approval-icon-btn:hover, | ||
| .rte-approval-icon-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-icon-btn { | ||
| background: #0f172a; | ||
| border-color: #475569; | ||
| color: #e2e8f0; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-icon-btn:hover, | ||
| .${d}.rte-approval-theme-dark .rte-approval-icon-btn:focus-visible { | ||
| border-color: #60a5fa; | ||
| box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.24); | ||
| } | ||
| .rte-approval-body { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 10px; | ||
| padding: 12px; | ||
| overflow: auto; | ||
| } | ||
| .rte-approval-summary { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| color: #475569; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-summary { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-approval-controls { | ||
| display: flex; | ||
| flex-wrap: wrap; | ||
| gap: 8px; | ||
| } | ||
| .rte-approval-btn { | ||
| border: 1px solid #cbd5e1; | ||
| background: #f8fafc; | ||
| color: inherit; | ||
| border-radius: 8px; | ||
| padding: 6px 10px; | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| cursor: pointer; | ||
| } | ||
| .rte-approval-btn:disabled { | ||
| opacity: 0.5; | ||
| cursor: not-allowed; | ||
| } | ||
| .rte-approval-btn:hover:not(:disabled), | ||
| .rte-approval-btn:focus-visible:not(:disabled) { | ||
| outline: none; | ||
| border-color: #1d4ed8; | ||
| box-shadow: 0 0 0 2px rgba(29, 78, 216, 0.2); | ||
| } | ||
| .rte-approval-btn-primary { | ||
| background: #1d4ed8; | ||
| border-color: #1d4ed8; | ||
| color: #ffffff; | ||
| } | ||
| .rte-approval-btn-primary:hover:not(:disabled), | ||
| .rte-approval-btn-primary:focus-visible:not(:disabled) { | ||
| background: #1e40af; | ||
| border-color: #1e40af; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-btn { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #e2e8f0; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-btn-primary { | ||
| border-color: #2563eb; | ||
| background: #2563eb; | ||
| color: #ffffff; | ||
| } | ||
| .rte-approval-form { | ||
| display: grid; | ||
| grid-template-columns: 1fr; | ||
| gap: 8px; | ||
| border: 1px solid #e2e8f0; | ||
| border-radius: 10px; | ||
| padding: 8px; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-form { | ||
| border-color: #334155; | ||
| } | ||
| .rte-approval-label { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 4px; | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| } | ||
| .rte-approval-field { | ||
| width: 100%; | ||
| box-sizing: border-box; | ||
| min-height: 30px; | ||
| border-radius: 8px; | ||
| border: 1px solid #cbd5e1; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| font-size: 13px; | ||
| padding: 6px 8px; | ||
| } | ||
| .rte-approval-field:focus-visible { | ||
| outline: none; | ||
| border-color: #1d4ed8; | ||
| box-shadow: 0 0 0 2px rgba(29, 78, 216, 0.2); | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-field { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #e2e8f0; | ||
| } | ||
| .rte-approval-section { | ||
| border: 1px solid #e2e8f0; | ||
| border-radius: 10px; | ||
| padding: 8px; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-section { | ||
| border-color: #334155; | ||
| } | ||
| .rte-approval-section-title { | ||
| margin: 0 0 8px; | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| } | ||
| .rte-approval-comments-list, | ||
| .rte-approval-signoffs-list { | ||
| margin: 0; | ||
| padding: 0; | ||
| list-style: none; | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 6px; | ||
| max-height: 150px; | ||
| overflow: auto; | ||
| } | ||
| .rte-approval-item { | ||
| border: 1px solid #dbeafe; | ||
| background: #eff6ff; | ||
| border-radius: 8px; | ||
| padding: 6px; | ||
| } | ||
| .rte-approval-item-comment { | ||
| border-color: #e2e8f0; | ||
| background: #f8fafc; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-item { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| } | ||
| .rte-approval-item-head { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| margin-bottom: 4px; | ||
| } | ||
| .rte-approval-item-author { | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| } | ||
| .rte-approval-item-time { | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-item-time { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-approval-item-message { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| white-space: pre-wrap; | ||
| } | ||
| .rte-approval-empty { | ||
| border: 1px dashed #cbd5e1; | ||
| border-radius: 8px; | ||
| padding: 8px; | ||
| font-size: 12px; | ||
| color: #64748b; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-empty { | ||
| border-color: #334155; | ||
| color: #94a3b8; | ||
| } | ||
| .rte-approval-shortcut { | ||
| margin: 0; | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| } | ||
| .${d}.rte-approval-theme-dark .rte-approval-shortcut { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-approval-live { | ||
| position: absolute; | ||
| width: 1px; | ||
| height: 1px; | ||
| margin: -1px; | ||
| padding: 0; | ||
| overflow: hidden; | ||
| clip: rect(0 0 0 0); | ||
| border: 0; | ||
| } | ||
| @media (max-width: 768px) { | ||
| .${d} { | ||
| left: 10px !important; | ||
| right: 10px; | ||
| top: 10px !important; | ||
| width: auto !important; | ||
| max-height: calc(100vh - 20px); | ||
| } | ||
| } | ||
| `, document.head.appendChild(e); | ||
| } | ||
| const qe = (e = {}) => { | ||
| const t = z(e); | ||
| return He(), { | ||
| name: "approvalWorkflow", | ||
| toolbar: [ | ||
| { | ||
| id: "approvalWorkflowGroup", | ||
| label: "Approval", | ||
| type: "group", | ||
| command: "approvalWorkflow", | ||
| items: [ | ||
| { | ||
| id: "approvalWorkflow", | ||
| label: "Approval Workflow", | ||
| command: "toggleApprovalWorkflowPanel", | ||
| shortcut: "Mod-Alt-Shift-a", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><rect x="4" y="5" width="16" height="14" rx="2.5" stroke="currentColor" stroke-width="1.7"/><path d="M8 10h8M8 14h5" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/><path d="m16.5 16 1.8 1.8 3.2-3.2" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg>' | ||
| }, | ||
| { | ||
| id: "approvalRequestReview", | ||
| label: "Request Review", | ||
| command: "requestApprovalReview", | ||
| shortcut: "Mod-Alt-Shift-r", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><circle cx="11" cy="11" r="6.5" stroke="currentColor" stroke-width="1.7"/><path d="M11 8v3l2 2" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/><path d="M17.5 17.5 20 20" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/></svg>' | ||
| }, | ||
| { | ||
| id: "approvalApprove", | ||
| label: "Approve", | ||
| command: "approveDocument", | ||
| shortcut: "Mod-Alt-Shift-p", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M5 12.5 9.5 17 19 7.5" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/><rect x="3.8" y="3.8" width="16.4" height="16.4" rx="3" stroke="currentColor" stroke-width="1.4"/></svg>' | ||
| }, | ||
| { | ||
| id: "approvalReopen", | ||
| label: "Reopen Draft", | ||
| command: "reopenDraft", | ||
| shortcut: "Mod-Alt-Shift-d", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M8 8H4v4" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/><path d="M5 12a7 7 0 1 0 2-4.95" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/></svg>' | ||
| } | ||
| ] | ||
| } | ||
| ], | ||
| commands: { | ||
| approvalWorkflow: (o, n) => { | ||
| const r = x(n); | ||
| if (!r) return !1; | ||
| const a = s.get(r) || t; | ||
| return s.set(r, a), f(r, a), v = r, A(r), q(r), !0; | ||
| }, | ||
| toggleApprovalWorkflowPanel: (o, n) => { | ||
| const r = x(n); | ||
| if (!r) return !1; | ||
| const a = s.get(r) || t; | ||
| return s.set(r, a), f(r, a), v = r, de(r, typeof o == "boolean" ? o : void 0); | ||
| }, | ||
| requestApprovalReview: (o, n) => { | ||
| const r = x(n); | ||
| if (!r) return !1; | ||
| const a = s.get(r) || t; | ||
| s.set(r, a), f(r, a); | ||
| const l = E(r, "review", a, a.defaultActor); | ||
| return A(r), l; | ||
| }, | ||
| approveDocument: (o, n) => { | ||
| const r = x(n); | ||
| if (!r) return !1; | ||
| const a = s.get(r) || t; | ||
| s.set(r, a), f(r, a); | ||
| const l = typeof o == "object" && o ? String(o.author || "") : a.defaultActor, c = typeof o == "object" && o ? String(o.comment || "") : typeof o == "string" ? o : "", u = Q(r, a, l, c); | ||
| return u && A(r), u; | ||
| }, | ||
| reopenDraft: (o, n) => { | ||
| const r = x(n); | ||
| if (!r) return !1; | ||
| const a = s.get(r) || t; | ||
| s.set(r, a), f(r, a); | ||
| const l = E(r, "draft", a, a.defaultActor); | ||
| return l && A(r), l; | ||
| }, | ||
| addApprovalComment: (o, n) => { | ||
| const r = x(n); | ||
| if (!r) return !1; | ||
| const a = s.get(r) || t; | ||
| s.set(r, a), f(r, a); | ||
| const l = typeof o == "object" && o ? String(o.author || "") : a.defaultActor, c = typeof o == "object" && o ? String(o.message || "") : typeof o == "string" ? o : "", u = pe(r, c, l, a); | ||
| return u && A(r), u; | ||
| }, | ||
| setApprovalStatus: (o, n) => { | ||
| const r = x(n); | ||
| if (!r || !o) return !1; | ||
| const a = ne(o), l = s.get(r) || t; | ||
| s.set(r, l), f(r, l); | ||
| const c = E(r, a, l, l.defaultActor); | ||
| return c && A(r), c; | ||
| }, | ||
| setApprovalWorkflowOptions: (o, n) => { | ||
| const r = x(n); | ||
| if (!r || !o || typeof o != "object") return !1; | ||
| const a = s.get(r) || t, l = z({ | ||
| ...a, | ||
| ...o, | ||
| labels: { | ||
| ...a.labels, | ||
| ...o.labels || {} | ||
| }, | ||
| normalizeText: o.normalizeText || a.normalizeText | ||
| }); | ||
| s.set(r, l); | ||
| const c = f(r, l); | ||
| return G(r, c, l), !0; | ||
| }, | ||
| getApprovalWorkflowState: (o, n) => { | ||
| const r = x(n); | ||
| if (!r) return !1; | ||
| const a = s.get(r) || t; | ||
| s.set(r, a); | ||
| const l = f(r, a), c = se(l); | ||
| if (typeof o == "function") | ||
| try { | ||
| o(c); | ||
| } catch { | ||
| } | ||
| return r.__approvalWorkflowState = c, r.dispatchEvent( | ||
| new CustomEvent("editora:approval-state", { | ||
| bubbles: !0, | ||
| detail: { | ||
| state: c | ||
| } | ||
| }) | ||
| ), !0; | ||
| } | ||
| }, | ||
| keymap: { | ||
| "Mod-Alt-Shift-a": "toggleApprovalWorkflowPanel", | ||
| "Mod-Alt-Shift-A": "toggleApprovalWorkflowPanel", | ||
| "Mod-Alt-Shift-r": "requestApprovalReview", | ||
| "Mod-Alt-Shift-R": "requestApprovalReview", | ||
| "Mod-Alt-Shift-p": "approveDocument", | ||
| "Mod-Alt-Shift-P": "approveDocument", | ||
| "Mod-Alt-Shift-d": "reopenDraft", | ||
| "Mod-Alt-Shift-D": "reopenDraft" | ||
| }, | ||
| init: function(n) { | ||
| _ += 1; | ||
| const r = this && typeof this.__pluginConfig == "object" ? z({ ...t, ...this.__pluginConfig }) : t; | ||
| Re(r); | ||
| const a = x( | ||
| n?.editorElement ? { editorElement: n.editorElement } : void 0, | ||
| !1 | ||
| ); | ||
| a && (s.set(a, r), f(a, r), v = a, q(a)); | ||
| }, | ||
| destroy: () => { | ||
| _ = Math.max(0, _ - 1), !(_ > 0) && De(); | ||
| } | ||
| }; | ||
| }; | ||
| export { | ||
| qe as ApprovalWorkflowPlugin | ||
| }; |
| "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const v=".rte-content, .editora-content",fe="[data-editora-editor], .rte-editor, .editora-editor, editora-editor",ye="__editoraCommandEditorRoot",he="rte-blocks-library-styles",d="rte-blocks-library-panel",E="blocks-library",C="blocksLibrary",$=':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)',Pe=80,Be=new Set(["script","style","meta","link","object","embed","iframe"]),De=/^(https?:|mailto:|tel:|#|\/)/i,Oe=/^data:image\/(?:png|gif|jpeg|jpg|webp);base64,/i,Ne={panelTitle:"Blocks Library",panelAriaLabel:"Blocks library panel",searchLabel:"Search blocks",searchPlaceholder:"Search by name, category, or keyword",categoryLabel:"Category",allCategoriesText:"All categories",recentHeading:"Recent inserts",insertText:"Insert Selected",closeText:"Close",noResultsText:"No matching blocks found.",summaryPrefix:"Blocks",loadingText:"Loading blocks...",loadErrorText:"Unable to load blocks right now.",readonlyMessage:"Editor is read-only. Block insertion is disabled.",shortcutText:"Shortcuts: Ctrl/Cmd+Alt+Shift+B (panel), Ctrl/Cmd+Alt+Shift+L (insert last)",helperText:"Use Arrow keys to move through blocks, Enter to insert, Esc to close.",lastInsertedPrefix:"Last inserted",resultsListLabel:"Block results"},b=new WeakMap,J=new WeakMap,w=new WeakMap,I=new WeakMap,O=new WeakMap,j=new WeakMap,W=new WeakMap,z=new WeakMap,q=new WeakMap,te=new WeakMap,x=new Map,U=new WeakMap,oe=new Set;let X=0,Ke=0,ke=0,M=null,y=null,_=null,P=null,A=null,D=null;function m(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function je(e){return e.replace(/\u00A0/g," ").replace(/\s+/g," ").trim()}function We(e){return e.toLowerCase().replace(/[^a-z0-9_-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,80)}function ce(e){const t=e.trim();return t&&(De.test(t)||Oe.test(t))?t:""}function xe(e){let t=e;return Be.forEach(r=>{const o=new RegExp(`<${r}[\\s\\S]*?>[\\s\\S]*?<\\/${r}>`,"gi"),l=new RegExp(`<${r}\\b[^>]*\\/?>`,"gi");t=t.replace(o,"").replace(l,"")}),t=t.replace(/\son\w+=(\"[^\"]*\"|'[^']*'|[^\s>]+)/gi,"").replace(/\s(xmlns|xml:[^=\s>]+)\s*=\s*(\"[^\"]*\"|'[^']*'|[^\s>]+)/gi,"").replace(/\s(href|src|xlink:href)\s*=\s*("|\')\s*(?:javascript:|vbscript:|data:text\/html)[^"']*\2/gi,"").replace(/\s(href|src|xlink:href)\s*=\s*(?:javascript:|vbscript:|data:text\/html)[^\s>]*/gi,"").replace(/\s(href|src|xlink:href)\s*=\s*("([^"]*)"|'([^']*)')/gi,(r,o,l,n,a)=>{const s=typeof n=="string"&&n.length>0?n:a||"",i=ce(s);if(!i)return"";const c=l.startsWith('"')?'"':"'";return` ${o}=${c}${i}${c}`}).replace(/\s(href|src|xlink:href)\s*=\s*([^\s>]+)/gi,(r,o,l)=>{const n=ce(l);return n?` ${o}="${n}"`:""}).replace(/\sstyle\s*=\s*("([^"]*)"|'([^']*)')/gi,(r,o,l,n)=>{const a=typeof l=="string"&&l.length>0?l:n||"";if(/expression\s*\(|javascript\s*:|vbscript\s*:|url\s*\(/i.test(a))return"";const s=o.startsWith('"')?'"':"'";return` style=${s}${a}${s}`}).trim(),t}function Fe(e){if(!e)return"";if(typeof document>"u")return xe(e);const t=document.createElement("template");t.innerHTML=e;const r=t.content;return!r||typeof r.querySelectorAll!="function"?xe(e):(Array.from(r.querySelectorAll("*")).forEach(l=>{const n=l.tagName.toLowerCase();if(Be.has(n)){l.remove();return}Array.from(l.attributes).forEach(s=>{const i=s.name.toLowerCase(),c=s.value;if(i.startsWith("on")){l.removeAttribute(s.name);return}if(i==="style"){/expression\s*\(|javascript\s*:|vbscript\s*:|url\s*\(/i.test(c)&&l.removeAttribute(s.name);return}if(i==="href"||i==="src"||i==="xlink:href"){const u=ce(c);if(!u){l.removeAttribute(s.name);return}u!==c&&l.setAttribute(s.name,u)}})}),t.innerHTML.trim())}function ne(e){return e.trim().toLowerCase()}function Ge(e){if(!e)return"";if(typeof document>"u")return e.replace(/<[^>]*>/g," ").replace(/\s+/g," ").trim();const t=document.createElement("template");t.innerHTML=e;const r=t.content;return!r||typeof r.textContent!="string"?e.replace(/<[^>]*>/g," ").replace(/\s+/g," ").trim():r.textContent.replace(/\s+/g," ").trim()}function Ce(e,t){if(!Array.isArray(e)||e.length===0)return[];const r=new Set,o=[];return e.forEach(l=>{const n=t.normalizeText(l.label||""),a=t.sanitizeBlockHtml(l.html||"",l).trim();if(!n||!a)return;const s=t.normalizeText(l.category||"General")||"General",i=ne(s);let u=We(t.normalizeText(l.id||n))||`block-${ke++}`;for(;r.has(u);)u=`${u}-${ke++}`;r.add(u);const f=(l.tags||[]).map(H=>t.normalizeText(H)).filter(Boolean),g=(l.keywords||[]).map(H=>t.normalizeText(H)).filter(Boolean),h=t.normalizeText(l.description||""),R=Ge(a),V=[n,h,s,...f,...g,R].join(" ").toLowerCase();o.push({id:u,label:n,html:a,description:h,category:s,categoryKey:i,tags:f,keywords:g,previewText:R,searchBlob:V})}),o}function Q(e={}){const t=e.normalizeText||je,r=e.sanitizeBlockHtml||Fe,o={blocks:[],defaultCategory:t(e.defaultCategory||""),maxResults:Math.max(4,Math.min(300,Number(e.maxResults??80))),maxRecentBlocks:Math.max(1,Math.min(20,Number(e.maxRecentBlocks??6))),debounceMs:Math.max(0,Math.min(700,Number(e.debounceMs??90))),cacheTtlMs:Math.max(0,Number(e.cacheTtlMs??6e4)),labels:{...Ne,...e.labels||{}},normalizeText:t,sanitizeBlockHtml:r,getBlocks:typeof e.getBlocks=="function"?e.getBlocks:void 0};return o.blocks=Ce(e.blocks,o),o}function Ue(e){return{blocks:e.blocks.map(t=>({id:t.id,label:t.label,html:t.html,description:t.description||void 0,category:t.category||void 0,tags:t.tags.length?[...t.tags]:void 0,keywords:t.keywords.length?[...t.keywords]:void 0})),defaultCategory:e.defaultCategory,maxResults:e.maxResults,maxRecentBlocks:e.maxRecentBlocks,debounceMs:e.debounceMs,cacheTtlMs:e.cacheTtlMs,labels:{...e.labels},normalizeText:e.normalizeText,sanitizeBlockHtml:e.sanitizeBlockHtml,getBlocks:e.getBlocks}}function le(e){return e.closest(fe)||e}function G(e){if(!e)return null;if(e.matches(v))return e;const t=e.querySelector(v);return t instanceof HTMLElement?t:null}function Ve(){if(typeof window>"u")return null;const e=window[ye];if(!(e instanceof HTMLElement))return null;window[ye]=null;const t=G(e);if(t)return t;const r=e.closest(fe);if(r){const l=G(r);if(l)return l}const o=e.closest(v);return o instanceof HTMLElement?o:null}function Ye(e){const t=e.closest("[data-editora-editor]");if(t&&G(t)===e)return t;let r=e;for(;r;){if(r.matches(fe)&&(r===e||G(r)===e))return r;r=r.parentElement}return le(e)}function $e(e){return e?e.nodeType===Node.ELEMENT_NODE?e:e.parentElement:null}function ee(){Array.from(oe).forEach(t=>{t.isConnected||ge(t)})}function S(e,t=!0,r=!0){if(ee(),e?.contentElement instanceof HTMLElement)return e.contentElement;if(e?.editorElement instanceof HTMLElement){const a=G(e.editorElement);if(a)return a}const o=Ve();if(o)return o;const l=window.getSelection();if(l&&l.rangeCount>0){const s=$e(l.getRangeAt(0).startContainer)?.closest(v);if(s)return s}const n=document.activeElement;if(n){if(n.matches(v))return n;const a=n.closest(v);if(a)return a}if(r){if(y&&y.isConnected)return y;y&&!y.isConnected&&(y=null)}return t?document.querySelector(v):null}function Xe(e){const t=e.target;if(t){const o=t.closest(v);if(o)return o}const r=window.getSelection();if(r&&r.rangeCount>0){const l=$e(r.getRangeAt(0).startContainer)?.closest(v);if(l)return l}return null}function Z(e){return e?(e.getAttribute("data-theme")||e.getAttribute("theme")||"").toLowerCase()==="dark"?!0:e.classList.contains("dark")||e.classList.contains("editora-theme-dark")||e.classList.contains("rte-theme-dark"):!1}function Ze(e){const t=le(e);if(Z(t))return!0;const r=t.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark");return Z(r)?!0:Z(document.documentElement)||Z(document.body)}function re(e,t){e.classList.remove("rte-blocks-library-theme-dark"),Ze(t)&&e.classList.add("rte-blocks-library-theme-dark")}function Se(e){return e.getAttribute("contenteditable")==="false"||e.getAttribute("data-readonly")==="true"}function we(e,t,r){const o=Ye(e);Array.from(o.querySelectorAll(`.rte-toolbar-button[data-command="${t}"], .editora-toolbar-button[data-command="${t}"]`)).forEach(n=>{n.classList.toggle("active",r),n.setAttribute("data-active",r?"true":"false"),n.setAttribute("aria-pressed",r?"true":"false")})}function Ee(e,t){const r=e.querySelector(".rte-blocks-library-live");r&&(r.textContent=t)}function se(e){const t=Re(e);if(t)try{q.set(e,t.cloneRange())}catch{}}function Te(e){const t=q.get(e);if(!t)return null;if(!e.isConnected)return q.delete(e),null;try{const r=t.cloneRange();return e.contains(r.commonAncestorContainer)?r:(q.delete(e),null)}catch{return q.delete(e),null}}function Je(e){const t=Te(e);return t?(He(e,t),!0):!1}function Qe(e){if(te.has(e))return;const t=()=>{const r=window.getSelection();if(!r||r.rangeCount===0)return;const o=r.getRangeAt(0);e.contains(o.commonAncestorContainer)&&se(e)};e.addEventListener("keyup",t),e.addEventListener("mouseup",t),e.addEventListener("touchend",t),te.set(e,t)}function et(e){const t=te.get(e);t&&(e.removeEventListener("keyup",t),e.removeEventListener("mouseup",t),e.removeEventListener("touchend",t),te.delete(e))}function k(e,t){b.has(e)||b.set(e,t),I.has(e)||(I.set(e,t.blocks),O.set(e,Date.now()));let r=w.get(e);return r||(r={query:"",category:t.defaultCategory?ne(t.defaultCategory):"all",selectedBlockId:null,recentBlockIds:[],lastInsertedBlockId:null,loading:!1,loadError:null,totalMatches:0,visibleMatches:0,filterCache:new Map,debounceTimer:null},w.set(e,r)),oe.add(e),Qe(e),r}function Me(e){const t=w.get(e);!t||t.debounceTimer===null||(window.clearTimeout(t.debounceTimer),t.debounceTimer=null)}function ge(e){Me(e),et(e),q.delete(e);const t=W.get(e);t&&(t.abort(),W.delete(e)),j.delete(e),z.delete(e),x.get(e)?.remove(),x.delete(e),U.delete(e),b.delete(e),J.delete(e),w.delete(e),I.delete(e),O.delete(e),oe.delete(e),y===e&&(y=null)}function tt(e){for(let t=0;t<e.length;t+=1){const r=e[t];if(!(r.type!=="childList"||r.removedNodes.length===0))for(let o=0;o<r.removedNodes.length;o+=1){const l=r.removedNodes[o];if(l.nodeType!==Node.ELEMENT_NODE)continue;const n=l;if(n.matches?.(v)||n.matches?.(`.${d}`)||n.querySelector?.(v)||n.querySelector?.(`.${d}`))return!0}}return!1}function pe(e){return U.get(e)===!0}function ue(e,t){if(!t.classList.contains("show"))return;const r=le(e).getBoundingClientRect(),o=Math.min(window.innerWidth-20,420),l=Math.max(10,window.innerWidth-o-10),n=Math.min(Math.max(10,r.right-o),l),a=Math.max(10,Math.min(window.innerHeight-10,r.top+12));t.style.width=`${o}px`,t.style.left=`${n}px`,t.style.top=`${a}px`,t.style.maxHeight=`${Math.max(260,window.innerHeight-20)}px`}function ae(e){return I.get(e)||b.get(e)?.blocks||[]}function rt(e,t){const r=new Map;ae(e).forEach(l=>{r.has(l.categoryKey)||r.set(l.categoryKey,l.category)});const o=Array.from(r.entries()).sort((l,n)=>l[1].localeCompare(n[1])).map(([l,n])=>({value:l,label:n}));return[{value:"all",label:t.labels.allCategoriesText},...o]}function Ae(e,t){const r=k(e,t),o=ae(e),l=r.query.trim().toLowerCase(),n=r.category||"all",a=`${l}|${n}|${t.maxResults}`,s=r.filterCache.get(a);if(s){const u=new Map(o.map(g=>[g.id,g])),f=s.ids.map(g=>u.get(g)).filter(Boolean);return r.totalMatches=s.total,r.visibleMatches=f.length,f}const i=[];let c=0;for(let u=0;u<o.length;u+=1){const f=o[u];n!=="all"&&f.categoryKey!==n||l&&!f.searchBlob.includes(l)||(c+=1,i.length<t.maxResults&&i.push(f))}if(r.totalMatches=c,r.visibleMatches=i.length,r.filterCache.set(a,{ids:i.map(u=>u.id),total:c}),r.filterCache.size>Pe){const u=r.filterCache.keys().next().value;typeof u=="string"&&r.filterCache.delete(u)}return i}function ot(e,t){const r=w.get(e);if(!r)return;if(t.length===0){r.selectedBlockId=null;return}t.some(l=>l.id===r.selectedBlockId)||(r.selectedBlockId=t[0].id)}function N(e){const t=w.get(e);we(e,"toggleBlocksLibraryPanel",pe(e)),we(e,"insertLastBlockSnippet",!!t?.lastInsertedBlockId)}function L(e){const t=x.get(e),r=b.get(e)||M,o=w.get(e);if(!t||!r||!o)return;re(t,e);const l=t.querySelector(".rte-blocks-library-title");l&&(l.textContent=r.labels.panelTitle);const n=t.querySelector('[data-action="close"]');n&&(n.setAttribute("aria-label",r.labels.closeText),n.textContent="✕");const a=t.querySelector(".rte-blocks-library-search-label");a&&(a.textContent=r.labels.searchLabel);const s=t.querySelector('[data-field="query"]');s&&(s.setAttribute("placeholder",r.labels.searchPlaceholder),s.value!==o.query&&(s.value=o.query));const i=t.querySelector(".rte-blocks-library-category-label");i&&(i.textContent=r.labels.categoryLabel);const c=t.querySelector('[data-field="category"]');if(c){const B=rt(e,r);c.innerHTML=B.map(p=>`<option value="${m(p.value)}">${m(p.label)}</option>`).join(""),B.some(p=>p.value===o.category)||(o.category="all"),c.value=o.category}const u=t.querySelector(".rte-blocks-library-helper");u&&(u.textContent=r.labels.helperText);const f=t.querySelector('.rte-blocks-library-list[role="listbox"]');f&&f.setAttribute("aria-label",r.labels.resultsListLabel);const g=t.querySelector(".rte-blocks-library-shortcut");g&&(g.textContent=r.labels.shortcutText);const h=t.querySelector('[data-action="insert-selected"]');if(h){h.textContent=r.labels.insertText;const B=!Se(e)&&!!o.selectedBlockId;h.disabled=!B,h.setAttribute("aria-disabled",B?"false":"true")}const R=t.querySelector(".rte-blocks-library-empty"),V=t.querySelector(".rte-blocks-library-list"),H=Ae(e,r);ot(e,H);const Y=t.querySelector(".rte-blocks-library-status");if(Y&&(o.loading?Y.textContent=r.labels.loadingText:o.loadError?Y.textContent=o.loadError:Y.textContent=`${r.labels.summaryPrefix}: ${o.visibleMatches}/${o.totalMatches}`),V){const B=new Set(o.recentBlockIds);V.innerHTML=H.map(p=>{const ie=o.selectedBlockId===p.id,qe=p.tags.length?` • ${p.tags.join(", ")}`:"",_e=B.has(p.id),me=p.previewText.slice(0,180);return` | ||
| <li class="rte-blocks-library-item-wrapper" role="presentation"> | ||
| <button | ||
| type="button" | ||
| class="rte-blocks-library-item${ie?" active":""}" | ||
| data-block-id="${m(p.id)}" | ||
| role="option" | ||
| aria-selected="${ie?"true":"false"}" | ||
| aria-label="${m(p.label)}" | ||
| tabindex="${ie?"0":"-1"}" | ||
| > | ||
| <span class="rte-blocks-library-item-head"> | ||
| <span class="rte-blocks-library-item-label">${m(p.label)}</span> | ||
| ${_e?`<span class="rte-blocks-library-recent-pill">${m(r.labels.recentHeading)}</span>`:""} | ||
| </span> | ||
| <span class="rte-blocks-library-item-meta">${m(p.category)}${m(qe)}</span> | ||
| ${p.description?`<span class="rte-blocks-library-item-description">${m(p.description)}</span>`:""} | ||
| ${me?`<span class="rte-blocks-library-item-preview">${m(me)}</span>`:""} | ||
| </button> | ||
| </li> | ||
| `}).join("")}R&&(R.hidden=H.length>0,R.textContent=r.labels.noResultsText);const K=t.querySelector(".rte-blocks-library-last-inserted");if(K)if(o.lastInsertedBlockId){const B=ae(e).find(p=>p.id===o.lastInsertedBlockId);B?(K.hidden=!1,K.textContent=`${r.labels.lastInsertedPrefix}: ${B.label}`):K.hidden=!0}else K.hidden=!0;t.setAttribute("aria-label",r.labels.panelAriaLabel)}function T(e,t=!1){const r=x.get(e);r&&(r.classList.remove("show"),U.set(e,!1),N(e),t&&(e.focus({preventScroll:!0}),Je(e)))}function nt(e){e.querySelector(".rte-blocks-library-item.active")?.focus()}function ve(e,t){const r=b.get(e)||M;if(!r)return;const o=w.get(e);if(!o)return;const l=Ae(e,r);if(l.length===0)return;const a=(Math.max(0,l.findIndex(i=>i.id===o.selectedBlockId))+t+l.length)%l.length;o.selectedBlockId=l[a].id,L(e);const s=x.get(e);s&&nt(s)}function de(e){const t=ct(e);se(e),x.forEach((o,l)=>{l!==e&&T(l,!1)}),t.classList.add("show"),U.set(e,!0),L(e),ue(e,t),N(e),t.querySelector('[data-field="query"]')?.focus(),be(e,!1)}function Ie(e,t){const r=pe(e);return(typeof t=="boolean"?t:!r)?de(e):T(e,!1),!0}function Re(e){const t=window.getSelection();if(!t||t.rangeCount===0)return null;const r=t.getRangeAt(0);return e.contains(r.commonAncestorContainer)?r:null}function He(e,t){if(!e.isConnected)return;const r=window.getSelection();r&&(r.removeAllRanges(),r.addRange(t))}function Le(e,t,r){const o=t.cloneRange();if(!e.contains(o.commonAncestorContainer))return!1;o.deleteContents();const l=document.createElement("template");l.innerHTML=r;const n=l.content;if(!n)return!1;const a=n.lastChild;if(o.insertNode(n),a){const s=document.createRange();s.setStartAfter(a),s.collapse(!0),He(e,s)}return se(e),!0}function lt(e,t){e.focus({preventScroll:!0});const r=Te(e);if(r&&Le(e,r,t))return!0;try{if(document.execCommand("insertHTML",!1,t))return se(e),!0}catch{}const o=Re(e);return o?Le(e,o,t):!1}function st(e,t){if(t===e.innerHTML)return;const r=window.execEditorCommand||window.executeEditorCommand;if(typeof r=="function")try{r("recordDomTransaction",e,t,e.innerHTML)}catch{}}function at(e){e.dispatchEvent(new Event("input",{bubbles:!0}))}function F(e,t){const r=b.get(e)||M;if(!r)return!1;const o=k(e,r),l=x.get(e);if(Se(e))return l&&Ee(l,r.labels.readonlyMessage),!1;const n=ae(e).find(i=>i.id===t);if(!n)return!1;const a=e.innerHTML;return lt(e,n.html)?(o.lastInsertedBlockId=n.id,o.selectedBlockId=n.id,o.recentBlockIds=[n.id,...o.recentBlockIds.filter(i=>i!==n.id)].slice(0,r.maxRecentBlocks),st(e,a),at(e),N(e),e.dispatchEvent(new CustomEvent("editora:blocks-library-insert",{bubbles:!0,detail:{blockId:n.id,label:n.label,category:n.category}})),L(e),l&&Ee(l,`${r.labels.lastInsertedPrefix}: ${n.label}`),!0):!1}function ze(e){const t=w.get(e);return t?.lastInsertedBlockId?F(e,t.lastInsertedBlockId):!1}function it(e){const t=b.get(e)||M;if(!t)return;const r=w.get(e);if(!r)return;Me(e);const o=()=>{r.debounceTimer=null,r.filterCache.clear(),L(e)};if(t.debounceMs<=0){o();return}r.debounceTimer=window.setTimeout(o,t.debounceMs)}function ct(e){const t=x.get(e);if(t)return t;const r=b.get(e)||M||Q(),o=k(e,r),l=`rte-blocks-library-panel-${Ke++}`,n=`${l}-query`,a=`${l}-category`,s=document.createElement("section");return s.className=d,s.id=l,s.setAttribute("role","dialog"),s.setAttribute("aria-modal","false"),s.setAttribute("aria-label",r.labels.panelAriaLabel),s.innerHTML=` | ||
| <header class="rte-blocks-library-header"> | ||
| <h2 class="rte-blocks-library-title">${m(r.labels.panelTitle)}</h2> | ||
| <button type="button" class="rte-blocks-library-icon-btn" data-action="close" aria-label="${m(r.labels.closeText)}">✕</button> | ||
| </header> | ||
| <div class="rte-blocks-library-body"> | ||
| <label class="rte-blocks-library-search-label" for="${m(n)}"></label> | ||
| <input id="${m(n)}" class="rte-blocks-library-input" type="text" data-field="query" autocomplete="off" /> | ||
| <label class="rte-blocks-library-category-label" for="${m(a)}"></label> | ||
| <select id="${m(a)}" class="rte-blocks-library-select" data-field="category"></select> | ||
| <p class="rte-blocks-library-status" aria-live="polite"></p> | ||
| <p class="rte-blocks-library-helper"></p> | ||
| <p class="rte-blocks-library-last-inserted" hidden></p> | ||
| <div class="rte-blocks-library-list-wrap"> | ||
| <ul class="rte-blocks-library-list" role="listbox" aria-label="${m(r.labels.resultsListLabel)}"></ul> | ||
| <p class="rte-blocks-library-empty" hidden></p> | ||
| </div> | ||
| <div class="rte-blocks-library-actions"> | ||
| <button type="button" class="rte-blocks-library-btn rte-blocks-library-btn-primary" data-action="insert-selected"></button> | ||
| </div> | ||
| <p class="rte-blocks-library-shortcut"></p> | ||
| </div> | ||
| <div class="rte-blocks-library-live" aria-live="polite" aria-atomic="true"></div> | ||
| `,s.addEventListener("click",i=>{const c=i.target,u=c?.closest("[data-action]");if(u){const h=u.getAttribute("data-action");if(h==="close"){T(e,!0);return}if(h==="insert-selected"){if(!o.selectedBlockId)return;F(e,o.selectedBlockId)&&T(e,!0)}return}const f=c?.closest("[data-block-id]");if(!f)return;const g=f.getAttribute("data-block-id");g&&(o.selectedBlockId=g,L(e),i.detail>=2&&F(e,g)&&T(e,!0))}),s.addEventListener("input",i=>{const c=i.target;!(c instanceof HTMLInputElement)||c.getAttribute("data-field")!=="query"||(o.query=r.normalizeText(c.value).toLowerCase(),o.filterCache.clear(),it(e))}),s.addEventListener("change",i=>{const c=i.target;!(c instanceof HTMLSelectElement)||c.getAttribute("data-field")!=="category"||(o.category=ne(c.value||"all")||"all",o.filterCache.clear(),L(e))}),s.addEventListener("keydown",i=>{if(i.key==="Escape"){i.preventDefault(),T(e,!0);return}if(i.key==="ArrowDown"){i.preventDefault(),ve(e,1);return}if(i.key==="ArrowUp"){i.preventDefault(),ve(e,-1);return}if(i.key==="Enter"){if(!i.target?.matches('[data-field="query"], [data-field="category"], [data-block-id]')||!o.selectedBlockId)return;i.preventDefault(),F(e,o.selectedBlockId)&&T(e,!0)}}),re(s,e),document.body.appendChild(s),x.set(e,s),U.set(e,!1),L(e),s}function ut(e){const t=w.get(e);return{query:t?.query||"",category:t?.category||"all",selectedBlockId:t?.selectedBlockId||null,totalMatches:t?.totalMatches||0,visibleMatches:t?.visibleMatches||0,recentBlockIds:t?.recentBlockIds?[...t.recentBlockIds]:[],lastInsertedBlockId:t?.lastInsertedBlockId||null,loading:t?.loading===!0,loadError:t?.loadError||null}}async function be(e,t){const r=b.get(e)||M;if(!r||typeof r.getBlocks!="function")return;const o=k(e,r),l=O.get(e)||0;if(!t&&r.cacheTtlMs>0&&Date.now()-l<r.cacheTtlMs)return;const n=j.get(e);if(n&&!t)return n;const a=W.get(e);a&&a.abort(),t&&n&&j.delete(e);const s=new AbortController;W.set(e,s);const i=(z.get(e)||0)+1;z.set(e,i),o.loading=!0,o.loadError=null,L(e);const c=Promise.resolve().then(async()=>{const u={editor:e,editorRoot:le(e),signal:s.signal},f=await r.getBlocks?.(u);if(s.signal.aborted||z.get(e)!==i)return;const g=Ce(f||[],r);I.set(e,g),O.set(e,Date.now());const h=w.get(e);h&&(h.loading=!1,h.loadError=null,h.filterCache.clear())}).catch(()=>{if(s.signal.aborted||z.get(e)!==i)return;const u=w.get(e);u&&(u.loading=!1,u.loadError=r.labels.loadErrorText)}).finally(()=>{z.get(e)===i&&(j.delete(e),W.delete(e)),L(e)});return j.set(e,c),c}function dt(e){const t=e.key.toLowerCase();return(e.metaKey||e.ctrlKey)&&e.altKey&&e.shiftKey&&t==="b"}function bt(e){const t=e.key.toLowerCase();return(e.metaKey||e.ctrlKey)&&e.altKey&&e.shiftKey&&t==="l"}function ft(e){M=e,_||(_=t=>{ee();const o=t.target?.closest(v);if(!o)return;const l=b.get(o)||e;k(o,l),b.set(o,l),y=o,N(o);const n=x.get(o);n&&(re(n,o),ue(o,n),L(o))},document.addEventListener("focusin",_,!0)),P||(P=t=>{if(t.defaultPrevented)return;const r=`.${d} input, .${d} textarea, .${d} select`,o=t.target;if(o?.closest(r)){if(t.key==="Escape"){const a=o.closest(`.${d}`),s=Array.from(x.entries()).find(([,i])=>i===a);s&&(t.preventDefault(),T(s[0],!0))}return}const l=Xe(t);if(!l)return;const n=b.get(l)||M||e;if(k(l,n),b.set(l,n),y=l,t.key==="Escape"&&pe(l)){t.preventDefault(),T(l,!0);return}if(dt(t)){t.preventDefault(),t.stopPropagation(),Ie(l);return}bt(t)&&(t.preventDefault(),t.stopPropagation(),ze(l))},document.addEventListener("keydown",P,!0)),A||(A=()=>{ee(),x.forEach((t,r)=>{!r.isConnected||!t.isConnected||(re(t,r),ue(r,t))})},window.addEventListener("scroll",A,!0),window.addEventListener("resize",A)),!D&&typeof MutationObserver<"u"&&document.body&&(D=new MutationObserver(t=>{tt(t)&&ee()}),D.observe(document.body,{childList:!0,subtree:!0}))}function gt(){_&&(document.removeEventListener("focusin",_,!0),_=null),P&&(document.removeEventListener("keydown",P,!0),P=null),A&&(window.removeEventListener("scroll",A,!0),window.removeEventListener("resize",A),A=null),D&&(D.disconnect(),D=null),x.forEach(t=>t.remove()),x.clear(),Array.from(oe).forEach(t=>ge(t)),M=null,y=null}function pt(){if(typeof document>"u"||document.getElementById(he))return;const e=document.createElement("style");e.id=he,e.textContent=` | ||
| .rte-toolbar-group-items.${E}, | ||
| .editora-toolbar-group-items.${E}, | ||
| .rte-toolbar-group-items.${C}, | ||
| .editora-toolbar-group-items.${C} { | ||
| display: flex; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 4px; | ||
| background: #ffffff; | ||
| } | ||
| .rte-toolbar-group-items.${E} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${E} .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${C} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${C} .editora-toolbar-button { | ||
| border: none; | ||
| border-right: 1px solid #cbd5e1; | ||
| border-radius: 0; | ||
| } | ||
| .rte-toolbar-group-items.${E} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${E} .editora-toolbar-item:last-child .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${C} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${C} .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| .rte-toolbar-button[data-command="insertLastBlockSnippet"].active, | ||
| .editora-toolbar-button[data-command="insertLastBlockSnippet"].active { | ||
| background: rgba(15, 118, 110, 0.12); | ||
| } | ||
| ${$} .rte-toolbar-group-items.${E}, | ||
| ${$} .editora-toolbar-group-items.${E}, | ||
| ${$} .rte-toolbar-group-items.${C}, | ||
| ${$} .editora-toolbar-group-items.${C} { | ||
| border-color: #566275; | ||
| } | ||
| ${$} .rte-toolbar-group-items.${E} .rte-toolbar-button svg, | ||
| ${$} .editora-toolbar-group-items.${E} .editora-toolbar-button svg, | ||
| ${$} .rte-toolbar-group-items.${C} .rte-toolbar-button svg, | ||
| ${$} .editora-toolbar-group-items.${C} .editora-toolbar-button svg | ||
| { | ||
| fill: none; | ||
| } | ||
| ${$} .rte-toolbar-group-items.${E} .rte-toolbar-button, | ||
| ${$} .editora-toolbar-group-items.${E} .editora-toolbar-button | ||
| { | ||
| border-color: #566275; | ||
| } | ||
| .${d} { | ||
| position: fixed; | ||
| z-index: 12000; | ||
| display: none; | ||
| width: min(420px, calc(100vw - 20px)); | ||
| max-height: calc(100vh - 20px); | ||
| border: 1px solid #d1d5db; | ||
| border-radius: 14px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| box-shadow: 0 24px 48px rgba(15, 23, 42, 0.24); | ||
| overflow: hidden; | ||
| } | ||
| .${d}.show { | ||
| display: flex; | ||
| flex-direction: column; | ||
| } | ||
| .${d}.rte-blocks-library-theme-dark { | ||
| border-color: #334155; | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| box-shadow: 0 24px 52px rgba(2, 6, 23, 0.68); | ||
| } | ||
| .rte-blocks-library-header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| padding: 12px 14px; | ||
| border-bottom: 1px solid #e2e8f0; | ||
| background: linear-gradient(180deg, #f8fafc 0%, #f1f5f9 100%); | ||
| } | ||
| .${d}.rte-blocks-library-theme-dark .rte-blocks-library-header { | ||
| border-color: #1e293b; | ||
| background: linear-gradient(180deg, #111827 0%, #0f172a 100%); | ||
| } | ||
| .rte-blocks-library-title { | ||
| margin: 0; | ||
| font-size: 15px; | ||
| line-height: 1.2; | ||
| font-weight: 700; | ||
| } | ||
| .rte-blocks-library-icon-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| min-height: 34px; | ||
| min-width: 34px; | ||
| width: 34px; | ||
| height: 34px; | ||
| padding: 0; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| font-weight: 600; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| cursor: pointer; | ||
| } | ||
| .rte-blocks-library-icon-btn:hover, | ||
| .rte-blocks-library-icon-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .${d}.rte-blocks-library-theme-dark .rte-blocks-library-icon-btn { | ||
| border-color: #475569; | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| } | ||
| .${d}.rte-blocks-library-theme-dark .rte-blocks-library-icon-btn:hover, | ||
| .${d}.rte-blocks-library-theme-dark .rte-blocks-library-icon-btn:focus-visible { | ||
| border-color: #60a5fa; | ||
| box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.24); | ||
| } | ||
| .rte-blocks-library-body { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 8px; | ||
| padding: 12px; | ||
| overflow: auto; | ||
| } | ||
| .rte-blocks-library-search-label, | ||
| .rte-blocks-library-category-label { | ||
| font-size: 12px; | ||
| line-height: 1.3; | ||
| font-weight: 700; | ||
| color: #334155; | ||
| } | ||
| .${d}.rte-blocks-library-theme-dark .rte-blocks-library-search-label, | ||
| .${d}.rte-blocks-library-theme-dark .rte-blocks-library-category-label { | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-blocks-library-input, | ||
| .rte-blocks-library-select { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| min-height: 34px; | ||
| padding: 0 10px; | ||
| font-size: 13px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| } | ||
| .rte-blocks-library-input:focus-visible, | ||
| .rte-blocks-library-select:focus-visible { | ||
| border-color: #0f766e; | ||
| box-shadow: 0 0 0 3px rgba(15, 118, 110, 0.18); | ||
| outline: none; | ||
| } | ||
| .${d}.rte-blocks-library-theme-dark .rte-blocks-library-input, | ||
| .${d}.rte-blocks-library-theme-dark .rte-blocks-library-select { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #e2e8f0; | ||
| } | ||
| .rte-blocks-library-status, | ||
| .rte-blocks-library-helper, | ||
| .rte-blocks-library-shortcut, | ||
| .rte-blocks-library-last-inserted { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #475569; | ||
| } | ||
| .rte-blocks-library-last-inserted { | ||
| font-weight: 600; | ||
| color: #0f766e; | ||
| } | ||
| .${d}.rte-blocks-library-theme-dark .rte-blocks-library-status, | ||
| .${d}.rte-blocks-library-theme-dark .rte-blocks-library-helper, | ||
| .${d}.rte-blocks-library-theme-dark .rte-blocks-library-shortcut { | ||
| color: #94a3b8; | ||
| } | ||
| .${d}.rte-blocks-library-theme-dark .rte-blocks-library-last-inserted { | ||
| color: #5eead4; | ||
| } | ||
| .rte-blocks-library-list-wrap { | ||
| border: 1px solid #e2e8f0; | ||
| border-radius: 10px; | ||
| padding: 6px; | ||
| background: #f8fafc; | ||
| max-height: min(44vh, 360px); | ||
| overflow: auto; | ||
| } | ||
| .${d}.rte-blocks-library-theme-dark .rte-blocks-library-list-wrap { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| } | ||
| .rte-blocks-library-list { | ||
| margin: 0; | ||
| padding: 0; | ||
| list-style: none; | ||
| display: grid; | ||
| gap: 6px; | ||
| } | ||
| .rte-blocks-library-item-wrapper { | ||
| margin: 0; | ||
| padding: 0; | ||
| } | ||
| .rte-blocks-library-item { | ||
| width: 100%; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| text-align: left; | ||
| padding: 8px; | ||
| display: grid; | ||
| gap: 3px; | ||
| cursor: pointer; | ||
| } | ||
| .rte-blocks-library-item:hover, | ||
| .rte-blocks-library-item:focus-visible { | ||
| border-color: #0f766e; | ||
| outline: none; | ||
| } | ||
| .rte-blocks-library-item.active { | ||
| border-color: #0f766e; | ||
| background: rgba(15, 118, 110, 0.12); | ||
| } | ||
| .${d}.rte-blocks-library-theme-dark .rte-blocks-library-item { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .${d}.rte-blocks-library-theme-dark .rte-blocks-library-item.active { | ||
| border-color: #2dd4bf; | ||
| background: rgba(45, 212, 191, 0.15); | ||
| } | ||
| .rte-blocks-library-item-head { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| } | ||
| .rte-blocks-library-item-label { | ||
| font-size: 13px; | ||
| line-height: 1.3; | ||
| font-weight: 700; | ||
| } | ||
| .rte-blocks-library-recent-pill { | ||
| font-size: 10px; | ||
| line-height: 1; | ||
| font-weight: 700; | ||
| text-transform: uppercase; | ||
| letter-spacing: 0.02em; | ||
| color: #0f766e; | ||
| border: 1px solid rgba(15, 118, 110, 0.38); | ||
| border-radius: 999px; | ||
| padding: 2px 6px; | ||
| } | ||
| .${d}.rte-blocks-library-theme-dark .rte-blocks-library-recent-pill { | ||
| color: #5eead4; | ||
| border-color: rgba(94, 234, 212, 0.45); | ||
| } | ||
| .rte-blocks-library-item-meta, | ||
| .rte-blocks-library-item-description, | ||
| .rte-blocks-library-item-preview { | ||
| font-size: 11px; | ||
| line-height: 1.3; | ||
| color: #64748b; | ||
| } | ||
| .rte-blocks-library-item-preview { | ||
| color: #334155; | ||
| display: -webkit-box; | ||
| -webkit-line-clamp: 2; | ||
| line-clamp: 2; | ||
| -webkit-box-orient: vertical; | ||
| overflow: hidden; | ||
| } | ||
| .${d}.rte-blocks-library-theme-dark .rte-blocks-library-item-meta, | ||
| .${d}.rte-blocks-library-theme-dark .rte-blocks-library-item-description { | ||
| color: #94a3b8; | ||
| } | ||
| .${d}.rte-blocks-library-theme-dark .rte-blocks-library-item-preview { | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-blocks-library-empty { | ||
| margin: 8px; | ||
| font-size: 12px; | ||
| color: #64748b; | ||
| } | ||
| .rte-blocks-library-actions { | ||
| display: flex; | ||
| gap: 8px; | ||
| } | ||
| .rte-blocks-library-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| min-height: 34px; | ||
| padding: 0 12px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| cursor: pointer; | ||
| } | ||
| .rte-blocks-library-btn:disabled { | ||
| opacity: 0.6; | ||
| cursor: not-allowed; | ||
| } | ||
| .rte-blocks-library-btn-primary { | ||
| border-color: #0f766e; | ||
| background: #0f766e; | ||
| color: #f8fafc; | ||
| } | ||
| .rte-blocks-library-btn-primary:hover, | ||
| .rte-blocks-library-btn-primary:focus-visible { | ||
| border-color: #115e59; | ||
| background: #115e59; | ||
| outline: none; | ||
| } | ||
| .${d}.rte-blocks-library-theme-dark .rte-blocks-library-btn { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .${d}.rte-blocks-library-theme-dark .rte-blocks-library-btn-primary { | ||
| border-color: #14b8a6; | ||
| background: #0f766e; | ||
| color: #f0fdfa; | ||
| } | ||
| .rte-blocks-library-live { | ||
| position: absolute; | ||
| width: 1px; | ||
| height: 1px; | ||
| margin: -1px; | ||
| padding: 0; | ||
| overflow: hidden; | ||
| clip: rect(0 0 0 0); | ||
| border: 0; | ||
| } | ||
| @media (max-width: 768px) { | ||
| .${d} { | ||
| left: 10px !important; | ||
| right: 10px; | ||
| top: 10px !important; | ||
| width: auto !important; | ||
| max-height: calc(100vh - 20px); | ||
| } | ||
| } | ||
| `,document.head.appendChild(e)}const mt=(e={})=>{const t=Q(e),r=new Set;return pt(),{name:"blocksLibrary",toolbar:[{id:"blocksLibraryGroup",label:"Blocks Library",type:"group",command:"blocksLibrary",items:[{id:"blocksLibraryPanel",label:"Blocks Library Panel",command:"toggleBlocksLibraryPanel",shortcut:"Mod-Alt-Shift-b",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><rect x="4" y="5" width="7" height="6" rx="1.5" stroke="currentColor" stroke-width="1.6"/><rect x="13" y="5" width="7" height="6" rx="1.5" stroke="currentColor" stroke-width="1.6"/><rect x="4" y="13" width="7" height="6" rx="1.5" stroke="currentColor" stroke-width="1.6"/><rect x="13" y="13" width="7" height="6" rx="1.5" stroke="currentColor" stroke-width="1.6"/></svg>'},{id:"insertLastBlockSnippet",label:"Insert Last Block",command:"insertLastBlockSnippet",shortcut:"Mod-Alt-Shift-l",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M7 5.5h10a1.5 1.5 0 0 1 1.5 1.5v10A1.5 1.5 0 0 1 17 18.5H7A1.5 1.5 0 0 1 5.5 17V7A1.5 1.5 0 0 1 7 5.5Z" stroke="currentColor" stroke-width="1.6"/><path d="M12 8.5v7" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><path d="M8.5 12h7" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>'}]}],commands:{blocksLibrary:(o,l)=>{const n=S(l,!1,!1);if(!n)return!1;const a=b.get(n)||t;return k(n,a),b.set(n,a),y=n,de(n),!0},openBlocksLibraryPanel:(o,l)=>{const n=S(l,!1,!1);if(!n)return!1;const a=b.get(n)||t;return k(n,a),b.set(n,a),y=n,de(n),!0},toggleBlocksLibraryPanel:(o,l)=>{const n=S(l,!1,!1);if(!n)return!1;const a=b.get(n)||t;return k(n,a),b.set(n,a),y=n,Ie(n,typeof o=="boolean"?o:void 0)},insertBlockSnippet:(o,l)=>{const n=S(l,!1,!1);if(!n)return!1;const a=b.get(n)||t;k(n,a),b.set(n,a);const s=typeof o=="string"?o:o?.id;return s?(y=n,F(n,s)):!1},insertLastBlockSnippet:(o,l)=>{const n=S(l,!1,!1);if(!n)return!1;const a=b.get(n)||t;return k(n,a),b.set(n,a),y=n,ze(n)},refreshBlocksLibraryData:(o,l)=>{const n=S(l,!1,!1);if(!n)return!1;const a=b.get(n)||t;return k(n,a),b.set(n,a),be(n,!0),!0},setBlocksLibraryOptions:(o,l)=>{const n=S(l,!1,!1);if(!n||!o||typeof o!="object")return!1;const a=b.get(n)||t,s=J.get(n)||Ue(a),i={...s,...o,labels:{...s.labels||{},...o.labels||{}},blocks:Array.isArray(o.blocks)?o.blocks:s.blocks,normalizeText:o.normalizeText||a.normalizeText,sanitizeBlockHtml:o.sanitizeBlockHtml||a.sanitizeBlockHtml,getBlocks:o.getBlocks||a.getBlocks},c=Q(i),u=Array.isArray(o.blocks),f=o.getBlocks!==void 0;b.set(n,c),J.set(n,i),(u||f||!I.has(n))&&(I.set(n,c.blocks),O.set(n,f?0:Date.now()));const g=k(n,c);return g.filterCache.clear(),typeof o.defaultCategory=="string"&&(g.category=ne(c.defaultCategory)||"all"),L(n),N(n),f&&be(n,!0),!0},getBlocksLibraryState:(o,l)=>{const n=S(l,!1,!1);if(!n)return!1;const a=b.get(n)||t;k(n,a);const s=ut(n);if(typeof o=="function")try{o(s)}catch{}return n.__blocksLibraryState=s,n.dispatchEvent(new CustomEvent("editora:blocks-library-state",{bubbles:!0,detail:s})),!0}},keymap:{"Mod-Alt-Shift-b":"toggleBlocksLibraryPanel","Mod-Alt-Shift-B":"toggleBlocksLibraryPanel","Mod-Alt-Shift-l":"insertLastBlockSnippet","Mod-Alt-Shift-L":"insertLastBlockSnippet"},init:function(l){X+=1;const n=this&&typeof this.__pluginConfig=="object"?{...e,...this.__pluginConfig}:e,a=Q(n);ft(a);const s=S(l?.editorElement?{editorElement:l.editorElement}:void 0,!1,!1);s&&(y=s,r.add(s),k(s,a),b.set(s,a),J.set(s,n),I.set(s,a.blocks),O.set(s,Date.now()),N(s))},destroy:()=>{r.forEach(o=>ge(o)),r.clear(),X=Math.max(0,X-1),!(X>0)&>()}}};exports.BlocksLibraryPlugin=mt; |
| const v = ".rte-content, .editora-content", fe = "[data-editora-editor], .rte-editor, .editora-editor, editora-editor", ye = "__editoraCommandEditorRoot", he = "rte-blocks-library-styles", u = "rte-blocks-library-panel", E = "blocks-library", B = "blocksLibrary", $ = ':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)'; | ||
| const Ce = /* @__PURE__ */ new Set(["script", "style", "meta", "link", "object", "embed", "iframe"]), Pe = /^(https?:|mailto:|tel:|#|\/)/i, De = /^data:image\/(?:png|gif|jpeg|jpg|webp);base64,/i, Oe = { | ||
| panelTitle: "Blocks Library", | ||
| panelAriaLabel: "Blocks library panel", | ||
| searchLabel: "Search blocks", | ||
| searchPlaceholder: "Search by name, category, or keyword", | ||
| categoryLabel: "Category", | ||
| allCategoriesText: "All categories", | ||
| recentHeading: "Recent inserts", | ||
| insertText: "Insert Selected", | ||
| closeText: "Close", | ||
| noResultsText: "No matching blocks found.", | ||
| summaryPrefix: "Blocks", | ||
| loadingText: "Loading blocks...", | ||
| loadErrorText: "Unable to load blocks right now.", | ||
| readonlyMessage: "Editor is read-only. Block insertion is disabled.", | ||
| shortcutText: "Shortcuts: Ctrl/Cmd+Alt+Shift+B (panel), Ctrl/Cmd+Alt+Shift+L (insert last)", | ||
| helperText: "Use Arrow keys to move through blocks, Enter to insert, Esc to close.", | ||
| lastInsertedPrefix: "Last inserted", | ||
| resultsListLabel: "Block results" | ||
| }, b = /* @__PURE__ */ new WeakMap(), J = /* @__PURE__ */ new WeakMap(), w = /* @__PURE__ */ new WeakMap(), I = /* @__PURE__ */ new WeakMap(), O = /* @__PURE__ */ new WeakMap(), j = /* @__PURE__ */ new WeakMap(), W = /* @__PURE__ */ new WeakMap(), z = /* @__PURE__ */ new WeakMap(), q = /* @__PURE__ */ new WeakMap(), te = /* @__PURE__ */ new WeakMap(), x = /* @__PURE__ */ new Map(), U = /* @__PURE__ */ new WeakMap(), oe = /* @__PURE__ */ new Set(); | ||
| let X = 0, Ne = 0, ke = 0, M = null, y = null, _ = null, P = null, A = null, D = null; | ||
| function m(e) { | ||
| return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); | ||
| } | ||
| function Ke(e) { | ||
| return e.replace(/\u00A0/g, " ").replace(/\s+/g, " ").trim(); | ||
| } | ||
| function je(e) { | ||
| return e.toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80); | ||
| } | ||
| function ce(e) { | ||
| const t = e.trim(); | ||
| return t && (Pe.test(t) || De.test(t)) ? t : ""; | ||
| } | ||
| function xe(e) { | ||
| let t = e; | ||
| return Ce.forEach((r) => { | ||
| const o = new RegExp(`<${r}[\\s\\S]*?>[\\s\\S]*?<\\/${r}>`, "gi"), l = new RegExp(`<${r}\\b[^>]*\\/?>`, "gi"); | ||
| t = t.replace(o, "").replace(l, ""); | ||
| }), t = t.replace(/\son\w+=(\"[^\"]*\"|'[^']*'|[^\s>]+)/gi, "").replace(/\s(xmlns|xml:[^=\s>]+)\s*=\s*(\"[^\"]*\"|'[^']*'|[^\s>]+)/gi, "").replace( | ||
| /\s(href|src|xlink:href)\s*=\s*("|\')\s*(?:javascript:|vbscript:|data:text\/html)[^"']*\2/gi, | ||
| "" | ||
| ).replace(/\s(href|src|xlink:href)\s*=\s*(?:javascript:|vbscript:|data:text\/html)[^\s>]*/gi, "").replace( | ||
| /\s(href|src|xlink:href)\s*=\s*("([^"]*)"|'([^']*)')/gi, | ||
| (r, o, l, n, a) => { | ||
| const s = typeof n == "string" && n.length > 0 ? n : a || "", i = ce(s); | ||
| if (!i) return ""; | ||
| const c = l.startsWith('"') ? '"' : "'"; | ||
| return ` ${o}=${c}${i}${c}`; | ||
| } | ||
| ).replace(/\s(href|src|xlink:href)\s*=\s*([^\s>]+)/gi, (r, o, l) => { | ||
| const n = ce(l); | ||
| return n ? ` ${o}="${n}"` : ""; | ||
| }).replace(/\sstyle\s*=\s*("([^"]*)"|'([^']*)')/gi, (r, o, l, n) => { | ||
| const a = typeof l == "string" && l.length > 0 ? l : n || ""; | ||
| if (/expression\s*\(|javascript\s*:|vbscript\s*:|url\s*\(/i.test(a)) | ||
| return ""; | ||
| const s = o.startsWith('"') ? '"' : "'"; | ||
| return ` style=${s}${a}${s}`; | ||
| }).trim(), t; | ||
| } | ||
| function We(e) { | ||
| if (!e) return ""; | ||
| if (typeof document > "u") | ||
| return xe(e); | ||
| const t = document.createElement("template"); | ||
| t.innerHTML = e; | ||
| const r = t.content; | ||
| return !r || typeof r.querySelectorAll != "function" ? xe(e) : (Array.from(r.querySelectorAll("*")).forEach((l) => { | ||
| const n = l.tagName.toLowerCase(); | ||
| if (Ce.has(n)) { | ||
| l.remove(); | ||
| return; | ||
| } | ||
| Array.from(l.attributes).forEach((s) => { | ||
| const i = s.name.toLowerCase(), c = s.value; | ||
| if (i.startsWith("on")) { | ||
| l.removeAttribute(s.name); | ||
| return; | ||
| } | ||
| if (i === "style") { | ||
| /expression\s*\(|javascript\s*:|vbscript\s*:|url\s*\(/i.test(c) && l.removeAttribute(s.name); | ||
| return; | ||
| } | ||
| if (i === "href" || i === "src" || i === "xlink:href") { | ||
| const d = ce(c); | ||
| if (!d) { | ||
| l.removeAttribute(s.name); | ||
| return; | ||
| } | ||
| d !== c && l.setAttribute(s.name, d); | ||
| } | ||
| }); | ||
| }), t.innerHTML.trim()); | ||
| } | ||
| function ne(e) { | ||
| return e.trim().toLowerCase(); | ||
| } | ||
| function Fe(e) { | ||
| if (!e) return ""; | ||
| if (typeof document > "u") | ||
| return e.replace(/<[^>]*>/g, " ").replace(/\s+/g, " ").trim(); | ||
| const t = document.createElement("template"); | ||
| t.innerHTML = e; | ||
| const r = t.content; | ||
| return !r || typeof r.textContent != "string" ? e.replace(/<[^>]*>/g, " ").replace(/\s+/g, " ").trim() : r.textContent.replace(/\s+/g, " ").trim(); | ||
| } | ||
| function Be(e, t) { | ||
| if (!Array.isArray(e) || e.length === 0) return []; | ||
| const r = /* @__PURE__ */ new Set(), o = []; | ||
| return e.forEach((l) => { | ||
| const n = t.normalizeText(l.label || ""), a = t.sanitizeBlockHtml(l.html || "", l).trim(); | ||
| if (!n || !a) return; | ||
| const s = t.normalizeText(l.category || "General") || "General", i = ne(s); | ||
| let d = je(t.normalizeText(l.id || n)) || `block-${ke++}`; | ||
| for (; r.has(d); ) | ||
| d = `${d}-${ke++}`; | ||
| r.add(d); | ||
| const f = (l.tags || []).map((H) => t.normalizeText(H)).filter(Boolean), g = (l.keywords || []).map((H) => t.normalizeText(H)).filter(Boolean), h = t.normalizeText(l.description || ""), R = Fe(a), V = [n, h, s, ...f, ...g, R].join(" ").toLowerCase(); | ||
| o.push({ | ||
| id: d, | ||
| label: n, | ||
| html: a, | ||
| description: h, | ||
| category: s, | ||
| categoryKey: i, | ||
| tags: f, | ||
| keywords: g, | ||
| previewText: R, | ||
| searchBlob: V | ||
| }); | ||
| }), o; | ||
| } | ||
| function Q(e = {}) { | ||
| const t = e.normalizeText || Ke, r = e.sanitizeBlockHtml || We, o = { | ||
| blocks: [], | ||
| defaultCategory: t(e.defaultCategory || ""), | ||
| maxResults: Math.max(4, Math.min(300, Number(e.maxResults ?? 80))), | ||
| maxRecentBlocks: Math.max(1, Math.min(20, Number(e.maxRecentBlocks ?? 6))), | ||
| debounceMs: Math.max(0, Math.min(700, Number(e.debounceMs ?? 90))), | ||
| cacheTtlMs: Math.max(0, Number(e.cacheTtlMs ?? 6e4)), | ||
| labels: { | ||
| ...Oe, | ||
| ...e.labels || {} | ||
| }, | ||
| normalizeText: t, | ||
| sanitizeBlockHtml: r, | ||
| getBlocks: typeof e.getBlocks == "function" ? e.getBlocks : void 0 | ||
| }; | ||
| return o.blocks = Be(e.blocks, o), o; | ||
| } | ||
| function Ge(e) { | ||
| return { | ||
| blocks: e.blocks.map((t) => ({ | ||
| id: t.id, | ||
| label: t.label, | ||
| html: t.html, | ||
| description: t.description || void 0, | ||
| category: t.category || void 0, | ||
| tags: t.tags.length ? [...t.tags] : void 0, | ||
| keywords: t.keywords.length ? [...t.keywords] : void 0 | ||
| })), | ||
| defaultCategory: e.defaultCategory, | ||
| maxResults: e.maxResults, | ||
| maxRecentBlocks: e.maxRecentBlocks, | ||
| debounceMs: e.debounceMs, | ||
| cacheTtlMs: e.cacheTtlMs, | ||
| labels: { ...e.labels }, | ||
| normalizeText: e.normalizeText, | ||
| sanitizeBlockHtml: e.sanitizeBlockHtml, | ||
| getBlocks: e.getBlocks | ||
| }; | ||
| } | ||
| function le(e) { | ||
| return e.closest(fe) || e; | ||
| } | ||
| function G(e) { | ||
| if (!e) return null; | ||
| if (e.matches(v)) return e; | ||
| const t = e.querySelector(v); | ||
| return t instanceof HTMLElement ? t : null; | ||
| } | ||
| function Ue() { | ||
| if (typeof window > "u") return null; | ||
| const e = window[ye]; | ||
| if (!(e instanceof HTMLElement)) return null; | ||
| window[ye] = null; | ||
| const t = G(e); | ||
| if (t) return t; | ||
| const r = e.closest(fe); | ||
| if (r) { | ||
| const l = G(r); | ||
| if (l) return l; | ||
| } | ||
| const o = e.closest(v); | ||
| return o instanceof HTMLElement ? o : null; | ||
| } | ||
| function Ve(e) { | ||
| const t = e.closest("[data-editora-editor]"); | ||
| if (t && G(t) === e) | ||
| return t; | ||
| let r = e; | ||
| for (; r; ) { | ||
| if (r.matches(fe) && (r === e || G(r) === e)) | ||
| return r; | ||
| r = r.parentElement; | ||
| } | ||
| return le(e); | ||
| } | ||
| function $e(e) { | ||
| return e ? e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement : null; | ||
| } | ||
| function ee() { | ||
| Array.from(oe).forEach((t) => { | ||
| t.isConnected || ge(t); | ||
| }); | ||
| } | ||
| function T(e, t = !0, r = !0) { | ||
| if (ee(), e?.contentElement instanceof HTMLElement) return e.contentElement; | ||
| if (e?.editorElement instanceof HTMLElement) { | ||
| const a = G(e.editorElement); | ||
| if (a) return a; | ||
| } | ||
| const o = Ue(); | ||
| if (o) return o; | ||
| const l = window.getSelection(); | ||
| if (l && l.rangeCount > 0) { | ||
| const s = $e(l.getRangeAt(0).startContainer)?.closest(v); | ||
| if (s) return s; | ||
| } | ||
| const n = document.activeElement; | ||
| if (n) { | ||
| if (n.matches(v)) return n; | ||
| const a = n.closest(v); | ||
| if (a) return a; | ||
| } | ||
| if (r) { | ||
| if (y && y.isConnected) return y; | ||
| y && !y.isConnected && (y = null); | ||
| } | ||
| return t ? document.querySelector(v) : null; | ||
| } | ||
| function Ye(e) { | ||
| const t = e.target; | ||
| if (t) { | ||
| const o = t.closest(v); | ||
| if (o) return o; | ||
| } | ||
| const r = window.getSelection(); | ||
| if (r && r.rangeCount > 0) { | ||
| const l = $e(r.getRangeAt(0).startContainer)?.closest(v); | ||
| if (l) return l; | ||
| } | ||
| return null; | ||
| } | ||
| function Z(e) { | ||
| return e ? (e.getAttribute("data-theme") || e.getAttribute("theme") || "").toLowerCase() === "dark" ? !0 : e.classList.contains("dark") || e.classList.contains("editora-theme-dark") || e.classList.contains("rte-theme-dark") : !1; | ||
| } | ||
| function Xe(e) { | ||
| const t = le(e); | ||
| if (Z(t)) return !0; | ||
| const r = t.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark"); | ||
| return Z(r) ? !0 : Z(document.documentElement) || Z(document.body); | ||
| } | ||
| function re(e, t) { | ||
| e.classList.remove("rte-blocks-library-theme-dark"), Xe(t) && e.classList.add("rte-blocks-library-theme-dark"); | ||
| } | ||
| function Te(e) { | ||
| return e.getAttribute("contenteditable") === "false" || e.getAttribute("data-readonly") === "true"; | ||
| } | ||
| function we(e, t, r) { | ||
| const o = Ve(e); | ||
| Array.from( | ||
| o.querySelectorAll( | ||
| `.rte-toolbar-button[data-command="${t}"], .editora-toolbar-button[data-command="${t}"]` | ||
| ) | ||
| ).forEach((n) => { | ||
| n.classList.toggle("active", r), n.setAttribute("data-active", r ? "true" : "false"), n.setAttribute("aria-pressed", r ? "true" : "false"); | ||
| }); | ||
| } | ||
| function Ee(e, t) { | ||
| const r = e.querySelector(".rte-blocks-library-live"); | ||
| r && (r.textContent = t); | ||
| } | ||
| function se(e) { | ||
| const t = Re(e); | ||
| if (t) | ||
| try { | ||
| q.set(e, t.cloneRange()); | ||
| } catch { | ||
| } | ||
| } | ||
| function Se(e) { | ||
| const t = q.get(e); | ||
| if (!t) return null; | ||
| if (!e.isConnected) | ||
| return q.delete(e), null; | ||
| try { | ||
| const r = t.cloneRange(); | ||
| return e.contains(r.commonAncestorContainer) ? r : (q.delete(e), null); | ||
| } catch { | ||
| return q.delete(e), null; | ||
| } | ||
| } | ||
| function Ze(e) { | ||
| const t = Se(e); | ||
| return t ? (He(e, t), !0) : !1; | ||
| } | ||
| function Je(e) { | ||
| if (te.has(e)) return; | ||
| const t = () => { | ||
| const r = window.getSelection(); | ||
| if (!r || r.rangeCount === 0) return; | ||
| const o = r.getRangeAt(0); | ||
| e.contains(o.commonAncestorContainer) && se(e); | ||
| }; | ||
| e.addEventListener("keyup", t), e.addEventListener("mouseup", t), e.addEventListener("touchend", t), te.set(e, t); | ||
| } | ||
| function Qe(e) { | ||
| const t = te.get(e); | ||
| t && (e.removeEventListener("keyup", t), e.removeEventListener("mouseup", t), e.removeEventListener("touchend", t), te.delete(e)); | ||
| } | ||
| function k(e, t) { | ||
| b.has(e) || b.set(e, t), I.has(e) || (I.set(e, t.blocks), O.set(e, Date.now())); | ||
| let r = w.get(e); | ||
| return r || (r = { | ||
| query: "", | ||
| category: t.defaultCategory ? ne(t.defaultCategory) : "all", | ||
| selectedBlockId: null, | ||
| recentBlockIds: [], | ||
| lastInsertedBlockId: null, | ||
| loading: !1, | ||
| loadError: null, | ||
| totalMatches: 0, | ||
| visibleMatches: 0, | ||
| filterCache: /* @__PURE__ */ new Map(), | ||
| debounceTimer: null | ||
| }, w.set(e, r)), oe.add(e), Je(e), r; | ||
| } | ||
| function Me(e) { | ||
| const t = w.get(e); | ||
| !t || t.debounceTimer === null || (window.clearTimeout(t.debounceTimer), t.debounceTimer = null); | ||
| } | ||
| function ge(e) { | ||
| Me(e), Qe(e), q.delete(e); | ||
| const t = W.get(e); | ||
| t && (t.abort(), W.delete(e)), j.delete(e), z.delete(e), x.get(e)?.remove(), x.delete(e), U.delete(e), b.delete(e), J.delete(e), w.delete(e), I.delete(e), O.delete(e), oe.delete(e), y === e && (y = null); | ||
| } | ||
| function et(e) { | ||
| for (let t = 0; t < e.length; t += 1) { | ||
| const r = e[t]; | ||
| if (!(r.type !== "childList" || r.removedNodes.length === 0)) | ||
| for (let o = 0; o < r.removedNodes.length; o += 1) { | ||
| const l = r.removedNodes[o]; | ||
| if (l.nodeType !== Node.ELEMENT_NODE) continue; | ||
| const n = l; | ||
| if (n.matches?.(v) || n.matches?.(`.${u}`) || n.querySelector?.(v) || n.querySelector?.(`.${u}`)) | ||
| return !0; | ||
| } | ||
| } | ||
| return !1; | ||
| } | ||
| function pe(e) { | ||
| return U.get(e) === !0; | ||
| } | ||
| function de(e, t) { | ||
| if (!t.classList.contains("show")) return; | ||
| const r = le(e).getBoundingClientRect(), o = Math.min(window.innerWidth - 20, 420), l = Math.max(10, window.innerWidth - o - 10), n = Math.min(Math.max(10, r.right - o), l), a = Math.max(10, Math.min(window.innerHeight - 10, r.top + 12)); | ||
| t.style.width = `${o}px`, t.style.left = `${n}px`, t.style.top = `${a}px`, t.style.maxHeight = `${Math.max(260, window.innerHeight - 20)}px`; | ||
| } | ||
| function ae(e) { | ||
| return I.get(e) || b.get(e)?.blocks || []; | ||
| } | ||
| function tt(e, t) { | ||
| const r = /* @__PURE__ */ new Map(); | ||
| ae(e).forEach((l) => { | ||
| r.has(l.categoryKey) || r.set(l.categoryKey, l.category); | ||
| }); | ||
| const o = Array.from(r.entries()).sort((l, n) => l[1].localeCompare(n[1])).map(([l, n]) => ({ value: l, label: n })); | ||
| return [{ value: "all", label: t.labels.allCategoriesText }, ...o]; | ||
| } | ||
| function Ae(e, t) { | ||
| const r = k(e, t), o = ae(e), l = r.query.trim().toLowerCase(), n = r.category || "all", a = `${l}|${n}|${t.maxResults}`, s = r.filterCache.get(a); | ||
| if (s) { | ||
| const d = new Map(o.map((g) => [g.id, g])), f = s.ids.map((g) => d.get(g)).filter(Boolean); | ||
| return r.totalMatches = s.total, r.visibleMatches = f.length, f; | ||
| } | ||
| const i = []; | ||
| let c = 0; | ||
| for (let d = 0; d < o.length; d += 1) { | ||
| const f = o[d]; | ||
| n !== "all" && f.categoryKey !== n || l && !f.searchBlob.includes(l) || (c += 1, i.length < t.maxResults && i.push(f)); | ||
| } | ||
| if (r.totalMatches = c, r.visibleMatches = i.length, r.filterCache.set(a, { | ||
| ids: i.map((d) => d.id), | ||
| total: c | ||
| }), r.filterCache.size > 80) { | ||
| const d = r.filterCache.keys().next().value; | ||
| typeof d == "string" && r.filterCache.delete(d); | ||
| } | ||
| return i; | ||
| } | ||
| function rt(e, t) { | ||
| const r = w.get(e); | ||
| if (!r) return; | ||
| if (t.length === 0) { | ||
| r.selectedBlockId = null; | ||
| return; | ||
| } | ||
| t.some((l) => l.id === r.selectedBlockId) || (r.selectedBlockId = t[0].id); | ||
| } | ||
| function N(e) { | ||
| const t = w.get(e); | ||
| we(e, "toggleBlocksLibraryPanel", pe(e)), we(e, "insertLastBlockSnippet", !!t?.lastInsertedBlockId); | ||
| } | ||
| function L(e) { | ||
| const t = x.get(e), r = b.get(e) || M, o = w.get(e); | ||
| if (!t || !r || !o) return; | ||
| re(t, e); | ||
| const l = t.querySelector(".rte-blocks-library-title"); | ||
| l && (l.textContent = r.labels.panelTitle); | ||
| const n = t.querySelector('[data-action="close"]'); | ||
| n && (n.setAttribute("aria-label", r.labels.closeText), n.textContent = "✕"); | ||
| const a = t.querySelector(".rte-blocks-library-search-label"); | ||
| a && (a.textContent = r.labels.searchLabel); | ||
| const s = t.querySelector('[data-field="query"]'); | ||
| s && (s.setAttribute("placeholder", r.labels.searchPlaceholder), s.value !== o.query && (s.value = o.query)); | ||
| const i = t.querySelector(".rte-blocks-library-category-label"); | ||
| i && (i.textContent = r.labels.categoryLabel); | ||
| const c = t.querySelector('[data-field="category"]'); | ||
| if (c) { | ||
| const C = tt(e, r); | ||
| c.innerHTML = C.map((p) => `<option value="${m(p.value)}">${m(p.label)}</option>`).join(""), C.some((p) => p.value === o.category) || (o.category = "all"), c.value = o.category; | ||
| } | ||
| const d = t.querySelector(".rte-blocks-library-helper"); | ||
| d && (d.textContent = r.labels.helperText); | ||
| const f = t.querySelector('.rte-blocks-library-list[role="listbox"]'); | ||
| f && f.setAttribute("aria-label", r.labels.resultsListLabel); | ||
| const g = t.querySelector(".rte-blocks-library-shortcut"); | ||
| g && (g.textContent = r.labels.shortcutText); | ||
| const h = t.querySelector('[data-action="insert-selected"]'); | ||
| if (h) { | ||
| h.textContent = r.labels.insertText; | ||
| const C = !Te(e) && !!o.selectedBlockId; | ||
| h.disabled = !C, h.setAttribute("aria-disabled", C ? "false" : "true"); | ||
| } | ||
| const R = t.querySelector(".rte-blocks-library-empty"), V = t.querySelector(".rte-blocks-library-list"), H = Ae(e, r); | ||
| rt(e, H); | ||
| const Y = t.querySelector(".rte-blocks-library-status"); | ||
| if (Y && (o.loading ? Y.textContent = r.labels.loadingText : o.loadError ? Y.textContent = o.loadError : Y.textContent = `${r.labels.summaryPrefix}: ${o.visibleMatches}/${o.totalMatches}`), V) { | ||
| const C = new Set(o.recentBlockIds); | ||
| V.innerHTML = H.map((p) => { | ||
| const ie = o.selectedBlockId === p.id, qe = p.tags.length ? ` • ${p.tags.join(", ")}` : "", _e = C.has(p.id), me = p.previewText.slice(0, 180); | ||
| return ` | ||
| <li class="rte-blocks-library-item-wrapper" role="presentation"> | ||
| <button | ||
| type="button" | ||
| class="rte-blocks-library-item${ie ? " active" : ""}" | ||
| data-block-id="${m(p.id)}" | ||
| role="option" | ||
| aria-selected="${ie ? "true" : "false"}" | ||
| aria-label="${m(p.label)}" | ||
| tabindex="${ie ? "0" : "-1"}" | ||
| > | ||
| <span class="rte-blocks-library-item-head"> | ||
| <span class="rte-blocks-library-item-label">${m(p.label)}</span> | ||
| ${_e ? `<span class="rte-blocks-library-recent-pill">${m(r.labels.recentHeading)}</span>` : ""} | ||
| </span> | ||
| <span class="rte-blocks-library-item-meta">${m(p.category)}${m(qe)}</span> | ||
| ${p.description ? `<span class="rte-blocks-library-item-description">${m(p.description)}</span>` : ""} | ||
| ${me ? `<span class="rte-blocks-library-item-preview">${m(me)}</span>` : ""} | ||
| </button> | ||
| </li> | ||
| `; | ||
| }).join(""); | ||
| } | ||
| R && (R.hidden = H.length > 0, R.textContent = r.labels.noResultsText); | ||
| const K = t.querySelector(".rte-blocks-library-last-inserted"); | ||
| if (K) | ||
| if (o.lastInsertedBlockId) { | ||
| const C = ae(e).find((p) => p.id === o.lastInsertedBlockId); | ||
| C ? (K.hidden = !1, K.textContent = `${r.labels.lastInsertedPrefix}: ${C.label}`) : K.hidden = !0; | ||
| } else | ||
| K.hidden = !0; | ||
| t.setAttribute("aria-label", r.labels.panelAriaLabel); | ||
| } | ||
| function S(e, t = !1) { | ||
| const r = x.get(e); | ||
| r && (r.classList.remove("show"), U.set(e, !1), N(e), t && (e.focus({ preventScroll: !0 }), Ze(e))); | ||
| } | ||
| function ot(e) { | ||
| e.querySelector(".rte-blocks-library-item.active")?.focus(); | ||
| } | ||
| function ve(e, t) { | ||
| const r = b.get(e) || M; | ||
| if (!r) return; | ||
| const o = w.get(e); | ||
| if (!o) return; | ||
| const l = Ae(e, r); | ||
| if (l.length === 0) return; | ||
| const a = (Math.max( | ||
| 0, | ||
| l.findIndex((i) => i.id === o.selectedBlockId) | ||
| ) + t + l.length) % l.length; | ||
| o.selectedBlockId = l[a].id, L(e); | ||
| const s = x.get(e); | ||
| s && ot(s); | ||
| } | ||
| function ue(e) { | ||
| const t = it(e); | ||
| se(e), x.forEach((o, l) => { | ||
| l !== e && S(l, !1); | ||
| }), t.classList.add("show"), U.set(e, !0), L(e), de(e, t), N(e), t.querySelector('[data-field="query"]')?.focus(), be(e, !1); | ||
| } | ||
| function Ie(e, t) { | ||
| const r = pe(e); | ||
| return (typeof t == "boolean" ? t : !r) ? ue(e) : S(e, !1), !0; | ||
| } | ||
| function Re(e) { | ||
| const t = window.getSelection(); | ||
| if (!t || t.rangeCount === 0) return null; | ||
| const r = t.getRangeAt(0); | ||
| return e.contains(r.commonAncestorContainer) ? r : null; | ||
| } | ||
| function He(e, t) { | ||
| if (!e.isConnected) return; | ||
| const r = window.getSelection(); | ||
| r && (r.removeAllRanges(), r.addRange(t)); | ||
| } | ||
| function Le(e, t, r) { | ||
| const o = t.cloneRange(); | ||
| if (!e.contains(o.commonAncestorContainer)) return !1; | ||
| o.deleteContents(); | ||
| const l = document.createElement("template"); | ||
| l.innerHTML = r; | ||
| const n = l.content; | ||
| if (!n) return !1; | ||
| const a = n.lastChild; | ||
| if (o.insertNode(n), a) { | ||
| const s = document.createRange(); | ||
| s.setStartAfter(a), s.collapse(!0), He(e, s); | ||
| } | ||
| return se(e), !0; | ||
| } | ||
| function nt(e, t) { | ||
| e.focus({ preventScroll: !0 }); | ||
| const r = Se(e); | ||
| if (r && Le(e, r, t)) | ||
| return !0; | ||
| try { | ||
| if (document.execCommand("insertHTML", !1, t)) | ||
| return se(e), !0; | ||
| } catch { | ||
| } | ||
| const o = Re(e); | ||
| return o ? Le(e, o, t) : !1; | ||
| } | ||
| function lt(e, t) { | ||
| if (t === e.innerHTML) return; | ||
| const r = window.execEditorCommand || window.executeEditorCommand; | ||
| if (typeof r == "function") | ||
| try { | ||
| r("recordDomTransaction", e, t, e.innerHTML); | ||
| } catch { | ||
| } | ||
| } | ||
| function st(e) { | ||
| e.dispatchEvent(new Event("input", { bubbles: !0 })); | ||
| } | ||
| function F(e, t) { | ||
| const r = b.get(e) || M; | ||
| if (!r) return !1; | ||
| const o = k(e, r), l = x.get(e); | ||
| if (Te(e)) | ||
| return l && Ee(l, r.labels.readonlyMessage), !1; | ||
| const n = ae(e).find((i) => i.id === t); | ||
| if (!n) return !1; | ||
| const a = e.innerHTML; | ||
| return nt(e, n.html) ? (o.lastInsertedBlockId = n.id, o.selectedBlockId = n.id, o.recentBlockIds = [n.id, ...o.recentBlockIds.filter((i) => i !== n.id)].slice( | ||
| 0, | ||
| r.maxRecentBlocks | ||
| ), lt(e, a), st(e), N(e), e.dispatchEvent( | ||
| new CustomEvent("editora:blocks-library-insert", { | ||
| bubbles: !0, | ||
| detail: { | ||
| blockId: n.id, | ||
| label: n.label, | ||
| category: n.category | ||
| } | ||
| }) | ||
| ), L(e), l && Ee(l, `${r.labels.lastInsertedPrefix}: ${n.label}`), !0) : !1; | ||
| } | ||
| function ze(e) { | ||
| const t = w.get(e); | ||
| return t?.lastInsertedBlockId ? F(e, t.lastInsertedBlockId) : !1; | ||
| } | ||
| function at(e) { | ||
| const t = b.get(e) || M; | ||
| if (!t) return; | ||
| const r = w.get(e); | ||
| if (!r) return; | ||
| Me(e); | ||
| const o = () => { | ||
| r.debounceTimer = null, r.filterCache.clear(), L(e); | ||
| }; | ||
| if (t.debounceMs <= 0) { | ||
| o(); | ||
| return; | ||
| } | ||
| r.debounceTimer = window.setTimeout(o, t.debounceMs); | ||
| } | ||
| function it(e) { | ||
| const t = x.get(e); | ||
| if (t) return t; | ||
| const r = b.get(e) || M || Q(), o = k(e, r), l = `rte-blocks-library-panel-${Ne++}`, n = `${l}-query`, a = `${l}-category`, s = document.createElement("section"); | ||
| return s.className = u, s.id = l, s.setAttribute("role", "dialog"), s.setAttribute("aria-modal", "false"), s.setAttribute("aria-label", r.labels.panelAriaLabel), s.innerHTML = ` | ||
| <header class="rte-blocks-library-header"> | ||
| <h2 class="rte-blocks-library-title">${m(r.labels.panelTitle)}</h2> | ||
| <button type="button" class="rte-blocks-library-icon-btn" data-action="close" aria-label="${m(r.labels.closeText)}">✕</button> | ||
| </header> | ||
| <div class="rte-blocks-library-body"> | ||
| <label class="rte-blocks-library-search-label" for="${m(n)}"></label> | ||
| <input id="${m(n)}" class="rte-blocks-library-input" type="text" data-field="query" autocomplete="off" /> | ||
| <label class="rte-blocks-library-category-label" for="${m(a)}"></label> | ||
| <select id="${m(a)}" class="rte-blocks-library-select" data-field="category"></select> | ||
| <p class="rte-blocks-library-status" aria-live="polite"></p> | ||
| <p class="rte-blocks-library-helper"></p> | ||
| <p class="rte-blocks-library-last-inserted" hidden></p> | ||
| <div class="rte-blocks-library-list-wrap"> | ||
| <ul class="rte-blocks-library-list" role="listbox" aria-label="${m(r.labels.resultsListLabel)}"></ul> | ||
| <p class="rte-blocks-library-empty" hidden></p> | ||
| </div> | ||
| <div class="rte-blocks-library-actions"> | ||
| <button type="button" class="rte-blocks-library-btn rte-blocks-library-btn-primary" data-action="insert-selected"></button> | ||
| </div> | ||
| <p class="rte-blocks-library-shortcut"></p> | ||
| </div> | ||
| <div class="rte-blocks-library-live" aria-live="polite" aria-atomic="true"></div> | ||
| `, s.addEventListener("click", (i) => { | ||
| const c = i.target, d = c?.closest("[data-action]"); | ||
| if (d) { | ||
| const h = d.getAttribute("data-action"); | ||
| if (h === "close") { | ||
| S(e, !0); | ||
| return; | ||
| } | ||
| if (h === "insert-selected") { | ||
| if (!o.selectedBlockId) return; | ||
| F(e, o.selectedBlockId) && S(e, !0); | ||
| } | ||
| return; | ||
| } | ||
| const f = c?.closest("[data-block-id]"); | ||
| if (!f) return; | ||
| const g = f.getAttribute("data-block-id"); | ||
| g && (o.selectedBlockId = g, L(e), i.detail >= 2 && F(e, g) && S(e, !0)); | ||
| }), s.addEventListener("input", (i) => { | ||
| const c = i.target; | ||
| !(c instanceof HTMLInputElement) || c.getAttribute("data-field") !== "query" || (o.query = r.normalizeText(c.value).toLowerCase(), o.filterCache.clear(), at(e)); | ||
| }), s.addEventListener("change", (i) => { | ||
| const c = i.target; | ||
| !(c instanceof HTMLSelectElement) || c.getAttribute("data-field") !== "category" || (o.category = ne(c.value || "all") || "all", o.filterCache.clear(), L(e)); | ||
| }), s.addEventListener("keydown", (i) => { | ||
| if (i.key === "Escape") { | ||
| i.preventDefault(), S(e, !0); | ||
| return; | ||
| } | ||
| if (i.key === "ArrowDown") { | ||
| i.preventDefault(), ve(e, 1); | ||
| return; | ||
| } | ||
| if (i.key === "ArrowUp") { | ||
| i.preventDefault(), ve(e, -1); | ||
| return; | ||
| } | ||
| if (i.key === "Enter") { | ||
| if (!i.target?.matches('[data-field="query"], [data-field="category"], [data-block-id]') || !o.selectedBlockId) return; | ||
| i.preventDefault(), F(e, o.selectedBlockId) && S(e, !0); | ||
| } | ||
| }), re(s, e), document.body.appendChild(s), x.set(e, s), U.set(e, !1), L(e), s; | ||
| } | ||
| function ct(e) { | ||
| const t = w.get(e); | ||
| return { | ||
| query: t?.query || "", | ||
| category: t?.category || "all", | ||
| selectedBlockId: t?.selectedBlockId || null, | ||
| totalMatches: t?.totalMatches || 0, | ||
| visibleMatches: t?.visibleMatches || 0, | ||
| recentBlockIds: t?.recentBlockIds ? [...t.recentBlockIds] : [], | ||
| lastInsertedBlockId: t?.lastInsertedBlockId || null, | ||
| loading: t?.loading === !0, | ||
| loadError: t?.loadError || null | ||
| }; | ||
| } | ||
| async function be(e, t) { | ||
| const r = b.get(e) || M; | ||
| if (!r || typeof r.getBlocks != "function") return; | ||
| const o = k(e, r), l = O.get(e) || 0; | ||
| if (!t && r.cacheTtlMs > 0 && Date.now() - l < r.cacheTtlMs) | ||
| return; | ||
| const n = j.get(e); | ||
| if (n && !t) | ||
| return n; | ||
| const a = W.get(e); | ||
| a && a.abort(), t && n && j.delete(e); | ||
| const s = new AbortController(); | ||
| W.set(e, s); | ||
| const i = (z.get(e) || 0) + 1; | ||
| z.set(e, i), o.loading = !0, o.loadError = null, L(e); | ||
| const c = Promise.resolve().then(async () => { | ||
| const d = { | ||
| editor: e, | ||
| editorRoot: le(e), | ||
| signal: s.signal | ||
| }, f = await r.getBlocks?.(d); | ||
| if (s.signal.aborted || z.get(e) !== i) return; | ||
| const g = Be(f || [], r); | ||
| I.set(e, g), O.set(e, Date.now()); | ||
| const h = w.get(e); | ||
| h && (h.loading = !1, h.loadError = null, h.filterCache.clear()); | ||
| }).catch(() => { | ||
| if (s.signal.aborted || z.get(e) !== i) return; | ||
| const d = w.get(e); | ||
| d && (d.loading = !1, d.loadError = r.labels.loadErrorText); | ||
| }).finally(() => { | ||
| z.get(e) === i && (j.delete(e), W.delete(e)), L(e); | ||
| }); | ||
| return j.set(e, c), c; | ||
| } | ||
| function dt(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "b"; | ||
| } | ||
| function ut(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "l"; | ||
| } | ||
| function bt(e) { | ||
| M = e, _ || (_ = (t) => { | ||
| ee(); | ||
| const o = t.target?.closest(v); | ||
| if (!o) return; | ||
| const l = b.get(o) || e; | ||
| k(o, l), b.set(o, l), y = o, N(o); | ||
| const n = x.get(o); | ||
| n && (re(n, o), de(o, n), L(o)); | ||
| }, document.addEventListener("focusin", _, !0)), P || (P = (t) => { | ||
| if (t.defaultPrevented) return; | ||
| const r = `.${u} input, .${u} textarea, .${u} select`, o = t.target; | ||
| if (o?.closest(r)) { | ||
| if (t.key === "Escape") { | ||
| const a = o.closest(`.${u}`), s = Array.from(x.entries()).find(([, i]) => i === a); | ||
| s && (t.preventDefault(), S(s[0], !0)); | ||
| } | ||
| return; | ||
| } | ||
| const l = Ye(t); | ||
| if (!l) return; | ||
| const n = b.get(l) || M || e; | ||
| if (k(l, n), b.set(l, n), y = l, t.key === "Escape" && pe(l)) { | ||
| t.preventDefault(), S(l, !0); | ||
| return; | ||
| } | ||
| if (dt(t)) { | ||
| t.preventDefault(), t.stopPropagation(), Ie(l); | ||
| return; | ||
| } | ||
| ut(t) && (t.preventDefault(), t.stopPropagation(), ze(l)); | ||
| }, document.addEventListener("keydown", P, !0)), A || (A = () => { | ||
| ee(), x.forEach((t, r) => { | ||
| !r.isConnected || !t.isConnected || (re(t, r), de(r, t)); | ||
| }); | ||
| }, window.addEventListener("scroll", A, !0), window.addEventListener("resize", A)), !D && typeof MutationObserver < "u" && document.body && (D = new MutationObserver((t) => { | ||
| et(t) && ee(); | ||
| }), D.observe(document.body, { | ||
| childList: !0, | ||
| subtree: !0 | ||
| })); | ||
| } | ||
| function ft() { | ||
| _ && (document.removeEventListener("focusin", _, !0), _ = null), P && (document.removeEventListener("keydown", P, !0), P = null), A && (window.removeEventListener("scroll", A, !0), window.removeEventListener("resize", A), A = null), D && (D.disconnect(), D = null), x.forEach((t) => t.remove()), x.clear(), Array.from(oe).forEach((t) => ge(t)), M = null, y = null; | ||
| } | ||
| function gt() { | ||
| if (typeof document > "u" || document.getElementById(he)) return; | ||
| const e = document.createElement("style"); | ||
| e.id = he, e.textContent = ` | ||
| .rte-toolbar-group-items.${E}, | ||
| .editora-toolbar-group-items.${E}, | ||
| .rte-toolbar-group-items.${B}, | ||
| .editora-toolbar-group-items.${B} { | ||
| display: flex; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 4px; | ||
| background: #ffffff; | ||
| } | ||
| .rte-toolbar-group-items.${E} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${E} .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${B} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${B} .editora-toolbar-button { | ||
| border: none; | ||
| border-right: 1px solid #cbd5e1; | ||
| border-radius: 0; | ||
| } | ||
| .rte-toolbar-group-items.${E} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${E} .editora-toolbar-item:last-child .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${B} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${B} .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| .rte-toolbar-button[data-command="insertLastBlockSnippet"].active, | ||
| .editora-toolbar-button[data-command="insertLastBlockSnippet"].active { | ||
| background: rgba(15, 118, 110, 0.12); | ||
| } | ||
| ${$} .rte-toolbar-group-items.${E}, | ||
| ${$} .editora-toolbar-group-items.${E}, | ||
| ${$} .rte-toolbar-group-items.${B}, | ||
| ${$} .editora-toolbar-group-items.${B} { | ||
| border-color: #566275; | ||
| } | ||
| ${$} .rte-toolbar-group-items.${E} .rte-toolbar-button svg, | ||
| ${$} .editora-toolbar-group-items.${E} .editora-toolbar-button svg, | ||
| ${$} .rte-toolbar-group-items.${B} .rte-toolbar-button svg, | ||
| ${$} .editora-toolbar-group-items.${B} .editora-toolbar-button svg | ||
| { | ||
| fill: none; | ||
| } | ||
| ${$} .rte-toolbar-group-items.${E} .rte-toolbar-button, | ||
| ${$} .editora-toolbar-group-items.${E} .editora-toolbar-button | ||
| { | ||
| border-color: #566275; | ||
| } | ||
| .${u} { | ||
| position: fixed; | ||
| z-index: 12000; | ||
| display: none; | ||
| width: min(420px, calc(100vw - 20px)); | ||
| max-height: calc(100vh - 20px); | ||
| border: 1px solid #d1d5db; | ||
| border-radius: 14px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| box-shadow: 0 24px 48px rgba(15, 23, 42, 0.24); | ||
| overflow: hidden; | ||
| } | ||
| .${u}.show { | ||
| display: flex; | ||
| flex-direction: column; | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark { | ||
| border-color: #334155; | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| box-shadow: 0 24px 52px rgba(2, 6, 23, 0.68); | ||
| } | ||
| .rte-blocks-library-header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| padding: 12px 14px; | ||
| border-bottom: 1px solid #e2e8f0; | ||
| background: linear-gradient(180deg, #f8fafc 0%, #f1f5f9 100%); | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-header { | ||
| border-color: #1e293b; | ||
| background: linear-gradient(180deg, #111827 0%, #0f172a 100%); | ||
| } | ||
| .rte-blocks-library-title { | ||
| margin: 0; | ||
| font-size: 15px; | ||
| line-height: 1.2; | ||
| font-weight: 700; | ||
| } | ||
| .rte-blocks-library-icon-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| min-height: 34px; | ||
| min-width: 34px; | ||
| width: 34px; | ||
| height: 34px; | ||
| padding: 0; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| font-weight: 600; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| cursor: pointer; | ||
| } | ||
| .rte-blocks-library-icon-btn:hover, | ||
| .rte-blocks-library-icon-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-icon-btn { | ||
| border-color: #475569; | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-icon-btn:hover, | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-icon-btn:focus-visible { | ||
| border-color: #60a5fa; | ||
| box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.24); | ||
| } | ||
| .rte-blocks-library-body { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 8px; | ||
| padding: 12px; | ||
| overflow: auto; | ||
| } | ||
| .rte-blocks-library-search-label, | ||
| .rte-blocks-library-category-label { | ||
| font-size: 12px; | ||
| line-height: 1.3; | ||
| font-weight: 700; | ||
| color: #334155; | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-search-label, | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-category-label { | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-blocks-library-input, | ||
| .rte-blocks-library-select { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| min-height: 34px; | ||
| padding: 0 10px; | ||
| font-size: 13px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| } | ||
| .rte-blocks-library-input:focus-visible, | ||
| .rte-blocks-library-select:focus-visible { | ||
| border-color: #0f766e; | ||
| box-shadow: 0 0 0 3px rgba(15, 118, 110, 0.18); | ||
| outline: none; | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-input, | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-select { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #e2e8f0; | ||
| } | ||
| .rte-blocks-library-status, | ||
| .rte-blocks-library-helper, | ||
| .rte-blocks-library-shortcut, | ||
| .rte-blocks-library-last-inserted { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #475569; | ||
| } | ||
| .rte-blocks-library-last-inserted { | ||
| font-weight: 600; | ||
| color: #0f766e; | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-status, | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-helper, | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-shortcut { | ||
| color: #94a3b8; | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-last-inserted { | ||
| color: #5eead4; | ||
| } | ||
| .rte-blocks-library-list-wrap { | ||
| border: 1px solid #e2e8f0; | ||
| border-radius: 10px; | ||
| padding: 6px; | ||
| background: #f8fafc; | ||
| max-height: min(44vh, 360px); | ||
| overflow: auto; | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-list-wrap { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| } | ||
| .rte-blocks-library-list { | ||
| margin: 0; | ||
| padding: 0; | ||
| list-style: none; | ||
| display: grid; | ||
| gap: 6px; | ||
| } | ||
| .rte-blocks-library-item-wrapper { | ||
| margin: 0; | ||
| padding: 0; | ||
| } | ||
| .rte-blocks-library-item { | ||
| width: 100%; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| text-align: left; | ||
| padding: 8px; | ||
| display: grid; | ||
| gap: 3px; | ||
| cursor: pointer; | ||
| } | ||
| .rte-blocks-library-item:hover, | ||
| .rte-blocks-library-item:focus-visible { | ||
| border-color: #0f766e; | ||
| outline: none; | ||
| } | ||
| .rte-blocks-library-item.active { | ||
| border-color: #0f766e; | ||
| background: rgba(15, 118, 110, 0.12); | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-item { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-item.active { | ||
| border-color: #2dd4bf; | ||
| background: rgba(45, 212, 191, 0.15); | ||
| } | ||
| .rte-blocks-library-item-head { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| } | ||
| .rte-blocks-library-item-label { | ||
| font-size: 13px; | ||
| line-height: 1.3; | ||
| font-weight: 700; | ||
| } | ||
| .rte-blocks-library-recent-pill { | ||
| font-size: 10px; | ||
| line-height: 1; | ||
| font-weight: 700; | ||
| text-transform: uppercase; | ||
| letter-spacing: 0.02em; | ||
| color: #0f766e; | ||
| border: 1px solid rgba(15, 118, 110, 0.38); | ||
| border-radius: 999px; | ||
| padding: 2px 6px; | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-recent-pill { | ||
| color: #5eead4; | ||
| border-color: rgba(94, 234, 212, 0.45); | ||
| } | ||
| .rte-blocks-library-item-meta, | ||
| .rte-blocks-library-item-description, | ||
| .rte-blocks-library-item-preview { | ||
| font-size: 11px; | ||
| line-height: 1.3; | ||
| color: #64748b; | ||
| } | ||
| .rte-blocks-library-item-preview { | ||
| color: #334155; | ||
| display: -webkit-box; | ||
| -webkit-line-clamp: 2; | ||
| line-clamp: 2; | ||
| -webkit-box-orient: vertical; | ||
| overflow: hidden; | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-item-meta, | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-item-description { | ||
| color: #94a3b8; | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-item-preview { | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-blocks-library-empty { | ||
| margin: 8px; | ||
| font-size: 12px; | ||
| color: #64748b; | ||
| } | ||
| .rte-blocks-library-actions { | ||
| display: flex; | ||
| gap: 8px; | ||
| } | ||
| .rte-blocks-library-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| min-height: 34px; | ||
| padding: 0 12px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| cursor: pointer; | ||
| } | ||
| .rte-blocks-library-btn:disabled { | ||
| opacity: 0.6; | ||
| cursor: not-allowed; | ||
| } | ||
| .rte-blocks-library-btn-primary { | ||
| border-color: #0f766e; | ||
| background: #0f766e; | ||
| color: #f8fafc; | ||
| } | ||
| .rte-blocks-library-btn-primary:hover, | ||
| .rte-blocks-library-btn-primary:focus-visible { | ||
| border-color: #115e59; | ||
| background: #115e59; | ||
| outline: none; | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-btn { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-blocks-library-theme-dark .rte-blocks-library-btn-primary { | ||
| border-color: #14b8a6; | ||
| background: #0f766e; | ||
| color: #f0fdfa; | ||
| } | ||
| .rte-blocks-library-live { | ||
| position: absolute; | ||
| width: 1px; | ||
| height: 1px; | ||
| margin: -1px; | ||
| padding: 0; | ||
| overflow: hidden; | ||
| clip: rect(0 0 0 0); | ||
| border: 0; | ||
| } | ||
| @media (max-width: 768px) { | ||
| .${u} { | ||
| left: 10px !important; | ||
| right: 10px; | ||
| top: 10px !important; | ||
| width: auto !important; | ||
| max-height: calc(100vh - 20px); | ||
| } | ||
| } | ||
| `, document.head.appendChild(e); | ||
| } | ||
| const pt = (e = {}) => { | ||
| const t = Q(e), r = /* @__PURE__ */ new Set(); | ||
| return gt(), { | ||
| name: "blocksLibrary", | ||
| toolbar: [ | ||
| { | ||
| id: "blocksLibraryGroup", | ||
| label: "Blocks Library", | ||
| type: "group", | ||
| command: "blocksLibrary", | ||
| items: [ | ||
| { | ||
| id: "blocksLibraryPanel", | ||
| label: "Blocks Library Panel", | ||
| command: "toggleBlocksLibraryPanel", | ||
| shortcut: "Mod-Alt-Shift-b", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><rect x="4" y="5" width="7" height="6" rx="1.5" stroke="currentColor" stroke-width="1.6"/><rect x="13" y="5" width="7" height="6" rx="1.5" stroke="currentColor" stroke-width="1.6"/><rect x="4" y="13" width="7" height="6" rx="1.5" stroke="currentColor" stroke-width="1.6"/><rect x="13" y="13" width="7" height="6" rx="1.5" stroke="currentColor" stroke-width="1.6"/></svg>' | ||
| }, | ||
| { | ||
| id: "insertLastBlockSnippet", | ||
| label: "Insert Last Block", | ||
| command: "insertLastBlockSnippet", | ||
| shortcut: "Mod-Alt-Shift-l", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M7 5.5h10a1.5 1.5 0 0 1 1.5 1.5v10A1.5 1.5 0 0 1 17 18.5H7A1.5 1.5 0 0 1 5.5 17V7A1.5 1.5 0 0 1 7 5.5Z" stroke="currentColor" stroke-width="1.6"/><path d="M12 8.5v7" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><path d="M8.5 12h7" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>' | ||
| } | ||
| ] | ||
| } | ||
| ], | ||
| commands: { | ||
| blocksLibrary: (o, l) => { | ||
| const n = T(l, !1, !1); | ||
| if (!n) return !1; | ||
| const a = b.get(n) || t; | ||
| return k(n, a), b.set(n, a), y = n, ue(n), !0; | ||
| }, | ||
| openBlocksLibraryPanel: (o, l) => { | ||
| const n = T(l, !1, !1); | ||
| if (!n) return !1; | ||
| const a = b.get(n) || t; | ||
| return k(n, a), b.set(n, a), y = n, ue(n), !0; | ||
| }, | ||
| toggleBlocksLibraryPanel: (o, l) => { | ||
| const n = T(l, !1, !1); | ||
| if (!n) return !1; | ||
| const a = b.get(n) || t; | ||
| return k(n, a), b.set(n, a), y = n, Ie(n, typeof o == "boolean" ? o : void 0); | ||
| }, | ||
| insertBlockSnippet: (o, l) => { | ||
| const n = T(l, !1, !1); | ||
| if (!n) return !1; | ||
| const a = b.get(n) || t; | ||
| k(n, a), b.set(n, a); | ||
| const s = typeof o == "string" ? o : o?.id; | ||
| return s ? (y = n, F(n, s)) : !1; | ||
| }, | ||
| insertLastBlockSnippet: (o, l) => { | ||
| const n = T(l, !1, !1); | ||
| if (!n) return !1; | ||
| const a = b.get(n) || t; | ||
| return k(n, a), b.set(n, a), y = n, ze(n); | ||
| }, | ||
| refreshBlocksLibraryData: (o, l) => { | ||
| const n = T(l, !1, !1); | ||
| if (!n) return !1; | ||
| const a = b.get(n) || t; | ||
| return k(n, a), b.set(n, a), be(n, !0), !0; | ||
| }, | ||
| setBlocksLibraryOptions: (o, l) => { | ||
| const n = T(l, !1, !1); | ||
| if (!n || !o || typeof o != "object") return !1; | ||
| const a = b.get(n) || t, s = J.get(n) || Ge(a), i = { | ||
| ...s, | ||
| ...o, | ||
| labels: { | ||
| ...s.labels || {}, | ||
| ...o.labels || {} | ||
| }, | ||
| blocks: Array.isArray(o.blocks) ? o.blocks : s.blocks, | ||
| normalizeText: o.normalizeText || a.normalizeText, | ||
| sanitizeBlockHtml: o.sanitizeBlockHtml || a.sanitizeBlockHtml, | ||
| getBlocks: o.getBlocks || a.getBlocks | ||
| }, c = Q(i), d = Array.isArray(o.blocks), f = o.getBlocks !== void 0; | ||
| b.set(n, c), J.set(n, i), (d || f || !I.has(n)) && (I.set(n, c.blocks), O.set(n, f ? 0 : Date.now())); | ||
| const g = k(n, c); | ||
| return g.filterCache.clear(), typeof o.defaultCategory == "string" && (g.category = ne(c.defaultCategory) || "all"), L(n), N(n), f && be(n, !0), !0; | ||
| }, | ||
| getBlocksLibraryState: (o, l) => { | ||
| const n = T(l, !1, !1); | ||
| if (!n) return !1; | ||
| const a = b.get(n) || t; | ||
| k(n, a); | ||
| const s = ct(n); | ||
| if (typeof o == "function") | ||
| try { | ||
| o(s); | ||
| } catch { | ||
| } | ||
| return n.__blocksLibraryState = s, n.dispatchEvent( | ||
| new CustomEvent("editora:blocks-library-state", { | ||
| bubbles: !0, | ||
| detail: s | ||
| }) | ||
| ), !0; | ||
| } | ||
| }, | ||
| keymap: { | ||
| "Mod-Alt-Shift-b": "toggleBlocksLibraryPanel", | ||
| "Mod-Alt-Shift-B": "toggleBlocksLibraryPanel", | ||
| "Mod-Alt-Shift-l": "insertLastBlockSnippet", | ||
| "Mod-Alt-Shift-L": "insertLastBlockSnippet" | ||
| }, | ||
| init: function(l) { | ||
| X += 1; | ||
| const n = this && typeof this.__pluginConfig == "object" ? { ...e, ...this.__pluginConfig } : e, a = Q(n); | ||
| bt(a); | ||
| const s = T( | ||
| l?.editorElement ? { editorElement: l.editorElement } : void 0, | ||
| !1, | ||
| !1 | ||
| ); | ||
| s && (y = s, r.add(s), k(s, a), b.set(s, a), J.set(s, n), I.set(s, a.blocks), O.set(s, Date.now()), N(s)); | ||
| }, | ||
| destroy: () => { | ||
| r.forEach((o) => ge(o)), r.clear(), X = Math.max(0, X - 1), !(X > 0) && ft(); | ||
| } | ||
| }; | ||
| }; | ||
| export { | ||
| pt as BlocksLibraryPlugin | ||
| }; |
| "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const E=".rte-content, .editora-content",mt="rte-citations-styles",b="rte-citations-panel",ot=".rte-citation-ref[data-citation-id]",W='.rte-citation-bibliography[data-type="citation-bibliography"]',G='.rte-citation-footnotes[data-type="citation-footnotes"]',x=':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)',L=["apa","mla","chicago"],Bt={panelTitle:"Citations",panelAriaLabel:"Citations panel",styleLabel:"Citation style",authorLabel:"Author",yearLabel:"Year",titleLabel:"Title",sourceLabel:"Source",urlLabel:"URL",noteLabel:"Footnote note",insertText:"Insert Citation",refreshText:"Refresh Bibliography",closeText:"Close",bibliographyTitle:"References",footnotesTitle:"Citation Notes",noCitationsText:"No citations inserted yet.",styleButtonPrefix:"Style",recentHeading:"Recent citations",deleteRecentText:"x",summaryPrefix:"Citations",invalidMessage:"Author and title are required."},f=new WeakMap,T=new WeakMap,pt=new WeakMap,D=new WeakMap,v=new Map,V=new WeakMap,Q=new WeakMap,q=new Set;let I=null,B=null,O=null,k=null,Y=0,Ot=0,at=0,M=null,p=null;function g(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function Pt(t){return t.replace(/\u00A0/g," ").replace(/\s+/g," ").trim()}function ht(t,e){const n=e(t);if(!n)return"";const i=n.match(/\d{4}/);return i?i[0]:n}function xt(t,e){const n=e(t);return n?/^https?:\/\//i.test(n)?n:`https://${n}`:""}function F(t){return t.toLowerCase().replace(/[^a-z0-9_-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,80)}function yt(t,e){return{id:F(e.normalizeText(t.id||"")),author:e.normalizeText(t.author||""),year:ht(t.year||"",e.normalizeText)||void 0,title:e.normalizeText(t.title||""),source:e.normalizeText(t.source||"")||void 0,url:xt(t.url||"",e.normalizeText)||void 0,note:e.normalizeText(t.note||"")||void 0}}function Z(t={}){const e=t.defaultStyle&&L.includes(t.defaultStyle)?t.defaultStyle:"apa",n={...Bt,...t.labels||{}};return{defaultStyle:e,enableFootnoteSync:t.enableFootnoteSync!==!1,debounceMs:Math.max(80,Number(t.debounceMs??220)),maxRecentCitations:Math.max(3,Math.min(30,Number(t.maxRecentCitations??8))),labels:n,normalizeText:t.normalizeText||Pt,generateCitationId:typeof t.generateCitationId=="function"?t.generateCitationId:void 0}}function Ct(t){return t?t.nodeType===Node.ELEMENT_NODE?t:t.parentElement:null}function lt(t){return t.closest("[data-editora-editor], .rte-editor, .editora-editor, editora-editor")||t}function X(t){return t?(t.getAttribute("data-theme")||t.getAttribute("theme")||"").toLowerCase()==="dark"?!0:t.classList.contains("dark")||t.classList.contains("editora-theme-dark")||t.classList.contains("rte-theme-dark"):!1}function Dt(t){const e=lt(t);if(X(e))return!0;const n=e.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark");return X(n)?!0:X(document.documentElement)||X(document.body)}function tt(t,e){t.classList.remove("rte-citations-theme-dark"),Dt(e)&&t.classList.add("rte-citations-theme-dark")}function h(t,e=!0){if(t?.contentElement instanceof HTMLElement)return t.contentElement;if(t?.editorElement instanceof HTMLElement){const o=t.editorElement;if(o.matches(E))return o;const r=o.querySelector(E);if(r instanceof HTMLElement)return r}const n=window.getSelection();if(n&&n.rangeCount>0){const o=n.getRangeAt(0).startContainer,a=Ct(o)?.closest(E);if(a)return a}const i=document.activeElement;if(i){if(i.matches(E))return i;const o=i.closest(E);if(o)return o}return p&&p.isConnected?p:(p&&!p.isConnected&&(p=null),e?document.querySelector(E):null)}function $(t){return t.getAttribute("contenteditable")==="false"||t.getAttribute("data-readonly")==="true"}function j(t){const e=Ct(t);return e?!!(e.closest(W)||e.closest(G)):!1}function Ht(t,e){if(at+=1,e.generateCitationId){const n=e.generateCitationId({editor:t,index:at}),i=F(e.normalizeText(n||""));if(i)return i}return`cite-${Date.now().toString(36)}-${at.toString(36)}`}function st(t){return t.map(e=>(e||"").trim()).filter(Boolean).join(" ").trim()}function Ft(t,e){const n=t.author||"Unknown",i=t.year||"n.d.";return e==="mla"?`(${n} ${i})`:e==="chicago"?`(${n} ${i})`:`(${n}, ${i})`}function ut(t,e){const n=t.author||"Unknown",i=t.year||"n.d.",o=t.title||"Untitled",r=t.source||"",a=t.url||"";return st(e==="mla"?[`${n}.`,`"${o}."`,r?`${r},`:"",`${i}.`,a]:e==="chicago"?[`${n}.`,`${o}.`,r?`${r}.`:"",`(${i}).`,a]:[`${n}.`,`(${i}).`,`${o}.`,r?`${r}.`:"",a])}function R(t){return Array.from(t.querySelectorAll(ot)).filter(e=>!e.closest(W)&&!e.closest(G))}function wt(t,e){const n=F(e.normalizeText(t.getAttribute("data-citation-id")||""));if(!n)return null;const i=e.normalizeText(t.getAttribute("data-citation-author")||""),o=e.normalizeText(t.getAttribute("data-citation-title")||"");return{id:n,author:i||"Unknown",year:ht(t.getAttribute("data-citation-year")||"",e.normalizeText)||void 0,title:o||"Untitled",source:e.normalizeText(t.getAttribute("data-citation-source")||"")||void 0,url:xt(t.getAttribute("data-citation-url")||"",e.normalizeText)||void 0,note:e.normalizeText(t.getAttribute("data-citation-note")||"")||void 0}}function vt(t,e,n){t.classList.add("rte-citation-ref"),t.setAttribute("data-citation-id",e.id),t.setAttribute("data-citation-author",e.author||""),t.setAttribute("data-citation-year",e.year||""),t.setAttribute("data-citation-title",e.title||""),t.setAttribute("data-citation-source",e.source||""),t.setAttribute("data-citation-url",e.url||""),t.setAttribute("data-citation-note",e.note||""),t.setAttribute("contenteditable","false"),t.setAttribute("tabindex","0"),t.setAttribute("role","doc-biblioref"),t.setAttribute("data-style",n),t.textContent=Ft(e,n)}function it(t,e,n){const i=lt(t);Array.from(i.querySelectorAll(`.rte-toolbar-button[data-command="${e}"], .editora-toolbar-button[data-command="${e}"]`)).forEach(r=>{r.classList.toggle("active",n),r.setAttribute("data-active",n?"true":"false"),r.setAttribute("aria-pressed",n?"true":"false")})}function N(t,e){const n=T.get(t);return n&&L.includes(n)?n:e?.defaultStyle||"apa"}function K(t,e){const n=R(t),i=new Map;return n.forEach(o=>{const r=wt(o,e);if(!r)return;if(!i.has(r.id)){i.set(r.id,r);return}const a=i.get(r.id);i.set(r.id,{...a,author:a.author||r.author,title:a.title||r.title,year:a.year||r.year,source:a.source||r.source,url:a.url||r.url,note:a.note||r.note})}),Array.from(i.values())}function _t(t,e,n){const i=yt(e,n);if(!i.id||!i.author||!i.title)return;const r=(D.get(t)||[]).filter(a=>a.id!==i.id);D.set(t,[i,...r].slice(0,n.maxRecentCitations))}function rt(t,e,n){const i=D.get(t)||[],o=new Map;e.slice(Math.max(0,e.length-n.maxRecentCitations)).reverse().forEach(a=>{a.id&&o.set(a.id,a)}),i.forEach(a=>{!a.id||o.has(a.id)||o.set(a.id,a)});const r=Array.from(o.values()).slice(0,n.maxRecentCitations);return D.set(t,r),r}function St(t,e,n,i){const o=F(i.normalizeText(e||""));return o&&rt(t,n,i).find(a=>a.id===o)||null}function qt(t,e,n){const i=F(n.normalizeText(e||""));if(!i)return!1;const o=D.get(t)||[],r=o.filter(a=>a.id!==i);return r.length===o.length?!1:(D.set(t,r),!0)}function Et(t,e,n){const i=document.createElement("section");i.className=t,i.setAttribute("data-type",e),i.setAttribute("contenteditable","false"),i.setAttribute("aria-label",n),e==="citation-bibliography"?i.setAttribute("role","doc-bibliography"):e==="citation-footnotes"&&i.setAttribute("role","doc-endnotes");const o=document.createElement("h3");o.className="rte-citation-section-title",o.textContent=n;const r=document.createElement("ol");return r.className="rte-citation-list",r.setAttribute("role","list"),i.appendChild(o),i.appendChild(r),i}function jt(t,e){let n=t.querySelector(W);n||(n=Et("rte-citation-bibliography","citation-bibliography",e.labels.bibliographyTitle),t.appendChild(n));const i=n.querySelector(".rte-citation-section-title");return i&&(i.textContent=e.labels.bibliographyTitle),n.setAttribute("aria-label",e.labels.bibliographyTitle),n}function Kt(t,e){let n=t.querySelector(G);n||(n=Et("rte-citation-footnotes","citation-footnotes",e.labels.footnotesTitle),t.appendChild(n));const i=n.querySelector(".rte-citation-section-title");return i&&(i.textContent=e.labels.footnotesTitle),n.setAttribute("aria-label",e.labels.footnotesTitle),n}function $t(t,e){t.querySelector(e)?.remove()}function Ut(t,e,n,i){if(e.length===0){$t(t,W);return}const r=jt(t,n).querySelector(".rte-citation-list");if(!r)return;const a=document.createDocumentFragment();e.forEach((s,u)=>{const c=document.createElement("li");c.className="rte-citation-item",c.id=`rte-citation-entry-${s.id}`,c.setAttribute("data-citation-id",s.id),c.setAttribute("data-citation-number",String(u+1)),c.textContent=ut(s,i),a.appendChild(c)}),r.innerHTML="",r.appendChild(a)}function Wt(t,e,n,i){if(!n.enableFootnoteSync||e.length===0){$t(t,G),R(t).forEach(l=>{l.removeAttribute("data-footnote-number"),l.removeAttribute("data-footnote-target")});return}const r=Kt(t,n).querySelector(".rte-citation-list");if(!r)return;const a=new Map,s=new Map;e.forEach((l,d)=>{s.set(l.id,d+1)});const u=new Map;R(t).forEach(l=>{const d=l.getAttribute("data-citation-id")||"";if(!d||!s.has(d))return;const m=(u.get(d)||0)+1;u.set(d,m);const w=`rte-citation-ref-${d}-${m}`;l.id=w;const A=s.get(d);l.setAttribute("data-footnote-number",String(A)),l.setAttribute("data-footnote-target",`rte-citation-note-${d}`),a.has(d)||a.set(d,w)});const c=document.createDocumentFragment();e.forEach((l,d)=>{const m=document.createElement("li");m.className="rte-citation-item rte-citation-footnote-item",m.id=`rte-citation-note-${l.id}`,m.setAttribute("data-citation-id",l.id);const w=document.createElement("span");w.className="rte-citation-footnote-number",w.textContent=`${d+1}. `;const A=document.createElement("span");A.className="rte-citation-footnote-text";const It=l.note?`${l.note}. `:"";A.textContent=`${It}${ut(l,i)}`,m.appendChild(w),m.appendChild(A);const gt=a.get(l.id);if(gt){const _=document.createElement("a");_.className="rte-citation-backref",_.href=`#${gt}`,_.setAttribute("aria-label",`Back to citation ${d+1}`),_.textContent="Back",m.appendChild(_)}c.appendChild(m)}),r.innerHTML="",r.appendChild(c)}function Gt(t,e,n,i){const o=ut(e,n);t.setAttribute("data-citation-number",String(i)),t.setAttribute("aria-label",`Citation ${i}: ${o}`)}function Vt(t,e,n){const i=R(t);let o=`${e}:${n?"1":"0"}:${i.length}`;return i.forEach(r=>{o+=`|${r.getAttribute("data-citation-id")||""}`,o+=`|${r.getAttribute("data-citation-author")||""}`,o+=`|${r.getAttribute("data-citation-year")||""}`,o+=`|${r.getAttribute("data-citation-title")||""}`,o+=`|${r.getAttribute("data-citation-source")||""}`,o+=`|${r.getAttribute("data-citation-url")||""}`,o+=`|${r.getAttribute("data-citation-note")||""}`}),o}function H(t){const e=v.get(t);if(!e)return;const n=f.get(t)||M;if(!n)return;const i=N(t,n),o=K(t,n),r=rt(t,o,n),a=e.querySelector(".rte-citations-status"),s=e.querySelector('[data-action="cycle-style"]'),u=e.querySelector(".rte-citations-recent-list");if(a){const c=o.length;a.textContent=`${n.labels.summaryPrefix}: ${c} | Style: ${i.toUpperCase()} | Footnotes: ${n.enableFootnoteSync?"On":"Off"}`}if(s&&(s.textContent=`${n.labels.styleButtonPrefix}: ${i.toUpperCase()}`,s.setAttribute("aria-label",`${n.labels.styleButtonPrefix}: ${i.toUpperCase()}`)),u){if(r.length===0){u.innerHTML=`<li class="rte-citations-empty">${g(n.labels.noCitationsText)}</li>`;return}u.innerHTML=r.map(c=>` | ||
| <li class="rte-citations-recent-item"> | ||
| <div class="rte-citations-recent-row"> | ||
| <button | ||
| type="button" | ||
| class="rte-citations-recent-btn" | ||
| data-action="insert-from-recent" | ||
| data-citation-id="${g(c.id)}" | ||
| aria-label="Insert citation: ${g(c.title)}" | ||
| > | ||
| <span class="rte-citations-recent-title">${g(c.title)}</span> | ||
| <span class="rte-citations-recent-meta">${g(c.author)}${c.year?` (${g(c.year)})`:""}</span> | ||
| </button> | ||
| <button | ||
| type="button" | ||
| class="rte-citations-recent-delete" | ||
| data-action="delete-by-id" | ||
| data-citation-id="${g(c.id)}" | ||
| aria-label="Delete citation: ${g(c.title)}" | ||
| >${g(n.labels.deleteRecentText)}</button> | ||
| </div> | ||
| </li> | ||
| `).join("")}}function y(t,e,n=!1){const i=N(t,e),o=Vt(t,i,e.enableFootnoteSync);if(!n&&pt.get(t)===o)return K(t,e);const r=R(t),a=new Map;r.forEach(c=>{const l=wt(c,e);l&&(a.has(l.id)||a.set(l.id,l))});const s=Array.from(a.values());rt(t,s,e);const u=new Map;return s.forEach((c,l)=>{u.set(c.id,l+1)}),r.forEach(c=>{const l=c.getAttribute("data-citation-id")||"",d=a.get(l);if(!d)return;vt(c,d,i);const m=u.get(d.id)||1;Gt(c,d,i,Math.max(1,m))}),Ut(t,s,e,i),Wt(t,s,e,i),pt.set(t,o),H(t),t.dispatchEvent(new CustomEvent("editora:citations-refreshed",{bubbles:!0,detail:{citations:s,style:i,footnoteSync:e.enableFootnoteSync}})),s}function At(t){const e=Q.get(t);typeof e=="number"&&(window.clearTimeout(e),q.delete(e),Q.delete(t))}function kt(t){const e=f.get(t)||M;if(!e)return;At(t);const n=window.setTimeout(()=>{q.delete(n),Q.delete(t),y(t,e,!1)},e.debounceMs);q.add(n),Q.set(t,n)}function Yt(t){const e=window.getSelection();if(!e)throw new Error("Selection unavailable");if(e.rangeCount>0){const a=e.getRangeAt(0);if(t.contains(a.commonAncestorContainer)&&!j(a.commonAncestorContainer))return a.cloneRange()}const n=document.createRange(),i=t.querySelector(W),o=t.querySelector(G),r=i||o;return r?(n.setStartBefore(r),n.collapse(!0),n):(n.selectNodeContents(t),n.collapse(!1),n)}function dt(t){t.dispatchEvent(new Event("input",{bubbles:!0}))}function ft(t,e){if(e===t.innerHTML)return;const n=window.execEditorCommand||window.executeEditorCommand;if(typeof n=="function")try{n("recordDomTransaction",t,e,t.innerHTML)}catch{}}function Tt(t,e){const n=window.getSelection();if(!n)return;const i=document.createRange();if(t.nodeType===Node.TEXT_NODE){const o=t,r=Math.max(0,Math.min(e,o.length));i.setStart(o,r)}else{const o=t.childNodes.length,r=Math.max(0,Math.min(e,o));i.setStart(t,r)}i.collapse(!0),n.removeAllRanges(),n.addRange(i)}function Mt(t){if(t.collapsed||t.startContainer!==t.endContainer||t.endOffset!==t.startOffset+1||!(t.startContainer instanceof Element||t.startContainer instanceof DocumentFragment))return null;const e=t.startContainer.childNodes[t.startOffset];return!(e instanceof HTMLElement)||!e.matches(ot)?null:e}function J(t,e,n){const{startContainer:i,startOffset:o}=t;if(i.nodeType===Node.ELEMENT_NODE){const a=i;if(n==="previous"){if(o>0)return a.childNodes[o-1]||null}else if(o<a.childNodes.length)return a.childNodes[o]||null}if(i.nodeType===Node.TEXT_NODE&&(n==="previous"&&o<i.data.length||n==="next"&&o>0))return null;let r=i;for(;r&&r!==e;){const a=n==="previous"?r.previousSibling:r.nextSibling;if(a)return a;r=r.parentNode}return null}function Lt(t,e,n){if(!t.collapsed)return null;const i=a=>a instanceof HTMLElement&&a.matches(ot)?a:null,{startContainer:o,startOffset:r}=t;if(o.nodeType===Node.ELEMENT_NODE){const a=o;return n==="Backspace"&&r>0?i(a.childNodes[r-1]||null):n==="Delete"?i(a.childNodes[r]||null):null}if(o.nodeType===Node.TEXT_NODE){const a=o;if(n==="Backspace"&&r===0){const s=i(a.previousSibling);return s||i(J(t,e,"previous"))}if(n==="Delete"&&r===a.data.length){const s=i(a.nextSibling);return s||i(J(t,e,"next"))}}return i(n==="Backspace"?J(t,e,"previous"):J(t,e,"next"))}function P(t,e,n){const i=t.closest(E);if(!i||j(t))return!1;const o=t.parentNode;if(!o)return!1;const r=i.innerHTML,a=Array.from(o.childNodes).indexOf(t);if(a<0)return!1;const s=t.nextSibling;return s instanceof Text&&(s.data===" "?s.remove():s.data.startsWith(" ")&&(s.data=s.data.slice(1))),t.remove(),Tt(o,a),y(i,n,!0),ft(i,r),dt(i),e==="Delete"&&i.focus({preventScroll:!0}),!0}function Xt(t,e,n){if(t.key!=="Backspace"&&t.key!=="Delete")return!1;const i=t.key,o=t.target;if(o?.matches(ot)&&e.contains(o)&&!j(o))return t.preventDefault(),t.stopPropagation(),P(o,i,n);const r=window.getSelection();if(!r||r.rangeCount===0)return!1;const a=r.getRangeAt(0);if(!e.contains(a.commonAncestorContainer)||j(a.commonAncestorContainer))return!1;const s=Mt(a);if(s)return t.preventDefault(),t.stopPropagation(),P(s,i,n);const u=Lt(a,e,i);return u?(t.preventDefault(),t.stopPropagation(),P(u,i,n)):!1}function Rt(t,e,n){const i=F(n.normalizeText(e||""));if(!i)return!1;const o=R(t).filter(a=>a.getAttribute("data-citation-id")===i);if(o.length===0)return!1;if(o.length===1)return P(o[0],"Delete",n);const r=t.innerHTML;return o.forEach(a=>{const s=a.nextSibling;s instanceof Text&&(s.data===" "?s.remove():s.data.startsWith(" ")&&(s.data=s.data.slice(1))),a.remove()}),Tt(t,t.childNodes.length),y(t,n,!0),ft(t,r),dt(t),t.focus({preventScroll:!0}),!0}function Jt(t,e){const n=window.getSelection();if(!n||n.rangeCount===0)return!1;const i=n.getRangeAt(0);if(!t.contains(i.commonAncestorContainer)||j(i.commonAncestorContainer))return!1;const o=Mt(i);if(o)return P(o,"Delete",e);const r=Lt(i,t,"Backspace");return r?P(r,"Backspace",e):!1}function et(t,e,n){const i=yt(e,n);if(!i.author||!i.title)return!1;i.id||(i.id=Ht(t,n));const o=t.innerHTML;let r;try{r=Yt(t)}catch{return!1}const a=window.getSelection();if(!a)return!1;r.collapsed||r.deleteContents();const s=document.createElement("span");vt(s,i,N(t,n));try{r.insertNode(s)}catch{return!1}const u=document.createTextNode(" ");s.nextSibling?s.parentNode?.insertBefore(u,s.nextSibling):s.parentNode?.appendChild(u);const c=document.createRange();if(u.parentNode){const l=Array.from(u.parentNode.childNodes).indexOf(u)+1;c.setStart(u.parentNode,Math.max(0,l))}else c.setStartAfter(s);return c.collapse(!0),a.removeAllRanges(),a.addRange(c),_t(t,i,n),y(t,n,!0),ft(t,o),dt(t),!0}function Zt(t,e){if(!e)return!1;const n=R(t).find(r=>r.getAttribute("data-citation-id")===e)||null;if(!n)return!1;n.scrollIntoView({behavior:"smooth",block:"center",inline:"nearest"}),n.focus({preventScroll:!0});const i=window.getSelection();if(!i)return!0;const o=document.createRange();return o.selectNode(n),i.removeAllRanges(),i.addRange(o),!0}function nt(t){return V.get(t)===!0}function U(t,e=!1){const n=v.get(t);n&&(n.classList.remove("show"),V.set(t,!1),it(t,"toggleCitationsPanel",!1),e&&t.focus({preventScroll:!0}))}function Qt(t){v.forEach((e,n)=>{n!==t&&U(n,!1)})}function ct(t,e){if(!e.classList.contains("show"))return;const i=lt(t).getBoundingClientRect(),o=Math.min(window.innerWidth-20,380),r=Math.max(10,window.innerWidth-o-10),a=Math.min(Math.max(10,i.right-o),r),s=Math.max(10,Math.min(window.innerHeight-10-260,i.top+10));e.style.width=`${o}px`,e.style.left=`${a}px`,e.style.top=`${s}px`,e.style.maxHeight=`${Math.max(260,window.innerHeight-24)}px`}function C(t,e){return t.querySelector(`[data-field="${e}"]`)}function te(t){const e=C(t,"author")?.value||"",n=C(t,"year")?.value||"",i=C(t,"title")?.value||"",o=C(t,"source")?.value||"",r=C(t,"url")?.value||"",a=C(t,"note")?.value||"";return{author:e,year:n,title:i,source:o,url:r,note:a}}function S(t,e){const n=t.querySelector(".rte-citations-live");n&&(n.textContent=e)}function ee(t,e,n){const i=C(e,"style");i&&(i.value=N(t,n))}function Nt(t,e,n){const i=L.includes(e)?e:n.defaultStyle;return T.set(t,i),y(t,n,!0),i}function bt(t,e){const n=N(t,e),i=L.indexOf(n),o=L[(i+1)%L.length];return T.set(t,o),y(t,e,!0),o}function ne(t){const e=v.get(t);if(e)return e;const n=f.get(t)||M||Z(),i=`rte-citations-panel-${Ot++}`,o=document.createElement("section");o.className=b,o.id=i,o.setAttribute("role","dialog"),o.setAttribute("aria-modal","false"),o.setAttribute("aria-label",n.labels.panelAriaLabel),o.setAttribute("tabindex","-1"),o.innerHTML=` | ||
| <header class="rte-citations-header"> | ||
| <h2 class="rte-citations-title">${g(n.labels.panelTitle)}</h2> | ||
| <button type="button" class="rte-citations-icon-btn" data-action="close" aria-label="${g(n.labels.closeText)}">✕</button> | ||
| </header> | ||
| <div class="rte-citations-body"> | ||
| <p class="rte-citations-status" aria-live="polite"></p> | ||
| <div class="rte-citations-grid"> | ||
| <label class="rte-citations-label"> | ||
| ${g(n.labels.styleLabel)} | ||
| <select data-field="style" class="rte-citations-field"> | ||
| <option value="apa">APA</option> | ||
| <option value="mla">MLA</option> | ||
| <option value="chicago">Chicago</option> | ||
| </select> | ||
| </label> | ||
| <label class="rte-citations-label"> | ||
| ${g(n.labels.authorLabel)} | ||
| <input type="text" data-field="author" class="rte-citations-field" autocomplete="off" /> | ||
| </label> | ||
| <label class="rte-citations-label"> | ||
| ${g(n.labels.yearLabel)} | ||
| <input type="text" data-field="year" class="rte-citations-field" inputmode="numeric" autocomplete="off" /> | ||
| </label> | ||
| <label class="rte-citations-label"> | ||
| ${g(n.labels.titleLabel)} | ||
| <input type="text" data-field="title" class="rte-citations-field" autocomplete="off" /> | ||
| </label> | ||
| <label class="rte-citations-label"> | ||
| ${g(n.labels.sourceLabel)} | ||
| <input type="text" data-field="source" class="rte-citations-field" autocomplete="off" /> | ||
| </label> | ||
| <label class="rte-citations-label"> | ||
| ${g(n.labels.urlLabel)} | ||
| <input type="url" data-field="url" class="rte-citations-field" autocomplete="off" /> | ||
| </label> | ||
| <label class="rte-citations-label rte-citations-label-note"> | ||
| ${g(n.labels.noteLabel)} | ||
| <textarea data-field="note" class="rte-citations-field" rows="2"></textarea> | ||
| </label> | ||
| </div> | ||
| <div class="rte-citations-controls" role="toolbar" aria-label="Citation actions"> | ||
| <button type="button" class="rte-citations-btn rte-citations-btn-primary" data-action="insert">${g(n.labels.insertText)}</button> | ||
| <button type="button" class="rte-citations-btn" data-action="refresh">${g(n.labels.refreshText)}</button> | ||
| <button type="button" class="rte-citations-btn" data-action="cycle-style"></button> | ||
| </div> | ||
| <section class="rte-citations-recent" aria-label="${g(n.labels.recentHeading)}"> | ||
| <h3 class="rte-citations-recent-heading">${g(n.labels.recentHeading)}</h3> | ||
| <ul class="rte-citations-recent-list" role="list"></ul> | ||
| </section> | ||
| <p class="rte-citations-shortcut">Shortcut: Ctrl/Cmd + Alt + Shift + C</p> | ||
| <span class="rte-citations-live" aria-live="polite"></span> | ||
| </div> | ||
| `,o.addEventListener("click",a=>{const s=a.target;if(!s)return;const u=s.closest("[data-action]");if(!u)return;const c=u.getAttribute("data-action")||"",l=f.get(t)||M||n;if(f.set(t,l),c==="close"){U(t,!0);return}if(c==="insert"){if($(t))return;const d=te(o);if(!l.normalizeText(d.author)||!l.normalizeText(d.title)){S(o,l.labels.invalidMessage);return}if(!et(t,d,l)){S(o,l.labels.invalidMessage);return}S(o,"Citation inserted.");const w=C(o,"title"),A=C(o,"note");w&&(w.value=""),A&&(A.value="");return}if(c==="refresh"){const d=y(t,l,!0);S(o,`Refreshed ${d.length} citation${d.length===1?"":"s"}.`);return}if(c==="cycle-style"){const d=bt(t,l);ee(t,o,l),S(o,`Style changed to ${d.toUpperCase()}.`);return}if(c==="insert-from-recent"){if($(t))return;const d=u.getAttribute("data-citation-id")||"",m=St(t,d,K(t,l),l);if(!m)return;et(t,m,l),S(o,`Inserted citation: ${m.title}.`);return}if(c==="delete-by-id"){if($(t))return;const d=u.getAttribute("data-citation-id")||"";if(Rt(t,d,l)){S(o,"Citation deleted.");return}qt(t,d,l)&&(H(t),S(o,"Removed from recent citations."))}}),o.addEventListener("keydown",a=>{if(a.key==="Escape"){a.preventDefault(),U(t,!0);return}const s=a.target;if(!s||!s.matches(".rte-citations-recent-btn")||a.key!=="ArrowDown"&&a.key!=="ArrowUp")return;const u=Array.from(o.querySelectorAll(".rte-citations-recent-btn"));if(u.length===0)return;const c=u.indexOf(s);if(c<0)return;a.preventDefault();const l=a.key==="ArrowDown"?1:-1,d=(c+l+u.length)%u.length;u[d].focus()});const r=C(o,"style");return r?.addEventListener("change",()=>{const a=f.get(t)||M||n,s=r.value;Nt(t,s,a),S(o,`Style changed to ${s.toUpperCase()}.`)}),tt(o,t),document.body.appendChild(o),v.set(t,o),V.set(t,!1),H(t),o}function z(t){const e=ne(t);Qt(t),e.classList.add("show"),V.set(t,!0),it(t,"toggleCitationsPanel",!0),tt(e,t),ct(t,e),H(t),C(e,"author")?.focus()}function zt(t,e){const n=nt(t);return(typeof e=="boolean"?e:!n)?z(t):U(t,!1),!0}function oe(t){const e=t.key.toLowerCase();return(t.metaKey||t.ctrlKey)&&t.altKey&&t.shiftKey&&e==="c"}function ie(t){const e=t.key.toLowerCase();return(t.metaKey||t.ctrlKey)&&t.altKey&&t.shiftKey&&e==="b"}function re(t){const e=t.key.toLowerCase();return(t.metaKey||t.ctrlKey)&&t.altKey&&t.shiftKey&&e==="j"}function ae(t){M=t,I||(I=e=>{const i=e.target?.closest(E);if(!i)return;p=i,f.has(i)||f.set(i,t),T.has(i)||T.set(i,t.defaultStyle);const o=v.get(i);o&&(tt(o,i),ct(i,o)),it(i,"toggleCitationsPanel",nt(i))},document.addEventListener("focusin",I,!0)),B||(B=e=>{const i=e.target?.closest(E);i&&(p=i,kt(i))},document.addEventListener("input",B,!0)),O||(O=e=>{if(e.defaultPrevented)return;const i=!!e.target?.closest(`.${b} input, .${b} textarea, .${b} select`),o=h(void 0,!1);if(!o||$(o))return;const r=f.get(o)||M||t;if(f.set(o,r),p=o,e.key==="Escape"&&nt(o)){e.preventDefault(),U(o,!0);return}if(!i&&!Xt(e,o,r)){if(oe(e)){e.preventDefault(),e.stopPropagation(),zt(o);return}if(ie(e)){e.preventDefault(),e.stopPropagation(),y(o,r,!0),z(o);return}re(e)&&(e.preventDefault(),e.stopPropagation(),bt(o,r))}},document.addEventListener("keydown",O,!0)),k||(k=()=>{v.forEach((e,n)=>{if(!n.isConnected||!e.isConnected){At(n),e.remove(),v.delete(n),V.delete(n);return}tt(e,n),ct(n,e)})},window.addEventListener("scroll",k,!0),window.addEventListener("resize",k))}function se(){I&&(document.removeEventListener("focusin",I,!0),I=null),B&&(document.removeEventListener("input",B,!0),B=null),O&&(document.removeEventListener("keydown",O,!0),O=null),k&&(window.removeEventListener("scroll",k,!0),window.removeEventListener("resize",k),k=null),v.forEach(t=>t.remove()),v.clear(),M=null,p=null}function ce(){if(typeof document>"u"||document.getElementById(mt))return;const t=document.createElement("style");t.id=mt,t.textContent=` | ||
| .rte-toolbar-group-items.citations, | ||
| .editora-toolbar-group-items.citations { | ||
| display: flex; | ||
| border: 1px solid #ccc; | ||
| border-radius: 3px; | ||
| background: #fff; | ||
| } | ||
| .rte-toolbar-group-items.citations .rte-toolbar-button, | ||
| .editora-toolbar-group-items.citations .editora-toolbar-button { | ||
| border: none; | ||
| border-radius: 0; | ||
| border-right: 1px solid #ccc; | ||
| } | ||
| .rte-toolbar-group-items.citations .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.citations .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| .rte-toolbar-button[data-command="toggleCitationsPanel"].active, | ||
| .editora-toolbar-button[data-command="toggleCitationsPanel"].active { | ||
| background: #ccc; | ||
| } | ||
| ${x} .rte-toolbar-group-items.citations, | ||
| ${x} .editora-toolbar-group-items.citations, | ||
| .${b}.rte-citations-theme-dark { | ||
| border-color: #566275; | ||
| } | ||
| ${x} .rte-toolbar-group-items.citations .rte-toolbar-button[data-command="refreshCitations"] svg, | ||
| ${x} .editora-toolbar-group-items.citations .editora-toolbar-button[data-command="refreshCitations"] svg | ||
| { | ||
| fill: none; | ||
| } | ||
| ${x} .rte-toolbar-group-items.citations .rte-toolbar-button, | ||
| ${x} .editora-toolbar-group-items.citations .editora-toolbar-button | ||
| { | ||
| border-color: #566275; | ||
| } | ||
| ${x} .rte-toolbar-button[data-command="toggleCitationsPanel"].active, | ||
| ${x} .editora-toolbar-button[data-command="toggleCitationsPanel"].active { | ||
| background: linear-gradient(180deg, #5eaaf6 0%, #4a95de 100%); | ||
| } | ||
| .${b} { | ||
| position: fixed; | ||
| z-index: 1500; | ||
| right: 16px; | ||
| top: 16px; | ||
| width: min(380px, calc(100vw - 20px)); | ||
| max-height: calc(100vh - 24px); | ||
| display: none; | ||
| flex-direction: column; | ||
| border-radius: 12px; | ||
| border: 1px solid #d1d5db; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| box-shadow: 0 18px 38px rgba(15, 23, 42, 0.16); | ||
| overflow: hidden; | ||
| } | ||
| .${b}.show { | ||
| display: flex; | ||
| } | ||
| .${b}.rte-citations-theme-dark { | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| border-color: #334155; | ||
| box-shadow: 0 20px 40px rgba(2, 6, 23, 0.5); | ||
| } | ||
| .rte-citations-header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| padding: 10px 12px; | ||
| border-bottom: 1px solid #e2e8f0; | ||
| background: #f8fafc; | ||
| } | ||
| .${b}.rte-citations-theme-dark .rte-citations-header { | ||
| border-bottom-color: #334155; | ||
| background: #111827; | ||
| } | ||
| .rte-citations-title { | ||
| margin: 0; | ||
| font-size: 14px; | ||
| font-weight: 700; | ||
| } | ||
| .rte-citations-icon-btn { | ||
| border: 1px solid #cbd5e1; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| border-radius: 6px; | ||
| cursor: pointer; | ||
| min-width: 34px; | ||
| min-height: 34px; | ||
| width: 34px; | ||
| height: 34px; | ||
| padding: 0; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| font-weight: 600; | ||
| } | ||
| .rte-citations-icon-btn:hover, | ||
| .rte-citations-icon-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .${b}.rte-citations-theme-dark .rte-citations-icon-btn { | ||
| background: #0f172a; | ||
| border-color: #475569; | ||
| color: #e2e8f0; | ||
| } | ||
| .${b}.rte-citations-theme-dark .rte-citations-icon-btn:hover, | ||
| .${b}.rte-citations-theme-dark .rte-citations-icon-btn:focus-visible { | ||
| border-color: #60a5fa; | ||
| box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.24); | ||
| } | ||
| .rte-citations-body { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 10px; | ||
| padding: 12px; | ||
| overflow: auto; | ||
| } | ||
| .rte-citations-status { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| color: #475569; | ||
| } | ||
| .${b}.rte-citations-theme-dark .rte-citations-status { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-citations-grid { | ||
| display: grid; | ||
| grid-template-columns: 1fr 1fr; | ||
| gap: 8px; | ||
| } | ||
| .rte-citations-label { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 4px; | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| color: inherit; | ||
| } | ||
| .rte-citations-label-note { | ||
| grid-column: 1 / -1; | ||
| } | ||
| .rte-citations-field { | ||
| width: 100%; | ||
| box-sizing: border-box; | ||
| min-height: 30px; | ||
| border-radius: 8px; | ||
| border: 1px solid #cbd5e1; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| font-size: 13px; | ||
| padding: 6px 8px; | ||
| } | ||
| .rte-citations-field:focus-visible { | ||
| outline: none; | ||
| border-color: #1d4ed8; | ||
| box-shadow: 0 0 0 2px rgba(29, 78, 216, 0.2); | ||
| } | ||
| .${b}.rte-citations-theme-dark .rte-citations-field { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #e2e8f0; | ||
| } | ||
| .rte-citations-controls { | ||
| display: flex; | ||
| flex-wrap: wrap; | ||
| gap: 8px; | ||
| } | ||
| .rte-citations-btn { | ||
| border: 1px solid #cbd5e1; | ||
| background: #f8fafc; | ||
| color: inherit; | ||
| border-radius: 8px; | ||
| padding: 6px 10px; | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| cursor: pointer; | ||
| } | ||
| .rte-citations-btn:hover, | ||
| .rte-citations-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #1d4ed8; | ||
| box-shadow: 0 0 0 2px rgba(29, 78, 216, 0.2); | ||
| } | ||
| .rte-citations-btn-primary { | ||
| background: #1d4ed8; | ||
| border-color: #1d4ed8; | ||
| color: #ffffff; | ||
| } | ||
| .rte-citations-btn-primary:hover, | ||
| .rte-citations-btn-primary:focus-visible { | ||
| background: #1e40af; | ||
| border-color: #1e40af; | ||
| } | ||
| .${b}.rte-citations-theme-dark .rte-citations-btn { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #e2e8f0; | ||
| } | ||
| .${b}.rte-citations-theme-dark .rte-citations-btn-primary { | ||
| border-color: #2563eb; | ||
| background: #2563eb; | ||
| color: #ffffff; | ||
| } | ||
| .rte-citations-recent { | ||
| border: 1px solid #e2e8f0; | ||
| border-radius: 10px; | ||
| padding: 8px; | ||
| } | ||
| .${b}.rte-citations-theme-dark .rte-citations-recent { | ||
| border-color: #334155; | ||
| } | ||
| .rte-citations-recent-heading { | ||
| margin: 0 0 8px; | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| } | ||
| .rte-citations-recent-list { | ||
| margin: 0; | ||
| padding: 0; | ||
| list-style: none; | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 6px; | ||
| max-height: 170px; | ||
| overflow: auto; | ||
| } | ||
| .rte-citations-recent-btn { | ||
| width: 100%; | ||
| text-align: left; | ||
| border: 1px solid #cbd5e1; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| border-radius: 8px; | ||
| padding: 7px; | ||
| cursor: pointer; | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 2px; | ||
| } | ||
| .rte-citations-recent-row { | ||
| display: flex; | ||
| gap: 6px; | ||
| align-items: stretch; | ||
| } | ||
| .rte-citations-recent-delete { | ||
| flex: 0 0 auto; | ||
| border: 1px solid #fecaca; | ||
| background: #fff1f2; | ||
| color: #b91c1c; | ||
| border-radius: 8px; | ||
| padding: 0 8px; | ||
| font-size: 11px; | ||
| font-weight: 700; | ||
| cursor: pointer; | ||
| min-height: 34px; | ||
| } | ||
| .rte-citations-recent-delete:hover, | ||
| .rte-citations-recent-delete:focus-visible { | ||
| outline: none; | ||
| border-color: #f87171; | ||
| box-shadow: 0 0 0 2px rgba(248, 113, 113, 0.2); | ||
| } | ||
| .rte-citations-recent-btn:focus-visible, | ||
| .rte-citations-recent-btn:hover { | ||
| outline: none; | ||
| border-color: #1d4ed8; | ||
| box-shadow: 0 0 0 2px rgba(29, 78, 216, 0.18); | ||
| } | ||
| .${b}.rte-citations-theme-dark .rte-citations-recent-btn { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #e2e8f0; | ||
| } | ||
| .${b}.rte-citations-theme-dark .rte-citations-recent-delete { | ||
| border-color: #7f1d1d; | ||
| background: #2b1218; | ||
| color: #fca5a5; | ||
| } | ||
| .rte-citations-recent-title { | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| line-height: 1.3; | ||
| } | ||
| .rte-citations-recent-meta { | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| line-height: 1.3; | ||
| } | ||
| .${b}.rte-citations-theme-dark .rte-citations-recent-meta { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-citations-empty { | ||
| border: 1px dashed #cbd5e1; | ||
| border-radius: 8px; | ||
| padding: 8px; | ||
| font-size: 12px; | ||
| color: #64748b; | ||
| } | ||
| .${b}.rte-citations-theme-dark .rte-citations-empty { | ||
| border-color: #334155; | ||
| color: #94a3b8; | ||
| } | ||
| .rte-citations-shortcut { | ||
| margin: 0; | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| } | ||
| .${b}.rte-citations-theme-dark .rte-citations-shortcut { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-citations-live { | ||
| position: absolute; | ||
| width: 1px; | ||
| height: 1px; | ||
| margin: -1px; | ||
| padding: 0; | ||
| overflow: hidden; | ||
| clip: rect(0 0 0 0); | ||
| border: 0; | ||
| } | ||
| .rte-citation-ref { | ||
| display: inline-flex; | ||
| align-items: center; | ||
| border-radius: 6px; | ||
| border: 1px solid rgba(29, 78, 216, 0.24); | ||
| background: rgba(29, 78, 216, 0.08); | ||
| color: #1e3a8a; | ||
| padding: 0 4px; | ||
| margin: 0 1px; | ||
| font-size: 0.92em; | ||
| line-height: 1.35; | ||
| white-space: nowrap; | ||
| cursor: pointer; | ||
| user-select: all; | ||
| } | ||
| .rte-citation-ref:focus, | ||
| .rte-citation-ref:focus-visible { | ||
| outline: none; | ||
| border-color: #1d4ed8; | ||
| box-shadow: 0 0 0 2px rgba(29, 78, 216, 0.22); | ||
| } | ||
| .${x} .rte-citation-ref { | ||
| border-color: rgba(96, 165, 250, 0.45); | ||
| background: rgba(37, 99, 235, 0.22); | ||
| color: #bfdbfe; | ||
| } | ||
| .rte-citation-bibliography, | ||
| .rte-citation-footnotes { | ||
| margin-top: 16px; | ||
| border-top: 1px solid #d1d5db; | ||
| padding-top: 10px; | ||
| } | ||
| .${x} .rte-citation-bibliography, | ||
| .${x} .rte-citation-footnotes { | ||
| border-top-color: #475569; | ||
| } | ||
| .rte-citation-section-title { | ||
| margin: 0 0 8px; | ||
| font-size: 1em; | ||
| font-weight: 700; | ||
| } | ||
| .rte-citation-list { | ||
| margin: 0; | ||
| padding-left: 22px; | ||
| } | ||
| .rte-citation-item { | ||
| margin: 0 0 8px; | ||
| line-height: 1.45; | ||
| } | ||
| .rte-citation-backref { | ||
| margin-left: 8px; | ||
| color: #1d4ed8; | ||
| text-decoration: none; | ||
| font-size: 0.9em; | ||
| } | ||
| .rte-citation-backref:hover, | ||
| .rte-citation-backref:focus-visible { | ||
| text-decoration: underline; | ||
| outline: none; | ||
| } | ||
| .${x} .rte-citation-backref { | ||
| color: #93c5fd; | ||
| } | ||
| @media (max-width: 768px) { | ||
| .${b} { | ||
| left: 10px !important; | ||
| right: 10px; | ||
| top: 10px !important; | ||
| width: auto !important; | ||
| max-height: calc(100vh - 20px); | ||
| } | ||
| .rte-citations-grid { | ||
| grid-template-columns: 1fr; | ||
| } | ||
| .rte-citations-recent-list { | ||
| max-height: 34vh; | ||
| } | ||
| } | ||
| `,document.head.appendChild(t)}const le=(t={})=>{const e=Z(t);return ce(),{name:"citations",toolbar:[{id:"citationsGroup",label:"Citations",type:"group",command:"citations",items:[{id:"citations",label:"Citations",command:"toggleCitationsPanel",shortcut:"Mod-Alt-Shift-c",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M6 5h12M6 9h12M6 13h8M6 17h10" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/><path d="M17 14.5a2.5 2.5 0 0 1 2.5 2.5v2H15v-2a2 2 0 0 1 2-2Z" stroke="currentColor" stroke-width="1.5"/></svg>'},{id:"citationsRefresh",label:"Refresh Citations",command:"refreshCitations",shortcut:"Mod-Alt-Shift-b",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M20 12a8 8 0 1 1-2.34-5.66" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/><path d="M20 4v6h-6" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg>'},{id:"citationsStyle",label:"Cycle Citation Style",command:"cycleCitationStyle",shortcut:"Mod-Alt-Shift-j",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M5 6h14M5 10h8M5 14h14M5 18h10" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/><circle cx="18" cy="10" r="2" stroke="currentColor" stroke-width="1.6"/></svg>'}]}],commands:{citations:(n,i)=>{const o=h(i);if(!o||$(o))return!1;const r=f.get(o)||e;return f.set(o,r),T.set(o,N(o,r)),p=o,z(o),y(o,r,!1),!0},toggleCitationsPanel:(n,i)=>{const o=h(i);if(!o||$(o))return!1;const r=f.get(o)||e;f.set(o,r),p=o;const a=zt(o,typeof n=="boolean"?n:void 0);return nt(o)&&y(o,r,!1),a},insertCitation:(n,i)=>{const o=h(i);if(!o||$(o)||!n||typeof n!="object")return!1;const r=f.get(o)||e;f.set(o,r),p=o;const a=et(o,n,r);return a&&z(o),a},refreshCitations:(n,i)=>{const o=h(i);if(!o)return!1;const r=f.get(o)||e;return f.set(o,r),p=o,y(o,r,!0),z(o),!0},setCitationStyle:(n,i)=>{const o=h(i);if(!o||!n)return!1;const r=f.get(o)||e;return f.set(o,r),p=o,Nt(o,n,r),!0},cycleCitationStyle:(n,i)=>{const o=h(i);if(!o)return!1;const r=f.get(o)||e;return f.set(o,r),p=o,bt(o,r),H(o),!0},getCitationRecords:(n,i)=>{const o=h(i);if(!o)return!1;const r=f.get(o)||e,a=K(o,r);if(typeof n=="function")try{n(a)}catch{}return o.__citationRecords=a,o.dispatchEvent(new CustomEvent("editora:citations-data",{bubbles:!0,detail:{records:a,style:N(o,r)}})),!0},setCitationsOptions:(n,i)=>{const o=h(i);if(!o||!n||typeof n!="object")return!1;const r=f.get(o)||e,a=Z({...r,...n,labels:{...r.labels,...n.labels||{}},normalizeText:n.normalizeText||r.normalizeText,generateCitationId:n.generateCitationId||r.generateCitationId});return f.set(o,a),n.defaultStyle&&L.includes(n.defaultStyle)&&T.set(o,n.defaultStyle),y(o,a,!0),H(o),!0},locateCitation:(n,i)=>{const o=h(i);return!o||typeof n!="string"?!1:Zt(o,n)},deleteCitation:(n,i)=>{const o=h(i);if(!o||$(o))return!1;const r=f.get(o)||e;return f.set(o,r),typeof n=="string"&&n.trim()?Rt(o,n,r):Jt(o,r)},insertRecentCitation:(n,i)=>{const o=h(i);if(!o||$(o))return!1;const r=f.get(o)||e;f.set(o,r);const a=K(o,r),s=rt(o,a,r);if(s.length===0)return!1;const u=typeof n=="string"&&n.trim()?St(o,n,a,r):s[0];if(!u)return!1;const c=et(o,u,r);return c&&z(o),c}},keymap:{"Mod-Alt-Shift-c":"toggleCitationsPanel","Mod-Alt-Shift-C":"toggleCitationsPanel","Mod-Alt-Shift-b":"refreshCitations","Mod-Alt-Shift-B":"refreshCitations","Mod-Alt-Shift-j":"cycleCitationStyle","Mod-Alt-Shift-J":"cycleCitationStyle"},init:function(i){Y+=1;const o=this&&typeof this.__pluginConfig=="object"?Z({...e,...this.__pluginConfig}):e;ae(o);const r=h(i&&i.editorElement?{editorElement:i.editorElement}:void 0,!1);r&&(p=r,f.set(r,o),T.set(r,o.defaultStyle),it(r,"toggleCitationsPanel",!1),kt(r))},destroy:()=>{Y=Math.max(0,Y-1),!(Y>0)&&(q.forEach(n=>{window.clearTimeout(n)}),q.clear(),se())}}};exports.CitationsPlugin=le; |
| const S = ".rte-content, .editora-content", mt = "rte-citations-styles", b = "rte-citations-panel", ot = ".rte-citation-ref[data-citation-id]", W = '.rte-citation-bibliography[data-type="citation-bibliography"]', G = '.rte-citation-footnotes[data-type="citation-footnotes"]', x = ':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)', L = ["apa", "mla", "chicago"], Bt = { | ||
| panelTitle: "Citations", | ||
| panelAriaLabel: "Citations panel", | ||
| styleLabel: "Citation style", | ||
| authorLabel: "Author", | ||
| yearLabel: "Year", | ||
| titleLabel: "Title", | ||
| sourceLabel: "Source", | ||
| urlLabel: "URL", | ||
| noteLabel: "Footnote note", | ||
| insertText: "Insert Citation", | ||
| refreshText: "Refresh Bibliography", | ||
| closeText: "Close", | ||
| bibliographyTitle: "References", | ||
| footnotesTitle: "Citation Notes", | ||
| noCitationsText: "No citations inserted yet.", | ||
| styleButtonPrefix: "Style", | ||
| recentHeading: "Recent citations", | ||
| deleteRecentText: "x", | ||
| summaryPrefix: "Citations", | ||
| invalidMessage: "Author and title are required." | ||
| }, f = /* @__PURE__ */ new WeakMap(), T = /* @__PURE__ */ new WeakMap(), pt = /* @__PURE__ */ new WeakMap(), D = /* @__PURE__ */ new WeakMap(), v = /* @__PURE__ */ new Map(), V = /* @__PURE__ */ new WeakMap(), Q = /* @__PURE__ */ new WeakMap(), q = /* @__PURE__ */ new Set(); | ||
| let I = null, B = null, O = null, k = null, Y = 0, Ot = 0, at = 0, M = null, p = null; | ||
| function g(t) { | ||
| return t.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); | ||
| } | ||
| function Pt(t) { | ||
| return t.replace(/\u00A0/g, " ").replace(/\s+/g, " ").trim(); | ||
| } | ||
| function ht(t, e) { | ||
| const n = e(t); | ||
| if (!n) return ""; | ||
| const i = n.match(/\d{4}/); | ||
| return i ? i[0] : n; | ||
| } | ||
| function xt(t, e) { | ||
| const n = e(t); | ||
| return n ? /^https?:\/\//i.test(n) ? n : `https://${n}` : ""; | ||
| } | ||
| function F(t) { | ||
| return t.toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80); | ||
| } | ||
| function yt(t, e) { | ||
| return { | ||
| id: F(e.normalizeText(t.id || "")), | ||
| author: e.normalizeText(t.author || ""), | ||
| year: ht(t.year || "", e.normalizeText) || void 0, | ||
| title: e.normalizeText(t.title || ""), | ||
| source: e.normalizeText(t.source || "") || void 0, | ||
| url: xt(t.url || "", e.normalizeText) || void 0, | ||
| note: e.normalizeText(t.note || "") || void 0 | ||
| }; | ||
| } | ||
| function Z(t = {}) { | ||
| const e = t.defaultStyle && L.includes(t.defaultStyle) ? t.defaultStyle : "apa", n = { | ||
| ...Bt, | ||
| ...t.labels || {} | ||
| }; | ||
| return { | ||
| defaultStyle: e, | ||
| enableFootnoteSync: t.enableFootnoteSync !== !1, | ||
| debounceMs: Math.max(80, Number(t.debounceMs ?? 220)), | ||
| maxRecentCitations: Math.max(3, Math.min(30, Number(t.maxRecentCitations ?? 8))), | ||
| labels: n, | ||
| normalizeText: t.normalizeText || Pt, | ||
| generateCitationId: typeof t.generateCitationId == "function" ? t.generateCitationId : void 0 | ||
| }; | ||
| } | ||
| function Ct(t) { | ||
| return t ? t.nodeType === Node.ELEMENT_NODE ? t : t.parentElement : null; | ||
| } | ||
| function lt(t) { | ||
| return t.closest("[data-editora-editor], .rte-editor, .editora-editor, editora-editor") || t; | ||
| } | ||
| function X(t) { | ||
| return t ? (t.getAttribute("data-theme") || t.getAttribute("theme") || "").toLowerCase() === "dark" ? !0 : t.classList.contains("dark") || t.classList.contains("editora-theme-dark") || t.classList.contains("rte-theme-dark") : !1; | ||
| } | ||
| function Dt(t) { | ||
| const e = lt(t); | ||
| if (X(e)) return !0; | ||
| const n = e.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark"); | ||
| return X(n) ? !0 : X(document.documentElement) || X(document.body); | ||
| } | ||
| function tt(t, e) { | ||
| t.classList.remove("rte-citations-theme-dark"), Dt(e) && t.classList.add("rte-citations-theme-dark"); | ||
| } | ||
| function h(t, e = !0) { | ||
| if (t?.contentElement instanceof HTMLElement) return t.contentElement; | ||
| if (t?.editorElement instanceof HTMLElement) { | ||
| const o = t.editorElement; | ||
| if (o.matches(S)) return o; | ||
| const r = o.querySelector(S); | ||
| if (r instanceof HTMLElement) return r; | ||
| } | ||
| const n = window.getSelection(); | ||
| if (n && n.rangeCount > 0) { | ||
| const o = n.getRangeAt(0).startContainer, a = Ct(o)?.closest(S); | ||
| if (a) return a; | ||
| } | ||
| const i = document.activeElement; | ||
| if (i) { | ||
| if (i.matches(S)) return i; | ||
| const o = i.closest(S); | ||
| if (o) return o; | ||
| } | ||
| return p && p.isConnected ? p : (p && !p.isConnected && (p = null), e ? document.querySelector(S) : null); | ||
| } | ||
| function $(t) { | ||
| return t.getAttribute("contenteditable") === "false" || t.getAttribute("data-readonly") === "true"; | ||
| } | ||
| function j(t) { | ||
| const e = Ct(t); | ||
| return e ? !!(e.closest(W) || e.closest(G)) : !1; | ||
| } | ||
| function Ht(t, e) { | ||
| if (at += 1, e.generateCitationId) { | ||
| const n = e.generateCitationId({ editor: t, index: at }), i = F(e.normalizeText(n || "")); | ||
| if (i) return i; | ||
| } | ||
| return `cite-${Date.now().toString(36)}-${at.toString(36)}`; | ||
| } | ||
| function st(t) { | ||
| return t.map((e) => (e || "").trim()).filter(Boolean).join(" ").trim(); | ||
| } | ||
| function Ft(t, e) { | ||
| const n = t.author || "Unknown", i = t.year || "n.d."; | ||
| return e === "mla" ? `(${n} ${i})` : e === "chicago" ? `(${n} ${i})` : `(${n}, ${i})`; | ||
| } | ||
| function ut(t, e) { | ||
| const n = t.author || "Unknown", i = t.year || "n.d.", o = t.title || "Untitled", r = t.source || "", a = t.url || ""; | ||
| return st(e === "mla" ? [ | ||
| `${n}.`, | ||
| `"${o}."`, | ||
| r ? `${r},` : "", | ||
| `${i}.`, | ||
| a | ||
| ] : e === "chicago" ? [ | ||
| `${n}.`, | ||
| `${o}.`, | ||
| r ? `${r}.` : "", | ||
| `(${i}).`, | ||
| a | ||
| ] : [ | ||
| `${n}.`, | ||
| `(${i}).`, | ||
| `${o}.`, | ||
| r ? `${r}.` : "", | ||
| a | ||
| ]); | ||
| } | ||
| function R(t) { | ||
| return Array.from(t.querySelectorAll(ot)).filter( | ||
| (e) => !e.closest(W) && !e.closest(G) | ||
| ); | ||
| } | ||
| function wt(t, e) { | ||
| const n = F(e.normalizeText(t.getAttribute("data-citation-id") || "")); | ||
| if (!n) return null; | ||
| const i = e.normalizeText(t.getAttribute("data-citation-author") || ""), o = e.normalizeText(t.getAttribute("data-citation-title") || ""); | ||
| return { | ||
| id: n, | ||
| author: i || "Unknown", | ||
| year: ht(t.getAttribute("data-citation-year") || "", e.normalizeText) || void 0, | ||
| title: o || "Untitled", | ||
| source: e.normalizeText(t.getAttribute("data-citation-source") || "") || void 0, | ||
| url: xt(t.getAttribute("data-citation-url") || "", e.normalizeText) || void 0, | ||
| note: e.normalizeText(t.getAttribute("data-citation-note") || "") || void 0 | ||
| }; | ||
| } | ||
| function vt(t, e, n) { | ||
| t.classList.add("rte-citation-ref"), t.setAttribute("data-citation-id", e.id), t.setAttribute("data-citation-author", e.author || ""), t.setAttribute("data-citation-year", e.year || ""), t.setAttribute("data-citation-title", e.title || ""), t.setAttribute("data-citation-source", e.source || ""), t.setAttribute("data-citation-url", e.url || ""), t.setAttribute("data-citation-note", e.note || ""), t.setAttribute("contenteditable", "false"), t.setAttribute("tabindex", "0"), t.setAttribute("role", "doc-biblioref"), t.setAttribute("data-style", n), t.textContent = Ft(e, n); | ||
| } | ||
| function it(t, e, n) { | ||
| const i = lt(t); | ||
| Array.from( | ||
| i.querySelectorAll( | ||
| `.rte-toolbar-button[data-command="${e}"], .editora-toolbar-button[data-command="${e}"]` | ||
| ) | ||
| ).forEach((r) => { | ||
| r.classList.toggle("active", n), r.setAttribute("data-active", n ? "true" : "false"), r.setAttribute("aria-pressed", n ? "true" : "false"); | ||
| }); | ||
| } | ||
| function N(t, e) { | ||
| const n = T.get(t); | ||
| return n && L.includes(n) ? n : e?.defaultStyle || "apa"; | ||
| } | ||
| function K(t, e) { | ||
| const n = R(t), i = /* @__PURE__ */ new Map(); | ||
| return n.forEach((o) => { | ||
| const r = wt(o, e); | ||
| if (!r) return; | ||
| if (!i.has(r.id)) { | ||
| i.set(r.id, r); | ||
| return; | ||
| } | ||
| const a = i.get(r.id); | ||
| i.set(r.id, { | ||
| ...a, | ||
| author: a.author || r.author, | ||
| title: a.title || r.title, | ||
| year: a.year || r.year, | ||
| source: a.source || r.source, | ||
| url: a.url || r.url, | ||
| note: a.note || r.note | ||
| }); | ||
| }), Array.from(i.values()); | ||
| } | ||
| function _t(t, e, n) { | ||
| const i = yt(e, n); | ||
| if (!i.id || !i.author || !i.title) return; | ||
| const r = (D.get(t) || []).filter((a) => a.id !== i.id); | ||
| D.set(t, [i, ...r].slice(0, n.maxRecentCitations)); | ||
| } | ||
| function rt(t, e, n) { | ||
| const i = D.get(t) || [], o = /* @__PURE__ */ new Map(); | ||
| e.slice(Math.max(0, e.length - n.maxRecentCitations)).reverse().forEach((a) => { | ||
| a.id && o.set(a.id, a); | ||
| }), i.forEach((a) => { | ||
| !a.id || o.has(a.id) || o.set(a.id, a); | ||
| }); | ||
| const r = Array.from(o.values()).slice(0, n.maxRecentCitations); | ||
| return D.set(t, r), r; | ||
| } | ||
| function Et(t, e, n, i) { | ||
| const o = F(i.normalizeText(e || "")); | ||
| return o && rt(t, n, i).find((a) => a.id === o) || null; | ||
| } | ||
| function qt(t, e, n) { | ||
| const i = F(n.normalizeText(e || "")); | ||
| if (!i) return !1; | ||
| const o = D.get(t) || [], r = o.filter((a) => a.id !== i); | ||
| return r.length === o.length ? !1 : (D.set(t, r), !0); | ||
| } | ||
| function St(t, e, n) { | ||
| const i = document.createElement("section"); | ||
| i.className = t, i.setAttribute("data-type", e), i.setAttribute("contenteditable", "false"), i.setAttribute("aria-label", n), e === "citation-bibliography" ? i.setAttribute("role", "doc-bibliography") : e === "citation-footnotes" && i.setAttribute("role", "doc-endnotes"); | ||
| const o = document.createElement("h3"); | ||
| o.className = "rte-citation-section-title", o.textContent = n; | ||
| const r = document.createElement("ol"); | ||
| return r.className = "rte-citation-list", r.setAttribute("role", "list"), i.appendChild(o), i.appendChild(r), i; | ||
| } | ||
| function jt(t, e) { | ||
| let n = t.querySelector(W); | ||
| n || (n = St("rte-citation-bibliography", "citation-bibliography", e.labels.bibliographyTitle), t.appendChild(n)); | ||
| const i = n.querySelector(".rte-citation-section-title"); | ||
| return i && (i.textContent = e.labels.bibliographyTitle), n.setAttribute("aria-label", e.labels.bibliographyTitle), n; | ||
| } | ||
| function Kt(t, e) { | ||
| let n = t.querySelector(G); | ||
| n || (n = St("rte-citation-footnotes", "citation-footnotes", e.labels.footnotesTitle), t.appendChild(n)); | ||
| const i = n.querySelector(".rte-citation-section-title"); | ||
| return i && (i.textContent = e.labels.footnotesTitle), n.setAttribute("aria-label", e.labels.footnotesTitle), n; | ||
| } | ||
| function $t(t, e) { | ||
| t.querySelector(e)?.remove(); | ||
| } | ||
| function Ut(t, e, n, i) { | ||
| if (e.length === 0) { | ||
| $t(t, W); | ||
| return; | ||
| } | ||
| const r = jt(t, n).querySelector(".rte-citation-list"); | ||
| if (!r) return; | ||
| const a = document.createDocumentFragment(); | ||
| e.forEach((s, u) => { | ||
| const c = document.createElement("li"); | ||
| c.className = "rte-citation-item", c.id = `rte-citation-entry-${s.id}`, c.setAttribute("data-citation-id", s.id), c.setAttribute("data-citation-number", String(u + 1)), c.textContent = ut(s, i), a.appendChild(c); | ||
| }), r.innerHTML = "", r.appendChild(a); | ||
| } | ||
| function Wt(t, e, n, i) { | ||
| if (!n.enableFootnoteSync || e.length === 0) { | ||
| $t(t, G), R(t).forEach((l) => { | ||
| l.removeAttribute("data-footnote-number"), l.removeAttribute("data-footnote-target"); | ||
| }); | ||
| return; | ||
| } | ||
| const r = Kt(t, n).querySelector(".rte-citation-list"); | ||
| if (!r) return; | ||
| const a = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(); | ||
| e.forEach((l, d) => { | ||
| s.set(l.id, d + 1); | ||
| }); | ||
| const u = /* @__PURE__ */ new Map(); | ||
| R(t).forEach((l) => { | ||
| const d = l.getAttribute("data-citation-id") || ""; | ||
| if (!d || !s.has(d)) return; | ||
| const m = (u.get(d) || 0) + 1; | ||
| u.set(d, m); | ||
| const w = `rte-citation-ref-${d}-${m}`; | ||
| l.id = w; | ||
| const A = s.get(d); | ||
| l.setAttribute("data-footnote-number", String(A)), l.setAttribute("data-footnote-target", `rte-citation-note-${d}`), a.has(d) || a.set(d, w); | ||
| }); | ||
| const c = document.createDocumentFragment(); | ||
| e.forEach((l, d) => { | ||
| const m = document.createElement("li"); | ||
| m.className = "rte-citation-item rte-citation-footnote-item", m.id = `rte-citation-note-${l.id}`, m.setAttribute("data-citation-id", l.id); | ||
| const w = document.createElement("span"); | ||
| w.className = "rte-citation-footnote-number", w.textContent = `${d + 1}. `; | ||
| const A = document.createElement("span"); | ||
| A.className = "rte-citation-footnote-text"; | ||
| const It = l.note ? `${l.note}. ` : ""; | ||
| A.textContent = `${It}${ut(l, i)}`, m.appendChild(w), m.appendChild(A); | ||
| const gt = a.get(l.id); | ||
| if (gt) { | ||
| const _ = document.createElement("a"); | ||
| _.className = "rte-citation-backref", _.href = `#${gt}`, _.setAttribute("aria-label", `Back to citation ${d + 1}`), _.textContent = "Back", m.appendChild(_); | ||
| } | ||
| c.appendChild(m); | ||
| }), r.innerHTML = "", r.appendChild(c); | ||
| } | ||
| function Gt(t, e, n, i) { | ||
| const o = ut(e, n); | ||
| t.setAttribute("data-citation-number", String(i)), t.setAttribute("aria-label", `Citation ${i}: ${o}`); | ||
| } | ||
| function Vt(t, e, n) { | ||
| const i = R(t); | ||
| let o = `${e}:${n ? "1" : "0"}:${i.length}`; | ||
| return i.forEach((r) => { | ||
| o += `|${r.getAttribute("data-citation-id") || ""}`, o += `|${r.getAttribute("data-citation-author") || ""}`, o += `|${r.getAttribute("data-citation-year") || ""}`, o += `|${r.getAttribute("data-citation-title") || ""}`, o += `|${r.getAttribute("data-citation-source") || ""}`, o += `|${r.getAttribute("data-citation-url") || ""}`, o += `|${r.getAttribute("data-citation-note") || ""}`; | ||
| }), o; | ||
| } | ||
| function H(t) { | ||
| const e = v.get(t); | ||
| if (!e) return; | ||
| const n = f.get(t) || M; | ||
| if (!n) return; | ||
| const i = N(t, n), o = K(t, n), r = rt(t, o, n), a = e.querySelector(".rte-citations-status"), s = e.querySelector('[data-action="cycle-style"]'), u = e.querySelector(".rte-citations-recent-list"); | ||
| if (a) { | ||
| const c = o.length; | ||
| a.textContent = `${n.labels.summaryPrefix}: ${c} | Style: ${i.toUpperCase()} | Footnotes: ${n.enableFootnoteSync ? "On" : "Off"}`; | ||
| } | ||
| if (s && (s.textContent = `${n.labels.styleButtonPrefix}: ${i.toUpperCase()}`, s.setAttribute("aria-label", `${n.labels.styleButtonPrefix}: ${i.toUpperCase()}`)), u) { | ||
| if (r.length === 0) { | ||
| u.innerHTML = `<li class="rte-citations-empty">${g(n.labels.noCitationsText)}</li>`; | ||
| return; | ||
| } | ||
| u.innerHTML = r.map( | ||
| (c) => ` | ||
| <li class="rte-citations-recent-item"> | ||
| <div class="rte-citations-recent-row"> | ||
| <button | ||
| type="button" | ||
| class="rte-citations-recent-btn" | ||
| data-action="insert-from-recent" | ||
| data-citation-id="${g(c.id)}" | ||
| aria-label="Insert citation: ${g(c.title)}" | ||
| > | ||
| <span class="rte-citations-recent-title">${g(c.title)}</span> | ||
| <span class="rte-citations-recent-meta">${g(c.author)}${c.year ? ` (${g(c.year)})` : ""}</span> | ||
| </button> | ||
| <button | ||
| type="button" | ||
| class="rte-citations-recent-delete" | ||
| data-action="delete-by-id" | ||
| data-citation-id="${g(c.id)}" | ||
| aria-label="Delete citation: ${g(c.title)}" | ||
| >${g(n.labels.deleteRecentText)}</button> | ||
| </div> | ||
| </li> | ||
| ` | ||
| ).join(""); | ||
| } | ||
| } | ||
| function y(t, e, n = !1) { | ||
| const i = N(t, e), o = Vt(t, i, e.enableFootnoteSync); | ||
| if (!n && pt.get(t) === o) | ||
| return K(t, e); | ||
| const r = R(t), a = /* @__PURE__ */ new Map(); | ||
| r.forEach((c) => { | ||
| const l = wt(c, e); | ||
| l && (a.has(l.id) || a.set(l.id, l)); | ||
| }); | ||
| const s = Array.from(a.values()); | ||
| rt(t, s, e); | ||
| const u = /* @__PURE__ */ new Map(); | ||
| return s.forEach((c, l) => { | ||
| u.set(c.id, l + 1); | ||
| }), r.forEach((c) => { | ||
| const l = c.getAttribute("data-citation-id") || "", d = a.get(l); | ||
| if (!d) return; | ||
| vt(c, d, i); | ||
| const m = u.get(d.id) || 1; | ||
| Gt(c, d, i, Math.max(1, m)); | ||
| }), Ut(t, s, e, i), Wt(t, s, e, i), pt.set(t, o), H(t), t.dispatchEvent( | ||
| new CustomEvent("editora:citations-refreshed", { | ||
| bubbles: !0, | ||
| detail: { | ||
| citations: s, | ||
| style: i, | ||
| footnoteSync: e.enableFootnoteSync | ||
| } | ||
| }) | ||
| ), s; | ||
| } | ||
| function At(t) { | ||
| const e = Q.get(t); | ||
| typeof e == "number" && (window.clearTimeout(e), q.delete(e), Q.delete(t)); | ||
| } | ||
| function kt(t) { | ||
| const e = f.get(t) || M; | ||
| if (!e) return; | ||
| At(t); | ||
| const n = window.setTimeout(() => { | ||
| q.delete(n), Q.delete(t), y(t, e, !1); | ||
| }, e.debounceMs); | ||
| q.add(n), Q.set(t, n); | ||
| } | ||
| function Yt(t) { | ||
| const e = window.getSelection(); | ||
| if (!e) throw new Error("Selection unavailable"); | ||
| if (e.rangeCount > 0) { | ||
| const a = e.getRangeAt(0); | ||
| if (t.contains(a.commonAncestorContainer) && !j(a.commonAncestorContainer)) | ||
| return a.cloneRange(); | ||
| } | ||
| const n = document.createRange(), i = t.querySelector(W), o = t.querySelector(G), r = i || o; | ||
| return r ? (n.setStartBefore(r), n.collapse(!0), n) : (n.selectNodeContents(t), n.collapse(!1), n); | ||
| } | ||
| function dt(t) { | ||
| t.dispatchEvent(new Event("input", { bubbles: !0 })); | ||
| } | ||
| function ft(t, e) { | ||
| if (e === t.innerHTML) return; | ||
| const n = window.execEditorCommand || window.executeEditorCommand; | ||
| if (typeof n == "function") | ||
| try { | ||
| n("recordDomTransaction", t, e, t.innerHTML); | ||
| } catch { | ||
| } | ||
| } | ||
| function Tt(t, e) { | ||
| const n = window.getSelection(); | ||
| if (!n) return; | ||
| const i = document.createRange(); | ||
| if (t.nodeType === Node.TEXT_NODE) { | ||
| const o = t, r = Math.max(0, Math.min(e, o.length)); | ||
| i.setStart(o, r); | ||
| } else { | ||
| const o = t.childNodes.length, r = Math.max(0, Math.min(e, o)); | ||
| i.setStart(t, r); | ||
| } | ||
| i.collapse(!0), n.removeAllRanges(), n.addRange(i); | ||
| } | ||
| function Mt(t) { | ||
| if (t.collapsed || t.startContainer !== t.endContainer || t.endOffset !== t.startOffset + 1 || !(t.startContainer instanceof Element || t.startContainer instanceof DocumentFragment)) | ||
| return null; | ||
| const e = t.startContainer.childNodes[t.startOffset]; | ||
| return !(e instanceof HTMLElement) || !e.matches(ot) ? null : e; | ||
| } | ||
| function J(t, e, n) { | ||
| const { startContainer: i, startOffset: o } = t; | ||
| if (i.nodeType === Node.ELEMENT_NODE) { | ||
| const a = i; | ||
| if (n === "previous") { | ||
| if (o > 0) return a.childNodes[o - 1] || null; | ||
| } else if (o < a.childNodes.length) | ||
| return a.childNodes[o] || null; | ||
| } | ||
| if (i.nodeType === Node.TEXT_NODE && (n === "previous" && o < i.data.length || n === "next" && o > 0)) | ||
| return null; | ||
| let r = i; | ||
| for (; r && r !== e; ) { | ||
| const a = n === "previous" ? r.previousSibling : r.nextSibling; | ||
| if (a) return a; | ||
| r = r.parentNode; | ||
| } | ||
| return null; | ||
| } | ||
| function Lt(t, e, n) { | ||
| if (!t.collapsed) return null; | ||
| const i = (a) => a instanceof HTMLElement && a.matches(ot) ? a : null, { startContainer: o, startOffset: r } = t; | ||
| if (o.nodeType === Node.ELEMENT_NODE) { | ||
| const a = o; | ||
| return n === "Backspace" && r > 0 ? i(a.childNodes[r - 1] || null) : n === "Delete" ? i(a.childNodes[r] || null) : null; | ||
| } | ||
| if (o.nodeType === Node.TEXT_NODE) { | ||
| const a = o; | ||
| if (n === "Backspace" && r === 0) { | ||
| const s = i(a.previousSibling); | ||
| return s || i(J(t, e, "previous")); | ||
| } | ||
| if (n === "Delete" && r === a.data.length) { | ||
| const s = i(a.nextSibling); | ||
| return s || i(J(t, e, "next")); | ||
| } | ||
| } | ||
| return i(n === "Backspace" ? J(t, e, "previous") : J(t, e, "next")); | ||
| } | ||
| function P(t, e, n) { | ||
| const i = t.closest(S); | ||
| if (!i || j(t)) return !1; | ||
| const o = t.parentNode; | ||
| if (!o) return !1; | ||
| const r = i.innerHTML, a = Array.from(o.childNodes).indexOf(t); | ||
| if (a < 0) return !1; | ||
| const s = t.nextSibling; | ||
| return s instanceof Text && (s.data === " " ? s.remove() : s.data.startsWith(" ") && (s.data = s.data.slice(1))), t.remove(), Tt(o, a), y(i, n, !0), ft(i, r), dt(i), e === "Delete" && i.focus({ preventScroll: !0 }), !0; | ||
| } | ||
| function Xt(t, e, n) { | ||
| if (t.key !== "Backspace" && t.key !== "Delete") return !1; | ||
| const i = t.key, o = t.target; | ||
| if (o?.matches(ot) && e.contains(o) && !j(o)) | ||
| return t.preventDefault(), t.stopPropagation(), P(o, i, n); | ||
| const r = window.getSelection(); | ||
| if (!r || r.rangeCount === 0) return !1; | ||
| const a = r.getRangeAt(0); | ||
| if (!e.contains(a.commonAncestorContainer) || j(a.commonAncestorContainer)) return !1; | ||
| const s = Mt(a); | ||
| if (s) | ||
| return t.preventDefault(), t.stopPropagation(), P(s, i, n); | ||
| const u = Lt(a, e, i); | ||
| return u ? (t.preventDefault(), t.stopPropagation(), P(u, i, n)) : !1; | ||
| } | ||
| function Rt(t, e, n) { | ||
| const i = F(n.normalizeText(e || "")); | ||
| if (!i) return !1; | ||
| const o = R(t).filter((a) => a.getAttribute("data-citation-id") === i); | ||
| if (o.length === 0) return !1; | ||
| if (o.length === 1) | ||
| return P(o[0], "Delete", n); | ||
| const r = t.innerHTML; | ||
| return o.forEach((a) => { | ||
| const s = a.nextSibling; | ||
| s instanceof Text && (s.data === " " ? s.remove() : s.data.startsWith(" ") && (s.data = s.data.slice(1))), a.remove(); | ||
| }), Tt(t, t.childNodes.length), y(t, n, !0), ft(t, r), dt(t), t.focus({ preventScroll: !0 }), !0; | ||
| } | ||
| function Jt(t, e) { | ||
| const n = window.getSelection(); | ||
| if (!n || n.rangeCount === 0) return !1; | ||
| const i = n.getRangeAt(0); | ||
| if (!t.contains(i.commonAncestorContainer) || j(i.commonAncestorContainer)) return !1; | ||
| const o = Mt(i); | ||
| if (o) | ||
| return P(o, "Delete", e); | ||
| const r = Lt(i, t, "Backspace"); | ||
| return r ? P(r, "Backspace", e) : !1; | ||
| } | ||
| function et(t, e, n) { | ||
| const i = yt(e, n); | ||
| if (!i.author || !i.title) return !1; | ||
| i.id || (i.id = Ht(t, n)); | ||
| const o = t.innerHTML; | ||
| let r; | ||
| try { | ||
| r = Yt(t); | ||
| } catch { | ||
| return !1; | ||
| } | ||
| const a = window.getSelection(); | ||
| if (!a) return !1; | ||
| r.collapsed || r.deleteContents(); | ||
| const s = document.createElement("span"); | ||
| vt(s, i, N(t, n)); | ||
| try { | ||
| r.insertNode(s); | ||
| } catch { | ||
| return !1; | ||
| } | ||
| const u = document.createTextNode(" "); | ||
| s.nextSibling ? s.parentNode?.insertBefore(u, s.nextSibling) : s.parentNode?.appendChild(u); | ||
| const c = document.createRange(); | ||
| if (u.parentNode) { | ||
| const l = Array.from(u.parentNode.childNodes).indexOf(u) + 1; | ||
| c.setStart(u.parentNode, Math.max(0, l)); | ||
| } else | ||
| c.setStartAfter(s); | ||
| return c.collapse(!0), a.removeAllRanges(), a.addRange(c), _t(t, i, n), y(t, n, !0), ft(t, o), dt(t), !0; | ||
| } | ||
| function Zt(t, e) { | ||
| if (!e) return !1; | ||
| const n = R(t).find((r) => r.getAttribute("data-citation-id") === e) || null; | ||
| if (!n) return !1; | ||
| n.scrollIntoView({ behavior: "smooth", block: "center", inline: "nearest" }), n.focus({ preventScroll: !0 }); | ||
| const i = window.getSelection(); | ||
| if (!i) return !0; | ||
| const o = document.createRange(); | ||
| return o.selectNode(n), i.removeAllRanges(), i.addRange(o), !0; | ||
| } | ||
| function nt(t) { | ||
| return V.get(t) === !0; | ||
| } | ||
| function U(t, e = !1) { | ||
| const n = v.get(t); | ||
| n && (n.classList.remove("show"), V.set(t, !1), it(t, "toggleCitationsPanel", !1), e && t.focus({ preventScroll: !0 })); | ||
| } | ||
| function Qt(t) { | ||
| v.forEach((e, n) => { | ||
| n !== t && U(n, !1); | ||
| }); | ||
| } | ||
| function ct(t, e) { | ||
| if (!e.classList.contains("show")) return; | ||
| const i = lt(t).getBoundingClientRect(), o = Math.min(window.innerWidth - 20, 380), r = Math.max(10, window.innerWidth - o - 10), a = Math.min(Math.max(10, i.right - o), r), s = Math.max(10, Math.min(window.innerHeight - 10 - 260, i.top + 10)); | ||
| e.style.width = `${o}px`, e.style.left = `${a}px`, e.style.top = `${s}px`, e.style.maxHeight = `${Math.max(260, window.innerHeight - 24)}px`; | ||
| } | ||
| function C(t, e) { | ||
| return t.querySelector(`[data-field="${e}"]`); | ||
| } | ||
| function te(t) { | ||
| const e = C(t, "author")?.value || "", n = C(t, "year")?.value || "", i = C(t, "title")?.value || "", o = C(t, "source")?.value || "", r = C(t, "url")?.value || "", a = C(t, "note")?.value || ""; | ||
| return { | ||
| author: e, | ||
| year: n, | ||
| title: i, | ||
| source: o, | ||
| url: r, | ||
| note: a | ||
| }; | ||
| } | ||
| function E(t, e) { | ||
| const n = t.querySelector(".rte-citations-live"); | ||
| n && (n.textContent = e); | ||
| } | ||
| function ee(t, e, n) { | ||
| const i = C(e, "style"); | ||
| i && (i.value = N(t, n)); | ||
| } | ||
| function Nt(t, e, n) { | ||
| const i = L.includes(e) ? e : n.defaultStyle; | ||
| return T.set(t, i), y(t, n, !0), i; | ||
| } | ||
| function bt(t, e) { | ||
| const n = N(t, e), i = L.indexOf(n), o = L[(i + 1) % L.length]; | ||
| return T.set(t, o), y(t, e, !0), o; | ||
| } | ||
| function ne(t) { | ||
| const e = v.get(t); | ||
| if (e) return e; | ||
| const n = f.get(t) || M || Z(), i = `rte-citations-panel-${Ot++}`, o = document.createElement("section"); | ||
| o.className = b, o.id = i, o.setAttribute("role", "dialog"), o.setAttribute("aria-modal", "false"), o.setAttribute("aria-label", n.labels.panelAriaLabel), o.setAttribute("tabindex", "-1"), o.innerHTML = ` | ||
| <header class="rte-citations-header"> | ||
| <h2 class="rte-citations-title">${g(n.labels.panelTitle)}</h2> | ||
| <button type="button" class="rte-citations-icon-btn" data-action="close" aria-label="${g(n.labels.closeText)}">✕</button> | ||
| </header> | ||
| <div class="rte-citations-body"> | ||
| <p class="rte-citations-status" aria-live="polite"></p> | ||
| <div class="rte-citations-grid"> | ||
| <label class="rte-citations-label"> | ||
| ${g(n.labels.styleLabel)} | ||
| <select data-field="style" class="rte-citations-field"> | ||
| <option value="apa">APA</option> | ||
| <option value="mla">MLA</option> | ||
| <option value="chicago">Chicago</option> | ||
| </select> | ||
| </label> | ||
| <label class="rte-citations-label"> | ||
| ${g(n.labels.authorLabel)} | ||
| <input type="text" data-field="author" class="rte-citations-field" autocomplete="off" /> | ||
| </label> | ||
| <label class="rte-citations-label"> | ||
| ${g(n.labels.yearLabel)} | ||
| <input type="text" data-field="year" class="rte-citations-field" inputmode="numeric" autocomplete="off" /> | ||
| </label> | ||
| <label class="rte-citations-label"> | ||
| ${g(n.labels.titleLabel)} | ||
| <input type="text" data-field="title" class="rte-citations-field" autocomplete="off" /> | ||
| </label> | ||
| <label class="rte-citations-label"> | ||
| ${g(n.labels.sourceLabel)} | ||
| <input type="text" data-field="source" class="rte-citations-field" autocomplete="off" /> | ||
| </label> | ||
| <label class="rte-citations-label"> | ||
| ${g(n.labels.urlLabel)} | ||
| <input type="url" data-field="url" class="rte-citations-field" autocomplete="off" /> | ||
| </label> | ||
| <label class="rte-citations-label rte-citations-label-note"> | ||
| ${g(n.labels.noteLabel)} | ||
| <textarea data-field="note" class="rte-citations-field" rows="2"></textarea> | ||
| </label> | ||
| </div> | ||
| <div class="rte-citations-controls" role="toolbar" aria-label="Citation actions"> | ||
| <button type="button" class="rte-citations-btn rte-citations-btn-primary" data-action="insert">${g(n.labels.insertText)}</button> | ||
| <button type="button" class="rte-citations-btn" data-action="refresh">${g(n.labels.refreshText)}</button> | ||
| <button type="button" class="rte-citations-btn" data-action="cycle-style"></button> | ||
| </div> | ||
| <section class="rte-citations-recent" aria-label="${g(n.labels.recentHeading)}"> | ||
| <h3 class="rte-citations-recent-heading">${g(n.labels.recentHeading)}</h3> | ||
| <ul class="rte-citations-recent-list" role="list"></ul> | ||
| </section> | ||
| <p class="rte-citations-shortcut">Shortcut: Ctrl/Cmd + Alt + Shift + C</p> | ||
| <span class="rte-citations-live" aria-live="polite"></span> | ||
| </div> | ||
| `, o.addEventListener("click", (a) => { | ||
| const s = a.target; | ||
| if (!s) return; | ||
| const u = s.closest("[data-action]"); | ||
| if (!u) return; | ||
| const c = u.getAttribute("data-action") || "", l = f.get(t) || M || n; | ||
| if (f.set(t, l), c === "close") { | ||
| U(t, !0); | ||
| return; | ||
| } | ||
| if (c === "insert") { | ||
| if ($(t)) return; | ||
| const d = te(o); | ||
| if (!l.normalizeText(d.author) || !l.normalizeText(d.title)) { | ||
| E(o, l.labels.invalidMessage); | ||
| return; | ||
| } | ||
| if (!et(t, d, l)) { | ||
| E(o, l.labels.invalidMessage); | ||
| return; | ||
| } | ||
| E(o, "Citation inserted."); | ||
| const w = C(o, "title"), A = C(o, "note"); | ||
| w && (w.value = ""), A && (A.value = ""); | ||
| return; | ||
| } | ||
| if (c === "refresh") { | ||
| const d = y(t, l, !0); | ||
| E(o, `Refreshed ${d.length} citation${d.length === 1 ? "" : "s"}.`); | ||
| return; | ||
| } | ||
| if (c === "cycle-style") { | ||
| const d = bt(t, l); | ||
| ee(t, o, l), E(o, `Style changed to ${d.toUpperCase()}.`); | ||
| return; | ||
| } | ||
| if (c === "insert-from-recent") { | ||
| if ($(t)) return; | ||
| const d = u.getAttribute("data-citation-id") || "", m = Et(t, d, K(t, l), l); | ||
| if (!m) return; | ||
| et(t, m, l), E(o, `Inserted citation: ${m.title}.`); | ||
| return; | ||
| } | ||
| if (c === "delete-by-id") { | ||
| if ($(t)) return; | ||
| const d = u.getAttribute("data-citation-id") || ""; | ||
| if (Rt(t, d, l)) { | ||
| E(o, "Citation deleted."); | ||
| return; | ||
| } | ||
| qt(t, d, l) && (H(t), E(o, "Removed from recent citations.")); | ||
| } | ||
| }), o.addEventListener("keydown", (a) => { | ||
| if (a.key === "Escape") { | ||
| a.preventDefault(), U(t, !0); | ||
| return; | ||
| } | ||
| const s = a.target; | ||
| if (!s || !s.matches(".rte-citations-recent-btn") || a.key !== "ArrowDown" && a.key !== "ArrowUp") return; | ||
| const u = Array.from(o.querySelectorAll(".rte-citations-recent-btn")); | ||
| if (u.length === 0) return; | ||
| const c = u.indexOf(s); | ||
| if (c < 0) return; | ||
| a.preventDefault(); | ||
| const l = a.key === "ArrowDown" ? 1 : -1, d = (c + l + u.length) % u.length; | ||
| u[d].focus(); | ||
| }); | ||
| const r = C(o, "style"); | ||
| return r?.addEventListener("change", () => { | ||
| const a = f.get(t) || M || n, s = r.value; | ||
| Nt(t, s, a), E(o, `Style changed to ${s.toUpperCase()}.`); | ||
| }), tt(o, t), document.body.appendChild(o), v.set(t, o), V.set(t, !1), H(t), o; | ||
| } | ||
| function z(t) { | ||
| const e = ne(t); | ||
| Qt(t), e.classList.add("show"), V.set(t, !0), it(t, "toggleCitationsPanel", !0), tt(e, t), ct(t, e), H(t), C(e, "author")?.focus(); | ||
| } | ||
| function zt(t, e) { | ||
| const n = nt(t); | ||
| return (typeof e == "boolean" ? e : !n) ? z(t) : U(t, !1), !0; | ||
| } | ||
| function oe(t) { | ||
| const e = t.key.toLowerCase(); | ||
| return (t.metaKey || t.ctrlKey) && t.altKey && t.shiftKey && e === "c"; | ||
| } | ||
| function ie(t) { | ||
| const e = t.key.toLowerCase(); | ||
| return (t.metaKey || t.ctrlKey) && t.altKey && t.shiftKey && e === "b"; | ||
| } | ||
| function re(t) { | ||
| const e = t.key.toLowerCase(); | ||
| return (t.metaKey || t.ctrlKey) && t.altKey && t.shiftKey && e === "j"; | ||
| } | ||
| function ae(t) { | ||
| M = t, I || (I = (e) => { | ||
| const i = e.target?.closest(S); | ||
| if (!i) return; | ||
| p = i, f.has(i) || f.set(i, t), T.has(i) || T.set(i, t.defaultStyle); | ||
| const o = v.get(i); | ||
| o && (tt(o, i), ct(i, o)), it(i, "toggleCitationsPanel", nt(i)); | ||
| }, document.addEventListener("focusin", I, !0)), B || (B = (e) => { | ||
| const i = e.target?.closest(S); | ||
| i && (p = i, kt(i)); | ||
| }, document.addEventListener("input", B, !0)), O || (O = (e) => { | ||
| if (e.defaultPrevented) return; | ||
| const i = !!e.target?.closest(`.${b} input, .${b} textarea, .${b} select`), o = h(void 0, !1); | ||
| if (!o || $(o)) return; | ||
| const r = f.get(o) || M || t; | ||
| if (f.set(o, r), p = o, e.key === "Escape" && nt(o)) { | ||
| e.preventDefault(), U(o, !0); | ||
| return; | ||
| } | ||
| if (!i && !Xt(e, o, r)) { | ||
| if (oe(e)) { | ||
| e.preventDefault(), e.stopPropagation(), zt(o); | ||
| return; | ||
| } | ||
| if (ie(e)) { | ||
| e.preventDefault(), e.stopPropagation(), y(o, r, !0), z(o); | ||
| return; | ||
| } | ||
| re(e) && (e.preventDefault(), e.stopPropagation(), bt(o, r)); | ||
| } | ||
| }, document.addEventListener("keydown", O, !0)), k || (k = () => { | ||
| v.forEach((e, n) => { | ||
| if (!n.isConnected || !e.isConnected) { | ||
| At(n), e.remove(), v.delete(n), V.delete(n); | ||
| return; | ||
| } | ||
| tt(e, n), ct(n, e); | ||
| }); | ||
| }, window.addEventListener("scroll", k, !0), window.addEventListener("resize", k)); | ||
| } | ||
| function se() { | ||
| I && (document.removeEventListener("focusin", I, !0), I = null), B && (document.removeEventListener("input", B, !0), B = null), O && (document.removeEventListener("keydown", O, !0), O = null), k && (window.removeEventListener("scroll", k, !0), window.removeEventListener("resize", k), k = null), v.forEach((t) => t.remove()), v.clear(), M = null, p = null; | ||
| } | ||
| function ce() { | ||
| if (typeof document > "u" || document.getElementById(mt)) return; | ||
| const t = document.createElement("style"); | ||
| t.id = mt, t.textContent = ` | ||
| .rte-toolbar-group-items.citations, | ||
| .editora-toolbar-group-items.citations { | ||
| display: flex; | ||
| border: 1px solid #ccc; | ||
| border-radius: 3px; | ||
| background: #fff; | ||
| } | ||
| .rte-toolbar-group-items.citations .rte-toolbar-button, | ||
| .editora-toolbar-group-items.citations .editora-toolbar-button { | ||
| border: none; | ||
| border-radius: 0; | ||
| border-right: 1px solid #ccc; | ||
| } | ||
| .rte-toolbar-group-items.citations .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.citations .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| .rte-toolbar-button[data-command="toggleCitationsPanel"].active, | ||
| .editora-toolbar-button[data-command="toggleCitationsPanel"].active { | ||
| background: #ccc; | ||
| } | ||
| ${x} .rte-toolbar-group-items.citations, | ||
| ${x} .editora-toolbar-group-items.citations, | ||
| .${b}.rte-citations-theme-dark { | ||
| border-color: #566275; | ||
| } | ||
| ${x} .rte-toolbar-group-items.citations .rte-toolbar-button[data-command="refreshCitations"] svg, | ||
| ${x} .editora-toolbar-group-items.citations .editora-toolbar-button[data-command="refreshCitations"] svg | ||
| { | ||
| fill: none; | ||
| } | ||
| ${x} .rte-toolbar-group-items.citations .rte-toolbar-button, | ||
| ${x} .editora-toolbar-group-items.citations .editora-toolbar-button | ||
| { | ||
| border-color: #566275; | ||
| } | ||
| ${x} .rte-toolbar-button[data-command="toggleCitationsPanel"].active, | ||
| ${x} .editora-toolbar-button[data-command="toggleCitationsPanel"].active { | ||
| background: linear-gradient(180deg, #5eaaf6 0%, #4a95de 100%); | ||
| } | ||
| .${b} { | ||
| position: fixed; | ||
| z-index: 1500; | ||
| right: 16px; | ||
| top: 16px; | ||
| width: min(380px, calc(100vw - 20px)); | ||
| max-height: calc(100vh - 24px); | ||
| display: none; | ||
| flex-direction: column; | ||
| border-radius: 12px; | ||
| border: 1px solid #d1d5db; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| box-shadow: 0 18px 38px rgba(15, 23, 42, 0.16); | ||
| overflow: hidden; | ||
| } | ||
| .${b}.show { | ||
| display: flex; | ||
| } | ||
| .${b}.rte-citations-theme-dark { | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| border-color: #334155; | ||
| box-shadow: 0 20px 40px rgba(2, 6, 23, 0.5); | ||
| } | ||
| .rte-citations-header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| padding: 10px 12px; | ||
| border-bottom: 1px solid #e2e8f0; | ||
| background: #f8fafc; | ||
| } | ||
| .${b}.rte-citations-theme-dark .rte-citations-header { | ||
| border-bottom-color: #334155; | ||
| background: #111827; | ||
| } | ||
| .rte-citations-title { | ||
| margin: 0; | ||
| font-size: 14px; | ||
| font-weight: 700; | ||
| } | ||
| .rte-citations-icon-btn { | ||
| border: 1px solid #cbd5e1; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| border-radius: 6px; | ||
| cursor: pointer; | ||
| min-width: 34px; | ||
| min-height: 34px; | ||
| width: 34px; | ||
| height: 34px; | ||
| padding: 0; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| font-weight: 600; | ||
| } | ||
| .rte-citations-icon-btn:hover, | ||
| .rte-citations-icon-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .${b}.rte-citations-theme-dark .rte-citations-icon-btn { | ||
| background: #0f172a; | ||
| border-color: #475569; | ||
| color: #e2e8f0; | ||
| } | ||
| .${b}.rte-citations-theme-dark .rte-citations-icon-btn:hover, | ||
| .${b}.rte-citations-theme-dark .rte-citations-icon-btn:focus-visible { | ||
| border-color: #60a5fa; | ||
| box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.24); | ||
| } | ||
| .rte-citations-body { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 10px; | ||
| padding: 12px; | ||
| overflow: auto; | ||
| } | ||
| .rte-citations-status { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| color: #475569; | ||
| } | ||
| .${b}.rte-citations-theme-dark .rte-citations-status { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-citations-grid { | ||
| display: grid; | ||
| grid-template-columns: 1fr 1fr; | ||
| gap: 8px; | ||
| } | ||
| .rte-citations-label { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 4px; | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| color: inherit; | ||
| } | ||
| .rte-citations-label-note { | ||
| grid-column: 1 / -1; | ||
| } | ||
| .rte-citations-field { | ||
| width: 100%; | ||
| box-sizing: border-box; | ||
| min-height: 30px; | ||
| border-radius: 8px; | ||
| border: 1px solid #cbd5e1; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| font-size: 13px; | ||
| padding: 6px 8px; | ||
| } | ||
| .rte-citations-field:focus-visible { | ||
| outline: none; | ||
| border-color: #1d4ed8; | ||
| box-shadow: 0 0 0 2px rgba(29, 78, 216, 0.2); | ||
| } | ||
| .${b}.rte-citations-theme-dark .rte-citations-field { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #e2e8f0; | ||
| } | ||
| .rte-citations-controls { | ||
| display: flex; | ||
| flex-wrap: wrap; | ||
| gap: 8px; | ||
| } | ||
| .rte-citations-btn { | ||
| border: 1px solid #cbd5e1; | ||
| background: #f8fafc; | ||
| color: inherit; | ||
| border-radius: 8px; | ||
| padding: 6px 10px; | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| cursor: pointer; | ||
| } | ||
| .rte-citations-btn:hover, | ||
| .rte-citations-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #1d4ed8; | ||
| box-shadow: 0 0 0 2px rgba(29, 78, 216, 0.2); | ||
| } | ||
| .rte-citations-btn-primary { | ||
| background: #1d4ed8; | ||
| border-color: #1d4ed8; | ||
| color: #ffffff; | ||
| } | ||
| .rte-citations-btn-primary:hover, | ||
| .rte-citations-btn-primary:focus-visible { | ||
| background: #1e40af; | ||
| border-color: #1e40af; | ||
| } | ||
| .${b}.rte-citations-theme-dark .rte-citations-btn { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #e2e8f0; | ||
| } | ||
| .${b}.rte-citations-theme-dark .rte-citations-btn-primary { | ||
| border-color: #2563eb; | ||
| background: #2563eb; | ||
| color: #ffffff; | ||
| } | ||
| .rte-citations-recent { | ||
| border: 1px solid #e2e8f0; | ||
| border-radius: 10px; | ||
| padding: 8px; | ||
| } | ||
| .${b}.rte-citations-theme-dark .rte-citations-recent { | ||
| border-color: #334155; | ||
| } | ||
| .rte-citations-recent-heading { | ||
| margin: 0 0 8px; | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| } | ||
| .rte-citations-recent-list { | ||
| margin: 0; | ||
| padding: 0; | ||
| list-style: none; | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 6px; | ||
| max-height: 170px; | ||
| overflow: auto; | ||
| } | ||
| .rte-citations-recent-btn { | ||
| width: 100%; | ||
| text-align: left; | ||
| border: 1px solid #cbd5e1; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| border-radius: 8px; | ||
| padding: 7px; | ||
| cursor: pointer; | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 2px; | ||
| } | ||
| .rte-citations-recent-row { | ||
| display: flex; | ||
| gap: 6px; | ||
| align-items: stretch; | ||
| } | ||
| .rte-citations-recent-delete { | ||
| flex: 0 0 auto; | ||
| border: 1px solid #fecaca; | ||
| background: #fff1f2; | ||
| color: #b91c1c; | ||
| border-radius: 8px; | ||
| padding: 0 8px; | ||
| font-size: 11px; | ||
| font-weight: 700; | ||
| cursor: pointer; | ||
| min-height: 34px; | ||
| } | ||
| .rte-citations-recent-delete:hover, | ||
| .rte-citations-recent-delete:focus-visible { | ||
| outline: none; | ||
| border-color: #f87171; | ||
| box-shadow: 0 0 0 2px rgba(248, 113, 113, 0.2); | ||
| } | ||
| .rte-citations-recent-btn:focus-visible, | ||
| .rte-citations-recent-btn:hover { | ||
| outline: none; | ||
| border-color: #1d4ed8; | ||
| box-shadow: 0 0 0 2px rgba(29, 78, 216, 0.18); | ||
| } | ||
| .${b}.rte-citations-theme-dark .rte-citations-recent-btn { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #e2e8f0; | ||
| } | ||
| .${b}.rte-citations-theme-dark .rte-citations-recent-delete { | ||
| border-color: #7f1d1d; | ||
| background: #2b1218; | ||
| color: #fca5a5; | ||
| } | ||
| .rte-citations-recent-title { | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| line-height: 1.3; | ||
| } | ||
| .rte-citations-recent-meta { | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| line-height: 1.3; | ||
| } | ||
| .${b}.rte-citations-theme-dark .rte-citations-recent-meta { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-citations-empty { | ||
| border: 1px dashed #cbd5e1; | ||
| border-radius: 8px; | ||
| padding: 8px; | ||
| font-size: 12px; | ||
| color: #64748b; | ||
| } | ||
| .${b}.rte-citations-theme-dark .rte-citations-empty { | ||
| border-color: #334155; | ||
| color: #94a3b8; | ||
| } | ||
| .rte-citations-shortcut { | ||
| margin: 0; | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| } | ||
| .${b}.rte-citations-theme-dark .rte-citations-shortcut { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-citations-live { | ||
| position: absolute; | ||
| width: 1px; | ||
| height: 1px; | ||
| margin: -1px; | ||
| padding: 0; | ||
| overflow: hidden; | ||
| clip: rect(0 0 0 0); | ||
| border: 0; | ||
| } | ||
| .rte-citation-ref { | ||
| display: inline-flex; | ||
| align-items: center; | ||
| border-radius: 6px; | ||
| border: 1px solid rgba(29, 78, 216, 0.24); | ||
| background: rgba(29, 78, 216, 0.08); | ||
| color: #1e3a8a; | ||
| padding: 0 4px; | ||
| margin: 0 1px; | ||
| font-size: 0.92em; | ||
| line-height: 1.35; | ||
| white-space: nowrap; | ||
| cursor: pointer; | ||
| user-select: all; | ||
| } | ||
| .rte-citation-ref:focus, | ||
| .rte-citation-ref:focus-visible { | ||
| outline: none; | ||
| border-color: #1d4ed8; | ||
| box-shadow: 0 0 0 2px rgba(29, 78, 216, 0.22); | ||
| } | ||
| .${x} .rte-citation-ref { | ||
| border-color: rgba(96, 165, 250, 0.45); | ||
| background: rgba(37, 99, 235, 0.22); | ||
| color: #bfdbfe; | ||
| } | ||
| .rte-citation-bibliography, | ||
| .rte-citation-footnotes { | ||
| margin-top: 16px; | ||
| border-top: 1px solid #d1d5db; | ||
| padding-top: 10px; | ||
| } | ||
| .${x} .rte-citation-bibliography, | ||
| .${x} .rte-citation-footnotes { | ||
| border-top-color: #475569; | ||
| } | ||
| .rte-citation-section-title { | ||
| margin: 0 0 8px; | ||
| font-size: 1em; | ||
| font-weight: 700; | ||
| } | ||
| .rte-citation-list { | ||
| margin: 0; | ||
| padding-left: 22px; | ||
| } | ||
| .rte-citation-item { | ||
| margin: 0 0 8px; | ||
| line-height: 1.45; | ||
| } | ||
| .rte-citation-backref { | ||
| margin-left: 8px; | ||
| color: #1d4ed8; | ||
| text-decoration: none; | ||
| font-size: 0.9em; | ||
| } | ||
| .rte-citation-backref:hover, | ||
| .rte-citation-backref:focus-visible { | ||
| text-decoration: underline; | ||
| outline: none; | ||
| } | ||
| .${x} .rte-citation-backref { | ||
| color: #93c5fd; | ||
| } | ||
| @media (max-width: 768px) { | ||
| .${b} { | ||
| left: 10px !important; | ||
| right: 10px; | ||
| top: 10px !important; | ||
| width: auto !important; | ||
| max-height: calc(100vh - 20px); | ||
| } | ||
| .rte-citations-grid { | ||
| grid-template-columns: 1fr; | ||
| } | ||
| .rte-citations-recent-list { | ||
| max-height: 34vh; | ||
| } | ||
| } | ||
| `, document.head.appendChild(t); | ||
| } | ||
| const le = (t = {}) => { | ||
| const e = Z(t); | ||
| return ce(), { | ||
| name: "citations", | ||
| toolbar: [ | ||
| { | ||
| id: "citationsGroup", | ||
| label: "Citations", | ||
| type: "group", | ||
| command: "citations", | ||
| items: [ | ||
| { | ||
| id: "citations", | ||
| label: "Citations", | ||
| command: "toggleCitationsPanel", | ||
| shortcut: "Mod-Alt-Shift-c", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M6 5h12M6 9h12M6 13h8M6 17h10" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/><path d="M17 14.5a2.5 2.5 0 0 1 2.5 2.5v2H15v-2a2 2 0 0 1 2-2Z" stroke="currentColor" stroke-width="1.5"/></svg>' | ||
| }, | ||
| { | ||
| id: "citationsRefresh", | ||
| label: "Refresh Citations", | ||
| command: "refreshCitations", | ||
| shortcut: "Mod-Alt-Shift-b", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M20 12a8 8 0 1 1-2.34-5.66" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/><path d="M20 4v6h-6" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg>' | ||
| }, | ||
| { | ||
| id: "citationsStyle", | ||
| label: "Cycle Citation Style", | ||
| command: "cycleCitationStyle", | ||
| shortcut: "Mod-Alt-Shift-j", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M5 6h14M5 10h8M5 14h14M5 18h10" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/><circle cx="18" cy="10" r="2" stroke="currentColor" stroke-width="1.6"/></svg>' | ||
| } | ||
| ] | ||
| } | ||
| ], | ||
| commands: { | ||
| citations: (n, i) => { | ||
| const o = h(i); | ||
| if (!o || $(o)) return !1; | ||
| const r = f.get(o) || e; | ||
| return f.set(o, r), T.set(o, N(o, r)), p = o, z(o), y(o, r, !1), !0; | ||
| }, | ||
| toggleCitationsPanel: (n, i) => { | ||
| const o = h(i); | ||
| if (!o || $(o)) return !1; | ||
| const r = f.get(o) || e; | ||
| f.set(o, r), p = o; | ||
| const a = zt(o, typeof n == "boolean" ? n : void 0); | ||
| return nt(o) && y(o, r, !1), a; | ||
| }, | ||
| insertCitation: (n, i) => { | ||
| const o = h(i); | ||
| if (!o || $(o) || !n || typeof n != "object") return !1; | ||
| const r = f.get(o) || e; | ||
| f.set(o, r), p = o; | ||
| const a = et(o, n, r); | ||
| return a && z(o), a; | ||
| }, | ||
| refreshCitations: (n, i) => { | ||
| const o = h(i); | ||
| if (!o) return !1; | ||
| const r = f.get(o) || e; | ||
| return f.set(o, r), p = o, y(o, r, !0), z(o), !0; | ||
| }, | ||
| setCitationStyle: (n, i) => { | ||
| const o = h(i); | ||
| if (!o || !n) return !1; | ||
| const r = f.get(o) || e; | ||
| return f.set(o, r), p = o, Nt(o, n, r), !0; | ||
| }, | ||
| cycleCitationStyle: (n, i) => { | ||
| const o = h(i); | ||
| if (!o) return !1; | ||
| const r = f.get(o) || e; | ||
| return f.set(o, r), p = o, bt(o, r), H(o), !0; | ||
| }, | ||
| getCitationRecords: (n, i) => { | ||
| const o = h(i); | ||
| if (!o) return !1; | ||
| const r = f.get(o) || e, a = K(o, r); | ||
| if (typeof n == "function") | ||
| try { | ||
| n(a); | ||
| } catch { | ||
| } | ||
| return o.__citationRecords = a, o.dispatchEvent( | ||
| new CustomEvent("editora:citations-data", { | ||
| bubbles: !0, | ||
| detail: { | ||
| records: a, | ||
| style: N(o, r) | ||
| } | ||
| }) | ||
| ), !0; | ||
| }, | ||
| setCitationsOptions: (n, i) => { | ||
| const o = h(i); | ||
| if (!o || !n || typeof n != "object") return !1; | ||
| const r = f.get(o) || e, a = Z({ | ||
| ...r, | ||
| ...n, | ||
| labels: { | ||
| ...r.labels, | ||
| ...n.labels || {} | ||
| }, | ||
| normalizeText: n.normalizeText || r.normalizeText, | ||
| generateCitationId: n.generateCitationId || r.generateCitationId | ||
| }); | ||
| return f.set(o, a), n.defaultStyle && L.includes(n.defaultStyle) && T.set(o, n.defaultStyle), y(o, a, !0), H(o), !0; | ||
| }, | ||
| locateCitation: (n, i) => { | ||
| const o = h(i); | ||
| return !o || typeof n != "string" ? !1 : Zt(o, n); | ||
| }, | ||
| deleteCitation: (n, i) => { | ||
| const o = h(i); | ||
| if (!o || $(o)) return !1; | ||
| const r = f.get(o) || e; | ||
| return f.set(o, r), typeof n == "string" && n.trim() ? Rt(o, n, r) : Jt(o, r); | ||
| }, | ||
| insertRecentCitation: (n, i) => { | ||
| const o = h(i); | ||
| if (!o || $(o)) return !1; | ||
| const r = f.get(o) || e; | ||
| f.set(o, r); | ||
| const a = K(o, r), s = rt(o, a, r); | ||
| if (s.length === 0) return !1; | ||
| const u = typeof n == "string" && n.trim() ? Et(o, n, a, r) : s[0]; | ||
| if (!u) return !1; | ||
| const c = et(o, u, r); | ||
| return c && z(o), c; | ||
| } | ||
| }, | ||
| keymap: { | ||
| "Mod-Alt-Shift-c": "toggleCitationsPanel", | ||
| "Mod-Alt-Shift-C": "toggleCitationsPanel", | ||
| "Mod-Alt-Shift-b": "refreshCitations", | ||
| "Mod-Alt-Shift-B": "refreshCitations", | ||
| "Mod-Alt-Shift-j": "cycleCitationStyle", | ||
| "Mod-Alt-Shift-J": "cycleCitationStyle" | ||
| }, | ||
| init: function(i) { | ||
| Y += 1; | ||
| const o = this && typeof this.__pluginConfig == "object" ? Z({ ...e, ...this.__pluginConfig }) : e; | ||
| ae(o); | ||
| const r = h( | ||
| i && i.editorElement ? { editorElement: i.editorElement } : void 0, | ||
| !1 | ||
| ); | ||
| r && (p = r, f.set(r, o), T.set(r, o.defaultStyle), it(r, "toggleCitationsPanel", !1), kt(r)); | ||
| }, | ||
| destroy: () => { | ||
| Y = Math.max(0, Y - 1), !(Y > 0) && (q.forEach((n) => { | ||
| window.clearTimeout(n); | ||
| }), q.clear(), se()); | ||
| } | ||
| }; | ||
| }; | ||
| export { | ||
| le as CitationsPlugin | ||
| }; |
| "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const L=".rte-content, .editora-content",H='.rte-conditional-block[data-conditional-content="true"]',b=':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)',f=':is([data-theme="acme"], .editora-theme-acme, .rte-theme-acme)',p=":is(.rte-content.rte-conditional-theme-dark, .editora-content.rte-conditional-theme-dark)",h=":is(.rte-content.rte-conditional-theme-acme, .editora-content.rte-conditional-theme-acme)",Ce="rte-conditional-content-styles",c="rte-conditional-dialog-overlay",u="rte-conditional-floating-toolbar",w=new WeakMap,$e=new WeakMap,x=new WeakMap,_=new Map,z=new Map;let le=null,se=0,G=null,U=null,Y=null,J=null,X=null,Q=null,N=null,g=null,ee=null;const Oe={dialogTitleInsert:"Insert Conditional Content",dialogTitleEdit:"Edit Conditional Content",conditionLabel:"Condition",conditionPlaceholder:'user.role == "admin"',audienceLabel:"Audience (comma separated)",audiencePlaceholder:"all",localeLabel:"Locale (comma separated)",localePlaceholder:"all",elseLabel:"Enable Else Block",saveText:"Save",cancelText:"Cancel",blockIfLabel:"IF",blockElseLabel:"ELSE",allAudiencesText:"all audiences",allLocalesText:"all locales"};function y(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function P(e){return e?e.split(",").map(t=>t.trim()).filter(Boolean):[]}function Le(e){return!e||e.length===0?"":e.join(", ")}function te(e){return e?e.map(t=>t.trim()).filter(Boolean):[]}function Re(e){return{...Oe,...e||{}}}function k(e){return e.getAttribute("contenteditable")==="false"||e.getAttribute("data-readonly")==="true"}function ce(e){return e.closest("[data-editora-editor], .rte-editor, .editora-editor, editora-editor")||e}function ue(e){if(!e)return!1;const t=e.getAttribute("data-theme")||e.getAttribute("theme");return t&&t.toLowerCase()==="dark"?!0:e.classList.contains("dark")||e.classList.contains("editora-theme-dark")||e.classList.contains("rte-theme-dark")}function qe(e){const t=ce(e);if(ue(t))return!0;const o=t.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark");return ue(o)?!0:ue(document.documentElement)||ue(document.body)}function fe(e){if(!e)return!1;const t=e.getAttribute("data-theme")||e.getAttribute("theme");return t&&t.toLowerCase()==="acme"?!0:e.classList.contains("editora-theme-acme")||e.classList.contains("rte-theme-acme")}function Ke(e){const t=ce(e);if(fe(t))return!0;const o=t.closest("[data-theme], [theme], .editora-theme-acme, .rte-theme-acme");return fe(o)?!0:fe(document.documentElement)||fe(document.body)}function Ie(e){return qe(e)?"dark":Ke(e)?"acme":"light"}function he(e,t){const o=Ie(t);e.classList.remove("rte-conditional-theme-dark","rte-conditional-theme-acme"),o==="dark"?e.classList.add("rte-conditional-theme-dark"):o==="acme"&&e.classList.add("rte-conditional-theme-acme")}function A(e,t=!0){if(e?.contentElement instanceof HTMLElement)return e.contentElement;if(e?.editorElement instanceof HTMLElement){const n=e.editorElement;if(n.matches(L))return n;const a=n.querySelector(L);if(a instanceof HTMLElement)return a}const o=window.getSelection();if(o&&o.rangeCount>0){const n=o.getRangeAt(0).startContainer,r=(n.nodeType===Node.ELEMENT_NODE?n:n.parentElement)?.closest(L);if(r)return r}const i=document.activeElement;if(i){if(i.matches(L))return i;const n=i.closest(L);if(n)return n}return g&&g.isConnected?g:t?document.querySelector(L):null}function ke(e){const t=window.getSelection();if(!t||t.rangeCount===0)return null;const o=t.getRangeAt(0);return e.contains(o.commonAncestorContainer)?o.cloneRange():null}function xe(e,t){const o=window.getSelection();o&&(o.removeAllRanges(),o.addRange(t),e.focus({preventScroll:!0}))}function Se(e){e.dispatchEvent(new Event("input",{bubbles:!0}))}function Te(e,t){if(t===e.innerHTML)return;const o=window.execEditorCommand||window.executeEditorCommand;if(typeof o=="function")try{o("recordDomTransaction",e,t,e.innerHTML)}catch{}}function pe(e,t){const o=document.createRange();o.selectNodeContents(t),o.collapse(!1),xe(e,o)}function ye(e,t){if(t)return t.split(".").filter(Boolean).reduce((o,i)=>{if(o!=null&&typeof o=="object")return o[i]},e)}function _e(e){const t=e.trim();if(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"))return t.slice(1,-1);if(t==="true")return!0;if(t==="false")return!1;if(t==="null")return null;const o=Number(t);if(!Number.isNaN(o)&&t!=="")return o;if(t.startsWith("[")&&t.endsWith("]")||t.startsWith("{")&&t.endsWith("}"))try{return JSON.parse(t)}catch{return t}return t}function ze(e,t){const o=e.trim();if(!o)return!0;if(o.startsWith("!")){const E=o.slice(1).trim();return!ye(t,E)}const i=o.match(/^([a-zA-Z_$][\w.$]*)\s*(==|!=|>=|<=|>|<|in|contains|~=)\s*(.+)$/);if(!i)return!!ye(t,o);const[,n,a,r]=i,l=ye(t,n),d=_e(r);switch(a){case"==":return l==d;case"!=":return l!=d;case">":return Number(l)>Number(d);case"<":return Number(l)<Number(d);case">=":return Number(l)>=Number(d);case"<=":return Number(l)<=Number(d);case"in":return Array.isArray(d)?d.some(E=>E==l):typeof d=="string"?d.split(",").map(E=>E.trim()).includes(String(l)):!1;case"contains":case"~=":return Array.isArray(l)?l.some(E=>String(E).toLowerCase()===String(d).toLowerCase()):typeof l=="string"?l.toLowerCase().includes(String(d).toLowerCase()):!1;default:return!1}}function Fe(){if(typeof document>"u"||document.getElementById(Ce))return;const e=document.createElement("style");e.id=Ce,e.textContent=` | ||
| .rte-conditional-block { | ||
| border: 1px solid #dbe3ec; | ||
| border-radius: 8px; | ||
| margin: 10px 0; | ||
| background: #f8fafc; | ||
| overflow: hidden; | ||
| } | ||
| .rte-conditional-header, | ||
| .rte-conditional-else-label { | ||
| display: flex; | ||
| align-items: center; | ||
| gap: 8px; | ||
| background: #eef2f7; | ||
| border-bottom: 1px solid #dbe3ec; | ||
| padding: 8px 10px; | ||
| user-select: none; | ||
| } | ||
| .rte-conditional-else-label { | ||
| border-top: 1px solid #dbe3ec; | ||
| border-bottom: 1px solid #dbe3ec; | ||
| } | ||
| .rte-conditional-chip { | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| min-width: 34px; | ||
| height: 20px; | ||
| border-radius: 999px; | ||
| border: 1px solid #bfdbfe; | ||
| background: #dbeafe; | ||
| color: #1e3a8a; | ||
| font-size: 11px; | ||
| font-weight: 700; | ||
| letter-spacing: 0.03em; | ||
| text-transform: uppercase; | ||
| padding: 0 7px; | ||
| flex: 0 0 auto; | ||
| } | ||
| .rte-conditional-chip-else { | ||
| border-color: #fecaca; | ||
| background: #fee2e2; | ||
| color: #991b1b; | ||
| } | ||
| .rte-conditional-summary { | ||
| font-size: 12px; | ||
| color: #0f172a; | ||
| font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; | ||
| overflow: hidden; | ||
| text-overflow: ellipsis; | ||
| white-space: nowrap; | ||
| flex: 1; | ||
| } | ||
| .rte-conditional-meta { | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| white-space: nowrap; | ||
| flex: 0 0 auto; | ||
| } | ||
| .rte-conditional-body { | ||
| padding: 10px; | ||
| background: #ffffff; | ||
| min-height: 44px; | ||
| } | ||
| .rte-conditional-hidden { | ||
| display: none !important; | ||
| } | ||
| .rte-toolbar-group-items.conditional-content, | ||
| .editora-toolbar-group-items.conditional-content { | ||
| display: flex; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| background: #ffffff; | ||
| } | ||
| .rte-toolbar-group-items.conditional-content .rte-toolbar-item, | ||
| .editora-toolbar-group-items.conditional-content .editora-toolbar-item { | ||
| display: flex; | ||
| } | ||
| .rte-toolbar-group-items.conditional-content .rte-toolbar-button, | ||
| .editora-toolbar-group-items.conditional-content .editora-toolbar-button { | ||
| border: none; | ||
| border-right: 1px solid #cbd5e1; | ||
| border-radius: 0; | ||
| } | ||
| .rte-toolbar-group-items.conditional-content .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.conditional-content .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| .rte-toolbar-button[data-command="toggleConditionalPreview"].active, | ||
| .editora-toolbar-button[data-command="toggleConditionalPreview"].active { | ||
| background: #ccc; | ||
| } | ||
| .rte-conditional-block.rte-conditional-preview { | ||
| border-style: dashed; | ||
| } | ||
| .rte-conditional-block.rte-conditional-preview .rte-conditional-body[contenteditable="false"] { | ||
| cursor: default; | ||
| } | ||
| .${c} { | ||
| position: fixed; | ||
| inset: 0; | ||
| background: rgba(15, 23, 42, 0.5); | ||
| z-index: 2147483646; | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| padding: 20px; | ||
| } | ||
| .rte-conditional-dialog { | ||
| width: min(560px, 96vw); | ||
| max-height: min(88vh, 760px); | ||
| border: 1px solid #dbe3ec; | ||
| border-radius: 8px; | ||
| background: #ffffff; | ||
| box-shadow: 0 24px 50px rgba(15, 23, 42, 0.25); | ||
| display: flex; | ||
| flex-direction: column; | ||
| overflow: hidden; | ||
| } | ||
| .rte-conditional-dialog-header, | ||
| .rte-conditional-dialog-footer { | ||
| padding: 12px 14px; | ||
| border-bottom: 1px solid #e2e8f0; | ||
| background: #f8fafc; | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 10px; | ||
| } | ||
| .rte-conditional-dialog-footer { | ||
| border-top: 1px solid #e2e8f0; | ||
| border-bottom: none; | ||
| justify-content: flex-end; | ||
| } | ||
| .rte-conditional-dialog-title { | ||
| margin: 0; | ||
| font-size: 16px; | ||
| font-weight: 700; | ||
| color: #0f172a; | ||
| } | ||
| .rte-conditional-dialog-body { | ||
| padding: 14px; | ||
| overflow: auto; | ||
| display: grid; | ||
| grid-template-columns: 1fr; | ||
| gap: 12px; | ||
| } | ||
| .rte-conditional-field { | ||
| display: grid; | ||
| gap: 6px; | ||
| } | ||
| .rte-conditional-field label { | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| color: #334155; | ||
| } | ||
| .rte-conditional-field input[type="text"] { | ||
| width: 100%; | ||
| min-height: 36px; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| padding: 8px 10px; | ||
| font-size: 13px; | ||
| line-height: 1.4; | ||
| box-sizing: border-box; | ||
| color: #0f172a; | ||
| background: #ffffff; | ||
| } | ||
| .rte-conditional-field input[type="text"]:focus-visible, | ||
| .rte-conditional-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .rte-conditional-checkbox { | ||
| display: inline-flex; | ||
| align-items: center; | ||
| gap: 8px; | ||
| font-size: 13px; | ||
| color: #334155; | ||
| min-height: 36px; | ||
| } | ||
| .rte-conditional-help { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| color: #64748b; | ||
| } | ||
| .rte-conditional-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| min-height: 34px; | ||
| padding: 6px 12px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| font-size: 13px; | ||
| cursor: pointer; | ||
| } | ||
| .rte-conditional-btn-primary { | ||
| border-color: #2563eb; | ||
| background: #2563eb; | ||
| color: #ffffff; | ||
| } | ||
| .rte-conditional-btn-primary:hover { | ||
| background: #1d4ed8; | ||
| } | ||
| .${u} { | ||
| position: fixed; | ||
| z-index: 2147483645; | ||
| display: none; | ||
| align-items: center; | ||
| gap: 6px; | ||
| padding: 6px; | ||
| border-radius: 8px; | ||
| border: 1px solid #cbd5e1; | ||
| background: rgba(255, 255, 255, 0.98); | ||
| box-shadow: 0 14px 30px rgba(15, 23, 42, 0.2); | ||
| backdrop-filter: blur(6px); | ||
| } | ||
| .${u}.show { | ||
| display: inline-flex; | ||
| } | ||
| .${u} .rte-conditional-float-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| min-height: 30px; | ||
| min-width: 30px; | ||
| padding: 0 8px; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| gap: 6px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| cursor: pointer; | ||
| font-size: 12px; | ||
| line-height: 1; | ||
| } | ||
| .${u} .rte-conditional-float-btn:hover { | ||
| background: #f8fafc; | ||
| } | ||
| .${u} .rte-conditional-float-btn[data-action="delete"] { | ||
| border-color: #fecaca; | ||
| color: #991b1b; | ||
| background: #fff5f5; | ||
| } | ||
| .rte-conditional-preview-on ${H} { | ||
| border-width: 2px; | ||
| } | ||
| .rte-conditional-preview-on ${H} .rte-conditional-header { | ||
| background: #ecfeff; | ||
| border-color: #bae6fd; | ||
| } | ||
| ${b} .rte-conditional-block, | ||
| ${p} .rte-conditional-block, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-block { | ||
| background: #111827; | ||
| border-color: #334155; | ||
| } | ||
| ${b} .rte-conditional-header, | ||
| ${b} .rte-conditional-else-label, | ||
| ${p} .rte-conditional-header, | ||
| ${p} .rte-conditional-else-label, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-header, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-else-label { | ||
| background: #0f172a; | ||
| border-color: #334155; | ||
| } | ||
| ${b} .rte-conditional-summary, | ||
| ${p} .rte-conditional-summary, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-summary { | ||
| color: #e2e8f0; | ||
| } | ||
| ${b} .rte-conditional-meta, | ||
| ${p} .rte-conditional-meta, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-meta { | ||
| color: #94a3b8; | ||
| } | ||
| ${b} .rte-conditional-chip, | ||
| ${p} .rte-conditional-chip, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-chip { | ||
| background: #1e3a8a; | ||
| border-color: #3b82f6; | ||
| color: #dbeafe; | ||
| } | ||
| ${b} .rte-conditional-chip-else, | ||
| ${p} .rte-conditional-chip-else, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-chip-else { | ||
| background: #7f1d1d; | ||
| border-color: #ef4444; | ||
| color: #fee2e2; | ||
| } | ||
| ${b} .rte-conditional-body, | ||
| ${p} .rte-conditional-body, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-body { | ||
| background: #1f2937; | ||
| color: #e2e8f0; | ||
| } | ||
| ${b} .rte-conditional-dialog, | ||
| ${p} .rte-conditional-dialog, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-dialog { | ||
| background: #1f2937; | ||
| border-color: #334155; | ||
| } | ||
| ${b} .rte-conditional-dialog-header, | ||
| ${b} .rte-conditional-dialog-footer, | ||
| ${p} .rte-conditional-dialog-header, | ||
| ${p} .rte-conditional-dialog-footer, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-dialog-header, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-dialog-footer { | ||
| background: #111827; | ||
| border-color: #334155; | ||
| } | ||
| ${b} .rte-conditional-dialog-title, | ||
| ${b} .rte-conditional-field label, | ||
| ${b} .rte-conditional-checkbox, | ||
| ${p} .rte-conditional-dialog-title, | ||
| ${p} .rte-conditional-field label, | ||
| ${p} .rte-conditional-checkbox, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-dialog-title, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-field label, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-checkbox { | ||
| color: #e2e8f0; | ||
| } | ||
| ${b} .rte-conditional-help, | ||
| ${p} .rte-conditional-help, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-help { | ||
| color: #94a3b8; | ||
| } | ||
| ${b} .rte-conditional-field input[type="text"], | ||
| ${b} .rte-conditional-btn, | ||
| ${p} .rte-conditional-field input[type="text"], | ||
| ${p} .rte-conditional-btn, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-field input[type="text"], | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-btn { | ||
| background: #0f172a; | ||
| border-color: #475569; | ||
| color: #e2e8f0; | ||
| } | ||
| ${b} .rte-conditional-btn-primary, | ||
| ${p} .rte-conditional-btn-primary, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-btn-primary { | ||
| border-color: #3b82f6; | ||
| background: #2563eb; | ||
| color: #ffffff; | ||
| } | ||
| ${b} .rte-toolbar-group-items.conditional-content, | ||
| .${c}.rte-conditional-theme-dark .rte-toolbar-group-items.conditional-content, | ||
| ${p} .rte-toolbar-group-items.conditional-content, | ||
| ${b} .editora-toolbar-group-items.conditional-content { | ||
| border-color: #566275; | ||
| } | ||
| ${b} .rte-toolbar-group-items.conditional-content .rte-toolbar-button, | ||
| ${p} .rte-toolbar-group-items.conditional-content .rte-toolbar-button, | ||
| ${b} .editora-toolbar-group-items.conditional-content .editora-toolbar-button { | ||
| border-right-color: #566275; | ||
| } | ||
| ${b} .${u}, | ||
| .${c}.rte-conditional-theme-dark .${u}, | ||
| .${u}.rte-conditional-theme-dark { | ||
| background: rgba(17, 24, 39, 0.98); | ||
| border-color: #334155; | ||
| box-shadow: 0 14px 30px rgba(2, 6, 23, 0.5); | ||
| } | ||
| ${b} .${u} .rte-conditional-float-btn, | ||
| .${c}.rte-conditional-theme-dark .${u} .rte-conditional-float-btn, | ||
| .${u}.rte-conditional-theme-dark .rte-conditional-float-btn { | ||
| background: #0f172a; | ||
| border-color: #475569; | ||
| color: #e2e8f0; | ||
| } | ||
| ${b} .${u} .rte-conditional-float-btn[data-action="delete"], | ||
| .${c}.rte-conditional-theme-dark .${u} .rte-conditional-float-btn[data-action="delete"], | ||
| .${u}.rte-conditional-theme-dark .rte-conditional-float-btn[data-action="delete"] { | ||
| border-color: #ef4444; | ||
| color: #fecaca; | ||
| background: rgba(127, 29, 29, 0.45); | ||
| } | ||
| ${f} .rte-conditional-block, | ||
| ${h} .rte-conditional-block, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-block { | ||
| background: #f8fbff; | ||
| border-color: #cbd8e8; | ||
| } | ||
| ${f} .rte-conditional-header, | ||
| ${f} .rte-conditional-else-label, | ||
| ${h} .rte-conditional-header, | ||
| ${h} .rte-conditional-else-label, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-header, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-else-label { | ||
| background: linear-gradient(180deg, #eef4fb 0%, #e6eef8 100%); | ||
| border-color: #cbd8e8; | ||
| } | ||
| ${f} .rte-conditional-summary, | ||
| ${h} .rte-conditional-summary, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-summary { | ||
| color: #0f172a; | ||
| } | ||
| ${f} .rte-conditional-meta, | ||
| ${h} .rte-conditional-meta, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-meta { | ||
| color: #587089; | ||
| } | ||
| ${f} .rte-conditional-chip, | ||
| ${h} .rte-conditional-chip, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-chip { | ||
| background: #d9f5ee; | ||
| border-color: #66c6b3; | ||
| color: #0f4f4a; | ||
| } | ||
| ${f} .rte-conditional-chip-else, | ||
| ${h} .rte-conditional-chip-else, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-chip-else { | ||
| background: #fde8ea; | ||
| border-color: #f1a7b2; | ||
| color: #8b1f2f; | ||
| } | ||
| ${f} .rte-conditional-body, | ||
| ${h} .rte-conditional-body, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-body { | ||
| background: #fcfeff; | ||
| color: #0f172a; | ||
| } | ||
| ${f} .rte-conditional-dialog, | ||
| ${h} .rte-conditional-dialog, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-dialog { | ||
| background: #ffffff; | ||
| border-color: #cbd8e8; | ||
| box-shadow: 0 20px 44px rgba(15, 23, 42, 0.18); | ||
| } | ||
| ${f} .rte-conditional-dialog-header, | ||
| ${f} .rte-conditional-dialog-footer, | ||
| ${h} .rte-conditional-dialog-header, | ||
| ${h} .rte-conditional-dialog-footer, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-dialog-header, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-dialog-footer { | ||
| background: #f3f8fd; | ||
| border-color: #d8e4f1; | ||
| } | ||
| ${f} .rte-conditional-dialog-title, | ||
| ${f} .rte-conditional-field label, | ||
| ${f} .rte-conditional-checkbox, | ||
| ${h} .rte-conditional-dialog-title, | ||
| ${h} .rte-conditional-field label, | ||
| ${h} .rte-conditional-checkbox, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-dialog-title, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-field label, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-checkbox { | ||
| color: #1f334a; | ||
| } | ||
| ${f} .rte-conditional-help, | ||
| ${h} .rte-conditional-help, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-help { | ||
| color: #5f738d; | ||
| } | ||
| ${f} .rte-conditional-field input[type="text"], | ||
| ${f} .rte-conditional-btn, | ||
| ${h} .rte-conditional-field input[type="text"], | ||
| ${h} .rte-conditional-btn, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-field input[type="text"], | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-btn { | ||
| background: #ffffff; | ||
| border-color: #bfd0e2; | ||
| color: #0f172a; | ||
| } | ||
| ${f} .rte-conditional-btn-primary, | ||
| ${h} .rte-conditional-btn-primary, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-btn-primary { | ||
| border-color: #0f766e; | ||
| background: #0f766e; | ||
| color: #ffffff; | ||
| } | ||
| ${f} .rte-toolbar-group-items.conditional-content, | ||
| .${c}.rte-conditional-theme-acme .rte-toolbar-group-items.conditional-content, | ||
| ${h} .rte-toolbar-group-items.conditional-content, | ||
| ${f} .editora-toolbar-group-items.conditional-content { | ||
| border-color: #bfd0e2; | ||
| } | ||
| ${f} .rte-toolbar-group-items.conditional-content .rte-toolbar-button, | ||
| ${h} .rte-toolbar-group-items.conditional-content .rte-toolbar-button, | ||
| ${f} .editora-toolbar-group-items.conditional-content .editora-toolbar-button { | ||
| border-right-color: #bfd0e2; | ||
| } | ||
| ${f} .${u}, | ||
| .${c}.rte-conditional-theme-acme .${u}, | ||
| .${u}.rte-conditional-theme-acme { | ||
| background: rgba(255, 255, 255, 0.98); | ||
| border-color: #bfd0e2; | ||
| box-shadow: 0 14px 28px rgba(15, 23, 42, 0.16); | ||
| } | ||
| ${f} .${u} .rte-conditional-float-btn, | ||
| .${c}.rte-conditional-theme-acme .${u} .rte-conditional-float-btn, | ||
| .${u}.rte-conditional-theme-acme .rte-conditional-float-btn { | ||
| background: #ffffff; | ||
| border-color: #bfd0e2; | ||
| color: #1f334a; | ||
| } | ||
| ${f} .${u} .rte-conditional-float-btn:hover, | ||
| .${c}.rte-conditional-theme-acme .${u} .rte-conditional-float-btn:hover, | ||
| .${u}.rte-conditional-theme-acme .rte-conditional-float-btn:hover { | ||
| background: #eef7f5; | ||
| color: #0f4f4a; | ||
| } | ||
| ${f} .${u} .rte-conditional-float-btn[data-action="delete"], | ||
| .${c}.rte-conditional-theme-acme .${u} .rte-conditional-float-btn[data-action="delete"], | ||
| .${u}.rte-conditional-theme-acme .rte-conditional-float-btn[data-action="delete"] { | ||
| border-color: #f1a7b2; | ||
| color: #8b1f2f; | ||
| background: #fff4f6; | ||
| } | ||
| `,document.head.appendChild(e)}function je(e){return{defaultCondition:e.defaultCondition||"",defaultAudience:te(e.defaultAudience||[]),defaultLocale:te(e.defaultLocale||[]),enableElseByDefault:e.enableElseByDefault===!0,labels:Re(e.labels),context:e.context,getContext:e.getContext,currentAudience:e.currentAudience,currentLocale:e.currentLocale,evaluateCondition:e.evaluateCondition||ze}}function Be(){le&&(le.cleanup(),le=null)}function Ve(e){return e?e.nodeType===Node.ELEMENT_NODE?e:e.parentElement:null}function oe(e,t){e.setAttribute("contenteditable","false"),e.setAttribute("spellcheck","false");const o=e.querySelector(".rte-conditional-header");o&&(o.setAttribute("contenteditable","false"),o.setAttribute("tabindex","0"),o.setAttribute("role","button"),o.setAttribute("aria-label","Edit conditional rule"));const i=e.querySelector(".rte-conditional-else-label");i&&i.setAttribute("contenteditable","false"),Ge(e,!t)}function We(e){const t=e.querySelector('.rte-conditional-body[data-slot="if"]');if(!t)return;const o=new Set,i=e.querySelector(".rte-conditional-header"),n=e.querySelector(".rte-conditional-else-label"),a=e.querySelector('.rte-conditional-body[data-slot="else"]');i&&o.add(i),o.add(t),n&&o.add(n),a&&o.add(a),Array.from(e.childNodes).forEach(l=>{if(!(l instanceof HTMLElement&&o.has(l))){if(l.nodeType===Node.TEXT_NODE&&!(l.textContent||"").trim()){l.remove();return}t.appendChild(l)}})}function W(e){const t=window.getSelection();if(t&&t.rangeCount>0){const n=t.getRangeAt(0).startContainer,r=(n.nodeType===Node.ELEMENT_NODE?n:n.parentElement)?.closest(H);if(r&&e.contains(r))return r}const i=document.activeElement?.closest(H);return i&&e.contains(i)?i:null}function Ee(e,t){let o=e.querySelector(".rte-conditional-else-label"),i=e.querySelector('.rte-conditional-body[data-slot="else"]');o||(o=document.createElement("div"),o.className="rte-conditional-else-label",o.setAttribute("contenteditable","false"),o.innerHTML=` | ||
| <span class="rte-conditional-chip rte-conditional-chip-else">${y(t.blockElseLabel)}</span> | ||
| <span class="rte-conditional-summary">Else branch</span> | ||
| `,e.appendChild(o)),i||(i=document.createElement("div"),i.className="rte-conditional-body rte-conditional-else-body",i.setAttribute("data-slot","else"),i.innerHTML="<p><br></p>",e.appendChild(i))}function Ze(e,t){e.setAttribute("data-has-else",t?"true":"false");const o=e.querySelector(".rte-conditional-else-label"),i=e.querySelector('.rte-conditional-body[data-slot="else"]');o&&o.classList.toggle("rte-conditional-hidden",!t),i&&i.classList.toggle("rte-conditional-hidden",!t)}function Ge(e,t){Array.from(e.querySelectorAll(".rte-conditional-body")).forEach(i=>{i.setAttribute("contenteditable",t?"true":"false")}),e.setAttribute("contenteditable","false")}function ve(e,t){const o=e.getAttribute("data-condition")||"",i=P(e.getAttribute("data-audience")),n=P(e.getAttribute("data-locale"));let a=e.querySelector(".rte-conditional-header");a||(a=document.createElement("div"),a.className="rte-conditional-header",e.prepend(a)),a.setAttribute("contenteditable","false"),a.setAttribute("tabindex","0"),a.setAttribute("role","button"),a.setAttribute("aria-label","Edit conditional rule");const r=o||"(always true)",l=i.length>0?i.join(", "):t.allAudiencesText,d=n.length>0?n.join(", "):t.allLocalesText;if(a.innerHTML=` | ||
| <span class="rte-conditional-chip">${y(t.blockIfLabel)}</span> | ||
| <span class="rte-conditional-summary">${y(r)}</span> | ||
| <span class="rte-conditional-meta">${y(l)} · ${y(d)}</span> | ||
| `,!e.querySelector('.rte-conditional-body[data-slot="if"]')){const v=document.createElement("div");v.className="rte-conditional-body",v.setAttribute("data-slot","if"),v.innerHTML="<p><br></p>",e.insertBefore(v,e.children[1]||null)}const m=e.getAttribute("data-has-else")==="true";m&&Ee(e,t),We(e),Ze(e,m)}function Me(e,t){const o=document.createElement("section");o.className="rte-conditional-block",o.setAttribute("data-conditional-content","true"),o.setAttribute("data-condition",(e.condition||"").trim()),o.setAttribute("data-audience",te(e.audience).join(",")),o.setAttribute("data-locale",te(e.locale).join(",")),o.setAttribute("data-has-else",e.hasElse?"true":"false"),o.setAttribute("role","group"),o.setAttribute("aria-label","Conditional content block"),o.setAttribute("contenteditable","false"),o.setAttribute("spellcheck","false");const i=document.createElement("div");i.className="rte-conditional-header",i.setAttribute("contenteditable","false");const n=document.createElement("div");return n.className="rte-conditional-body",n.setAttribute("data-slot","if"),n.innerHTML="<p><br></p>",o.appendChild(i),o.appendChild(n),e.hasElse&&Ee(o,t),ve(o,t),oe(o,!1),o}function Ue(e,t){if(t)try{if(!e.isConnected)return;const o=e.contains(t.startContainer),i=e.contains(t.endContainer);if(!o||!i)return;xe(e,t)}catch{}}function Ye(e){return(e.textContent||"").replace(/\u200B/g,"").trim().length>0?!0:e.querySelector("img, video, table, iframe, hr, pre, blockquote, ul, ol")!==null}function Ne(e,t,o){let i=null;i||(i=ke(e)),i||(i=document.createRange(),i.selectNodeContents(e),i.collapse(!1));let n=null;i.collapsed||(n=i.extractContents()),i.insertNode(t);const a=t.querySelector('.rte-conditional-body[data-slot="if"]');a&&n&&Ye(n)&&(a.innerHTML="",a.appendChild(n)),a?pe(e,a):pe(e,t),e.normalize()}function Je(e){return{condition:e.getAttribute("data-condition")||"",audience:P(e.getAttribute("data-audience")),locale:P(e.getAttribute("data-locale")),hasElse:e.getAttribute("data-has-else")==="true"}}function Xe(e,t,o){e.setAttribute("data-condition",(t.condition||"").trim()),e.setAttribute("data-audience",te(t.audience).join(",")),e.setAttribute("data-locale",te(t.locale).join(",")),e.setAttribute("data-has-else",t.hasElse?"true":"false"),t.hasElse&&Ee(e,o),ve(e,o),oe(e,e.classList.contains("rte-conditional-preview"))}function ne(e,t){he(e,e);const o=Array.from(e.querySelectorAll(H)),i=w.get(e)===!0;return o.forEach(n=>{n.classList.add("rte-conditional-block"),n.setAttribute("data-conditional-content","true"),n.hasAttribute("data-condition")||n.setAttribute("data-condition",""),n.hasAttribute("data-audience")||n.setAttribute("data-audience",""),n.hasAttribute("data-locale")||n.setAttribute("data-locale",""),n.hasAttribute("data-has-else")||n.setAttribute("data-has-else","false"),n.setAttribute("role","group"),n.setAttribute("aria-label","Conditional content block"),n.setAttribute("contenteditable","false"),n.setAttribute("spellcheck","false"),ve(n,t),oe(n,i)}),o}async function Qe(e,t){const o=$e.get(e);if(o)return o;if(typeof t.getContext=="function")try{const i=ce(e),n=await Promise.resolve(t.getContext({editor:e,editorRoot:i}));if(n&&typeof n=="object")return n}catch{return{}}if(typeof t.context=="function")try{const i=t.context();if(i&&typeof i=="object")return i}catch{return{}}return t.context&&typeof t.context=="object"?t.context:{}}function be(e){return Array.isArray(e)?e.map(t=>t.trim().toLowerCase()).filter(Boolean):typeof e=="string"?e.split(",").map(t=>t.trim().toLowerCase()).filter(Boolean):[]}function Ae(e,t){return e.length===0||e.includes("all")?!0:t.length===0?!1:e.some(o=>t.includes(o))}async function Z(e,t,o){const i=t.labels,n=ne(e,i);if(w.set(e,o),De(e,o),ce(e).classList.toggle("rte-conditional-preview-on",o),!o){n.forEach($=>{$.classList.remove("rte-conditional-preview"),oe($,!1);const O=$.querySelector('.rte-conditional-body[data-slot="if"]'),T=$.querySelector('.rte-conditional-body[data-slot="else"]'),F=$.querySelector(".rte-conditional-else-label"),B=$.getAttribute("data-has-else")==="true";O&&(O.classList.remove("rte-conditional-hidden"),O.removeAttribute("aria-hidden")),T&&(T.classList.toggle("rte-conditional-hidden",!B),T.setAttribute("aria-hidden",B?"false":"true")),F&&F.classList.toggle("rte-conditional-hidden",!B)});return}const r=await Qe(e,t),l=be(t.currentAudience),d=be(t.currentLocale),E=be(r.audience??r.user?.audience),m=be(r.locale??r.user?.locale),v=l.length>0?l:E,S=d.length>0?d:m;n.forEach($=>{const O=$.getAttribute("data-condition")||"",T=P($.getAttribute("data-audience")).map(s=>s.toLowerCase()),F=P($.getAttribute("data-locale")).map(s=>s.toLowerCase()),B=$.getAttribute("data-has-else")==="true",ge=t.evaluateCondition(O,r),M=Ae(T,v),de=Ae(F,S),R=ge&&M&&de,ie=$.querySelector('.rte-conditional-body[data-slot="if"]'),j=$.querySelector('.rte-conditional-body[data-slot="else"]'),ae=$.querySelector(".rte-conditional-else-label");if($.classList.add("rte-conditional-preview"),oe($,!0),ie&&(ie.classList.toggle("rte-conditional-hidden",!R),ie.setAttribute("aria-hidden",R?"false":"true")),j){const s=B&&!R;j.classList.toggle("rte-conditional-hidden",!s),j.setAttribute("aria-hidden",s?"false":"true")}if(ae){const s=B&&!R;ae.classList.toggle("rte-conditional-hidden",!s)}})}function De(e,t){const o=ce(e);Array.from(o.querySelectorAll('[data-command="toggleConditionalPreview"], [data-command="conditionalPreview"]')).forEach(n=>{n.setAttribute("data-active",t?"true":"false"),n.classList.toggle("active",t),n.setAttribute("aria-pressed",t?"true":"false")})}function et(e){const t=_.get(e);if(t&&t.isConnected)return t;const o=document.createElement("div");return o.className=u,o.setAttribute("role","toolbar"),o.setAttribute("aria-label","Conditional block actions"),o.innerHTML=` | ||
| <button type="button" class="rte-conditional-float-btn" data-action="edit" title="Edit Condition" aria-label="Edit Condition"> | ||
| <svg width="16" height="16" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M4 17.3V20h2.7l9.7-9.7-2.7-2.7L4 17.3Zm14.7-9.4a1 1 0 0 0 0-1.4l-1.2-1.2a1 1 0 0 0-1.4 0l-1.1 1.1 2.7 2.7 1-1.2Z" fill="currentColor"></path></svg> | ||
| </button> | ||
| <button type="button" class="rte-conditional-float-btn" data-action="delete" title="Delete Block" aria-label="Delete Block"> | ||
| <svg width="16" height="16" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M8 4h8l1 2h4v2H3V6h4l1-2Zm1 6h2v8H9v-8Zm4 0h2v8h-2v-8Z" fill="currentColor"></path></svg> | ||
| </button> | ||
| `,o.addEventListener("mousedown",i=>{i.preventDefault()}),o.addEventListener("click",i=>{const a=i.target?.closest("[data-action]")?.getAttribute("data-action");if(!a)return;const r=x.get(e)||ee;if(!r)return;const l=z.get(e);if(!(!l||!e.contains(l))){if(a==="edit"){C(e,r,"edit",void 0,l);return}a==="delete"&&(Pe(e,l),z.set(e,null),I(e))}}),document.body.appendChild(o),_.set(e,o),o}function I(e){const t=_.get(e);t&&t.classList.remove("show")}function He(e,t){const o=t.getBoundingClientRect();e.style.left="0px",e.style.top="0px",e.classList.add("show");const i=e.getBoundingClientRect(),n=8,a=window.innerWidth,r=window.innerHeight;let l=o.top-i.height-n;l<n&&(l=o.bottom+n),l=Math.min(l,r-i.height-n);let d=o.right-i.width;d=Math.max(n,Math.min(d,a-i.width-n)),e.style.left=`${d}px`,e.style.top=`${l}px`}function me(e,t){const o=et(e);he(o,e),z.set(e,t),He(o,t)}function D(e){const t=x.get(e)||ee;if(!t)return;const o=W(e);if(!o||!e.contains(o)||k(e)){z.set(e,null),I(e);return}ne(e,t.labels),me(e,o)}function tt(){_.forEach((e,t)=>{if(!t.isConnected||!e.isConnected){e.remove(),_.delete(t),z.delete(t);return}if(!e.classList.contains("show"))return;he(e,t);const o=z.get(t);if(!o||!t.contains(o)){I(t);return}He(e,o)})}function Pe(e,t){if(!e.contains(t))return!1;const o=e.innerHTML,i=t.parentNode,n=t.nextSibling;t.remove(),i===e&&e.innerHTML.trim()===""&&(e.innerHTML="<p><br></p>");const a=document.createRange();return n&&e.contains(n)?a.setStartBefore(n):(a.selectNodeContents(e),a.collapse(!1)),a.collapse(!0),xe(e,a),Se(e),Te(e,o),!0}function we(e,t,o){const i=e.cloneRange(),n=document.createRange();return n.selectNodeContents(t),n.collapse(o==="start"),i.startContainer===n.startContainer&&i.startOffset===n.startOffset&&i.endContainer===n.endContainer&&i.endOffset===n.endOffset}function C(e,t,o,i,n){Be();const a=t.labels,r=o==="insert"?ke(e):null,l=document.createElement("div");l.className=c,he(l,e);const d=document.createElement("section");d.className="rte-conditional-dialog",d.setAttribute("role","dialog"),d.setAttribute("aria-modal","true"),d.setAttribute("aria-labelledby","rte-conditional-dialog-title");const E=n?Je(n):void 0,m=i||E||{},v=m.condition??t.defaultCondition,S=m.audience??t.defaultAudience,$=m.locale??t.defaultLocale,O=m.hasElse??t.enableElseByDefault;d.innerHTML=` | ||
| <header class="rte-conditional-dialog-header"> | ||
| <h2 id="rte-conditional-dialog-title" class="rte-conditional-dialog-title">${y(o==="edit"?a.dialogTitleEdit:a.dialogTitleInsert)}</h2> | ||
| <button type="button" class="rte-conditional-btn" data-action="cancel" aria-label="${y(a.cancelText)}">✕</button> | ||
| </header> | ||
| <div class="rte-conditional-dialog-body"> | ||
| <div class="rte-conditional-field"> | ||
| <label for="rte-conditional-condition">${y(a.conditionLabel)}</label> | ||
| <input id="rte-conditional-condition" class="rte-conditional-input-condition" type="text" value="${y(v||"")}" placeholder="${y(a.conditionPlaceholder)}" /> | ||
| </div> | ||
| <div class="rte-conditional-field"> | ||
| <label for="rte-conditional-audience">${y(a.audienceLabel)}</label> | ||
| <input id="rte-conditional-audience" class="rte-conditional-input-audience" type="text" value="${y(Le(S))}" placeholder="${y(a.audiencePlaceholder)}" /> | ||
| </div> | ||
| <div class="rte-conditional-field"> | ||
| <label for="rte-conditional-locale">${y(a.localeLabel)}</label> | ||
| <input id="rte-conditional-locale" class="rte-conditional-input-locale" type="text" value="${y(Le($))}" placeholder="${y(a.localePlaceholder)}" /> | ||
| </div> | ||
| <label class="rte-conditional-checkbox"> | ||
| <input class="rte-conditional-input-else" type="checkbox" ${O?"checked":""} /> | ||
| <span>${y(a.elseLabel)}</span> | ||
| </label> | ||
| <p class="rte-conditional-help">Example condition: <code>user.role == "admin"</code>, <code>locale == "en-US"</code>, <code>!feature.beta</code></p> | ||
| </div> | ||
| <footer class="rte-conditional-dialog-footer"> | ||
| <button type="button" class="rte-conditional-btn" data-action="cancel">${y(a.cancelText)}</button> | ||
| <button type="button" class="rte-conditional-btn rte-conditional-btn-primary" data-action="save">${y(a.saveText)}</button> | ||
| </footer> | ||
| `,l.appendChild(d),document.body.appendChild(l);const T=d.querySelector(".rte-conditional-input-condition"),F=d.querySelector(".rte-conditional-input-audience"),B=d.querySelector(".rte-conditional-input-locale"),ge=d.querySelector(".rte-conditional-input-else"),M=()=>{l.removeEventListener("click",R),l.removeEventListener("keydown",ae,!0),document.removeEventListener("keydown",de,!0),l.parentNode&&l.parentNode.removeChild(l),le=null,e.focus({preventScroll:!0}),D(e)},de=s=>{s.key==="Escape"&&(s.preventDefault(),s.stopPropagation(),M())},R=s=>{s.target===l&&M()},ie=s=>{if(s.key!=="Tab")return;const q=Array.from(d.querySelectorAll('button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'));if(q.length===0)return;const V=q[0],K=q[q.length-1],re=document.activeElement;if(s.shiftKey&&re===V){s.preventDefault(),K.focus();return}!s.shiftKey&&re===K&&(s.preventDefault(),V.focus())},j=async()=>{const s={condition:T?.value?.trim()||"",audience:P(F?.value),locale:P(B?.value),hasElse:ge?.checked||!1},q=e.innerHTML;if(n)Xe(n,s,a),oe(n,w.get(e)===!0);else{Ue(e,r);const K=Me(s,a);try{Ne(e,K)}catch{e.appendChild(K);const re=K.querySelector('.rte-conditional-body[data-slot="if"]');re?pe(e,re):pe(e,K)}}w.get(e)===!0&&await Z(e,t,!0),Se(e),Te(e,q),D(e),M()},ae=s=>{if(s.key==="Escape"){s.preventDefault(),M();return}ie(s),s.key==="Enter"&&!s.shiftKey&&s.target instanceof HTMLInputElement&&(s.preventDefault(),j())};d.addEventListener("click",s=>{const V=s.target.getAttribute("data-action");if(V==="cancel"){M();return}V==="save"&&j()}),l.addEventListener("click",R),l.addEventListener("keydown",ae,!0),document.addEventListener("keydown",de,!0),le={cleanup:M},T?.focus()}function ot(e){const t=e.metaKey||e.ctrlKey,i=(typeof e.key=="string"?e.key:"").toLowerCase(),n=typeof e.code=="string"?e.code.toLowerCase():"",a=t&&e.altKey&&e.shiftKey&&(i==="c"||n==="keyc"),r=!e.metaKey&&!e.ctrlKey&&!e.altKey&&!e.shiftKey&&(i==="f9"||n==="f9");return a||r}function nt(e){const t=e.metaKey||e.ctrlKey,i=(typeof e.key=="string"?e.key:"").toLowerCase(),n=typeof e.code=="string"?e.code.toLowerCase():"",a=t&&e.altKey&&e.shiftKey&&(i==="p"||n==="keyp"),r=!e.metaKey&&!e.ctrlKey&&!e.altKey&&!e.shiftKey&&(i==="f10"||n==="f10");return a||r}function it(e){ee=e,U||(U=t=>{const i=t.target?.closest(L);if(!i)return;g=i,x.has(i)||x.set(i,e);const n=x.get(i)||e;ne(i,n.labels),De(i,w.get(i)===!0),D(i)},document.addEventListener("focusin",U,!0)),G||(G=t=>{if(document.querySelector(`.${c}`))return;const i=t.target;if(!!i?.closest("input, textarea, select"))return;const r=i?.closest(L)||A(void 0,!1)||g;if(!r||k(r))return;const l=x.get(r)||ee||e,d=document.activeElement,E=i?.closest(".rte-conditional-header")||d?.closest(".rte-conditional-header");if(E&&(t.key==="Enter"||t.key===" ")){const m=E.closest(H);if(m&&r.contains(m)){t.preventDefault(),t.stopPropagation(),C(r,l,"edit",void 0,m);return}}if(ot(t)){t.preventDefault(),t.stopPropagation();const m=W(r);m?C(r,l,"edit",void 0,m):C(r,l,"insert");return}if(nt(t)){t.preventDefault(),t.stopPropagation();const m=w.get(r)!==!0;Z(r,l,m),D(r);return}if((t.key==="Backspace"||t.key==="Delete")&&!t.altKey&&!t.ctrlKey&&!t.metaKey){const m=window.getSelection();if(!m||m.rangeCount===0)return;const v=m.getRangeAt(0);if(!v.collapsed||!r.contains(v.commonAncestorContainer))return;const S=Ve(v.startContainer)?.closest(".rte-conditional-body");if(!S||!r.contains(S))return;if(t.key==="Backspace"&&we(v,S,"start")){t.preventDefault();return}if(t.key==="Delete"&&we(v,S,"end")){t.preventDefault();return}}},document.addEventListener("keydown",G,!0)),J||(J=t=>{const o=t.target;if(!o||o.closest(`.${u}`))return;const i=o.closest(L);if(!i){g&&I(g);return}if(k(i))return;g=i,x.has(i)||x.set(i,e);const n=o.closest(H);if(!n){I(i);return}requestAnimationFrame(()=>{!i.isConnected||!i.contains(n)||me(i,n)})},document.addEventListener("mousedown",J,!0)),Y||(Y=t=>{const o=t.target;if(!o||o.closest(`.${u}`))return;const i=o.closest(L);if(!i){g&&I(g);return}if(k(i))return;g=i,x.has(i)||x.set(i,e);const n=x.get(i)||e,a=o.closest(H),r=!!o.closest(".rte-conditional-header, .rte-conditional-summary, .rte-conditional-meta, .rte-conditional-else-label");if(a&&r){t.preventDefault(),t.stopPropagation(),C(i,n,"edit",void 0,a),me(i,a);return}a?me(i,a):I(i)},document.addEventListener("click",Y,!0)),X||(X=()=>{const t=A(void 0,!1)||g;t&&t.isConnected&&D(t)},document.addEventListener("selectionchange",X)),Q||(Q=t=>{const i=t.target?.closest(L);if(!i)return;const n=x.get(i)||ee||e;ne(i,n.labels),D(i)},document.addEventListener("input",Q,!0)),N||(N=()=>{tt()},window.addEventListener("scroll",N,!0),window.addEventListener("resize",N))}function at(){U&&(document.removeEventListener("focusin",U,!0),U=null),G&&(document.removeEventListener("keydown",G,!0),G=null),Y&&(document.removeEventListener("click",Y,!0),Y=null),J&&(document.removeEventListener("mousedown",J,!0),J=null),X&&(document.removeEventListener("selectionchange",X),X=null),Q&&(document.removeEventListener("input",Q,!0),Q=null),N&&(window.removeEventListener("scroll",N,!0),window.removeEventListener("resize",N),N=null),_.forEach(e=>{e.remove()}),_.clear(),z.clear(),ee=null,g=null}const rt=(e={})=>{const t=je(e);return Fe(),{name:"conditionalContent",toolbar:[{id:"conditionalContentGroup",label:"Conditional Content",type:"group",command:"conditionalContent",items:[{id:"conditionalContent",label:"Conditional Rule",command:"openConditionalDialog",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M6 5h12a1 1 0 0 1 1 1v3h-2V7H7v3H5V6a1 1 0 0 1 1-1Zm-1 9h2v3h10v-3h2v4a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1v-4Zm3-2a1 1 0 0 1 1-1h2.6l1.8-2.4a1 1 0 1 1 1.6 1.2L13.8 11H15a1 1 0 1 1 0 2h-2.7l-1.9 2.5a1 1 0 1 1-1.6-1.2L10.1 13H9a1 1 0 0 1-1-1Z" fill="currentColor"></path></svg>',shortcut:"Mod-Alt-Shift-c"},{id:"conditionalPreview",label:"Conditional Preview",command:"toggleConditionalPreview",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M4 6h16a1 1 0 0 1 1 1v3h-2V8H5v8h14v-2h2v3a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1Zm5 3h2v2H9V9Zm0 4h2v2H9v-2Zm4-4h6v2h-6V9Zm0 4h6v2h-6v-2Z" fill="currentColor"></path></svg>',shortcut:"Mod-Alt-Shift-p"}]}],commands:{conditionalContent:(o,i)=>{const n=A(i);if(!n||k(n))return!1;g=n,x.set(n,t),ne(n,t.labels);const a=o?.target;if(a==="insert")return C(n,t,"insert",o),!0;const r=W(n);return a==="edit"||r?!r&&a==="edit"?!1:(C(n,t,"edit",o,r||void 0),!0):(C(n,t,"insert",o),!0)},openConditionalDialog:(o,i)=>{const n=A(i);if(!n||k(n))return!1;g=n,x.set(n,t),ne(n,t.labels);const a=o?.target;if(a==="insert")return C(n,t,"insert",o),!0;const r=W(n);return a==="edit"||r?!r&&a==="edit"?!1:(C(n,t,"edit",o,r||void 0),!0):(C(n,t,"insert",o),!0)},conditionalPreview:async(o,i)=>{const n=A(i);if(!n)return!1;g=n,x.set(n,t);const a=typeof o=="boolean"?o:w.get(n)!==!0;return await Z(n,t,a),D(n),!0},editConditionalBlock:(o,i)=>{const n=A(i);if(!n||k(n))return!1;g=n,x.set(n,t);const a=W(n);return a?(C(n,t,"edit",o,a),!0):!1},deleteConditionalBlock:(o,i)=>{const n=A(i);if(!n||k(n))return!1;const a=W(n);if(!a)return!1;const r=Pe(n,a);return r&&D(n),r},insertConditionalBlock:(o,i)=>{const n=A(i);if(!n||k(n))return!1;g=n,x.set(n,t);const a={condition:o?.condition??t.defaultCondition,audience:o?.audience??t.defaultAudience,locale:o?.locale??t.defaultLocale,hasElse:o?.hasElse??t.enableElseByDefault},r=Me(a,t.labels);return Ne(n,r),w.get(n)===!0&&Z(n,t,!0),!0},toggleConditionalPreview:async(o,i)=>{const n=A(i);if(!n)return!1;g=n,x.set(n,t);const a=typeof o=="boolean"?o:w.get(n)!==!0;return await Z(n,t,a),!0},setConditionalContext:(o,i)=>{const n=A(i);return n?(g=n,!o||typeof o!="object"?$e.delete(n):$e.set(n,o),w.get(n)===!0&&Z(n,t,!0),!0):!1}},keymap:{"Mod-Alt-Shift-c":"openConditionalDialog","Mod-Alt-Shift-C":"openConditionalDialog","Mod-Alt-Shift-p":"toggleConditionalPreview","Mod-Alt-Shift-P":"toggleConditionalPreview",F9:"openConditionalDialog",F10:"toggleConditionalPreview"},init:()=>{se+=1,it(t)},destroy:()=>{se=Math.max(0,se-1),se===0&&(Be(),at())}}};exports.ConditionalContentPlugin=rt; |
| const L = ".rte-content, .editora-content", H = '.rte-conditional-block[data-conditional-content="true"]', b = ':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)', f = ':is([data-theme="acme"], .editora-theme-acme, .rte-theme-acme)', p = ":is(.rte-content.rte-conditional-theme-dark, .editora-content.rte-conditional-theme-dark)", h = ":is(.rte-content.rte-conditional-theme-acme, .editora-content.rte-conditional-theme-acme)", Ce = "rte-conditional-content-styles", c = "rte-conditional-dialog-overlay", u = "rte-conditional-floating-toolbar", w = /* @__PURE__ */ new WeakMap(), $e = /* @__PURE__ */ new WeakMap(), x = /* @__PURE__ */ new WeakMap(), _ = /* @__PURE__ */ new Map(), z = /* @__PURE__ */ new Map(); | ||
| let le = null, se = 0, G = null, U = null, Y = null, J = null, X = null, Q = null, N = null, g = null, ee = null; | ||
| const Pe = { | ||
| dialogTitleInsert: "Insert Conditional Content", | ||
| dialogTitleEdit: "Edit Conditional Content", | ||
| conditionLabel: "Condition", | ||
| conditionPlaceholder: 'user.role == "admin"', | ||
| audienceLabel: "Audience (comma separated)", | ||
| audiencePlaceholder: "all", | ||
| localeLabel: "Locale (comma separated)", | ||
| localePlaceholder: "all", | ||
| elseLabel: "Enable Else Block", | ||
| saveText: "Save", | ||
| cancelText: "Cancel", | ||
| blockIfLabel: "IF", | ||
| blockElseLabel: "ELSE", | ||
| allAudiencesText: "all audiences", | ||
| allLocalesText: "all locales" | ||
| }; | ||
| function y(e) { | ||
| return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); | ||
| } | ||
| function O(e) { | ||
| return e ? e.split(",").map((t) => t.trim()).filter(Boolean) : []; | ||
| } | ||
| function Le(e) { | ||
| return !e || e.length === 0 ? "" : e.join(", "); | ||
| } | ||
| function te(e) { | ||
| return e ? e.map((t) => t.trim()).filter(Boolean) : []; | ||
| } | ||
| function Re(e) { | ||
| return { | ||
| ...Pe, | ||
| ...e || {} | ||
| }; | ||
| } | ||
| function k(e) { | ||
| return e.getAttribute("contenteditable") === "false" || e.getAttribute("data-readonly") === "true"; | ||
| } | ||
| function ce(e) { | ||
| return e.closest("[data-editora-editor], .rte-editor, .editora-editor, editora-editor") || e; | ||
| } | ||
| function ue(e) { | ||
| if (!e) return !1; | ||
| const t = e.getAttribute("data-theme") || e.getAttribute("theme"); | ||
| return t && t.toLowerCase() === "dark" ? !0 : e.classList.contains("dark") || e.classList.contains("editora-theme-dark") || e.classList.contains("rte-theme-dark"); | ||
| } | ||
| function qe(e) { | ||
| const t = ce(e); | ||
| if (ue(t)) return !0; | ||
| const o = t.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark"); | ||
| return ue(o) ? !0 : ue(document.documentElement) || ue(document.body); | ||
| } | ||
| function fe(e) { | ||
| if (!e) return !1; | ||
| const t = e.getAttribute("data-theme") || e.getAttribute("theme"); | ||
| return t && t.toLowerCase() === "acme" ? !0 : e.classList.contains("editora-theme-acme") || e.classList.contains("rte-theme-acme"); | ||
| } | ||
| function Ke(e) { | ||
| const t = ce(e); | ||
| if (fe(t)) return !0; | ||
| const o = t.closest("[data-theme], [theme], .editora-theme-acme, .rte-theme-acme"); | ||
| return fe(o) ? !0 : fe(document.documentElement) || fe(document.body); | ||
| } | ||
| function Ie(e) { | ||
| return qe(e) ? "dark" : Ke(e) ? "acme" : "light"; | ||
| } | ||
| function he(e, t) { | ||
| const o = Ie(t); | ||
| e.classList.remove("rte-conditional-theme-dark", "rte-conditional-theme-acme"), o === "dark" ? e.classList.add("rte-conditional-theme-dark") : o === "acme" && e.classList.add("rte-conditional-theme-acme"); | ||
| } | ||
| function A(e, t = !0) { | ||
| if (e?.contentElement instanceof HTMLElement) return e.contentElement; | ||
| if (e?.editorElement instanceof HTMLElement) { | ||
| const n = e.editorElement; | ||
| if (n.matches(L)) return n; | ||
| const a = n.querySelector(L); | ||
| if (a instanceof HTMLElement) return a; | ||
| } | ||
| const o = window.getSelection(); | ||
| if (o && o.rangeCount > 0) { | ||
| const n = o.getRangeAt(0).startContainer, r = (n.nodeType === Node.ELEMENT_NODE ? n : n.parentElement)?.closest(L); | ||
| if (r) return r; | ||
| } | ||
| const i = document.activeElement; | ||
| if (i) { | ||
| if (i.matches(L)) return i; | ||
| const n = i.closest(L); | ||
| if (n) return n; | ||
| } | ||
| return g && g.isConnected ? g : t ? document.querySelector(L) : null; | ||
| } | ||
| function ke(e) { | ||
| const t = window.getSelection(); | ||
| if (!t || t.rangeCount === 0) return null; | ||
| const o = t.getRangeAt(0); | ||
| return e.contains(o.commonAncestorContainer) ? o.cloneRange() : null; | ||
| } | ||
| function xe(e, t) { | ||
| const o = window.getSelection(); | ||
| o && (o.removeAllRanges(), o.addRange(t), e.focus({ preventScroll: !0 })); | ||
| } | ||
| function Se(e) { | ||
| e.dispatchEvent(new Event("input", { bubbles: !0 })); | ||
| } | ||
| function Te(e, t) { | ||
| if (t === e.innerHTML) return; | ||
| const o = window.execEditorCommand || window.executeEditorCommand; | ||
| if (typeof o == "function") | ||
| try { | ||
| o("recordDomTransaction", e, t, e.innerHTML); | ||
| } catch { | ||
| } | ||
| } | ||
| function pe(e, t) { | ||
| const o = document.createRange(); | ||
| o.selectNodeContents(t), o.collapse(!1), xe(e, o); | ||
| } | ||
| function ye(e, t) { | ||
| if (t) | ||
| return t.split(".").filter(Boolean).reduce((o, i) => { | ||
| if (o != null && typeof o == "object") | ||
| return o[i]; | ||
| }, e); | ||
| } | ||
| function _e(e) { | ||
| const t = e.trim(); | ||
| if (t.startsWith('"') && t.endsWith('"') || t.startsWith("'") && t.endsWith("'")) | ||
| return t.slice(1, -1); | ||
| if (t === "true") return !0; | ||
| if (t === "false") return !1; | ||
| if (t === "null") return null; | ||
| const o = Number(t); | ||
| if (!Number.isNaN(o) && t !== "") return o; | ||
| if (t.startsWith("[") && t.endsWith("]") || t.startsWith("{") && t.endsWith("}")) | ||
| try { | ||
| return JSON.parse(t); | ||
| } catch { | ||
| return t; | ||
| } | ||
| return t; | ||
| } | ||
| function ze(e, t) { | ||
| const o = e.trim(); | ||
| if (!o) return !0; | ||
| if (o.startsWith("!")) { | ||
| const E = o.slice(1).trim(); | ||
| return !ye(t, E); | ||
| } | ||
| const i = o.match(/^([a-zA-Z_$][\w.$]*)\s*(==|!=|>=|<=|>|<|in|contains|~=)\s*(.+)$/); | ||
| if (!i) | ||
| return !!ye(t, o); | ||
| const [, n, a, r] = i, l = ye(t, n), d = _e(r); | ||
| switch (a) { | ||
| case "==": | ||
| return l == d; | ||
| case "!=": | ||
| return l != d; | ||
| case ">": | ||
| return Number(l) > Number(d); | ||
| case "<": | ||
| return Number(l) < Number(d); | ||
| case ">=": | ||
| return Number(l) >= Number(d); | ||
| case "<=": | ||
| return Number(l) <= Number(d); | ||
| case "in": | ||
| return Array.isArray(d) ? d.some((E) => E == l) : typeof d == "string" ? d.split(",").map((E) => E.trim()).includes(String(l)) : !1; | ||
| case "contains": | ||
| case "~=": | ||
| return Array.isArray(l) ? l.some((E) => String(E).toLowerCase() === String(d).toLowerCase()) : typeof l == "string" ? l.toLowerCase().includes(String(d).toLowerCase()) : !1; | ||
| default: | ||
| return !1; | ||
| } | ||
| } | ||
| function Fe() { | ||
| if (typeof document > "u" || document.getElementById(Ce)) return; | ||
| const e = document.createElement("style"); | ||
| e.id = Ce, e.textContent = ` | ||
| .rte-conditional-block { | ||
| border: 1px solid #dbe3ec; | ||
| border-radius: 8px; | ||
| margin: 10px 0; | ||
| background: #f8fafc; | ||
| overflow: hidden; | ||
| } | ||
| .rte-conditional-header, | ||
| .rte-conditional-else-label { | ||
| display: flex; | ||
| align-items: center; | ||
| gap: 8px; | ||
| background: #eef2f7; | ||
| border-bottom: 1px solid #dbe3ec; | ||
| padding: 8px 10px; | ||
| user-select: none; | ||
| } | ||
| .rte-conditional-else-label { | ||
| border-top: 1px solid #dbe3ec; | ||
| border-bottom: 1px solid #dbe3ec; | ||
| } | ||
| .rte-conditional-chip { | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| min-width: 34px; | ||
| height: 20px; | ||
| border-radius: 999px; | ||
| border: 1px solid #bfdbfe; | ||
| background: #dbeafe; | ||
| color: #1e3a8a; | ||
| font-size: 11px; | ||
| font-weight: 700; | ||
| letter-spacing: 0.03em; | ||
| text-transform: uppercase; | ||
| padding: 0 7px; | ||
| flex: 0 0 auto; | ||
| } | ||
| .rte-conditional-chip-else { | ||
| border-color: #fecaca; | ||
| background: #fee2e2; | ||
| color: #991b1b; | ||
| } | ||
| .rte-conditional-summary { | ||
| font-size: 12px; | ||
| color: #0f172a; | ||
| font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; | ||
| overflow: hidden; | ||
| text-overflow: ellipsis; | ||
| white-space: nowrap; | ||
| flex: 1; | ||
| } | ||
| .rte-conditional-meta { | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| white-space: nowrap; | ||
| flex: 0 0 auto; | ||
| } | ||
| .rte-conditional-body { | ||
| padding: 10px; | ||
| background: #ffffff; | ||
| min-height: 44px; | ||
| } | ||
| .rte-conditional-hidden { | ||
| display: none !important; | ||
| } | ||
| .rte-toolbar-group-items.conditional-content, | ||
| .editora-toolbar-group-items.conditional-content { | ||
| display: flex; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| background: #ffffff; | ||
| } | ||
| .rte-toolbar-group-items.conditional-content .rte-toolbar-item, | ||
| .editora-toolbar-group-items.conditional-content .editora-toolbar-item { | ||
| display: flex; | ||
| } | ||
| .rte-toolbar-group-items.conditional-content .rte-toolbar-button, | ||
| .editora-toolbar-group-items.conditional-content .editora-toolbar-button { | ||
| border: none; | ||
| border-right: 1px solid #cbd5e1; | ||
| border-radius: 0; | ||
| } | ||
| .rte-toolbar-group-items.conditional-content .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.conditional-content .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| .rte-toolbar-button[data-command="toggleConditionalPreview"].active, | ||
| .editora-toolbar-button[data-command="toggleConditionalPreview"].active { | ||
| background: #ccc; | ||
| } | ||
| .rte-conditional-block.rte-conditional-preview { | ||
| border-style: dashed; | ||
| } | ||
| .rte-conditional-block.rte-conditional-preview .rte-conditional-body[contenteditable="false"] { | ||
| cursor: default; | ||
| } | ||
| .${c} { | ||
| position: fixed; | ||
| inset: 0; | ||
| background: rgba(15, 23, 42, 0.5); | ||
| z-index: 2147483646; | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| padding: 20px; | ||
| } | ||
| .rte-conditional-dialog { | ||
| width: min(560px, 96vw); | ||
| max-height: min(88vh, 760px); | ||
| border: 1px solid #dbe3ec; | ||
| border-radius: 8px; | ||
| background: #ffffff; | ||
| box-shadow: 0 24px 50px rgba(15, 23, 42, 0.25); | ||
| display: flex; | ||
| flex-direction: column; | ||
| overflow: hidden; | ||
| } | ||
| .rte-conditional-dialog-header, | ||
| .rte-conditional-dialog-footer { | ||
| padding: 12px 14px; | ||
| border-bottom: 1px solid #e2e8f0; | ||
| background: #f8fafc; | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 10px; | ||
| } | ||
| .rte-conditional-dialog-footer { | ||
| border-top: 1px solid #e2e8f0; | ||
| border-bottom: none; | ||
| justify-content: flex-end; | ||
| } | ||
| .rte-conditional-dialog-title { | ||
| margin: 0; | ||
| font-size: 16px; | ||
| font-weight: 700; | ||
| color: #0f172a; | ||
| } | ||
| .rte-conditional-dialog-body { | ||
| padding: 14px; | ||
| overflow: auto; | ||
| display: grid; | ||
| grid-template-columns: 1fr; | ||
| gap: 12px; | ||
| } | ||
| .rte-conditional-field { | ||
| display: grid; | ||
| gap: 6px; | ||
| } | ||
| .rte-conditional-field label { | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| color: #334155; | ||
| } | ||
| .rte-conditional-field input[type="text"] { | ||
| width: 100%; | ||
| min-height: 36px; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| padding: 8px 10px; | ||
| font-size: 13px; | ||
| line-height: 1.4; | ||
| box-sizing: border-box; | ||
| color: #0f172a; | ||
| background: #ffffff; | ||
| } | ||
| .rte-conditional-field input[type="text"]:focus-visible, | ||
| .rte-conditional-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .rte-conditional-checkbox { | ||
| display: inline-flex; | ||
| align-items: center; | ||
| gap: 8px; | ||
| font-size: 13px; | ||
| color: #334155; | ||
| min-height: 36px; | ||
| } | ||
| .rte-conditional-help { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| color: #64748b; | ||
| } | ||
| .rte-conditional-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| min-height: 34px; | ||
| padding: 6px 12px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| font-size: 13px; | ||
| cursor: pointer; | ||
| } | ||
| .rte-conditional-btn-primary { | ||
| border-color: #2563eb; | ||
| background: #2563eb; | ||
| color: #ffffff; | ||
| } | ||
| .rte-conditional-btn-primary:hover { | ||
| background: #1d4ed8; | ||
| } | ||
| .${u} { | ||
| position: fixed; | ||
| z-index: 2147483645; | ||
| display: none; | ||
| align-items: center; | ||
| gap: 6px; | ||
| padding: 6px; | ||
| border-radius: 8px; | ||
| border: 1px solid #cbd5e1; | ||
| background: rgba(255, 255, 255, 0.98); | ||
| box-shadow: 0 14px 30px rgba(15, 23, 42, 0.2); | ||
| backdrop-filter: blur(6px); | ||
| } | ||
| .${u}.show { | ||
| display: inline-flex; | ||
| } | ||
| .${u} .rte-conditional-float-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| min-height: 30px; | ||
| min-width: 30px; | ||
| padding: 0 8px; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| gap: 6px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| cursor: pointer; | ||
| font-size: 12px; | ||
| line-height: 1; | ||
| } | ||
| .${u} .rte-conditional-float-btn:hover { | ||
| background: #f8fafc; | ||
| } | ||
| .${u} .rte-conditional-float-btn[data-action="delete"] { | ||
| border-color: #fecaca; | ||
| color: #991b1b; | ||
| background: #fff5f5; | ||
| } | ||
| .rte-conditional-preview-on ${H} { | ||
| border-width: 2px; | ||
| } | ||
| .rte-conditional-preview-on ${H} .rte-conditional-header { | ||
| background: #ecfeff; | ||
| border-color: #bae6fd; | ||
| } | ||
| ${b} .rte-conditional-block, | ||
| ${p} .rte-conditional-block, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-block { | ||
| background: #111827; | ||
| border-color: #334155; | ||
| } | ||
| ${b} .rte-conditional-header, | ||
| ${b} .rte-conditional-else-label, | ||
| ${p} .rte-conditional-header, | ||
| ${p} .rte-conditional-else-label, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-header, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-else-label { | ||
| background: #0f172a; | ||
| border-color: #334155; | ||
| } | ||
| ${b} .rte-conditional-summary, | ||
| ${p} .rte-conditional-summary, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-summary { | ||
| color: #e2e8f0; | ||
| } | ||
| ${b} .rte-conditional-meta, | ||
| ${p} .rte-conditional-meta, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-meta { | ||
| color: #94a3b8; | ||
| } | ||
| ${b} .rte-conditional-chip, | ||
| ${p} .rte-conditional-chip, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-chip { | ||
| background: #1e3a8a; | ||
| border-color: #3b82f6; | ||
| color: #dbeafe; | ||
| } | ||
| ${b} .rte-conditional-chip-else, | ||
| ${p} .rte-conditional-chip-else, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-chip-else { | ||
| background: #7f1d1d; | ||
| border-color: #ef4444; | ||
| color: #fee2e2; | ||
| } | ||
| ${b} .rte-conditional-body, | ||
| ${p} .rte-conditional-body, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-body { | ||
| background: #1f2937; | ||
| color: #e2e8f0; | ||
| } | ||
| ${b} .rte-conditional-dialog, | ||
| ${p} .rte-conditional-dialog, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-dialog { | ||
| background: #1f2937; | ||
| border-color: #334155; | ||
| } | ||
| ${b} .rte-conditional-dialog-header, | ||
| ${b} .rte-conditional-dialog-footer, | ||
| ${p} .rte-conditional-dialog-header, | ||
| ${p} .rte-conditional-dialog-footer, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-dialog-header, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-dialog-footer { | ||
| background: #111827; | ||
| border-color: #334155; | ||
| } | ||
| ${b} .rte-conditional-dialog-title, | ||
| ${b} .rte-conditional-field label, | ||
| ${b} .rte-conditional-checkbox, | ||
| ${p} .rte-conditional-dialog-title, | ||
| ${p} .rte-conditional-field label, | ||
| ${p} .rte-conditional-checkbox, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-dialog-title, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-field label, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-checkbox { | ||
| color: #e2e8f0; | ||
| } | ||
| ${b} .rte-conditional-help, | ||
| ${p} .rte-conditional-help, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-help { | ||
| color: #94a3b8; | ||
| } | ||
| ${b} .rte-conditional-field input[type="text"], | ||
| ${b} .rte-conditional-btn, | ||
| ${p} .rte-conditional-field input[type="text"], | ||
| ${p} .rte-conditional-btn, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-field input[type="text"], | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-btn { | ||
| background: #0f172a; | ||
| border-color: #475569; | ||
| color: #e2e8f0; | ||
| } | ||
| ${b} .rte-conditional-btn-primary, | ||
| ${p} .rte-conditional-btn-primary, | ||
| .${c}.rte-conditional-theme-dark .rte-conditional-btn-primary { | ||
| border-color: #3b82f6; | ||
| background: #2563eb; | ||
| color: #ffffff; | ||
| } | ||
| ${b} .rte-toolbar-group-items.conditional-content, | ||
| .${c}.rte-conditional-theme-dark .rte-toolbar-group-items.conditional-content, | ||
| ${p} .rte-toolbar-group-items.conditional-content, | ||
| ${b} .editora-toolbar-group-items.conditional-content { | ||
| border-color: #566275; | ||
| } | ||
| ${b} .rte-toolbar-group-items.conditional-content .rte-toolbar-button, | ||
| ${p} .rte-toolbar-group-items.conditional-content .rte-toolbar-button, | ||
| ${b} .editora-toolbar-group-items.conditional-content .editora-toolbar-button { | ||
| border-right-color: #566275; | ||
| } | ||
| ${b} .${u}, | ||
| .${c}.rte-conditional-theme-dark .${u}, | ||
| .${u}.rte-conditional-theme-dark { | ||
| background: rgba(17, 24, 39, 0.98); | ||
| border-color: #334155; | ||
| box-shadow: 0 14px 30px rgba(2, 6, 23, 0.5); | ||
| } | ||
| ${b} .${u} .rte-conditional-float-btn, | ||
| .${c}.rte-conditional-theme-dark .${u} .rte-conditional-float-btn, | ||
| .${u}.rte-conditional-theme-dark .rte-conditional-float-btn { | ||
| background: #0f172a; | ||
| border-color: #475569; | ||
| color: #e2e8f0; | ||
| } | ||
| ${b} .${u} .rte-conditional-float-btn[data-action="delete"], | ||
| .${c}.rte-conditional-theme-dark .${u} .rte-conditional-float-btn[data-action="delete"], | ||
| .${u}.rte-conditional-theme-dark .rte-conditional-float-btn[data-action="delete"] { | ||
| border-color: #ef4444; | ||
| color: #fecaca; | ||
| background: rgba(127, 29, 29, 0.45); | ||
| } | ||
| ${f} .rte-conditional-block, | ||
| ${h} .rte-conditional-block, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-block { | ||
| background: #f8fbff; | ||
| border-color: #cbd8e8; | ||
| } | ||
| ${f} .rte-conditional-header, | ||
| ${f} .rte-conditional-else-label, | ||
| ${h} .rte-conditional-header, | ||
| ${h} .rte-conditional-else-label, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-header, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-else-label { | ||
| background: linear-gradient(180deg, #eef4fb 0%, #e6eef8 100%); | ||
| border-color: #cbd8e8; | ||
| } | ||
| ${f} .rte-conditional-summary, | ||
| ${h} .rte-conditional-summary, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-summary { | ||
| color: #0f172a; | ||
| } | ||
| ${f} .rte-conditional-meta, | ||
| ${h} .rte-conditional-meta, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-meta { | ||
| color: #587089; | ||
| } | ||
| ${f} .rte-conditional-chip, | ||
| ${h} .rte-conditional-chip, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-chip { | ||
| background: #d9f5ee; | ||
| border-color: #66c6b3; | ||
| color: #0f4f4a; | ||
| } | ||
| ${f} .rte-conditional-chip-else, | ||
| ${h} .rte-conditional-chip-else, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-chip-else { | ||
| background: #fde8ea; | ||
| border-color: #f1a7b2; | ||
| color: #8b1f2f; | ||
| } | ||
| ${f} .rte-conditional-body, | ||
| ${h} .rte-conditional-body, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-body { | ||
| background: #fcfeff; | ||
| color: #0f172a; | ||
| } | ||
| ${f} .rte-conditional-dialog, | ||
| ${h} .rte-conditional-dialog, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-dialog { | ||
| background: #ffffff; | ||
| border-color: #cbd8e8; | ||
| box-shadow: 0 20px 44px rgba(15, 23, 42, 0.18); | ||
| } | ||
| ${f} .rte-conditional-dialog-header, | ||
| ${f} .rte-conditional-dialog-footer, | ||
| ${h} .rte-conditional-dialog-header, | ||
| ${h} .rte-conditional-dialog-footer, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-dialog-header, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-dialog-footer { | ||
| background: #f3f8fd; | ||
| border-color: #d8e4f1; | ||
| } | ||
| ${f} .rte-conditional-dialog-title, | ||
| ${f} .rte-conditional-field label, | ||
| ${f} .rte-conditional-checkbox, | ||
| ${h} .rte-conditional-dialog-title, | ||
| ${h} .rte-conditional-field label, | ||
| ${h} .rte-conditional-checkbox, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-dialog-title, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-field label, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-checkbox { | ||
| color: #1f334a; | ||
| } | ||
| ${f} .rte-conditional-help, | ||
| ${h} .rte-conditional-help, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-help { | ||
| color: #5f738d; | ||
| } | ||
| ${f} .rte-conditional-field input[type="text"], | ||
| ${f} .rte-conditional-btn, | ||
| ${h} .rte-conditional-field input[type="text"], | ||
| ${h} .rte-conditional-btn, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-field input[type="text"], | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-btn { | ||
| background: #ffffff; | ||
| border-color: #bfd0e2; | ||
| color: #0f172a; | ||
| } | ||
| ${f} .rte-conditional-btn-primary, | ||
| ${h} .rte-conditional-btn-primary, | ||
| .${c}.rte-conditional-theme-acme .rte-conditional-btn-primary { | ||
| border-color: #0f766e; | ||
| background: #0f766e; | ||
| color: #ffffff; | ||
| } | ||
| ${f} .rte-toolbar-group-items.conditional-content, | ||
| .${c}.rte-conditional-theme-acme .rte-toolbar-group-items.conditional-content, | ||
| ${h} .rte-toolbar-group-items.conditional-content, | ||
| ${f} .editora-toolbar-group-items.conditional-content { | ||
| border-color: #bfd0e2; | ||
| } | ||
| ${f} .rte-toolbar-group-items.conditional-content .rte-toolbar-button, | ||
| ${h} .rte-toolbar-group-items.conditional-content .rte-toolbar-button, | ||
| ${f} .editora-toolbar-group-items.conditional-content .editora-toolbar-button { | ||
| border-right-color: #bfd0e2; | ||
| } | ||
| ${f} .${u}, | ||
| .${c}.rte-conditional-theme-acme .${u}, | ||
| .${u}.rte-conditional-theme-acme { | ||
| background: rgba(255, 255, 255, 0.98); | ||
| border-color: #bfd0e2; | ||
| box-shadow: 0 14px 28px rgba(15, 23, 42, 0.16); | ||
| } | ||
| ${f} .${u} .rte-conditional-float-btn, | ||
| .${c}.rte-conditional-theme-acme .${u} .rte-conditional-float-btn, | ||
| .${u}.rte-conditional-theme-acme .rte-conditional-float-btn { | ||
| background: #ffffff; | ||
| border-color: #bfd0e2; | ||
| color: #1f334a; | ||
| } | ||
| ${f} .${u} .rte-conditional-float-btn:hover, | ||
| .${c}.rte-conditional-theme-acme .${u} .rte-conditional-float-btn:hover, | ||
| .${u}.rte-conditional-theme-acme .rte-conditional-float-btn:hover { | ||
| background: #eef7f5; | ||
| color: #0f4f4a; | ||
| } | ||
| ${f} .${u} .rte-conditional-float-btn[data-action="delete"], | ||
| .${c}.rte-conditional-theme-acme .${u} .rte-conditional-float-btn[data-action="delete"], | ||
| .${u}.rte-conditional-theme-acme .rte-conditional-float-btn[data-action="delete"] { | ||
| border-color: #f1a7b2; | ||
| color: #8b1f2f; | ||
| background: #fff4f6; | ||
| } | ||
| `, document.head.appendChild(e); | ||
| } | ||
| function je(e) { | ||
| return { | ||
| defaultCondition: e.defaultCondition || "", | ||
| defaultAudience: te(e.defaultAudience || []), | ||
| defaultLocale: te(e.defaultLocale || []), | ||
| enableElseByDefault: e.enableElseByDefault === !0, | ||
| labels: Re(e.labels), | ||
| context: e.context, | ||
| getContext: e.getContext, | ||
| currentAudience: e.currentAudience, | ||
| currentLocale: e.currentLocale, | ||
| evaluateCondition: e.evaluateCondition || ze | ||
| }; | ||
| } | ||
| function Be() { | ||
| le && (le.cleanup(), le = null); | ||
| } | ||
| function Ve(e) { | ||
| return e ? e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement : null; | ||
| } | ||
| function oe(e, t) { | ||
| e.setAttribute("contenteditable", "false"), e.setAttribute("spellcheck", "false"); | ||
| const o = e.querySelector(".rte-conditional-header"); | ||
| o && (o.setAttribute("contenteditable", "false"), o.setAttribute("tabindex", "0"), o.setAttribute("role", "button"), o.setAttribute("aria-label", "Edit conditional rule")); | ||
| const i = e.querySelector(".rte-conditional-else-label"); | ||
| i && i.setAttribute("contenteditable", "false"), Ge(e, !t); | ||
| } | ||
| function We(e) { | ||
| const t = e.querySelector('.rte-conditional-body[data-slot="if"]'); | ||
| if (!t) return; | ||
| const o = /* @__PURE__ */ new Set(), i = e.querySelector(".rte-conditional-header"), n = e.querySelector(".rte-conditional-else-label"), a = e.querySelector('.rte-conditional-body[data-slot="else"]'); | ||
| i && o.add(i), o.add(t), n && o.add(n), a && o.add(a), Array.from(e.childNodes).forEach((l) => { | ||
| if (!(l instanceof HTMLElement && o.has(l))) { | ||
| if (l.nodeType === Node.TEXT_NODE && !(l.textContent || "").trim()) { | ||
| l.remove(); | ||
| return; | ||
| } | ||
| t.appendChild(l); | ||
| } | ||
| }); | ||
| } | ||
| function W(e) { | ||
| const t = window.getSelection(); | ||
| if (t && t.rangeCount > 0) { | ||
| const n = t.getRangeAt(0).startContainer, r = (n.nodeType === Node.ELEMENT_NODE ? n : n.parentElement)?.closest(H); | ||
| if (r && e.contains(r)) return r; | ||
| } | ||
| const i = document.activeElement?.closest(H); | ||
| return i && e.contains(i) ? i : null; | ||
| } | ||
| function Ee(e, t) { | ||
| let o = e.querySelector(".rte-conditional-else-label"), i = e.querySelector('.rte-conditional-body[data-slot="else"]'); | ||
| o || (o = document.createElement("div"), o.className = "rte-conditional-else-label", o.setAttribute("contenteditable", "false"), o.innerHTML = ` | ||
| <span class="rte-conditional-chip rte-conditional-chip-else">${y(t.blockElseLabel)}</span> | ||
| <span class="rte-conditional-summary">Else branch</span> | ||
| `, e.appendChild(o)), i || (i = document.createElement("div"), i.className = "rte-conditional-body rte-conditional-else-body", i.setAttribute("data-slot", "else"), i.innerHTML = "<p><br></p>", e.appendChild(i)); | ||
| } | ||
| function Ze(e, t) { | ||
| e.setAttribute("data-has-else", t ? "true" : "false"); | ||
| const o = e.querySelector(".rte-conditional-else-label"), i = e.querySelector('.rte-conditional-body[data-slot="else"]'); | ||
| o && o.classList.toggle("rte-conditional-hidden", !t), i && i.classList.toggle("rte-conditional-hidden", !t); | ||
| } | ||
| function Ge(e, t) { | ||
| Array.from(e.querySelectorAll(".rte-conditional-body")).forEach((i) => { | ||
| i.setAttribute("contenteditable", t ? "true" : "false"); | ||
| }), e.setAttribute("contenteditable", "false"); | ||
| } | ||
| function ve(e, t) { | ||
| const o = e.getAttribute("data-condition") || "", i = O(e.getAttribute("data-audience")), n = O(e.getAttribute("data-locale")); | ||
| let a = e.querySelector(".rte-conditional-header"); | ||
| a || (a = document.createElement("div"), a.className = "rte-conditional-header", e.prepend(a)), a.setAttribute("contenteditable", "false"), a.setAttribute("tabindex", "0"), a.setAttribute("role", "button"), a.setAttribute("aria-label", "Edit conditional rule"); | ||
| const r = o || "(always true)", l = i.length > 0 ? i.join(", ") : t.allAudiencesText, d = n.length > 0 ? n.join(", ") : t.allLocalesText; | ||
| if (a.innerHTML = ` | ||
| <span class="rte-conditional-chip">${y(t.blockIfLabel)}</span> | ||
| <span class="rte-conditional-summary">${y(r)}</span> | ||
| <span class="rte-conditional-meta">${y(l)} · ${y(d)}</span> | ||
| `, !e.querySelector('.rte-conditional-body[data-slot="if"]')) { | ||
| const v = document.createElement("div"); | ||
| v.className = "rte-conditional-body", v.setAttribute("data-slot", "if"), v.innerHTML = "<p><br></p>", e.insertBefore(v, e.children[1] || null); | ||
| } | ||
| const m = e.getAttribute("data-has-else") === "true"; | ||
| m && Ee(e, t), We(e), Ze(e, m); | ||
| } | ||
| function Me(e, t) { | ||
| const o = document.createElement("section"); | ||
| o.className = "rte-conditional-block", o.setAttribute("data-conditional-content", "true"), o.setAttribute("data-condition", (e.condition || "").trim()), o.setAttribute("data-audience", te(e.audience).join(",")), o.setAttribute("data-locale", te(e.locale).join(",")), o.setAttribute("data-has-else", e.hasElse ? "true" : "false"), o.setAttribute("role", "group"), o.setAttribute("aria-label", "Conditional content block"), o.setAttribute("contenteditable", "false"), o.setAttribute("spellcheck", "false"); | ||
| const i = document.createElement("div"); | ||
| i.className = "rte-conditional-header", i.setAttribute("contenteditable", "false"); | ||
| const n = document.createElement("div"); | ||
| return n.className = "rte-conditional-body", n.setAttribute("data-slot", "if"), n.innerHTML = "<p><br></p>", o.appendChild(i), o.appendChild(n), e.hasElse && Ee(o, t), ve(o, t), oe(o, !1), o; | ||
| } | ||
| function Ue(e, t) { | ||
| if (t) | ||
| try { | ||
| if (!e.isConnected) return; | ||
| const o = e.contains(t.startContainer), i = e.contains(t.endContainer); | ||
| if (!o || !i) return; | ||
| xe(e, t); | ||
| } catch { | ||
| } | ||
| } | ||
| function Ye(e) { | ||
| return (e.textContent || "").replace(/\u200B/g, "").trim().length > 0 ? !0 : e.querySelector("img, video, table, iframe, hr, pre, blockquote, ul, ol") !== null; | ||
| } | ||
| function Ne(e, t, o) { | ||
| let i = null; | ||
| i || (i = ke(e)), i || (i = document.createRange(), i.selectNodeContents(e), i.collapse(!1)); | ||
| let n = null; | ||
| i.collapsed || (n = i.extractContents()), i.insertNode(t); | ||
| const a = t.querySelector('.rte-conditional-body[data-slot="if"]'); | ||
| a && n && Ye(n) && (a.innerHTML = "", a.appendChild(n)), a ? pe(e, a) : pe(e, t), e.normalize(); | ||
| } | ||
| function Je(e) { | ||
| return { | ||
| condition: e.getAttribute("data-condition") || "", | ||
| audience: O(e.getAttribute("data-audience")), | ||
| locale: O(e.getAttribute("data-locale")), | ||
| hasElse: e.getAttribute("data-has-else") === "true" | ||
| }; | ||
| } | ||
| function Xe(e, t, o) { | ||
| e.setAttribute("data-condition", (t.condition || "").trim()), e.setAttribute("data-audience", te(t.audience).join(",")), e.setAttribute("data-locale", te(t.locale).join(",")), e.setAttribute("data-has-else", t.hasElse ? "true" : "false"), t.hasElse && Ee(e, o), ve(e, o), oe(e, e.classList.contains("rte-conditional-preview")); | ||
| } | ||
| function ne(e, t) { | ||
| he(e, e); | ||
| const o = Array.from(e.querySelectorAll(H)), i = w.get(e) === !0; | ||
| return o.forEach((n) => { | ||
| n.classList.add("rte-conditional-block"), n.setAttribute("data-conditional-content", "true"), n.hasAttribute("data-condition") || n.setAttribute("data-condition", ""), n.hasAttribute("data-audience") || n.setAttribute("data-audience", ""), n.hasAttribute("data-locale") || n.setAttribute("data-locale", ""), n.hasAttribute("data-has-else") || n.setAttribute("data-has-else", "false"), n.setAttribute("role", "group"), n.setAttribute("aria-label", "Conditional content block"), n.setAttribute("contenteditable", "false"), n.setAttribute("spellcheck", "false"), ve(n, t), oe(n, i); | ||
| }), o; | ||
| } | ||
| async function Qe(e, t) { | ||
| const o = $e.get(e); | ||
| if (o) | ||
| return o; | ||
| if (typeof t.getContext == "function") | ||
| try { | ||
| const i = ce(e), n = await Promise.resolve(t.getContext({ editor: e, editorRoot: i })); | ||
| if (n && typeof n == "object") | ||
| return n; | ||
| } catch { | ||
| return {}; | ||
| } | ||
| if (typeof t.context == "function") | ||
| try { | ||
| const i = t.context(); | ||
| if (i && typeof i == "object") | ||
| return i; | ||
| } catch { | ||
| return {}; | ||
| } | ||
| return t.context && typeof t.context == "object" ? t.context : {}; | ||
| } | ||
| function be(e) { | ||
| return Array.isArray(e) ? e.map((t) => t.trim().toLowerCase()).filter(Boolean) : typeof e == "string" ? e.split(",").map((t) => t.trim().toLowerCase()).filter(Boolean) : []; | ||
| } | ||
| function Ae(e, t) { | ||
| return e.length === 0 || e.includes("all") ? !0 : t.length === 0 ? !1 : e.some((o) => t.includes(o)); | ||
| } | ||
| async function Z(e, t, o) { | ||
| const i = t.labels, n = ne(e, i); | ||
| if (w.set(e, o), De(e, o), ce(e).classList.toggle("rte-conditional-preview-on", o), !o) { | ||
| n.forEach(($) => { | ||
| $.classList.remove("rte-conditional-preview"), oe($, !1); | ||
| const P = $.querySelector('.rte-conditional-body[data-slot="if"]'), T = $.querySelector('.rte-conditional-body[data-slot="else"]'), F = $.querySelector(".rte-conditional-else-label"), B = $.getAttribute("data-has-else") === "true"; | ||
| P && (P.classList.remove("rte-conditional-hidden"), P.removeAttribute("aria-hidden")), T && (T.classList.toggle("rte-conditional-hidden", !B), T.setAttribute("aria-hidden", B ? "false" : "true")), F && F.classList.toggle("rte-conditional-hidden", !B); | ||
| }); | ||
| return; | ||
| } | ||
| const r = await Qe(e, t), l = be(t.currentAudience), d = be(t.currentLocale), E = be( | ||
| r.audience ?? r.user?.audience | ||
| ), m = be( | ||
| r.locale ?? r.user?.locale | ||
| ), v = l.length > 0 ? l : E, S = d.length > 0 ? d : m; | ||
| n.forEach(($) => { | ||
| const P = $.getAttribute("data-condition") || "", T = O($.getAttribute("data-audience")).map((s) => s.toLowerCase()), F = O($.getAttribute("data-locale")).map((s) => s.toLowerCase()), B = $.getAttribute("data-has-else") === "true", ge = t.evaluateCondition(P, r), M = Ae(T, v), de = Ae(F, S), R = ge && M && de, ie = $.querySelector('.rte-conditional-body[data-slot="if"]'), j = $.querySelector('.rte-conditional-body[data-slot="else"]'), ae = $.querySelector(".rte-conditional-else-label"); | ||
| if ($.classList.add("rte-conditional-preview"), oe($, !0), ie && (ie.classList.toggle("rte-conditional-hidden", !R), ie.setAttribute("aria-hidden", R ? "false" : "true")), j) { | ||
| const s = B && !R; | ||
| j.classList.toggle("rte-conditional-hidden", !s), j.setAttribute("aria-hidden", s ? "false" : "true"); | ||
| } | ||
| if (ae) { | ||
| const s = B && !R; | ||
| ae.classList.toggle("rte-conditional-hidden", !s); | ||
| } | ||
| }); | ||
| } | ||
| function De(e, t) { | ||
| const o = ce(e); | ||
| Array.from( | ||
| o.querySelectorAll('[data-command="toggleConditionalPreview"], [data-command="conditionalPreview"]') | ||
| ).forEach((n) => { | ||
| n.setAttribute("data-active", t ? "true" : "false"), n.classList.toggle("active", t), n.setAttribute("aria-pressed", t ? "true" : "false"); | ||
| }); | ||
| } | ||
| function et(e) { | ||
| const t = _.get(e); | ||
| if (t && t.isConnected) return t; | ||
| const o = document.createElement("div"); | ||
| return o.className = u, o.setAttribute("role", "toolbar"), o.setAttribute("aria-label", "Conditional block actions"), o.innerHTML = ` | ||
| <button type="button" class="rte-conditional-float-btn" data-action="edit" title="Edit Condition" aria-label="Edit Condition"> | ||
| <svg width="16" height="16" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M4 17.3V20h2.7l9.7-9.7-2.7-2.7L4 17.3Zm14.7-9.4a1 1 0 0 0 0-1.4l-1.2-1.2a1 1 0 0 0-1.4 0l-1.1 1.1 2.7 2.7 1-1.2Z" fill="currentColor"></path></svg> | ||
| </button> | ||
| <button type="button" class="rte-conditional-float-btn" data-action="delete" title="Delete Block" aria-label="Delete Block"> | ||
| <svg width="16" height="16" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M8 4h8l1 2h4v2H3V6h4l1-2Zm1 6h2v8H9v-8Zm4 0h2v8h-2v-8Z" fill="currentColor"></path></svg> | ||
| </button> | ||
| `, o.addEventListener("mousedown", (i) => { | ||
| i.preventDefault(); | ||
| }), o.addEventListener("click", (i) => { | ||
| const a = i.target?.closest("[data-action]")?.getAttribute("data-action"); | ||
| if (!a) return; | ||
| const r = x.get(e) || ee; | ||
| if (!r) return; | ||
| const l = z.get(e); | ||
| if (!(!l || !e.contains(l))) { | ||
| if (a === "edit") { | ||
| C(e, r, "edit", void 0, l); | ||
| return; | ||
| } | ||
| a === "delete" && (Oe(e, l), z.set(e, null), I(e)); | ||
| } | ||
| }), document.body.appendChild(o), _.set(e, o), o; | ||
| } | ||
| function I(e) { | ||
| const t = _.get(e); | ||
| t && t.classList.remove("show"); | ||
| } | ||
| function He(e, t) { | ||
| const o = t.getBoundingClientRect(); | ||
| e.style.left = "0px", e.style.top = "0px", e.classList.add("show"); | ||
| const i = e.getBoundingClientRect(), n = 8, a = window.innerWidth, r = window.innerHeight; | ||
| let l = o.top - i.height - n; | ||
| l < n && (l = o.bottom + n), l = Math.min(l, r - i.height - n); | ||
| let d = o.right - i.width; | ||
| d = Math.max(n, Math.min(d, a - i.width - n)), e.style.left = `${d}px`, e.style.top = `${l}px`; | ||
| } | ||
| function me(e, t) { | ||
| const o = et(e); | ||
| he(o, e), z.set(e, t), He(o, t); | ||
| } | ||
| function D(e) { | ||
| const t = x.get(e) || ee; | ||
| if (!t) return; | ||
| const o = W(e); | ||
| if (!o || !e.contains(o) || k(e)) { | ||
| z.set(e, null), I(e); | ||
| return; | ||
| } | ||
| ne(e, t.labels), me(e, o); | ||
| } | ||
| function tt() { | ||
| _.forEach((e, t) => { | ||
| if (!t.isConnected || !e.isConnected) { | ||
| e.remove(), _.delete(t), z.delete(t); | ||
| return; | ||
| } | ||
| if (!e.classList.contains("show")) return; | ||
| he(e, t); | ||
| const o = z.get(t); | ||
| if (!o || !t.contains(o)) { | ||
| I(t); | ||
| return; | ||
| } | ||
| He(e, o); | ||
| }); | ||
| } | ||
| function Oe(e, t) { | ||
| if (!e.contains(t)) return !1; | ||
| const o = e.innerHTML, i = t.parentNode, n = t.nextSibling; | ||
| t.remove(), i === e && e.innerHTML.trim() === "" && (e.innerHTML = "<p><br></p>"); | ||
| const a = document.createRange(); | ||
| return n && e.contains(n) ? a.setStartBefore(n) : (a.selectNodeContents(e), a.collapse(!1)), a.collapse(!0), xe(e, a), Se(e), Te(e, o), !0; | ||
| } | ||
| function we(e, t, o) { | ||
| const i = e.cloneRange(), n = document.createRange(); | ||
| return n.selectNodeContents(t), n.collapse(o === "start"), i.startContainer === n.startContainer && i.startOffset === n.startOffset && i.endContainer === n.endContainer && i.endOffset === n.endOffset; | ||
| } | ||
| function C(e, t, o, i, n) { | ||
| Be(); | ||
| const a = t.labels, r = o === "insert" ? ke(e) : null, l = document.createElement("div"); | ||
| l.className = c, he(l, e); | ||
| const d = document.createElement("section"); | ||
| d.className = "rte-conditional-dialog", d.setAttribute("role", "dialog"), d.setAttribute("aria-modal", "true"), d.setAttribute("aria-labelledby", "rte-conditional-dialog-title"); | ||
| const E = n ? Je(n) : void 0, m = i || E || {}, v = m.condition ?? t.defaultCondition, S = m.audience ?? t.defaultAudience, $ = m.locale ?? t.defaultLocale, P = m.hasElse ?? t.enableElseByDefault; | ||
| d.innerHTML = ` | ||
| <header class="rte-conditional-dialog-header"> | ||
| <h2 id="rte-conditional-dialog-title" class="rte-conditional-dialog-title">${y( | ||
| o === "edit" ? a.dialogTitleEdit : a.dialogTitleInsert | ||
| )}</h2> | ||
| <button type="button" class="rte-conditional-btn" data-action="cancel" aria-label="${y(a.cancelText)}">✕</button> | ||
| </header> | ||
| <div class="rte-conditional-dialog-body"> | ||
| <div class="rte-conditional-field"> | ||
| <label for="rte-conditional-condition">${y(a.conditionLabel)}</label> | ||
| <input id="rte-conditional-condition" class="rte-conditional-input-condition" type="text" value="${y( | ||
| v || "" | ||
| )}" placeholder="${y(a.conditionPlaceholder)}" /> | ||
| </div> | ||
| <div class="rte-conditional-field"> | ||
| <label for="rte-conditional-audience">${y(a.audienceLabel)}</label> | ||
| <input id="rte-conditional-audience" class="rte-conditional-input-audience" type="text" value="${y( | ||
| Le(S) | ||
| )}" placeholder="${y(a.audiencePlaceholder)}" /> | ||
| </div> | ||
| <div class="rte-conditional-field"> | ||
| <label for="rte-conditional-locale">${y(a.localeLabel)}</label> | ||
| <input id="rte-conditional-locale" class="rte-conditional-input-locale" type="text" value="${y( | ||
| Le($) | ||
| )}" placeholder="${y(a.localePlaceholder)}" /> | ||
| </div> | ||
| <label class="rte-conditional-checkbox"> | ||
| <input class="rte-conditional-input-else" type="checkbox" ${P ? "checked" : ""} /> | ||
| <span>${y(a.elseLabel)}</span> | ||
| </label> | ||
| <p class="rte-conditional-help">Example condition: <code>user.role == "admin"</code>, <code>locale == "en-US"</code>, <code>!feature.beta</code></p> | ||
| </div> | ||
| <footer class="rte-conditional-dialog-footer"> | ||
| <button type="button" class="rte-conditional-btn" data-action="cancel">${y(a.cancelText)}</button> | ||
| <button type="button" class="rte-conditional-btn rte-conditional-btn-primary" data-action="save">${y(a.saveText)}</button> | ||
| </footer> | ||
| `, l.appendChild(d), document.body.appendChild(l); | ||
| const T = d.querySelector(".rte-conditional-input-condition"), F = d.querySelector(".rte-conditional-input-audience"), B = d.querySelector(".rte-conditional-input-locale"), ge = d.querySelector(".rte-conditional-input-else"), M = () => { | ||
| l.removeEventListener("click", R), l.removeEventListener("keydown", ae, !0), document.removeEventListener("keydown", de, !0), l.parentNode && l.parentNode.removeChild(l), le = null, e.focus({ preventScroll: !0 }), D(e); | ||
| }, de = (s) => { | ||
| s.key === "Escape" && (s.preventDefault(), s.stopPropagation(), M()); | ||
| }, R = (s) => { | ||
| s.target === l && M(); | ||
| }, ie = (s) => { | ||
| if (s.key !== "Tab") return; | ||
| const q = Array.from( | ||
| d.querySelectorAll('button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])') | ||
| ); | ||
| if (q.length === 0) return; | ||
| const V = q[0], K = q[q.length - 1], re = document.activeElement; | ||
| if (s.shiftKey && re === V) { | ||
| s.preventDefault(), K.focus(); | ||
| return; | ||
| } | ||
| !s.shiftKey && re === K && (s.preventDefault(), V.focus()); | ||
| }, j = async () => { | ||
| const s = { | ||
| condition: T?.value?.trim() || "", | ||
| audience: O(F?.value), | ||
| locale: O(B?.value), | ||
| hasElse: ge?.checked || !1 | ||
| }, q = e.innerHTML; | ||
| if (n) | ||
| Xe(n, s, a), oe(n, w.get(e) === !0); | ||
| else { | ||
| Ue(e, r); | ||
| const K = Me(s, a); | ||
| try { | ||
| Ne(e, K); | ||
| } catch { | ||
| e.appendChild(K); | ||
| const re = K.querySelector('.rte-conditional-body[data-slot="if"]'); | ||
| re ? pe(e, re) : pe(e, K); | ||
| } | ||
| } | ||
| w.get(e) === !0 && await Z(e, t, !0), Se(e), Te(e, q), D(e), M(); | ||
| }, ae = (s) => { | ||
| if (s.key === "Escape") { | ||
| s.preventDefault(), M(); | ||
| return; | ||
| } | ||
| ie(s), s.key === "Enter" && !s.shiftKey && s.target instanceof HTMLInputElement && (s.preventDefault(), j()); | ||
| }; | ||
| d.addEventListener("click", (s) => { | ||
| const V = s.target.getAttribute("data-action"); | ||
| if (V === "cancel") { | ||
| M(); | ||
| return; | ||
| } | ||
| V === "save" && j(); | ||
| }), l.addEventListener("click", R), l.addEventListener("keydown", ae, !0), document.addEventListener("keydown", de, !0), le = { cleanup: M }, T?.focus(); | ||
| } | ||
| function ot(e) { | ||
| const t = e.metaKey || e.ctrlKey, i = (typeof e.key == "string" ? e.key : "").toLowerCase(), n = typeof e.code == "string" ? e.code.toLowerCase() : "", a = t && e.altKey && e.shiftKey && (i === "c" || n === "keyc"), r = !e.metaKey && !e.ctrlKey && !e.altKey && !e.shiftKey && (i === "f9" || n === "f9"); | ||
| return a || r; | ||
| } | ||
| function nt(e) { | ||
| const t = e.metaKey || e.ctrlKey, i = (typeof e.key == "string" ? e.key : "").toLowerCase(), n = typeof e.code == "string" ? e.code.toLowerCase() : "", a = t && e.altKey && e.shiftKey && (i === "p" || n === "keyp"), r = !e.metaKey && !e.ctrlKey && !e.altKey && !e.shiftKey && (i === "f10" || n === "f10"); | ||
| return a || r; | ||
| } | ||
| function it(e) { | ||
| ee = e, U || (U = (t) => { | ||
| const i = t.target?.closest(L); | ||
| if (!i) return; | ||
| g = i, x.has(i) || x.set(i, e); | ||
| const n = x.get(i) || e; | ||
| ne(i, n.labels), De(i, w.get(i) === !0), D(i); | ||
| }, document.addEventListener("focusin", U, !0)), G || (G = (t) => { | ||
| if (document.querySelector(`.${c}`)) return; | ||
| const i = t.target; | ||
| if (!!i?.closest("input, textarea, select")) return; | ||
| const r = i?.closest(L) || A(void 0, !1) || g; | ||
| if (!r || k(r)) return; | ||
| const l = x.get(r) || ee || e, d = document.activeElement, E = i?.closest(".rte-conditional-header") || d?.closest(".rte-conditional-header"); | ||
| if (E && (t.key === "Enter" || t.key === " ")) { | ||
| const m = E.closest(H); | ||
| if (m && r.contains(m)) { | ||
| t.preventDefault(), t.stopPropagation(), C(r, l, "edit", void 0, m); | ||
| return; | ||
| } | ||
| } | ||
| if (ot(t)) { | ||
| t.preventDefault(), t.stopPropagation(); | ||
| const m = W(r); | ||
| m ? C(r, l, "edit", void 0, m) : C(r, l, "insert"); | ||
| return; | ||
| } | ||
| if (nt(t)) { | ||
| t.preventDefault(), t.stopPropagation(); | ||
| const m = w.get(r) !== !0; | ||
| Z(r, l, m), D(r); | ||
| return; | ||
| } | ||
| if ((t.key === "Backspace" || t.key === "Delete") && !t.altKey && !t.ctrlKey && !t.metaKey) { | ||
| const m = window.getSelection(); | ||
| if (!m || m.rangeCount === 0) return; | ||
| const v = m.getRangeAt(0); | ||
| if (!v.collapsed || !r.contains(v.commonAncestorContainer)) return; | ||
| const S = Ve(v.startContainer)?.closest(".rte-conditional-body"); | ||
| if (!S || !r.contains(S)) return; | ||
| if (t.key === "Backspace" && we(v, S, "start")) { | ||
| t.preventDefault(); | ||
| return; | ||
| } | ||
| if (t.key === "Delete" && we(v, S, "end")) { | ||
| t.preventDefault(); | ||
| return; | ||
| } | ||
| } | ||
| }, document.addEventListener("keydown", G, !0)), J || (J = (t) => { | ||
| const o = t.target; | ||
| if (!o || o.closest(`.${u}`)) return; | ||
| const i = o.closest(L); | ||
| if (!i) { | ||
| g && I(g); | ||
| return; | ||
| } | ||
| if (k(i)) return; | ||
| g = i, x.has(i) || x.set(i, e); | ||
| const n = o.closest(H); | ||
| if (!n) { | ||
| I(i); | ||
| return; | ||
| } | ||
| requestAnimationFrame(() => { | ||
| !i.isConnected || !i.contains(n) || me(i, n); | ||
| }); | ||
| }, document.addEventListener("mousedown", J, !0)), Y || (Y = (t) => { | ||
| const o = t.target; | ||
| if (!o || o.closest(`.${u}`)) return; | ||
| const i = o.closest(L); | ||
| if (!i) { | ||
| g && I(g); | ||
| return; | ||
| } | ||
| if (k(i)) return; | ||
| g = i, x.has(i) || x.set(i, e); | ||
| const n = x.get(i) || e, a = o.closest(H), r = !!o.closest(".rte-conditional-header, .rte-conditional-summary, .rte-conditional-meta, .rte-conditional-else-label"); | ||
| if (a && r) { | ||
| t.preventDefault(), t.stopPropagation(), C(i, n, "edit", void 0, a), me(i, a); | ||
| return; | ||
| } | ||
| a ? me(i, a) : I(i); | ||
| }, document.addEventListener("click", Y, !0)), X || (X = () => { | ||
| const t = A(void 0, !1) || g; | ||
| t && t.isConnected && D(t); | ||
| }, document.addEventListener("selectionchange", X)), Q || (Q = (t) => { | ||
| const i = t.target?.closest(L); | ||
| if (!i) return; | ||
| const n = x.get(i) || ee || e; | ||
| ne(i, n.labels), D(i); | ||
| }, document.addEventListener("input", Q, !0)), N || (N = () => { | ||
| tt(); | ||
| }, window.addEventListener("scroll", N, !0), window.addEventListener("resize", N)); | ||
| } | ||
| function at() { | ||
| U && (document.removeEventListener("focusin", U, !0), U = null), G && (document.removeEventListener("keydown", G, !0), G = null), Y && (document.removeEventListener("click", Y, !0), Y = null), J && (document.removeEventListener("mousedown", J, !0), J = null), X && (document.removeEventListener("selectionchange", X), X = null), Q && (document.removeEventListener("input", Q, !0), Q = null), N && (window.removeEventListener("scroll", N, !0), window.removeEventListener("resize", N), N = null), _.forEach((e) => { | ||
| e.remove(); | ||
| }), _.clear(), z.clear(), ee = null, g = null; | ||
| } | ||
| const rt = (e = {}) => { | ||
| const t = je(e); | ||
| return Fe(), { | ||
| name: "conditionalContent", | ||
| toolbar: [ | ||
| { | ||
| id: "conditionalContentGroup", | ||
| label: "Conditional Content", | ||
| type: "group", | ||
| command: "conditionalContent", | ||
| items: [ | ||
| { | ||
| id: "conditionalContent", | ||
| label: "Conditional Rule", | ||
| command: "openConditionalDialog", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M6 5h12a1 1 0 0 1 1 1v3h-2V7H7v3H5V6a1 1 0 0 1 1-1Zm-1 9h2v3h10v-3h2v4a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1v-4Zm3-2a1 1 0 0 1 1-1h2.6l1.8-2.4a1 1 0 1 1 1.6 1.2L13.8 11H15a1 1 0 1 1 0 2h-2.7l-1.9 2.5a1 1 0 1 1-1.6-1.2L10.1 13H9a1 1 0 0 1-1-1Z" fill="currentColor"></path></svg>', | ||
| shortcut: "Mod-Alt-Shift-c" | ||
| }, | ||
| { | ||
| id: "conditionalPreview", | ||
| label: "Conditional Preview", | ||
| command: "toggleConditionalPreview", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M4 6h16a1 1 0 0 1 1 1v3h-2V8H5v8h14v-2h2v3a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1Zm5 3h2v2H9V9Zm0 4h2v2H9v-2Zm4-4h6v2h-6V9Zm0 4h6v2h-6v-2Z" fill="currentColor"></path></svg>', | ||
| shortcut: "Mod-Alt-Shift-p" | ||
| } | ||
| ] | ||
| } | ||
| ], | ||
| commands: { | ||
| conditionalContent: (o, i) => { | ||
| const n = A(i); | ||
| if (!n || k(n)) return !1; | ||
| g = n, x.set(n, t), ne(n, t.labels); | ||
| const a = o?.target; | ||
| if (a === "insert") | ||
| return C(n, t, "insert", o), !0; | ||
| const r = W(n); | ||
| return a === "edit" || r ? !r && a === "edit" ? !1 : (C(n, t, "edit", o, r || void 0), !0) : (C(n, t, "insert", o), !0); | ||
| }, | ||
| openConditionalDialog: (o, i) => { | ||
| const n = A(i); | ||
| if (!n || k(n)) return !1; | ||
| g = n, x.set(n, t), ne(n, t.labels); | ||
| const a = o?.target; | ||
| if (a === "insert") | ||
| return C(n, t, "insert", o), !0; | ||
| const r = W(n); | ||
| return a === "edit" || r ? !r && a === "edit" ? !1 : (C(n, t, "edit", o, r || void 0), !0) : (C(n, t, "insert", o), !0); | ||
| }, | ||
| conditionalPreview: async (o, i) => { | ||
| const n = A(i); | ||
| if (!n) return !1; | ||
| g = n, x.set(n, t); | ||
| const a = typeof o == "boolean" ? o : w.get(n) !== !0; | ||
| return await Z(n, t, a), D(n), !0; | ||
| }, | ||
| editConditionalBlock: (o, i) => { | ||
| const n = A(i); | ||
| if (!n || k(n)) return !1; | ||
| g = n, x.set(n, t); | ||
| const a = W(n); | ||
| return a ? (C(n, t, "edit", o, a), !0) : !1; | ||
| }, | ||
| deleteConditionalBlock: (o, i) => { | ||
| const n = A(i); | ||
| if (!n || k(n)) return !1; | ||
| const a = W(n); | ||
| if (!a) return !1; | ||
| const r = Oe(n, a); | ||
| return r && D(n), r; | ||
| }, | ||
| insertConditionalBlock: (o, i) => { | ||
| const n = A(i); | ||
| if (!n || k(n)) return !1; | ||
| g = n, x.set(n, t); | ||
| const a = { | ||
| condition: o?.condition ?? t.defaultCondition, | ||
| audience: o?.audience ?? t.defaultAudience, | ||
| locale: o?.locale ?? t.defaultLocale, | ||
| hasElse: o?.hasElse ?? t.enableElseByDefault | ||
| }, r = Me(a, t.labels); | ||
| return Ne(n, r), w.get(n) === !0 && Z(n, t, !0), !0; | ||
| }, | ||
| toggleConditionalPreview: async (o, i) => { | ||
| const n = A(i); | ||
| if (!n) return !1; | ||
| g = n, x.set(n, t); | ||
| const a = typeof o == "boolean" ? o : w.get(n) !== !0; | ||
| return await Z(n, t, a), !0; | ||
| }, | ||
| setConditionalContext: (o, i) => { | ||
| const n = A(i); | ||
| return n ? (g = n, !o || typeof o != "object" ? $e.delete(n) : $e.set(n, o), w.get(n) === !0 && Z(n, t, !0), !0) : !1; | ||
| } | ||
| }, | ||
| keymap: { | ||
| "Mod-Alt-Shift-c": "openConditionalDialog", | ||
| "Mod-Alt-Shift-C": "openConditionalDialog", | ||
| "Mod-Alt-Shift-p": "toggleConditionalPreview", | ||
| "Mod-Alt-Shift-P": "toggleConditionalPreview", | ||
| F9: "openConditionalDialog", | ||
| F10: "toggleConditionalPreview" | ||
| }, | ||
| init: () => { | ||
| se += 1, it(t); | ||
| }, | ||
| destroy: () => { | ||
| se = Math.max(0, se - 1), se === 0 && (Be(), at()); | ||
| } | ||
| }; | ||
| }; | ||
| export { | ||
| rt as ConditionalContentPlugin | ||
| }; |
| "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const R=".rte-content, .editora-content",ee="[data-editora-editor], .rte-editor, .editora-editor, editora-editor",oe="__editoraCommandEditorRoot",se="rte-content-rules-styles",f="rte-content-rules-panel",P=':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)',he={panelTitle:"Content Rules",panelAriaLabel:"Content rules panel",runAuditText:"Run Audit",realtimeOnText:"Realtime On",realtimeOffText:"Realtime Off",closeText:"Close",noIssuesText:"No rule violations detected.",summaryPrefix:"Issues",locateText:"Locate",bannedWordMessage:"Banned word found",requiredHeadingMessage:"Missing required heading",sentenceLengthMessage:"Sentence is too long",readabilityMessage:"Readability score is below threshold"},d=new WeakMap,v=new WeakMap,de=new WeakMap,T=new WeakMap,V=new WeakMap,le=new WeakMap,Y=new WeakMap,h=new Map,B=new WeakMap,z=new Set;let N=0,pe=0,E=null,g=null,L=null,I=null,H=null,S=null;function k(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function xe(e){return{...he,...e||{}}}function ye(e){return e.replace(/\u00A0/g," ").replace(/\s+/g," ").trim()}function ae(e){if(!e)return[];const t=new Set;return e.forEach(n=>{const o=n.trim();o&&t.add(o)}),Array.from(t)}function j(e={}){return{bannedWords:ae(e.bannedWords),requiredHeadings:ae(e.requiredHeadings),maxSentenceWords:Math.max(8,Number(e.maxSentenceWords??32)),minReadabilityScore:Math.max(0,Math.min(120,Number(e.minReadabilityScore??55))),maxIssues:Math.max(1,Number(e.maxIssues??100)),debounceMs:Math.max(50,Number(e.debounceMs??220)),enableRealtime:e.enableRealtime!==!1,labels:xe(e.labels),normalizeText:e.normalizeText||ye,customRules:Array.isArray(e.customRules)?e.customRules:[]}}function X(e){return e.closest(ee)||e}function F(e){if(!e)return null;if(e.matches(R))return e;const t=e.querySelector(R);return t instanceof HTMLElement?t:null}function we(){if(typeof window>"u")return null;const e=window[oe];if(!(e instanceof HTMLElement))return null;window[oe]=null;const t=F(e);if(t)return t;const n=e.closest(ee);if(n){const o=F(n);if(o)return o}return null}function ke(e){const t=e.closest("[data-editora-editor]");if(t&&F(t)===e)return t;let n=e;for(;n;){if(n.matches(ee)&&(n===e||F(n)===e))return n;n=n.parentElement}return X(e)}function K(e){return e?(e.getAttribute("data-theme")||e.getAttribute("theme")||"").toLowerCase()==="dark"?!0:e.classList.contains("dark")||e.classList.contains("editora-theme-dark")||e.classList.contains("rte-theme-dark"):!1}function Re(e){const t=X(e);if(K(t))return!0;const n=t.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark");return K(n)?!0:K(document.documentElement)||K(document.body)}function G(e,t){e.classList.remove("rte-content-rules-theme-dark"),Re(t)&&e.classList.add("rte-content-rules-theme-dark")}function Ee(e){return e?e.nodeType===Node.ELEMENT_NODE?e:e.parentElement:null}function $(e,t=!0){if(e?.contentElement instanceof HTMLElement)return e.contentElement;if(e?.editorElement instanceof HTMLElement){const s=e.editorElement;if(s.matches(R))return s;const i=s.querySelector(R);if(i instanceof HTMLElement)return i}const n=we();if(n)return n;const o=window.getSelection();if(o&&o.rangeCount>0){const s=o.getRangeAt(0).startContainer,l=Ee(s)?.closest(R);if(l)return l}const r=document.activeElement;if(r){if(r.matches(R))return r;const s=r.closest(R);if(s)return s}return g&&g.isConnected?g:(g&&!g.isConnected&&(g=null),t?document.querySelector(R):null)}function Z(e){return e.getAttribute("contenteditable")==="false"||e.getAttribute("data-readonly")==="true"}function Ce(e,t){const n=e.innerText||e.textContent||"";return t(n)}function ve(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function ie(e){let t=2166136261;for(let n=0;n<e.length;n+=1)t^=e.charCodeAt(n),t=Math.imul(t,16777619);return t>>>0}function ce(e){const t=e.match(/\b[\w'-]+\b/g);return t?t.length:0}function fe(e){const t=e.match(/[^.!?]+[.!?]*/g);return t?t.map(n=>n.trim()).filter(Boolean).length:0}function Me(e){const t=e.toLowerCase().replace(/[^a-z]/g,"");if(!t)return 0;if(t.length<=3)return 1;const n=t.match(/[aeiouy]+/g);let o=n?n.length:1;return t.endsWith("e")&&(o-=1),Math.max(1,o)}function $e(e){const t=e.match(/\b[\w'-]+\b/g)||[],n=t.length;if(n===0)return 100;const o=Math.max(1,fe(e)),r=t.reduce((i,l)=>i+Me(l),0),s=206.835-1.015*(n/o)-84.6*(r/Math.max(1,n));return Number.isFinite(s)?Math.max(0,Math.min(120,s)):0}function _(e,t){return`${e}-${t}`}function x(e,t){return e.length>=t}function q(e,t,n){x(e,n)||e.push(t)}function ge(e,t=140){return e.length<=t?e:`${e.slice(0,t-1).trimEnd()}...`}function Se(e,t,n,o){return{id:e.id||_(t,o),ruleId:e.ruleId||t,severity:e.severity||n,message:e.message||t,excerpt:e.excerpt?ge(e.excerpt,220):void 0,suggestion:e.suggestion,locateText:e.locateText,selector:e.selector}}function Te(e,t){const n=Array.from(e.querySelectorAll("h1, h2, h3, h4, h5, h6")),o=new Set;return n.forEach(r=>{const s=t(r.textContent||"").toLowerCase();s&&o.add(s)}),o}function Ae(e){const t=e.match(/[^.!?\n]+[.!?]?/g);return t?t.map(n=>n.trim()).filter(Boolean):[]}async function C(e,t,n=!1){const o=Ce(e,t.normalizeText),r=e.innerHTML,s=`${o.length}:${ie(o)}:${r.length}:${ie(r)}`;if(!n&&le.get(e)===s)return v.get(e)||[];const i=(Y.get(e)||0)+1;Y.set(e,i);const l=ce(o),c=fe(o),u=$e(o),a=[],y=t.labels;if(t.bannedWords.length>0){let w=0;for(const p of t.bannedWords){const m=new RegExp(`\\b${ve(p)}\\b`,"gi");let b=m.exec(o);for(;b&&!x(a,t.maxIssues);){const re=b[0];q(a,{id:_("banned-word",w),ruleId:"banned-word",severity:"error",message:`${y.bannedWordMessage}: "${re}"`,locateText:re,suggestion:"Replace or remove banned terms."},t.maxIssues),w+=1,b=m.exec(o)}if(x(a,t.maxIssues))break}}if(!x(a,t.maxIssues)&&t.requiredHeadings.length>0){const w=Te(e,t.normalizeText);let p=0;t.requiredHeadings.forEach(m=>{if(x(a,t.maxIssues))return;const b=t.normalizeText(m).toLowerCase();!b||w.has(b)||(q(a,{id:_("required-heading",p),ruleId:"required-heading",severity:"warning",message:`${y.requiredHeadingMessage}: "${m}"`,suggestion:`Add a heading named "${m}".`},t.maxIssues),p+=1)})}if(!x(a,t.maxIssues)){const w=Ae(o);let p=0;for(const m of w){if(x(a,t.maxIssues))break;const b=ce(m);b<=t.maxSentenceWords||(q(a,{id:_("sentence-length",p),ruleId:"sentence-length",severity:"warning",message:`${y.sentenceLengthMessage} (${b}/${t.maxSentenceWords} words)`,excerpt:ge(m,200),locateText:m.slice(0,64),suggestion:"Split into shorter sentences for readability."},t.maxIssues),p+=1)}}if(!x(a,t.maxIssues)&&l>0&&u<t.minReadabilityScore&&q(a,{id:_("readability",0),ruleId:"readability",severity:"info",message:`${y.readabilityMessage}: ${u.toFixed(1)} < ${t.minReadabilityScore}`,suggestion:"Use shorter sentences and simpler wording."},t.maxIssues),!x(a,t.maxIssues)&&t.customRules.length>0){const w={editor:e,editorRoot:X(e),text:o,html:r,wordCount:l,sentenceCount:c,readabilityScore:u};for(const p of t.customRules){if(x(a,t.maxIssues))break;try{const m=await p.evaluate(w);if(!Array.isArray(m))continue;for(let b=0;b<m.length&&!x(a,t.maxIssues);b+=1)q(a,Se(m[b],p.id,p.severity||"warning",b),t.maxIssues)}catch{}}}if(Y.get(e)!==i)return v.get(e)||[];const D={readabilityScore:u,wordCount:l,sentenceCount:c};return le.set(e,s),v.set(e,a),de.set(e,D),te(e),e.dispatchEvent(new CustomEvent("editora:content-rules-audit",{bubbles:!0,detail:{issues:a,metrics:D}})),a}function Le(e){return e.reduce((t,n)=>(t[n.severity]+=1,t),{error:0,warning:0,info:0})}function Ie(e){return e==="error"?"Error":e==="warning"?"Warning":"Info"}function M(e,t,n){const o=ke(e);Array.from(o.querySelectorAll(`.rte-toolbar-button[data-command="${t}"], .editora-toolbar-button[data-command="${t}"]`)).forEach(s=>{s.classList.toggle("active",n),s.setAttribute("data-active",n?"true":"false"),s.setAttribute("aria-pressed",n?"true":"false")})}function U(e){return B.get(e)===!0}function J(e,t){if(!t.classList.contains("show"))return;const o=X(e).getBoundingClientRect(),r=Math.min(window.innerWidth-20,360);t.style.width=`${r}px`,t.style.maxHeight=`${Math.max(220,window.innerHeight-24)}px`;const s=Math.max(10,o.right-r),i=Math.max(10,window.innerWidth-r-10),l=Math.min(s,i),c=Math.max(10,Math.min(window.innerHeight-10-240,o.top+10));t.style.left=`${l}px`,t.style.top=`${c}px`}function ue(e,t){const n=t.trim().toLowerCase();if(!n)return!1;const o=window.getSelection();if(!o)return!1;const r=document.createTreeWalker(e,NodeFilter.SHOW_TEXT,null);let s=r.nextNode();for(;s;){const l=s.data.toLowerCase().indexOf(n);if(l!==-1){const c=document.createRange();c.setStart(s,l),c.setEnd(s,Math.min(s.length,l+n.length)),o.removeAllRanges(),o.addRange(c);const u=s.parentElement;return u&&u.scrollIntoView({behavior:"smooth",block:"center",inline:"nearest"}),e.focus({preventScroll:!0}),!0}s=r.nextNode()}return!1}function He(e,t){if(t.selector){const n=e.querySelector(t.selector);if(n)return n.scrollIntoView({behavior:"smooth",block:"center",inline:"nearest"}),n.focus({preventScroll:!0}),!0}return!!(t.locateText&&ue(e,t.locateText)||t.excerpt&&ue(e,t.excerpt.slice(0,64)))}function Oe(e,t){return(v.get(e)||[]).find(o=>o.id===t)}function A(e,t){const n=T.get(e);return typeof n=="boolean"?n:t?t.enableRealtime:!0}function W(e,t,n){const o=t.querySelector('[data-action="toggle-realtime"]');if(!o)return;const r=A(e,n);o.textContent=r?n.labels.realtimeOnText:n.labels.realtimeOffText,o.setAttribute("aria-pressed",r?"true":"false"),M(e,"toggleContentRulesRealtime",r)}function te(e){const t=h.get(e);if(!t)return;const n=d.get(e)||E;if(!n)return;const o=v.get(e)||[],r=de.get(e)||{readabilityScore:100},s=t.querySelector(".rte-content-rules-count"),i=t.querySelector(".rte-content-rules-summary"),l=t.querySelector(".rte-content-rules-list"),c=t.querySelector(".rte-content-rules-live");if(!s||!i||!l||!c)return;const u=Le(o);if(s.textContent=String(o.length),i.textContent=`${n.labels.summaryPrefix}: ${o.length} | Error ${u.error} | Warning ${u.warning} | Info ${u.info} | Readability ${r.readabilityScore.toFixed(1)}`,c.textContent=`${o.length} issues. ${u.error} errors, ${u.warning} warnings, ${u.info} info.`,o.length===0){l.innerHTML=`<li class="rte-content-rules-empty">${k(n.labels.noIssuesText)}</li>`;return}l.innerHTML=o.map(a=>{const y=a.excerpt?`<p class="rte-content-rules-excerpt">${k(a.excerpt)}</p>`:"",D=a.suggestion?`<p class="rte-content-rules-suggestion">${k(a.suggestion)}</p>`:"",w=`${n.labels.locateText}: ${a.message}`;return` | ||
| <li class="rte-content-rules-item rte-content-rules-item-${a.severity}"> | ||
| <button | ||
| type="button" | ||
| class="rte-content-rules-item-btn" | ||
| data-action="focus-issue" | ||
| data-issue-id="${k(a.id)}" | ||
| data-role="issue-button" | ||
| aria-label="${k(w)}" | ||
| > | ||
| <span class="rte-content-rules-badge">${k(Ie(a.severity))}</span> | ||
| <span class="rte-content-rules-message">${k(a.message)}</span> | ||
| </button> | ||
| ${y} | ||
| ${D} | ||
| </li> | ||
| `}).join("")}function O(e,t=!1){const n=h.get(e);n&&(n.classList.remove("show"),B.set(e,!1),M(e,"toggleContentRulesPanel",!1),t&&e.focus({preventScroll:!0}))}function We(e){h.forEach((t,n)=>{n!==e&&O(n,!1)})}function Pe(e){const t=h.get(e);if(t)return t;const n=d.get(e)||E||j(),o=`rte-content-rules-panel-${pe++}`,r=document.createElement("section");return r.className=f,r.id=o,r.setAttribute("role","dialog"),r.setAttribute("aria-modal","false"),r.setAttribute("aria-label",n.labels.panelAriaLabel),r.innerHTML=` | ||
| <header class="rte-content-rules-header"> | ||
| <h2 class="rte-content-rules-title">${k(n.labels.panelTitle)}</h2> | ||
| <button type="button" class="rte-content-rules-icon-btn" data-action="close" aria-label="${k(n.labels.closeText)}">✕</button> | ||
| </header> | ||
| <div class="rte-content-rules-body"> | ||
| <div class="rte-content-rules-topline"> | ||
| <p class="rte-content-rules-summary" aria-live="polite"></p> | ||
| <span class="rte-content-rules-count" aria-hidden="true">0</span> | ||
| </div> | ||
| <div class="rte-content-rules-controls" role="toolbar" aria-label="Content rules controls"> | ||
| <button type="button" class="rte-content-rules-btn rte-content-rules-btn-primary" data-action="run-audit">${k(n.labels.runAuditText)}</button> | ||
| <button type="button" class="rte-content-rules-btn" data-action="toggle-realtime" aria-pressed="false"></button> | ||
| </div> | ||
| <ul class="rte-content-rules-list" role="list" aria-label="Detected content rule issues"></ul> | ||
| <p class="rte-content-rules-shortcut">Shortcut: Ctrl/Cmd + Alt + Shift + R</p> | ||
| <span class="rte-content-rules-live" aria-live="polite"></span> | ||
| </div> | ||
| `,r.addEventListener("click",s=>{const l=s.target?.closest("[data-action]");if(!l)return;const c=l.getAttribute("data-action");if(c){if(c==="close"){O(e,!0);return}if(c==="run-audit"){const u=d.get(e)||E||n;C(e,u,!0);return}if(c==="toggle-realtime"){const a=!A(e,d.get(e)||E||n);if(T.set(e,a),W(e,r,d.get(e)||E||n),a){const y=d.get(e)||E||n;C(e,y,!0)}return}if(c==="focus-issue"){const u=l.getAttribute("data-issue-id")||"",a=Oe(e,u);if(!a)return;He(e,a),O(e,!1)}}}),r.addEventListener("keydown",s=>{if(s.key==="Escape"){s.preventDefault(),O(e,!0);return}if(s.key!=="ArrowDown"&&s.key!=="ArrowUp")return;const i=Array.from(r.querySelectorAll('[data-role="issue-button"]'));if(i.length===0)return;const l=document.activeElement,c=i.findIndex(y=>y===l);if(c===-1)return;s.preventDefault();const u=s.key==="ArrowDown"?1:-1,a=(c+u+i.length)%i.length;i[a].focus()}),G(r,e),document.body.appendChild(r),h.set(e,r),B.set(e,!1),W(e,r,n),r}function ne(e){const t=Pe(e);We(e),t.classList.add("show"),B.set(e,!0),G(t,e),J(e,t),te(e),M(e,"toggleContentRulesPanel",!0),t.querySelector('[data-action="run-audit"]')?.focus()}function Q(e,t){const n=U(e);return(typeof t=="boolean"?t:!n)?ne(e):O(e,!1),!0}function me(e){const t=V.get(e);typeof t=="number"&&(window.clearTimeout(t),z.delete(t),V.delete(e))}function be(e){const t=d.get(e)||E;if(!t||!A(e,t))return;me(e);const n=window.setTimeout(()=>{z.delete(n),V.delete(e),C(e,t,!1)},t.debounceMs);z.add(n),V.set(e,n)}function qe(e){const t=e.key.toLowerCase();return(e.metaKey||e.ctrlKey)&&e.altKey&&e.shiftKey&&t==="r"}function _e(e){const t=e.key.toLowerCase();return(e.metaKey||e.ctrlKey)&&e.altKey&&e.shiftKey&&t==="l"}function ze(e){const t=e.key.toLowerCase();return(e.metaKey||e.ctrlKey)&&e.altKey&&e.shiftKey&&t==="t"}function Be(){if(typeof document>"u"||document.getElementById(se))return;const e=document.createElement("style");e.id=se,e.textContent=` | ||
| .rte-toolbar-group-items.content-rules, | ||
| .editora-toolbar-group-items.content-rules { | ||
| display: flex; | ||
| border: 1px solid #ccc; | ||
| border-radius: 3px; | ||
| background: #fff; | ||
| } | ||
| .rte-toolbar-group-items.content-rules .rte-toolbar-button, | ||
| .editora-toolbar-group-items.content-rules .editora-toolbar-button { | ||
| border: none; | ||
| border-radius: 0px; | ||
| } | ||
| .rte-toolbar-group-items.content-rules .rte-toolbar-button, | ||
| .editora-toolbar-group-items.content-rules .editora-toolbar-button { | ||
| border-right: 1px solid #ccc; | ||
| } | ||
| .rte-toolbar-group-items.content-rules .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.content-rules .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| .rte-toolbar-button[data-command="toggleContentRulesRealtime"].active, | ||
| .editora-toolbar-button[data-command="toggleContentRulesRealtime"].active { | ||
| background-color: #ccc; | ||
| } | ||
| ${P} .rte-toolbar-group-items.content-rules, | ||
| ${P} .editora-toolbar-group-items.content-rules { | ||
| border-color: #566275; | ||
| } | ||
| ${P} .rte-toolbar-group-items.content-rules .rte-toolbar-button, | ||
| ${P} .editora-toolbar-group-items.content-rules .editora-toolbar-button | ||
| { | ||
| border-color: #566275; | ||
| } | ||
| ${P} .rte-toolbar-group-items.content-rules .rte-toolbar-button svg{ | ||
| fill: none; | ||
| } | ||
| .${f} { | ||
| position: fixed; | ||
| z-index: 12000; | ||
| display: none; | ||
| width: min(360px, calc(100vw - 20px)); | ||
| max-height: calc(100vh - 20px); | ||
| border: 1px solid #d1d5db; | ||
| border-radius: 14px; | ||
| background: #ffffff; | ||
| color: #111827; | ||
| box-shadow: 0 18px 45px rgba(15, 23, 42, 0.25); | ||
| overflow: hidden; | ||
| } | ||
| .${f}.show { | ||
| display: flex; | ||
| flex-direction: column; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark { | ||
| border-color: #334155; | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| box-shadow: 0 20px 46px rgba(2, 6, 23, 0.68); | ||
| } | ||
| .rte-content-rules-header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| padding: 12px 14px; | ||
| border-bottom: 1px solid #e5e7eb; | ||
| background: linear-gradient(180deg, #f9fafb 0%, #f3f4f6 100%); | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-header { | ||
| border-color: #1e293b; | ||
| background: linear-gradient(180deg, #111827 0%, #0f172a 100%); | ||
| } | ||
| .rte-content-rules-title { | ||
| margin: 0; | ||
| font-size: 15px; | ||
| line-height: 1.2; | ||
| font-weight: 700; | ||
| } | ||
| .rte-content-rules-icon-btn { | ||
| width: 34px; | ||
| height: 34px; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| font-weight: 600; | ||
| padding: 0; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| cursor: pointer; | ||
| } | ||
| .rte-content-rules-icon-btn:hover, | ||
| .rte-content-rules-icon-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-icon-btn { | ||
| background: #0f172a; | ||
| border-color: #475569; | ||
| color: #e2e8f0; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-icon-btn:hover, | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-icon-btn:focus-visible { | ||
| border-color: #60a5fa; | ||
| box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.24); | ||
| } | ||
| .rte-content-rules-body { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 10px; | ||
| padding: 12px; | ||
| overflow: auto; | ||
| } | ||
| .rte-content-rules-topline { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| } | ||
| .rte-content-rules-summary { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #475569; | ||
| flex: 1; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-summary { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-content-rules-count { | ||
| min-width: 32px; | ||
| height: 32px; | ||
| border-radius: 999px; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| font-weight: 700; | ||
| font-size: 13px; | ||
| border: 1px solid #cbd5e1; | ||
| background: #f8fafc; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-count { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-content-rules-controls { | ||
| display: flex; | ||
| gap: 8px; | ||
| flex-wrap: wrap; | ||
| } | ||
| .rte-content-rules-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| height: 34px; | ||
| padding: 0 10px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| cursor: pointer; | ||
| } | ||
| .rte-content-rules-btn:hover, | ||
| .rte-content-rules-btn:focus-visible { | ||
| border-color: #94a3b8; | ||
| background: #f8fafc; | ||
| outline: none; | ||
| } | ||
| .rte-content-rules-btn-primary { | ||
| border-color: #0284c7; | ||
| background: #0ea5e9; | ||
| color: #f8fafc; | ||
| } | ||
| .rte-content-rules-btn-primary:hover, | ||
| .rte-content-rules-btn-primary:focus-visible { | ||
| border-color: #0369a1; | ||
| background: #0284c7; | ||
| color: #ffffff; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-btn { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-btn:hover, | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-btn:focus-visible { | ||
| border-color: #475569; | ||
| background: #1e293b; | ||
| } | ||
| .rte-content-rules-list { | ||
| list-style: none; | ||
| margin: 0; | ||
| padding: 0; | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 8px; | ||
| max-height: min(55vh, 420px); | ||
| overflow: auto; | ||
| } | ||
| .rte-content-rules-item { | ||
| border: 1px solid #e2e8f0; | ||
| border-radius: 10px; | ||
| padding: 8px; | ||
| background: #ffffff; | ||
| } | ||
| .rte-content-rules-item-error { | ||
| border-color: #fca5a5; | ||
| background: #fef2f2; | ||
| } | ||
| .rte-content-rules-item-warning { | ||
| border-color: #fcd34d; | ||
| background: #fffbeb; | ||
| } | ||
| .rte-content-rules-item-info { | ||
| border-color: #93c5fd; | ||
| background: #eff6ff; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-item { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-item-error { | ||
| border-color: #7f1d1d; | ||
| background: #2b0b11; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-item-warning { | ||
| border-color: #78350f; | ||
| background: #2b1907; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-item-info { | ||
| border-color: #1d4ed8; | ||
| background: #0a162f; | ||
| } | ||
| .rte-content-rules-item-btn { | ||
| width: 100%; | ||
| border: none; | ||
| background: transparent; | ||
| display: flex; | ||
| align-items: flex-start; | ||
| gap: 8px; | ||
| text-align: left; | ||
| padding: 0; | ||
| color: inherit; | ||
| cursor: pointer; | ||
| } | ||
| .rte-content-rules-item-btn:focus-visible { | ||
| outline: 2px solid #0284c7; | ||
| outline-offset: 3px; | ||
| border-radius: 6px; | ||
| } | ||
| .rte-content-rules-badge { | ||
| flex: 0 0 auto; | ||
| margin-top: 1px; | ||
| border-radius: 999px; | ||
| border: 1px solid currentColor; | ||
| padding: 1px 8px; | ||
| font-size: 10px; | ||
| font-weight: 700; | ||
| line-height: 1.3; | ||
| text-transform: uppercase; | ||
| opacity: 0.86; | ||
| } | ||
| .rte-content-rules-message { | ||
| font-size: 13px; | ||
| line-height: 1.35; | ||
| font-weight: 600; | ||
| } | ||
| .rte-content-rules-excerpt, | ||
| .rte-content-rules-suggestion { | ||
| margin: 8px 0 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #334155; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-excerpt, | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-suggestion { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-content-rules-empty { | ||
| border: 1px dashed #cbd5e1; | ||
| border-radius: 10px; | ||
| padding: 10px; | ||
| font-size: 13px; | ||
| color: #475569; | ||
| background: #f8fafc; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-empty { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #94a3b8; | ||
| } | ||
| .rte-content-rules-shortcut { | ||
| margin: 2px 0 0; | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-shortcut { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-content-rules-live { | ||
| position: absolute; | ||
| width: 1px; | ||
| height: 1px; | ||
| margin: -1px; | ||
| padding: 0; | ||
| overflow: hidden; | ||
| clip: rect(0 0 0 0); | ||
| border: 0; | ||
| } | ||
| @media (max-width: 768px) { | ||
| .${f} { | ||
| left: 10px !important; | ||
| right: 10px; | ||
| top: 10px !important; | ||
| width: auto !important; | ||
| max-height: calc(100vh - 20px); | ||
| } | ||
| .rte-content-rules-list { | ||
| max-height: 45vh; | ||
| } | ||
| } | ||
| `,document.head.appendChild(e)}function De(e){E=e,L||(L=t=>{const o=t.target?.closest(R);if(!o)return;g=o,d.has(o)||d.set(o,e),v.has(o)||v.set(o,[]),T.has(o)||T.set(o,e.enableRealtime);const r=h.get(o);r&&(G(r,o),J(o,r),W(o,r,d.get(o)||e)),M(o,"toggleContentRulesPanel",U(o)),M(o,"toggleContentRulesRealtime",A(o,e))},document.addEventListener("focusin",L,!0)),I||(I=t=>{const o=t.target?.closest(R);o&&(g=o,be(o))},document.addEventListener("input",I,!0)),H||(H=t=>{if(t.defaultPrevented||t.target?.closest("input, textarea, select"))return;const o=t.key==="Escape",r=qe(t),s=_e(t),i=ze(t);if(!o&&!r&&!s&&!i)return;const l=$(void 0,!1);if(!l||Z(l))return;const c=d.get(l)||E||e;if(d.set(l,c),g=l,o&&U(l)){t.preventDefault(),O(l,!0);return}if(r){t.preventDefault(),t.stopPropagation(),Q(l);return}if(s){t.preventDefault(),t.stopPropagation(),C(l,c,!0),ne(l);return}if(i){t.preventDefault(),t.stopPropagation();const u=!A(l,c);T.set(l,u);const a=h.get(l);a&&W(l,a,c),M(l,"toggleContentRulesRealtime",u),u&&C(l,c,!0)}},document.addEventListener("keydown",H,!0)),S||(S=()=>{h.forEach((t,n)=>{if(!n.isConnected||!t.isConnected){me(n),t.remove(),h.delete(n),B.delete(n);return}G(t,n),J(n,t)})},window.addEventListener("scroll",S,!0),window.addEventListener("resize",S))}function Ne(){L&&(document.removeEventListener("focusin",L,!0),L=null),I&&(document.removeEventListener("input",I,!0),I=null),H&&(document.removeEventListener("keydown",H,!0),H=null),S&&(window.removeEventListener("scroll",S,!0),window.removeEventListener("resize",S),S=null),h.forEach(e=>{e.remove()}),h.clear(),E=null,g=null}const Ke=(e={})=>{const t=j(e);return Be(),{name:"contentRules",toolbar:[{id:"contentRulesGroup",label:"Content Rules",type:"group",command:"contentRules",items:[{id:"contentRules",label:"Content Rules",command:"toggleContentRulesPanel",shortcut:"Mod-Alt-Shift-r",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M6 3h9l5 5v11a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2Zm8 2v4h4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/><path d="M8 11h8M8 15h8M8 19h5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>'},{id:"contentRulesAudit",label:"Run Rules Audit",command:"runContentRulesAudit",shortcut:"Mod-Alt-Shift-l",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M4 12h4l2 5 4-10 2 5h4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/><circle cx="12" cy="12" r="9" stroke="currentColor" stroke-width="1.6"/></svg>'},{id:"contentRulesRealtime",label:"Toggle Realtime Rules",command:"toggleContentRulesRealtime",shortcut:"Mod-Alt-Shift-t",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M12 3v4M12 17v4M4.9 4.9l2.8 2.8M16.3 16.3l2.8 2.8M3 12h4M17 12h4M4.9 19.1l2.8-2.8M16.3 7.7l2.8-2.8" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><circle cx="12" cy="12" r="4" stroke="currentColor" stroke-width="1.6"/></svg>'}]}],commands:{contentRules:(n,o)=>{const r=$(o);if(!r||Z(r))return!1;const s=d.get(r)||t;return d.set(r,s),g=r,Q(r,!0),C(r,s,!1),!0},toggleContentRulesPanel:(n,o)=>{const r=$(o);if(!r||Z(r))return!1;g=r;const s=d.get(r)||t;d.set(r,s);const i=Q(r,typeof n=="boolean"?n:void 0);return U(r)&&C(r,s,!1),i},runContentRulesAudit:async(n,o)=>{const r=$(o);if(!r)return!1;g=r;const s=d.get(r)||t;return d.set(r,s),await C(r,s,!0),ne(r),!0},toggleContentRulesRealtime:(n,o)=>{const r=$(o);if(!r)return!1;g=r;const s=d.get(r)||t;d.set(r,s);const i=typeof n=="boolean"?n:!A(r,s);T.set(r,i);const l=h.get(r);return l&&W(r,l,s),M(r,"toggleContentRulesRealtime",i),i&&C(r,s,!0),!0},getContentRulesIssues:(n,o)=>{const r=$(o);if(!r)return!1;const s=v.get(r)||[];if(typeof n=="function")try{n(s)}catch{}return r.__contentRulesIssues=s,r.dispatchEvent(new CustomEvent("editora:content-rules-issues",{bubbles:!0,detail:{issues:s}})),!0},setContentRulesOptions:(n,o)=>{const r=$(o);if(!r||!n||typeof n!="object")return!1;const s=d.get(r)||t,i=j({...s,...n,labels:{...s.labels,...n.labels||{}}});d.set(r,i),typeof n.enableRealtime=="boolean"&&T.set(r,n.enableRealtime),A(r,i)&&C(r,i,!0);const l=h.get(r);if(l){l.setAttribute("aria-label",i.labels.panelAriaLabel);const c=l.querySelector(".rte-content-rules-title");c&&(c.textContent=i.labels.panelTitle),W(r,l,i),te(r)}return!0}},keymap:{"Mod-Alt-Shift-r":"toggleContentRulesPanel","Mod-Alt-Shift-R":"toggleContentRulesPanel","Mod-Alt-Shift-l":"runContentRulesAudit","Mod-Alt-Shift-L":"runContentRulesAudit","Mod-Alt-Shift-t":"toggleContentRulesRealtime","Mod-Alt-Shift-T":"toggleContentRulesRealtime"},init:function(o){N+=1;const r=this&&typeof this.__pluginConfig=="object"?j({...t,...this.__pluginConfig}):t;De(r);const s=$(o&&o.editorElement?{editorElement:o.editorElement}:void 0,!1);s&&(g=s,d.set(s,r),T.set(s,r.enableRealtime),v.set(s,[]),M(s,"toggleContentRulesPanel",!1),M(s,"toggleContentRulesRealtime",r.enableRealtime),r.enableRealtime&&be(s))},destroy:()=>{N=Math.max(0,N-1),!(N>0)&&(z.forEach(n=>{window.clearTimeout(n)}),z.clear(),Ne())}}};exports.ContentRulesPlugin=Ke; |
| const R = ".rte-content, .editora-content", ee = "[data-editora-editor], .rte-editor, .editora-editor, editora-editor", oe = "__editoraCommandEditorRoot", se = "rte-content-rules-styles", f = "rte-content-rules-panel", q = ':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)', he = { | ||
| panelTitle: "Content Rules", | ||
| panelAriaLabel: "Content rules panel", | ||
| runAuditText: "Run Audit", | ||
| realtimeOnText: "Realtime On", | ||
| realtimeOffText: "Realtime Off", | ||
| closeText: "Close", | ||
| noIssuesText: "No rule violations detected.", | ||
| summaryPrefix: "Issues", | ||
| locateText: "Locate", | ||
| bannedWordMessage: "Banned word found", | ||
| requiredHeadingMessage: "Missing required heading", | ||
| sentenceLengthMessage: "Sentence is too long", | ||
| readabilityMessage: "Readability score is below threshold" | ||
| }, d = /* @__PURE__ */ new WeakMap(), v = /* @__PURE__ */ new WeakMap(), de = /* @__PURE__ */ new WeakMap(), T = /* @__PURE__ */ new WeakMap(), V = /* @__PURE__ */ new WeakMap(), le = /* @__PURE__ */ new WeakMap(), Y = /* @__PURE__ */ new WeakMap(), h = /* @__PURE__ */ new Map(), B = /* @__PURE__ */ new WeakMap(), _ = /* @__PURE__ */ new Set(); | ||
| let N = 0, pe = 0, E = null, g = null, L = null, I = null, H = null, S = null; | ||
| function k(e) { | ||
| return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); | ||
| } | ||
| function xe(e) { | ||
| return { | ||
| ...he, | ||
| ...e || {} | ||
| }; | ||
| } | ||
| function ye(e) { | ||
| return e.replace(/\u00A0/g, " ").replace(/\s+/g, " ").trim(); | ||
| } | ||
| function ae(e) { | ||
| if (!e) return []; | ||
| const t = /* @__PURE__ */ new Set(); | ||
| return e.forEach((n) => { | ||
| const o = n.trim(); | ||
| o && t.add(o); | ||
| }), Array.from(t); | ||
| } | ||
| function j(e = {}) { | ||
| return { | ||
| bannedWords: ae(e.bannedWords), | ||
| requiredHeadings: ae(e.requiredHeadings), | ||
| maxSentenceWords: Math.max(8, Number(e.maxSentenceWords ?? 32)), | ||
| minReadabilityScore: Math.max(0, Math.min(120, Number(e.minReadabilityScore ?? 55))), | ||
| maxIssues: Math.max(1, Number(e.maxIssues ?? 100)), | ||
| debounceMs: Math.max(50, Number(e.debounceMs ?? 220)), | ||
| enableRealtime: e.enableRealtime !== !1, | ||
| labels: xe(e.labels), | ||
| normalizeText: e.normalizeText || ye, | ||
| customRules: Array.isArray(e.customRules) ? e.customRules : [] | ||
| }; | ||
| } | ||
| function X(e) { | ||
| return e.closest(ee) || e; | ||
| } | ||
| function F(e) { | ||
| if (!e) return null; | ||
| if (e.matches(R)) return e; | ||
| const t = e.querySelector(R); | ||
| return t instanceof HTMLElement ? t : null; | ||
| } | ||
| function we() { | ||
| if (typeof window > "u") return null; | ||
| const e = window[oe]; | ||
| if (!(e instanceof HTMLElement)) return null; | ||
| window[oe] = null; | ||
| const t = F(e); | ||
| if (t) return t; | ||
| const n = e.closest(ee); | ||
| if (n) { | ||
| const o = F(n); | ||
| if (o) return o; | ||
| } | ||
| return null; | ||
| } | ||
| function ke(e) { | ||
| const t = e.closest("[data-editora-editor]"); | ||
| if (t && F(t) === e) | ||
| return t; | ||
| let n = e; | ||
| for (; n; ) { | ||
| if (n.matches(ee) && (n === e || F(n) === e)) | ||
| return n; | ||
| n = n.parentElement; | ||
| } | ||
| return X(e); | ||
| } | ||
| function K(e) { | ||
| return e ? (e.getAttribute("data-theme") || e.getAttribute("theme") || "").toLowerCase() === "dark" ? !0 : e.classList.contains("dark") || e.classList.contains("editora-theme-dark") || e.classList.contains("rte-theme-dark") : !1; | ||
| } | ||
| function Re(e) { | ||
| const t = X(e); | ||
| if (K(t)) return !0; | ||
| const n = t.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark"); | ||
| return K(n) ? !0 : K(document.documentElement) || K(document.body); | ||
| } | ||
| function G(e, t) { | ||
| e.classList.remove("rte-content-rules-theme-dark"), Re(t) && e.classList.add("rte-content-rules-theme-dark"); | ||
| } | ||
| function Ee(e) { | ||
| return e ? e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement : null; | ||
| } | ||
| function M(e, t = !0) { | ||
| if (e?.contentElement instanceof HTMLElement) return e.contentElement; | ||
| if (e?.editorElement instanceof HTMLElement) { | ||
| const s = e.editorElement; | ||
| if (s.matches(R)) return s; | ||
| const i = s.querySelector(R); | ||
| if (i instanceof HTMLElement) return i; | ||
| } | ||
| const n = we(); | ||
| if (n) return n; | ||
| const o = window.getSelection(); | ||
| if (o && o.rangeCount > 0) { | ||
| const s = o.getRangeAt(0).startContainer, l = Ee(s)?.closest(R); | ||
| if (l) return l; | ||
| } | ||
| const r = document.activeElement; | ||
| if (r) { | ||
| if (r.matches(R)) return r; | ||
| const s = r.closest(R); | ||
| if (s) return s; | ||
| } | ||
| return g && g.isConnected ? g : (g && !g.isConnected && (g = null), t ? document.querySelector(R) : null); | ||
| } | ||
| function Z(e) { | ||
| return e.getAttribute("contenteditable") === "false" || e.getAttribute("data-readonly") === "true"; | ||
| } | ||
| function Ce(e, t) { | ||
| const n = e.innerText || e.textContent || ""; | ||
| return t(n); | ||
| } | ||
| function ve(e) { | ||
| return e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); | ||
| } | ||
| function ie(e) { | ||
| let t = 2166136261; | ||
| for (let n = 0; n < e.length; n += 1) | ||
| t ^= e.charCodeAt(n), t = Math.imul(t, 16777619); | ||
| return t >>> 0; | ||
| } | ||
| function ce(e) { | ||
| const t = e.match(/\b[\w'-]+\b/g); | ||
| return t ? t.length : 0; | ||
| } | ||
| function fe(e) { | ||
| const t = e.match(/[^.!?]+[.!?]*/g); | ||
| return t ? t.map((n) => n.trim()).filter(Boolean).length : 0; | ||
| } | ||
| function $e(e) { | ||
| const t = e.toLowerCase().replace(/[^a-z]/g, ""); | ||
| if (!t) return 0; | ||
| if (t.length <= 3) return 1; | ||
| const n = t.match(/[aeiouy]+/g); | ||
| let o = n ? n.length : 1; | ||
| return t.endsWith("e") && (o -= 1), Math.max(1, o); | ||
| } | ||
| function Me(e) { | ||
| const t = e.match(/\b[\w'-]+\b/g) || [], n = t.length; | ||
| if (n === 0) return 100; | ||
| const o = Math.max(1, fe(e)), r = t.reduce((i, l) => i + $e(l), 0), s = 206.835 - 1.015 * (n / o) - 84.6 * (r / Math.max(1, n)); | ||
| return Number.isFinite(s) ? Math.max(0, Math.min(120, s)) : 0; | ||
| } | ||
| function z(e, t) { | ||
| return `${e}-${t}`; | ||
| } | ||
| function x(e, t) { | ||
| return e.length >= t; | ||
| } | ||
| function P(e, t, n) { | ||
| x(e, n) || e.push(t); | ||
| } | ||
| function ge(e, t = 140) { | ||
| return e.length <= t ? e : `${e.slice(0, t - 1).trimEnd()}...`; | ||
| } | ||
| function Se(e, t, n, o) { | ||
| return { | ||
| id: e.id || z(t, o), | ||
| ruleId: e.ruleId || t, | ||
| severity: e.severity || n, | ||
| message: e.message || t, | ||
| excerpt: e.excerpt ? ge(e.excerpt, 220) : void 0, | ||
| suggestion: e.suggestion, | ||
| locateText: e.locateText, | ||
| selector: e.selector | ||
| }; | ||
| } | ||
| function Te(e, t) { | ||
| const n = Array.from(e.querySelectorAll("h1, h2, h3, h4, h5, h6")), o = /* @__PURE__ */ new Set(); | ||
| return n.forEach((r) => { | ||
| const s = t(r.textContent || "").toLowerCase(); | ||
| s && o.add(s); | ||
| }), o; | ||
| } | ||
| function Ae(e) { | ||
| const t = e.match(/[^.!?\n]+[.!?]?/g); | ||
| return t ? t.map((n) => n.trim()).filter(Boolean) : []; | ||
| } | ||
| async function C(e, t, n = !1) { | ||
| const o = Ce(e, t.normalizeText), r = e.innerHTML, s = `${o.length}:${ie(o)}:${r.length}:${ie(r)}`; | ||
| if (!n && le.get(e) === s) | ||
| return v.get(e) || []; | ||
| const i = (Y.get(e) || 0) + 1; | ||
| Y.set(e, i); | ||
| const l = ce(o), c = fe(o), u = Me(o), a = [], y = t.labels; | ||
| if (t.bannedWords.length > 0) { | ||
| let w = 0; | ||
| for (const p of t.bannedWords) { | ||
| const m = new RegExp(`\\b${ve(p)}\\b`, "gi"); | ||
| let b = m.exec(o); | ||
| for (; b && !x(a, t.maxIssues); ) { | ||
| const re = b[0]; | ||
| P( | ||
| a, | ||
| { | ||
| id: z("banned-word", w), | ||
| ruleId: "banned-word", | ||
| severity: "error", | ||
| message: `${y.bannedWordMessage}: "${re}"`, | ||
| locateText: re, | ||
| suggestion: "Replace or remove banned terms." | ||
| }, | ||
| t.maxIssues | ||
| ), w += 1, b = m.exec(o); | ||
| } | ||
| if (x(a, t.maxIssues)) break; | ||
| } | ||
| } | ||
| if (!x(a, t.maxIssues) && t.requiredHeadings.length > 0) { | ||
| const w = Te(e, t.normalizeText); | ||
| let p = 0; | ||
| t.requiredHeadings.forEach((m) => { | ||
| if (x(a, t.maxIssues)) return; | ||
| const b = t.normalizeText(m).toLowerCase(); | ||
| !b || w.has(b) || (P( | ||
| a, | ||
| { | ||
| id: z("required-heading", p), | ||
| ruleId: "required-heading", | ||
| severity: "warning", | ||
| message: `${y.requiredHeadingMessage}: "${m}"`, | ||
| suggestion: `Add a heading named "${m}".` | ||
| }, | ||
| t.maxIssues | ||
| ), p += 1); | ||
| }); | ||
| } | ||
| if (!x(a, t.maxIssues)) { | ||
| const w = Ae(o); | ||
| let p = 0; | ||
| for (const m of w) { | ||
| if (x(a, t.maxIssues)) break; | ||
| const b = ce(m); | ||
| b <= t.maxSentenceWords || (P( | ||
| a, | ||
| { | ||
| id: z("sentence-length", p), | ||
| ruleId: "sentence-length", | ||
| severity: "warning", | ||
| message: `${y.sentenceLengthMessage} (${b}/${t.maxSentenceWords} words)`, | ||
| excerpt: ge(m, 200), | ||
| locateText: m.slice(0, 64), | ||
| suggestion: "Split into shorter sentences for readability." | ||
| }, | ||
| t.maxIssues | ||
| ), p += 1); | ||
| } | ||
| } | ||
| if (!x(a, t.maxIssues) && l > 0 && u < t.minReadabilityScore && P( | ||
| a, | ||
| { | ||
| id: z("readability", 0), | ||
| ruleId: "readability", | ||
| severity: "info", | ||
| message: `${y.readabilityMessage}: ${u.toFixed(1)} < ${t.minReadabilityScore}`, | ||
| suggestion: "Use shorter sentences and simpler wording." | ||
| }, | ||
| t.maxIssues | ||
| ), !x(a, t.maxIssues) && t.customRules.length > 0) { | ||
| const w = { | ||
| editor: e, | ||
| editorRoot: X(e), | ||
| text: o, | ||
| html: r, | ||
| wordCount: l, | ||
| sentenceCount: c, | ||
| readabilityScore: u | ||
| }; | ||
| for (const p of t.customRules) { | ||
| if (x(a, t.maxIssues)) break; | ||
| try { | ||
| const m = await p.evaluate(w); | ||
| if (!Array.isArray(m)) continue; | ||
| for (let b = 0; b < m.length && !x(a, t.maxIssues); b += 1) | ||
| P( | ||
| a, | ||
| Se(m[b], p.id, p.severity || "warning", b), | ||
| t.maxIssues | ||
| ); | ||
| } catch { | ||
| } | ||
| } | ||
| } | ||
| if (Y.get(e) !== i) | ||
| return v.get(e) || []; | ||
| const D = { | ||
| readabilityScore: u, | ||
| wordCount: l, | ||
| sentenceCount: c | ||
| }; | ||
| return le.set(e, s), v.set(e, a), de.set(e, D), te(e), e.dispatchEvent( | ||
| new CustomEvent("editora:content-rules-audit", { | ||
| bubbles: !0, | ||
| detail: { | ||
| issues: a, | ||
| metrics: D | ||
| } | ||
| }) | ||
| ), a; | ||
| } | ||
| function Le(e) { | ||
| return e.reduce( | ||
| (t, n) => (t[n.severity] += 1, t), | ||
| { error: 0, warning: 0, info: 0 } | ||
| ); | ||
| } | ||
| function Ie(e) { | ||
| return e === "error" ? "Error" : e === "warning" ? "Warning" : "Info"; | ||
| } | ||
| function $(e, t, n) { | ||
| const o = ke(e); | ||
| Array.from( | ||
| o.querySelectorAll( | ||
| `.rte-toolbar-button[data-command="${t}"], .editora-toolbar-button[data-command="${t}"]` | ||
| ) | ||
| ).forEach((s) => { | ||
| s.classList.toggle("active", n), s.setAttribute("data-active", n ? "true" : "false"), s.setAttribute("aria-pressed", n ? "true" : "false"); | ||
| }); | ||
| } | ||
| function U(e) { | ||
| return B.get(e) === !0; | ||
| } | ||
| function J(e, t) { | ||
| if (!t.classList.contains("show")) return; | ||
| const o = X(e).getBoundingClientRect(), r = Math.min(window.innerWidth - 20, 360); | ||
| t.style.width = `${r}px`, t.style.maxHeight = `${Math.max(220, window.innerHeight - 24)}px`; | ||
| const s = Math.max(10, o.right - r), i = Math.max(10, window.innerWidth - r - 10), l = Math.min(s, i), c = Math.max(10, Math.min(window.innerHeight - 10 - 240, o.top + 10)); | ||
| t.style.left = `${l}px`, t.style.top = `${c}px`; | ||
| } | ||
| function ue(e, t) { | ||
| const n = t.trim().toLowerCase(); | ||
| if (!n) return !1; | ||
| const o = window.getSelection(); | ||
| if (!o) return !1; | ||
| const r = document.createTreeWalker(e, NodeFilter.SHOW_TEXT, null); | ||
| let s = r.nextNode(); | ||
| for (; s; ) { | ||
| const l = s.data.toLowerCase().indexOf(n); | ||
| if (l !== -1) { | ||
| const c = document.createRange(); | ||
| c.setStart(s, l), c.setEnd(s, Math.min(s.length, l + n.length)), o.removeAllRanges(), o.addRange(c); | ||
| const u = s.parentElement; | ||
| return u && u.scrollIntoView({ behavior: "smooth", block: "center", inline: "nearest" }), e.focus({ preventScroll: !0 }), !0; | ||
| } | ||
| s = r.nextNode(); | ||
| } | ||
| return !1; | ||
| } | ||
| function He(e, t) { | ||
| if (t.selector) { | ||
| const n = e.querySelector(t.selector); | ||
| if (n) | ||
| return n.scrollIntoView({ behavior: "smooth", block: "center", inline: "nearest" }), n.focus({ preventScroll: !0 }), !0; | ||
| } | ||
| return !!(t.locateText && ue(e, t.locateText) || t.excerpt && ue(e, t.excerpt.slice(0, 64))); | ||
| } | ||
| function We(e, t) { | ||
| return (v.get(e) || []).find((o) => o.id === t); | ||
| } | ||
| function A(e, t) { | ||
| const n = T.get(e); | ||
| return typeof n == "boolean" ? n : t ? t.enableRealtime : !0; | ||
| } | ||
| function O(e, t, n) { | ||
| const o = t.querySelector('[data-action="toggle-realtime"]'); | ||
| if (!o) return; | ||
| const r = A(e, n); | ||
| o.textContent = r ? n.labels.realtimeOnText : n.labels.realtimeOffText, o.setAttribute("aria-pressed", r ? "true" : "false"), $(e, "toggleContentRulesRealtime", r); | ||
| } | ||
| function te(e) { | ||
| const t = h.get(e); | ||
| if (!t) return; | ||
| const n = d.get(e) || E; | ||
| if (!n) return; | ||
| const o = v.get(e) || [], r = de.get(e) || { | ||
| readabilityScore: 100 | ||
| }, s = t.querySelector(".rte-content-rules-count"), i = t.querySelector(".rte-content-rules-summary"), l = t.querySelector(".rte-content-rules-list"), c = t.querySelector(".rte-content-rules-live"); | ||
| if (!s || !i || !l || !c) return; | ||
| const u = Le(o); | ||
| if (s.textContent = String(o.length), i.textContent = `${n.labels.summaryPrefix}: ${o.length} | Error ${u.error} | Warning ${u.warning} | Info ${u.info} | Readability ${r.readabilityScore.toFixed(1)}`, c.textContent = `${o.length} issues. ${u.error} errors, ${u.warning} warnings, ${u.info} info.`, o.length === 0) { | ||
| l.innerHTML = `<li class="rte-content-rules-empty">${k(n.labels.noIssuesText)}</li>`; | ||
| return; | ||
| } | ||
| l.innerHTML = o.map((a) => { | ||
| const y = a.excerpt ? `<p class="rte-content-rules-excerpt">${k(a.excerpt)}</p>` : "", D = a.suggestion ? `<p class="rte-content-rules-suggestion">${k(a.suggestion)}</p>` : "", w = `${n.labels.locateText}: ${a.message}`; | ||
| return ` | ||
| <li class="rte-content-rules-item rte-content-rules-item-${a.severity}"> | ||
| <button | ||
| type="button" | ||
| class="rte-content-rules-item-btn" | ||
| data-action="focus-issue" | ||
| data-issue-id="${k(a.id)}" | ||
| data-role="issue-button" | ||
| aria-label="${k(w)}" | ||
| > | ||
| <span class="rte-content-rules-badge">${k(Ie(a.severity))}</span> | ||
| <span class="rte-content-rules-message">${k(a.message)}</span> | ||
| </button> | ||
| ${y} | ||
| ${D} | ||
| </li> | ||
| `; | ||
| }).join(""); | ||
| } | ||
| function W(e, t = !1) { | ||
| const n = h.get(e); | ||
| n && (n.classList.remove("show"), B.set(e, !1), $(e, "toggleContentRulesPanel", !1), t && e.focus({ preventScroll: !0 })); | ||
| } | ||
| function Oe(e) { | ||
| h.forEach((t, n) => { | ||
| n !== e && W(n, !1); | ||
| }); | ||
| } | ||
| function qe(e) { | ||
| const t = h.get(e); | ||
| if (t) return t; | ||
| const n = d.get(e) || E || j(), o = `rte-content-rules-panel-${pe++}`, r = document.createElement("section"); | ||
| return r.className = f, r.id = o, r.setAttribute("role", "dialog"), r.setAttribute("aria-modal", "false"), r.setAttribute("aria-label", n.labels.panelAriaLabel), r.innerHTML = ` | ||
| <header class="rte-content-rules-header"> | ||
| <h2 class="rte-content-rules-title">${k(n.labels.panelTitle)}</h2> | ||
| <button type="button" class="rte-content-rules-icon-btn" data-action="close" aria-label="${k(n.labels.closeText)}">✕</button> | ||
| </header> | ||
| <div class="rte-content-rules-body"> | ||
| <div class="rte-content-rules-topline"> | ||
| <p class="rte-content-rules-summary" aria-live="polite"></p> | ||
| <span class="rte-content-rules-count" aria-hidden="true">0</span> | ||
| </div> | ||
| <div class="rte-content-rules-controls" role="toolbar" aria-label="Content rules controls"> | ||
| <button type="button" class="rte-content-rules-btn rte-content-rules-btn-primary" data-action="run-audit">${k(n.labels.runAuditText)}</button> | ||
| <button type="button" class="rte-content-rules-btn" data-action="toggle-realtime" aria-pressed="false"></button> | ||
| </div> | ||
| <ul class="rte-content-rules-list" role="list" aria-label="Detected content rule issues"></ul> | ||
| <p class="rte-content-rules-shortcut">Shortcut: Ctrl/Cmd + Alt + Shift + R</p> | ||
| <span class="rte-content-rules-live" aria-live="polite"></span> | ||
| </div> | ||
| `, r.addEventListener("click", (s) => { | ||
| const l = s.target?.closest("[data-action]"); | ||
| if (!l) return; | ||
| const c = l.getAttribute("data-action"); | ||
| if (c) { | ||
| if (c === "close") { | ||
| W(e, !0); | ||
| return; | ||
| } | ||
| if (c === "run-audit") { | ||
| const u = d.get(e) || E || n; | ||
| C(e, u, !0); | ||
| return; | ||
| } | ||
| if (c === "toggle-realtime") { | ||
| const a = !A(e, d.get(e) || E || n); | ||
| if (T.set(e, a), O(e, r, d.get(e) || E || n), a) { | ||
| const y = d.get(e) || E || n; | ||
| C(e, y, !0); | ||
| } | ||
| return; | ||
| } | ||
| if (c === "focus-issue") { | ||
| const u = l.getAttribute("data-issue-id") || "", a = We(e, u); | ||
| if (!a) return; | ||
| He(e, a), W(e, !1); | ||
| } | ||
| } | ||
| }), r.addEventListener("keydown", (s) => { | ||
| if (s.key === "Escape") { | ||
| s.preventDefault(), W(e, !0); | ||
| return; | ||
| } | ||
| if (s.key !== "ArrowDown" && s.key !== "ArrowUp") return; | ||
| const i = Array.from(r.querySelectorAll('[data-role="issue-button"]')); | ||
| if (i.length === 0) return; | ||
| const l = document.activeElement, c = i.findIndex((y) => y === l); | ||
| if (c === -1) return; | ||
| s.preventDefault(); | ||
| const u = s.key === "ArrowDown" ? 1 : -1, a = (c + u + i.length) % i.length; | ||
| i[a].focus(); | ||
| }), G(r, e), document.body.appendChild(r), h.set(e, r), B.set(e, !1), O(e, r, n), r; | ||
| } | ||
| function ne(e) { | ||
| const t = qe(e); | ||
| Oe(e), t.classList.add("show"), B.set(e, !0), G(t, e), J(e, t), te(e), $(e, "toggleContentRulesPanel", !0), t.querySelector('[data-action="run-audit"]')?.focus(); | ||
| } | ||
| function Q(e, t) { | ||
| const n = U(e); | ||
| return (typeof t == "boolean" ? t : !n) ? ne(e) : W(e, !1), !0; | ||
| } | ||
| function me(e) { | ||
| const t = V.get(e); | ||
| typeof t == "number" && (window.clearTimeout(t), _.delete(t), V.delete(e)); | ||
| } | ||
| function be(e) { | ||
| const t = d.get(e) || E; | ||
| if (!t || !A(e, t)) return; | ||
| me(e); | ||
| const n = window.setTimeout(() => { | ||
| _.delete(n), V.delete(e), C(e, t, !1); | ||
| }, t.debounceMs); | ||
| _.add(n), V.set(e, n); | ||
| } | ||
| function Pe(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "r"; | ||
| } | ||
| function ze(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "l"; | ||
| } | ||
| function _e(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "t"; | ||
| } | ||
| function Be() { | ||
| if (typeof document > "u" || document.getElementById(se)) return; | ||
| const e = document.createElement("style"); | ||
| e.id = se, e.textContent = ` | ||
| .rte-toolbar-group-items.content-rules, | ||
| .editora-toolbar-group-items.content-rules { | ||
| display: flex; | ||
| border: 1px solid #ccc; | ||
| border-radius: 3px; | ||
| background: #fff; | ||
| } | ||
| .rte-toolbar-group-items.content-rules .rte-toolbar-button, | ||
| .editora-toolbar-group-items.content-rules .editora-toolbar-button { | ||
| border: none; | ||
| border-radius: 0px; | ||
| } | ||
| .rte-toolbar-group-items.content-rules .rte-toolbar-button, | ||
| .editora-toolbar-group-items.content-rules .editora-toolbar-button { | ||
| border-right: 1px solid #ccc; | ||
| } | ||
| .rte-toolbar-group-items.content-rules .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.content-rules .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| .rte-toolbar-button[data-command="toggleContentRulesRealtime"].active, | ||
| .editora-toolbar-button[data-command="toggleContentRulesRealtime"].active { | ||
| background-color: #ccc; | ||
| } | ||
| ${q} .rte-toolbar-group-items.content-rules, | ||
| ${q} .editora-toolbar-group-items.content-rules { | ||
| border-color: #566275; | ||
| } | ||
| ${q} .rte-toolbar-group-items.content-rules .rte-toolbar-button, | ||
| ${q} .editora-toolbar-group-items.content-rules .editora-toolbar-button | ||
| { | ||
| border-color: #566275; | ||
| } | ||
| ${q} .rte-toolbar-group-items.content-rules .rte-toolbar-button svg{ | ||
| fill: none; | ||
| } | ||
| .${f} { | ||
| position: fixed; | ||
| z-index: 12000; | ||
| display: none; | ||
| width: min(360px, calc(100vw - 20px)); | ||
| max-height: calc(100vh - 20px); | ||
| border: 1px solid #d1d5db; | ||
| border-radius: 14px; | ||
| background: #ffffff; | ||
| color: #111827; | ||
| box-shadow: 0 18px 45px rgba(15, 23, 42, 0.25); | ||
| overflow: hidden; | ||
| } | ||
| .${f}.show { | ||
| display: flex; | ||
| flex-direction: column; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark { | ||
| border-color: #334155; | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| box-shadow: 0 20px 46px rgba(2, 6, 23, 0.68); | ||
| } | ||
| .rte-content-rules-header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| padding: 12px 14px; | ||
| border-bottom: 1px solid #e5e7eb; | ||
| background: linear-gradient(180deg, #f9fafb 0%, #f3f4f6 100%); | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-header { | ||
| border-color: #1e293b; | ||
| background: linear-gradient(180deg, #111827 0%, #0f172a 100%); | ||
| } | ||
| .rte-content-rules-title { | ||
| margin: 0; | ||
| font-size: 15px; | ||
| line-height: 1.2; | ||
| font-weight: 700; | ||
| } | ||
| .rte-content-rules-icon-btn { | ||
| width: 34px; | ||
| height: 34px; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| font-weight: 600; | ||
| padding: 0; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| cursor: pointer; | ||
| } | ||
| .rte-content-rules-icon-btn:hover, | ||
| .rte-content-rules-icon-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-icon-btn { | ||
| background: #0f172a; | ||
| border-color: #475569; | ||
| color: #e2e8f0; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-icon-btn:hover, | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-icon-btn:focus-visible { | ||
| border-color: #60a5fa; | ||
| box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.24); | ||
| } | ||
| .rte-content-rules-body { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 10px; | ||
| padding: 12px; | ||
| overflow: auto; | ||
| } | ||
| .rte-content-rules-topline { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| } | ||
| .rte-content-rules-summary { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #475569; | ||
| flex: 1; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-summary { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-content-rules-count { | ||
| min-width: 32px; | ||
| height: 32px; | ||
| border-radius: 999px; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| font-weight: 700; | ||
| font-size: 13px; | ||
| border: 1px solid #cbd5e1; | ||
| background: #f8fafc; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-count { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-content-rules-controls { | ||
| display: flex; | ||
| gap: 8px; | ||
| flex-wrap: wrap; | ||
| } | ||
| .rte-content-rules-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| height: 34px; | ||
| padding: 0 10px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| cursor: pointer; | ||
| } | ||
| .rte-content-rules-btn:hover, | ||
| .rte-content-rules-btn:focus-visible { | ||
| border-color: #94a3b8; | ||
| background: #f8fafc; | ||
| outline: none; | ||
| } | ||
| .rte-content-rules-btn-primary { | ||
| border-color: #0284c7; | ||
| background: #0ea5e9; | ||
| color: #f8fafc; | ||
| } | ||
| .rte-content-rules-btn-primary:hover, | ||
| .rte-content-rules-btn-primary:focus-visible { | ||
| border-color: #0369a1; | ||
| background: #0284c7; | ||
| color: #ffffff; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-btn { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-btn:hover, | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-btn:focus-visible { | ||
| border-color: #475569; | ||
| background: #1e293b; | ||
| } | ||
| .rte-content-rules-list { | ||
| list-style: none; | ||
| margin: 0; | ||
| padding: 0; | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 8px; | ||
| max-height: min(55vh, 420px); | ||
| overflow: auto; | ||
| } | ||
| .rte-content-rules-item { | ||
| border: 1px solid #e2e8f0; | ||
| border-radius: 10px; | ||
| padding: 8px; | ||
| background: #ffffff; | ||
| } | ||
| .rte-content-rules-item-error { | ||
| border-color: #fca5a5; | ||
| background: #fef2f2; | ||
| } | ||
| .rte-content-rules-item-warning { | ||
| border-color: #fcd34d; | ||
| background: #fffbeb; | ||
| } | ||
| .rte-content-rules-item-info { | ||
| border-color: #93c5fd; | ||
| background: #eff6ff; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-item { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-item-error { | ||
| border-color: #7f1d1d; | ||
| background: #2b0b11; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-item-warning { | ||
| border-color: #78350f; | ||
| background: #2b1907; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-item-info { | ||
| border-color: #1d4ed8; | ||
| background: #0a162f; | ||
| } | ||
| .rte-content-rules-item-btn { | ||
| width: 100%; | ||
| border: none; | ||
| background: transparent; | ||
| display: flex; | ||
| align-items: flex-start; | ||
| gap: 8px; | ||
| text-align: left; | ||
| padding: 0; | ||
| color: inherit; | ||
| cursor: pointer; | ||
| } | ||
| .rte-content-rules-item-btn:focus-visible { | ||
| outline: 2px solid #0284c7; | ||
| outline-offset: 3px; | ||
| border-radius: 6px; | ||
| } | ||
| .rte-content-rules-badge { | ||
| flex: 0 0 auto; | ||
| margin-top: 1px; | ||
| border-radius: 999px; | ||
| border: 1px solid currentColor; | ||
| padding: 1px 8px; | ||
| font-size: 10px; | ||
| font-weight: 700; | ||
| line-height: 1.3; | ||
| text-transform: uppercase; | ||
| opacity: 0.86; | ||
| } | ||
| .rte-content-rules-message { | ||
| font-size: 13px; | ||
| line-height: 1.35; | ||
| font-weight: 600; | ||
| } | ||
| .rte-content-rules-excerpt, | ||
| .rte-content-rules-suggestion { | ||
| margin: 8px 0 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #334155; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-excerpt, | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-suggestion { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-content-rules-empty { | ||
| border: 1px dashed #cbd5e1; | ||
| border-radius: 10px; | ||
| padding: 10px; | ||
| font-size: 13px; | ||
| color: #475569; | ||
| background: #f8fafc; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-empty { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #94a3b8; | ||
| } | ||
| .rte-content-rules-shortcut { | ||
| margin: 2px 0 0; | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| } | ||
| .${f}.rte-content-rules-theme-dark .rte-content-rules-shortcut { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-content-rules-live { | ||
| position: absolute; | ||
| width: 1px; | ||
| height: 1px; | ||
| margin: -1px; | ||
| padding: 0; | ||
| overflow: hidden; | ||
| clip: rect(0 0 0 0); | ||
| border: 0; | ||
| } | ||
| @media (max-width: 768px) { | ||
| .${f} { | ||
| left: 10px !important; | ||
| right: 10px; | ||
| top: 10px !important; | ||
| width: auto !important; | ||
| max-height: calc(100vh - 20px); | ||
| } | ||
| .rte-content-rules-list { | ||
| max-height: 45vh; | ||
| } | ||
| } | ||
| `, document.head.appendChild(e); | ||
| } | ||
| function De(e) { | ||
| E = e, L || (L = (t) => { | ||
| const o = t.target?.closest(R); | ||
| if (!o) return; | ||
| g = o, d.has(o) || d.set(o, e), v.has(o) || v.set(o, []), T.has(o) || T.set(o, e.enableRealtime); | ||
| const r = h.get(o); | ||
| r && (G(r, o), J(o, r), O(o, r, d.get(o) || e)), $(o, "toggleContentRulesPanel", U(o)), $(o, "toggleContentRulesRealtime", A(o, e)); | ||
| }, document.addEventListener("focusin", L, !0)), I || (I = (t) => { | ||
| const o = t.target?.closest(R); | ||
| o && (g = o, be(o)); | ||
| }, document.addEventListener("input", I, !0)), H || (H = (t) => { | ||
| if (t.defaultPrevented || t.target?.closest("input, textarea, select")) return; | ||
| const o = t.key === "Escape", r = Pe(t), s = ze(t), i = _e(t); | ||
| if (!o && !r && !s && !i) | ||
| return; | ||
| const l = M(void 0, !1); | ||
| if (!l || Z(l)) return; | ||
| const c = d.get(l) || E || e; | ||
| if (d.set(l, c), g = l, o && U(l)) { | ||
| t.preventDefault(), W(l, !0); | ||
| return; | ||
| } | ||
| if (r) { | ||
| t.preventDefault(), t.stopPropagation(), Q(l); | ||
| return; | ||
| } | ||
| if (s) { | ||
| t.preventDefault(), t.stopPropagation(), C(l, c, !0), ne(l); | ||
| return; | ||
| } | ||
| if (i) { | ||
| t.preventDefault(), t.stopPropagation(); | ||
| const u = !A(l, c); | ||
| T.set(l, u); | ||
| const a = h.get(l); | ||
| a && O(l, a, c), $(l, "toggleContentRulesRealtime", u), u && C(l, c, !0); | ||
| } | ||
| }, document.addEventListener("keydown", H, !0)), S || (S = () => { | ||
| h.forEach((t, n) => { | ||
| if (!n.isConnected || !t.isConnected) { | ||
| me(n), t.remove(), h.delete(n), B.delete(n); | ||
| return; | ||
| } | ||
| G(t, n), J(n, t); | ||
| }); | ||
| }, window.addEventListener("scroll", S, !0), window.addEventListener("resize", S)); | ||
| } | ||
| function Ne() { | ||
| L && (document.removeEventListener("focusin", L, !0), L = null), I && (document.removeEventListener("input", I, !0), I = null), H && (document.removeEventListener("keydown", H, !0), H = null), S && (window.removeEventListener("scroll", S, !0), window.removeEventListener("resize", S), S = null), h.forEach((e) => { | ||
| e.remove(); | ||
| }), h.clear(), E = null, g = null; | ||
| } | ||
| const Ke = (e = {}) => { | ||
| const t = j(e); | ||
| return Be(), { | ||
| name: "contentRules", | ||
| toolbar: [ | ||
| { | ||
| id: "contentRulesGroup", | ||
| label: "Content Rules", | ||
| type: "group", | ||
| command: "contentRules", | ||
| items: [ | ||
| { | ||
| id: "contentRules", | ||
| label: "Content Rules", | ||
| command: "toggleContentRulesPanel", | ||
| shortcut: "Mod-Alt-Shift-r", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M6 3h9l5 5v11a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2Zm8 2v4h4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/><path d="M8 11h8M8 15h8M8 19h5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>' | ||
| }, | ||
| { | ||
| id: "contentRulesAudit", | ||
| label: "Run Rules Audit", | ||
| command: "runContentRulesAudit", | ||
| shortcut: "Mod-Alt-Shift-l", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M4 12h4l2 5 4-10 2 5h4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/><circle cx="12" cy="12" r="9" stroke="currentColor" stroke-width="1.6"/></svg>' | ||
| }, | ||
| { | ||
| id: "contentRulesRealtime", | ||
| label: "Toggle Realtime Rules", | ||
| command: "toggleContentRulesRealtime", | ||
| shortcut: "Mod-Alt-Shift-t", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M12 3v4M12 17v4M4.9 4.9l2.8 2.8M16.3 16.3l2.8 2.8M3 12h4M17 12h4M4.9 19.1l2.8-2.8M16.3 7.7l2.8-2.8" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><circle cx="12" cy="12" r="4" stroke="currentColor" stroke-width="1.6"/></svg>' | ||
| } | ||
| ] | ||
| } | ||
| ], | ||
| commands: { | ||
| contentRules: (n, o) => { | ||
| const r = M(o); | ||
| if (!r || Z(r)) return !1; | ||
| const s = d.get(r) || t; | ||
| return d.set(r, s), g = r, Q(r, !0), C(r, s, !1), !0; | ||
| }, | ||
| toggleContentRulesPanel: (n, o) => { | ||
| const r = M(o); | ||
| if (!r || Z(r)) return !1; | ||
| g = r; | ||
| const s = d.get(r) || t; | ||
| d.set(r, s); | ||
| const i = Q(r, typeof n == "boolean" ? n : void 0); | ||
| return U(r) && C(r, s, !1), i; | ||
| }, | ||
| runContentRulesAudit: async (n, o) => { | ||
| const r = M(o); | ||
| if (!r) return !1; | ||
| g = r; | ||
| const s = d.get(r) || t; | ||
| return d.set(r, s), await C(r, s, !0), ne(r), !0; | ||
| }, | ||
| toggleContentRulesRealtime: (n, o) => { | ||
| const r = M(o); | ||
| if (!r) return !1; | ||
| g = r; | ||
| const s = d.get(r) || t; | ||
| d.set(r, s); | ||
| const i = typeof n == "boolean" ? n : !A(r, s); | ||
| T.set(r, i); | ||
| const l = h.get(r); | ||
| return l && O(r, l, s), $(r, "toggleContentRulesRealtime", i), i && C(r, s, !0), !0; | ||
| }, | ||
| getContentRulesIssues: (n, o) => { | ||
| const r = M(o); | ||
| if (!r) return !1; | ||
| const s = v.get(r) || []; | ||
| if (typeof n == "function") | ||
| try { | ||
| n(s); | ||
| } catch { | ||
| } | ||
| return r.__contentRulesIssues = s, r.dispatchEvent( | ||
| new CustomEvent("editora:content-rules-issues", { | ||
| bubbles: !0, | ||
| detail: { issues: s } | ||
| }) | ||
| ), !0; | ||
| }, | ||
| setContentRulesOptions: (n, o) => { | ||
| const r = M(o); | ||
| if (!r || !n || typeof n != "object") return !1; | ||
| const s = d.get(r) || t, i = j({ | ||
| ...s, | ||
| ...n, | ||
| labels: { | ||
| ...s.labels, | ||
| ...n.labels || {} | ||
| } | ||
| }); | ||
| d.set(r, i), typeof n.enableRealtime == "boolean" && T.set(r, n.enableRealtime), A(r, i) && C(r, i, !0); | ||
| const l = h.get(r); | ||
| if (l) { | ||
| l.setAttribute("aria-label", i.labels.panelAriaLabel); | ||
| const c = l.querySelector(".rte-content-rules-title"); | ||
| c && (c.textContent = i.labels.panelTitle), O(r, l, i), te(r); | ||
| } | ||
| return !0; | ||
| } | ||
| }, | ||
| keymap: { | ||
| "Mod-Alt-Shift-r": "toggleContentRulesPanel", | ||
| "Mod-Alt-Shift-R": "toggleContentRulesPanel", | ||
| "Mod-Alt-Shift-l": "runContentRulesAudit", | ||
| "Mod-Alt-Shift-L": "runContentRulesAudit", | ||
| "Mod-Alt-Shift-t": "toggleContentRulesRealtime", | ||
| "Mod-Alt-Shift-T": "toggleContentRulesRealtime" | ||
| }, | ||
| init: function(o) { | ||
| N += 1; | ||
| const r = this && typeof this.__pluginConfig == "object" ? j({ ...t, ...this.__pluginConfig }) : t; | ||
| De(r); | ||
| const s = M( | ||
| o && o.editorElement ? { editorElement: o.editorElement } : void 0, | ||
| !1 | ||
| ); | ||
| s && (g = s, d.set(s, r), T.set(s, r.enableRealtime), v.set(s, []), $(s, "toggleContentRulesPanel", !1), $(s, "toggleContentRulesRealtime", r.enableRealtime), r.enableRealtime && be(s)); | ||
| }, | ||
| destroy: () => { | ||
| N = Math.max(0, N - 1), !(N > 0) && (_.forEach((n) => { | ||
| window.clearTimeout(n); | ||
| }), _.clear(), Ne()); | ||
| } | ||
| }; | ||
| }; | ||
| export { | ||
| Ke as ContentRulesPlugin | ||
| }; |
| "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const A=".rte-content, .editora-content",C='.rte-data-binding[data-binding="true"]',it="rte-data-binding-styles",g="rte-data-binding-dialog-overlay",f=':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)',pt={dialogTitleInsert:"Insert Data Binding",dialogTitleEdit:"Edit Data Binding",keyLabel:"Data Key",keyPlaceholder:"user.firstName",fallbackLabel:"Fallback Text",fallbackPlaceholder:"Guest",formatLabel:"Format",currencyLabel:"Currency",currencyPlaceholder:"USD",saveText:"Save",cancelText:"Cancel",previewOnText:"Preview On",previewOffText:"Preview Off",tokenAriaPrefix:"Data binding token"},v=new WeakMap,W=new WeakMap,b=new WeakMap,N=new WeakMap,G=new WeakMap;let R=null,h=null,U=0,P=null,O=null,M=null,_=null;function yt(t){return{...pt,...t||{}}}function ot(t={}){const n=(t.locale||(typeof navigator<"u"?navigator.language:"en-US")).trim()||"en-US";return{data:t.data,getData:t.getData,api:t.api,cacheTtlMs:Math.max(0,Number(t.cacheTtlMs??3e4)),labels:yt(t.labels),defaultFormat:t.defaultFormat||"text",defaultFallback:t.defaultFallback||"",locale:n,numberFormatOptions:t.numberFormatOptions||{},dateFormatOptions:t.dateFormatOptions||{year:"numeric",month:"short",day:"2-digit"}}}function y(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function dt(t){return t?t.nodeType===Node.ELEMENT_NODE?t:t.parentElement:null}function j(t){return t.closest("[data-editora-editor], .rte-editor, .editora-editor, editora-editor")||t}function q(t){return t?(t.getAttribute("data-theme")||t.getAttribute("theme")||"").toLowerCase()==="dark"?!0:t.classList.contains("dark")||t.classList.contains("editora-theme-dark")||t.classList.contains("rte-theme-dark"):!1}function ht(t){const n=j(t);if(q(n))return!0;const a=n.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark");return q(a)?!0:q(document.documentElement)||q(document.body)}function D(t,n=!0){if(t?.contentElement instanceof HTMLElement)return t.contentElement;if(t?.editorElement instanceof HTMLElement){const e=t.editorElement;if(e.matches(A))return e;const i=e.querySelector(A);if(i instanceof HTMLElement)return i}const a=window.getSelection();if(a&&a.rangeCount>0){const e=a.getRangeAt(0).startContainer,o=dt(e)?.closest(A);if(o)return o}const r=document.activeElement;if(r){if(r.matches(A))return r;const e=r.closest(A);if(e)return e}return h&&h.isConnected?h:n?document.querySelector(A):null}function K(t){return t.getAttribute("contenteditable")==="false"||t.getAttribute("data-readonly")==="true"}function lt(t){const n=window.getSelection();if(!n||n.rangeCount===0)return null;const a=n.getRangeAt(0);return t.contains(a.commonAncestorContainer)?a.cloneRange():null}function st(t,n){const a=window.getSelection();a&&(a.removeAllRanges(),a.addRange(n),t.focus({preventScroll:!0}))}function kt(t,n){const a=(n||"").trim();if(a)return a.split(".").filter(Boolean).reduce((r,e)=>{if(!(r==null||typeof r!="object"))return r[e]},t)}function vt(){if(typeof document>"u"||document.getElementById(it))return;const t=document.createElement("style");t.id=it,t.textContent=` | ||
| .rte-data-binding { | ||
| display: inline-flex; | ||
| align-items: center; | ||
| max-width: 100%; | ||
| gap: 5px; | ||
| padding: 2px 8px 2px 7px; | ||
| border-radius: 999px; | ||
| border: 1px dashed #8b5cf6; | ||
| background: linear-gradient(180deg, #f9f7ff 0%, #f1edff 100%); | ||
| color: #4c1d95; | ||
| font-size: 0.88em; | ||
| font-weight: 600; | ||
| line-height: 1.3; | ||
| vertical-align: baseline; | ||
| white-space: nowrap; | ||
| overflow: hidden; | ||
| text-overflow: ellipsis; | ||
| user-select: all; | ||
| font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; | ||
| cursor: pointer; | ||
| } | ||
| .rte-data-binding::before { | ||
| content: '{}'; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| min-width: 14px; | ||
| height: 14px; | ||
| border-radius: 999px; | ||
| background: rgba(139, 92, 246, 0.16); | ||
| color: #5b21b6; | ||
| font-size: 10px; | ||
| font-weight: 700; | ||
| line-height: 1; | ||
| letter-spacing: -0.2px; | ||
| flex: 0 0 auto; | ||
| } | ||
| .rte-data-binding.rte-data-binding-preview { | ||
| border-style: solid; | ||
| background: #ecfdf5; | ||
| border-color: #34d399; | ||
| color: #065f46; | ||
| user-select: text; | ||
| } | ||
| .rte-data-binding.rte-data-binding-preview::before { | ||
| content: '='; | ||
| background: rgba(16, 185, 129, 0.15); | ||
| color: #047857; | ||
| letter-spacing: 0; | ||
| } | ||
| .rte-data-binding.rte-data-binding-missing { | ||
| border-style: dashed; | ||
| border-color: #f87171; | ||
| background: #fef2f2; | ||
| color: #991b1b; | ||
| } | ||
| .rte-data-binding-dialog-overlay { | ||
| position: fixed; | ||
| inset: 0; | ||
| z-index: 2147483646; | ||
| background: rgba(15, 23, 42, 0.54); | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| padding: 20px; | ||
| } | ||
| .rte-data-binding-dialog { | ||
| width: min(560px, 96vw); | ||
| max-height: min(86vh, 720px); | ||
| border: 1px solid #dbe3ec; | ||
| border-radius: 8px; | ||
| background: #ffffff; | ||
| box-shadow: 0 24px 50px rgba(15, 23, 42, 0.26); | ||
| display: flex; | ||
| flex-direction: column; | ||
| overflow: hidden; | ||
| } | ||
| .rte-data-binding-header, | ||
| .rte-data-binding-footer { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 10px; | ||
| padding: 12px 14px; | ||
| background: #f8fafc; | ||
| border-bottom: 1px solid #e2e8f0; | ||
| } | ||
| .rte-data-binding-footer { | ||
| justify-content: flex-end; | ||
| border-bottom: 0; | ||
| border-top: 1px solid #e2e8f0; | ||
| } | ||
| .rte-data-binding-title { | ||
| margin: 0; | ||
| font-size: 16px; | ||
| font-weight: 700; | ||
| color: #0f172a; | ||
| } | ||
| .rte-data-binding-body { | ||
| padding: 14px; | ||
| overflow: auto; | ||
| display: grid; | ||
| gap: 12px; | ||
| grid-template-columns: 1fr; | ||
| } | ||
| .rte-data-binding-field { | ||
| display: grid; | ||
| gap: 6px; | ||
| } | ||
| .rte-data-binding-field label { | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| color: #334155; | ||
| } | ||
| .rte-data-binding-field input, | ||
| .rte-data-binding-field select { | ||
| width: 100%; | ||
| min-height: 36px; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| padding: 8px 10px; | ||
| font-size: 13px; | ||
| line-height: 1.4; | ||
| color: #0f172a; | ||
| background: #ffffff; | ||
| box-sizing: border-box; | ||
| } | ||
| .rte-data-binding-help { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| color: #64748b; | ||
| } | ||
| .rte-data-binding-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| min-height: 34px; | ||
| padding: 6px 12px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| font-size: 13px; | ||
| cursor: pointer; | ||
| } | ||
| .rte-data-binding-btn-primary { | ||
| background: #2563eb; | ||
| border-color: #2563eb; | ||
| color: #ffffff; | ||
| } | ||
| .rte-data-binding-btn-primary:hover { | ||
| background: #1d4ed8; | ||
| } | ||
| .rte-toolbar-group-items.data-binding, | ||
| .editora-toolbar-group-items.data-binding { | ||
| display: flex; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| overflow: hidden; | ||
| background: #ffffff; | ||
| } | ||
| .rte-toolbar-group-items.data-binding .rte-toolbar-item, | ||
| .editora-toolbar-group-items.data-binding .editora-toolbar-item { | ||
| display: flex; | ||
| } | ||
| .rte-toolbar-group-items.data-binding .rte-toolbar-button, | ||
| .editora-toolbar-group-items.data-binding .editora-toolbar-button { | ||
| border: 0; | ||
| border-radius: 0; | ||
| border-right: 1px solid #cbd5e1; | ||
| } | ||
| .rte-toolbar-group-items.data-binding .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.data-binding .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: 0; | ||
| } | ||
| .rte-data-binding-btn:focus-visible, | ||
| .rte-data-binding-field input:focus-visible, | ||
| .rte-data-binding-field select:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| ${f} .rte-data-binding, | ||
| .${g}.rte-data-binding-theme-dark .rte-data-binding { | ||
| background: linear-gradient(180deg, #3b0764 0%, #2e1065 100%); | ||
| border-color: #a78bfa; | ||
| color: #ede9fe; | ||
| } | ||
| ${f} .rte-data-binding::before, | ||
| .${g}.rte-data-binding-theme-dark .rte-data-binding::before { | ||
| background: rgba(167, 139, 250, 0.22); | ||
| color: #ddd6fe; | ||
| } | ||
| ${f} .rte-data-binding.rte-data-binding-preview, | ||
| .${g}.rte-data-binding-theme-dark .rte-data-binding.rte-data-binding-preview { | ||
| background: #064e3b; | ||
| border-color: #10b981; | ||
| color: #d1fae5; | ||
| } | ||
| ${f} .rte-data-binding.rte-data-binding-missing, | ||
| .${g}.rte-data-binding-theme-dark .rte-data-binding.rte-data-binding-missing { | ||
| background: #7f1d1d; | ||
| border-color: #ef4444; | ||
| color: #fee2e2; | ||
| } | ||
| ${f} .rte-toolbar-group-items.data-binding, | ||
| ${f} .editora-toolbar-group-items.data-binding { | ||
| display: flex; | ||
| border: 1px solid #566275; | ||
| border-radius: 6px; | ||
| overflow: hidden; | ||
| } | ||
| ${f} .rte-toolbar-group-items.data-binding .rte-toolbar-button, | ||
| ${f} .editora-toolbar-group-items.data-binding .editora-toolbar-button { | ||
| border-right-color: #566275; | ||
| } | ||
| ${f} .rte-data-binding-dialog, | ||
| .${g}.rte-data-binding-theme-dark .rte-data-binding-dialog { | ||
| background: #1f2937; | ||
| border-color: #334155; | ||
| } | ||
| ${f} .rte-data-binding-header, | ||
| ${f} .rte-data-binding-footer, | ||
| .${g}.rte-data-binding-theme-dark .rte-data-binding-header, | ||
| .${g}.rte-data-binding-theme-dark .rte-data-binding-footer { | ||
| background: #111827; | ||
| border-color: #334155; | ||
| } | ||
| ${f} .rte-data-binding-title, | ||
| ${f} .rte-data-binding-field label, | ||
| .${g}.rte-data-binding-theme-dark .rte-data-binding-title, | ||
| .${g}.rte-data-binding-theme-dark .rte-data-binding-field label { | ||
| color: #e2e8f0; | ||
| } | ||
| ${f} .rte-data-binding-help, | ||
| .${g}.rte-data-binding-theme-dark .rte-data-binding-help { | ||
| color: #94a3b8; | ||
| } | ||
| ${f} .rte-data-binding-field input, | ||
| ${f} .rte-data-binding-field select, | ||
| ${f} .rte-data-binding-btn, | ||
| .${g}.rte-data-binding-theme-dark .rte-data-binding-field input, | ||
| .${g}.rte-data-binding-theme-dark .rte-data-binding-field select, | ||
| .${g}.rte-data-binding-theme-dark .rte-data-binding-btn { | ||
| background: #0f172a; | ||
| border-color: #475569; | ||
| color: #e2e8f0; | ||
| } | ||
| ${f} .rte-data-binding-btn-primary, | ||
| .${g}.rte-data-binding-theme-dark .rte-data-binding-btn-primary { | ||
| background: #2563eb; | ||
| border-color: #2563eb; | ||
| color: #ffffff; | ||
| } | ||
| `,document.head.appendChild(t)}function J(t){t.dispatchEvent(new Event("input",{bubbles:!0}))}function Y(t,n){if(n===t.innerHTML)return;const a=window.execEditorCommand||window.executeEditorCommand;if(typeof a=="function")try{a("recordDomTransaction",t,n,t.innerHTML)}catch{}}function H(t,n){return{key:String(t.key||"").trim(),fallback:String(t.fallback??n.defaultFallback??""),format:t.format||n.defaultFormat||"text",currency:String(t.currency||"USD").trim().toUpperCase()||"USD"}}function ct(t){return`{{${t.key}}}`}function ut(t,n){const a=document.createElement("span");return a.className="rte-data-binding",a.setAttribute("data-binding","true"),a.setAttribute("data-binding-key",t.key),a.setAttribute("data-binding-fallback",t.fallback||""),a.setAttribute("data-binding-format",t.format||"text"),a.setAttribute("data-binding-currency",t.currency||"USD"),a.setAttribute("contenteditable","false"),a.setAttribute("spellcheck","false"),a.setAttribute("draggable","false"),a.setAttribute("tabindex","0"),a.setAttribute("role","button"),a.setAttribute("aria-label",`${n.tokenAriaPrefix}: ${t.key}. Press Enter to edit.`),a.textContent=ct(t),a}function Z(t,n){return H({key:t.getAttribute("data-binding-key")||"",fallback:t.getAttribute("data-binding-fallback")||n.defaultFallback,format:t.getAttribute("data-binding-format")||n.defaultFormat,currency:t.getAttribute("data-binding-currency")||"USD"},n)}function X(t,n,a){t.classList.add("rte-data-binding"),t.setAttribute("data-binding","true"),t.setAttribute("data-binding-key",n.key),t.setAttribute("data-binding-fallback",n.fallback||""),t.setAttribute("data-binding-format",n.format||"text"),t.setAttribute("data-binding-currency",n.currency||"USD"),t.setAttribute("contenteditable","false"),t.setAttribute("spellcheck","false"),t.setAttribute("draggable","false"),t.setAttribute("tabindex","0"),t.setAttribute("role","button"),t.setAttribute("aria-label",`${a.tokenAriaPrefix}: ${n.key}. Press Enter to edit.`)}function V(t,n){const a=Array.from(t.querySelectorAll(C));return a.forEach(r=>{const e=Z(r,n);X(r,e,n.labels)}),a}function Q(t){const n=window.getSelection();if(n&&n.rangeCount>0){const e=n.getRangeAt(0).startContainer,o=dt(e)?.closest(C);if(o&&t.contains(o))return o}const r=document.activeElement?.closest(C);return r&&t.contains(r)?r:null}function ft(){R&&(R.cleanup(),R=null)}function tt(t,n,a){const r=j(t);Array.from(r.querySelectorAll('[data-command="toggleDataBindingPreview"]')).forEach(i=>{if(i.setAttribute("data-active",n?"true":"false"),i.classList.toggle("active",n),i.setAttribute("aria-pressed",n?"true":"false"),a){const o=n?a.labels.previewOnText:a.labels.previewOffText;i.setAttribute("title",o),i.setAttribute("aria-label",o)}})}function xt(t,n,a){const r=n.format||"text";if(t==null)return n.fallback||"";if(r==="json"){if(typeof t=="string")return t;try{return JSON.stringify(t)}catch{return String(t)}}if(r==="date"){const e=t instanceof Date?t:new Date(String(t));if(Number.isNaN(e.getTime()))return String(t);try{return new Intl.DateTimeFormat(a.locale,a.dateFormatOptions).format(e)}catch{return e.toISOString()}}if(r==="number"||r==="currency"){const e=typeof t=="number"?t:Number(t);if(!Number.isFinite(e))return String(t);const i={...a.numberFormatOptions};if(r==="currency"){const o=(n.currency||"USD").toUpperCase();Object.assign(i,{style:"currency",currency:o})}try{return new Intl.NumberFormat(a.locale,i).format(e)}catch{return String(e)}}return String(t)}function T(t,n,a,r){const e=Z(t,n),i=e.key;if(t.classList.remove("rte-data-binding-preview","rte-data-binding-missing"),!a){t.textContent=ct(e),t.setAttribute("aria-label",`${n.labels.tokenAriaPrefix}: ${i}. Press Enter to edit.`);return}const o=kt(r,i),l=o==null,d=l?e.fallback||"":xt(o,e,n);t.textContent=d||e.fallback||"",t.classList.add("rte-data-binding-preview"),l&&!(e.fallback||"").trim()&&t.classList.add("rte-data-binding-missing"),t.setAttribute("aria-label",`${n.labels.tokenAriaPrefix}: ${i} = ${t.textContent||""}. Press Enter to edit.`)}function x(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function wt(t,n){return n?n.split(".").filter(Boolean).reduce((a,r)=>{if(!(!x(a)&&!Array.isArray(a)))return a[r]},t):t}function Et(t,n,a){const r=n.api,e=j(t),i={editor:t,editorRoot:e,signal:a};if(r.buildRequest){const p=r.buildRequest(i);return{url:p.url,init:{...p.init||{},signal:a}}}const o=(r.method||"GET").toUpperCase(),l=typeof r.headers=="function"?r.headers(i):r.headers||{},d=typeof r.params=="function"?r.params(i):r.params,c=new URL(r.url,window.location.origin);d&&Object.entries(d).forEach(([p,m])=>{m!=null&&c.searchParams.set(p,String(m))});const u={method:o,headers:{...l},credentials:r.credentials,mode:r.mode,cache:r.cache,signal:a};if(o!=="GET"&&o!=="HEAD"){const p=typeof r.body=="function"?r.body(i):r.body;if(p!=null)if(x(p)){u.body=JSON.stringify(p);const m=u.headers;!m["Content-Type"]&&!m["content-type"]&&(m["Content-Type"]="application/json")}else u.body=p}return{url:c.toString(),init:u}}async function Dt(t,n){const a=n.api;if(!a)return{};const r=new AbortController,e=j(t),i={editor:t,editorRoot:e,signal:r.signal},o=Math.max(0,Number(a.timeoutMs??1e4));let l=null;o>0&&(l=window.setTimeout(()=>r.abort(),o));try{const{url:d,init:c}=Et(t,n,r.signal),u=await fetch(d,{...c,signal:r.signal});if(!u.ok)throw new Error(`Data binding API request failed: ${u.status}`);const m=(a.responseType||"json")==="text"?await u.text():await u.json();if(a.transformResponse){const B=a.transformResponse(m,i);return x(B)?B:{}}const $=wt(m,a.responsePath);return x($)?$:x(m)?m:{value:$}}catch(d){return d?.name!=="AbortError"&&a.onError?.(d,i),{}}finally{l!==null&&window.clearTimeout(l)}}async function I(t,n){const a=W.get(t);if(a)return a;const r=N.get(t),e=Date.now();if(r&&e-r.timestamp<=n.cacheTtlMs)return r.data;const i=G.get(t);if(i)return i;const o=(async()=>{try{if(typeof n.getData=="function"){const d=await Promise.resolve(n.getData({editor:t,editorRoot:j(t)}));if(x(d))return d}if(n.api){const d=await Dt(t,n);if(x(d))return d}if(typeof n.data=="function"){const d=await Promise.resolve(n.data());if(x(d))return d}return x(n.data)?n.data:{}}finally{G.delete(t)}})();G.set(t,o);const l=await o;return N.set(t,{timestamp:e,data:l}),l}async function z(t,n,a){const r=V(t,n);if(v.set(t,a),tt(t,a,n),!a){r.forEach(i=>T(i,n,!1));return}const e=await I(t,n);r.forEach(i=>T(i,n,!0,e))}function bt(t,n){let a=lt(t);a||(a=document.createRange(),a.selectNodeContents(t),a.collapse(!1)),a.collapsed||a.deleteContents(),a.insertNode(n);const r=document.createTextNode(" ");n.after(r);const e=document.createRange();e.setStart(r,1),e.collapse(!0),st(t,e),t.normalize()}function At(t){const n=t.metaKey||t.ctrlKey,a=t.key.toLowerCase(),r=n&&t.altKey&&t.shiftKey&&a==="d",e=!t.metaKey&&!t.ctrlKey&&!t.altKey&&!t.shiftKey&&a==="f7";return r||e}function St(t){const n=t.metaKey||t.ctrlKey,a=t.key.toLowerCase(),r=n&&t.altKey&&t.shiftKey&&a==="b",e=!t.metaKey&&!t.ctrlKey&&!t.altKey&&!t.shiftKey&&a==="f8";return r||e}function S(t,n,a,r,e){ft();const i=a==="insert"?lt(t):null,o=n.labels,l=e?Z(e,n):H(r||{},n),d=document.createElement("div");d.className=g,ht(t)&&d.classList.add("rte-data-binding-theme-dark");const c=document.createElement("section");c.className="rte-data-binding-dialog",c.setAttribute("role","dialog"),c.setAttribute("aria-modal","true"),c.setAttribute("aria-labelledby","rte-data-binding-dialog-title"),c.innerHTML=` | ||
| <header class="rte-data-binding-header"> | ||
| <h2 id="rte-data-binding-dialog-title" class="rte-data-binding-title">${y(a==="edit"?o.dialogTitleEdit:o.dialogTitleInsert)}</h2> | ||
| <button type="button" class="rte-data-binding-btn" data-action="cancel" aria-label="${y(o.cancelText)}">✕</button> | ||
| </header> | ||
| <div class="rte-data-binding-body"> | ||
| <div class="rte-data-binding-field"> | ||
| <label for="rte-data-binding-key">${y(o.keyLabel)}</label> | ||
| <input id="rte-data-binding-key" class="rte-data-binding-key" type="text" value="${y(l.key)}" placeholder="${y(o.keyPlaceholder)}" /> | ||
| </div> | ||
| <div class="rte-data-binding-field"> | ||
| <label for="rte-data-binding-fallback">${y(o.fallbackLabel)}</label> | ||
| <input id="rte-data-binding-fallback" class="rte-data-binding-fallback" type="text" value="${y(l.fallback||"")}" placeholder="${y(o.fallbackPlaceholder)}" /> | ||
| </div> | ||
| <div class="rte-data-binding-field"> | ||
| <label for="rte-data-binding-format">${y(o.formatLabel)}</label> | ||
| <select id="rte-data-binding-format" class="rte-data-binding-format"> | ||
| <option value="text" ${l.format==="text"?"selected":""}>Text</option> | ||
| <option value="number" ${l.format==="number"?"selected":""}>Number</option> | ||
| <option value="currency" ${l.format==="currency"?"selected":""}>Currency</option> | ||
| <option value="date" ${l.format==="date"?"selected":""}>Date</option> | ||
| <option value="json" ${l.format==="json"?"selected":""}>JSON</option> | ||
| </select> | ||
| </div> | ||
| <div class="rte-data-binding-field"> | ||
| <label for="rte-data-binding-currency">${y(o.currencyLabel)}</label> | ||
| <input id="rte-data-binding-currency" class="rte-data-binding-currency" type="text" maxlength="3" value="${y(l.currency||"USD")}" placeholder="${y(o.currencyPlaceholder)}" /> | ||
| </div> | ||
| <p class="rte-data-binding-help">Use dot paths like <code>user.name</code> or <code>order.total</code>.</p> | ||
| </div> | ||
| <footer class="rte-data-binding-footer"> | ||
| <button type="button" class="rte-data-binding-btn" data-action="cancel">${y(o.cancelText)}</button> | ||
| <button type="button" class="rte-data-binding-btn rte-data-binding-btn-primary" data-action="save">${y(o.saveText)}</button> | ||
| </footer> | ||
| `,d.appendChild(c),document.body.appendChild(d);const u=c.querySelector(".rte-data-binding-key"),p=c.querySelector(".rte-data-binding-fallback"),m=c.querySelector(".rte-data-binding-format"),$=c.querySelector(".rte-data-binding-currency"),B=()=>{const s=m?.value==="currency",k=$?.closest(".rte-data-binding-field");k&&(k.style.display=s?"grid":"none")};B(),m?.addEventListener("change",B);const L=()=>{d.removeEventListener("click",nt),d.removeEventListener("keydown",rt,!0),document.removeEventListener("keydown",et,!0),d.parentNode&&d.parentNode.removeChild(d),R=null,t.focus({preventScroll:!0})},et=s=>{s.key==="Escape"&&(s.preventDefault(),s.stopPropagation(),L())},nt=s=>{s.target===d&&L()},gt=s=>{if(s.key!=="Tab")return;const k=Array.from(c.querySelectorAll('button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'));if(k.length===0)return;const w=k[0],E=k[k.length-1],F=document.activeElement;if(s.shiftKey&&F===w){s.preventDefault(),E.focus();return}!s.shiftKey&&F===E&&(s.preventDefault(),w.focus())},at=async()=>{const s=(u?.value||"").trim();if(!s){u?.focus();return}const k=H({key:s,fallback:(p?.value||"").trim(),format:m?.value||n.defaultFormat,currency:($?.value||"USD").trim().toUpperCase()},n),w=t.innerHTML;if(e){X(e,k,o);const E=v.get(t)===!0,F=E?await I(t,n):void 0;T(e,n,E,F)}else{if(i)try{st(t,i)}catch{}const E=ut(k,o);if(bt(t,E),v.get(t)===!0){const mt=await I(t,n);T(E,n,!0,mt)}}J(t),Y(t,w),L()},rt=s=>{if(s.key==="Escape"){s.preventDefault(),L();return}gt(s),s.key==="Enter"&&!s.shiftKey&&s.target instanceof HTMLInputElement&&(s.preventDefault(),at())};c.addEventListener("click",s=>{const w=s.target?.getAttribute("data-action");if(w){if(w==="cancel"){L();return}w==="save"&&at()}}),d.addEventListener("click",nt),d.addEventListener("keydown",rt,!0),document.addEventListener("keydown",et,!0),R={cleanup:L},u?.focus()}function Tt(t){_=t,O||(O=n=>{const r=n.target?.closest(A);if(!r)return;h=r,b.has(r)||b.set(r,t);const e=b.get(r)||t;V(r,e);const i=v.get(r)===!0;tt(r,i,e),i||Array.from(r.querySelectorAll(C)).forEach(l=>T(l,e,!1))},document.addEventListener("focusin",O,!0)),P||(P=n=>{if(document.querySelector(`.${g}`))return;const a=n.target;if(a?.closest("input, textarea, select"))return;const r=D(void 0,!1);if(!r||K(r))return;const e=b.get(r)||_||t,i=a?.closest(C);if(i&&(n.key==="Enter"||n.key===" ")){n.preventDefault(),n.stopPropagation(),h=r,S(r,e,"edit",void 0,i);return}if(At(n)){n.preventDefault(),n.stopPropagation();const o=Q(r);o?S(r,e,"edit",void 0,o):S(r,e,"insert");return}if(St(n)){n.preventDefault(),n.stopPropagation();const o=v.get(r)!==!0;z(r,e,o)}},document.addEventListener("keydown",P,!0)),M||(M=n=>{if(document.querySelector(`.${g}`)||n.defaultPrevented||n.button!==0||n.metaKey||n.ctrlKey||n.altKey||n.shiftKey)return;const r=n.target?.closest(C);if(!r)return;const e=r.closest(A);if(!e||K(e))return;const i=b.get(e)||_||t;b.set(e,i),h=e,n.preventDefault(),n.stopPropagation(),r.focus({preventScroll:!0}),S(e,i,"edit",void 0,r)},document.addEventListener("click",M,!0))}function $t(){O&&(document.removeEventListener("focusin",O,!0),O=null),P&&(document.removeEventListener("keydown",P,!0),P=null),M&&(document.removeEventListener("click",M,!0),M=null),_=null,h=null}const Lt=(t={})=>{const n=ot(t);return vt(),{name:"dataBinding",toolbar:[{id:"dataBindingTools",label:"Data Binding",type:"group",command:"openDataBindingDialog",items:[{id:"dataBinding",label:"Data Binding",command:"openDataBindingDialog",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M7 4a3 3 0 0 0-3 3v3h2V7a1 1 0 0 1 1-1h3V4H7Zm10 0h-3v2h3a1 1 0 0 1 1 1v3h2V7a3 3 0 0 0-3-3ZM4 14v3a3 3 0 0 0 3 3h3v-2H7a1 1 0 0 1-1-1v-3H4Zm14 0v3a1 1 0 0 1-1 1h-3v2h3a3 3 0 0 0 3-3v-3h-2ZM8.5 12a1.5 1.5 0 1 1 0-3h7a1.5 1.5 0 0 1 0 3h-7Zm0 4a1.5 1.5 0 1 1 0-3h4a1.5 1.5 0 0 1 0 3h-4Z" fill="currentColor"></path></svg>'},{id:"dataBindingPreview",label:"Data Preview",command:"toggleDataBindingPreview",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M12 3c-4.4 0-8 1.3-8 3v12c0 1.7 3.6 3 8 3s8-1.3 8-3V6c0-1.7-3.6-3-8-3Zm0 2c3.9 0 6 .9 6 1s-2.1 1-6 1-6-.9-6-1 2.1-1 6-1Zm0 4c3 0 5.6-.5 7-1.3V11c0 .9-2.7 2-7 2s-7-1.1-7-2V7.7C6.4 8.5 9 9 12 9Zm0 6c-4.3 0-7-1.1-7-2v3c0 .9 2.7 2 7 2s7-1.1 7-2v-3c0 .9-2.7 2-7 2Z" fill="currentColor"></path><path d="M16.5 9.4a1 1 0 0 1 1.4 0l1.1 1.1 1.8-1.8a1 1 0 1 1 1.4 1.4l-2.5 2.5a1 1 0 0 1-1.4 0l-1.8-1.8a1 1 0 0 1 0-1.4Z" fill="currentColor"></path></svg>'}]}],commands:{openDataBindingDialog:(a,r)=>{const e=D(r);if(!e||K(e))return!1;h=e;const i=b.get(e)||n;b.set(e,i),V(e,i);const o=a?.target;if(o==="insert")return S(e,i,"insert",a),!0;const l=Q(e);return o==="edit"||l?!l&&o==="edit"?!1:(S(e,i,"edit",a,l||void 0),!0):(S(e,i,"insert",a),!0)},insertDataBindingToken:async(a,r)=>{const e=D(r);if(!e||K(e))return!1;h=e;const i=b.get(e)||n;b.set(e,i);const o=H(a||{},i);if(!o.key)return!1;const l=e.innerHTML,d=ut(o,i.labels);if(bt(e,d),v.get(e)===!0){const u=await I(e,i);T(d,i,!0,u)}return J(e),Y(e,l),!0},editDataBindingToken:async(a,r)=>{const e=D(r);if(!e||K(e))return!1;h=e;const i=b.get(e)||n;b.set(e,i);const o=Q(e);if(!o)return!1;const l=Z(o,i),d=H({...l,...a||{}},i);if(!d.key)return!1;const c=e.innerHTML;X(o,d,i.labels);const u=v.get(e)===!0,p=u?await I(e,i):void 0;return T(o,i,u,p),J(e),Y(e,c),!0},toggleDataBindingPreview:async(a,r)=>{const e=D(r);if(!e)return!1;h=e;const i=b.get(e)||n;b.set(e,i);const o=typeof a=="boolean"?a:v.get(e)!==!0;return await z(e,i,o),!0},setDataBindingData:async(a,r)=>{const e=D(r);if(!e)return!1;if(h=e,a&&typeof a=="object"?(W.set(e,a),N.set(e,{timestamp:Date.now(),data:a})):(W.delete(e),N.delete(e)),v.get(e)===!0){const i=b.get(e)||n;await z(e,i,!0)}return!0},refreshDataBindings:async(a,r)=>{const e=D(r);if(!e)return!1;h=e,N.delete(e);const i=b.get(e)||n;b.set(e,i);const o=v.get(e)===!0;return await z(e,i,o),!0}},keymap:{"Mod-Alt-Shift-d":"openDataBindingDialog","Mod-Alt-Shift-D":"openDataBindingDialog","Mod-Alt-Shift-b":"toggleDataBindingPreview","Mod-Alt-Shift-B":"toggleDataBindingPreview",F7:"openDataBindingDialog",F8:"toggleDataBindingPreview"},init:function(r){U+=1;const e=this&&typeof this.__pluginConfig=="object"?ot({...n,...this.__pluginConfig}):n;Tt(e);const i=D(r&&r.editorElement?{editorElement:r.editorElement}:void 0,!1);if(i){h=i,b.set(i,e),V(i,e);const o=v.get(i)===!0;tt(i,o,e)}},destroy:()=>{U=Math.max(0,U-1),U===0&&(ft(),$t())}}};exports.DataBindingPlugin=Lt; |
| const A = ".rte-content, .editora-content", C = '.rte-data-binding[data-binding="true"]', it = "rte-data-binding-styles", g = "rte-data-binding-dialog-overlay", f = ':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)', pt = { | ||
| dialogTitleInsert: "Insert Data Binding", | ||
| dialogTitleEdit: "Edit Data Binding", | ||
| keyLabel: "Data Key", | ||
| keyPlaceholder: "user.firstName", | ||
| fallbackLabel: "Fallback Text", | ||
| fallbackPlaceholder: "Guest", | ||
| formatLabel: "Format", | ||
| currencyLabel: "Currency", | ||
| currencyPlaceholder: "USD", | ||
| saveText: "Save", | ||
| cancelText: "Cancel", | ||
| previewOnText: "Preview On", | ||
| previewOffText: "Preview Off", | ||
| tokenAriaPrefix: "Data binding token" | ||
| }, x = /* @__PURE__ */ new WeakMap(), W = /* @__PURE__ */ new WeakMap(), b = /* @__PURE__ */ new WeakMap(), N = /* @__PURE__ */ new WeakMap(), G = /* @__PURE__ */ new WeakMap(); | ||
| let R = null, h = null, U = 0, P = null, O = null, M = null, z = null; | ||
| function yt(t) { | ||
| return { | ||
| ...pt, | ||
| ...t || {} | ||
| }; | ||
| } | ||
| function ot(t = {}) { | ||
| const n = (t.locale || (typeof navigator < "u" ? navigator.language : "en-US")).trim() || "en-US"; | ||
| return { | ||
| data: t.data, | ||
| getData: t.getData, | ||
| api: t.api, | ||
| cacheTtlMs: Math.max(0, Number(t.cacheTtlMs ?? 3e4)), | ||
| labels: yt(t.labels), | ||
| defaultFormat: t.defaultFormat || "text", | ||
| defaultFallback: t.defaultFallback || "", | ||
| locale: n, | ||
| numberFormatOptions: t.numberFormatOptions || {}, | ||
| dateFormatOptions: t.dateFormatOptions || { year: "numeric", month: "short", day: "2-digit" } | ||
| }; | ||
| } | ||
| function y(t) { | ||
| return t.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); | ||
| } | ||
| function dt(t) { | ||
| return t ? t.nodeType === Node.ELEMENT_NODE ? t : t.parentElement : null; | ||
| } | ||
| function j(t) { | ||
| return t.closest("[data-editora-editor], .rte-editor, .editora-editor, editora-editor") || t; | ||
| } | ||
| function q(t) { | ||
| return t ? (t.getAttribute("data-theme") || t.getAttribute("theme") || "").toLowerCase() === "dark" ? !0 : t.classList.contains("dark") || t.classList.contains("editora-theme-dark") || t.classList.contains("rte-theme-dark") : !1; | ||
| } | ||
| function ht(t) { | ||
| const n = j(t); | ||
| if (q(n)) return !0; | ||
| const a = n.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark"); | ||
| return q(a) ? !0 : q(document.documentElement) || q(document.body); | ||
| } | ||
| function D(t, n = !0) { | ||
| if (t?.contentElement instanceof HTMLElement) return t.contentElement; | ||
| if (t?.editorElement instanceof HTMLElement) { | ||
| const e = t.editorElement; | ||
| if (e.matches(A)) return e; | ||
| const i = e.querySelector(A); | ||
| if (i instanceof HTMLElement) return i; | ||
| } | ||
| const a = window.getSelection(); | ||
| if (a && a.rangeCount > 0) { | ||
| const e = a.getRangeAt(0).startContainer, o = dt(e)?.closest(A); | ||
| if (o) return o; | ||
| } | ||
| const r = document.activeElement; | ||
| if (r) { | ||
| if (r.matches(A)) return r; | ||
| const e = r.closest(A); | ||
| if (e) return e; | ||
| } | ||
| return h && h.isConnected ? h : n ? document.querySelector(A) : null; | ||
| } | ||
| function K(t) { | ||
| return t.getAttribute("contenteditable") === "false" || t.getAttribute("data-readonly") === "true"; | ||
| } | ||
| function lt(t) { | ||
| const n = window.getSelection(); | ||
| if (!n || n.rangeCount === 0) return null; | ||
| const a = n.getRangeAt(0); | ||
| return t.contains(a.commonAncestorContainer) ? a.cloneRange() : null; | ||
| } | ||
| function st(t, n) { | ||
| const a = window.getSelection(); | ||
| a && (a.removeAllRanges(), a.addRange(n), t.focus({ preventScroll: !0 })); | ||
| } | ||
| function kt(t, n) { | ||
| const a = (n || "").trim(); | ||
| if (a) | ||
| return a.split(".").filter(Boolean).reduce((r, e) => { | ||
| if (!(r == null || typeof r != "object")) | ||
| return r[e]; | ||
| }, t); | ||
| } | ||
| function xt() { | ||
| if (typeof document > "u" || document.getElementById(it)) return; | ||
| const t = document.createElement("style"); | ||
| t.id = it, t.textContent = ` | ||
| .rte-data-binding { | ||
| display: inline-flex; | ||
| align-items: center; | ||
| max-width: 100%; | ||
| gap: 5px; | ||
| padding: 2px 8px 2px 7px; | ||
| border-radius: 999px; | ||
| border: 1px dashed #8b5cf6; | ||
| background: linear-gradient(180deg, #f9f7ff 0%, #f1edff 100%); | ||
| color: #4c1d95; | ||
| font-size: 0.88em; | ||
| font-weight: 600; | ||
| line-height: 1.3; | ||
| vertical-align: baseline; | ||
| white-space: nowrap; | ||
| overflow: hidden; | ||
| text-overflow: ellipsis; | ||
| user-select: all; | ||
| font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; | ||
| cursor: pointer; | ||
| } | ||
| .rte-data-binding::before { | ||
| content: '{}'; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| min-width: 14px; | ||
| height: 14px; | ||
| border-radius: 999px; | ||
| background: rgba(139, 92, 246, 0.16); | ||
| color: #5b21b6; | ||
| font-size: 10px; | ||
| font-weight: 700; | ||
| line-height: 1; | ||
| letter-spacing: -0.2px; | ||
| flex: 0 0 auto; | ||
| } | ||
| .rte-data-binding.rte-data-binding-preview { | ||
| border-style: solid; | ||
| background: #ecfdf5; | ||
| border-color: #34d399; | ||
| color: #065f46; | ||
| user-select: text; | ||
| } | ||
| .rte-data-binding.rte-data-binding-preview::before { | ||
| content: '='; | ||
| background: rgba(16, 185, 129, 0.15); | ||
| color: #047857; | ||
| letter-spacing: 0; | ||
| } | ||
| .rte-data-binding.rte-data-binding-missing { | ||
| border-style: dashed; | ||
| border-color: #f87171; | ||
| background: #fef2f2; | ||
| color: #991b1b; | ||
| } | ||
| .rte-data-binding-dialog-overlay { | ||
| position: fixed; | ||
| inset: 0; | ||
| z-index: 2147483646; | ||
| background: rgba(15, 23, 42, 0.54); | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| padding: 20px; | ||
| } | ||
| .rte-data-binding-dialog { | ||
| width: min(560px, 96vw); | ||
| max-height: min(86vh, 720px); | ||
| border: 1px solid #dbe3ec; | ||
| border-radius: 8px; | ||
| background: #ffffff; | ||
| box-shadow: 0 24px 50px rgba(15, 23, 42, 0.26); | ||
| display: flex; | ||
| flex-direction: column; | ||
| overflow: hidden; | ||
| } | ||
| .rte-data-binding-header, | ||
| .rte-data-binding-footer { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 10px; | ||
| padding: 12px 14px; | ||
| background: #f8fafc; | ||
| border-bottom: 1px solid #e2e8f0; | ||
| } | ||
| .rte-data-binding-footer { | ||
| justify-content: flex-end; | ||
| border-bottom: 0; | ||
| border-top: 1px solid #e2e8f0; | ||
| } | ||
| .rte-data-binding-title { | ||
| margin: 0; | ||
| font-size: 16px; | ||
| font-weight: 700; | ||
| color: #0f172a; | ||
| } | ||
| .rte-data-binding-body { | ||
| padding: 14px; | ||
| overflow: auto; | ||
| display: grid; | ||
| gap: 12px; | ||
| grid-template-columns: 1fr; | ||
| } | ||
| .rte-data-binding-field { | ||
| display: grid; | ||
| gap: 6px; | ||
| } | ||
| .rte-data-binding-field label { | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| color: #334155; | ||
| } | ||
| .rte-data-binding-field input, | ||
| .rte-data-binding-field select { | ||
| width: 100%; | ||
| min-height: 36px; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| padding: 8px 10px; | ||
| font-size: 13px; | ||
| line-height: 1.4; | ||
| color: #0f172a; | ||
| background: #ffffff; | ||
| box-sizing: border-box; | ||
| } | ||
| .rte-data-binding-help { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| color: #64748b; | ||
| } | ||
| .rte-data-binding-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| min-height: 34px; | ||
| padding: 6px 12px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| font-size: 13px; | ||
| cursor: pointer; | ||
| } | ||
| .rte-data-binding-btn-primary { | ||
| background: #2563eb; | ||
| border-color: #2563eb; | ||
| color: #ffffff; | ||
| } | ||
| .rte-data-binding-btn-primary:hover { | ||
| background: #1d4ed8; | ||
| } | ||
| .rte-toolbar-group-items.data-binding, | ||
| .editora-toolbar-group-items.data-binding { | ||
| display: flex; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| overflow: hidden; | ||
| background: #ffffff; | ||
| } | ||
| .rte-toolbar-group-items.data-binding .rte-toolbar-item, | ||
| .editora-toolbar-group-items.data-binding .editora-toolbar-item { | ||
| display: flex; | ||
| } | ||
| .rte-toolbar-group-items.data-binding .rte-toolbar-button, | ||
| .editora-toolbar-group-items.data-binding .editora-toolbar-button { | ||
| border: 0; | ||
| border-radius: 0; | ||
| border-right: 1px solid #cbd5e1; | ||
| } | ||
| .rte-toolbar-group-items.data-binding .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.data-binding .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: 0; | ||
| } | ||
| .rte-data-binding-btn:focus-visible, | ||
| .rte-data-binding-field input:focus-visible, | ||
| .rte-data-binding-field select:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| ${f} .rte-data-binding, | ||
| .${g}.rte-data-binding-theme-dark .rte-data-binding { | ||
| background: linear-gradient(180deg, #3b0764 0%, #2e1065 100%); | ||
| border-color: #a78bfa; | ||
| color: #ede9fe; | ||
| } | ||
| ${f} .rte-data-binding::before, | ||
| .${g}.rte-data-binding-theme-dark .rte-data-binding::before { | ||
| background: rgba(167, 139, 250, 0.22); | ||
| color: #ddd6fe; | ||
| } | ||
| ${f} .rte-data-binding.rte-data-binding-preview, | ||
| .${g}.rte-data-binding-theme-dark .rte-data-binding.rte-data-binding-preview { | ||
| background: #064e3b; | ||
| border-color: #10b981; | ||
| color: #d1fae5; | ||
| } | ||
| ${f} .rte-data-binding.rte-data-binding-missing, | ||
| .${g}.rte-data-binding-theme-dark .rte-data-binding.rte-data-binding-missing { | ||
| background: #7f1d1d; | ||
| border-color: #ef4444; | ||
| color: #fee2e2; | ||
| } | ||
| ${f} .rte-toolbar-group-items.data-binding, | ||
| ${f} .editora-toolbar-group-items.data-binding { | ||
| display: flex; | ||
| border: 1px solid #566275; | ||
| border-radius: 6px; | ||
| overflow: hidden; | ||
| } | ||
| ${f} .rte-toolbar-group-items.data-binding .rte-toolbar-button, | ||
| ${f} .editora-toolbar-group-items.data-binding .editora-toolbar-button { | ||
| border-right-color: #566275; | ||
| } | ||
| ${f} .rte-data-binding-dialog, | ||
| .${g}.rte-data-binding-theme-dark .rte-data-binding-dialog { | ||
| background: #1f2937; | ||
| border-color: #334155; | ||
| } | ||
| ${f} .rte-data-binding-header, | ||
| ${f} .rte-data-binding-footer, | ||
| .${g}.rte-data-binding-theme-dark .rte-data-binding-header, | ||
| .${g}.rte-data-binding-theme-dark .rte-data-binding-footer { | ||
| background: #111827; | ||
| border-color: #334155; | ||
| } | ||
| ${f} .rte-data-binding-title, | ||
| ${f} .rte-data-binding-field label, | ||
| .${g}.rte-data-binding-theme-dark .rte-data-binding-title, | ||
| .${g}.rte-data-binding-theme-dark .rte-data-binding-field label { | ||
| color: #e2e8f0; | ||
| } | ||
| ${f} .rte-data-binding-help, | ||
| .${g}.rte-data-binding-theme-dark .rte-data-binding-help { | ||
| color: #94a3b8; | ||
| } | ||
| ${f} .rte-data-binding-field input, | ||
| ${f} .rte-data-binding-field select, | ||
| ${f} .rte-data-binding-btn, | ||
| .${g}.rte-data-binding-theme-dark .rte-data-binding-field input, | ||
| .${g}.rte-data-binding-theme-dark .rte-data-binding-field select, | ||
| .${g}.rte-data-binding-theme-dark .rte-data-binding-btn { | ||
| background: #0f172a; | ||
| border-color: #475569; | ||
| color: #e2e8f0; | ||
| } | ||
| ${f} .rte-data-binding-btn-primary, | ||
| .${g}.rte-data-binding-theme-dark .rte-data-binding-btn-primary { | ||
| background: #2563eb; | ||
| border-color: #2563eb; | ||
| color: #ffffff; | ||
| } | ||
| `, document.head.appendChild(t); | ||
| } | ||
| function J(t) { | ||
| t.dispatchEvent(new Event("input", { bubbles: !0 })); | ||
| } | ||
| function Y(t, n) { | ||
| if (n === t.innerHTML) return; | ||
| const a = window.execEditorCommand || window.executeEditorCommand; | ||
| if (typeof a == "function") | ||
| try { | ||
| a("recordDomTransaction", t, n, t.innerHTML); | ||
| } catch { | ||
| } | ||
| } | ||
| function H(t, n) { | ||
| return { | ||
| key: String(t.key || "").trim(), | ||
| fallback: String(t.fallback ?? n.defaultFallback ?? ""), | ||
| format: t.format || n.defaultFormat || "text", | ||
| currency: String(t.currency || "USD").trim().toUpperCase() || "USD" | ||
| }; | ||
| } | ||
| function ct(t) { | ||
| return `{{${t.key}}}`; | ||
| } | ||
| function ut(t, n) { | ||
| const a = document.createElement("span"); | ||
| return a.className = "rte-data-binding", a.setAttribute("data-binding", "true"), a.setAttribute("data-binding-key", t.key), a.setAttribute("data-binding-fallback", t.fallback || ""), a.setAttribute("data-binding-format", t.format || "text"), a.setAttribute("data-binding-currency", t.currency || "USD"), a.setAttribute("contenteditable", "false"), a.setAttribute("spellcheck", "false"), a.setAttribute("draggable", "false"), a.setAttribute("tabindex", "0"), a.setAttribute("role", "button"), a.setAttribute("aria-label", `${n.tokenAriaPrefix}: ${t.key}. Press Enter to edit.`), a.textContent = ct(t), a; | ||
| } | ||
| function Z(t, n) { | ||
| return H( | ||
| { | ||
| key: t.getAttribute("data-binding-key") || "", | ||
| fallback: t.getAttribute("data-binding-fallback") || n.defaultFallback, | ||
| format: t.getAttribute("data-binding-format") || n.defaultFormat, | ||
| currency: t.getAttribute("data-binding-currency") || "USD" | ||
| }, | ||
| n | ||
| ); | ||
| } | ||
| function X(t, n, a) { | ||
| t.classList.add("rte-data-binding"), t.setAttribute("data-binding", "true"), t.setAttribute("data-binding-key", n.key), t.setAttribute("data-binding-fallback", n.fallback || ""), t.setAttribute("data-binding-format", n.format || "text"), t.setAttribute("data-binding-currency", n.currency || "USD"), t.setAttribute("contenteditable", "false"), t.setAttribute("spellcheck", "false"), t.setAttribute("draggable", "false"), t.setAttribute("tabindex", "0"), t.setAttribute("role", "button"), t.setAttribute("aria-label", `${a.tokenAriaPrefix}: ${n.key}. Press Enter to edit.`); | ||
| } | ||
| function V(t, n) { | ||
| const a = Array.from(t.querySelectorAll(C)); | ||
| return a.forEach((r) => { | ||
| const e = Z(r, n); | ||
| X(r, e, n.labels); | ||
| }), a; | ||
| } | ||
| function Q(t) { | ||
| const n = window.getSelection(); | ||
| if (n && n.rangeCount > 0) { | ||
| const e = n.getRangeAt(0).startContainer, o = dt(e)?.closest(C); | ||
| if (o && t.contains(o)) return o; | ||
| } | ||
| const r = document.activeElement?.closest(C); | ||
| return r && t.contains(r) ? r : null; | ||
| } | ||
| function ft() { | ||
| R && (R.cleanup(), R = null); | ||
| } | ||
| function tt(t, n, a) { | ||
| const r = j(t); | ||
| Array.from(r.querySelectorAll('[data-command="toggleDataBindingPreview"]')).forEach((i) => { | ||
| if (i.setAttribute("data-active", n ? "true" : "false"), i.classList.toggle("active", n), i.setAttribute("aria-pressed", n ? "true" : "false"), a) { | ||
| const o = n ? a.labels.previewOnText : a.labels.previewOffText; | ||
| i.setAttribute("title", o), i.setAttribute("aria-label", o); | ||
| } | ||
| }); | ||
| } | ||
| function vt(t, n, a) { | ||
| const r = n.format || "text"; | ||
| if (t == null) return n.fallback || ""; | ||
| if (r === "json") { | ||
| if (typeof t == "string") return t; | ||
| try { | ||
| return JSON.stringify(t); | ||
| } catch { | ||
| return String(t); | ||
| } | ||
| } | ||
| if (r === "date") { | ||
| const e = t instanceof Date ? t : new Date(String(t)); | ||
| if (Number.isNaN(e.getTime())) return String(t); | ||
| try { | ||
| return new Intl.DateTimeFormat(a.locale, a.dateFormatOptions).format(e); | ||
| } catch { | ||
| return e.toISOString(); | ||
| } | ||
| } | ||
| if (r === "number" || r === "currency") { | ||
| const e = typeof t == "number" ? t : Number(t); | ||
| if (!Number.isFinite(e)) return String(t); | ||
| const i = { ...a.numberFormatOptions }; | ||
| if (r === "currency") { | ||
| const o = (n.currency || "USD").toUpperCase(); | ||
| Object.assign(i, { style: "currency", currency: o }); | ||
| } | ||
| try { | ||
| return new Intl.NumberFormat(a.locale, i).format(e); | ||
| } catch { | ||
| return String(e); | ||
| } | ||
| } | ||
| return String(t); | ||
| } | ||
| function T(t, n, a, r) { | ||
| const e = Z(t, n), i = e.key; | ||
| if (t.classList.remove("rte-data-binding-preview", "rte-data-binding-missing"), !a) { | ||
| t.textContent = ct(e), t.setAttribute("aria-label", `${n.labels.tokenAriaPrefix}: ${i}. Press Enter to edit.`); | ||
| return; | ||
| } | ||
| const o = kt(r, i), l = o == null, d = l ? e.fallback || "" : vt(o, e, n); | ||
| t.textContent = d || e.fallback || "", t.classList.add("rte-data-binding-preview"), l && !(e.fallback || "").trim() && t.classList.add("rte-data-binding-missing"), t.setAttribute("aria-label", `${n.labels.tokenAriaPrefix}: ${i} = ${t.textContent || ""}. Press Enter to edit.`); | ||
| } | ||
| function v(t) { | ||
| return typeof t == "object" && t !== null && !Array.isArray(t); | ||
| } | ||
| function wt(t, n) { | ||
| return n ? n.split(".").filter(Boolean).reduce((a, r) => { | ||
| if (!(!v(a) && !Array.isArray(a))) | ||
| return a[r]; | ||
| }, t) : t; | ||
| } | ||
| function Et(t, n, a) { | ||
| const r = n.api, e = j(t), i = { editor: t, editorRoot: e, signal: a }; | ||
| if (r.buildRequest) { | ||
| const p = r.buildRequest(i); | ||
| return { url: p.url, init: { ...p.init || {}, signal: a } }; | ||
| } | ||
| const o = (r.method || "GET").toUpperCase(), l = typeof r.headers == "function" ? r.headers(i) : r.headers || {}, d = typeof r.params == "function" ? r.params(i) : r.params, c = new URL(r.url, window.location.origin); | ||
| d && Object.entries(d).forEach(([p, m]) => { | ||
| m != null && c.searchParams.set(p, String(m)); | ||
| }); | ||
| const u = { | ||
| method: o, | ||
| headers: { ...l }, | ||
| credentials: r.credentials, | ||
| mode: r.mode, | ||
| cache: r.cache, | ||
| signal: a | ||
| }; | ||
| if (o !== "GET" && o !== "HEAD") { | ||
| const p = typeof r.body == "function" ? r.body(i) : r.body; | ||
| if (p != null) | ||
| if (v(p)) { | ||
| u.body = JSON.stringify(p); | ||
| const m = u.headers; | ||
| !m["Content-Type"] && !m["content-type"] && (m["Content-Type"] = "application/json"); | ||
| } else | ||
| u.body = p; | ||
| } | ||
| return { url: c.toString(), init: u }; | ||
| } | ||
| async function Dt(t, n) { | ||
| const a = n.api; | ||
| if (!a) return {}; | ||
| const r = new AbortController(), e = j(t), i = { editor: t, editorRoot: e, signal: r.signal }, o = Math.max(0, Number(a.timeoutMs ?? 1e4)); | ||
| let l = null; | ||
| o > 0 && (l = window.setTimeout(() => r.abort(), o)); | ||
| try { | ||
| const { url: d, init: c } = Et(t, n, r.signal), u = await fetch(d, { ...c, signal: r.signal }); | ||
| if (!u.ok) | ||
| throw new Error(`Data binding API request failed: ${u.status}`); | ||
| const m = (a.responseType || "json") === "text" ? await u.text() : await u.json(); | ||
| if (a.transformResponse) { | ||
| const B = a.transformResponse(m, i); | ||
| return v(B) ? B : {}; | ||
| } | ||
| const $ = wt(m, a.responsePath); | ||
| return v($) ? $ : v(m) ? m : { value: $ }; | ||
| } catch (d) { | ||
| return d?.name !== "AbortError" && a.onError?.(d, i), {}; | ||
| } finally { | ||
| l !== null && window.clearTimeout(l); | ||
| } | ||
| } | ||
| async function I(t, n) { | ||
| const a = W.get(t); | ||
| if (a) return a; | ||
| const r = N.get(t), e = Date.now(); | ||
| if (r && e - r.timestamp <= n.cacheTtlMs) | ||
| return r.data; | ||
| const i = G.get(t); | ||
| if (i) return i; | ||
| const o = (async () => { | ||
| try { | ||
| if (typeof n.getData == "function") { | ||
| const d = await Promise.resolve(n.getData({ editor: t, editorRoot: j(t) })); | ||
| if (v(d)) return d; | ||
| } | ||
| if (n.api) { | ||
| const d = await Dt(t, n); | ||
| if (v(d)) return d; | ||
| } | ||
| if (typeof n.data == "function") { | ||
| const d = await Promise.resolve(n.data()); | ||
| if (v(d)) return d; | ||
| } | ||
| return v(n.data) ? n.data : {}; | ||
| } finally { | ||
| G.delete(t); | ||
| } | ||
| })(); | ||
| G.set(t, o); | ||
| const l = await o; | ||
| return N.set(t, { timestamp: e, data: l }), l; | ||
| } | ||
| async function _(t, n, a) { | ||
| const r = V(t, n); | ||
| if (x.set(t, a), tt(t, a, n), !a) { | ||
| r.forEach((i) => T(i, n, !1)); | ||
| return; | ||
| } | ||
| const e = await I(t, n); | ||
| r.forEach((i) => T(i, n, !0, e)); | ||
| } | ||
| function bt(t, n) { | ||
| let a = lt(t); | ||
| a || (a = document.createRange(), a.selectNodeContents(t), a.collapse(!1)), a.collapsed || a.deleteContents(), a.insertNode(n); | ||
| const r = document.createTextNode(" "); | ||
| n.after(r); | ||
| const e = document.createRange(); | ||
| e.setStart(r, 1), e.collapse(!0), st(t, e), t.normalize(); | ||
| } | ||
| function At(t) { | ||
| const n = t.metaKey || t.ctrlKey, a = t.key.toLowerCase(), r = n && t.altKey && t.shiftKey && a === "d", e = !t.metaKey && !t.ctrlKey && !t.altKey && !t.shiftKey && a === "f7"; | ||
| return r || e; | ||
| } | ||
| function St(t) { | ||
| const n = t.metaKey || t.ctrlKey, a = t.key.toLowerCase(), r = n && t.altKey && t.shiftKey && a === "b", e = !t.metaKey && !t.ctrlKey && !t.altKey && !t.shiftKey && a === "f8"; | ||
| return r || e; | ||
| } | ||
| function S(t, n, a, r, e) { | ||
| ft(); | ||
| const i = a === "insert" ? lt(t) : null, o = n.labels, l = e ? Z(e, n) : H(r || {}, n), d = document.createElement("div"); | ||
| d.className = g, ht(t) && d.classList.add("rte-data-binding-theme-dark"); | ||
| const c = document.createElement("section"); | ||
| c.className = "rte-data-binding-dialog", c.setAttribute("role", "dialog"), c.setAttribute("aria-modal", "true"), c.setAttribute("aria-labelledby", "rte-data-binding-dialog-title"), c.innerHTML = ` | ||
| <header class="rte-data-binding-header"> | ||
| <h2 id="rte-data-binding-dialog-title" class="rte-data-binding-title">${y( | ||
| a === "edit" ? o.dialogTitleEdit : o.dialogTitleInsert | ||
| )}</h2> | ||
| <button type="button" class="rte-data-binding-btn" data-action="cancel" aria-label="${y(o.cancelText)}">✕</button> | ||
| </header> | ||
| <div class="rte-data-binding-body"> | ||
| <div class="rte-data-binding-field"> | ||
| <label for="rte-data-binding-key">${y(o.keyLabel)}</label> | ||
| <input id="rte-data-binding-key" class="rte-data-binding-key" type="text" value="${y(l.key)}" placeholder="${y( | ||
| o.keyPlaceholder | ||
| )}" /> | ||
| </div> | ||
| <div class="rte-data-binding-field"> | ||
| <label for="rte-data-binding-fallback">${y(o.fallbackLabel)}</label> | ||
| <input id="rte-data-binding-fallback" class="rte-data-binding-fallback" type="text" value="${y( | ||
| l.fallback || "" | ||
| )}" placeholder="${y(o.fallbackPlaceholder)}" /> | ||
| </div> | ||
| <div class="rte-data-binding-field"> | ||
| <label for="rte-data-binding-format">${y(o.formatLabel)}</label> | ||
| <select id="rte-data-binding-format" class="rte-data-binding-format"> | ||
| <option value="text" ${l.format === "text" ? "selected" : ""}>Text</option> | ||
| <option value="number" ${l.format === "number" ? "selected" : ""}>Number</option> | ||
| <option value="currency" ${l.format === "currency" ? "selected" : ""}>Currency</option> | ||
| <option value="date" ${l.format === "date" ? "selected" : ""}>Date</option> | ||
| <option value="json" ${l.format === "json" ? "selected" : ""}>JSON</option> | ||
| </select> | ||
| </div> | ||
| <div class="rte-data-binding-field"> | ||
| <label for="rte-data-binding-currency">${y(o.currencyLabel)}</label> | ||
| <input id="rte-data-binding-currency" class="rte-data-binding-currency" type="text" maxlength="3" value="${y( | ||
| l.currency || "USD" | ||
| )}" placeholder="${y(o.currencyPlaceholder)}" /> | ||
| </div> | ||
| <p class="rte-data-binding-help">Use dot paths like <code>user.name</code> or <code>order.total</code>.</p> | ||
| </div> | ||
| <footer class="rte-data-binding-footer"> | ||
| <button type="button" class="rte-data-binding-btn" data-action="cancel">${y(o.cancelText)}</button> | ||
| <button type="button" class="rte-data-binding-btn rte-data-binding-btn-primary" data-action="save">${y(o.saveText)}</button> | ||
| </footer> | ||
| `, d.appendChild(c), document.body.appendChild(d); | ||
| const u = c.querySelector(".rte-data-binding-key"), p = c.querySelector(".rte-data-binding-fallback"), m = c.querySelector(".rte-data-binding-format"), $ = c.querySelector(".rte-data-binding-currency"), B = () => { | ||
| const s = m?.value === "currency", k = $?.closest(".rte-data-binding-field"); | ||
| k && (k.style.display = s ? "grid" : "none"); | ||
| }; | ||
| B(), m?.addEventListener("change", B); | ||
| const L = () => { | ||
| d.removeEventListener("click", nt), d.removeEventListener("keydown", rt, !0), document.removeEventListener("keydown", et, !0), d.parentNode && d.parentNode.removeChild(d), R = null, t.focus({ preventScroll: !0 }); | ||
| }, et = (s) => { | ||
| s.key === "Escape" && (s.preventDefault(), s.stopPropagation(), L()); | ||
| }, nt = (s) => { | ||
| s.target === d && L(); | ||
| }, gt = (s) => { | ||
| if (s.key !== "Tab") return; | ||
| const k = Array.from( | ||
| c.querySelectorAll('button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])') | ||
| ); | ||
| if (k.length === 0) return; | ||
| const w = k[0], E = k[k.length - 1], F = document.activeElement; | ||
| if (s.shiftKey && F === w) { | ||
| s.preventDefault(), E.focus(); | ||
| return; | ||
| } | ||
| !s.shiftKey && F === E && (s.preventDefault(), w.focus()); | ||
| }, at = async () => { | ||
| const s = (u?.value || "").trim(); | ||
| if (!s) { | ||
| u?.focus(); | ||
| return; | ||
| } | ||
| const k = H( | ||
| { | ||
| key: s, | ||
| fallback: (p?.value || "").trim(), | ||
| format: m?.value || n.defaultFormat, | ||
| currency: ($?.value || "USD").trim().toUpperCase() | ||
| }, | ||
| n | ||
| ), w = t.innerHTML; | ||
| if (e) { | ||
| X(e, k, o); | ||
| const E = x.get(t) === !0, F = E ? await I(t, n) : void 0; | ||
| T(e, n, E, F); | ||
| } else { | ||
| if (i) | ||
| try { | ||
| st(t, i); | ||
| } catch { | ||
| } | ||
| const E = ut(k, o); | ||
| if (bt(t, E), x.get(t) === !0) { | ||
| const mt = await I(t, n); | ||
| T(E, n, !0, mt); | ||
| } | ||
| } | ||
| J(t), Y(t, w), L(); | ||
| }, rt = (s) => { | ||
| if (s.key === "Escape") { | ||
| s.preventDefault(), L(); | ||
| return; | ||
| } | ||
| gt(s), s.key === "Enter" && !s.shiftKey && s.target instanceof HTMLInputElement && (s.preventDefault(), at()); | ||
| }; | ||
| c.addEventListener("click", (s) => { | ||
| const w = s.target?.getAttribute("data-action"); | ||
| if (w) { | ||
| if (w === "cancel") { | ||
| L(); | ||
| return; | ||
| } | ||
| w === "save" && at(); | ||
| } | ||
| }), d.addEventListener("click", nt), d.addEventListener("keydown", rt, !0), document.addEventListener("keydown", et, !0), R = { cleanup: L }, u?.focus(); | ||
| } | ||
| function Tt(t) { | ||
| z = t, O || (O = (n) => { | ||
| const r = n.target?.closest(A); | ||
| if (!r) return; | ||
| h = r, b.has(r) || b.set(r, t); | ||
| const e = b.get(r) || t; | ||
| V(r, e); | ||
| const i = x.get(r) === !0; | ||
| tt(r, i, e), i || Array.from(r.querySelectorAll(C)).forEach((l) => T(l, e, !1)); | ||
| }, document.addEventListener("focusin", O, !0)), P || (P = (n) => { | ||
| if (document.querySelector(`.${g}`)) return; | ||
| const a = n.target; | ||
| if (a?.closest("input, textarea, select")) return; | ||
| const r = D(void 0, !1); | ||
| if (!r || K(r)) return; | ||
| const e = b.get(r) || z || t, i = a?.closest(C); | ||
| if (i && (n.key === "Enter" || n.key === " ")) { | ||
| n.preventDefault(), n.stopPropagation(), h = r, S(r, e, "edit", void 0, i); | ||
| return; | ||
| } | ||
| if (At(n)) { | ||
| n.preventDefault(), n.stopPropagation(); | ||
| const o = Q(r); | ||
| o ? S(r, e, "edit", void 0, o) : S(r, e, "insert"); | ||
| return; | ||
| } | ||
| if (St(n)) { | ||
| n.preventDefault(), n.stopPropagation(); | ||
| const o = x.get(r) !== !0; | ||
| _(r, e, o); | ||
| } | ||
| }, document.addEventListener("keydown", P, !0)), M || (M = (n) => { | ||
| if (document.querySelector(`.${g}`) || n.defaultPrevented || n.button !== 0 || n.metaKey || n.ctrlKey || n.altKey || n.shiftKey) return; | ||
| const r = n.target?.closest(C); | ||
| if (!r) return; | ||
| const e = r.closest(A); | ||
| if (!e || K(e)) return; | ||
| const i = b.get(e) || z || t; | ||
| b.set(e, i), h = e, n.preventDefault(), n.stopPropagation(), r.focus({ preventScroll: !0 }), S(e, i, "edit", void 0, r); | ||
| }, document.addEventListener("click", M, !0)); | ||
| } | ||
| function $t() { | ||
| O && (document.removeEventListener("focusin", O, !0), O = null), P && (document.removeEventListener("keydown", P, !0), P = null), M && (document.removeEventListener("click", M, !0), M = null), z = null, h = null; | ||
| } | ||
| const Lt = (t = {}) => { | ||
| const n = ot(t); | ||
| return xt(), { | ||
| name: "dataBinding", | ||
| toolbar: [ | ||
| { | ||
| id: "dataBindingTools", | ||
| label: "Data Binding", | ||
| type: "group", | ||
| command: "openDataBindingDialog", | ||
| items: [ | ||
| { | ||
| id: "dataBinding", | ||
| label: "Data Binding", | ||
| command: "openDataBindingDialog", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M7 4a3 3 0 0 0-3 3v3h2V7a1 1 0 0 1 1-1h3V4H7Zm10 0h-3v2h3a1 1 0 0 1 1 1v3h2V7a3 3 0 0 0-3-3ZM4 14v3a3 3 0 0 0 3 3h3v-2H7a1 1 0 0 1-1-1v-3H4Zm14 0v3a1 1 0 0 1-1 1h-3v2h3a3 3 0 0 0 3-3v-3h-2ZM8.5 12a1.5 1.5 0 1 1 0-3h7a1.5 1.5 0 0 1 0 3h-7Zm0 4a1.5 1.5 0 1 1 0-3h4a1.5 1.5 0 0 1 0 3h-4Z" fill="currentColor"></path></svg>' | ||
| }, | ||
| { | ||
| id: "dataBindingPreview", | ||
| label: "Data Preview", | ||
| command: "toggleDataBindingPreview", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M12 3c-4.4 0-8 1.3-8 3v12c0 1.7 3.6 3 8 3s8-1.3 8-3V6c0-1.7-3.6-3-8-3Zm0 2c3.9 0 6 .9 6 1s-2.1 1-6 1-6-.9-6-1 2.1-1 6-1Zm0 4c3 0 5.6-.5 7-1.3V11c0 .9-2.7 2-7 2s-7-1.1-7-2V7.7C6.4 8.5 9 9 12 9Zm0 6c-4.3 0-7-1.1-7-2v3c0 .9 2.7 2 7 2s7-1.1 7-2v-3c0 .9-2.7 2-7 2Z" fill="currentColor"></path><path d="M16.5 9.4a1 1 0 0 1 1.4 0l1.1 1.1 1.8-1.8a1 1 0 1 1 1.4 1.4l-2.5 2.5a1 1 0 0 1-1.4 0l-1.8-1.8a1 1 0 0 1 0-1.4Z" fill="currentColor"></path></svg>' | ||
| } | ||
| ] | ||
| } | ||
| ], | ||
| commands: { | ||
| openDataBindingDialog: (a, r) => { | ||
| const e = D(r); | ||
| if (!e || K(e)) return !1; | ||
| h = e; | ||
| const i = b.get(e) || n; | ||
| b.set(e, i), V(e, i); | ||
| const o = a?.target; | ||
| if (o === "insert") | ||
| return S(e, i, "insert", a), !0; | ||
| const l = Q(e); | ||
| return o === "edit" || l ? !l && o === "edit" ? !1 : (S(e, i, "edit", a, l || void 0), !0) : (S(e, i, "insert", a), !0); | ||
| }, | ||
| insertDataBindingToken: async (a, r) => { | ||
| const e = D(r); | ||
| if (!e || K(e)) return !1; | ||
| h = e; | ||
| const i = b.get(e) || n; | ||
| b.set(e, i); | ||
| const o = H(a || {}, i); | ||
| if (!o.key) return !1; | ||
| const l = e.innerHTML, d = ut(o, i.labels); | ||
| if (bt(e, d), x.get(e) === !0) { | ||
| const u = await I(e, i); | ||
| T(d, i, !0, u); | ||
| } | ||
| return J(e), Y(e, l), !0; | ||
| }, | ||
| editDataBindingToken: async (a, r) => { | ||
| const e = D(r); | ||
| if (!e || K(e)) return !1; | ||
| h = e; | ||
| const i = b.get(e) || n; | ||
| b.set(e, i); | ||
| const o = Q(e); | ||
| if (!o) return !1; | ||
| const l = Z(o, i), d = H({ ...l, ...a || {} }, i); | ||
| if (!d.key) return !1; | ||
| const c = e.innerHTML; | ||
| X(o, d, i.labels); | ||
| const u = x.get(e) === !0, p = u ? await I(e, i) : void 0; | ||
| return T(o, i, u, p), J(e), Y(e, c), !0; | ||
| }, | ||
| toggleDataBindingPreview: async (a, r) => { | ||
| const e = D(r); | ||
| if (!e) return !1; | ||
| h = e; | ||
| const i = b.get(e) || n; | ||
| b.set(e, i); | ||
| const o = typeof a == "boolean" ? a : x.get(e) !== !0; | ||
| return await _(e, i, o), !0; | ||
| }, | ||
| setDataBindingData: async (a, r) => { | ||
| const e = D(r); | ||
| if (!e) return !1; | ||
| if (h = e, a && typeof a == "object" ? (W.set(e, a), N.set(e, { timestamp: Date.now(), data: a })) : (W.delete(e), N.delete(e)), x.get(e) === !0) { | ||
| const i = b.get(e) || n; | ||
| await _(e, i, !0); | ||
| } | ||
| return !0; | ||
| }, | ||
| refreshDataBindings: async (a, r) => { | ||
| const e = D(r); | ||
| if (!e) return !1; | ||
| h = e, N.delete(e); | ||
| const i = b.get(e) || n; | ||
| b.set(e, i); | ||
| const o = x.get(e) === !0; | ||
| return await _(e, i, o), !0; | ||
| } | ||
| }, | ||
| keymap: { | ||
| "Mod-Alt-Shift-d": "openDataBindingDialog", | ||
| "Mod-Alt-Shift-D": "openDataBindingDialog", | ||
| "Mod-Alt-Shift-b": "toggleDataBindingPreview", | ||
| "Mod-Alt-Shift-B": "toggleDataBindingPreview", | ||
| F7: "openDataBindingDialog", | ||
| F8: "toggleDataBindingPreview" | ||
| }, | ||
| init: function(r) { | ||
| U += 1; | ||
| const e = this && typeof this.__pluginConfig == "object" ? ot({ ...n, ...this.__pluginConfig }) : n; | ||
| Tt(e); | ||
| const i = D( | ||
| r && r.editorElement ? { editorElement: r.editorElement } : void 0, | ||
| !1 | ||
| ); | ||
| if (i) { | ||
| h = i, b.set(i, e), V(i, e); | ||
| const o = x.get(i) === !0; | ||
| tt(i, o, e); | ||
| } | ||
| }, | ||
| destroy: () => { | ||
| U = Math.max(0, U - 1), U === 0 && (ft(), $t()); | ||
| } | ||
| }; | ||
| }; | ||
| export { | ||
| Lt as DataBindingPlugin | ||
| }; |
| "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const S=".rte-content, .editora-content",ie="[data-editora-editor], .rte-editor, .editora-editor, editora-editor",fe="__editoraCommandEditorRoot",he="rte-doc-schema-styles",m="rte-doc-schema-panel",v="document-schema",M="doc-schema",H="docSchema",E=':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)',Ie={panelTitle:"Document Schema",panelAriaLabel:"Document schema panel",schemaLabel:"Schema",schemaDescriptionPrefix:"Description",validateText:"Run Validation",insertMissingText:"Insert Missing Sections",realtimeOnText:"Realtime On",realtimeOffText:"Realtime Off",closeText:"Close",noIssuesText:"No schema violations detected.",summaryPrefix:"Schema",issueListLabel:"Schema issues",shortcutText:"Shortcuts: Ctrl/Cmd+Alt+Shift+G (panel), Ctrl/Cmd+Alt+Shift+J (validate)",helperText:"Choose a schema, validate structure, then insert missing sections safely.",readonlyMessage:"Editor is read-only. Missing sections cannot be inserted.",defaultPlaceholderText:"Add section content.",missingSectionMessage:"Missing required section",duplicateSectionMessage:"Section appears too many times",outOfOrderMessage:"Section appears out of required order",unknownHeadingMessage:"Heading is not part of selected schema",insertedSummaryPrefix:"Inserted missing sections"},u=new WeakMap,X=new WeakMap,j=new WeakMap,p=new Map,F=new WeakMap,te=new WeakMap,ne=new Set;let W=0,Ae=0,ge=0,w=null,b=null,q=null,z=null,B=null,R=null,K=null;function I(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function Le(e){return e.replace(/\u00A0/g," ").replace(/\s+/g," ").trim()}function P(e,t,n){return Number.isFinite(e)?Math.max(t,Math.min(n,e)):t}function xe(e){return e.toLowerCase().replace(/[^a-z0-9_-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,80)}function ce(e,t){return t(e).toLowerCase().replace(/^[\s\-\u2022]*(?:[0-9]+(?:\.[0-9]+)*)[\)\.\-:\s]+/,"").replace(/^[\s\-\u2022]*(?:[ivxlcdm]+)[\)\.\-:\s]+/i,"").replace(/[::]+$/g,"").replace(/\s+/g," ").trim()}function be(){return[{id:"contract",label:"Contract",description:"Template for legal/commercial agreements with strict section ordering.",strictOrder:!0,allowUnknownHeadings:!1,sections:[{id:"summary",title:"Executive Summary",aliases:["Overview"]},{id:"scope",title:"Scope"},{id:"terms",title:"Terms and Conditions",aliases:["Terms"]},{id:"responsibilities",title:"Responsibilities"},{id:"sla",title:"Service Levels",aliases:["SLA","Service Level Agreement"]},{id:"termination",title:"Termination"}]},{id:"sop",label:"SOP",description:"Standard operating procedure with clear implementation and governance sections.",strictOrder:!0,allowUnknownHeadings:!0,sections:[{id:"purpose",title:"Purpose"},{id:"scope",title:"Scope"},{id:"procedure",title:"Procedure",maxOccurrences:10},{id:"roles",title:"Roles and Responsibilities",aliases:["Responsibilities"]},{id:"validation",title:"Validation"},{id:"revision-history",title:"Revision History",aliases:["Change History"]}]},{id:"policy",label:"Policy",description:"Policy document with control ownership, exception handling, and enforcement.",strictOrder:!0,allowUnknownHeadings:!0,sections:[{id:"statement",title:"Policy Statement"},{id:"applicability",title:"Applicability",aliases:["Scope"]},{id:"controls",title:"Controls"},{id:"exceptions",title:"Exceptions"},{id:"enforcement",title:"Enforcement"}]}]}function Oe(e,t,n){const r=n(e.title||"");if(!r)return null;const s=xe(n(e.id||r))||`section-${t+1}`,o=P(Number(e.minOccurrences??1),0,20),a=Math.max(1,o),c=P(Number(e.maxOccurrences??a),o,40),i=n(e.placeholder||""),l=Array.isArray(e.aliases)?e.aliases.map(y=>n(y)).filter(Boolean):[],d=[r,...l].map(y=>ce(y,n)).filter(Boolean);return{id:s,title:r,minOccurrences:o,maxOccurrences:c,placeholder:i,matchKeys:Array.from(new Set(d))}}function Se(e,t){const n=Array.isArray(e)&&e.length>0?e:be(),r=[],s=new Set;return n.forEach((o,a)=>{const c=t(o.label||"");if(!c)return;const i=xe(t(o.id||c))||`schema-${a+1}`;let l=i,d=1;for(;s.has(l);)l=`${i}-${d++}`;s.add(l);const y=Array.isArray(o.sections)?o.sections:[],f=[],k=new Set;if(y.forEach(($,h)=>{const x=Oe($,h,t);if(!x)return;let N=x.id,Te=1;for(;k.has(N);)N=`${x.id}-${Te++}`;k.add(N),f.push({...x,id:N})}),f.length===0)return;const O=new Map,A=new Map;f.forEach(($,h)=>{A.set($.id,h),$.matchKeys.forEach(x=>{O.has(x)||O.set(x,$)})}),r.push({id:l,label:c,description:t(o.description||""),strictOrder:o.strictOrder!==!1,allowUnknownHeadings:!!o.allowUnknownHeadings,sections:f,matchKeyToSection:O,orderBySectionId:A})}),r.length>0?r:Se(be(),t)}function Z(e={}){const t=e.normalizeText||Le,n=Se(e.schemas,t),r=t(e.defaultSchemaId||""),s=n.some(o=>o.id===r)?r:n[0]?.id||null;return{schemas:n,defaultSchemaId:s,enableRealtime:e.enableRealtime!==!1,debounceMs:P(Number(e.debounceMs??260),60,2e3),maxIssues:P(Number(e.maxIssues??80),5,500),labels:{...Ie,...e.labels||{}},normalizeText:t}}function He(e){return{schemas:e.schemas.map(t=>({id:t.id,label:t.label,description:t.description||void 0,strictOrder:t.strictOrder,allowUnknownHeadings:t.allowUnknownHeadings,sections:t.sections.map(n=>({id:n.id,title:n.title,minOccurrences:n.minOccurrences,maxOccurrences:n.maxOccurrences,placeholder:n.placeholder||void 0}))})),defaultSchemaId:e.defaultSchemaId||void 0,enableRealtime:e.enableRealtime,debounceMs:e.debounceMs,maxIssues:e.maxIssues,labels:{...e.labels},normalizeText:e.normalizeText}}function le(e){return e.closest(ie)||e}function U(e){if(!e)return null;if(e.matches(S))return e;const t=e.querySelector(S);return t instanceof HTMLElement?t:null}function Re(){if(typeof window>"u")return null;const e=window[fe];if(!(e instanceof HTMLElement))return null;window[fe]=null;const t=U(e);if(t)return t;const n=e.closest(ie);if(n){const s=U(n);if(s)return s}const r=e.closest(S);return r instanceof HTMLElement?r:null}function De(e){const t=e.closest("[data-editora-editor]");if(t&&U(t)===e)return t;let n=e;for(;n;){if(n.matches(ie)&&(n===e||U(n)===e))return n;n=n.parentElement}return le(e)}function ye(e){return e?e.nodeType===Node.ELEMENT_NODE?e:e.parentElement:null}function Y(e){return e?(e.getAttribute("data-theme")||e.getAttribute("theme")||"").toLowerCase()==="dark"?!0:e.classList.contains("dark")||e.classList.contains("editora-theme-dark")||e.classList.contains("rte-theme-dark"):!1}function Ne(e){const t=le(e);if(Y(t))return!0;const n=t.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark");return Y(n)?!0:Y(document.documentElement)||Y(document.body)}function oe(e,t){e.classList.remove("rte-doc-schema-theme-dark"),Ne(t)&&e.classList.add("rte-doc-schema-theme-dark")}function Pe(e){for(let t=0;t<e.length;t+=1){const n=e[t];if(!(n.type!=="childList"||n.removedNodes.length===0))for(let r=0;r<n.removedNodes.length;r+=1){const s=n.removedNodes[r];if(s.nodeType!==Node.ELEMENT_NODE)continue;const o=s;if(o.matches?.(S)||o.matches?.(`.${m}`)||o.querySelector?.(S)||o.querySelector?.(`.${m}`))return!0}}return!1}function Q(){Array.from(ne).forEach(t=>{t.isConnected||ue(t)})}function T(e,t=!0,n=!0){if(Q(),e?.contentElement instanceof HTMLElement)return e.contentElement;if(e?.editorElement instanceof HTMLElement){const c=U(e.editorElement);if(c)return c}const r=Re();if(r)return r;const s=window.getSelection();if(s&&s.rangeCount>0){const c=ye(s.getRangeAt(0).startContainer)?.closest(S);if(c)return c}const o=document.activeElement;if(o){if(o.matches(S))return o;const c=o.closest(S);if(c)return c}if(n&&b&&b.isConnected)return b;if(!t)return null;const a=document.querySelector(S);return a instanceof HTMLElement?a:null}function _e(e){const t=e.target;if(t){const r=t.closest(`.${m}`);if(r){const o=Array.from(p.entries()).find(([,a])=>a===r);if(o)return o[0]}const s=t.closest(S);if(s)return s}const n=document.activeElement;if(n){const r=n.closest(`.${m}`);if(r){const o=Array.from(p.entries()).find(([,a])=>a===r);if(o)return o[0]}const s=n.closest(S);if(s)return s}return null}function pe(e,t,n){const r=De(e);Array.from(r.querySelectorAll(`.rte-toolbar-button[data-command="${t}"], .editora-toolbar-button[data-command="${t}"]`)).forEach(o=>{o.classList.toggle("active",n),o.setAttribute("data-active",n?"true":"false"),o.setAttribute("aria-pressed",n?"true":"false")})}function de(e){const t=te.get(e);typeof t=="number"&&(window.clearTimeout(t),te.delete(e))}function L(e,t){return t&&e.schemas.find(n=>n.id===t)||null}function re(e){return e.defaultSchemaId||e.schemas[0]?.id||null}function g(e,t){u.has(e)||u.set(e,t);let n=j.get(e);return n||(n={activeSchemaId:re(t),realtimeEnabled:t.enableRealtime,issues:[],headingCount:0,recognizedHeadingCount:0,missingCount:0,lastRunAt:null,snapshot:""},j.set(e,n)),(!n.activeSchemaId||!L(t,n.activeSchemaId))&&(n.activeSchemaId=re(t)),ne.add(e),n}function ue(e){de(e),p.get(e)?.remove(),p.delete(e),F.delete(e),u.delete(e),X.delete(e),j.delete(e),ne.delete(e),b===e&&(b=null)}function me(e){return F.get(e)===!0}function ve(e){return e.getAttribute("contenteditable")==="false"||e.getAttribute("data-readonly")==="true"}function se(e,t){if(!t.classList.contains("show"))return;const n=le(e).getBoundingClientRect(),r=Math.min(window.innerWidth-20,440),s=Math.max(10,window.innerWidth-r-10),o=Math.min(Math.max(10,n.right-r),s),a=Math.max(10,Math.min(window.innerHeight-10,n.top+12));t.style.width=`${r}px`,t.style.left=`${o}px`,t.style.top=`${a}px`,t.style.maxHeight=`${Math.max(260,window.innerHeight-20)}px`}function ee(e,t){const n=e.querySelector(".rte-doc-schema-live");n&&(n.textContent=t)}function qe(e,t){const n=Array.from(e.querySelectorAll("h1, h2, h3, h4, h5, h6")),r=[];return n.forEach((s,o)=>{const a=t(s.textContent||"");if(!a)return;const c=Number(s.tagName.slice(1))||0,i=ce(a,t);r.push({text:a,key:i,index:o,level:c})}),r}function Ee(e,t,n){const r=Array.from(e.querySelectorAll("h1, h2, h3, h4, h5, h6")),s=[];return r.forEach(o=>{const a=n(o.textContent||"");if(!a)return;const c=ce(a,n),i=c&&t.matchKeyToSection.get(c)||null,l=i?t.orderBySectionId.get(i.id)??null:null,d=P(Number(o.tagName.slice(1))||0,1,6);s.push({element:o,level:d,section:i,order:l})}),s}function ze(e,t=2){const n=e.filter(i=>i.section).map(i=>i.level),r=n.length>0?n:e.map(i=>i.level);if(r.length===0)return t;const s=new Map;r.forEach((i,l)=>{s.has(i)||s.set(i,{count:0,firstIndex:l});const d=s.get(i);d.count+=1});let o=t,a=-1,c=Number.MAX_SAFE_INTEGER;return s.forEach((i,l)=>{(i.count>a||i.count===a&&i.firstIndex<c||i.count===a&&i.firstIndex===c&&l<o)&&(o=l,a=i.count,c=i.firstIndex)}),P(o,1,6)}function Be(e){const t=window.getSelection();if(!t||t.rangeCount===0)return null;const n=t.getRangeAt(0);if(ye(n.startContainer)?.closest(S)!==e)return null;if(n.startContainer.nodeType===Node.ELEMENT_NODE){const o=n.startContainer,a=o.childNodes[n.startOffset]||null;return{parent:o,referenceNode:a}}const s=n.startContainer.parentNode;return s?{parent:s,referenceNode:n.startContainer.nextSibling||null}:null}function Ke(e,t,n,r){const s=Ee(e,n,r),o=n.orderBySectionId.get(t.id);if(typeof o!="number"||s.length===0)return{parent:e,referenceNode:null};const a=s.find(i=>typeof i.order=="number"&&i.order>o);if(a&&a.element.parentNode)return{parent:a.element.parentNode,referenceNode:a.element};let c=-1;for(let i=0;i<s.length;i+=1){const l=s[i];typeof l.order=="number"&&l.order<o&&(c=i)}if(c>=0){const i=s[c+1]?.element||null;return{parent:i?.parentNode||s[c].element.parentNode||e,referenceNode:i}}return{parent:e,referenceNode:null}}function Ve(e,t,n,r){const s=e.ownerDocument||document,o=`h${P(r,1,6)}`,a=s.createElement(o);a.setAttribute("data-doc-schema-section",t.id),a.textContent=t.title;const c=s.createElement("p");return c.textContent=t.placeholder||n.labels.defaultPlaceholderText,[a,c]}function V(e,t,n,r={}){return ge+=1,{id:`doc-schema-issue-${ge}`,type:e,severity:t,message:n,...r}}function J(e,t,n){return e.replace(/\{section\}/g,t||"").replace(/\{heading\}/g,n||"").trim()}function je(e,t,n){const r=qe(e,n.normalizeText),s=[],o=new Map,a=[];for(let i=0;i<r.length&&!(s.length>=n.maxIssues);i+=1){const l=r[i];if(!l.key)continue;const d=t.matchKeyToSection.get(l.key);if(d){o.set(d.id,(o.get(d.id)||0)+1),a.push({section:d,heading:l});continue}t.allowUnknownHeadings||s.push(V("unknown-heading","warning",J(n.labels.unknownHeadingMessage,null,l.text),{headingText:l.text,suggestion:"Map this heading to a schema alias or remove it from strict structure mode."}))}let c=0;for(let i=0;i<t.sections.length&&!(s.length>=n.maxIssues);i+=1){const l=t.sections[i],d=o.get(l.id)||0;d<l.minOccurrences&&(c+=1,s.push(V("missing-section","error",J(n.labels.missingSectionMessage,l.title,null),{sectionId:l.id,sectionTitle:l.title,suggestion:`Add heading "${l.title}" to satisfy schema requirements.`}))),d>l.maxOccurrences&&s.length<n.maxIssues&&s.push(V("duplicate-section","warning",J(n.labels.duplicateSectionMessage,l.title,null),{sectionId:l.id,sectionTitle:l.title,suggestion:`Keep at most ${l.maxOccurrences} instance(s) of "${l.title}".`}))}if(t.strictOrder&&s.length<n.maxIssues){let i=-1;for(let l=0;l<a.length&&!(s.length>=n.maxIssues);l+=1){const d=a[l],y=t.orderBySectionId.get(d.section.id)??l;y<i?s.push(V("out-of-order","warning",J(n.labels.outOfOrderMessage,d.section.title,d.heading.text),{sectionId:d.section.id,sectionTitle:d.section.title,headingText:d.heading.text,suggestion:`Move "${d.section.title}" after earlier required sections.`})):i=y}}return{issues:s,headingCount:r.length,recognizedHeadingCount:a.length,missingCount:c}}function we(e){const t=u.get(e)||w,n=j.get(e),r=t?L(t,n?.activeSchemaId||null):null;return{activeSchemaId:n?.activeSchemaId||null,activeSchemaLabel:r?.label||null,realtimeEnabled:n?.realtimeEnabled===!0,issues:n?.issues?n.issues.map(s=>({...s})):[],headingCount:n?.headingCount||0,recognizedHeadingCount:n?.recognizedHeadingCount||0,missingCount:n?.missingCount||0,lastRunAt:n?.lastRunAt||null}}function D(e){const t=j.get(e);pe(e,"toggleDocSchemaPanel",me(e)),pe(e,"toggleDocSchemaRealtime",t?.realtimeEnabled===!0)}function _(e){const t=p.get(e);if(!t)return;const n=u.get(e)||w;if(!n)return;const r=g(e,n),s=L(n,r.activeSchemaId),o=t.querySelector(".rte-doc-schema-label");o&&(o.textContent=n.labels.schemaLabel);const a=t.querySelector('[data-field="schema"]');a&&(a.innerHTML=n.schemas.map(h=>`<option value="${I(h.id)}">${I(h.label)}</option>`).join(""),a.value=r.activeSchemaId||"");const c=t.querySelector(".rte-doc-schema-description");if(c){const h=s?.description||"";c.textContent=h?`${n.labels.schemaDescriptionPrefix}: ${h}`:"",c.hidden=!h}const i=t.querySelector(".rte-doc-schema-summary");if(i){const h=s?.label||"N/A",x=r.issues.length;i.textContent=`${n.labels.summaryPrefix}: ${h} • ${x} issue${x===1?"":"s"}`}const l=t.querySelector(".rte-doc-schema-helper");l&&(l.textContent=n.labels.helperText);const d=t.querySelector(".rte-doc-schema-shortcut");d&&(d.textContent=n.labels.shortcutText);const y=t.querySelector('[data-action="run-validation"]');y&&(y.textContent=n.labels.validateText);const f=t.querySelector('[data-action="insert-missing"]');if(f){f.textContent=n.labels.insertMissingText;const h=r.issues.some(x=>x.type==="missing-section");f.disabled=!h||ve(e)}const k=t.querySelector('[data-action="toggle-realtime"]');k&&(k.textContent=r.realtimeEnabled?n.labels.realtimeOnText:n.labels.realtimeOffText,k.setAttribute("aria-pressed",r.realtimeEnabled?"true":"false"));const O=t.querySelector('[data-action="close"]');O&&O.setAttribute("aria-label",n.labels.closeText);const A=t.querySelector(".rte-doc-schema-issues"),$=t.querySelector(".rte-doc-schema-empty");A&&(A.setAttribute("aria-label",n.labels.issueListLabel),r.issues.length===0?(A.innerHTML="",$&&($.hidden=!1,$.textContent=n.labels.noIssuesText)):($&&($.hidden=!0),A.innerHTML=r.issues.map(h=>{const x=h.severity==="error"?"error":h.severity==="warning"?"warning":"info",N=h.sectionTitle||h.headingText||"";return` | ||
| <li class="rte-doc-schema-issue ${x}" role="listitem"> | ||
| <p class="rte-doc-schema-issue-message">${I(h.message)}${N?`: <strong>${I(N)}</strong>`:""}</p> | ||
| ${h.suggestion?`<p class="rte-doc-schema-issue-suggestion">${I(h.suggestion)}</p>`:""} | ||
| </li> | ||
| `}).join(""))),t.setAttribute("aria-label",n.labels.panelAriaLabel)}function G(e,t=!1){const n=p.get(e);n&&(n.classList.remove("show"),F.set(e,!1),D(e),t&&e.focus({preventScroll:!0}))}function ae(e){const t=Fe(e);p.forEach((r,s)=>{s!==e&&G(s,!1)}),t.classList.add("show"),F.set(e,!0),_(e),se(e,t),D(e),t.querySelector('[data-field="schema"]')?.focus(),C(e,"panel-open",!1)}function ke(e,t){const n=me(e);return(typeof t=="boolean"?t:!n)?ae(e):G(e,!1),!0}function Ue(e,t){if(t===e.innerHTML)return;const n=window.execEditorCommand||window.executeEditorCommand;if(typeof n=="function")try{n("recordDomTransaction",e,t,e.innerHTML)}catch{}}function Ge(e){e.dispatchEvent(new Event("input",{bubbles:!0}))}function C(e,t,n){const r=u.get(e)||w;if(!r)return[];const s=g(e,r),o=p.get(e),a=e.innerHTML;if(!n&&s.snapshot===a)return s.issues;const c=L(r,s.activeSchemaId);if(!c)return s.issues=[V("missing-section","error","No active schema is configured for this editor.",{suggestion:"Set `defaultSchemaId` or update schema options."})],s.headingCount=0,s.recognizedHeadingCount=0,s.missingCount=1,s.lastRunAt=new Date().toISOString(),s.snapshot=a,_(e),D(e),s.issues;const i=je(e,c,r);return s.issues=i.issues,s.headingCount=i.headingCount,s.recognizedHeadingCount=i.recognizedHeadingCount,s.missingCount=i.missingCount,s.lastRunAt=new Date().toISOString(),s.snapshot=a,_(e),D(e),e.dispatchEvent(new CustomEvent("editora:doc-schema-validation",{bubbles:!0,detail:{reason:t,state:we(e)}})),o&&ee(o,i.issues.length===0?r.labels.noIssuesText:`${i.issues.length} issue${i.issues.length===1?"":"s"} detected.`),s.issues}function $e(e){const t=u.get(e)||w;if(!t)return;de(e);const n=window.setTimeout(()=>{te.delete(e),C(e,"realtime",!1)},t.debounceMs);te.set(e,n)}function Ce(e,t){const n=u.get(e)||w;if(!n)return!1;const r=g(e,n),s=typeof t=="boolean"?t:!r.realtimeEnabled;return r.realtimeEnabled=s,s?$e(e):de(e),_(e),D(e),!0}function Me(e){const t=u.get(e)||w;if(!t)return!1;const n=g(e,t),r=p.get(e);if(ve(e))return r&&ee(r,t.labels.readonlyMessage),!1;const s=L(t,n.activeSchemaId);if(!s)return!1;C(e,"insert-missing-pre",!0);const o=Array.from(new Set(n.issues.filter(f=>f.type==="missing-section"&&f.sectionId).map(f=>f.sectionId))),a=s.sections.filter(f=>o.includes(f.id));if(a.length===0)return r&&ee(r,t.labels.noIssuesText),!1;const c=e.innerHTML,i=Ee(e,s,t.normalizeText),l=ze(i,2),d=Be(e);a.forEach(f=>{const k=s.strictOrder?Ke(e,f,s,t.normalizeText):d||{parent:e,referenceNode:null},[O,A]=Ve(e,f,t,l);k.parent.insertBefore(O,k.referenceNode),k.parent.insertBefore(A,k.referenceNode)}),Ue(e,c),Ge(e),C(e,"insert-missing-post",!0);const y=a.map(f=>f.title).join(", ");return e.dispatchEvent(new CustomEvent("editora:doc-schema-insert-missing",{bubbles:!0,detail:{schemaId:s.id,sectionIds:a.map(f=>f.id)}})),r&&ee(r,`${t.labels.insertedSummaryPrefix}: ${y}`),!0}function Fe(e){const t=p.get(e);if(t)return t;const n=u.get(e)||w||Z();g(e,n);const r=`rte-doc-schema-panel-${Ae++}`,s=`${r}-schema`,o=document.createElement("section");return o.className=m,o.id=r,o.setAttribute("role","dialog"),o.setAttribute("aria-modal","false"),o.setAttribute("aria-label",n.labels.panelAriaLabel),o.innerHTML=` | ||
| <header class="rte-doc-schema-header"> | ||
| <h2 class="rte-doc-schema-title">${I(n.labels.panelTitle)}</h2> | ||
| <button type="button" class="rte-doc-schema-icon-btn" data-action="close" aria-label="${I(n.labels.closeText)}">✕</button> | ||
| </header> | ||
| <div class="rte-doc-schema-body"> | ||
| <label class="rte-doc-schema-label" for="${I(s)}"></label> | ||
| <select id="${I(s)}" class="rte-doc-schema-select" data-field="schema"></select> | ||
| <p class="rte-doc-schema-description" hidden></p> | ||
| <p class="rte-doc-schema-summary"></p> | ||
| <div class="rte-doc-schema-actions"> | ||
| <button type="button" class="rte-doc-schema-btn rte-doc-schema-btn-primary" data-action="run-validation"></button> | ||
| <button type="button" class="rte-doc-schema-btn" data-action="insert-missing"></button> | ||
| <button type="button" class="rte-doc-schema-btn" data-action="toggle-realtime" aria-pressed="false"></button> | ||
| </div> | ||
| <p class="rte-doc-schema-helper"></p> | ||
| <p class="rte-doc-schema-shortcut"></p> | ||
| <div class="rte-doc-schema-issues-wrap"> | ||
| <ul class="rte-doc-schema-issues" role="list" aria-label="${I(n.labels.issueListLabel)}"></ul> | ||
| <p class="rte-doc-schema-empty" hidden></p> | ||
| </div> | ||
| </div> | ||
| <div class="rte-doc-schema-live" aria-live="polite" aria-atomic="true"></div> | ||
| `,o.addEventListener("click",a=>{const i=a.target?.closest("[data-action]");if(!i)return;const l=i.getAttribute("data-action");if(l==="close"){G(e,!0);return}if(l==="run-validation"){C(e,"panel-button",!0);return}if(l==="insert-missing"){Me(e);return}l==="toggle-realtime"&&Ce(e)}),o.addEventListener("change",a=>{const c=a.target;if(!(c instanceof HTMLSelectElement)||c.getAttribute("data-field")!=="schema")return;const i=u.get(e)||w;if(!i)return;const l=g(e,i),d=c.value;L(i,d)&&(l.activeSchemaId=d,l.snapshot="",C(e,"schema-change",!0))}),o.addEventListener("keydown",a=>{a.key==="Escape"&&(a.preventDefault(),G(e,!0))}),oe(o,e),document.body.appendChild(o),p.set(e,o),F.set(e,!1),_(e),o}function We(e){const t=e.key.toLowerCase();return(e.metaKey||e.ctrlKey)&&e.altKey&&e.shiftKey&&t==="g"}function Ye(e){const t=e.key.toLowerCase();return(e.metaKey||e.ctrlKey)&&e.altKey&&e.shiftKey&&t==="j"}function Je(e){w=e,q||(q=t=>{Q();const r=t.target?.closest(S);if(!r)return;const s=u.get(r)||e;g(r,s),u.set(r,s),b=r,D(r);const o=p.get(r);o&&(oe(o,r),se(r,o),_(r))},document.addEventListener("focusin",q,!0)),z||(z=t=>{const r=t.target?.closest(S);if(!r)return;const s=u.get(r)||w;!s||!g(r,s).realtimeEnabled||$e(r)},document.addEventListener("input",z,!0)),B||(B=t=>{if(t.defaultPrevented||t.target?.closest(`.${m}`)&&t.key!=="Escape")return;const r=_e(t);if(!r)return;const s=u.get(r)||w||e;if(g(r,s),u.set(r,s),b=r,t.key==="Escape"&&me(r)){t.preventDefault(),G(r,!0);return}if(We(t)){t.preventDefault(),t.stopPropagation(),ke(r);return}Ye(t)&&(t.preventDefault(),t.stopPropagation(),C(r,"shortcut",!0))},document.addEventListener("keydown",B,!0)),R||(R=()=>{Q(),p.forEach((t,n)=>{!n.isConnected||!t.isConnected||(oe(t,n),se(n,t))})},window.addEventListener("scroll",R,!0),window.addEventListener("resize",R)),!K&&typeof MutationObserver<"u"&&document.body&&(K=new MutationObserver(t=>{Pe(t)&&Q()}),K.observe(document.body,{childList:!0,subtree:!0}))}function Xe(){q&&(document.removeEventListener("focusin",q,!0),q=null),z&&(document.removeEventListener("input",z,!0),z=null),B&&(document.removeEventListener("keydown",B,!0),B=null),R&&(window.removeEventListener("scroll",R,!0),window.removeEventListener("resize",R),R=null),K&&(K.disconnect(),K=null),p.forEach(t=>t.remove()),p.clear(),Array.from(ne).forEach(t=>ue(t)),w=null,b=null}function Ze(){if(typeof document>"u"||document.getElementById(he))return;const e=document.createElement("style");e.id=he,e.textContent=` | ||
| .rte-toolbar-group-items.${v}, | ||
| .editora-toolbar-group-items.${v}, | ||
| .rte-toolbar-group-items.${M}, | ||
| .editora-toolbar-group-items.${M}, | ||
| .rte-toolbar-group-items.${H}, | ||
| .editora-toolbar-group-items.${H} { | ||
| display: flex; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 4px; | ||
| background: #ffffff; | ||
| } | ||
| .rte-toolbar-group-items.${v} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${v} .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${M} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${M} .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${H} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${H} .editora-toolbar-button { | ||
| border: none; | ||
| border-right: 1px solid #cbd5e1; | ||
| border-radius: 0; | ||
| } | ||
| .rte-toolbar-group-items.${v} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${v} .editora-toolbar-item:last-child .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${M} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${M} .editora-toolbar-item:last-child .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${H} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${H} .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| ${E} .rte-toolbar-group-items.${v}, | ||
| ${E} .editora-toolbar-group-items.${v}, | ||
| ${E} .rte-toolbar-group-items.${M}, | ||
| ${E} .editora-toolbar-group-items.${M}, | ||
| ${E} .rte-toolbar-group-items.${H}, | ||
| ${E} .editora-toolbar-group-items.${H} { | ||
| border-color: #566275; | ||
| } | ||
| .rte-toolbar-button[data-command="toggleDocSchemaRealtime"].active, | ||
| .editora-toolbar-button[data-command="toggleDocSchemaRealtime"].active { | ||
| background-color: #ccc; | ||
| } | ||
| ${E} .rte-toolbar-group-items.${v} .rte-toolbar-button svg, | ||
| ${E} .editora-toolbar-group-items.${v} .editora-toolbar-button svg, | ||
| ${E} .rte-toolbar-group-items.${M} .rte-toolbar-button svg, | ||
| ${E} .editora-toolbar-group-items.${M} .editora-toolbar-button svg | ||
| { | ||
| fill: none; | ||
| } | ||
| ${E} .rte-toolbar-group-items.${v} .rte-toolbar-button, | ||
| ${E} .editora-toolbar-group-items.${v} .editora-toolbar-button | ||
| { | ||
| border-color: #566275; | ||
| } | ||
| .${m} { | ||
| position: fixed; | ||
| z-index: 12000; | ||
| display: none; | ||
| width: min(440px, calc(100vw - 20px)); | ||
| max-height: calc(100vh - 20px); | ||
| border: 1px solid #d1d5db; | ||
| border-radius: 14px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| box-shadow: 0 24px 48px rgba(15, 23, 42, 0.24); | ||
| overflow: hidden; | ||
| } | ||
| .${m}.show { | ||
| display: flex; | ||
| flex-direction: column; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark { | ||
| border-color: #334155; | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| box-shadow: 0 24px 52px rgba(2, 6, 23, 0.68); | ||
| } | ||
| .rte-doc-schema-header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| padding: 12px 14px; | ||
| border-bottom: 1px solid #e2e8f0; | ||
| background: linear-gradient(180deg, #f8fafc 0%, #f1f5f9 100%); | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-header { | ||
| border-color: #1e293b; | ||
| background: linear-gradient(180deg, #111827 0%, #0f172a 100%); | ||
| } | ||
| .rte-doc-schema-title { | ||
| margin: 0; | ||
| font-size: 15px; | ||
| line-height: 1.2; | ||
| font-weight: 700; | ||
| } | ||
| .rte-doc-schema-icon-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| min-height: 34px; | ||
| width: 34px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| font-weight: 600; | ||
| padding: 0; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| cursor: pointer; | ||
| } | ||
| .rte-doc-schema-icon-btn:hover, | ||
| .rte-doc-schema-icon-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-icon-btn { | ||
| border-color: #475569; | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-icon-btn:hover, | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-icon-btn:focus-visible { | ||
| border-color: #60a5fa; | ||
| box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.24); | ||
| } | ||
| .rte-doc-schema-body { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 8px; | ||
| padding: 12px; | ||
| overflow: auto; | ||
| } | ||
| .rte-doc-schema-label { | ||
| font-size: 12px; | ||
| line-height: 1.3; | ||
| font-weight: 700; | ||
| color: #334155; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-label { | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-doc-schema-select { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| min-height: 34px; | ||
| padding: 0 10px; | ||
| font-size: 13px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| } | ||
| .rte-doc-schema-select:focus-visible { | ||
| border-color: #0f766e; | ||
| box-shadow: 0 0 0 3px rgba(15, 118, 110, 0.18); | ||
| outline: none; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-select { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #e2e8f0; | ||
| } | ||
| .rte-doc-schema-description, | ||
| .rte-doc-schema-summary, | ||
| .rte-doc-schema-helper, | ||
| .rte-doc-schema-shortcut { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #475569; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-description, | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-summary, | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-helper, | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-shortcut { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-doc-schema-actions { | ||
| display: grid; | ||
| grid-template-columns: repeat(3, minmax(0, 1fr)); | ||
| gap: 8px; | ||
| } | ||
| .rte-doc-schema-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| min-height: 34px; | ||
| padding: 0 8px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| cursor: pointer; | ||
| } | ||
| .rte-doc-schema-btn:disabled { | ||
| opacity: 0.6; | ||
| cursor: not-allowed; | ||
| } | ||
| .rte-doc-schema-btn-primary { | ||
| border-color: #0f766e; | ||
| background: #0f766e; | ||
| color: #f8fafc; | ||
| } | ||
| .rte-doc-schema-btn:hover, | ||
| .rte-doc-schema-btn:focus-visible { | ||
| border-color: #94a3b8; | ||
| outline: none; | ||
| } | ||
| .rte-doc-schema-btn-primary:hover, | ||
| .rte-doc-schema-btn-primary:focus-visible { | ||
| border-color: #115e59; | ||
| background: #115e59; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-btn { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-btn-primary { | ||
| border-color: #14b8a6; | ||
| background: #0f766e; | ||
| color: #f0fdfa; | ||
| } | ||
| .rte-doc-schema-issues-wrap { | ||
| border: 1px solid #e2e8f0; | ||
| border-radius: 10px; | ||
| padding: 6px; | ||
| background: #f8fafc; | ||
| max-height: min(40vh, 320px); | ||
| overflow: auto; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-issues-wrap { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| } | ||
| .rte-doc-schema-issues { | ||
| margin: 0; | ||
| padding: 0; | ||
| list-style: none; | ||
| display: grid; | ||
| gap: 6px; | ||
| } | ||
| .rte-doc-schema-issue { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| background: #ffffff; | ||
| padding: 8px; | ||
| display: grid; | ||
| gap: 4px; | ||
| } | ||
| .rte-doc-schema-issue.error { | ||
| border-color: #ef4444; | ||
| background: #fef2f2; | ||
| } | ||
| .rte-doc-schema-issue.warning { | ||
| border-color: #f59e0b; | ||
| background: #fffbeb; | ||
| } | ||
| .rte-doc-schema-issue.info { | ||
| border-color: #0ea5e9; | ||
| background: #f0f9ff; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-issue { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-issue.error { | ||
| border-color: rgba(239, 68, 68, 0.7); | ||
| background: rgba(127, 29, 29, 0.28); | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-issue.warning { | ||
| border-color: rgba(245, 158, 11, 0.72); | ||
| background: rgba(120, 53, 15, 0.28); | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-issue.info { | ||
| border-color: rgba(14, 165, 233, 0.7); | ||
| background: rgba(7, 89, 133, 0.28); | ||
| } | ||
| .rte-doc-schema-issue-message, | ||
| .rte-doc-schema-issue-suggestion { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #1f2937; | ||
| } | ||
| .rte-doc-schema-issue-suggestion { | ||
| color: #475569; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-issue-message { | ||
| color: #e2e8f0; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-issue-suggestion { | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-doc-schema-empty { | ||
| margin: 8px; | ||
| font-size: 12px; | ||
| color: #64748b; | ||
| } | ||
| .rte-doc-schema-live { | ||
| position: absolute; | ||
| width: 1px; | ||
| height: 1px; | ||
| margin: -1px; | ||
| padding: 0; | ||
| overflow: hidden; | ||
| clip: rect(0 0 0 0); | ||
| border: 0; | ||
| } | ||
| @media (max-width: 768px) { | ||
| .${m} { | ||
| left: 10px !important; | ||
| right: 10px; | ||
| top: 10px !important; | ||
| width: auto !important; | ||
| max-height: calc(100vh - 20px); | ||
| } | ||
| .rte-doc-schema-actions { | ||
| grid-template-columns: 1fr; | ||
| } | ||
| } | ||
| `,document.head.appendChild(e)}const Qe=(e={})=>{const t=Z(e),n=new Set;return Ze(),{name:"docSchema",toolbar:[{id:"docSchemaGroup",label:"Document Schema",type:"group",command:"docSchema",items:[{id:"toggleDocSchemaPanel",label:"Document Schema",command:"toggleDocSchemaPanel",shortcut:"Mod-Alt-Shift-g",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M6 4.5h12A1.5 1.5 0 0 1 19.5 6v12A1.5 1.5 0 0 1 18 19.5H6A1.5 1.5 0 0 1 4.5 18V6A1.5 1.5 0 0 1 6 4.5Z" stroke="currentColor" stroke-width="1.6"/><path d="M8 8h8M8 12h8M8 16h5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>'},{id:"runDocSchemaValidation",label:"Run Schema Validation",command:"runDocSchemaValidation",shortcut:"Mod-Alt-Shift-j",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M12 3.5 4.5 6.5v5c0 4.8 3.1 8.9 7.5 10 4.4-1.1 7.5-5.2 7.5-10v-5L12 3.5Z" stroke="currentColor" stroke-width="1.6"/><path d="m9 12.5 2 2 4-4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>'},{id:"toggleDocSchemaRealtime",label:"Toggle Schema Realtime",command:"toggleDocSchemaRealtime",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M4.5 12a7.5 7.5 0 1 1 7.5 7.5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><path d="M9.5 19.5H5.5v-4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/><circle cx="12" cy="12" r="2" fill="currentColor"/></svg>'}]}],commands:{docSchema:(r,s)=>{const o=T(s,!1,!1);if(!o)return!1;const a=u.get(o)||t;return g(o,a),u.set(o,a),b=o,ae(o),!0},openDocSchemaPanel:(r,s)=>{const o=T(s,!1,!1);if(!o)return!1;const a=u.get(o)||t;return g(o,a),u.set(o,a),b=o,ae(o),!0},toggleDocSchemaPanel:(r,s)=>{const o=T(s,!1,!1);if(!o)return!1;const a=u.get(o)||t;return g(o,a),u.set(o,a),b=o,ke(o,typeof r=="boolean"?r:void 0)},runDocSchemaValidation:(r,s)=>{const o=T(s,!1,!1);if(!o)return!1;const a=u.get(o)||t;return g(o,a),u.set(o,a),b=o,C(o,"command",!0),!0},insertMissingDocSchemaSections:(r,s)=>{const o=T(s,!1,!1);if(!o)return!1;const a=u.get(o)||t;return g(o,a),u.set(o,a),b=o,Me(o)},toggleDocSchemaRealtime:(r,s)=>{const o=T(s,!1,!1);if(!o)return!1;const a=u.get(o)||t;return g(o,a),u.set(o,a),b=o,Ce(o,typeof r=="boolean"?r:void 0)},setDocSchemaMode:(r,s)=>{const o=T(s,!1,!1);if(!o)return!1;const a=u.get(o)||t,c=g(o,a);u.set(o,a);const i=typeof r=="string"?r:r?.schemaId||r?.id;return!i||!L(a,i)?!1:(c.activeSchemaId=i,c.snapshot="",C(o,"set-mode",!0),!0)},setDocSchemaOptions:(r,s)=>{const o=T(s,!1,!1);if(!o||!r||typeof r!="object")return!1;const a=u.get(o)||t,c=X.get(o)||He(a),i={...c,...r,labels:{...c.labels||{},...r.labels||{}},schemas:Array.isArray(r.schemas)?r.schemas:c.schemas,normalizeText:r.normalizeText||a.normalizeText},l=Z(i);u.set(o,l),X.set(o,i);const d=g(o,l);return typeof r.enableRealtime=="boolean"&&(d.realtimeEnabled=r.enableRealtime),(!d.activeSchemaId||!L(l,d.activeSchemaId))&&(d.activeSchemaId=re(l)),typeof r.defaultSchemaId=="string"&&L(l,r.defaultSchemaId)&&(d.activeSchemaId=r.defaultSchemaId),d.snapshot="",C(o,"set-options",!0),_(o),D(o),!0},getDocSchemaState:(r,s)=>{const o=T(s,!1,!1);if(!o)return!1;const a=u.get(o)||t;g(o,a);const c=we(o);if(typeof r=="function")try{r(c)}catch{}return o.__docSchemaState=c,o.dispatchEvent(new CustomEvent("editora:doc-schema-state",{bubbles:!0,detail:c})),!0}},keymap:{"Mod-Alt-Shift-g":"toggleDocSchemaPanel","Mod-Alt-Shift-G":"toggleDocSchemaPanel","Mod-Alt-Shift-j":"runDocSchemaValidation","Mod-Alt-Shift-J":"runDocSchemaValidation"},init:function(s){W+=1;const o=this&&typeof this.__pluginConfig=="object"?{...e,...this.__pluginConfig}:e,a=Z(o);Je(a);const c=T(s?.editorElement?{editorElement:s.editorElement}:void 0,!1,!1);c&&(b=c,n.add(c),g(c,a),u.set(c,a),X.set(c,o),D(c),C(c,"init",!0))},destroy:()=>{n.forEach(r=>ue(r)),n.clear(),W=Math.max(0,W-1),!(W>0)&&Xe()}}};exports.DocSchemaPlugin=Qe; |
| const S = ".rte-content, .editora-content", ie = "[data-editora-editor], .rte-editor, .editora-editor, editora-editor", fe = "__editoraCommandEditorRoot", he = "rte-doc-schema-styles", m = "rte-doc-schema-panel", v = "document-schema", T = "doc-schema", H = "docSchema", E = ':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)', Me = { | ||
| panelTitle: "Document Schema", | ||
| panelAriaLabel: "Document schema panel", | ||
| schemaLabel: "Schema", | ||
| schemaDescriptionPrefix: "Description", | ||
| validateText: "Run Validation", | ||
| insertMissingText: "Insert Missing Sections", | ||
| realtimeOnText: "Realtime On", | ||
| realtimeOffText: "Realtime Off", | ||
| closeText: "Close", | ||
| noIssuesText: "No schema violations detected.", | ||
| summaryPrefix: "Schema", | ||
| issueListLabel: "Schema issues", | ||
| shortcutText: "Shortcuts: Ctrl/Cmd+Alt+Shift+G (panel), Ctrl/Cmd+Alt+Shift+J (validate)", | ||
| helperText: "Choose a schema, validate structure, then insert missing sections safely.", | ||
| readonlyMessage: "Editor is read-only. Missing sections cannot be inserted.", | ||
| defaultPlaceholderText: "Add section content.", | ||
| missingSectionMessage: "Missing required section", | ||
| duplicateSectionMessage: "Section appears too many times", | ||
| outOfOrderMessage: "Section appears out of required order", | ||
| unknownHeadingMessage: "Heading is not part of selected schema", | ||
| insertedSummaryPrefix: "Inserted missing sections" | ||
| }, u = /* @__PURE__ */ new WeakMap(), X = /* @__PURE__ */ new WeakMap(), j = /* @__PURE__ */ new WeakMap(), b = /* @__PURE__ */ new Map(), F = /* @__PURE__ */ new WeakMap(), te = /* @__PURE__ */ new WeakMap(), ne = /* @__PURE__ */ new Set(); | ||
| let W = 0, Ae = 0, ge = 0, w = null, p = null, q = null, z = null, B = null, R = null, K = null; | ||
| function M(e) { | ||
| return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); | ||
| } | ||
| function Le(e) { | ||
| return e.replace(/\u00A0/g, " ").replace(/\s+/g, " ").trim(); | ||
| } | ||
| function P(e, t, n) { | ||
| return Number.isFinite(e) ? Math.max(t, Math.min(n, e)) : t; | ||
| } | ||
| function xe(e) { | ||
| return e.toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80); | ||
| } | ||
| function ce(e, t) { | ||
| return t(e).toLowerCase().replace(/^[\s\-\u2022]*(?:[0-9]+(?:\.[0-9]+)*)[\)\.\-:\s]+/, "").replace(/^[\s\-\u2022]*(?:[ivxlcdm]+)[\)\.\-:\s]+/i, "").replace(/[::]+$/g, "").replace(/\s+/g, " ").trim(); | ||
| } | ||
| function pe() { | ||
| return [ | ||
| { | ||
| id: "contract", | ||
| label: "Contract", | ||
| description: "Template for legal/commercial agreements with strict section ordering.", | ||
| strictOrder: !0, | ||
| allowUnknownHeadings: !1, | ||
| sections: [ | ||
| { id: "summary", title: "Executive Summary", aliases: ["Overview"] }, | ||
| { id: "scope", title: "Scope" }, | ||
| { id: "terms", title: "Terms and Conditions", aliases: ["Terms"] }, | ||
| { id: "responsibilities", title: "Responsibilities" }, | ||
| { id: "sla", title: "Service Levels", aliases: ["SLA", "Service Level Agreement"] }, | ||
| { id: "termination", title: "Termination" } | ||
| ] | ||
| }, | ||
| { | ||
| id: "sop", | ||
| label: "SOP", | ||
| description: "Standard operating procedure with clear implementation and governance sections.", | ||
| strictOrder: !0, | ||
| allowUnknownHeadings: !0, | ||
| sections: [ | ||
| { id: "purpose", title: "Purpose" }, | ||
| { id: "scope", title: "Scope" }, | ||
| { id: "procedure", title: "Procedure", maxOccurrences: 10 }, | ||
| { id: "roles", title: "Roles and Responsibilities", aliases: ["Responsibilities"] }, | ||
| { id: "validation", title: "Validation" }, | ||
| { id: "revision-history", title: "Revision History", aliases: ["Change History"] } | ||
| ] | ||
| }, | ||
| { | ||
| id: "policy", | ||
| label: "Policy", | ||
| description: "Policy document with control ownership, exception handling, and enforcement.", | ||
| strictOrder: !0, | ||
| allowUnknownHeadings: !0, | ||
| sections: [ | ||
| { id: "statement", title: "Policy Statement" }, | ||
| { id: "applicability", title: "Applicability", aliases: ["Scope"] }, | ||
| { id: "controls", title: "Controls" }, | ||
| { id: "exceptions", title: "Exceptions" }, | ||
| { id: "enforcement", title: "Enforcement" } | ||
| ] | ||
| } | ||
| ]; | ||
| } | ||
| function Oe(e, t, n) { | ||
| const r = n(e.title || ""); | ||
| if (!r) return null; | ||
| const s = xe(n(e.id || r)) || `section-${t + 1}`, o = P(Number(e.minOccurrences ?? 1), 0, 20), a = Math.max(1, o), c = P(Number(e.maxOccurrences ?? a), o, 40), i = n(e.placeholder || ""), l = Array.isArray(e.aliases) ? e.aliases.map((y) => n(y)).filter(Boolean) : [], d = [r, ...l].map((y) => ce(y, n)).filter(Boolean); | ||
| return { | ||
| id: s, | ||
| title: r, | ||
| minOccurrences: o, | ||
| maxOccurrences: c, | ||
| placeholder: i, | ||
| matchKeys: Array.from(new Set(d)) | ||
| }; | ||
| } | ||
| function Se(e, t) { | ||
| const n = Array.isArray(e) && e.length > 0 ? e : pe(), r = [], s = /* @__PURE__ */ new Set(); | ||
| return n.forEach((o, a) => { | ||
| const c = t(o.label || ""); | ||
| if (!c) return; | ||
| const i = xe(t(o.id || c)) || `schema-${a + 1}`; | ||
| let l = i, d = 1; | ||
| for (; s.has(l); ) | ||
| l = `${i}-${d++}`; | ||
| s.add(l); | ||
| const y = Array.isArray(o.sections) ? o.sections : [], f = [], k = /* @__PURE__ */ new Set(); | ||
| if (y.forEach(($, h) => { | ||
| const x = Oe($, h, t); | ||
| if (!x) return; | ||
| let N = x.id, Ie = 1; | ||
| for (; k.has(N); ) | ||
| N = `${x.id}-${Ie++}`; | ||
| k.add(N), f.push({ | ||
| ...x, | ||
| id: N | ||
| }); | ||
| }), f.length === 0) return; | ||
| const O = /* @__PURE__ */ new Map(), A = /* @__PURE__ */ new Map(); | ||
| f.forEach(($, h) => { | ||
| A.set($.id, h), $.matchKeys.forEach((x) => { | ||
| O.has(x) || O.set(x, $); | ||
| }); | ||
| }), r.push({ | ||
| id: l, | ||
| label: c, | ||
| description: t(o.description || ""), | ||
| strictOrder: o.strictOrder !== !1, | ||
| allowUnknownHeadings: !!o.allowUnknownHeadings, | ||
| sections: f, | ||
| matchKeyToSection: O, | ||
| orderBySectionId: A | ||
| }); | ||
| }), r.length > 0 ? r : Se(pe(), t); | ||
| } | ||
| function Z(e = {}) { | ||
| const t = e.normalizeText || Le, n = Se(e.schemas, t), r = t(e.defaultSchemaId || ""), s = n.some((o) => o.id === r) ? r : n[0]?.id || null; | ||
| return { | ||
| schemas: n, | ||
| defaultSchemaId: s, | ||
| enableRealtime: e.enableRealtime !== !1, | ||
| debounceMs: P(Number(e.debounceMs ?? 260), 60, 2e3), | ||
| maxIssues: P(Number(e.maxIssues ?? 80), 5, 500), | ||
| labels: { | ||
| ...Me, | ||
| ...e.labels || {} | ||
| }, | ||
| normalizeText: t | ||
| }; | ||
| } | ||
| function He(e) { | ||
| return { | ||
| schemas: e.schemas.map((t) => ({ | ||
| id: t.id, | ||
| label: t.label, | ||
| description: t.description || void 0, | ||
| strictOrder: t.strictOrder, | ||
| allowUnknownHeadings: t.allowUnknownHeadings, | ||
| sections: t.sections.map((n) => ({ | ||
| id: n.id, | ||
| title: n.title, | ||
| minOccurrences: n.minOccurrences, | ||
| maxOccurrences: n.maxOccurrences, | ||
| placeholder: n.placeholder || void 0 | ||
| })) | ||
| })), | ||
| defaultSchemaId: e.defaultSchemaId || void 0, | ||
| enableRealtime: e.enableRealtime, | ||
| debounceMs: e.debounceMs, | ||
| maxIssues: e.maxIssues, | ||
| labels: { ...e.labels }, | ||
| normalizeText: e.normalizeText | ||
| }; | ||
| } | ||
| function le(e) { | ||
| return e.closest(ie) || e; | ||
| } | ||
| function U(e) { | ||
| if (!e) return null; | ||
| if (e.matches(S)) return e; | ||
| const t = e.querySelector(S); | ||
| return t instanceof HTMLElement ? t : null; | ||
| } | ||
| function Re() { | ||
| if (typeof window > "u") return null; | ||
| const e = window[fe]; | ||
| if (!(e instanceof HTMLElement)) return null; | ||
| window[fe] = null; | ||
| const t = U(e); | ||
| if (t) return t; | ||
| const n = e.closest(ie); | ||
| if (n) { | ||
| const s = U(n); | ||
| if (s) return s; | ||
| } | ||
| const r = e.closest(S); | ||
| return r instanceof HTMLElement ? r : null; | ||
| } | ||
| function De(e) { | ||
| const t = e.closest("[data-editora-editor]"); | ||
| if (t && U(t) === e) | ||
| return t; | ||
| let n = e; | ||
| for (; n; ) { | ||
| if (n.matches(ie) && (n === e || U(n) === e)) | ||
| return n; | ||
| n = n.parentElement; | ||
| } | ||
| return le(e); | ||
| } | ||
| function ye(e) { | ||
| return e ? e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement : null; | ||
| } | ||
| function Y(e) { | ||
| return e ? (e.getAttribute("data-theme") || e.getAttribute("theme") || "").toLowerCase() === "dark" ? !0 : e.classList.contains("dark") || e.classList.contains("editora-theme-dark") || e.classList.contains("rte-theme-dark") : !1; | ||
| } | ||
| function Ne(e) { | ||
| const t = le(e); | ||
| if (Y(t)) return !0; | ||
| const n = t.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark"); | ||
| return Y(n) ? !0 : Y(document.documentElement) || Y(document.body); | ||
| } | ||
| function oe(e, t) { | ||
| e.classList.remove("rte-doc-schema-theme-dark"), Ne(t) && e.classList.add("rte-doc-schema-theme-dark"); | ||
| } | ||
| function Pe(e) { | ||
| for (let t = 0; t < e.length; t += 1) { | ||
| const n = e[t]; | ||
| if (!(n.type !== "childList" || n.removedNodes.length === 0)) | ||
| for (let r = 0; r < n.removedNodes.length; r += 1) { | ||
| const s = n.removedNodes[r]; | ||
| if (s.nodeType !== Node.ELEMENT_NODE) continue; | ||
| const o = s; | ||
| if (o.matches?.(S) || o.matches?.(`.${m}`) || o.querySelector?.(S) || o.querySelector?.(`.${m}`)) | ||
| return !0; | ||
| } | ||
| } | ||
| return !1; | ||
| } | ||
| function Q() { | ||
| Array.from(ne).forEach((t) => { | ||
| t.isConnected || ue(t); | ||
| }); | ||
| } | ||
| function I(e, t = !0, n = !0) { | ||
| if (Q(), e?.contentElement instanceof HTMLElement) return e.contentElement; | ||
| if (e?.editorElement instanceof HTMLElement) { | ||
| const c = U(e.editorElement); | ||
| if (c) return c; | ||
| } | ||
| const r = Re(); | ||
| if (r) return r; | ||
| const s = window.getSelection(); | ||
| if (s && s.rangeCount > 0) { | ||
| const c = ye(s.getRangeAt(0).startContainer)?.closest( | ||
| S | ||
| ); | ||
| if (c) return c; | ||
| } | ||
| const o = document.activeElement; | ||
| if (o) { | ||
| if (o.matches(S)) return o; | ||
| const c = o.closest(S); | ||
| if (c) return c; | ||
| } | ||
| if (n && p && p.isConnected) | ||
| return p; | ||
| if (!t) return null; | ||
| const a = document.querySelector(S); | ||
| return a instanceof HTMLElement ? a : null; | ||
| } | ||
| function _e(e) { | ||
| const t = e.target; | ||
| if (t) { | ||
| const r = t.closest(`.${m}`); | ||
| if (r) { | ||
| const o = Array.from(b.entries()).find(([, a]) => a === r); | ||
| if (o) return o[0]; | ||
| } | ||
| const s = t.closest(S); | ||
| if (s) return s; | ||
| } | ||
| const n = document.activeElement; | ||
| if (n) { | ||
| const r = n.closest(`.${m}`); | ||
| if (r) { | ||
| const o = Array.from(b.entries()).find(([, a]) => a === r); | ||
| if (o) return o[0]; | ||
| } | ||
| const s = n.closest(S); | ||
| if (s) return s; | ||
| } | ||
| return null; | ||
| } | ||
| function be(e, t, n) { | ||
| const r = De(e); | ||
| Array.from( | ||
| r.querySelectorAll( | ||
| `.rte-toolbar-button[data-command="${t}"], .editora-toolbar-button[data-command="${t}"]` | ||
| ) | ||
| ).forEach((o) => { | ||
| o.classList.toggle("active", n), o.setAttribute("data-active", n ? "true" : "false"), o.setAttribute("aria-pressed", n ? "true" : "false"); | ||
| }); | ||
| } | ||
| function de(e) { | ||
| const t = te.get(e); | ||
| typeof t == "number" && (window.clearTimeout(t), te.delete(e)); | ||
| } | ||
| function L(e, t) { | ||
| return t && e.schemas.find((n) => n.id === t) || null; | ||
| } | ||
| function re(e) { | ||
| return e.defaultSchemaId || e.schemas[0]?.id || null; | ||
| } | ||
| function g(e, t) { | ||
| u.has(e) || u.set(e, t); | ||
| let n = j.get(e); | ||
| return n || (n = { | ||
| activeSchemaId: re(t), | ||
| realtimeEnabled: t.enableRealtime, | ||
| issues: [], | ||
| headingCount: 0, | ||
| recognizedHeadingCount: 0, | ||
| missingCount: 0, | ||
| lastRunAt: null, | ||
| snapshot: "" | ||
| }, j.set(e, n)), (!n.activeSchemaId || !L(t, n.activeSchemaId)) && (n.activeSchemaId = re(t)), ne.add(e), n; | ||
| } | ||
| function ue(e) { | ||
| de(e), b.get(e)?.remove(), b.delete(e), F.delete(e), u.delete(e), X.delete(e), j.delete(e), ne.delete(e), p === e && (p = null); | ||
| } | ||
| function me(e) { | ||
| return F.get(e) === !0; | ||
| } | ||
| function ve(e) { | ||
| return e.getAttribute("contenteditable") === "false" || e.getAttribute("data-readonly") === "true"; | ||
| } | ||
| function se(e, t) { | ||
| if (!t.classList.contains("show")) return; | ||
| const n = le(e).getBoundingClientRect(), r = Math.min(window.innerWidth - 20, 440), s = Math.max(10, window.innerWidth - r - 10), o = Math.min(Math.max(10, n.right - r), s), a = Math.max(10, Math.min(window.innerHeight - 10, n.top + 12)); | ||
| t.style.width = `${r}px`, t.style.left = `${o}px`, t.style.top = `${a}px`, t.style.maxHeight = `${Math.max(260, window.innerHeight - 20)}px`; | ||
| } | ||
| function ee(e, t) { | ||
| const n = e.querySelector(".rte-doc-schema-live"); | ||
| n && (n.textContent = t); | ||
| } | ||
| function qe(e, t) { | ||
| const n = Array.from(e.querySelectorAll("h1, h2, h3, h4, h5, h6")), r = []; | ||
| return n.forEach((s, o) => { | ||
| const a = t(s.textContent || ""); | ||
| if (!a) return; | ||
| const c = Number(s.tagName.slice(1)) || 0, i = ce(a, t); | ||
| r.push({ | ||
| text: a, | ||
| key: i, | ||
| index: o, | ||
| level: c | ||
| }); | ||
| }), r; | ||
| } | ||
| function Ee(e, t, n) { | ||
| const r = Array.from(e.querySelectorAll("h1, h2, h3, h4, h5, h6")), s = []; | ||
| return r.forEach((o) => { | ||
| const a = n(o.textContent || ""); | ||
| if (!a) return; | ||
| const c = ce(a, n), i = c && t.matchKeyToSection.get(c) || null, l = i ? t.orderBySectionId.get(i.id) ?? null : null, d = P(Number(o.tagName.slice(1)) || 0, 1, 6); | ||
| s.push({ | ||
| element: o, | ||
| level: d, | ||
| section: i, | ||
| order: l | ||
| }); | ||
| }), s; | ||
| } | ||
| function ze(e, t = 2) { | ||
| const n = e.filter((i) => i.section).map((i) => i.level), r = n.length > 0 ? n : e.map((i) => i.level); | ||
| if (r.length === 0) return t; | ||
| const s = /* @__PURE__ */ new Map(); | ||
| r.forEach((i, l) => { | ||
| s.has(i) || s.set(i, { count: 0, firstIndex: l }); | ||
| const d = s.get(i); | ||
| d.count += 1; | ||
| }); | ||
| let o = t, a = -1, c = Number.MAX_SAFE_INTEGER; | ||
| return s.forEach((i, l) => { | ||
| (i.count > a || i.count === a && i.firstIndex < c || i.count === a && i.firstIndex === c && l < o) && (o = l, a = i.count, c = i.firstIndex); | ||
| }), P(o, 1, 6); | ||
| } | ||
| function Be(e) { | ||
| const t = window.getSelection(); | ||
| if (!t || t.rangeCount === 0) return null; | ||
| const n = t.getRangeAt(0); | ||
| if (ye(n.startContainer)?.closest(S) !== e) return null; | ||
| if (n.startContainer.nodeType === Node.ELEMENT_NODE) { | ||
| const o = n.startContainer, a = o.childNodes[n.startOffset] || null; | ||
| return { parent: o, referenceNode: a }; | ||
| } | ||
| const s = n.startContainer.parentNode; | ||
| return s ? { | ||
| parent: s, | ||
| referenceNode: n.startContainer.nextSibling || null | ||
| } : null; | ||
| } | ||
| function Ke(e, t, n, r) { | ||
| const s = Ee(e, n, r), o = n.orderBySectionId.get(t.id); | ||
| if (typeof o != "number" || s.length === 0) | ||
| return { parent: e, referenceNode: null }; | ||
| const a = s.find((i) => typeof i.order == "number" && i.order > o); | ||
| if (a && a.element.parentNode) | ||
| return { | ||
| parent: a.element.parentNode, | ||
| referenceNode: a.element | ||
| }; | ||
| let c = -1; | ||
| for (let i = 0; i < s.length; i += 1) { | ||
| const l = s[i]; | ||
| typeof l.order == "number" && l.order < o && (c = i); | ||
| } | ||
| if (c >= 0) { | ||
| const i = s[c + 1]?.element || null; | ||
| return { | ||
| parent: i?.parentNode || s[c].element.parentNode || e, | ||
| referenceNode: i | ||
| }; | ||
| } | ||
| return { parent: e, referenceNode: null }; | ||
| } | ||
| function Ve(e, t, n, r) { | ||
| const s = e.ownerDocument || document, o = `h${P(r, 1, 6)}`, a = s.createElement(o); | ||
| a.setAttribute("data-doc-schema-section", t.id), a.textContent = t.title; | ||
| const c = s.createElement("p"); | ||
| return c.textContent = t.placeholder || n.labels.defaultPlaceholderText, [a, c]; | ||
| } | ||
| function V(e, t, n, r = {}) { | ||
| return ge += 1, { | ||
| id: `doc-schema-issue-${ge}`, | ||
| type: e, | ||
| severity: t, | ||
| message: n, | ||
| ...r | ||
| }; | ||
| } | ||
| function J(e, t, n) { | ||
| return e.replace(/\{section\}/g, t || "").replace(/\{heading\}/g, n || "").trim(); | ||
| } | ||
| function je(e, t, n) { | ||
| const r = qe(e, n.normalizeText), s = [], o = /* @__PURE__ */ new Map(), a = []; | ||
| for (let i = 0; i < r.length && !(s.length >= n.maxIssues); i += 1) { | ||
| const l = r[i]; | ||
| if (!l.key) continue; | ||
| const d = t.matchKeyToSection.get(l.key); | ||
| if (d) { | ||
| o.set(d.id, (o.get(d.id) || 0) + 1), a.push({ section: d, heading: l }); | ||
| continue; | ||
| } | ||
| t.allowUnknownHeadings || s.push( | ||
| V( | ||
| "unknown-heading", | ||
| "warning", | ||
| J(n.labels.unknownHeadingMessage, null, l.text), | ||
| { | ||
| headingText: l.text, | ||
| suggestion: "Map this heading to a schema alias or remove it from strict structure mode." | ||
| } | ||
| ) | ||
| ); | ||
| } | ||
| let c = 0; | ||
| for (let i = 0; i < t.sections.length && !(s.length >= n.maxIssues); i += 1) { | ||
| const l = t.sections[i], d = o.get(l.id) || 0; | ||
| d < l.minOccurrences && (c += 1, s.push( | ||
| V( | ||
| "missing-section", | ||
| "error", | ||
| J(n.labels.missingSectionMessage, l.title, null), | ||
| { | ||
| sectionId: l.id, | ||
| sectionTitle: l.title, | ||
| suggestion: `Add heading "${l.title}" to satisfy schema requirements.` | ||
| } | ||
| ) | ||
| )), d > l.maxOccurrences && s.length < n.maxIssues && s.push( | ||
| V( | ||
| "duplicate-section", | ||
| "warning", | ||
| J(n.labels.duplicateSectionMessage, l.title, null), | ||
| { | ||
| sectionId: l.id, | ||
| sectionTitle: l.title, | ||
| suggestion: `Keep at most ${l.maxOccurrences} instance(s) of "${l.title}".` | ||
| } | ||
| ) | ||
| ); | ||
| } | ||
| if (t.strictOrder && s.length < n.maxIssues) { | ||
| let i = -1; | ||
| for (let l = 0; l < a.length && !(s.length >= n.maxIssues); l += 1) { | ||
| const d = a[l], y = t.orderBySectionId.get(d.section.id) ?? l; | ||
| y < i ? s.push( | ||
| V( | ||
| "out-of-order", | ||
| "warning", | ||
| J(n.labels.outOfOrderMessage, d.section.title, d.heading.text), | ||
| { | ||
| sectionId: d.section.id, | ||
| sectionTitle: d.section.title, | ||
| headingText: d.heading.text, | ||
| suggestion: `Move "${d.section.title}" after earlier required sections.` | ||
| } | ||
| ) | ||
| ) : i = y; | ||
| } | ||
| } | ||
| return { | ||
| issues: s, | ||
| headingCount: r.length, | ||
| recognizedHeadingCount: a.length, | ||
| missingCount: c | ||
| }; | ||
| } | ||
| function we(e) { | ||
| const t = u.get(e) || w, n = j.get(e), r = t ? L(t, n?.activeSchemaId || null) : null; | ||
| return { | ||
| activeSchemaId: n?.activeSchemaId || null, | ||
| activeSchemaLabel: r?.label || null, | ||
| realtimeEnabled: n?.realtimeEnabled === !0, | ||
| issues: n?.issues ? n.issues.map((s) => ({ ...s })) : [], | ||
| headingCount: n?.headingCount || 0, | ||
| recognizedHeadingCount: n?.recognizedHeadingCount || 0, | ||
| missingCount: n?.missingCount || 0, | ||
| lastRunAt: n?.lastRunAt || null | ||
| }; | ||
| } | ||
| function D(e) { | ||
| const t = j.get(e); | ||
| be(e, "toggleDocSchemaPanel", me(e)), be(e, "toggleDocSchemaRealtime", t?.realtimeEnabled === !0); | ||
| } | ||
| function _(e) { | ||
| const t = b.get(e); | ||
| if (!t) return; | ||
| const n = u.get(e) || w; | ||
| if (!n) return; | ||
| const r = g(e, n), s = L(n, r.activeSchemaId), o = t.querySelector(".rte-doc-schema-label"); | ||
| o && (o.textContent = n.labels.schemaLabel); | ||
| const a = t.querySelector('[data-field="schema"]'); | ||
| a && (a.innerHTML = n.schemas.map((h) => `<option value="${M(h.id)}">${M(h.label)}</option>`).join(""), a.value = r.activeSchemaId || ""); | ||
| const c = t.querySelector(".rte-doc-schema-description"); | ||
| if (c) { | ||
| const h = s?.description || ""; | ||
| c.textContent = h ? `${n.labels.schemaDescriptionPrefix}: ${h}` : "", c.hidden = !h; | ||
| } | ||
| const i = t.querySelector(".rte-doc-schema-summary"); | ||
| if (i) { | ||
| const h = s?.label || "N/A", x = r.issues.length; | ||
| i.textContent = `${n.labels.summaryPrefix}: ${h} • ${x} issue${x === 1 ? "" : "s"}`; | ||
| } | ||
| const l = t.querySelector(".rte-doc-schema-helper"); | ||
| l && (l.textContent = n.labels.helperText); | ||
| const d = t.querySelector(".rte-doc-schema-shortcut"); | ||
| d && (d.textContent = n.labels.shortcutText); | ||
| const y = t.querySelector('[data-action="run-validation"]'); | ||
| y && (y.textContent = n.labels.validateText); | ||
| const f = t.querySelector('[data-action="insert-missing"]'); | ||
| if (f) { | ||
| f.textContent = n.labels.insertMissingText; | ||
| const h = r.issues.some((x) => x.type === "missing-section"); | ||
| f.disabled = !h || ve(e); | ||
| } | ||
| const k = t.querySelector('[data-action="toggle-realtime"]'); | ||
| k && (k.textContent = r.realtimeEnabled ? n.labels.realtimeOnText : n.labels.realtimeOffText, k.setAttribute("aria-pressed", r.realtimeEnabled ? "true" : "false")); | ||
| const O = t.querySelector('[data-action="close"]'); | ||
| O && O.setAttribute("aria-label", n.labels.closeText); | ||
| const A = t.querySelector(".rte-doc-schema-issues"), $ = t.querySelector(".rte-doc-schema-empty"); | ||
| A && (A.setAttribute("aria-label", n.labels.issueListLabel), r.issues.length === 0 ? (A.innerHTML = "", $ && ($.hidden = !1, $.textContent = n.labels.noIssuesText)) : ($ && ($.hidden = !0), A.innerHTML = r.issues.map((h) => { | ||
| const x = h.severity === "error" ? "error" : h.severity === "warning" ? "warning" : "info", N = h.sectionTitle || h.headingText || ""; | ||
| return ` | ||
| <li class="rte-doc-schema-issue ${x}" role="listitem"> | ||
| <p class="rte-doc-schema-issue-message">${M(h.message)}${N ? `: <strong>${M(N)}</strong>` : ""}</p> | ||
| ${h.suggestion ? `<p class="rte-doc-schema-issue-suggestion">${M(h.suggestion)}</p>` : ""} | ||
| </li> | ||
| `; | ||
| }).join(""))), t.setAttribute("aria-label", n.labels.panelAriaLabel); | ||
| } | ||
| function G(e, t = !1) { | ||
| const n = b.get(e); | ||
| n && (n.classList.remove("show"), F.set(e, !1), D(e), t && e.focus({ preventScroll: !0 })); | ||
| } | ||
| function ae(e) { | ||
| const t = Fe(e); | ||
| b.forEach((r, s) => { | ||
| s !== e && G(s, !1); | ||
| }), t.classList.add("show"), F.set(e, !0), _(e), se(e, t), D(e), t.querySelector('[data-field="schema"]')?.focus(), C(e, "panel-open", !1); | ||
| } | ||
| function ke(e, t) { | ||
| const n = me(e); | ||
| return (typeof t == "boolean" ? t : !n) ? ae(e) : G(e, !1), !0; | ||
| } | ||
| function Ue(e, t) { | ||
| if (t === e.innerHTML) return; | ||
| const n = window.execEditorCommand || window.executeEditorCommand; | ||
| if (typeof n == "function") | ||
| try { | ||
| n("recordDomTransaction", e, t, e.innerHTML); | ||
| } catch { | ||
| } | ||
| } | ||
| function Ge(e) { | ||
| e.dispatchEvent(new Event("input", { bubbles: !0 })); | ||
| } | ||
| function C(e, t, n) { | ||
| const r = u.get(e) || w; | ||
| if (!r) return []; | ||
| const s = g(e, r), o = b.get(e), a = e.innerHTML; | ||
| if (!n && s.snapshot === a) | ||
| return s.issues; | ||
| const c = L(r, s.activeSchemaId); | ||
| if (!c) | ||
| return s.issues = [ | ||
| V("missing-section", "error", "No active schema is configured for this editor.", { | ||
| suggestion: "Set `defaultSchemaId` or update schema options." | ||
| }) | ||
| ], s.headingCount = 0, s.recognizedHeadingCount = 0, s.missingCount = 1, s.lastRunAt = (/* @__PURE__ */ new Date()).toISOString(), s.snapshot = a, _(e), D(e), s.issues; | ||
| const i = je(e, c, r); | ||
| return s.issues = i.issues, s.headingCount = i.headingCount, s.recognizedHeadingCount = i.recognizedHeadingCount, s.missingCount = i.missingCount, s.lastRunAt = (/* @__PURE__ */ new Date()).toISOString(), s.snapshot = a, _(e), D(e), e.dispatchEvent( | ||
| new CustomEvent("editora:doc-schema-validation", { | ||
| bubbles: !0, | ||
| detail: { | ||
| reason: t, | ||
| state: we(e) | ||
| } | ||
| }) | ||
| ), o && ee( | ||
| o, | ||
| i.issues.length === 0 ? r.labels.noIssuesText : `${i.issues.length} issue${i.issues.length === 1 ? "" : "s"} detected.` | ||
| ), s.issues; | ||
| } | ||
| function $e(e) { | ||
| const t = u.get(e) || w; | ||
| if (!t) return; | ||
| de(e); | ||
| const n = window.setTimeout(() => { | ||
| te.delete(e), C(e, "realtime", !1); | ||
| }, t.debounceMs); | ||
| te.set(e, n); | ||
| } | ||
| function Ce(e, t) { | ||
| const n = u.get(e) || w; | ||
| if (!n) return !1; | ||
| const r = g(e, n), s = typeof t == "boolean" ? t : !r.realtimeEnabled; | ||
| return r.realtimeEnabled = s, s ? $e(e) : de(e), _(e), D(e), !0; | ||
| } | ||
| function Te(e) { | ||
| const t = u.get(e) || w; | ||
| if (!t) return !1; | ||
| const n = g(e, t), r = b.get(e); | ||
| if (ve(e)) | ||
| return r && ee(r, t.labels.readonlyMessage), !1; | ||
| const s = L(t, n.activeSchemaId); | ||
| if (!s) return !1; | ||
| C(e, "insert-missing-pre", !0); | ||
| const o = Array.from( | ||
| new Set( | ||
| n.issues.filter((f) => f.type === "missing-section" && f.sectionId).map((f) => f.sectionId) | ||
| ) | ||
| ), a = s.sections.filter((f) => o.includes(f.id)); | ||
| if (a.length === 0) | ||
| return r && ee(r, t.labels.noIssuesText), !1; | ||
| const c = e.innerHTML, i = Ee(e, s, t.normalizeText), l = ze(i, 2), d = Be(e); | ||
| a.forEach((f) => { | ||
| const k = s.strictOrder ? Ke(e, f, s, t.normalizeText) : d || { parent: e, referenceNode: null }, [O, A] = Ve(e, f, t, l); | ||
| k.parent.insertBefore(O, k.referenceNode), k.parent.insertBefore(A, k.referenceNode); | ||
| }), Ue(e, c), Ge(e), C(e, "insert-missing-post", !0); | ||
| const y = a.map((f) => f.title).join(", "); | ||
| return e.dispatchEvent( | ||
| new CustomEvent("editora:doc-schema-insert-missing", { | ||
| bubbles: !0, | ||
| detail: { | ||
| schemaId: s.id, | ||
| sectionIds: a.map((f) => f.id) | ||
| } | ||
| }) | ||
| ), r && ee(r, `${t.labels.insertedSummaryPrefix}: ${y}`), !0; | ||
| } | ||
| function Fe(e) { | ||
| const t = b.get(e); | ||
| if (t) return t; | ||
| const n = u.get(e) || w || Z(); | ||
| g(e, n); | ||
| const r = `rte-doc-schema-panel-${Ae++}`, s = `${r}-schema`, o = document.createElement("section"); | ||
| return o.className = m, o.id = r, o.setAttribute("role", "dialog"), o.setAttribute("aria-modal", "false"), o.setAttribute("aria-label", n.labels.panelAriaLabel), o.innerHTML = ` | ||
| <header class="rte-doc-schema-header"> | ||
| <h2 class="rte-doc-schema-title">${M(n.labels.panelTitle)}</h2> | ||
| <button type="button" class="rte-doc-schema-icon-btn" data-action="close" aria-label="${M( | ||
| n.labels.closeText | ||
| )}">✕</button> | ||
| </header> | ||
| <div class="rte-doc-schema-body"> | ||
| <label class="rte-doc-schema-label" for="${M(s)}"></label> | ||
| <select id="${M(s)}" class="rte-doc-schema-select" data-field="schema"></select> | ||
| <p class="rte-doc-schema-description" hidden></p> | ||
| <p class="rte-doc-schema-summary"></p> | ||
| <div class="rte-doc-schema-actions"> | ||
| <button type="button" class="rte-doc-schema-btn rte-doc-schema-btn-primary" data-action="run-validation"></button> | ||
| <button type="button" class="rte-doc-schema-btn" data-action="insert-missing"></button> | ||
| <button type="button" class="rte-doc-schema-btn" data-action="toggle-realtime" aria-pressed="false"></button> | ||
| </div> | ||
| <p class="rte-doc-schema-helper"></p> | ||
| <p class="rte-doc-schema-shortcut"></p> | ||
| <div class="rte-doc-schema-issues-wrap"> | ||
| <ul class="rte-doc-schema-issues" role="list" aria-label="${M(n.labels.issueListLabel)}"></ul> | ||
| <p class="rte-doc-schema-empty" hidden></p> | ||
| </div> | ||
| </div> | ||
| <div class="rte-doc-schema-live" aria-live="polite" aria-atomic="true"></div> | ||
| `, o.addEventListener("click", (a) => { | ||
| const i = a.target?.closest("[data-action]"); | ||
| if (!i) return; | ||
| const l = i.getAttribute("data-action"); | ||
| if (l === "close") { | ||
| G(e, !0); | ||
| return; | ||
| } | ||
| if (l === "run-validation") { | ||
| C(e, "panel-button", !0); | ||
| return; | ||
| } | ||
| if (l === "insert-missing") { | ||
| Te(e); | ||
| return; | ||
| } | ||
| l === "toggle-realtime" && Ce(e); | ||
| }), o.addEventListener("change", (a) => { | ||
| const c = a.target; | ||
| if (!(c instanceof HTMLSelectElement) || c.getAttribute("data-field") !== "schema") return; | ||
| const i = u.get(e) || w; | ||
| if (!i) return; | ||
| const l = g(e, i), d = c.value; | ||
| L(i, d) && (l.activeSchemaId = d, l.snapshot = "", C(e, "schema-change", !0)); | ||
| }), o.addEventListener("keydown", (a) => { | ||
| a.key === "Escape" && (a.preventDefault(), G(e, !0)); | ||
| }), oe(o, e), document.body.appendChild(o), b.set(e, o), F.set(e, !1), _(e), o; | ||
| } | ||
| function We(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "g"; | ||
| } | ||
| function Ye(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "j"; | ||
| } | ||
| function Je(e) { | ||
| w = e, q || (q = (t) => { | ||
| Q(); | ||
| const r = t.target?.closest(S); | ||
| if (!r) return; | ||
| const s = u.get(r) || e; | ||
| g(r, s), u.set(r, s), p = r, D(r); | ||
| const o = b.get(r); | ||
| o && (oe(o, r), se(r, o), _(r)); | ||
| }, document.addEventListener("focusin", q, !0)), z || (z = (t) => { | ||
| const r = t.target?.closest(S); | ||
| if (!r) return; | ||
| const s = u.get(r) || w; | ||
| !s || !g(r, s).realtimeEnabled || $e(r); | ||
| }, document.addEventListener("input", z, !0)), B || (B = (t) => { | ||
| if (t.defaultPrevented || t.target?.closest(`.${m}`) && t.key !== "Escape") return; | ||
| const r = _e(t); | ||
| if (!r) return; | ||
| const s = u.get(r) || w || e; | ||
| if (g(r, s), u.set(r, s), p = r, t.key === "Escape" && me(r)) { | ||
| t.preventDefault(), G(r, !0); | ||
| return; | ||
| } | ||
| if (We(t)) { | ||
| t.preventDefault(), t.stopPropagation(), ke(r); | ||
| return; | ||
| } | ||
| Ye(t) && (t.preventDefault(), t.stopPropagation(), C(r, "shortcut", !0)); | ||
| }, document.addEventListener("keydown", B, !0)), R || (R = () => { | ||
| Q(), b.forEach((t, n) => { | ||
| !n.isConnected || !t.isConnected || (oe(t, n), se(n, t)); | ||
| }); | ||
| }, window.addEventListener("scroll", R, !0), window.addEventListener("resize", R)), !K && typeof MutationObserver < "u" && document.body && (K = new MutationObserver((t) => { | ||
| Pe(t) && Q(); | ||
| }), K.observe(document.body, { | ||
| childList: !0, | ||
| subtree: !0 | ||
| })); | ||
| } | ||
| function Xe() { | ||
| q && (document.removeEventListener("focusin", q, !0), q = null), z && (document.removeEventListener("input", z, !0), z = null), B && (document.removeEventListener("keydown", B, !0), B = null), R && (window.removeEventListener("scroll", R, !0), window.removeEventListener("resize", R), R = null), K && (K.disconnect(), K = null), b.forEach((t) => t.remove()), b.clear(), Array.from(ne).forEach((t) => ue(t)), w = null, p = null; | ||
| } | ||
| function Ze() { | ||
| if (typeof document > "u" || document.getElementById(he)) return; | ||
| const e = document.createElement("style"); | ||
| e.id = he, e.textContent = ` | ||
| .rte-toolbar-group-items.${v}, | ||
| .editora-toolbar-group-items.${v}, | ||
| .rte-toolbar-group-items.${T}, | ||
| .editora-toolbar-group-items.${T}, | ||
| .rte-toolbar-group-items.${H}, | ||
| .editora-toolbar-group-items.${H} { | ||
| display: flex; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 4px; | ||
| background: #ffffff; | ||
| } | ||
| .rte-toolbar-group-items.${v} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${v} .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${T} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${T} .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${H} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${H} .editora-toolbar-button { | ||
| border: none; | ||
| border-right: 1px solid #cbd5e1; | ||
| border-radius: 0; | ||
| } | ||
| .rte-toolbar-group-items.${v} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${v} .editora-toolbar-item:last-child .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${T} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${T} .editora-toolbar-item:last-child .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${H} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${H} .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| ${E} .rte-toolbar-group-items.${v}, | ||
| ${E} .editora-toolbar-group-items.${v}, | ||
| ${E} .rte-toolbar-group-items.${T}, | ||
| ${E} .editora-toolbar-group-items.${T}, | ||
| ${E} .rte-toolbar-group-items.${H}, | ||
| ${E} .editora-toolbar-group-items.${H} { | ||
| border-color: #566275; | ||
| } | ||
| .rte-toolbar-button[data-command="toggleDocSchemaRealtime"].active, | ||
| .editora-toolbar-button[data-command="toggleDocSchemaRealtime"].active { | ||
| background-color: #ccc; | ||
| } | ||
| ${E} .rte-toolbar-group-items.${v} .rte-toolbar-button svg, | ||
| ${E} .editora-toolbar-group-items.${v} .editora-toolbar-button svg, | ||
| ${E} .rte-toolbar-group-items.${T} .rte-toolbar-button svg, | ||
| ${E} .editora-toolbar-group-items.${T} .editora-toolbar-button svg | ||
| { | ||
| fill: none; | ||
| } | ||
| ${E} .rte-toolbar-group-items.${v} .rte-toolbar-button, | ||
| ${E} .editora-toolbar-group-items.${v} .editora-toolbar-button | ||
| { | ||
| border-color: #566275; | ||
| } | ||
| .${m} { | ||
| position: fixed; | ||
| z-index: 12000; | ||
| display: none; | ||
| width: min(440px, calc(100vw - 20px)); | ||
| max-height: calc(100vh - 20px); | ||
| border: 1px solid #d1d5db; | ||
| border-radius: 14px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| box-shadow: 0 24px 48px rgba(15, 23, 42, 0.24); | ||
| overflow: hidden; | ||
| } | ||
| .${m}.show { | ||
| display: flex; | ||
| flex-direction: column; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark { | ||
| border-color: #334155; | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| box-shadow: 0 24px 52px rgba(2, 6, 23, 0.68); | ||
| } | ||
| .rte-doc-schema-header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| padding: 12px 14px; | ||
| border-bottom: 1px solid #e2e8f0; | ||
| background: linear-gradient(180deg, #f8fafc 0%, #f1f5f9 100%); | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-header { | ||
| border-color: #1e293b; | ||
| background: linear-gradient(180deg, #111827 0%, #0f172a 100%); | ||
| } | ||
| .rte-doc-schema-title { | ||
| margin: 0; | ||
| font-size: 15px; | ||
| line-height: 1.2; | ||
| font-weight: 700; | ||
| } | ||
| .rte-doc-schema-icon-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| min-height: 34px; | ||
| width: 34px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| font-weight: 600; | ||
| padding: 0; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| cursor: pointer; | ||
| } | ||
| .rte-doc-schema-icon-btn:hover, | ||
| .rte-doc-schema-icon-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-icon-btn { | ||
| border-color: #475569; | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-icon-btn:hover, | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-icon-btn:focus-visible { | ||
| border-color: #60a5fa; | ||
| box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.24); | ||
| } | ||
| .rte-doc-schema-body { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 8px; | ||
| padding: 12px; | ||
| overflow: auto; | ||
| } | ||
| .rte-doc-schema-label { | ||
| font-size: 12px; | ||
| line-height: 1.3; | ||
| font-weight: 700; | ||
| color: #334155; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-label { | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-doc-schema-select { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| min-height: 34px; | ||
| padding: 0 10px; | ||
| font-size: 13px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| } | ||
| .rte-doc-schema-select:focus-visible { | ||
| border-color: #0f766e; | ||
| box-shadow: 0 0 0 3px rgba(15, 118, 110, 0.18); | ||
| outline: none; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-select { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #e2e8f0; | ||
| } | ||
| .rte-doc-schema-description, | ||
| .rte-doc-schema-summary, | ||
| .rte-doc-schema-helper, | ||
| .rte-doc-schema-shortcut { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #475569; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-description, | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-summary, | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-helper, | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-shortcut { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-doc-schema-actions { | ||
| display: grid; | ||
| grid-template-columns: repeat(3, minmax(0, 1fr)); | ||
| gap: 8px; | ||
| } | ||
| .rte-doc-schema-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| min-height: 34px; | ||
| padding: 0 8px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| cursor: pointer; | ||
| } | ||
| .rte-doc-schema-btn:disabled { | ||
| opacity: 0.6; | ||
| cursor: not-allowed; | ||
| } | ||
| .rte-doc-schema-btn-primary { | ||
| border-color: #0f766e; | ||
| background: #0f766e; | ||
| color: #f8fafc; | ||
| } | ||
| .rte-doc-schema-btn:hover, | ||
| .rte-doc-schema-btn:focus-visible { | ||
| border-color: #94a3b8; | ||
| outline: none; | ||
| } | ||
| .rte-doc-schema-btn-primary:hover, | ||
| .rte-doc-schema-btn-primary:focus-visible { | ||
| border-color: #115e59; | ||
| background: #115e59; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-btn { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-btn-primary { | ||
| border-color: #14b8a6; | ||
| background: #0f766e; | ||
| color: #f0fdfa; | ||
| } | ||
| .rte-doc-schema-issues-wrap { | ||
| border: 1px solid #e2e8f0; | ||
| border-radius: 10px; | ||
| padding: 6px; | ||
| background: #f8fafc; | ||
| max-height: min(40vh, 320px); | ||
| overflow: auto; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-issues-wrap { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| } | ||
| .rte-doc-schema-issues { | ||
| margin: 0; | ||
| padding: 0; | ||
| list-style: none; | ||
| display: grid; | ||
| gap: 6px; | ||
| } | ||
| .rte-doc-schema-issue { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| background: #ffffff; | ||
| padding: 8px; | ||
| display: grid; | ||
| gap: 4px; | ||
| } | ||
| .rte-doc-schema-issue.error { | ||
| border-color: #ef4444; | ||
| background: #fef2f2; | ||
| } | ||
| .rte-doc-schema-issue.warning { | ||
| border-color: #f59e0b; | ||
| background: #fffbeb; | ||
| } | ||
| .rte-doc-schema-issue.info { | ||
| border-color: #0ea5e9; | ||
| background: #f0f9ff; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-issue { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-issue.error { | ||
| border-color: rgba(239, 68, 68, 0.7); | ||
| background: rgba(127, 29, 29, 0.28); | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-issue.warning { | ||
| border-color: rgba(245, 158, 11, 0.72); | ||
| background: rgba(120, 53, 15, 0.28); | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-issue.info { | ||
| border-color: rgba(14, 165, 233, 0.7); | ||
| background: rgba(7, 89, 133, 0.28); | ||
| } | ||
| .rte-doc-schema-issue-message, | ||
| .rte-doc-schema-issue-suggestion { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #1f2937; | ||
| } | ||
| .rte-doc-schema-issue-suggestion { | ||
| color: #475569; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-issue-message { | ||
| color: #e2e8f0; | ||
| } | ||
| .${m}.rte-doc-schema-theme-dark .rte-doc-schema-issue-suggestion { | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-doc-schema-empty { | ||
| margin: 8px; | ||
| font-size: 12px; | ||
| color: #64748b; | ||
| } | ||
| .rte-doc-schema-live { | ||
| position: absolute; | ||
| width: 1px; | ||
| height: 1px; | ||
| margin: -1px; | ||
| padding: 0; | ||
| overflow: hidden; | ||
| clip: rect(0 0 0 0); | ||
| border: 0; | ||
| } | ||
| @media (max-width: 768px) { | ||
| .${m} { | ||
| left: 10px !important; | ||
| right: 10px; | ||
| top: 10px !important; | ||
| width: auto !important; | ||
| max-height: calc(100vh - 20px); | ||
| } | ||
| .rte-doc-schema-actions { | ||
| grid-template-columns: 1fr; | ||
| } | ||
| } | ||
| `, document.head.appendChild(e); | ||
| } | ||
| const Qe = (e = {}) => { | ||
| const t = Z(e), n = /* @__PURE__ */ new Set(); | ||
| return Ze(), { | ||
| name: "docSchema", | ||
| toolbar: [ | ||
| { | ||
| id: "docSchemaGroup", | ||
| label: "Document Schema", | ||
| type: "group", | ||
| command: "docSchema", | ||
| items: [ | ||
| { | ||
| id: "toggleDocSchemaPanel", | ||
| label: "Document Schema", | ||
| command: "toggleDocSchemaPanel", | ||
| shortcut: "Mod-Alt-Shift-g", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M6 4.5h12A1.5 1.5 0 0 1 19.5 6v12A1.5 1.5 0 0 1 18 19.5H6A1.5 1.5 0 0 1 4.5 18V6A1.5 1.5 0 0 1 6 4.5Z" stroke="currentColor" stroke-width="1.6"/><path d="M8 8h8M8 12h8M8 16h5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>' | ||
| }, | ||
| { | ||
| id: "runDocSchemaValidation", | ||
| label: "Run Schema Validation", | ||
| command: "runDocSchemaValidation", | ||
| shortcut: "Mod-Alt-Shift-j", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M12 3.5 4.5 6.5v5c0 4.8 3.1 8.9 7.5 10 4.4-1.1 7.5-5.2 7.5-10v-5L12 3.5Z" stroke="currentColor" stroke-width="1.6"/><path d="m9 12.5 2 2 4-4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>' | ||
| }, | ||
| { | ||
| id: "toggleDocSchemaRealtime", | ||
| label: "Toggle Schema Realtime", | ||
| command: "toggleDocSchemaRealtime", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M4.5 12a7.5 7.5 0 1 1 7.5 7.5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><path d="M9.5 19.5H5.5v-4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/><circle cx="12" cy="12" r="2" fill="currentColor"/></svg>' | ||
| } | ||
| ] | ||
| } | ||
| ], | ||
| commands: { | ||
| docSchema: (r, s) => { | ||
| const o = I(s, !1, !1); | ||
| if (!o) return !1; | ||
| const a = u.get(o) || t; | ||
| return g(o, a), u.set(o, a), p = o, ae(o), !0; | ||
| }, | ||
| openDocSchemaPanel: (r, s) => { | ||
| const o = I(s, !1, !1); | ||
| if (!o) return !1; | ||
| const a = u.get(o) || t; | ||
| return g(o, a), u.set(o, a), p = o, ae(o), !0; | ||
| }, | ||
| toggleDocSchemaPanel: (r, s) => { | ||
| const o = I(s, !1, !1); | ||
| if (!o) return !1; | ||
| const a = u.get(o) || t; | ||
| return g(o, a), u.set(o, a), p = o, ke(o, typeof r == "boolean" ? r : void 0); | ||
| }, | ||
| runDocSchemaValidation: (r, s) => { | ||
| const o = I(s, !1, !1); | ||
| if (!o) return !1; | ||
| const a = u.get(o) || t; | ||
| return g(o, a), u.set(o, a), p = o, C(o, "command", !0), !0; | ||
| }, | ||
| insertMissingDocSchemaSections: (r, s) => { | ||
| const o = I(s, !1, !1); | ||
| if (!o) return !1; | ||
| const a = u.get(o) || t; | ||
| return g(o, a), u.set(o, a), p = o, Te(o); | ||
| }, | ||
| toggleDocSchemaRealtime: (r, s) => { | ||
| const o = I(s, !1, !1); | ||
| if (!o) return !1; | ||
| const a = u.get(o) || t; | ||
| return g(o, a), u.set(o, a), p = o, Ce(o, typeof r == "boolean" ? r : void 0); | ||
| }, | ||
| setDocSchemaMode: (r, s) => { | ||
| const o = I(s, !1, !1); | ||
| if (!o) return !1; | ||
| const a = u.get(o) || t, c = g(o, a); | ||
| u.set(o, a); | ||
| const i = typeof r == "string" ? r : r?.schemaId || r?.id; | ||
| return !i || !L(a, i) ? !1 : (c.activeSchemaId = i, c.snapshot = "", C(o, "set-mode", !0), !0); | ||
| }, | ||
| setDocSchemaOptions: (r, s) => { | ||
| const o = I(s, !1, !1); | ||
| if (!o || !r || typeof r != "object") return !1; | ||
| const a = u.get(o) || t, c = X.get(o) || He(a), i = { | ||
| ...c, | ||
| ...r, | ||
| labels: { | ||
| ...c.labels || {}, | ||
| ...r.labels || {} | ||
| }, | ||
| schemas: Array.isArray(r.schemas) ? r.schemas : c.schemas, | ||
| normalizeText: r.normalizeText || a.normalizeText | ||
| }, l = Z(i); | ||
| u.set(o, l), X.set(o, i); | ||
| const d = g(o, l); | ||
| return typeof r.enableRealtime == "boolean" && (d.realtimeEnabled = r.enableRealtime), (!d.activeSchemaId || !L(l, d.activeSchemaId)) && (d.activeSchemaId = re(l)), typeof r.defaultSchemaId == "string" && L(l, r.defaultSchemaId) && (d.activeSchemaId = r.defaultSchemaId), d.snapshot = "", C(o, "set-options", !0), _(o), D(o), !0; | ||
| }, | ||
| getDocSchemaState: (r, s) => { | ||
| const o = I(s, !1, !1); | ||
| if (!o) return !1; | ||
| const a = u.get(o) || t; | ||
| g(o, a); | ||
| const c = we(o); | ||
| if (typeof r == "function") | ||
| try { | ||
| r(c); | ||
| } catch { | ||
| } | ||
| return o.__docSchemaState = c, o.dispatchEvent( | ||
| new CustomEvent("editora:doc-schema-state", { | ||
| bubbles: !0, | ||
| detail: c | ||
| }) | ||
| ), !0; | ||
| } | ||
| }, | ||
| keymap: { | ||
| "Mod-Alt-Shift-g": "toggleDocSchemaPanel", | ||
| "Mod-Alt-Shift-G": "toggleDocSchemaPanel", | ||
| "Mod-Alt-Shift-j": "runDocSchemaValidation", | ||
| "Mod-Alt-Shift-J": "runDocSchemaValidation" | ||
| }, | ||
| init: function(s) { | ||
| W += 1; | ||
| const o = this && typeof this.__pluginConfig == "object" ? { ...e, ...this.__pluginConfig } : e, a = Z(o); | ||
| Je(a); | ||
| const c = I( | ||
| s?.editorElement ? { editorElement: s.editorElement } : void 0, | ||
| !1, | ||
| !1 | ||
| ); | ||
| c && (p = c, n.add(c), g(c, a), u.set(c, a), X.set(c, o), D(c), C(c, "init", !0)); | ||
| }, | ||
| destroy: () => { | ||
| n.forEach((r) => ue(r)), n.clear(), W = Math.max(0, W - 1), !(W > 0) && Xe(); | ||
| } | ||
| }; | ||
| }; | ||
| export { | ||
| Qe as DocSchemaPlugin | ||
| }; |
| "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const a=require("./mentions.cjs.js"),t=require("./track-changes.cjs.js"),o=require("./version-diff.cjs.js"),l=require("./conditional-content.cjs.js"),r=require("./data-binding.cjs.js"),g=require("./content-rules.cjs.js"),u=require("./citations.cjs.js"),s=require("./approval-workflow.cjs.js"),c=require("./pii-redaction.cjs.js"),P=require("./smart-paste.cjs.js"),m=require("./blocks-library.cjs.js"),C=require("./doc-schema.cjs.js"),d=require("./translation-workflow.cjs.js"),p=require("./slash-commands.cjs.js"),M=require("./spell-check.cjs.js"),T=require("./a11y-checker.cjs.js"),f=require("./comments.cjs.js"),q=require("./merge-tag.cjs.js"),e=require("./template.cjs.js"),n=require("./media-manager.cjs.js"),i=require("./index-tqLTHcO6.js");exports.MentionPlugin=a.MentionPlugin;exports.TrackChangesPlugin=t.TrackChangesPlugin;exports.VersionDiffPlugin=o.VersionDiffPlugin;exports.ConditionalContentPlugin=l.ConditionalContentPlugin;exports.DataBindingPlugin=r.DataBindingPlugin;exports.ContentRulesPlugin=g.ContentRulesPlugin;exports.CitationsPlugin=u.CitationsPlugin;exports.ApprovalWorkflowPlugin=s.ApprovalWorkflowPlugin;exports.PIIRedactionPlugin=c.PIIRedactionPlugin;exports.SmartPastePlugin=P.SmartPastePlugin;exports.BlocksLibraryPlugin=m.BlocksLibraryPlugin;exports.DocSchemaPlugin=C.DocSchemaPlugin;exports.TranslationWorkflowPlugin=d.TranslationWorkflowPlugin;exports.SlashCommandsPlugin=p.SlashCommandsPlugin;exports.SpellCheckPlugin=M.SpellCheckPlugin;exports.A11yCheckerPlugin=T.A11yCheckerPlugin;exports.CommentsPlugin=f.CommentsPlugin;exports.MergeTagPlugin=q.MergeTagPlugin;exports.PREDEFINED_TEMPLATES=e.PREDEFINED_TEMPLATES;exports.TemplatePlugin=e.TemplatePlugin;exports.addCustomTemplate=e.addCustomTemplate;exports.getAllTemplates=e.getAllTemplates;exports.getTemplateCategories=e.getTemplateCategories;exports.getTemplatesByCategory=e.getTemplatesByCategory;exports.sanitizeTemplate=e.sanitizeTemplate;exports.searchTemplates=e.searchTemplates;exports.validateTemplate=e.validateTemplate;exports.MediaManagerPlugin=n.MediaManagerPlugin;exports.getMediaManagerConfig=n.getMediaManagerConfig;exports.setMediaManagerConfig=n.setMediaManagerConfig;exports.DocumentManagerPlugin=i.DocumentManagerPlugin;exports.getDocumentManagerConfig=i.getDocumentManagerConfig;exports.setDocumentManagerConfig=i.setDocumentManagerConfig; |
| import { MentionPlugin as r } from "./mentions.esm.js"; | ||
| import { TrackChangesPlugin as n } from "./track-changes.esm.js"; | ||
| import { VersionDiffPlugin as i } from "./version-diff.esm.js"; | ||
| import { ConditionalContentPlugin as l } from "./conditional-content.esm.js"; | ||
| import { DataBindingPlugin as p } from "./data-binding.esm.js"; | ||
| import { ContentRulesPlugin as u } from "./content-rules.esm.js"; | ||
| import { CitationsPlugin as s } from "./citations.esm.js"; | ||
| import { ApprovalWorkflowPlugin as C } from "./approval-workflow.esm.js"; | ||
| import { PIIRedactionPlugin as M } from "./pii-redaction.esm.js"; | ||
| import { SmartPastePlugin as d } from "./smart-paste.esm.js"; | ||
| import { BlocksLibraryPlugin as h } from "./blocks-library.esm.js"; | ||
| import { DocSchemaPlugin as E } from "./doc-schema.esm.js"; | ||
| import { TranslationWorkflowPlugin as y } from "./translation-workflow.esm.js"; | ||
| import { SlashCommandsPlugin as B } from "./slash-commands.esm.js"; | ||
| import { SpellCheckPlugin as R } from "./spell-check.esm.js"; | ||
| import { A11yCheckerPlugin as w } from "./a11y-checker.esm.js"; | ||
| import { CommentsPlugin as W } from "./comments.esm.js"; | ||
| import { MergeTagPlugin as z } from "./merge-tag.esm.js"; | ||
| import { PREDEFINED_TEMPLATES as N, TemplatePlugin as V, addCustomTemplate as _, getAllTemplates as j, getTemplateCategories as q, getTemplatesByCategory as G, sanitizeTemplate as H, searchTemplates as J, validateTemplate as K } from "./template.esm.js"; | ||
| import { MediaManagerPlugin as Q, getMediaManagerConfig as U, setMediaManagerConfig as X } from "./media-manager.esm.js"; | ||
| import { D as Z, g as $, s as ee } from "./index-BFsKNTTj.mjs"; | ||
| export { | ||
| w as A11yCheckerPlugin, | ||
| C as ApprovalWorkflowPlugin, | ||
| h as BlocksLibraryPlugin, | ||
| s as CitationsPlugin, | ||
| W as CommentsPlugin, | ||
| l as ConditionalContentPlugin, | ||
| u as ContentRulesPlugin, | ||
| p as DataBindingPlugin, | ||
| E as DocSchemaPlugin, | ||
| Z as DocumentManagerPlugin, | ||
| Q as MediaManagerPlugin, | ||
| r as MentionPlugin, | ||
| z as MergeTagPlugin, | ||
| M as PIIRedactionPlugin, | ||
| N as PREDEFINED_TEMPLATES, | ||
| B as SlashCommandsPlugin, | ||
| d as SmartPastePlugin, | ||
| R as SpellCheckPlugin, | ||
| V as TemplatePlugin, | ||
| n as TrackChangesPlugin, | ||
| y as TranslationWorkflowPlugin, | ||
| i as VersionDiffPlugin, | ||
| _ as addCustomTemplate, | ||
| j as getAllTemplates, | ||
| $ as getDocumentManagerConfig, | ||
| U as getMediaManagerConfig, | ||
| q as getTemplateCategories, | ||
| G as getTemplatesByCategory, | ||
| H as sanitizeTemplate, | ||
| J as searchTemplates, | ||
| ee as setDocumentManagerConfig, | ||
| X as setMediaManagerConfig, | ||
| K as validateTemplate | ||
| }; |
| "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const g=".rte-content, .editora-content",Y="[data-editora-editor], .rte-editor, .editora-editor, editora-editor",w='.rte-mention[data-mention="true"]',b=':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)',L=new WeakMap,R=new WeakMap;let q=!1,N=!1,T=null,v=0;function Q(e,n){if(n===e.innerHTML)return;const o=window.execEditorCommand||window.executeEditorCommand;if(typeof o=="function")try{o("recordDomTransaction",e,n,e.innerHTML)}catch{}}function U(e){e.dispatchEvent(new Event("input",{bubbles:!0}))}function h(e,n){const o=window.getSelection();o&&(o.removeAllRanges(),o.addRange(n),e.focus({preventScroll:!0}))}function S(e,n){return e.startContainer===n.startContainer&&e.startOffset===n.startOffset&&e.endContainer===n.endContainer&&e.endOffset===n.endOffset}function E(e){const n=window.getSelection();if(!n||n.rangeCount===0)return null;const o=n.getRangeAt(0);return e.contains(o.commonAncestorContainer)?o.cloneRange():null}function C(e){Array.from(e.querySelectorAll(w)).forEach(o=>{o.setAttribute("data-mention","true"),o.setAttribute("contenteditable","false"),o.setAttribute("spellcheck","false"),o.setAttribute("draggable","false"),o.classList.add("rte-mention")})}function _(e){return e?e.nodeType===Node.ELEMENT_NODE?e:e.parentElement:null}function ee(e){return e.closest(Y)||e}function M(e){return e?(e.getAttribute("data-theme")||e.getAttribute("theme")||"").toLowerCase()==="dark"?!0:e.classList.contains("dark")||e.classList.contains("editora-theme-dark")||e.classList.contains("rte-theme-dark"):!1}function ne(e){const n=ee(e);if(M(n))return!0;const o=n.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark");return M(o)?!0:M(document.documentElement)||M(document.body)}function W(e,n){e.classList.remove("rte-mention-theme-dark"),ne(n)&&e.classList.add("rte-mention-theme-dark")}function te(e){if(e?.contentElement instanceof HTMLElement)return e.contentElement;if(e?.editorElement instanceof HTMLElement){const t=e.editorElement;if(t.matches(g))return t;const r=t.querySelector(g);if(r instanceof HTMLElement)return r}const n=window.getSelection();if(n&&n.rangeCount>0){const t=n.getRangeAt(0).startContainer,i=(t.nodeType===Node.ELEMENT_NODE?t:t.parentElement)?.closest(g);if(i)return i}const o=document.activeElement;if(o){if(o.matches(g))return o;const t=o.closest(g);if(t)return t}return document.querySelector(g)}function x(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function D(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function re(e,n){return n?n.split(".").filter(Boolean).reduce((o,t)=>{if(!(!D(o)&&!Array.isArray(o)))return o[t]},e):e}function oe(e){return e?/\s|[([{"'`]/.test(e):!0}function ie(e){if(!e.collapsed)return null;const n=e.startContainer,o=e.startOffset;if(n.nodeType===Node.TEXT_NODE){const t=n;return{node:t,textBefore:t.data.slice(0,o),caretOffset:o}}if(n.nodeType===Node.ELEMENT_NODE){const t=n;if(o>0){const r=t.childNodes[o-1];if(r&&r.nodeType===Node.TEXT_NODE){const i=r;return{node:i,textBefore:i.data,caretOffset:i.length}}}}return null}function ae(e,n,o){let t=-1,r="";if(n.forEach(a=>{const l=e.lastIndexOf(a);l>t&&(t=l,r=a)}),t<0||!oe(e[t-1]))return null;const i=e.slice(t+1);return/\s/.test(i)||i.length>o?null:{trigger:r,query:i,startOffset:t}}function le(e,n){const o=n.cloneRange();o.collapse(!1);const t=o.getClientRects();if(t.length>0)return t[t.length-1];const r=document.createElement("span");r.textContent="",r.style.position="relative",o.insertNode(r);const i=r.getBoundingClientRect();return r.remove(),e.normalize(),i}function se(e,n){if(e.panel&&e.list)return;const o=document.createElement("div");o.className="rte-mention-panel",o.style.display="none";const t=document.createElement("div");t.className="rte-mention-list",o.appendChild(t),document.body.appendChild(o),W(o,e.editor),e.panel=o,e.list=t,o.addEventListener("mousedown",r=>{r.preventDefault()}),o.addEventListener("click",r=>{const i=r.target;if(!i)return;const a=i.closest(".rte-mention-item");if(!a)return;const l=Number(a.getAttribute("data-index"));Number.isFinite(l)&&K(e,n,l)})}function m(e){e.panel&&(e.debounceHandle!==null&&(window.clearTimeout(e.debounceHandle),e.debounceHandle=null),e.abortController&&(e.abortController.abort(),e.abortController=null),e.panel.style.display="none",e.panel.classList.remove("show"),e.isOpen=!1,e.loading=!1,e.items=[],e.activeIndex=0,e.query="",e.replaceRange=null)}function $(e,n){if(!e.panel)return;W(e.panel,e.editor);const o=le(e.editor,n),t=e.panel;t.style.display="block",t.classList.add("show"),t.style.left="0px",t.style.top="0px";const r=t.getBoundingClientRect(),i=window.innerWidth,a=window.innerHeight;let l=Math.max(8,Math.min(o.left,i-r.width-8)),s=o.bottom+8;s+r.height>a-8&&(s=Math.max(8,o.top-r.height-8)),t.style.position="fixed",t.style.left=`${l}px`,t.style.top=`${s}px`}function ce(e,n){if(!n)return x(e);const o=e.toLowerCase(),t=n.toLowerCase(),r=o.indexOf(t);if(r<0)return x(e);const i=x(e.slice(0,r)),a=x(e.slice(r,r+n.length)),l=x(e.slice(r+n.length));return`${i}<mark>${a}</mark>${l}`}function B(e,n){if(!e.list)return;const o=e.list;if(o.innerHTML="",e.loading){const t=document.createElement("div");t.className="rte-mention-empty",t.textContent=n.loadingText,o.appendChild(t);return}if(e.items.length===0){const t=document.createElement("div");t.className="rte-mention-empty",t.textContent=e.query.length>0?n.noResultsText:n.emptyStateText,o.appendChild(t);return}e.items.forEach((t,r)=>{const i=document.createElement("button");i.type="button",i.className="rte-mention-item",r===e.activeIndex&&i.classList.add("active"),i.setAttribute("data-index",String(r));const a=n.itemRenderer?n.itemRenderer(t,e.query):`<span class="rte-mention-item-label">${ce(t.label,e.query)}</span>${t.meta?`<span class="rte-mention-item-meta">${x(t.meta)}</span>`:""}`;i.innerHTML=a,o.appendChild(i)})}function G(e,n){const o=new Set,t=[];return e.forEach(r=>{const i=(r.id||"").trim();!i||o.has(i)||(o.add(i),t.push({id:i,label:r.label||i,value:r.value,meta:r.meta}))}),t.slice(0,n)}function ue(e,n){if(e.buildRequest){const c=e.buildRequest(n);return{url:c.url,init:c.init||{}}}const o=(e.method||"GET").toUpperCase(),t=typeof e.headers=="function"?e.headers(n):e.headers||{},r=e.queryParam||"q",i=e.triggerParam||"trigger",a=e.limitParam||"limit",l=e.staticParams||{},s={method:o,headers:{...t},credentials:e.credentials,mode:e.mode,cache:e.cache,signal:n.signal},f=new URL(e.url,window.location.origin);if(o==="GET"||o==="HEAD"){const c=new URLSearchParams(f.search);Object.entries(l).forEach(([d,p])=>c.set(d,String(p))),c.set(r,n.query),c.set(i,n.trigger),c.set(a,String(n.limit)),f.search=c.toString()}else{const c=typeof e.body=="function"?e.body(n):e.body,d={[r]:n.query,[i]:n.trigger,[a]:n.limit,...l},p=c??d;if(D(p)){s.body=JSON.stringify(p);const y=s.headers;!y["Content-Type"]&&!y["content-type"]&&(y["Content-Type"]="application/json")}else s.body=p}return{url:f.toString(),init:s}}async function de(e,n,o,t){const r=n.api;if(!r)return[];e.abortController&&e.abortController.abort();const i=new AbortController;e.abortController=i;const a={query:o,trigger:t,limit:n.maxSuggestions,signal:i.signal},l=Math.max(0,r.timeoutMs??1e4);let s=null;l>0&&(s=window.setTimeout(()=>i.abort(),l));try{const{url:f,init:c}=ue(r,a),d=await fetch(f,{...c,signal:i.signal});if(!d.ok)throw new Error(`Mention API request failed: ${d.status}`);const y=(r.responseType||"json")==="text"?await d.text():await d.json();let O=[];if(r.transformResponse)O=r.transformResponse(y,a)||[];else{const P=re(y,r.responsePath);O=(Array.isArray(P)?P:Array.isArray(y)?y:[]).map((u,J)=>{if(r.mapItem)return r.mapItem(u,J);if(!D(u))return null;const I=String(u.id??u.value??u.key??"").trim();if(!I)return null;const Z=String(u.label??u.name??I).trim();return{id:I,label:Z,value:u.value?String(u.value):void 0,meta:u.meta?String(u.meta):void 0}}).filter(u=>!!u)}return G(O,n.maxSuggestions)}catch(f){return f?.name!=="AbortError"&&r.onError?.(f,a),[]}finally{s!==null&&window.clearTimeout(s),e.abortController===i&&(e.abortController=null)}}async function fe(e,n,o,t){const r=++e.requestId;let i=[];if(n.search){const a=await n.search(o,t);i=Array.isArray(a)?a:[]}else if(n.api)i=await de(e,n,o,t);else{const a=o.toLowerCase();i=n.items.filter(l=>a?l.label.toLowerCase().includes(a)||l.id.toLowerCase().includes(a):!0)}return r!==e.requestId?[]:G(i,n.maxSuggestions)}function me(e,n,o){const t=e.editor;if(C(t),!window.getSelection())return!1;const i=t.innerHTML;let a=e.replaceRange?e.replaceRange.cloneRange():E(t);if(!a||!t.contains(a.commonAncestorContainer)&&(a=E(t),!a))return!1;const l=A(t,a.cloneRange(),"after");S(l,a)||(h(t,l),a=l),a.deleteContents();const s=document.createElement("span");s.className="rte-mention",s.setAttribute("data-mention","true"),s.setAttribute("data-mention-id",o.id),s.setAttribute("contenteditable","false"),s.textContent=o.value||`${e.trigger}${o.label}`,a.insertNode(s);let f=s,c=1;if(n.insertSpaceAfterMention){const p=document.createTextNode(" ");s.after(p),f=p,c=1}const d=document.createRange();return d.setStart(f,c),d.collapse(!0),h(t,d),m(e),C(t),U(t),Q(t,i),!0}function K(e,n,o){if(o<0||o>=e.items.length)return;const t=e.items[o];me(e,n,t)}function pe(e){return e.startContainer!==e.endContainer||e.startContainer.nodeType!==Node.ELEMENT_NODE||e.endOffset-e.startOffset!==1?null:e.startContainer.childNodes[e.startOffset]||null}function ge(e,n){const o=pe(e);return!(o instanceof HTMLElement)||!o.matches(w)||!n.contains(o)?null:o}function V(e,n){const o=ge(e,n);if(o)return o;const r=_(e.startContainer)?.closest(w);if(r&&n.contains(r))return r;const a=_(e.endContainer)?.closest(w);return a&&n.contains(a)?a:null}function A(e,n,o="after"){const t=V(n,e);if(!t)return n;const r=document.createRange();return o==="before"?r.setStartBefore(t):r.setStartAfter(t),r.collapse(!0),r}function j(e,n,o="after"){const t=document.createRange();o==="before"?t.setStartBefore(n):t.setStartAfter(n),t.collapse(!0),h(e,t)}function he(e,n,o){if(!e.collapsed)return null;const t=e.startContainer,r=e.startOffset;let i=null;if(t.nodeType===Node.TEXT_NODE){const a=t;n==="backward"&&r===0?i=a.previousSibling:n==="forward"&&r===a.length&&(i=a.nextSibling)}else if(t.nodeType===Node.ELEMENT_NODE){const a=t;n==="backward"&&r>0?i=a.childNodes[r-1]||null:n==="forward"&&r<a.childNodes.length&&(i=a.childNodes[r]||null)}return!(i instanceof HTMLElement)||!i.matches(w)||!o.contains(i)?null:i}function z(e,n){const o=E(e);if(!o)return!1;const t=he(o,n,e);if(!t)return!1;const r=t.parentNode;if(!r)return!1;const i=e.innerHTML,a=Array.prototype.indexOf.call(r.childNodes,t);t.remove();const l=document.createRange();return l.setStart(r,Math.max(0,a)),l.collapse(!0),h(e,l),U(e),Q(e,i),!0}function X(e,n,o,t,r,i){if(se(e,n),e.query=t,e.trigger=r,e.replaceRange=i.cloneRange(),e.loading=!!(n.api&&!n.search),e.debounceHandle!==null&&(window.clearTimeout(e.debounceHandle),e.debounceHandle=null),!e.panel)return;e.isOpen||(e.panel.style.display="block",e.panel.classList.add("show"),e.isOpen=!0),B(e,n),$(e,o);const a=()=>{e.debounceHandle=null,fe(e,n,t,r).then(s=>{e.loading=!1,e.items=s,e.activeIndex=0,e.panel&&(B(e,n),$(e,o))})},l=n.api&&!n.search?Math.max(0,n.api.debounceMs??180):0;l>0?e.debounceHandle=window.setTimeout(a,l):a()}function ye(e,n){const o=e.editor;C(o);let t=E(o);if(!t||!t.collapsed){m(e);return}const r=A(o,t.cloneRange(),"after");if(!S(r,t)){h(o,r),t=r,m(e);return}const i=ie(t);if(!i){m(e);return}const a=ae(i.textBefore,n.triggerChars,n.maxQueryLength);if(!a){m(e);return}if(a.query.length<n.minChars){m(e);return}const l=t.cloneRange();l.setStart(i.node,a.startOffset),l.setEnd(i.node,i.caretOffset),X(e,n,t,a.query,a.trigger,l)}function F(e,n){if(e.items.length===0)return;const o=e.items.length;if(e.activeIndex=((e.activeIndex+n)%o+o)%o,!e.list)return;const t=Array.from(e.list.querySelectorAll(".rte-mention-item"));t.forEach((i,a)=>i.classList.toggle("active",a===e.activeIndex)),t[e.activeIndex]?.scrollIntoView({block:"nearest"})}function be(e){return{editor:e,panel:null,list:null,replaceRange:null,items:[],activeIndex:0,query:"",trigger:"@",loading:!1,isOpen:!1,requestId:0,debounceHandle:null,abortController:null}}function Ee(e){const n=L.get(e);n&&(n.panel?.parentNode&&n.panel.parentNode.removeChild(n.panel),L.delete(e))}function H(e,n,o){if(R.has(e))return;C(e);const t={beforeInput:r=>{C(e);const i=E(e);if(!i)return;const a=V(i,e);if(!a)return;const l=r.inputType||"";if(l.startsWith("insert")){if(r.preventDefault(),j(e,a,"after"),l==="insertParagraph"||l==="insertLineBreak"){const s=l==="insertLineBreak"?"insertLineBreak":"insertParagraph";document.execCommand(s,!1);return}if(l==="insertText"||l==="insertCompositionText"){const s=r.data||"";if(!s)return;document.execCommand("insertText",!1,s)}}},input:()=>{ye(n,o)},keydown:r=>{if(n.isOpen){if(r.key==="ArrowDown"){r.preventDefault(),F(n,1);return}if(r.key==="ArrowUp"){r.preventDefault(),F(n,-1);return}if(r.key==="Enter"||r.key==="Tab"){r.preventDefault(),K(n,o,n.activeIndex);return}if(r.key==="Escape"){r.preventDefault(),m(n);return}}const i=E(e);if(i){const a=A(e,i.cloneRange(),"after");if(!S(a,i)){if(r.key==="Enter"){r.preventDefault(),h(e,a),document.execCommand("insertParagraph",!1);return}r.key.length===1&&!r.metaKey&&!r.ctrlKey&&!r.altKey&&h(e,a)}}if(r.key==="Backspace"&&z(e,"backward")){r.preventDefault();return}if(r.key==="Delete"&&z(e,"forward")){r.preventDefault();return}},click:r=>{const i=r.target;if(!i)return;const l=(i.nodeType===Node.ELEMENT_NODE?i:i.parentElement)?.closest(w);!l||!e.contains(l)||(r.preventDefault(),r.stopPropagation(),j(e,l,"after"),m(n))},blur:()=>{window.setTimeout(()=>{const r=document.activeElement;n.panel&&r&&n.panel.contains(r)||m(n)},0)},mousedown:r=>{if(!n.isOpen||!n.panel)return;const i=r.target;i&&!n.panel.contains(i)&&!e.contains(i)&&m(n)}};e.addEventListener("beforeinput",t.beforeInput),e.addEventListener("input",t.input),e.addEventListener("keydown",t.keydown),e.addEventListener("click",t.click),e.addEventListener("blur",t.blur),document.addEventListener("mousedown",t.mousedown,!0),R.set(e,t)}function xe(e){const n=R.get(e);n&&(e.removeEventListener("beforeinput",n.beforeInput),e.removeEventListener("input",n.input),e.removeEventListener("keydown",n.keydown),e.removeEventListener("click",n.click),e.removeEventListener("blur",n.blur),document.removeEventListener("mousedown",n.mousedown,!0),R.delete(e))}function we(){if(q||typeof document>"u")return;q=!0;const e=document.createElement("style");e.id="rte-mention-plugin-styles",e.textContent=` | ||
| .rte-mention { | ||
| display: inline-block; | ||
| padding: 0 6px; | ||
| margin: 0 1px; | ||
| border-radius: 10px; | ||
| background: #e8f0ff; | ||
| color: #1d4ed8; | ||
| font-weight: 600; | ||
| line-height: 1.6; | ||
| white-space: nowrap; | ||
| cursor: pointer; | ||
| } | ||
| .rte-mention-panel { | ||
| width: min(320px, calc(100vw - 16px)); | ||
| max-height: min(320px, calc(100vh - 32px)); | ||
| overflow: hidden; | ||
| border: 1px solid #d9dfeb; | ||
| border-radius: 3px; | ||
| background: #ffffff; | ||
| box-shadow: 0 18px 40px rgba(15, 23, 42, 0.2); | ||
| z-index: 2147483646; | ||
| } | ||
| .rte-mention-list { | ||
| max-height: min(300px, calc(100vh - 56px)); | ||
| overflow: auto; | ||
| padding: 0px; | ||
| } | ||
| .rte-mention-item { | ||
| width: 100%; | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 12px; | ||
| border: none; | ||
| background: transparent; | ||
| padding: 10px 12px; | ||
| border-radius: 0px; | ||
| color: #0f172a; | ||
| text-align: left; | ||
| cursor: pointer; | ||
| font: inherit; | ||
| } | ||
| .rte-mention-item:hover, | ||
| .rte-mention-item.active { | ||
| background: #eff6ff; | ||
| color: #1d4ed8; | ||
| } | ||
| .rte-mention-item-label mark { | ||
| background: rgba(59, 130, 246, 0.16); | ||
| color: inherit; | ||
| padding: 0 2px; | ||
| border-radius: 3px; | ||
| } | ||
| .rte-mention-item-meta { | ||
| font-size: 12px; | ||
| color: #64748b; | ||
| white-space: nowrap; | ||
| } | ||
| .rte-mention-empty { | ||
| padding: 12px; | ||
| color: #64748b; | ||
| font-size: 13px; | ||
| text-align: center; | ||
| } | ||
| ${b} .rte-mention { | ||
| background: rgba(37, 99, 235, 0.25); | ||
| color: #bfdbfe; | ||
| } | ||
| ${b} .rte-mention-panel, | ||
| .rte-mention-panel.rte-mention-theme-dark { | ||
| border-color: #364152; | ||
| background: #1f2937; | ||
| box-shadow: 0 22px 44px rgba(0, 0, 0, 0.48); | ||
| } | ||
| ${b} .rte-mention-item, | ||
| .rte-mention-panel.rte-mention-theme-dark .rte-mention-item { | ||
| color: #e5e7eb; | ||
| } | ||
| ${b} .rte-mention-item:hover, | ||
| ${b} .rte-mention-item.active, | ||
| .rte-mention-panel.rte-mention-theme-dark .rte-mention-item:hover, | ||
| .rte-mention-panel.rte-mention-theme-dark .rte-mention-item.active { | ||
| background: #334155; | ||
| color: #bfdbfe; | ||
| } | ||
| ${b} .rte-mention-item-meta, | ||
| ${b} .rte-mention-empty, | ||
| .rte-mention-panel.rte-mention-theme-dark .rte-mention-item-meta, | ||
| .rte-mention-panel.rte-mention-theme-dark .rte-mention-empty { | ||
| color: #9ca3af; | ||
| } | ||
| `,document.head.appendChild(e)}function Te(e){const n=(e.triggerChars||["@"]).filter(o=>typeof o=="string"&&o.length>0).map(o=>o[0]);return{triggerChars:n.length>0?n:["@"],minChars:Math.max(0,e.minChars??1),maxQueryLength:Math.max(1,e.maxQueryLength??32),maxSuggestions:Math.max(1,e.maxSuggestions??8),items:e.items||[{id:"john.doe",label:"John Doe",meta:"john@acme.com"},{id:"sarah.lee",label:"Sarah Lee",meta:"sarah@acme.com"},{id:"alex.chen",label:"Alex Chen",meta:"alex@acme.com"}],api:e.api,search:e.search,itemRenderer:e.itemRenderer,emptyStateText:e.emptyStateText||"Type to search mentions",noResultsText:e.noResultsText||"No matching mentions",loadingText:e.loadingText||"Loading...",insertSpaceAfterMention:e.insertSpaceAfterMention!==!1}}function k(e){const n=L.get(e);if(n)return n;const o=be(e);return L.set(e,o),o}function Ce(e){N||(N=!0,T=n=>{const o=n.target;if(!(o instanceof Node))return;const r=(o.nodeType===Node.ELEMENT_NODE?o:o.parentElement)?.closest(g)||null;if(!r)return;const i=k(r);H(r,i,e)},document.addEventListener("focusin",T,!0))}function ve(){!N||!T||(document.removeEventListener("focusin",T,!0),N=!1,T=null)}const Me=(e={})=>{we();const n=Te(e);return{name:"mentions",toolbar:[{label:"Mention",command:"insertMention",icon:'<svg width="24" height="24" focusable="false"><path d="M12.1 4a7.9 7.9 0 0 0-8 8c0 4.4 3.6 8 8 8 1.6 0 3-.4 4.4-1.3.4-.3.5-.9.2-1.3a1 1 0 0 0-1.3-.3 6 6 0 0 1-3.3.9 6 6 0 1 1 6-6v1.6c0 .8-.5 1.4-1.2 1.4-.8 0-1.2-.6-1.2-1.4V12c0-2-1.6-3.5-3.7-3.5s-3.8 1.6-3.8 3.6c0 2 1.7 3.6 3.8 3.6 1 0 1.9-.4 2.6-1 .5 1 1.4 1.6 2.5 1.6 1.8 0 3.2-1.5 3.2-3.4V12A7.9 7.9 0 0 0 12 4Zm0 9.7c-1 0-1.8-.8-1.8-1.7s.8-1.7 1.8-1.7c1 0 1.7.8 1.7 1.7s-.8 1.7-1.7 1.7Z"></path></svg>'}],commands:{insertMention:(o,t)=>{const r=te(t);if(!r)return!1;const i=k(r);H(r,i,n);let a=E(r);a||(a=document.createRange(),a.selectNodeContents(r),a.collapse(!1),h(r,a));const l=A(r,a.cloneRange(),"after");S(l,a)||(h(r,l),a=l),i.query="";const s=a.cloneRange();return i.trigger=n.triggerChars[0],X(i,n,a,"",i.trigger,s),!0}},init:()=>{v+=1,Ce(n),Array.from(document.querySelectorAll(g)).forEach(t=>{const r=k(t);H(t,r,n)})},destroy:()=>{v=Math.max(0,v-1),Array.from(document.querySelectorAll(g)).forEach(t=>{m(k(t)),xe(t),Ee(t)}),v===0&&ve()}}};exports.MentionPlugin=Me; |
| const g = ".rte-content, .editora-content", Y = "[data-editora-editor], .rte-editor, .editora-editor, editora-editor", w = '.rte-mention[data-mention="true"]', b = ':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)', M = /* @__PURE__ */ new WeakMap(), R = /* @__PURE__ */ new WeakMap(); | ||
| let P = !1, N = !1, T = null, v = 0; | ||
| function Q(e, n) { | ||
| if (n === e.innerHTML) return; | ||
| const o = window.execEditorCommand || window.executeEditorCommand; | ||
| if (typeof o == "function") | ||
| try { | ||
| o("recordDomTransaction", e, n, e.innerHTML); | ||
| } catch { | ||
| } | ||
| } | ||
| function U(e) { | ||
| e.dispatchEvent(new Event("input", { bubbles: !0 })); | ||
| } | ||
| function h(e, n) { | ||
| const o = window.getSelection(); | ||
| o && (o.removeAllRanges(), o.addRange(n), e.focus({ preventScroll: !0 })); | ||
| } | ||
| function S(e, n) { | ||
| return e.startContainer === n.startContainer && e.startOffset === n.startOffset && e.endContainer === n.endContainer && e.endOffset === n.endOffset; | ||
| } | ||
| function E(e) { | ||
| const n = window.getSelection(); | ||
| if (!n || n.rangeCount === 0) return null; | ||
| const o = n.getRangeAt(0); | ||
| return e.contains(o.commonAncestorContainer) ? o.cloneRange() : null; | ||
| } | ||
| function C(e) { | ||
| Array.from(e.querySelectorAll(w)).forEach((o) => { | ||
| o.setAttribute("data-mention", "true"), o.setAttribute("contenteditable", "false"), o.setAttribute("spellcheck", "false"), o.setAttribute("draggable", "false"), o.classList.add("rte-mention"); | ||
| }); | ||
| } | ||
| function _(e) { | ||
| return e ? e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement : null; | ||
| } | ||
| function ee(e) { | ||
| return e.closest(Y) || e; | ||
| } | ||
| function k(e) { | ||
| return e ? (e.getAttribute("data-theme") || e.getAttribute("theme") || "").toLowerCase() === "dark" ? !0 : e.classList.contains("dark") || e.classList.contains("editora-theme-dark") || e.classList.contains("rte-theme-dark") : !1; | ||
| } | ||
| function ne(e) { | ||
| const n = ee(e); | ||
| if (k(n)) return !0; | ||
| const o = n.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark"); | ||
| return k(o) ? !0 : k(document.documentElement) || k(document.body); | ||
| } | ||
| function W(e, n) { | ||
| e.classList.remove("rte-mention-theme-dark"), ne(n) && e.classList.add("rte-mention-theme-dark"); | ||
| } | ||
| function te(e) { | ||
| if (e?.contentElement instanceof HTMLElement) return e.contentElement; | ||
| if (e?.editorElement instanceof HTMLElement) { | ||
| const t = e.editorElement; | ||
| if (t.matches(g)) return t; | ||
| const r = t.querySelector(g); | ||
| if (r instanceof HTMLElement) return r; | ||
| } | ||
| const n = window.getSelection(); | ||
| if (n && n.rangeCount > 0) { | ||
| const t = n.getRangeAt(0).startContainer, i = (t.nodeType === Node.ELEMENT_NODE ? t : t.parentElement)?.closest(g); | ||
| if (i) return i; | ||
| } | ||
| const o = document.activeElement; | ||
| if (o) { | ||
| if (o.matches(g)) return o; | ||
| const t = o.closest(g); | ||
| if (t) return t; | ||
| } | ||
| return document.querySelector(g); | ||
| } | ||
| function x(e) { | ||
| return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); | ||
| } | ||
| function D(e) { | ||
| return typeof e == "object" && e !== null && !Array.isArray(e); | ||
| } | ||
| function re(e, n) { | ||
| return n ? n.split(".").filter(Boolean).reduce((o, t) => { | ||
| if (!(!D(o) && !Array.isArray(o))) | ||
| return o[t]; | ||
| }, e) : e; | ||
| } | ||
| function oe(e) { | ||
| return e ? /\s|[([{"'`]/.test(e) : !0; | ||
| } | ||
| function ie(e) { | ||
| if (!e.collapsed) return null; | ||
| const n = e.startContainer, o = e.startOffset; | ||
| if (n.nodeType === Node.TEXT_NODE) { | ||
| const t = n; | ||
| return { | ||
| node: t, | ||
| textBefore: t.data.slice(0, o), | ||
| caretOffset: o | ||
| }; | ||
| } | ||
| if (n.nodeType === Node.ELEMENT_NODE) { | ||
| const t = n; | ||
| if (o > 0) { | ||
| const r = t.childNodes[o - 1]; | ||
| if (r && r.nodeType === Node.TEXT_NODE) { | ||
| const i = r; | ||
| return { | ||
| node: i, | ||
| textBefore: i.data, | ||
| caretOffset: i.length | ||
| }; | ||
| } | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| function ae(e, n, o) { | ||
| let t = -1, r = ""; | ||
| if (n.forEach((a) => { | ||
| const l = e.lastIndexOf(a); | ||
| l > t && (t = l, r = a); | ||
| }), t < 0 || !oe(e[t - 1])) return null; | ||
| const i = e.slice(t + 1); | ||
| return /\s/.test(i) || i.length > o ? null : { | ||
| trigger: r, | ||
| query: i, | ||
| startOffset: t | ||
| }; | ||
| } | ||
| function le(e, n) { | ||
| const o = n.cloneRange(); | ||
| o.collapse(!1); | ||
| const t = o.getClientRects(); | ||
| if (t.length > 0) | ||
| return t[t.length - 1]; | ||
| const r = document.createElement("span"); | ||
| r.textContent = "", r.style.position = "relative", o.insertNode(r); | ||
| const i = r.getBoundingClientRect(); | ||
| return r.remove(), e.normalize(), i; | ||
| } | ||
| function se(e, n) { | ||
| if (e.panel && e.list) return; | ||
| const o = document.createElement("div"); | ||
| o.className = "rte-mention-panel", o.style.display = "none"; | ||
| const t = document.createElement("div"); | ||
| t.className = "rte-mention-list", o.appendChild(t), document.body.appendChild(o), W(o, e.editor), e.panel = o, e.list = t, o.addEventListener("mousedown", (r) => { | ||
| r.preventDefault(); | ||
| }), o.addEventListener("click", (r) => { | ||
| const i = r.target; | ||
| if (!i) return; | ||
| const a = i.closest(".rte-mention-item"); | ||
| if (!a) return; | ||
| const l = Number(a.getAttribute("data-index")); | ||
| Number.isFinite(l) && K(e, n, l); | ||
| }); | ||
| } | ||
| function m(e) { | ||
| e.panel && (e.debounceHandle !== null && (window.clearTimeout(e.debounceHandle), e.debounceHandle = null), e.abortController && (e.abortController.abort(), e.abortController = null), e.panel.style.display = "none", e.panel.classList.remove("show"), e.isOpen = !1, e.loading = !1, e.items = [], e.activeIndex = 0, e.query = "", e.replaceRange = null); | ||
| } | ||
| function $(e, n) { | ||
| if (!e.panel) return; | ||
| W(e.panel, e.editor); | ||
| const o = le(e.editor, n), t = e.panel; | ||
| t.style.display = "block", t.classList.add("show"), t.style.left = "0px", t.style.top = "0px"; | ||
| const r = t.getBoundingClientRect(), i = window.innerWidth, a = window.innerHeight; | ||
| let l = Math.max(8, Math.min(o.left, i - r.width - 8)), s = o.bottom + 8; | ||
| s + r.height > a - 8 && (s = Math.max(8, o.top - r.height - 8)), t.style.position = "fixed", t.style.left = `${l}px`, t.style.top = `${s}px`; | ||
| } | ||
| function ce(e, n) { | ||
| if (!n) return x(e); | ||
| const o = e.toLowerCase(), t = n.toLowerCase(), r = o.indexOf(t); | ||
| if (r < 0) return x(e); | ||
| const i = x(e.slice(0, r)), a = x(e.slice(r, r + n.length)), l = x(e.slice(r + n.length)); | ||
| return `${i}<mark>${a}</mark>${l}`; | ||
| } | ||
| function B(e, n) { | ||
| if (!e.list) return; | ||
| const o = e.list; | ||
| if (o.innerHTML = "", e.loading) { | ||
| const t = document.createElement("div"); | ||
| t.className = "rte-mention-empty", t.textContent = n.loadingText, o.appendChild(t); | ||
| return; | ||
| } | ||
| if (e.items.length === 0) { | ||
| const t = document.createElement("div"); | ||
| t.className = "rte-mention-empty", t.textContent = e.query.length > 0 ? n.noResultsText : n.emptyStateText, o.appendChild(t); | ||
| return; | ||
| } | ||
| e.items.forEach((t, r) => { | ||
| const i = document.createElement("button"); | ||
| i.type = "button", i.className = "rte-mention-item", r === e.activeIndex && i.classList.add("active"), i.setAttribute("data-index", String(r)); | ||
| const a = n.itemRenderer ? n.itemRenderer(t, e.query) : `<span class="rte-mention-item-label">${ce(t.label, e.query)}</span>${t.meta ? `<span class="rte-mention-item-meta">${x(t.meta)}</span>` : ""}`; | ||
| i.innerHTML = a, o.appendChild(i); | ||
| }); | ||
| } | ||
| function G(e, n) { | ||
| const o = /* @__PURE__ */ new Set(), t = []; | ||
| return e.forEach((r) => { | ||
| const i = (r.id || "").trim(); | ||
| !i || o.has(i) || (o.add(i), t.push({ | ||
| id: i, | ||
| label: r.label || i, | ||
| value: r.value, | ||
| meta: r.meta | ||
| })); | ||
| }), t.slice(0, n); | ||
| } | ||
| function ue(e, n) { | ||
| if (e.buildRequest) { | ||
| const c = e.buildRequest(n); | ||
| return { | ||
| url: c.url, | ||
| init: c.init || {} | ||
| }; | ||
| } | ||
| const o = (e.method || "GET").toUpperCase(), t = typeof e.headers == "function" ? e.headers(n) : e.headers || {}, r = e.queryParam || "q", i = e.triggerParam || "trigger", a = e.limitParam || "limit", l = e.staticParams || {}, s = { | ||
| method: o, | ||
| headers: { ...t }, | ||
| credentials: e.credentials, | ||
| mode: e.mode, | ||
| cache: e.cache, | ||
| signal: n.signal | ||
| }, f = new URL(e.url, window.location.origin); | ||
| if (o === "GET" || o === "HEAD") { | ||
| const c = new URLSearchParams(f.search); | ||
| Object.entries(l).forEach(([d, p]) => c.set(d, String(p))), c.set(r, n.query), c.set(i, n.trigger), c.set(a, String(n.limit)), f.search = c.toString(); | ||
| } else { | ||
| const c = typeof e.body == "function" ? e.body(n) : e.body, d = { | ||
| [r]: n.query, | ||
| [i]: n.trigger, | ||
| [a]: n.limit, | ||
| ...l | ||
| }, p = c ?? d; | ||
| if (D(p)) { | ||
| s.body = JSON.stringify(p); | ||
| const y = s.headers; | ||
| !y["Content-Type"] && !y["content-type"] && (y["Content-Type"] = "application/json"); | ||
| } else | ||
| s.body = p; | ||
| } | ||
| return { url: f.toString(), init: s }; | ||
| } | ||
| async function de(e, n, o, t) { | ||
| const r = n.api; | ||
| if (!r) return []; | ||
| e.abortController && e.abortController.abort(); | ||
| const i = new AbortController(); | ||
| e.abortController = i; | ||
| const a = { | ||
| query: o, | ||
| trigger: t, | ||
| limit: n.maxSuggestions, | ||
| signal: i.signal | ||
| }, l = Math.max(0, r.timeoutMs ?? 1e4); | ||
| let s = null; | ||
| l > 0 && (s = window.setTimeout(() => i.abort(), l)); | ||
| try { | ||
| const { url: f, init: c } = ue(r, a), d = await fetch(f, { | ||
| ...c, | ||
| signal: i.signal | ||
| }); | ||
| if (!d.ok) | ||
| throw new Error(`Mention API request failed: ${d.status}`); | ||
| const y = (r.responseType || "json") === "text" ? await d.text() : await d.json(); | ||
| let O = []; | ||
| if (r.transformResponse) | ||
| O = r.transformResponse(y, a) || []; | ||
| else { | ||
| const q = re(y, r.responsePath); | ||
| O = (Array.isArray(q) ? q : Array.isArray(y) ? y : []).map((u, J) => { | ||
| if (r.mapItem) | ||
| return r.mapItem(u, J); | ||
| if (!D(u)) return null; | ||
| const I = String(u.id ?? u.value ?? u.key ?? "").trim(); | ||
| if (!I) return null; | ||
| const Z = String(u.label ?? u.name ?? I).trim(); | ||
| return { | ||
| id: I, | ||
| label: Z, | ||
| value: u.value ? String(u.value) : void 0, | ||
| meta: u.meta ? String(u.meta) : void 0 | ||
| }; | ||
| }).filter((u) => !!u); | ||
| } | ||
| return G(O, n.maxSuggestions); | ||
| } catch (f) { | ||
| return f?.name !== "AbortError" && r.onError?.(f, a), []; | ||
| } finally { | ||
| s !== null && window.clearTimeout(s), e.abortController === i && (e.abortController = null); | ||
| } | ||
| } | ||
| async function fe(e, n, o, t) { | ||
| const r = ++e.requestId; | ||
| let i = []; | ||
| if (n.search) { | ||
| const a = await n.search(o, t); | ||
| i = Array.isArray(a) ? a : []; | ||
| } else if (n.api) | ||
| i = await de(e, n, o, t); | ||
| else { | ||
| const a = o.toLowerCase(); | ||
| i = n.items.filter((l) => a ? l.label.toLowerCase().includes(a) || l.id.toLowerCase().includes(a) : !0); | ||
| } | ||
| return r !== e.requestId ? [] : G(i, n.maxSuggestions); | ||
| } | ||
| function me(e, n, o) { | ||
| const t = e.editor; | ||
| if (C(t), !window.getSelection()) return !1; | ||
| const i = t.innerHTML; | ||
| let a = e.replaceRange ? e.replaceRange.cloneRange() : E(t); | ||
| if (!a || !t.contains(a.commonAncestorContainer) && (a = E(t), !a)) | ||
| return !1; | ||
| const l = A(t, a.cloneRange(), "after"); | ||
| S(l, a) || (h(t, l), a = l), a.deleteContents(); | ||
| const s = document.createElement("span"); | ||
| s.className = "rte-mention", s.setAttribute("data-mention", "true"), s.setAttribute("data-mention-id", o.id), s.setAttribute("contenteditable", "false"), s.textContent = o.value || `${e.trigger}${o.label}`, a.insertNode(s); | ||
| let f = s, c = 1; | ||
| if (n.insertSpaceAfterMention) { | ||
| const p = document.createTextNode(" "); | ||
| s.after(p), f = p, c = 1; | ||
| } | ||
| const d = document.createRange(); | ||
| return d.setStart(f, c), d.collapse(!0), h(t, d), m(e), C(t), U(t), Q(t, i), !0; | ||
| } | ||
| function K(e, n, o) { | ||
| if (o < 0 || o >= e.items.length) return; | ||
| const t = e.items[o]; | ||
| me(e, n, t); | ||
| } | ||
| function pe(e) { | ||
| return e.startContainer !== e.endContainer || e.startContainer.nodeType !== Node.ELEMENT_NODE || e.endOffset - e.startOffset !== 1 ? null : e.startContainer.childNodes[e.startOffset] || null; | ||
| } | ||
| function ge(e, n) { | ||
| const o = pe(e); | ||
| return !(o instanceof HTMLElement) || !o.matches(w) || !n.contains(o) ? null : o; | ||
| } | ||
| function V(e, n) { | ||
| const o = ge(e, n); | ||
| if (o) return o; | ||
| const r = _(e.startContainer)?.closest(w); | ||
| if (r && n.contains(r)) return r; | ||
| const a = _(e.endContainer)?.closest(w); | ||
| return a && n.contains(a) ? a : null; | ||
| } | ||
| function A(e, n, o = "after") { | ||
| const t = V(n, e); | ||
| if (!t) return n; | ||
| const r = document.createRange(); | ||
| return o === "before" ? r.setStartBefore(t) : r.setStartAfter(t), r.collapse(!0), r; | ||
| } | ||
| function j(e, n, o = "after") { | ||
| const t = document.createRange(); | ||
| o === "before" ? t.setStartBefore(n) : t.setStartAfter(n), t.collapse(!0), h(e, t); | ||
| } | ||
| function he(e, n, o) { | ||
| if (!e.collapsed) return null; | ||
| const t = e.startContainer, r = e.startOffset; | ||
| let i = null; | ||
| if (t.nodeType === Node.TEXT_NODE) { | ||
| const a = t; | ||
| n === "backward" && r === 0 ? i = a.previousSibling : n === "forward" && r === a.length && (i = a.nextSibling); | ||
| } else if (t.nodeType === Node.ELEMENT_NODE) { | ||
| const a = t; | ||
| n === "backward" && r > 0 ? i = a.childNodes[r - 1] || null : n === "forward" && r < a.childNodes.length && (i = a.childNodes[r] || null); | ||
| } | ||
| return !(i instanceof HTMLElement) || !i.matches(w) || !o.contains(i) ? null : i; | ||
| } | ||
| function z(e, n) { | ||
| const o = E(e); | ||
| if (!o) return !1; | ||
| const t = he(o, n, e); | ||
| if (!t) return !1; | ||
| const r = t.parentNode; | ||
| if (!r) return !1; | ||
| const i = e.innerHTML, a = Array.prototype.indexOf.call(r.childNodes, t); | ||
| t.remove(); | ||
| const l = document.createRange(); | ||
| return l.setStart(r, Math.max(0, a)), l.collapse(!0), h(e, l), U(e), Q(e, i), !0; | ||
| } | ||
| function X(e, n, o, t, r, i) { | ||
| if (se(e, n), e.query = t, e.trigger = r, e.replaceRange = i.cloneRange(), e.loading = !!(n.api && !n.search), e.debounceHandle !== null && (window.clearTimeout(e.debounceHandle), e.debounceHandle = null), !e.panel) return; | ||
| e.isOpen || (e.panel.style.display = "block", e.panel.classList.add("show"), e.isOpen = !0), B(e, n), $(e, o); | ||
| const a = () => { | ||
| e.debounceHandle = null, fe(e, n, t, r).then((s) => { | ||
| e.loading = !1, e.items = s, e.activeIndex = 0, e.panel && (B(e, n), $(e, o)); | ||
| }); | ||
| }, l = n.api && !n.search ? Math.max(0, n.api.debounceMs ?? 180) : 0; | ||
| l > 0 ? e.debounceHandle = window.setTimeout(a, l) : a(); | ||
| } | ||
| function ye(e, n) { | ||
| const o = e.editor; | ||
| C(o); | ||
| let t = E(o); | ||
| if (!t || !t.collapsed) { | ||
| m(e); | ||
| return; | ||
| } | ||
| const r = A(o, t.cloneRange(), "after"); | ||
| if (!S(r, t)) { | ||
| h(o, r), t = r, m(e); | ||
| return; | ||
| } | ||
| const i = ie(t); | ||
| if (!i) { | ||
| m(e); | ||
| return; | ||
| } | ||
| const a = ae(i.textBefore, n.triggerChars, n.maxQueryLength); | ||
| if (!a) { | ||
| m(e); | ||
| return; | ||
| } | ||
| if (a.query.length < n.minChars) { | ||
| m(e); | ||
| return; | ||
| } | ||
| const l = t.cloneRange(); | ||
| l.setStart(i.node, a.startOffset), l.setEnd(i.node, i.caretOffset), X(e, n, t, a.query, a.trigger, l); | ||
| } | ||
| function F(e, n) { | ||
| if (e.items.length === 0) return; | ||
| const o = e.items.length; | ||
| if (e.activeIndex = ((e.activeIndex + n) % o + o) % o, !e.list) return; | ||
| const t = Array.from(e.list.querySelectorAll(".rte-mention-item")); | ||
| t.forEach((i, a) => i.classList.toggle("active", a === e.activeIndex)), t[e.activeIndex]?.scrollIntoView({ block: "nearest" }); | ||
| } | ||
| function be(e) { | ||
| return { | ||
| editor: e, | ||
| panel: null, | ||
| list: null, | ||
| replaceRange: null, | ||
| items: [], | ||
| activeIndex: 0, | ||
| query: "", | ||
| trigger: "@", | ||
| loading: !1, | ||
| isOpen: !1, | ||
| requestId: 0, | ||
| debounceHandle: null, | ||
| abortController: null | ||
| }; | ||
| } | ||
| function Ee(e) { | ||
| const n = M.get(e); | ||
| n && (n.panel?.parentNode && n.panel.parentNode.removeChild(n.panel), M.delete(e)); | ||
| } | ||
| function H(e, n, o) { | ||
| if (R.has(e)) return; | ||
| C(e); | ||
| const t = { | ||
| beforeInput: (r) => { | ||
| C(e); | ||
| const i = E(e); | ||
| if (!i) return; | ||
| const a = V(i, e); | ||
| if (!a) return; | ||
| const l = r.inputType || ""; | ||
| if (l.startsWith("insert")) { | ||
| if (r.preventDefault(), j(e, a, "after"), l === "insertParagraph" || l === "insertLineBreak") { | ||
| const s = l === "insertLineBreak" ? "insertLineBreak" : "insertParagraph"; | ||
| document.execCommand(s, !1); | ||
| return; | ||
| } | ||
| if (l === "insertText" || l === "insertCompositionText") { | ||
| const s = r.data || ""; | ||
| if (!s) return; | ||
| document.execCommand("insertText", !1, s); | ||
| } | ||
| } | ||
| }, | ||
| input: () => { | ||
| ye(n, o); | ||
| }, | ||
| keydown: (r) => { | ||
| if (n.isOpen) { | ||
| if (r.key === "ArrowDown") { | ||
| r.preventDefault(), F(n, 1); | ||
| return; | ||
| } | ||
| if (r.key === "ArrowUp") { | ||
| r.preventDefault(), F(n, -1); | ||
| return; | ||
| } | ||
| if (r.key === "Enter" || r.key === "Tab") { | ||
| r.preventDefault(), K(n, o, n.activeIndex); | ||
| return; | ||
| } | ||
| if (r.key === "Escape") { | ||
| r.preventDefault(), m(n); | ||
| return; | ||
| } | ||
| } | ||
| const i = E(e); | ||
| if (i) { | ||
| const a = A(e, i.cloneRange(), "after"); | ||
| if (!S(a, i)) { | ||
| if (r.key === "Enter") { | ||
| r.preventDefault(), h(e, a), document.execCommand("insertParagraph", !1); | ||
| return; | ||
| } | ||
| r.key.length === 1 && !r.metaKey && !r.ctrlKey && !r.altKey && h(e, a); | ||
| } | ||
| } | ||
| if (r.key === "Backspace" && z(e, "backward")) { | ||
| r.preventDefault(); | ||
| return; | ||
| } | ||
| if (r.key === "Delete" && z(e, "forward")) { | ||
| r.preventDefault(); | ||
| return; | ||
| } | ||
| }, | ||
| click: (r) => { | ||
| const i = r.target; | ||
| if (!i) return; | ||
| const l = (i.nodeType === Node.ELEMENT_NODE ? i : i.parentElement)?.closest(w); | ||
| !l || !e.contains(l) || (r.preventDefault(), r.stopPropagation(), j(e, l, "after"), m(n)); | ||
| }, | ||
| blur: () => { | ||
| window.setTimeout(() => { | ||
| const r = document.activeElement; | ||
| n.panel && r && n.panel.contains(r) || m(n); | ||
| }, 0); | ||
| }, | ||
| mousedown: (r) => { | ||
| if (!n.isOpen || !n.panel) return; | ||
| const i = r.target; | ||
| i && !n.panel.contains(i) && !e.contains(i) && m(n); | ||
| } | ||
| }; | ||
| e.addEventListener("beforeinput", t.beforeInput), e.addEventListener("input", t.input), e.addEventListener("keydown", t.keydown), e.addEventListener("click", t.click), e.addEventListener("blur", t.blur), document.addEventListener("mousedown", t.mousedown, !0), R.set(e, t); | ||
| } | ||
| function xe(e) { | ||
| const n = R.get(e); | ||
| n && (e.removeEventListener("beforeinput", n.beforeInput), e.removeEventListener("input", n.input), e.removeEventListener("keydown", n.keydown), e.removeEventListener("click", n.click), e.removeEventListener("blur", n.blur), document.removeEventListener("mousedown", n.mousedown, !0), R.delete(e)); | ||
| } | ||
| function we() { | ||
| if (P || typeof document > "u") return; | ||
| P = !0; | ||
| const e = document.createElement("style"); | ||
| e.id = "rte-mention-plugin-styles", e.textContent = ` | ||
| .rte-mention { | ||
| display: inline-block; | ||
| padding: 0 6px; | ||
| margin: 0 1px; | ||
| border-radius: 10px; | ||
| background: #e8f0ff; | ||
| color: #1d4ed8; | ||
| font-weight: 600; | ||
| line-height: 1.6; | ||
| white-space: nowrap; | ||
| cursor: pointer; | ||
| } | ||
| .rte-mention-panel { | ||
| width: min(320px, calc(100vw - 16px)); | ||
| max-height: min(320px, calc(100vh - 32px)); | ||
| overflow: hidden; | ||
| border: 1px solid #d9dfeb; | ||
| border-radius: 3px; | ||
| background: #ffffff; | ||
| box-shadow: 0 18px 40px rgba(15, 23, 42, 0.2); | ||
| z-index: 2147483646; | ||
| } | ||
| .rte-mention-list { | ||
| max-height: min(300px, calc(100vh - 56px)); | ||
| overflow: auto; | ||
| padding: 0px; | ||
| } | ||
| .rte-mention-item { | ||
| width: 100%; | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 12px; | ||
| border: none; | ||
| background: transparent; | ||
| padding: 10px 12px; | ||
| border-radius: 0px; | ||
| color: #0f172a; | ||
| text-align: left; | ||
| cursor: pointer; | ||
| font: inherit; | ||
| } | ||
| .rte-mention-item:hover, | ||
| .rte-mention-item.active { | ||
| background: #eff6ff; | ||
| color: #1d4ed8; | ||
| } | ||
| .rte-mention-item-label mark { | ||
| background: rgba(59, 130, 246, 0.16); | ||
| color: inherit; | ||
| padding: 0 2px; | ||
| border-radius: 3px; | ||
| } | ||
| .rte-mention-item-meta { | ||
| font-size: 12px; | ||
| color: #64748b; | ||
| white-space: nowrap; | ||
| } | ||
| .rte-mention-empty { | ||
| padding: 12px; | ||
| color: #64748b; | ||
| font-size: 13px; | ||
| text-align: center; | ||
| } | ||
| ${b} .rte-mention { | ||
| background: rgba(37, 99, 235, 0.25); | ||
| color: #bfdbfe; | ||
| } | ||
| ${b} .rte-mention-panel, | ||
| .rte-mention-panel.rte-mention-theme-dark { | ||
| border-color: #364152; | ||
| background: #1f2937; | ||
| box-shadow: 0 22px 44px rgba(0, 0, 0, 0.48); | ||
| } | ||
| ${b} .rte-mention-item, | ||
| .rte-mention-panel.rte-mention-theme-dark .rte-mention-item { | ||
| color: #e5e7eb; | ||
| } | ||
| ${b} .rte-mention-item:hover, | ||
| ${b} .rte-mention-item.active, | ||
| .rte-mention-panel.rte-mention-theme-dark .rte-mention-item:hover, | ||
| .rte-mention-panel.rte-mention-theme-dark .rte-mention-item.active { | ||
| background: #334155; | ||
| color: #bfdbfe; | ||
| } | ||
| ${b} .rte-mention-item-meta, | ||
| ${b} .rte-mention-empty, | ||
| .rte-mention-panel.rte-mention-theme-dark .rte-mention-item-meta, | ||
| .rte-mention-panel.rte-mention-theme-dark .rte-mention-empty { | ||
| color: #9ca3af; | ||
| } | ||
| `, document.head.appendChild(e); | ||
| } | ||
| function Te(e) { | ||
| const n = (e.triggerChars || ["@"]).filter((o) => typeof o == "string" && o.length > 0).map((o) => o[0]); | ||
| return { | ||
| triggerChars: n.length > 0 ? n : ["@"], | ||
| minChars: Math.max(0, e.minChars ?? 1), | ||
| maxQueryLength: Math.max(1, e.maxQueryLength ?? 32), | ||
| maxSuggestions: Math.max(1, e.maxSuggestions ?? 8), | ||
| items: e.items || [ | ||
| { id: "john.doe", label: "John Doe", meta: "john@acme.com" }, | ||
| { id: "sarah.lee", label: "Sarah Lee", meta: "sarah@acme.com" }, | ||
| { id: "alex.chen", label: "Alex Chen", meta: "alex@acme.com" } | ||
| ], | ||
| api: e.api, | ||
| search: e.search, | ||
| itemRenderer: e.itemRenderer, | ||
| emptyStateText: e.emptyStateText || "Type to search mentions", | ||
| noResultsText: e.noResultsText || "No matching mentions", | ||
| loadingText: e.loadingText || "Loading...", | ||
| insertSpaceAfterMention: e.insertSpaceAfterMention !== !1 | ||
| }; | ||
| } | ||
| function L(e) { | ||
| const n = M.get(e); | ||
| if (n) return n; | ||
| const o = be(e); | ||
| return M.set(e, o), o; | ||
| } | ||
| function Ce(e) { | ||
| N || (N = !0, T = (n) => { | ||
| const o = n.target; | ||
| if (!(o instanceof Node)) return; | ||
| const r = (o.nodeType === Node.ELEMENT_NODE ? o : o.parentElement)?.closest(g) || null; | ||
| if (!r) return; | ||
| const i = L(r); | ||
| H(r, i, e); | ||
| }, document.addEventListener("focusin", T, !0)); | ||
| } | ||
| function ve() { | ||
| !N || !T || (document.removeEventListener("focusin", T, !0), N = !1, T = null); | ||
| } | ||
| const Le = (e = {}) => { | ||
| we(); | ||
| const n = Te(e); | ||
| return { | ||
| name: "mentions", | ||
| toolbar: [ | ||
| { | ||
| label: "Mention", | ||
| command: "insertMention", | ||
| icon: '<svg width="24" height="24" focusable="false"><path d="M12.1 4a7.9 7.9 0 0 0-8 8c0 4.4 3.6 8 8 8 1.6 0 3-.4 4.4-1.3.4-.3.5-.9.2-1.3a1 1 0 0 0-1.3-.3 6 6 0 0 1-3.3.9 6 6 0 1 1 6-6v1.6c0 .8-.5 1.4-1.2 1.4-.8 0-1.2-.6-1.2-1.4V12c0-2-1.6-3.5-3.7-3.5s-3.8 1.6-3.8 3.6c0 2 1.7 3.6 3.8 3.6 1 0 1.9-.4 2.6-1 .5 1 1.4 1.6 2.5 1.6 1.8 0 3.2-1.5 3.2-3.4V12A7.9 7.9 0 0 0 12 4Zm0 9.7c-1 0-1.8-.8-1.8-1.7s.8-1.7 1.8-1.7c1 0 1.7.8 1.7 1.7s-.8 1.7-1.7 1.7Z"></path></svg>' | ||
| } | ||
| ], | ||
| commands: { | ||
| insertMention: (o, t) => { | ||
| const r = te(t); | ||
| if (!r) return !1; | ||
| const i = L(r); | ||
| H(r, i, n); | ||
| let a = E(r); | ||
| a || (a = document.createRange(), a.selectNodeContents(r), a.collapse(!1), h(r, a)); | ||
| const l = A(r, a.cloneRange(), "after"); | ||
| S(l, a) || (h(r, l), a = l), i.query = ""; | ||
| const s = a.cloneRange(); | ||
| return i.trigger = n.triggerChars[0], X(i, n, a, "", i.trigger, s), !0; | ||
| } | ||
| }, | ||
| init: () => { | ||
| v += 1, Ce(n), Array.from(document.querySelectorAll(g)).forEach((t) => { | ||
| const r = L(t); | ||
| H(t, r, n); | ||
| }); | ||
| }, | ||
| destroy: () => { | ||
| v = Math.max(0, v - 1), Array.from(document.querySelectorAll(g)).forEach((t) => { | ||
| m(L(t)), xe(t), Ee(t); | ||
| }), v === 0 && ve(); | ||
| } | ||
| }; | ||
| }; | ||
| export { | ||
| Le as MentionPlugin | ||
| }; |
| "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const x=".rte-content, .editora-content",ae="[data-editora-editor], .rte-editor, .editora-editor, editora-editor",ke="__editoraCommandEditorRoot",we="rte-pii-redaction-styles",u="rte-pii-redaction-panel",k="pii-redaction",v="piiRedaction",$=':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)',pe=typeof NodeFilter<"u"?NodeFilter.SHOW_TEXT:4,Ne=["email","phone","ssn","credit-card","ipv4","api-key","jwt"],Oe={panelTitle:"PII Redaction",panelAriaLabel:"PII redaction panel",scanText:"Scan PII",redactAllText:"Redact All",redactText:"Redact",locateText:"Locate",realtimeOnText:"Realtime On",realtimeOffText:"Realtime Off",closeText:"Close",noFindingsText:"No PII detected in the document.",summaryPrefix:"Findings",shortcutText:"Shortcuts: Ctrl/Cmd+Alt+Shift+I/U/M/Y",readonlyRedactionText:"Editor is read-only. Reopen editable mode to redact.",matchLabel:"Detected",maskedLabel:"Masked",excerptLabel:"Context"},ze={email:{label:"Email",severity:"medium",pattern:/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi},phone:{label:"Phone",severity:"medium",pattern:/\b(?:\+?\d{1,3}[\s.-]?)?(?:\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4})\b/g},ssn:{label:"SSN",severity:"high",pattern:/\b\d{3}-\d{2}-\d{4}\b/g},"credit-card":{label:"Credit Card",severity:"high",pattern:/\b(?:\d[ -]*?){13,19}\b/g,validator:e=>qe(e)},ipv4:{label:"IPv4",severity:"low",pattern:/\b(?:(?:25[0-5]|2[0-4]\d|1?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|1?\d?\d)\b/g},"api-key":{label:"API Key",severity:"high",pattern:/\b(?:sk-[A-Za-z0-9]{20,}|AKIA[0-9A-Z]{16}|AIza[0-9A-Za-z\-_]{35}|ghp_[A-Za-z0-9]{36}|xox[baprs]-[A-Za-z0-9-]{10,})\b/g},jwt:{label:"JWT",severity:"high",pattern:/\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g}},f=new WeakMap,I=new WeakMap,E=new WeakMap,S=new WeakMap,te=new WeakMap,de=new WeakMap,Q=new WeakMap,m=new Map,Z=new WeakMap,q=new Set,W=new Set;let G=0,Fe=0,Ee=0,M=null,b=null,P=null,L=null,_=null,R=null,D=null;function p(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function He(e){return e.replace(/\u00A0/g," ").replace(/\s+/g," ").trim()}function Y(e){const t=e.flags.includes("g")?e.flags:`${e.flags}g`;return new RegExp(e.source,t)}function ge(e){return new RegExp(e.source,e.flags)}function X(e,t,n){return Math.max(t,Math.min(n,e))}function Be(e,t){return e==="high"||e==="medium"||e==="low"?e:t}function Ke(e){const t=(e||"*").slice(0,1)||"*";return/[A-Za-z0-9._%+\-\s]/.test(t)?"*":t}function ve(e){let t=2166136261;for(let n=0;n<e.length;n+=1)t^=e.charCodeAt(n),t=Math.imul(t,16777619);return t>>>0}function qe(e){const t=e.replace(/\D/g,"");if(t.length<13||t.length>19)return!1;let n=0,r=!1;for(let i=t.length-1;i>=0;i-=1){let o=Number(t[i]);r&&(o*=2,o>9&&(o-=9)),n+=o,r=!r}return n%10===0}function We(e,t){const n=ze[e];if(typeof t=="boolean")return{type:e,label:n.label,severity:n.severity,enabled:t,pattern:Y(n.pattern),validator:n.validator};if(!t)return{type:e,label:n.label,severity:n.severity,enabled:!0,pattern:Y(n.pattern),validator:n.validator};const r=t.pattern instanceof RegExp?Y(t.pattern):Y(n.pattern);return{type:e,label:n.label,severity:Be(t.severity,n.severity),enabled:t.enabled!==!1,pattern:r,validator:n.validator}}function ee(e={}){const t=Ne.map(r=>We(r,e.detectors?.[r])),n=t.map(r=>`${r.type}:${r.enabled?"1":"0"}:${r.severity}:${r.pattern.source}:${r.pattern.flags}`).join("|");return{enableRealtime:e.enableRealtime!==!1,debounceMs:X(Number(e.debounceMs??220),60,3e3),maxFindings:X(Number(e.maxFindings??140),1,500),maskChar:Ke(e.maskChar),revealStart:X(Number(e.revealStart??2),0,12),revealEnd:X(Number(e.revealEnd??2),0,12),redactionMode:e.redactionMode==="mask"?"mask":"token",redactionToken:(e.redactionToken||"REDACTED").trim()||"REDACTED",skipInCodeBlocks:e.skipInCodeBlocks!==!1,labels:{...Oe,...e.labels||{}},normalizeText:e.normalizeText||He,detectors:t,detectorSignature:n}}function ce(e){const t={};return e.detectors.forEach(n=>{t[n.type]={enabled:n.enabled,severity:n.severity,pattern:n.pattern}}),{enableRealtime:e.enableRealtime,debounceMs:e.debounceMs,maxFindings:e.maxFindings,maskChar:e.maskChar,revealStart:e.revealStart,revealEnd:e.revealEnd,redactionMode:e.redactionMode,redactionToken:e.redactionToken,skipInCodeBlocks:e.skipInCodeBlocks,labels:{...e.labels},normalizeText:e.normalizeText,detectors:t}}function be(e){return e.closest(ae)||e}function je(e){const t=e.closest("[data-editora-editor]");if(t&&O(t)===e)return t;let n=e;for(;n;){if(n.matches(ae)&&(n===e||O(n)===e))return n;n=n.parentElement}return be(e)}function O(e){if(!e)return null;if(e.matches(x))return e;const t=e.querySelector(x);return t instanceof HTMLElement?t:null}function Ze(){if(typeof window>"u")return null;const e=window[ke];if(!(e instanceof HTMLElement))return null;window[ke]=null;const t=O(e);if(t)return t;const n=e.closest(ae);if(n){const i=O(n);if(i)return i}const r=e.closest(x);return r instanceof HTMLElement?r:null}function J(e){return e?(e.getAttribute("data-theme")||e.getAttribute("theme")||"").toLowerCase()==="dark"?!0:e.classList.contains("dark")||e.classList.contains("editora-theme-dark")||e.classList.contains("rte-theme-dark"):!1}function Ve(e){const t=be(e);if(J(t))return!0;const n=t.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark");return J(n)?!0:J(document.documentElement)||J(document.body)}function ne(e,t){e.classList.remove("rte-pii-redaction-theme-dark"),Ve(t)&&e.classList.add("rte-pii-redaction-theme-dark")}function re(e){return e?e.nodeType===Node.ELEMENT_NODE?e:e.parentElement:null}function me(e){const t=te.get(e);typeof t=="number"&&(window.clearTimeout(t),W.delete(t),te.delete(e))}function V(e){return e.getAttribute("contenteditable")==="false"||e.getAttribute("data-readonly")==="true"}function le(e=0){return{total:0,high:0,medium:0,low:0,redactedCount:e,byType:{email:0,phone:0,ssn:0,"credit-card":0,ipv4:0,"api-key":0,jwt:0}}}function K(){Array.from(q).forEach(t=>{t.isConnected||Ie(t)})}function Ue(e){for(let t=0;t<e.length;t+=1){const n=e[t];if(!(n.type!=="childList"||n.removedNodes.length===0))for(let r=0;r<n.removedNodes.length;r+=1){const i=n.removedNodes[r];if(i.nodeType!==Node.ELEMENT_NODE)continue;const o=i;if(o.matches?.(x)||o.matches?.(`.${u}`)||o.querySelector?.(x)||o.querySelector?.(`.${u}`))return!0}}return!1}function T(e,t=!0){if(K(),e?.contentElement instanceof HTMLElement)return e.contentElement;if(e?.editorElement instanceof HTMLElement){const o=e.editorElement,a=O(o);if(a)return a}const n=Ze();if(n)return n;const r=window.getSelection();if(r&&r.rangeCount>0){const a=re(r.getRangeAt(0).startContainer)?.closest(x);if(a)return a}const i=document.activeElement;if(i){if(i.matches(x))return i;const o=i.closest(x);if(o)return o}return b&&b.isConnected?b:(b&&!b.isConnected&&(b=null),t?document.querySelector(x):null)}function Ie(e){me(e),m.get(e)?.remove(),m.delete(e),Z.delete(e),f.delete(e),I.delete(e),E.delete(e),S.delete(e),de.delete(e),Q.delete(e),q.delete(e),b===e&&(b=null)}function C(e,t,n){const r=je(e);Array.from(r.querySelectorAll(`.rte-toolbar-button[data-command="${t}"], .editora-toolbar-button[data-command="${t}"]`)).forEach(o=>{o.classList.toggle("active",n),o.setAttribute("data-active",n?"true":"false"),o.setAttribute("aria-pressed",n?"true":"false")})}function w(e,t){f.has(e)||f.set(e,t),I.has(e)||I.set(e,[]),E.has(e)||E.set(e,le(0)),S.has(e)||S.set(e,t.enableRealtime),q.add(e)}function oe(e){return Z.get(e)===!0}function $e(e,t,n,r){if(!e)return e;if(e.length<=n+r)return t.repeat(e.length);const i=e.slice(0,n),o=r>0?e.slice(e.length-r):"";return`${i}${t.repeat(Math.max(1,e.length-n-r))}${o}`}function se(e,t,n){const r=e.replace(/\D/g,"");if(r.length===0)return e;let i=0;const o=Math.max(0,r.length-n);return e.split("").map(a=>/\d/.test(a)?(i+=1,i<=o?t:a):a).join("")}function Ge(e,t){const n=e.indexOf("@");if(n<=0)return e;const r=e.slice(0,n),i=e.slice(n+1);return r.length<=2?`${r[0]||""}${t}[at]${i}`:`${r[0]}${t.repeat(Math.max(1,r.length-2))}${r[r.length-1]}[at]${i}`}function Ye(e,t){const n=e.split(".");return n.length!==4?e:`${n[0]}.${n[1]}.${n[2]}.${t.repeat(Math.max(1,n[3].length))}`}function Te(e,t,n){return e&&(t==="email"?Ge(e,n.maskChar):t==="phone"||t==="ssn"||t==="credit-card"?se(e,n.maskChar,4):t==="ipv4"?Ye(e,n.maskChar):t==="api-key"||t==="jwt"?$e(e,n.maskChar,0,0):$e(e,n.maskChar,n.revealStart,n.revealEnd))}function Ce(e,t,n){return n.redactionMode==="mask"?Te(e,t,n):`[${n.redactionToken}:${t.toUpperCase()}]`}function Xe(e){return Ee+=1,`pii-${e}-${Date.now().toString(36)}-${Ee.toString(36)}`}function he(e,t){return t.skipInCodeBlocks?!!e.parentElement?.closest("code, pre, kbd, samp"):!1}function Je(e,t){return t.some(n=>e.start<n.end&&n.start<e.end)}function Qe(e,t,n){const r=[];t.filter(a=>a.enabled).forEach(a=>{const l=ge(a.pattern);let c=l.exec(e);for(;c&&r.length<n*5;){const d=c[0]||"",s=c.index,g=s+d.length;d&&g>s&&(!a.validator||a.validator(d))&&r.push({type:a.type,severity:a.severity,value:d,start:s,end:g}),l.lastIndex===c.index&&(l.lastIndex+=1),c=l.exec(e)}}),r.sort((a,l)=>a.start!==l.start?a.start-l.start:l.end-a.end);const o=[];for(let a=0;a<r.length&&!(o.length>=n);a+=1){const l=r[a];Je({start:l.start,end:l.end},o)||o.push(l)}return o}function ue(e,t=120){return e.length<=t?e:`${e.slice(0,t-1).trimEnd()}...`}function et(e,t,n){const r=Math.max(0,t-28),i=Math.min(e.length,n+28);return ue(e.slice(r,i).trim(),180)}function tt(e,t){const n=le(t);return n.total=e.length,e.forEach(r=>{n.byType[r.type]+=1,r.severity==="high"?n.high+=1:r.severity==="medium"?n.medium+=1:n.low+=1}),n}function ie(e,t){const n=e.querySelector(".rte-pii-redaction-live");n&&(n.textContent=t)}function z(e,t,n){const r=t.querySelector('[data-action="toggle-realtime"]');if(!r)return;const i=F(e,n);r.textContent=i?n.labels.realtimeOnText:n.labels.realtimeOffText,r.setAttribute("aria-pressed",i?"true":"false"),C(e,"togglePIIRealtime",i)}function nt(e,t){e.setAttribute("aria-label",t.labels.panelAriaLabel);const n=e.querySelector(".rte-pii-redaction-title");n&&(n.textContent=t.labels.panelTitle);const r=e.querySelector('[data-action="close"]');r&&r.setAttribute("aria-label",t.labels.closeText);const i=e.querySelector('[data-action="run-scan"]');i&&(i.textContent=t.labels.scanText);const o=e.querySelector('[data-action="redact-all"]');o&&(o.textContent=t.labels.redactAllText);const a=e.querySelector(".rte-pii-redaction-shortcut");a&&(a.textContent=t.labels.shortcutText)}function H(e){const t=m.get(e);if(!t)return;const n=f.get(e)||M;if(!n)return;const r=I.get(e)||[],i=E.get(e)||le(0),o=V(e),a=t.querySelector(".rte-pii-redaction-count"),l=t.querySelector(".rte-pii-redaction-summary"),c=t.querySelector(".rte-pii-redaction-list"),d=t.querySelector('[data-action="redact-all"]');if(!(!a||!l||!c||!d)){if(a.textContent=String(i.total),l.textContent=`${n.labels.summaryPrefix}: ${i.total} | High ${i.high} | Medium ${i.medium} | Low ${i.low} | Redacted ${i.redactedCount}`,d.disabled=o||r.length===0,o?ie(t,n.labels.readonlyRedactionText):ie(t,`${i.total} PII findings detected.`),z(e,t,n),r.length===0){c.innerHTML=`<li class="rte-pii-redaction-empty">${p(n.labels.noFindingsText)}</li>`;return}c.innerHTML=r.map(s=>{const g=s.type.toUpperCase(),A=s.suggestion||"Redact this finding before export/share.",B=`${n.labels.locateText}: ${s.match}`,y=`${n.labels.redactText}: ${s.match}`,U=o?'disabled aria-disabled="true"':"";return` | ||
| <li class="rte-pii-redaction-item rte-pii-redaction-item-${s.severity}"> | ||
| <button | ||
| type="button" | ||
| class="rte-pii-redaction-item-btn" | ||
| data-action="locate-finding" | ||
| data-finding-id="${p(s.id)}" | ||
| data-role="finding-button" | ||
| aria-label="${p(B)}" | ||
| > | ||
| <span class="rte-pii-redaction-badge">${p(s.severity.toUpperCase())}</span> | ||
| <span class="rte-pii-redaction-type">${p(g)}</span> | ||
| </button> | ||
| <p class="rte-pii-redaction-line"><strong>${p(n.labels.matchLabel)}:</strong> ${p(ue(s.match,80))}</p> | ||
| <p class="rte-pii-redaction-line"><strong>${p(n.labels.maskedLabel)}:</strong> ${p(ue(s.masked,80))}</p> | ||
| ${s.excerpt?`<p class="rte-pii-redaction-line"><strong>${p(n.labels.excerptLabel)}:</strong> ${p(s.excerpt)}</p>`:""} | ||
| <p class="rte-pii-redaction-help">${p(A)}</p> | ||
| <div class="rte-pii-redaction-item-actions"> | ||
| <button type="button" class="rte-pii-redaction-btn" data-action="redact-finding" data-finding-id="${p(s.id)}" aria-label="${p(y)}" ${U}>${p(n.labels.redactText)}</button> | ||
| </div> | ||
| </li> | ||
| `}).join("")}}function fe(e,t){if(!t.classList.contains("show"))return;const r=be(e).getBoundingClientRect(),i=Math.min(window.innerWidth-20,390),o=Math.max(10,window.innerWidth-i-10),a=Math.min(Math.max(10,r.right-i),o),l=Math.max(10,Math.min(window.innerHeight-10-280,r.top+10));t.style.width=`${i}px`,t.style.left=`${a}px`,t.style.top=`${l}px`,t.style.maxHeight=`${Math.max(260,window.innerHeight-20)}px`}function F(e,t){const n=S.get(e);return typeof n=="boolean"?n:t?t.enableRealtime:!0}function Re(e,t){if(t===e.innerHTML)return;const n=window.execEditorCommand||window.executeEditorCommand;if(typeof n=="function")try{n("recordDomTransaction",e,t,e.innerHTML)}catch{}}function Se(e){e.dispatchEvent(new Event("input",{bubbles:!0}))}function Me(e,t){e.dispatchEvent(new CustomEvent("editora:pii-redacted",{bubbles:!0,detail:{redactedCount:t}}))}function Ae(e,t){return(I.get(e)||[]).find(r=>r.id===t)}function rt(e){const t=m.get(e);if(t)return t;const n=f.get(e)||M||ee(),r=`rte-pii-redaction-panel-${Fe++}`,i=document.createElement("section");return i.className=u,i.id=r,i.setAttribute("role","dialog"),i.setAttribute("aria-modal","false"),i.setAttribute("aria-label",n.labels.panelAriaLabel),i.innerHTML=` | ||
| <header class="rte-pii-redaction-header"> | ||
| <h2 class="rte-pii-redaction-title">${p(n.labels.panelTitle)}</h2> | ||
| <button type="button" class="rte-pii-redaction-icon-btn" data-action="close" aria-label="${p(n.labels.closeText)}">✕</button> | ||
| </header> | ||
| <div class="rte-pii-redaction-body"> | ||
| <div class="rte-pii-redaction-topline"> | ||
| <p class="rte-pii-redaction-summary" aria-live="polite"></p> | ||
| <span class="rte-pii-redaction-count" aria-hidden="true">0</span> | ||
| </div> | ||
| <div class="rte-pii-redaction-controls" role="toolbar" aria-label="PII redaction controls"> | ||
| <button type="button" class="rte-pii-redaction-btn rte-pii-redaction-btn-primary" data-action="run-scan">${p(n.labels.scanText)}</button> | ||
| <button type="button" class="rte-pii-redaction-btn" data-action="redact-all">${p(n.labels.redactAllText)}</button> | ||
| <button type="button" class="rte-pii-redaction-btn" data-action="toggle-realtime" aria-pressed="false"></button> | ||
| </div> | ||
| <ul class="rte-pii-redaction-list" role="list" aria-label="Detected PII findings"></ul> | ||
| <p class="rte-pii-redaction-shortcut">${p(n.labels.shortcutText)}</p> | ||
| <span class="rte-pii-redaction-live" aria-live="polite"></span> | ||
| </div> | ||
| `,i.addEventListener("click",o=>{const l=o.target?.closest("[data-action]");if(!l)return;const c=l.getAttribute("data-action")||"",d=f.get(e)||M||n;if(f.set(e,d),w(e,d),c==="close"){j(e,!0);return}if(c==="run-scan"){h(e,d,!0);return}if(c==="toggle-realtime"){const s=!F(e,d);S.set(e,s),z(e,i,d),s&&h(e,d,!0);return}if(c==="redact-all"){xe(e,d);return}if(c==="locate-finding"){const s=l.getAttribute("data-finding-id")||"",g=Ae(e,s);if(!g)return;at(e,g,d);return}if(c==="redact-finding"){const s=l.getAttribute("data-finding-id")||"";_e(e,s,d)}}),i.addEventListener("keydown",o=>{if(o.key==="Escape"){o.preventDefault(),j(e,!0);return}if(o.key!=="ArrowDown"&&o.key!=="ArrowUp")return;const a=Array.from(i.querySelectorAll('[data-role="finding-button"]'));if(a.length===0)return;const l=document.activeElement,c=a.findIndex(g=>g===l);if(c===-1)return;o.preventDefault();const d=o.key==="ArrowDown"?1:-1,s=(c+d+a.length)%a.length;a[s].focus()}),ne(i,e),document.body.appendChild(i),m.set(e,i),Z.set(e,!1),H(e),i}function j(e,t=!1){const n=m.get(e);n&&(n.classList.remove("show"),Z.set(e,!1),C(e,"togglePIIRedactionPanel",!1),t&&e.focus({preventScroll:!0}))}function N(e){K();const t=rt(e);m.forEach((r,i)=>{i!==e&&j(i,!1)}),t.classList.add("show"),Z.set(e,!0),C(e,"togglePIIRedactionPanel",!0),ne(t,e),fe(e,t),H(e),t.querySelector('[data-action="run-scan"]')?.focus()}function Pe(e,t){const n=oe(e);return(typeof t=="boolean"?t:!n)?N(e):j(e),!0}function ot(e,t){const n=t.normalizeText(e.innerText||e.textContent||""),r=e.innerHTML;return`${n.length}:${ve(n)}:${r.length}:${ve(r)}:${t.detectorSignature}`}function it(e,t){const n=[],r=ge(e.pattern);let i=r.exec(t);for(;i;){const o=i[0]||"",a=i.index,l=a+o.length;o&&l>a&&(!e.validator||e.validator(o))&&n.push({value:o,start:a,end:l}),r.lastIndex===i.index&&(r.lastIndex+=1),i=r.exec(t)}return n}function Le(e,t,n){const r=n.detectors.find(c=>c.type===t.type&&c.enabled);if(!r)return null;const i=t.match.toLowerCase();let o=0;const a=document.createTreeWalker(e,pe,null);let l=a.nextNode();for(;l;){if(!he(l,n)){const c=it(r,l.data);for(let d=0;d<c.length;d+=1){const s=c[d];if(s.value.toLowerCase()===i&&(o+=1,o===t.occurrence)){const g=document.createRange();return g.setStart(l,s.start),g.setEnd(l,s.end),g}}}l=a.nextNode()}return null}function at(e,t,n){const r=Le(e,t,n);if(!r)return!1;const i=window.getSelection();return i?(i.removeAllRanges(),i.addRange(r),re(r.startContainer)?.scrollIntoView({behavior:"smooth",block:"center",inline:"nearest"}),e.focus({preventScroll:!0}),!0):!1}async function h(e,t,n=!1){w(e,t);const r=ot(e,t);if(!n&&de.get(e)===r)return I.get(e)||[];const i=(Q.get(e)||0)+1;Q.set(e,i);const o=[],a=new Map,l=document.createTreeWalker(e,pe,null);let c=l.nextNode();for(;c&&o.length<t.maxFindings;){const g=c.data||"";if(g.trim()&&!he(c,t)){const A=Qe(g,t.detectors,t.maxFindings-o.length);for(let B=0;B<A.length&&!(o.length>=t.maxFindings);B+=1){const y=A[B],U=`${y.type}:${y.value.toLowerCase()}`,ye=(a.get(U)||0)+1;a.set(U,ye),o.push({id:Xe(y.type),type:y.type,severity:y.severity,match:y.value,masked:Te(y.value,y.type,t),occurrence:ye,excerpt:et(g,y.start,y.end),suggestion:"Review and redact this value before external sharing."})}}c=l.nextNode()}if(Q.get(e)!==i)return I.get(e)||[];const d=E.get(e)?.redactedCount||0,s=tt(o,d);return de.set(e,r),I.set(e,o),E.set(e,s),H(e),e.dispatchEvent(new CustomEvent("editora:pii-scan",{bubbles:!0,detail:{findings:o,stats:s}})),o}function lt(e,t){let n=e,r=0;return t.detectors.filter(o=>o.enabled).forEach(o=>{const a=ge(o.pattern);n=n.replace(a,l=>o.validator&&!o.validator(l)?l:(r+=1,Ce(l,o.type,t)))}),{nextValue:n,count:r}}async function _e(e,t,n){if(V(e)){const d=m.get(e);return d&&ie(d,n.labels.readonlyRedactionText),!1}const r=Ae(e,t);if(!r)return!1;const i=Le(e,r,n);if(!i)return!1;const o=e.innerHTML,a=Ce(r.match,r.type,n);if(i.startContainer===i.endContainer&&i.startContainer.nodeType===Node.TEXT_NODE){const d=i.startContainer,s=d.data,g=i.startOffset,A=i.endOffset;d.data=`${s.slice(0,g)}${a}${s.slice(A)}`}else i.deleteContents(),i.insertNode(document.createTextNode(a));Se(e),Re(e,o);const l=E.get(e)?.redactedCount||0;await h(e,n,!0);const c=E.get(e);return c&&(c.redactedCount=l+1,H(e)),Me(e,1),!0}async function xe(e,t){if(V(e)){const d=m.get(e);return d&&ie(d,t.labels.readonlyRedactionText),0}(I.get(e)||[]).length===0&&await h(e,t,!0);const r=e.innerHTML;let i=0;const o=document.createTreeWalker(e,pe,null);let a=o.nextNode();for(;a;){if(he(a,t)){a=o.nextNode();continue}const d=a.data||"";if(!d){a=o.nextNode();continue}const s=lt(d,t);s.count>0&&s.nextValue!==d&&(a.data=s.nextValue,i+=s.count),a=o.nextNode()}if(i===0)return 0;Se(e),Re(e,r);const l=E.get(e)?.redactedCount||0;await h(e,t,!0);const c=E.get(e);return c&&(c.redactedCount=l+i,H(e)),Me(e,i),i}function De(e){const t=f.get(e)||M;if(!t||!F(e,t)||V(e))return;me(e);const n=window.setTimeout(()=>{W.delete(n),te.delete(e),h(e,t,!1)},t.debounceMs);W.add(n),te.set(e,n)}function ct(e){const t=e.key.toLowerCase();return(e.metaKey||e.ctrlKey)&&e.altKey&&e.shiftKey&&t==="i"}function st(e){const t=e.key.toLowerCase();return(e.metaKey||e.ctrlKey)&&e.altKey&&e.shiftKey&&t==="u"}function dt(e){const t=e.key.toLowerCase();return(e.metaKey||e.ctrlKey)&&e.altKey&&e.shiftKey&&t==="m"}function ut(e){const t=e.key.toLowerCase();return(e.metaKey||e.ctrlKey)&&e.altKey&&e.shiftKey&&t==="y"}function ft(e){const t=re(e.target);if(t){const r=t.closest(x);if(r)return r;const i=t.closest(ae);if(i){const a=O(i);if(a)return a}const o=t.closest(`.${u}`);if(o){const a=Array.from(m.entries()).find(([,l])=>l===o);if(a)return a[0]}}const n=window.getSelection();if(n&&n.rangeCount>0){const r=re(n.getRangeAt(0).startContainer)?.closest(x);if(r)return r}return null}function pt(){if(typeof document>"u"||document.getElementById(we))return;const e=document.createElement("style");e.id=we,e.textContent=` | ||
| .rte-toolbar-group-items.${k}, | ||
| .editora-toolbar-group-items.${k}, | ||
| .rte-toolbar-group-items.${v}, | ||
| .editora-toolbar-group-items.${v} { | ||
| display: flex; | ||
| border: 1px solid #ccc; | ||
| border-radius: 3px; | ||
| background: #fff; | ||
| } | ||
| .rte-toolbar-group-items.${k} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${k} .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${v} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${v} .editora-toolbar-button { | ||
| border: none; | ||
| border-radius: 0; | ||
| border-right: 1px solid #ccc; | ||
| } | ||
| .rte-toolbar-group-items.${k} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${k} .editora-toolbar-item:last-child .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${v} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${v} .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| .rte-toolbar-button[data-command="togglePIIRealtime"].active, | ||
| .editora-toolbar-button[data-command="togglePIIRealtime"].active { | ||
| background-color: #ccc; | ||
| } | ||
| ${$} .rte-toolbar-group-items.${k}, | ||
| ${$} .editora-toolbar-group-items.${k}, | ||
| ${$} .rte-toolbar-group-items.${v}, | ||
| ${$} .editora-toolbar-group-items.${v}, | ||
| .${u}.rte-pii-redaction-theme-dark { | ||
| border-color: #566275; | ||
| } | ||
| ${$} .rte-toolbar-group-items.${k} .rte-toolbar-button svg, | ||
| ${$} .editora-toolbar-group-items.${k} .editora-toolbar-button svg, | ||
| ${$} .rte-toolbar-group-items.${v} .rte-toolbar-button svg, | ||
| ${$} .editora-toolbar-group-items.${v} .editora-toolbar-button svg | ||
| { | ||
| fill: none; | ||
| } | ||
| ${$} .rte-toolbar-group-items.${k} .rte-toolbar-button, | ||
| ${$} .editora-toolbar-group-items.${k} .editora-toolbar-button | ||
| { | ||
| border-color: #566275; | ||
| } | ||
| .${u} { | ||
| position: fixed; | ||
| z-index: 12000; | ||
| display: none; | ||
| width: min(390px, calc(100vw - 20px)); | ||
| max-height: calc(100vh - 20px); | ||
| border: 1px solid #d1d5db; | ||
| border-radius: 14px; | ||
| background: #ffffff; | ||
| color: #111827; | ||
| box-shadow: 0 18px 45px rgba(15, 23, 42, 0.25); | ||
| overflow: hidden; | ||
| } | ||
| .${u}.show { | ||
| display: flex; | ||
| flex-direction: column; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark { | ||
| border-color: #334155; | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| box-shadow: 0 20px 46px rgba(2, 6, 23, 0.68); | ||
| } | ||
| .rte-pii-redaction-header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| padding: 12px 14px; | ||
| border-bottom: 1px solid #e5e7eb; | ||
| background: linear-gradient(180deg, #f9fafb 0%, #f3f4f6 100%); | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-header { | ||
| border-color: #1e293b; | ||
| background: linear-gradient(180deg, #111827 0%, #0f172a 100%); | ||
| } | ||
| .rte-pii-redaction-title { | ||
| margin: 0; | ||
| font-size: 15px; | ||
| line-height: 1.2; | ||
| font-weight: 700; | ||
| } | ||
| .rte-pii-redaction-icon-btn { | ||
| width: 34px; | ||
| height: 34px; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| font-weight: 600; | ||
| padding: 0; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| cursor: pointer; | ||
| } | ||
| .rte-pii-redaction-icon-btn:hover, | ||
| .rte-pii-redaction-icon-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-icon-btn { | ||
| background: #0f172a; | ||
| border-color: #475569; | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-icon-btn:hover, | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-icon-btn:focus-visible { | ||
| border-color: #60a5fa; | ||
| box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.24); | ||
| } | ||
| .rte-pii-redaction-body { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 10px; | ||
| padding: 12px; | ||
| overflow: auto; | ||
| } | ||
| .rte-pii-redaction-topline { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| } | ||
| .rte-pii-redaction-summary { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #475569; | ||
| flex: 1; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-summary { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-pii-redaction-count { | ||
| min-width: 32px; | ||
| height: 32px; | ||
| border-radius: 999px; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| font-weight: 700; | ||
| font-size: 13px; | ||
| border: 1px solid #cbd5e1; | ||
| background: #f8fafc; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-count { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-pii-redaction-controls { | ||
| display: flex; | ||
| gap: 8px; | ||
| flex-wrap: wrap; | ||
| } | ||
| .rte-pii-redaction-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| height: 34px; | ||
| padding: 0 10px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| cursor: pointer; | ||
| } | ||
| .rte-pii-redaction-btn:hover, | ||
| .rte-pii-redaction-btn:focus-visible { | ||
| border-color: #94a3b8; | ||
| background: #f8fafc; | ||
| outline: none; | ||
| } | ||
| .rte-pii-redaction-btn:disabled { | ||
| opacity: 0.56; | ||
| cursor: not-allowed; | ||
| } | ||
| .rte-pii-redaction-btn-primary { | ||
| border-color: #0284c7; | ||
| background: #0ea5e9; | ||
| color: #f8fafc; | ||
| } | ||
| .rte-pii-redaction-btn-primary:hover, | ||
| .rte-pii-redaction-btn-primary:focus-visible { | ||
| border-color: #0369a1; | ||
| background: #0284c7; | ||
| color: #ffffff; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-btn { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-btn:hover, | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-btn:focus-visible { | ||
| border-color: #475569; | ||
| background: #1e293b; | ||
| } | ||
| .rte-pii-redaction-list { | ||
| list-style: none; | ||
| margin: 0; | ||
| padding: 0; | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 8px; | ||
| max-height: min(55vh, 420px); | ||
| overflow: auto; | ||
| } | ||
| .rte-pii-redaction-item { | ||
| border: 1px solid #e2e8f0; | ||
| border-radius: 10px; | ||
| padding: 8px; | ||
| background: #ffffff; | ||
| display: grid; | ||
| gap: 6px; | ||
| } | ||
| .rte-pii-redaction-item-high { | ||
| border-color: #fca5a5; | ||
| background: #fef2f2; | ||
| } | ||
| .rte-pii-redaction-item-medium { | ||
| border-color: #fcd34d; | ||
| background: #fffbeb; | ||
| } | ||
| .rte-pii-redaction-item-low { | ||
| border-color: #93c5fd; | ||
| background: #eff6ff; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-item { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-item-high { | ||
| border-color: #7f1d1d; | ||
| background: #2b0b11; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-item-medium { | ||
| border-color: #78350f; | ||
| background: #2b1907; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-item-low { | ||
| border-color: #1d4ed8; | ||
| background: #0a162f; | ||
| } | ||
| .rte-pii-redaction-item-btn { | ||
| border: none; | ||
| background: transparent; | ||
| width: 100%; | ||
| display: flex; | ||
| align-items: center; | ||
| gap: 8px; | ||
| text-align: left; | ||
| padding: 0; | ||
| color: inherit; | ||
| cursor: pointer; | ||
| } | ||
| .rte-pii-redaction-item-btn:focus-visible { | ||
| outline: 2px solid #0284c7; | ||
| outline-offset: 3px; | ||
| border-radius: 6px; | ||
| } | ||
| .rte-pii-redaction-badge { | ||
| border-radius: 999px; | ||
| border: 1px solid currentColor; | ||
| padding: 1px 8px; | ||
| font-size: 10px; | ||
| font-weight: 700; | ||
| line-height: 1.3; | ||
| text-transform: uppercase; | ||
| opacity: 0.86; | ||
| } | ||
| .rte-pii-redaction-type { | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| letter-spacing: 0.03em; | ||
| } | ||
| .rte-pii-redaction-line, | ||
| .rte-pii-redaction-help { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #334155; | ||
| word-break: break-word; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-line, | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-help { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-pii-redaction-item-actions { | ||
| display: flex; | ||
| justify-content: flex-end; | ||
| } | ||
| .rte-pii-redaction-empty { | ||
| border: 1px dashed #cbd5e1; | ||
| border-radius: 10px; | ||
| padding: 10px; | ||
| font-size: 13px; | ||
| color: #475569; | ||
| background: #f8fafc; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-empty { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #94a3b8; | ||
| } | ||
| .rte-pii-redaction-shortcut { | ||
| margin: 2px 0 0; | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-shortcut { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-pii-redaction-live { | ||
| position: absolute; | ||
| width: 1px; | ||
| height: 1px; | ||
| margin: -1px; | ||
| padding: 0; | ||
| overflow: hidden; | ||
| clip: rect(0 0 0 0); | ||
| border: 0; | ||
| } | ||
| @media (max-width: 768px) { | ||
| .${u} { | ||
| left: 10px !important; | ||
| right: 10px; | ||
| top: 10px !important; | ||
| width: auto !important; | ||
| max-height: calc(100vh - 20px); | ||
| } | ||
| .rte-pii-redaction-list { | ||
| max-height: 45vh; | ||
| } | ||
| } | ||
| `,document.head.appendChild(e)}function gt(e){M=e,P||(P=t=>{K();const r=t.target?.closest(x);if(!r)return;b=r;const i=f.get(r)||e;w(r,i),f.set(r,i),C(r,"togglePIIRedactionPanel",oe(r)),C(r,"togglePIIRealtime",F(r,i));const o=m.get(r);o&&(ne(o,r),fe(r,o),z(r,o,i))},document.addEventListener("focusin",P,!0)),L||(L=t=>{const r=t.target?.closest(x);r&&(b=r,De(r))},document.addEventListener("input",L,!0)),_||(_=t=>{if(t.defaultPrevented||t.target?.closest(`.${u} input, .${u} textarea, .${u} select`))return;const r=ft(t);if(!r)return;const i=f.get(r)||M||e;if(w(r,i),f.set(r,i),b=r,t.key==="Escape"&&oe(r)){t.preventDefault(),j(r,!0);return}if(ct(t)){t.preventDefault(),t.stopPropagation(),Pe(r);return}if(st(t)){t.preventDefault(),t.stopPropagation(),h(r,i,!0),N(r);return}if(dt(t)){t.preventDefault(),t.stopPropagation(),V(r)||(xe(r,i),N(r));return}if(ut(t)){t.preventDefault(),t.stopPropagation();const o=!F(r,i);S.set(r,o);const a=m.get(r);a&&z(r,a,i),C(r,"togglePIIRealtime",o),o&&h(r,i,!0)}},document.addEventListener("keydown",_,!0)),R||(R=()=>{K(),m.forEach((t,n)=>{!n.isConnected||!t.isConnected||(ne(t,n),fe(n,t))})},window.addEventListener("scroll",R,!0),window.addEventListener("resize",R)),!D&&typeof MutationObserver<"u"&&document.body&&(D=new MutationObserver(t=>{Ue(t)&&K()}),D.observe(document.body,{childList:!0,subtree:!0}))}function bt(){P&&(document.removeEventListener("focusin",P,!0),P=null),L&&(document.removeEventListener("input",L,!0),L=null),_&&(document.removeEventListener("keydown",_,!0),_=null),R&&(window.removeEventListener("scroll",R,!0),window.removeEventListener("resize",R),R=null),D&&(D.disconnect(),D=null),m.forEach(e=>e.remove()),m.clear(),q.forEach(e=>me(e)),q.clear(),M=null,b=null}const mt=(e={})=>{const t=ee(e),n=new Set;return pt(),{name:"piiRedaction",toolbar:[{id:"piiRedactionGroup",label:"PII Redaction",type:"group",command:"piiRedaction",items:[{id:"piiRedaction",label:"PII Redaction",command:"togglePIIRedactionPanel",shortcut:"Mod-Alt-Shift-i",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M12 3.5 19 6.5v4.8c0 4.4-2.7 8.1-7 9.2-4.3-1.1-7-4.8-7-9.2V6.5l7-3Z" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round"/><path d="M8.8 11.6h6.4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><circle cx="12" cy="11.6" r="1.2" fill="currentColor"/></svg>'},{id:"piiScan",label:"Scan PII",command:"runPIIScan",shortcut:"Mod-Alt-Shift-u",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><rect x="4.5" y="3.5" width="11" height="15" rx="2" stroke="currentColor" stroke-width="1.6"/><path d="M7.5 8.2h5M7.5 11.2h5M7.5 14.2h3.2" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><circle cx="16.8" cy="16.8" r="2.8" stroke="currentColor" stroke-width="1.6"/><path d="m18.8 18.8 2 2" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>'},{id:"piiRedactAll",label:"Redact All PII",command:"redactAllPII",shortcut:"Mod-Alt-Shift-m",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M5 18h14" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/><path d="M7 6h10l-1 8H8L7 6Z" stroke="currentColor" stroke-width="1.7"/><path d="m9 9 6 4" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/></svg>'},{id:"piiRealtime",label:"Toggle Realtime PII Scan",command:"togglePIIRealtime",shortcut:"Mod-Alt-Shift-y",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M12 3v4M12 17v4M4 12h4M16 12h4" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/><circle cx="12" cy="12" r="4" stroke="currentColor" stroke-width="1.7"/></svg>'}]}],commands:{piiRedaction:(r,i)=>{const o=T(i);if(!o)return!1;const a=f.get(o)||t;return w(o,a),f.set(o,a),b=o,N(o),h(o,a,!1),!0},togglePIIRedactionPanel:(r,i)=>{const o=T(i);if(!o)return!1;const a=f.get(o)||t;w(o,a),f.set(o,a),b=o;const l=Pe(o,typeof r=="boolean"?r:void 0);return oe(o)&&h(o,a,!1),l},runPIIScan:async(r,i)=>{const o=T(i);if(!o)return!1;const a=f.get(o)||t;return w(o,a),f.set(o,a),b=o,await h(o,a,!0),N(o),!0},redactAllPII:async(r,i)=>{const o=T(i);if(!o)return!1;const a=f.get(o)||t;w(o,a),f.set(o,a),b=o;const l=await xe(o,a);return l>0&&N(o),l>0},redactPIIFinding:async(r,i)=>{const o=T(i);if(!o||typeof r!="string"||!r)return!1;const a=f.get(o)||t;return w(o,a),f.set(o,a),b=o,_e(o,r,a)},togglePIIRealtime:(r,i)=>{const o=T(i);if(!o)return!1;const a=f.get(o)||t;w(o,a),f.set(o,a);const l=typeof r=="boolean"?r:!F(o,a);S.set(o,l);const c=m.get(o);return c&&z(o,c,a),C(o,"togglePIIRealtime",l),l&&h(o,a,!0),!0},getPIIRedactionFindings:(r,i)=>{const o=T(i);if(!o)return!1;const a=I.get(o)||[],l=E.get(o)||le(0),c=a.map(s=>({...s})),d={...l,byType:{...l.byType}};if(typeof r=="function")try{r(c,d)}catch{}return o.__piiRedactionFindings=c,o.dispatchEvent(new CustomEvent("editora:pii-findings",{bubbles:!0,detail:{findings:c,stats:d}})),!0},setPIIRedactionOptions:(r,i)=>{const o=T(i);if(!o||!r||typeof r!="object")return!1;const a=f.get(o)||t,l=ee({...ce(a),...r,labels:{...a.labels,...r.labels||{}},detectors:{...ce(a).detectors||{},...r.detectors||{}},normalizeText:r.normalizeText||a.normalizeText});f.set(o,l),typeof r.enableRealtime=="boolean"&&S.set(o,r.enableRealtime);const c=m.get(o);return c&&(nt(c,l),H(o),z(o,c,l)),h(o,l,!0),!0}},keymap:{"Mod-Alt-Shift-i":"togglePIIRedactionPanel","Mod-Alt-Shift-I":"togglePIIRedactionPanel","Mod-Alt-Shift-u":"runPIIScan","Mod-Alt-Shift-U":"runPIIScan","Mod-Alt-Shift-m":"redactAllPII","Mod-Alt-Shift-M":"redactAllPII","Mod-Alt-Shift-y":"togglePIIRealtime","Mod-Alt-Shift-Y":"togglePIIRealtime"},init:function(i){G+=1;const o=this&&typeof this.__pluginConfig=="object"?ee({...ce(t),...this.__pluginConfig}):t;gt(o);const a=T(i?.editorElement?{editorElement:i.editorElement}:void 0,!1);a&&(b=a,n.add(a),w(a,o),f.set(a,o),C(a,"togglePIIRedactionPanel",!1),C(a,"togglePIIRealtime",o.enableRealtime),o.enableRealtime&&De(a))},destroy:()=>{n.forEach(r=>Ie(r)),n.clear(),G=Math.max(0,G-1),!(G>0)&&(W.forEach(r=>{window.clearTimeout(r)}),W.clear(),bt())}}};exports.PIIRedactionPlugin=mt; |
| const x = ".rte-content, .editora-content", ae = "[data-editora-editor], .rte-editor, .editora-editor, editora-editor", ke = "__editoraCommandEditorRoot", we = "rte-pii-redaction-styles", u = "rte-pii-redaction-panel", k = "pii-redaction", v = "piiRedaction", $ = ':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)', pe = typeof NodeFilter < "u" ? NodeFilter.SHOW_TEXT : 4, Ne = [ | ||
| "email", | ||
| "phone", | ||
| "ssn", | ||
| "credit-card", | ||
| "ipv4", | ||
| "api-key", | ||
| "jwt" | ||
| ], Oe = { | ||
| panelTitle: "PII Redaction", | ||
| panelAriaLabel: "PII redaction panel", | ||
| scanText: "Scan PII", | ||
| redactAllText: "Redact All", | ||
| redactText: "Redact", | ||
| locateText: "Locate", | ||
| realtimeOnText: "Realtime On", | ||
| realtimeOffText: "Realtime Off", | ||
| closeText: "Close", | ||
| noFindingsText: "No PII detected in the document.", | ||
| summaryPrefix: "Findings", | ||
| shortcutText: "Shortcuts: Ctrl/Cmd+Alt+Shift+I/U/M/Y", | ||
| readonlyRedactionText: "Editor is read-only. Reopen editable mode to redact.", | ||
| matchLabel: "Detected", | ||
| maskedLabel: "Masked", | ||
| excerptLabel: "Context" | ||
| }, ze = { | ||
| email: { | ||
| label: "Email", | ||
| severity: "medium", | ||
| pattern: /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi | ||
| }, | ||
| phone: { | ||
| label: "Phone", | ||
| severity: "medium", | ||
| pattern: /\b(?:\+?\d{1,3}[\s.-]?)?(?:\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4})\b/g | ||
| }, | ||
| ssn: { | ||
| label: "SSN", | ||
| severity: "high", | ||
| pattern: /\b\d{3}-\d{2}-\d{4}\b/g | ||
| }, | ||
| "credit-card": { | ||
| label: "Credit Card", | ||
| severity: "high", | ||
| pattern: /\b(?:\d[ -]*?){13,19}\b/g, | ||
| validator: (e) => qe(e) | ||
| }, | ||
| ipv4: { | ||
| label: "IPv4", | ||
| severity: "low", | ||
| pattern: /\b(?:(?:25[0-5]|2[0-4]\d|1?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|1?\d?\d)\b/g | ||
| }, | ||
| "api-key": { | ||
| label: "API Key", | ||
| severity: "high", | ||
| pattern: /\b(?:sk-[A-Za-z0-9]{20,}|AKIA[0-9A-Z]{16}|AIza[0-9A-Za-z\-_]{35}|ghp_[A-Za-z0-9]{36}|xox[baprs]-[A-Za-z0-9-]{10,})\b/g | ||
| }, | ||
| jwt: { | ||
| label: "JWT", | ||
| severity: "high", | ||
| pattern: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g | ||
| } | ||
| }, f = /* @__PURE__ */ new WeakMap(), I = /* @__PURE__ */ new WeakMap(), E = /* @__PURE__ */ new WeakMap(), S = /* @__PURE__ */ new WeakMap(), te = /* @__PURE__ */ new WeakMap(), de = /* @__PURE__ */ new WeakMap(), Q = /* @__PURE__ */ new WeakMap(), m = /* @__PURE__ */ new Map(), Z = /* @__PURE__ */ new WeakMap(), q = /* @__PURE__ */ new Set(), W = /* @__PURE__ */ new Set(); | ||
| let G = 0, Fe = 0, Ee = 0, A = null, g = null, P = null, L = null, D = null, R = null, _ = null; | ||
| function p(e) { | ||
| return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); | ||
| } | ||
| function He(e) { | ||
| return e.replace(/\u00A0/g, " ").replace(/\s+/g, " ").trim(); | ||
| } | ||
| function Y(e) { | ||
| const t = e.flags.includes("g") ? e.flags : `${e.flags}g`; | ||
| return new RegExp(e.source, t); | ||
| } | ||
| function be(e) { | ||
| return new RegExp(e.source, e.flags); | ||
| } | ||
| function X(e, t, n) { | ||
| return Math.max(t, Math.min(n, e)); | ||
| } | ||
| function Be(e, t) { | ||
| return e === "high" || e === "medium" || e === "low" ? e : t; | ||
| } | ||
| function Ke(e) { | ||
| const t = (e || "*").slice(0, 1) || "*"; | ||
| return /[A-Za-z0-9._%+\-\s]/.test(t) ? "*" : t; | ||
| } | ||
| function ve(e) { | ||
| let t = 2166136261; | ||
| for (let n = 0; n < e.length; n += 1) | ||
| t ^= e.charCodeAt(n), t = Math.imul(t, 16777619); | ||
| return t >>> 0; | ||
| } | ||
| function qe(e) { | ||
| const t = e.replace(/\D/g, ""); | ||
| if (t.length < 13 || t.length > 19) return !1; | ||
| let n = 0, r = !1; | ||
| for (let i = t.length - 1; i >= 0; i -= 1) { | ||
| let o = Number(t[i]); | ||
| r && (o *= 2, o > 9 && (o -= 9)), n += o, r = !r; | ||
| } | ||
| return n % 10 === 0; | ||
| } | ||
| function We(e, t) { | ||
| const n = ze[e]; | ||
| if (typeof t == "boolean") | ||
| return { | ||
| type: e, | ||
| label: n.label, | ||
| severity: n.severity, | ||
| enabled: t, | ||
| pattern: Y(n.pattern), | ||
| validator: n.validator | ||
| }; | ||
| if (!t) | ||
| return { | ||
| type: e, | ||
| label: n.label, | ||
| severity: n.severity, | ||
| enabled: !0, | ||
| pattern: Y(n.pattern), | ||
| validator: n.validator | ||
| }; | ||
| const r = t.pattern instanceof RegExp ? Y(t.pattern) : Y(n.pattern); | ||
| return { | ||
| type: e, | ||
| label: n.label, | ||
| severity: Be(t.severity, n.severity), | ||
| enabled: t.enabled !== !1, | ||
| pattern: r, | ||
| validator: n.validator | ||
| }; | ||
| } | ||
| function ee(e = {}) { | ||
| const t = Ne.map((r) => We(r, e.detectors?.[r])), n = t.map((r) => `${r.type}:${r.enabled ? "1" : "0"}:${r.severity}:${r.pattern.source}:${r.pattern.flags}`).join("|"); | ||
| return { | ||
| enableRealtime: e.enableRealtime !== !1, | ||
| debounceMs: X(Number(e.debounceMs ?? 220), 60, 3e3), | ||
| maxFindings: X(Number(e.maxFindings ?? 140), 1, 500), | ||
| maskChar: Ke(e.maskChar), | ||
| revealStart: X(Number(e.revealStart ?? 2), 0, 12), | ||
| revealEnd: X(Number(e.revealEnd ?? 2), 0, 12), | ||
| redactionMode: e.redactionMode === "mask" ? "mask" : "token", | ||
| redactionToken: (e.redactionToken || "REDACTED").trim() || "REDACTED", | ||
| skipInCodeBlocks: e.skipInCodeBlocks !== !1, | ||
| labels: { | ||
| ...Oe, | ||
| ...e.labels || {} | ||
| }, | ||
| normalizeText: e.normalizeText || He, | ||
| detectors: t, | ||
| detectorSignature: n | ||
| }; | ||
| } | ||
| function ce(e) { | ||
| const t = {}; | ||
| return e.detectors.forEach((n) => { | ||
| t[n.type] = { | ||
| enabled: n.enabled, | ||
| severity: n.severity, | ||
| pattern: n.pattern | ||
| }; | ||
| }), { | ||
| enableRealtime: e.enableRealtime, | ||
| debounceMs: e.debounceMs, | ||
| maxFindings: e.maxFindings, | ||
| maskChar: e.maskChar, | ||
| revealStart: e.revealStart, | ||
| revealEnd: e.revealEnd, | ||
| redactionMode: e.redactionMode, | ||
| redactionToken: e.redactionToken, | ||
| skipInCodeBlocks: e.skipInCodeBlocks, | ||
| labels: { ...e.labels }, | ||
| normalizeText: e.normalizeText, | ||
| detectors: t | ||
| }; | ||
| } | ||
| function ge(e) { | ||
| return e.closest(ae) || e; | ||
| } | ||
| function je(e) { | ||
| const t = e.closest("[data-editora-editor]"); | ||
| if (t && O(t) === e) | ||
| return t; | ||
| let n = e; | ||
| for (; n; ) { | ||
| if (n.matches(ae) && (n === e || O(n) === e)) | ||
| return n; | ||
| n = n.parentElement; | ||
| } | ||
| return ge(e); | ||
| } | ||
| function O(e) { | ||
| if (!e) return null; | ||
| if (e.matches(x)) return e; | ||
| const t = e.querySelector(x); | ||
| return t instanceof HTMLElement ? t : null; | ||
| } | ||
| function Ze() { | ||
| if (typeof window > "u") return null; | ||
| const e = window[ke]; | ||
| if (!(e instanceof HTMLElement)) return null; | ||
| window[ke] = null; | ||
| const t = O(e); | ||
| if (t) return t; | ||
| const n = e.closest(ae); | ||
| if (n) { | ||
| const i = O(n); | ||
| if (i) return i; | ||
| } | ||
| const r = e.closest(x); | ||
| return r instanceof HTMLElement ? r : null; | ||
| } | ||
| function J(e) { | ||
| return e ? (e.getAttribute("data-theme") || e.getAttribute("theme") || "").toLowerCase() === "dark" ? !0 : e.classList.contains("dark") || e.classList.contains("editora-theme-dark") || e.classList.contains("rte-theme-dark") : !1; | ||
| } | ||
| function Ve(e) { | ||
| const t = ge(e); | ||
| if (J(t)) return !0; | ||
| const n = t.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark"); | ||
| return J(n) ? !0 : J(document.documentElement) || J(document.body); | ||
| } | ||
| function ne(e, t) { | ||
| e.classList.remove("rte-pii-redaction-theme-dark"), Ve(t) && e.classList.add("rte-pii-redaction-theme-dark"); | ||
| } | ||
| function re(e) { | ||
| return e ? e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement : null; | ||
| } | ||
| function me(e) { | ||
| const t = te.get(e); | ||
| typeof t == "number" && (window.clearTimeout(t), W.delete(t), te.delete(e)); | ||
| } | ||
| function V(e) { | ||
| return e.getAttribute("contenteditable") === "false" || e.getAttribute("data-readonly") === "true"; | ||
| } | ||
| function le(e = 0) { | ||
| return { | ||
| total: 0, | ||
| high: 0, | ||
| medium: 0, | ||
| low: 0, | ||
| redactedCount: e, | ||
| byType: { | ||
| email: 0, | ||
| phone: 0, | ||
| ssn: 0, | ||
| "credit-card": 0, | ||
| ipv4: 0, | ||
| "api-key": 0, | ||
| jwt: 0 | ||
| } | ||
| }; | ||
| } | ||
| function K() { | ||
| Array.from(q).forEach((t) => { | ||
| t.isConnected || Ie(t); | ||
| }); | ||
| } | ||
| function Ue(e) { | ||
| for (let t = 0; t < e.length; t += 1) { | ||
| const n = e[t]; | ||
| if (!(n.type !== "childList" || n.removedNodes.length === 0)) | ||
| for (let r = 0; r < n.removedNodes.length; r += 1) { | ||
| const i = n.removedNodes[r]; | ||
| if (i.nodeType !== Node.ELEMENT_NODE) continue; | ||
| const o = i; | ||
| if (o.matches?.(x) || o.matches?.(`.${u}`) || o.querySelector?.(x) || o.querySelector?.(`.${u}`)) | ||
| return !0; | ||
| } | ||
| } | ||
| return !1; | ||
| } | ||
| function T(e, t = !0) { | ||
| if (K(), e?.contentElement instanceof HTMLElement) return e.contentElement; | ||
| if (e?.editorElement instanceof HTMLElement) { | ||
| const o = e.editorElement, a = O(o); | ||
| if (a) return a; | ||
| } | ||
| const n = Ze(); | ||
| if (n) return n; | ||
| const r = window.getSelection(); | ||
| if (r && r.rangeCount > 0) { | ||
| const a = re(r.getRangeAt(0).startContainer)?.closest(x); | ||
| if (a) return a; | ||
| } | ||
| const i = document.activeElement; | ||
| if (i) { | ||
| if (i.matches(x)) return i; | ||
| const o = i.closest(x); | ||
| if (o) return o; | ||
| } | ||
| return g && g.isConnected ? g : (g && !g.isConnected && (g = null), t ? document.querySelector(x) : null); | ||
| } | ||
| function Ie(e) { | ||
| me(e), m.get(e)?.remove(), m.delete(e), Z.delete(e), f.delete(e), I.delete(e), E.delete(e), S.delete(e), de.delete(e), Q.delete(e), q.delete(e), g === e && (g = null); | ||
| } | ||
| function C(e, t, n) { | ||
| const r = je(e); | ||
| Array.from( | ||
| r.querySelectorAll( | ||
| `.rte-toolbar-button[data-command="${t}"], .editora-toolbar-button[data-command="${t}"]` | ||
| ) | ||
| ).forEach((o) => { | ||
| o.classList.toggle("active", n), o.setAttribute("data-active", n ? "true" : "false"), o.setAttribute("aria-pressed", n ? "true" : "false"); | ||
| }); | ||
| } | ||
| function w(e, t) { | ||
| f.has(e) || f.set(e, t), I.has(e) || I.set(e, []), E.has(e) || E.set(e, le(0)), S.has(e) || S.set(e, t.enableRealtime), q.add(e); | ||
| } | ||
| function oe(e) { | ||
| return Z.get(e) === !0; | ||
| } | ||
| function $e(e, t, n, r) { | ||
| if (!e) return e; | ||
| if (e.length <= n + r) | ||
| return t.repeat(e.length); | ||
| const i = e.slice(0, n), o = r > 0 ? e.slice(e.length - r) : ""; | ||
| return `${i}${t.repeat(Math.max(1, e.length - n - r))}${o}`; | ||
| } | ||
| function se(e, t, n) { | ||
| const r = e.replace(/\D/g, ""); | ||
| if (r.length === 0) return e; | ||
| let i = 0; | ||
| const o = Math.max(0, r.length - n); | ||
| return e.split("").map((a) => /\d/.test(a) ? (i += 1, i <= o ? t : a) : a).join(""); | ||
| } | ||
| function Ge(e, t) { | ||
| const n = e.indexOf("@"); | ||
| if (n <= 0) return e; | ||
| const r = e.slice(0, n), i = e.slice(n + 1); | ||
| return r.length <= 2 ? `${r[0] || ""}${t}[at]${i}` : `${r[0]}${t.repeat(Math.max(1, r.length - 2))}${r[r.length - 1]}[at]${i}`; | ||
| } | ||
| function Ye(e, t) { | ||
| const n = e.split("."); | ||
| return n.length !== 4 ? e : `${n[0]}.${n[1]}.${n[2]}.${t.repeat(Math.max(1, n[3].length))}`; | ||
| } | ||
| function Te(e, t, n) { | ||
| return e && (t === "email" ? Ge(e, n.maskChar) : t === "phone" || t === "ssn" || t === "credit-card" ? se(e, n.maskChar, 4) : t === "ipv4" ? Ye(e, n.maskChar) : t === "api-key" || t === "jwt" ? $e(e, n.maskChar, 0, 0) : $e(e, n.maskChar, n.revealStart, n.revealEnd)); | ||
| } | ||
| function Ce(e, t, n) { | ||
| return n.redactionMode === "mask" ? Te(e, t, n) : `[${n.redactionToken}:${t.toUpperCase()}]`; | ||
| } | ||
| function Xe(e) { | ||
| return Ee += 1, `pii-${e}-${Date.now().toString(36)}-${Ee.toString(36)}`; | ||
| } | ||
| function he(e, t) { | ||
| return t.skipInCodeBlocks ? !!e.parentElement?.closest("code, pre, kbd, samp") : !1; | ||
| } | ||
| function Je(e, t) { | ||
| return t.some((n) => e.start < n.end && n.start < e.end); | ||
| } | ||
| function Qe(e, t, n) { | ||
| const r = []; | ||
| t.filter((a) => a.enabled).forEach((a) => { | ||
| const l = be(a.pattern); | ||
| let c = l.exec(e); | ||
| for (; c && r.length < n * 5; ) { | ||
| const d = c[0] || "", s = c.index, b = s + d.length; | ||
| d && b > s && (!a.validator || a.validator(d)) && r.push({ | ||
| type: a.type, | ||
| severity: a.severity, | ||
| value: d, | ||
| start: s, | ||
| end: b | ||
| }), l.lastIndex === c.index && (l.lastIndex += 1), c = l.exec(e); | ||
| } | ||
| }), r.sort((a, l) => a.start !== l.start ? a.start - l.start : l.end - a.end); | ||
| const o = []; | ||
| for (let a = 0; a < r.length && !(o.length >= n); a += 1) { | ||
| const l = r[a]; | ||
| Je({ start: l.start, end: l.end }, o) || o.push(l); | ||
| } | ||
| return o; | ||
| } | ||
| function ue(e, t = 120) { | ||
| return e.length <= t ? e : `${e.slice(0, t - 1).trimEnd()}...`; | ||
| } | ||
| function et(e, t, n) { | ||
| const r = Math.max(0, t - 28), i = Math.min(e.length, n + 28); | ||
| return ue(e.slice(r, i).trim(), 180); | ||
| } | ||
| function tt(e, t) { | ||
| const n = le(t); | ||
| return n.total = e.length, e.forEach((r) => { | ||
| n.byType[r.type] += 1, r.severity === "high" ? n.high += 1 : r.severity === "medium" ? n.medium += 1 : n.low += 1; | ||
| }), n; | ||
| } | ||
| function ie(e, t) { | ||
| const n = e.querySelector(".rte-pii-redaction-live"); | ||
| n && (n.textContent = t); | ||
| } | ||
| function z(e, t, n) { | ||
| const r = t.querySelector('[data-action="toggle-realtime"]'); | ||
| if (!r) return; | ||
| const i = F(e, n); | ||
| r.textContent = i ? n.labels.realtimeOnText : n.labels.realtimeOffText, r.setAttribute("aria-pressed", i ? "true" : "false"), C(e, "togglePIIRealtime", i); | ||
| } | ||
| function nt(e, t) { | ||
| e.setAttribute("aria-label", t.labels.panelAriaLabel); | ||
| const n = e.querySelector(".rte-pii-redaction-title"); | ||
| n && (n.textContent = t.labels.panelTitle); | ||
| const r = e.querySelector('[data-action="close"]'); | ||
| r && r.setAttribute("aria-label", t.labels.closeText); | ||
| const i = e.querySelector('[data-action="run-scan"]'); | ||
| i && (i.textContent = t.labels.scanText); | ||
| const o = e.querySelector('[data-action="redact-all"]'); | ||
| o && (o.textContent = t.labels.redactAllText); | ||
| const a = e.querySelector(".rte-pii-redaction-shortcut"); | ||
| a && (a.textContent = t.labels.shortcutText); | ||
| } | ||
| function H(e) { | ||
| const t = m.get(e); | ||
| if (!t) return; | ||
| const n = f.get(e) || A; | ||
| if (!n) return; | ||
| const r = I.get(e) || [], i = E.get(e) || le(0), o = V(e), a = t.querySelector(".rte-pii-redaction-count"), l = t.querySelector(".rte-pii-redaction-summary"), c = t.querySelector(".rte-pii-redaction-list"), d = t.querySelector('[data-action="redact-all"]'); | ||
| if (!(!a || !l || !c || !d)) { | ||
| if (a.textContent = String(i.total), l.textContent = `${n.labels.summaryPrefix}: ${i.total} | High ${i.high} | Medium ${i.medium} | Low ${i.low} | Redacted ${i.redactedCount}`, d.disabled = o || r.length === 0, o ? ie(t, n.labels.readonlyRedactionText) : ie(t, `${i.total} PII findings detected.`), z(e, t, n), r.length === 0) { | ||
| c.innerHTML = `<li class="rte-pii-redaction-empty">${p(n.labels.noFindingsText)}</li>`; | ||
| return; | ||
| } | ||
| c.innerHTML = r.map((s) => { | ||
| const b = s.type.toUpperCase(), M = s.suggestion || "Redact this finding before export/share.", B = `${n.labels.locateText}: ${s.match}`, y = `${n.labels.redactText}: ${s.match}`, U = o ? 'disabled aria-disabled="true"' : ""; | ||
| return ` | ||
| <li class="rte-pii-redaction-item rte-pii-redaction-item-${s.severity}"> | ||
| <button | ||
| type="button" | ||
| class="rte-pii-redaction-item-btn" | ||
| data-action="locate-finding" | ||
| data-finding-id="${p(s.id)}" | ||
| data-role="finding-button" | ||
| aria-label="${p(B)}" | ||
| > | ||
| <span class="rte-pii-redaction-badge">${p(s.severity.toUpperCase())}</span> | ||
| <span class="rte-pii-redaction-type">${p(b)}</span> | ||
| </button> | ||
| <p class="rte-pii-redaction-line"><strong>${p(n.labels.matchLabel)}:</strong> ${p(ue(s.match, 80))}</p> | ||
| <p class="rte-pii-redaction-line"><strong>${p(n.labels.maskedLabel)}:</strong> ${p(ue(s.masked, 80))}</p> | ||
| ${s.excerpt ? `<p class="rte-pii-redaction-line"><strong>${p(n.labels.excerptLabel)}:</strong> ${p(s.excerpt)}</p>` : ""} | ||
| <p class="rte-pii-redaction-help">${p(M)}</p> | ||
| <div class="rte-pii-redaction-item-actions"> | ||
| <button type="button" class="rte-pii-redaction-btn" data-action="redact-finding" data-finding-id="${p( | ||
| s.id | ||
| )}" aria-label="${p(y)}" ${U}>${p(n.labels.redactText)}</button> | ||
| </div> | ||
| </li> | ||
| `; | ||
| }).join(""); | ||
| } | ||
| } | ||
| function fe(e, t) { | ||
| if (!t.classList.contains("show")) return; | ||
| const r = ge(e).getBoundingClientRect(), i = Math.min(window.innerWidth - 20, 390), o = Math.max(10, window.innerWidth - i - 10), a = Math.min(Math.max(10, r.right - i), o), l = Math.max(10, Math.min(window.innerHeight - 10 - 280, r.top + 10)); | ||
| t.style.width = `${i}px`, t.style.left = `${a}px`, t.style.top = `${l}px`, t.style.maxHeight = `${Math.max(260, window.innerHeight - 20)}px`; | ||
| } | ||
| function F(e, t) { | ||
| const n = S.get(e); | ||
| return typeof n == "boolean" ? n : t ? t.enableRealtime : !0; | ||
| } | ||
| function Re(e, t) { | ||
| if (t === e.innerHTML) return; | ||
| const n = window.execEditorCommand || window.executeEditorCommand; | ||
| if (typeof n == "function") | ||
| try { | ||
| n("recordDomTransaction", e, t, e.innerHTML); | ||
| } catch { | ||
| } | ||
| } | ||
| function Se(e) { | ||
| e.dispatchEvent(new Event("input", { bubbles: !0 })); | ||
| } | ||
| function Ae(e, t) { | ||
| e.dispatchEvent( | ||
| new CustomEvent("editora:pii-redacted", { | ||
| bubbles: !0, | ||
| detail: { | ||
| redactedCount: t | ||
| } | ||
| }) | ||
| ); | ||
| } | ||
| function Me(e, t) { | ||
| return (I.get(e) || []).find((r) => r.id === t); | ||
| } | ||
| function rt(e) { | ||
| const t = m.get(e); | ||
| if (t) return t; | ||
| const n = f.get(e) || A || ee(), r = `rte-pii-redaction-panel-${Fe++}`, i = document.createElement("section"); | ||
| return i.className = u, i.id = r, i.setAttribute("role", "dialog"), i.setAttribute("aria-modal", "false"), i.setAttribute("aria-label", n.labels.panelAriaLabel), i.innerHTML = ` | ||
| <header class="rte-pii-redaction-header"> | ||
| <h2 class="rte-pii-redaction-title">${p(n.labels.panelTitle)}</h2> | ||
| <button type="button" class="rte-pii-redaction-icon-btn" data-action="close" aria-label="${p( | ||
| n.labels.closeText | ||
| )}">✕</button> | ||
| </header> | ||
| <div class="rte-pii-redaction-body"> | ||
| <div class="rte-pii-redaction-topline"> | ||
| <p class="rte-pii-redaction-summary" aria-live="polite"></p> | ||
| <span class="rte-pii-redaction-count" aria-hidden="true">0</span> | ||
| </div> | ||
| <div class="rte-pii-redaction-controls" role="toolbar" aria-label="PII redaction controls"> | ||
| <button type="button" class="rte-pii-redaction-btn rte-pii-redaction-btn-primary" data-action="run-scan">${p( | ||
| n.labels.scanText | ||
| )}</button> | ||
| <button type="button" class="rte-pii-redaction-btn" data-action="redact-all">${p( | ||
| n.labels.redactAllText | ||
| )}</button> | ||
| <button type="button" class="rte-pii-redaction-btn" data-action="toggle-realtime" aria-pressed="false"></button> | ||
| </div> | ||
| <ul class="rte-pii-redaction-list" role="list" aria-label="Detected PII findings"></ul> | ||
| <p class="rte-pii-redaction-shortcut">${p(n.labels.shortcutText)}</p> | ||
| <span class="rte-pii-redaction-live" aria-live="polite"></span> | ||
| </div> | ||
| `, i.addEventListener("click", (o) => { | ||
| const l = o.target?.closest("[data-action]"); | ||
| if (!l) return; | ||
| const c = l.getAttribute("data-action") || "", d = f.get(e) || A || n; | ||
| if (f.set(e, d), w(e, d), c === "close") { | ||
| j(e, !0); | ||
| return; | ||
| } | ||
| if (c === "run-scan") { | ||
| h(e, d, !0); | ||
| return; | ||
| } | ||
| if (c === "toggle-realtime") { | ||
| const s = !F(e, d); | ||
| S.set(e, s), z(e, i, d), s && h(e, d, !0); | ||
| return; | ||
| } | ||
| if (c === "redact-all") { | ||
| xe(e, d); | ||
| return; | ||
| } | ||
| if (c === "locate-finding") { | ||
| const s = l.getAttribute("data-finding-id") || "", b = Me(e, s); | ||
| if (!b) return; | ||
| at(e, b, d); | ||
| return; | ||
| } | ||
| if (c === "redact-finding") { | ||
| const s = l.getAttribute("data-finding-id") || ""; | ||
| De(e, s, d); | ||
| } | ||
| }), i.addEventListener("keydown", (o) => { | ||
| if (o.key === "Escape") { | ||
| o.preventDefault(), j(e, !0); | ||
| return; | ||
| } | ||
| if (o.key !== "ArrowDown" && o.key !== "ArrowUp") return; | ||
| const a = Array.from(i.querySelectorAll('[data-role="finding-button"]')); | ||
| if (a.length === 0) return; | ||
| const l = document.activeElement, c = a.findIndex((b) => b === l); | ||
| if (c === -1) return; | ||
| o.preventDefault(); | ||
| const d = o.key === "ArrowDown" ? 1 : -1, s = (c + d + a.length) % a.length; | ||
| a[s].focus(); | ||
| }), ne(i, e), document.body.appendChild(i), m.set(e, i), Z.set(e, !1), H(e), i; | ||
| } | ||
| function j(e, t = !1) { | ||
| const n = m.get(e); | ||
| n && (n.classList.remove("show"), Z.set(e, !1), C(e, "togglePIIRedactionPanel", !1), t && e.focus({ preventScroll: !0 })); | ||
| } | ||
| function N(e) { | ||
| K(); | ||
| const t = rt(e); | ||
| m.forEach((r, i) => { | ||
| i !== e && j(i, !1); | ||
| }), t.classList.add("show"), Z.set(e, !0), C(e, "togglePIIRedactionPanel", !0), ne(t, e), fe(e, t), H(e), t.querySelector('[data-action="run-scan"]')?.focus(); | ||
| } | ||
| function Pe(e, t) { | ||
| const n = oe(e); | ||
| return (typeof t == "boolean" ? t : !n) ? N(e) : j(e), !0; | ||
| } | ||
| function ot(e, t) { | ||
| const n = t.normalizeText(e.innerText || e.textContent || ""), r = e.innerHTML; | ||
| return `${n.length}:${ve(n)}:${r.length}:${ve(r)}:${t.detectorSignature}`; | ||
| } | ||
| function it(e, t) { | ||
| const n = [], r = be(e.pattern); | ||
| let i = r.exec(t); | ||
| for (; i; ) { | ||
| const o = i[0] || "", a = i.index, l = a + o.length; | ||
| o && l > a && (!e.validator || e.validator(o)) && n.push({ value: o, start: a, end: l }), r.lastIndex === i.index && (r.lastIndex += 1), i = r.exec(t); | ||
| } | ||
| return n; | ||
| } | ||
| function Le(e, t, n) { | ||
| const r = n.detectors.find((c) => c.type === t.type && c.enabled); | ||
| if (!r) return null; | ||
| const i = t.match.toLowerCase(); | ||
| let o = 0; | ||
| const a = document.createTreeWalker(e, pe, null); | ||
| let l = a.nextNode(); | ||
| for (; l; ) { | ||
| if (!he(l, n)) { | ||
| const c = it(r, l.data); | ||
| for (let d = 0; d < c.length; d += 1) { | ||
| const s = c[d]; | ||
| if (s.value.toLowerCase() === i && (o += 1, o === t.occurrence)) { | ||
| const b = document.createRange(); | ||
| return b.setStart(l, s.start), b.setEnd(l, s.end), b; | ||
| } | ||
| } | ||
| } | ||
| l = a.nextNode(); | ||
| } | ||
| return null; | ||
| } | ||
| function at(e, t, n) { | ||
| const r = Le(e, t, n); | ||
| if (!r) return !1; | ||
| const i = window.getSelection(); | ||
| return i ? (i.removeAllRanges(), i.addRange(r), re(r.startContainer)?.scrollIntoView({ behavior: "smooth", block: "center", inline: "nearest" }), e.focus({ preventScroll: !0 }), !0) : !1; | ||
| } | ||
| async function h(e, t, n = !1) { | ||
| w(e, t); | ||
| const r = ot(e, t); | ||
| if (!n && de.get(e) === r) | ||
| return I.get(e) || []; | ||
| const i = (Q.get(e) || 0) + 1; | ||
| Q.set(e, i); | ||
| const o = [], a = /* @__PURE__ */ new Map(), l = document.createTreeWalker(e, pe, null); | ||
| let c = l.nextNode(); | ||
| for (; c && o.length < t.maxFindings; ) { | ||
| const b = c.data || ""; | ||
| if (b.trim() && !he(c, t)) { | ||
| const M = Qe(b, t.detectors, t.maxFindings - o.length); | ||
| for (let B = 0; B < M.length && !(o.length >= t.maxFindings); B += 1) { | ||
| const y = M[B], U = `${y.type}:${y.value.toLowerCase()}`, ye = (a.get(U) || 0) + 1; | ||
| a.set(U, ye), o.push({ | ||
| id: Xe(y.type), | ||
| type: y.type, | ||
| severity: y.severity, | ||
| match: y.value, | ||
| masked: Te(y.value, y.type, t), | ||
| occurrence: ye, | ||
| excerpt: et(b, y.start, y.end), | ||
| suggestion: "Review and redact this value before external sharing." | ||
| }); | ||
| } | ||
| } | ||
| c = l.nextNode(); | ||
| } | ||
| if (Q.get(e) !== i) | ||
| return I.get(e) || []; | ||
| const d = E.get(e)?.redactedCount || 0, s = tt(o, d); | ||
| return de.set(e, r), I.set(e, o), E.set(e, s), H(e), e.dispatchEvent( | ||
| new CustomEvent("editora:pii-scan", { | ||
| bubbles: !0, | ||
| detail: { | ||
| findings: o, | ||
| stats: s | ||
| } | ||
| }) | ||
| ), o; | ||
| } | ||
| function lt(e, t) { | ||
| let n = e, r = 0; | ||
| return t.detectors.filter((o) => o.enabled).forEach((o) => { | ||
| const a = be(o.pattern); | ||
| n = n.replace(a, (l) => o.validator && !o.validator(l) ? l : (r += 1, Ce(l, o.type, t))); | ||
| }), { nextValue: n, count: r }; | ||
| } | ||
| async function De(e, t, n) { | ||
| if (V(e)) { | ||
| const d = m.get(e); | ||
| return d && ie(d, n.labels.readonlyRedactionText), !1; | ||
| } | ||
| const r = Me(e, t); | ||
| if (!r) return !1; | ||
| const i = Le(e, r, n); | ||
| if (!i) return !1; | ||
| const o = e.innerHTML, a = Ce(r.match, r.type, n); | ||
| if (i.startContainer === i.endContainer && i.startContainer.nodeType === Node.TEXT_NODE) { | ||
| const d = i.startContainer, s = d.data, b = i.startOffset, M = i.endOffset; | ||
| d.data = `${s.slice(0, b)}${a}${s.slice(M)}`; | ||
| } else | ||
| i.deleteContents(), i.insertNode(document.createTextNode(a)); | ||
| Se(e), Re(e, o); | ||
| const l = E.get(e)?.redactedCount || 0; | ||
| await h(e, n, !0); | ||
| const c = E.get(e); | ||
| return c && (c.redactedCount = l + 1, H(e)), Ae(e, 1), !0; | ||
| } | ||
| async function xe(e, t) { | ||
| if (V(e)) { | ||
| const d = m.get(e); | ||
| return d && ie(d, t.labels.readonlyRedactionText), 0; | ||
| } | ||
| (I.get(e) || []).length === 0 && await h(e, t, !0); | ||
| const r = e.innerHTML; | ||
| let i = 0; | ||
| const o = document.createTreeWalker(e, pe, null); | ||
| let a = o.nextNode(); | ||
| for (; a; ) { | ||
| if (he(a, t)) { | ||
| a = o.nextNode(); | ||
| continue; | ||
| } | ||
| const d = a.data || ""; | ||
| if (!d) { | ||
| a = o.nextNode(); | ||
| continue; | ||
| } | ||
| const s = lt(d, t); | ||
| s.count > 0 && s.nextValue !== d && (a.data = s.nextValue, i += s.count), a = o.nextNode(); | ||
| } | ||
| if (i === 0) return 0; | ||
| Se(e), Re(e, r); | ||
| const l = E.get(e)?.redactedCount || 0; | ||
| await h(e, t, !0); | ||
| const c = E.get(e); | ||
| return c && (c.redactedCount = l + i, H(e)), Ae(e, i), i; | ||
| } | ||
| function _e(e) { | ||
| const t = f.get(e) || A; | ||
| if (!t || !F(e, t) || V(e)) return; | ||
| me(e); | ||
| const n = window.setTimeout(() => { | ||
| W.delete(n), te.delete(e), h(e, t, !1); | ||
| }, t.debounceMs); | ||
| W.add(n), te.set(e, n); | ||
| } | ||
| function ct(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "i"; | ||
| } | ||
| function st(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "u"; | ||
| } | ||
| function dt(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "m"; | ||
| } | ||
| function ut(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "y"; | ||
| } | ||
| function ft(e) { | ||
| const t = re(e.target); | ||
| if (t) { | ||
| const r = t.closest(x); | ||
| if (r) return r; | ||
| const i = t.closest(ae); | ||
| if (i) { | ||
| const a = O(i); | ||
| if (a) return a; | ||
| } | ||
| const o = t.closest(`.${u}`); | ||
| if (o) { | ||
| const a = Array.from(m.entries()).find(([, l]) => l === o); | ||
| if (a) return a[0]; | ||
| } | ||
| } | ||
| const n = window.getSelection(); | ||
| if (n && n.rangeCount > 0) { | ||
| const r = re(n.getRangeAt(0).startContainer)?.closest( | ||
| x | ||
| ); | ||
| if (r) return r; | ||
| } | ||
| return null; | ||
| } | ||
| function pt() { | ||
| if (typeof document > "u" || document.getElementById(we)) return; | ||
| const e = document.createElement("style"); | ||
| e.id = we, e.textContent = ` | ||
| .rte-toolbar-group-items.${k}, | ||
| .editora-toolbar-group-items.${k}, | ||
| .rte-toolbar-group-items.${v}, | ||
| .editora-toolbar-group-items.${v} { | ||
| display: flex; | ||
| border: 1px solid #ccc; | ||
| border-radius: 3px; | ||
| background: #fff; | ||
| } | ||
| .rte-toolbar-group-items.${k} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${k} .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${v} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${v} .editora-toolbar-button { | ||
| border: none; | ||
| border-radius: 0; | ||
| border-right: 1px solid #ccc; | ||
| } | ||
| .rte-toolbar-group-items.${k} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${k} .editora-toolbar-item:last-child .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${v} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${v} .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| .rte-toolbar-button[data-command="togglePIIRealtime"].active, | ||
| .editora-toolbar-button[data-command="togglePIIRealtime"].active { | ||
| background-color: #ccc; | ||
| } | ||
| ${$} .rte-toolbar-group-items.${k}, | ||
| ${$} .editora-toolbar-group-items.${k}, | ||
| ${$} .rte-toolbar-group-items.${v}, | ||
| ${$} .editora-toolbar-group-items.${v}, | ||
| .${u}.rte-pii-redaction-theme-dark { | ||
| border-color: #566275; | ||
| } | ||
| ${$} .rte-toolbar-group-items.${k} .rte-toolbar-button svg, | ||
| ${$} .editora-toolbar-group-items.${k} .editora-toolbar-button svg, | ||
| ${$} .rte-toolbar-group-items.${v} .rte-toolbar-button svg, | ||
| ${$} .editora-toolbar-group-items.${v} .editora-toolbar-button svg | ||
| { | ||
| fill: none; | ||
| } | ||
| ${$} .rte-toolbar-group-items.${k} .rte-toolbar-button, | ||
| ${$} .editora-toolbar-group-items.${k} .editora-toolbar-button | ||
| { | ||
| border-color: #566275; | ||
| } | ||
| .${u} { | ||
| position: fixed; | ||
| z-index: 12000; | ||
| display: none; | ||
| width: min(390px, calc(100vw - 20px)); | ||
| max-height: calc(100vh - 20px); | ||
| border: 1px solid #d1d5db; | ||
| border-radius: 14px; | ||
| background: #ffffff; | ||
| color: #111827; | ||
| box-shadow: 0 18px 45px rgba(15, 23, 42, 0.25); | ||
| overflow: hidden; | ||
| } | ||
| .${u}.show { | ||
| display: flex; | ||
| flex-direction: column; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark { | ||
| border-color: #334155; | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| box-shadow: 0 20px 46px rgba(2, 6, 23, 0.68); | ||
| } | ||
| .rte-pii-redaction-header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| padding: 12px 14px; | ||
| border-bottom: 1px solid #e5e7eb; | ||
| background: linear-gradient(180deg, #f9fafb 0%, #f3f4f6 100%); | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-header { | ||
| border-color: #1e293b; | ||
| background: linear-gradient(180deg, #111827 0%, #0f172a 100%); | ||
| } | ||
| .rte-pii-redaction-title { | ||
| margin: 0; | ||
| font-size: 15px; | ||
| line-height: 1.2; | ||
| font-weight: 700; | ||
| } | ||
| .rte-pii-redaction-icon-btn { | ||
| width: 34px; | ||
| height: 34px; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| font-weight: 600; | ||
| padding: 0; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| cursor: pointer; | ||
| } | ||
| .rte-pii-redaction-icon-btn:hover, | ||
| .rte-pii-redaction-icon-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-icon-btn { | ||
| background: #0f172a; | ||
| border-color: #475569; | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-icon-btn:hover, | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-icon-btn:focus-visible { | ||
| border-color: #60a5fa; | ||
| box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.24); | ||
| } | ||
| .rte-pii-redaction-body { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 10px; | ||
| padding: 12px; | ||
| overflow: auto; | ||
| } | ||
| .rte-pii-redaction-topline { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| } | ||
| .rte-pii-redaction-summary { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #475569; | ||
| flex: 1; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-summary { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-pii-redaction-count { | ||
| min-width: 32px; | ||
| height: 32px; | ||
| border-radius: 999px; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| font-weight: 700; | ||
| font-size: 13px; | ||
| border: 1px solid #cbd5e1; | ||
| background: #f8fafc; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-count { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-pii-redaction-controls { | ||
| display: flex; | ||
| gap: 8px; | ||
| flex-wrap: wrap; | ||
| } | ||
| .rte-pii-redaction-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| height: 34px; | ||
| padding: 0 10px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| cursor: pointer; | ||
| } | ||
| .rte-pii-redaction-btn:hover, | ||
| .rte-pii-redaction-btn:focus-visible { | ||
| border-color: #94a3b8; | ||
| background: #f8fafc; | ||
| outline: none; | ||
| } | ||
| .rte-pii-redaction-btn:disabled { | ||
| opacity: 0.56; | ||
| cursor: not-allowed; | ||
| } | ||
| .rte-pii-redaction-btn-primary { | ||
| border-color: #0284c7; | ||
| background: #0ea5e9; | ||
| color: #f8fafc; | ||
| } | ||
| .rte-pii-redaction-btn-primary:hover, | ||
| .rte-pii-redaction-btn-primary:focus-visible { | ||
| border-color: #0369a1; | ||
| background: #0284c7; | ||
| color: #ffffff; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-btn { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-btn:hover, | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-btn:focus-visible { | ||
| border-color: #475569; | ||
| background: #1e293b; | ||
| } | ||
| .rte-pii-redaction-list { | ||
| list-style: none; | ||
| margin: 0; | ||
| padding: 0; | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 8px; | ||
| max-height: min(55vh, 420px); | ||
| overflow: auto; | ||
| } | ||
| .rte-pii-redaction-item { | ||
| border: 1px solid #e2e8f0; | ||
| border-radius: 10px; | ||
| padding: 8px; | ||
| background: #ffffff; | ||
| display: grid; | ||
| gap: 6px; | ||
| } | ||
| .rte-pii-redaction-item-high { | ||
| border-color: #fca5a5; | ||
| background: #fef2f2; | ||
| } | ||
| .rte-pii-redaction-item-medium { | ||
| border-color: #fcd34d; | ||
| background: #fffbeb; | ||
| } | ||
| .rte-pii-redaction-item-low { | ||
| border-color: #93c5fd; | ||
| background: #eff6ff; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-item { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-item-high { | ||
| border-color: #7f1d1d; | ||
| background: #2b0b11; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-item-medium { | ||
| border-color: #78350f; | ||
| background: #2b1907; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-item-low { | ||
| border-color: #1d4ed8; | ||
| background: #0a162f; | ||
| } | ||
| .rte-pii-redaction-item-btn { | ||
| border: none; | ||
| background: transparent; | ||
| width: 100%; | ||
| display: flex; | ||
| align-items: center; | ||
| gap: 8px; | ||
| text-align: left; | ||
| padding: 0; | ||
| color: inherit; | ||
| cursor: pointer; | ||
| } | ||
| .rte-pii-redaction-item-btn:focus-visible { | ||
| outline: 2px solid #0284c7; | ||
| outline-offset: 3px; | ||
| border-radius: 6px; | ||
| } | ||
| .rte-pii-redaction-badge { | ||
| border-radius: 999px; | ||
| border: 1px solid currentColor; | ||
| padding: 1px 8px; | ||
| font-size: 10px; | ||
| font-weight: 700; | ||
| line-height: 1.3; | ||
| text-transform: uppercase; | ||
| opacity: 0.86; | ||
| } | ||
| .rte-pii-redaction-type { | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| letter-spacing: 0.03em; | ||
| } | ||
| .rte-pii-redaction-line, | ||
| .rte-pii-redaction-help { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #334155; | ||
| word-break: break-word; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-line, | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-help { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-pii-redaction-item-actions { | ||
| display: flex; | ||
| justify-content: flex-end; | ||
| } | ||
| .rte-pii-redaction-empty { | ||
| border: 1px dashed #cbd5e1; | ||
| border-radius: 10px; | ||
| padding: 10px; | ||
| font-size: 13px; | ||
| color: #475569; | ||
| background: #f8fafc; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-empty { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #94a3b8; | ||
| } | ||
| .rte-pii-redaction-shortcut { | ||
| margin: 2px 0 0; | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| } | ||
| .${u}.rte-pii-redaction-theme-dark .rte-pii-redaction-shortcut { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-pii-redaction-live { | ||
| position: absolute; | ||
| width: 1px; | ||
| height: 1px; | ||
| margin: -1px; | ||
| padding: 0; | ||
| overflow: hidden; | ||
| clip: rect(0 0 0 0); | ||
| border: 0; | ||
| } | ||
| @media (max-width: 768px) { | ||
| .${u} { | ||
| left: 10px !important; | ||
| right: 10px; | ||
| top: 10px !important; | ||
| width: auto !important; | ||
| max-height: calc(100vh - 20px); | ||
| } | ||
| .rte-pii-redaction-list { | ||
| max-height: 45vh; | ||
| } | ||
| } | ||
| `, document.head.appendChild(e); | ||
| } | ||
| function bt(e) { | ||
| A = e, P || (P = (t) => { | ||
| K(); | ||
| const r = t.target?.closest(x); | ||
| if (!r) return; | ||
| g = r; | ||
| const i = f.get(r) || e; | ||
| w(r, i), f.set(r, i), C(r, "togglePIIRedactionPanel", oe(r)), C(r, "togglePIIRealtime", F(r, i)); | ||
| const o = m.get(r); | ||
| o && (ne(o, r), fe(r, o), z(r, o, i)); | ||
| }, document.addEventListener("focusin", P, !0)), L || (L = (t) => { | ||
| const r = t.target?.closest(x); | ||
| r && (g = r, _e(r)); | ||
| }, document.addEventListener("input", L, !0)), D || (D = (t) => { | ||
| if (t.defaultPrevented || t.target?.closest(`.${u} input, .${u} textarea, .${u} select`)) return; | ||
| const r = ft(t); | ||
| if (!r) return; | ||
| const i = f.get(r) || A || e; | ||
| if (w(r, i), f.set(r, i), g = r, t.key === "Escape" && oe(r)) { | ||
| t.preventDefault(), j(r, !0); | ||
| return; | ||
| } | ||
| if (ct(t)) { | ||
| t.preventDefault(), t.stopPropagation(), Pe(r); | ||
| return; | ||
| } | ||
| if (st(t)) { | ||
| t.preventDefault(), t.stopPropagation(), h(r, i, !0), N(r); | ||
| return; | ||
| } | ||
| if (dt(t)) { | ||
| t.preventDefault(), t.stopPropagation(), V(r) || (xe(r, i), N(r)); | ||
| return; | ||
| } | ||
| if (ut(t)) { | ||
| t.preventDefault(), t.stopPropagation(); | ||
| const o = !F(r, i); | ||
| S.set(r, o); | ||
| const a = m.get(r); | ||
| a && z(r, a, i), C(r, "togglePIIRealtime", o), o && h(r, i, !0); | ||
| } | ||
| }, document.addEventListener("keydown", D, !0)), R || (R = () => { | ||
| K(), m.forEach((t, n) => { | ||
| !n.isConnected || !t.isConnected || (ne(t, n), fe(n, t)); | ||
| }); | ||
| }, window.addEventListener("scroll", R, !0), window.addEventListener("resize", R)), !_ && typeof MutationObserver < "u" && document.body && (_ = new MutationObserver((t) => { | ||
| Ue(t) && K(); | ||
| }), _.observe(document.body, { | ||
| childList: !0, | ||
| subtree: !0 | ||
| })); | ||
| } | ||
| function gt() { | ||
| P && (document.removeEventListener("focusin", P, !0), P = null), L && (document.removeEventListener("input", L, !0), L = null), D && (document.removeEventListener("keydown", D, !0), D = null), R && (window.removeEventListener("scroll", R, !0), window.removeEventListener("resize", R), R = null), _ && (_.disconnect(), _ = null), m.forEach((e) => e.remove()), m.clear(), q.forEach((e) => me(e)), q.clear(), A = null, g = null; | ||
| } | ||
| const mt = (e = {}) => { | ||
| const t = ee(e), n = /* @__PURE__ */ new Set(); | ||
| return pt(), { | ||
| name: "piiRedaction", | ||
| toolbar: [ | ||
| { | ||
| id: "piiRedactionGroup", | ||
| label: "PII Redaction", | ||
| type: "group", | ||
| command: "piiRedaction", | ||
| items: [ | ||
| { | ||
| id: "piiRedaction", | ||
| label: "PII Redaction", | ||
| command: "togglePIIRedactionPanel", | ||
| shortcut: "Mod-Alt-Shift-i", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M12 3.5 19 6.5v4.8c0 4.4-2.7 8.1-7 9.2-4.3-1.1-7-4.8-7-9.2V6.5l7-3Z" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round"/><path d="M8.8 11.6h6.4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><circle cx="12" cy="11.6" r="1.2" fill="currentColor"/></svg>' | ||
| }, | ||
| { | ||
| id: "piiScan", | ||
| label: "Scan PII", | ||
| command: "runPIIScan", | ||
| shortcut: "Mod-Alt-Shift-u", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><rect x="4.5" y="3.5" width="11" height="15" rx="2" stroke="currentColor" stroke-width="1.6"/><path d="M7.5 8.2h5M7.5 11.2h5M7.5 14.2h3.2" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><circle cx="16.8" cy="16.8" r="2.8" stroke="currentColor" stroke-width="1.6"/><path d="m18.8 18.8 2 2" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>' | ||
| }, | ||
| { | ||
| id: "piiRedactAll", | ||
| label: "Redact All PII", | ||
| command: "redactAllPII", | ||
| shortcut: "Mod-Alt-Shift-m", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M5 18h14" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/><path d="M7 6h10l-1 8H8L7 6Z" stroke="currentColor" stroke-width="1.7"/><path d="m9 9 6 4" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/></svg>' | ||
| }, | ||
| { | ||
| id: "piiRealtime", | ||
| label: "Toggle Realtime PII Scan", | ||
| command: "togglePIIRealtime", | ||
| shortcut: "Mod-Alt-Shift-y", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M12 3v4M12 17v4M4 12h4M16 12h4" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/><circle cx="12" cy="12" r="4" stroke="currentColor" stroke-width="1.7"/></svg>' | ||
| } | ||
| ] | ||
| } | ||
| ], | ||
| commands: { | ||
| piiRedaction: (r, i) => { | ||
| const o = T(i); | ||
| if (!o) return !1; | ||
| const a = f.get(o) || t; | ||
| return w(o, a), f.set(o, a), g = o, N(o), h(o, a, !1), !0; | ||
| }, | ||
| togglePIIRedactionPanel: (r, i) => { | ||
| const o = T(i); | ||
| if (!o) return !1; | ||
| const a = f.get(o) || t; | ||
| w(o, a), f.set(o, a), g = o; | ||
| const l = Pe(o, typeof r == "boolean" ? r : void 0); | ||
| return oe(o) && h(o, a, !1), l; | ||
| }, | ||
| runPIIScan: async (r, i) => { | ||
| const o = T(i); | ||
| if (!o) return !1; | ||
| const a = f.get(o) || t; | ||
| return w(o, a), f.set(o, a), g = o, await h(o, a, !0), N(o), !0; | ||
| }, | ||
| redactAllPII: async (r, i) => { | ||
| const o = T(i); | ||
| if (!o) return !1; | ||
| const a = f.get(o) || t; | ||
| w(o, a), f.set(o, a), g = o; | ||
| const l = await xe(o, a); | ||
| return l > 0 && N(o), l > 0; | ||
| }, | ||
| redactPIIFinding: async (r, i) => { | ||
| const o = T(i); | ||
| if (!o || typeof r != "string" || !r) return !1; | ||
| const a = f.get(o) || t; | ||
| return w(o, a), f.set(o, a), g = o, De(o, r, a); | ||
| }, | ||
| togglePIIRealtime: (r, i) => { | ||
| const o = T(i); | ||
| if (!o) return !1; | ||
| const a = f.get(o) || t; | ||
| w(o, a), f.set(o, a); | ||
| const l = typeof r == "boolean" ? r : !F(o, a); | ||
| S.set(o, l); | ||
| const c = m.get(o); | ||
| return c && z(o, c, a), C(o, "togglePIIRealtime", l), l && h(o, a, !0), !0; | ||
| }, | ||
| getPIIRedactionFindings: (r, i) => { | ||
| const o = T(i); | ||
| if (!o) return !1; | ||
| const a = I.get(o) || [], l = E.get(o) || le(0), c = a.map((s) => ({ ...s })), d = { | ||
| ...l, | ||
| byType: { ...l.byType } | ||
| }; | ||
| if (typeof r == "function") | ||
| try { | ||
| r(c, d); | ||
| } catch { | ||
| } | ||
| return o.__piiRedactionFindings = c, o.dispatchEvent( | ||
| new CustomEvent("editora:pii-findings", { | ||
| bubbles: !0, | ||
| detail: { findings: c, stats: d } | ||
| }) | ||
| ), !0; | ||
| }, | ||
| setPIIRedactionOptions: (r, i) => { | ||
| const o = T(i); | ||
| if (!o || !r || typeof r != "object") return !1; | ||
| const a = f.get(o) || t, l = ee({ | ||
| ...ce(a), | ||
| ...r, | ||
| labels: { | ||
| ...a.labels, | ||
| ...r.labels || {} | ||
| }, | ||
| detectors: { | ||
| ...ce(a).detectors || {}, | ||
| ...r.detectors || {} | ||
| }, | ||
| normalizeText: r.normalizeText || a.normalizeText | ||
| }); | ||
| f.set(o, l), typeof r.enableRealtime == "boolean" && S.set(o, r.enableRealtime); | ||
| const c = m.get(o); | ||
| return c && (nt(c, l), H(o), z(o, c, l)), h(o, l, !0), !0; | ||
| } | ||
| }, | ||
| keymap: { | ||
| "Mod-Alt-Shift-i": "togglePIIRedactionPanel", | ||
| "Mod-Alt-Shift-I": "togglePIIRedactionPanel", | ||
| "Mod-Alt-Shift-u": "runPIIScan", | ||
| "Mod-Alt-Shift-U": "runPIIScan", | ||
| "Mod-Alt-Shift-m": "redactAllPII", | ||
| "Mod-Alt-Shift-M": "redactAllPII", | ||
| "Mod-Alt-Shift-y": "togglePIIRealtime", | ||
| "Mod-Alt-Shift-Y": "togglePIIRealtime" | ||
| }, | ||
| init: function(i) { | ||
| G += 1; | ||
| const o = this && typeof this.__pluginConfig == "object" ? ee({ ...ce(t), ...this.__pluginConfig }) : t; | ||
| bt(o); | ||
| const a = T( | ||
| i?.editorElement ? { editorElement: i.editorElement } : void 0, | ||
| !1 | ||
| ); | ||
| a && (g = a, n.add(a), w(a, o), f.set(a, o), C(a, "togglePIIRedactionPanel", !1), C(a, "togglePIIRealtime", o.enableRealtime), o.enableRealtime && _e(a)); | ||
| }, | ||
| destroy: () => { | ||
| n.forEach((r) => Ie(r)), n.clear(), G = Math.max(0, G - 1), !(G > 0) && (W.forEach((r) => { | ||
| window.clearTimeout(r); | ||
| }), W.clear(), gt()); | ||
| } | ||
| }; | ||
| }; | ||
| export { | ||
| mt as PIIRedactionPlugin | ||
| }; |
| "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});function H(e,t){const r=Array.from({length:t}).map(()=>"<th><p><br></p></th>").join(""),n=Array.from({length:e}).map(()=>`<tr>${Array.from({length:t}).map(()=>"<td><p><br></p></td>").join("")}</tr>`).join("");return`<table class="rte-table"><thead><tr>${r}</tr></thead><tbody>${n}</tbody></table><p><br></p>`}function q(){return[{id:"paragraph",label:"Paragraph",description:"Switch to paragraph text",command:"paragraph",keywords:["text","normal","p"]},{id:"h1",label:"Heading 1",description:"Large section heading",command:"heading1",keywords:["title","header","h1"]},{id:"h2",label:"Heading 2",description:"Medium section heading",command:"heading2",keywords:["subtitle","header","h2"]},{id:"h3",label:"Heading 3",description:"Small section heading",command:"heading3",keywords:["header","h3"]},{id:"bulleted-list",label:"Bulleted List",description:"Create a bullet list",command:"toggleBulletList",keywords:["list","ul","bullet"]},{id:"numbered-list",label:"Numbered List",description:"Create a numbered list",command:"toggleOrderedList",keywords:["list","ol","numbered"]},{id:"blockquote",label:"Blockquote",description:"Insert a quote block",command:"toggleBlockquote",keywords:["quote","citation"]},{id:"table-3x3",label:"Table 3x3",description:"Insert a 3 x 3 table",action:({insertHTML:e})=>e(H(3,3)),keywords:["table","grid","rows","columns"]},{id:"horizontal-rule",label:"Divider",description:"Insert a horizontal rule",command:"insertHorizontalRule",keywords:["hr","separator","line"]},{id:"bold",label:"Bold",description:"Toggle bold formatting",command:"toggleBold",keywords:["strong","b"]},{id:"italic",label:"Italic",description:"Toggle italic formatting",command:"toggleItalic",keywords:["emphasis","i"]},{id:"underline",label:"Underline",description:"Toggle underline formatting",command:"toggleUnderline",keywords:["u"]},{id:"strikethrough",label:"Strikethrough",description:"Toggle strikethrough formatting",command:"toggleStrikethrough",keywords:["strike","s"]},{id:"clear-formatting",label:"Clear Formatting",description:"Remove text formatting",command:"clearFormatting",keywords:["reset","plain"]}]}function $(e){const t=[],r=new Set;return e.forEach(n=>{const o=String(n.id||"").trim(),i=String(n.label||"").trim();!o||!i||r.has(o)||(r.add(o),t.push({...n,id:o,label:i,description:n.description?String(n.description):void 0,keywords:Array.isArray(n.keywords)?n.keywords.map(a=>String(a)).filter(Boolean):void 0}))}),t}function D(e){const t=(e.triggerChar||"/")[0]||"/",r=e.includeDefaultItems!==!1,n=r?[...e.items||[],...q()]:e.items||[];return{triggerChar:t,minChars:Math.max(0,e.minChars??0),maxQueryLength:Math.max(1,e.maxQueryLength??48),maxSuggestions:Math.max(1,e.maxSuggestions??10),requireBoundary:e.requireBoundary!==!1,includeDefaultItems:r,items:$(n),itemRenderer:e.itemRenderer,emptyStateText:e.emptyStateText||"No commands found",panelLabel:e.panelLabel||"Slash commands"}}const u='[data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark';let E=!1;function B(){if(E||typeof document>"u")return;E=!0;const e=document.createElement("style");e.id="rte-slash-commands-styles",e.textContent=` | ||
| .rte-slash-panel { | ||
| width: min(225px, calc(100vw - 16px)); | ||
| max-height: min(360px, calc(100vh - 24px)); | ||
| overflow: hidden; | ||
| border: 1px solid #d9dfeb; | ||
| border-radius: 0px; | ||
| background: #ffffff; | ||
| box-shadow: 0 18px 40px rgba(15, 23, 42, 0.2); | ||
| z-index: 2147483646; | ||
| } | ||
| .rte-slash-list { | ||
| max-height: min(340px, calc(100vh - 32px)); | ||
| overflow: auto; | ||
| padding: 0px; | ||
| display: grid; | ||
| gap: 1px; | ||
| } | ||
| .rte-slash-item { | ||
| width: 100%; | ||
| border: none; | ||
| background: transparent; | ||
| color: #0f172a; | ||
| border-radius: 0px; | ||
| padding: 6px 9px; | ||
| text-align: left; | ||
| display: grid; | ||
| gap: 0px; | ||
| cursor: pointer; | ||
| font: inherit; | ||
| } | ||
| .rte-slash-item:hover, | ||
| .rte-slash-item.active { | ||
| background: #eff6ff; | ||
| color: #1d4ed8; | ||
| } | ||
| .rte-slash-item-title { | ||
| font-size: 13px; | ||
| font-weight: 600; | ||
| line-height: 1.35; | ||
| } | ||
| .rte-slash-item-description { | ||
| font-size: 12px; | ||
| color: #64748b; | ||
| line-height: 1.35; | ||
| } | ||
| .rte-slash-item mark { | ||
| background: rgba(59, 130, 246, 0.16); | ||
| color: inherit; | ||
| padding: 0 2px; | ||
| border-radius: 3px; | ||
| } | ||
| .rte-slash-empty { | ||
| font-size: 13px; | ||
| color: #64748b; | ||
| text-align: center; | ||
| padding: 12px; | ||
| } | ||
| ${u} .rte-slash-panel { | ||
| border-color: #364152; | ||
| background: #1f2937; | ||
| box-shadow: 0 22px 44px rgba(0, 0, 0, 0.48); | ||
| } | ||
| ${u} .rte-slash-item { | ||
| color: #e5e7eb; | ||
| } | ||
| ${u} .rte-slash-item:hover, | ||
| ${u} .rte-slash-item.active { | ||
| background: #334155; | ||
| color: #bfdbfe; | ||
| } | ||
| ${u} .rte-slash-item-description, | ||
| ${u} .rte-slash-empty { | ||
| color: #9ca3af; | ||
| } | ||
| `,document.head.appendChild(e)}const s=".rte-content, .editora-content",g=new WeakMap,p=new WeakMap;let b=!1,f=null,h=0,z=0;function P(e){return e?e.nodeType===Node.ELEMENT_NODE?e:e.parentElement:null}function I(e){return e.closest("[data-editora-editor], .rte-editor, .editora-editor, editora-editor")||e}function _(e){if(e?.contentElement instanceof HTMLElement)return e.contentElement;if(e?.editorElement instanceof HTMLElement){const n=e.editorElement;if(n.matches(s))return n;const o=n.querySelector(s);if(o instanceof HTMLElement)return o}const t=window.getSelection();if(t&&t.rangeCount>0){const n=t.getRangeAt(0).startContainer,i=(n.nodeType===Node.ELEMENT_NODE?n:n.parentElement)?.closest(s);if(i)return i}const r=document.activeElement;if(r){if(r.matches(s))return r;const n=r.closest(s);if(n)return n}return document.querySelector(s)}function m(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function F(e){return e?/\s|[([{"'`]/.test(e):!0}function v(e){const t=window.getSelection();if(!t||t.rangeCount===0)return null;const r=t.getRangeAt(0);return e.contains(r.commonAncestorContainer)?r.cloneRange():null}function y(e,t){const r=window.getSelection();r&&(r.removeAllRanges(),r.addRange(t),e.focus({preventScroll:!0}))}function j(e){if(!e.collapsed)return null;const t=e.startContainer,r=e.startOffset;if(t.nodeType===Node.TEXT_NODE){const n=t;return{node:n,textBefore:n.data.slice(0,r),caretOffset:r}}if(t.nodeType===Node.ELEMENT_NODE){const n=t;if(r>0){const o=n.childNodes[r-1];if(o&&o.nodeType===Node.TEXT_NODE){const i=o;return{node:i,textBefore:i.data,caretOffset:i.length}}}}return null}function K(e,t,r,n){const o=e.lastIndexOf(t);if(o<0||n&&!F(e[o-1]))return null;const i=e.slice(o+1);return/\s/.test(i)||i.length>r?null:{trigger:t,query:i,startOffset:o}}function Q(e,t){const r=t.cloneRange();r.collapse(!1);const n=r.getClientRects();if(n.length>0)return n[n.length-1];const o=document.createElement("span");o.textContent="",r.insertNode(o);const i=o.getBoundingClientRect();return o.remove(),e.normalize(),i}function A(e,t){if(!e.panel)return;const r=Q(e.editor,t),n=e.panel;n.style.display="block",n.classList.add("show"),n.style.left="0px",n.style.top="0px";const o=n.getBoundingClientRect(),i=window.innerWidth,a=window.innerHeight;let l=Math.max(8,Math.min(r.left,i-o.width-8)),d=r.bottom+8;d+o.height>a-8&&(d=Math.max(8,r.top-o.height-8)),n.style.position="fixed",n.style.left=`${l}px`,n.style.top=`${d}px`}function k(e,t){if(!t)return m(e);const r=e.toLowerCase(),n=t.toLowerCase(),o=r.indexOf(n);if(o<0)return m(e);const i=m(e.slice(0,o)),a=m(e.slice(o,o+t.length)),l=m(e.slice(o+t.length));return`${i}<mark>${a}</mark>${l}`}function U(e,t){if(e.panel&&e.list)return;const r=document.createElement("div");r.className="rte-slash-panel",r.style.display="none",r.setAttribute("role","dialog"),r.setAttribute("aria-modal","false");const n=document.createElement("div");n.className="rte-slash-list",n.setAttribute("role","listbox"),n.setAttribute("aria-label",t.panelLabel),r.appendChild(n),document.body.appendChild(r),e.panel=r,e.list=n,r.addEventListener("mousedown",o=>{o.preventDefault()}),r.addEventListener("click",o=>{const i=o.target;if(!i)return;const a=i.closest(".rte-slash-item");if(!a)return;const l=Number(a.getAttribute("data-index"));Number.isFinite(l)&&M(e,l)})}function c(e){e.panel&&(e.panel.style.display="none",e.panel.classList.remove("show"),e.isOpen=!1,e.filteredItems=[],e.activeIndex=0,e.query="",e.replaceRange=null,e.anchorRange=null)}function W(e,t,r){if(!t)return e.slice(0,r);const n=t.toLowerCase();return e.filter(i=>[i.id,i.label,i.description||"",i.command||"",...i.keywords||[]].join(" ").toLowerCase().includes(n)).slice(0,r)}function Z(e,t){if(!e.list)return;const r=e.list;if(r.innerHTML="",e.filteredItems.length===0){const n=document.createElement("div");n.className="rte-slash-empty",n.textContent=t.emptyStateText,r.appendChild(n),r.removeAttribute("aria-activedescendant");return}e.filteredItems.forEach((n,o)=>{const i=document.createElement("button");i.type="button",i.className="rte-slash-item",i.setAttribute("role","option"),i.setAttribute("data-index",String(o)),i.setAttribute("id",`rte-slash-item-${e.instanceId}-${o}`),i.setAttribute("aria-selected",o===e.activeIndex?"true":"false"),i.setAttribute("aria-label",n.description?`${n.label} - ${n.description}`:n.label),o===e.activeIndex&&i.classList.add("active"),t.itemRenderer?i.innerHTML=t.itemRenderer(n,e.query):i.innerHTML=` | ||
| <span class="rte-slash-item-title">${k(n.label,e.query)}</span> | ||
| ${n.description?`<span class="rte-slash-item-description">${k(n.description,e.query)}</span>`:""} | ||
| `,r.appendChild(i)}),e.filteredItems.length>0&&r.setAttribute("aria-activedescendant",`rte-slash-item-${e.instanceId}-${e.activeIndex}`)}function G(e,t){if(t===e.innerHTML)return;const r=window.execEditorCommand||window.executeEditorCommand;if(typeof r=="function")try{r("recordDomTransaction",e,t,e.innerHTML)}catch{}}function V(e){e.dispatchEvent(new Event("input",{bubbles:!0}))}function L(e,t){e.focus({preventScroll:!0});try{if(document.execCommand("insertHTML",!1,t))return!0}catch{}const r=window.getSelection();if(!r||r.rangeCount===0)return!1;const n=r.getRangeAt(0);if(!e.contains(n.commonAncestorContainer))return!1;n.deleteContents();const o=document.createElement("template");o.innerHTML=t;const i=o.content,a=i.lastChild;if(n.insertNode(i),a){const l=document.createRange();l.setStartAfter(a),l.collapse(!0),y(e,l)}return!0}function X(e,t){e.focus({preventScroll:!0});try{if(document.execCommand("insertText",!1,t))return!0}catch{}const r=window.getSelection();if(!r||r.rangeCount===0)return!1;const n=r.getRangeAt(0);if(!e.contains(n.commonAncestorContainer))return!1;n.deleteContents();const o=document.createTextNode(t);n.insertNode(o);const i=document.createRange();return i.setStart(o,o.length),i.collapse(!0),y(e,i),!0}function J(e,t){switch(e.toLowerCase()){case"paragraph":case"p":return document.execCommand("formatBlock",!1,"<p>");case"heading1":case"h1":return document.execCommand("formatBlock",!1,"<h1>");case"heading2":case"h2":return document.execCommand("formatBlock",!1,"<h2>");case"heading3":case"h3":return document.execCommand("formatBlock",!1,"<h3>");case"blockquote":case"toggleblockquote":return document.execCommand("formatBlock",!1,"<blockquote>");case"bulletlist":case"togglebulletlist":case"insertunorderedlist":return document.execCommand("insertUnorderedList");case"numberedlist":case"toggleorderedlist":case"insertorderedlist":return document.execCommand("insertOrderedList");case"horizontalrule":case"divider":case"inserthorizontalrule":return document.execCommand("insertHorizontalRule");case"bold":case"togglebold":return document.execCommand("bold");case"italic":case"toggleitalic":return document.execCommand("italic");case"underline":case"toggleunderline":return document.execCommand("underline");case"strikethrough":case"togglestrikethrough":return document.execCommand("strikeThrough");case"clearformatting":case"removeformat":return document.execCommand("removeFormat");default:try{return document.execCommand(e,!1,t)}catch{return!1}}}function S(e,t,r){const n=I(e);if(n&&typeof n.execCommand=="function")try{if(n.execCommand(t,r)!==!1)return!0}catch{}const o=window.execEditorCommand||window.executeEditorCommand;if(typeof o=="function")try{if(o(t,r,{editorElement:n,contentElement:e})!==!1)return!0}catch{}return J(t,r)}async function Y(e,t){const r=e.editor,n=I(r),o={editor:r,editorRoot:n,query:e.query,trigger:e.trigger,executeCommand:(i,a)=>S(r,i,a),insertHTML:i=>L(r,i)};return t.action?await Promise.resolve(t.action(o))!==!1:t.insertHTML?L(r,t.insertHTML):t.command?S(r,t.command,t.commandValue):!1}async function M(e,t){if(t<0||t>=e.filteredItems.length||!e.replaceRange)return;const r=e.filteredItems[t],n=e.editor,o=n.innerHTML,i=`${e.trigger}${e.query}`;if(!window.getSelection())return;const l=e.replaceRange.cloneRange();if(!n.contains(l.commonAncestorContainer))return;l.deleteContents();const d=l.cloneRange();d.collapse(!0),y(n,d);let x=!1;try{x=await Y(e,r)}catch{x=!1}c(e),x?(V(n),G(n,o)):i&&X(n,i),n.focus({preventScroll:!0})}function R(e,t){if(e.filteredItems.length===0)return;const r=e.filteredItems.length;if(e.activeIndex=((e.activeIndex+t)%r+r)%r,!e.list)return;const n=Array.from(e.list.querySelectorAll(".rte-slash-item"));n.forEach((i,a)=>{const l=a===e.activeIndex;i.classList.toggle("active",l),i.setAttribute("aria-selected",l?"true":"false")});const o=n[e.activeIndex];o&&(e.list.setAttribute("aria-activedescendant",o.id),o.scrollIntoView({block:"nearest"}))}function T(e){if(!(!e.isOpen||!e.panel||!e.anchorRange)){if(!e.editor.isConnected){c(e);return}A(e,e.anchorRange)}}function N(e,t,r,n,o,i){U(e,t),e.query=n,e.trigger=o,e.replaceRange=i.cloneRange(),e.anchorRange=r.cloneRange(),e.filteredItems=W(e.items,n,t.maxSuggestions),e.activeIndex=0,e.isOpen=!0,e.panel&&(Z(e,t),A(e,r))}function ee(e,t){const r=e.editor;if(r.getAttribute("contenteditable")==="false"){c(e);return}const n=v(r);if(!n||!n.collapsed){c(e);return}const o=j(n);if(!o){c(e);return}const i=K(o.textBefore,t.triggerChar,t.maxQueryLength,t.requireBoundary);if(!i){c(e);return}if(i.query.length<t.minChars){c(e);return}const a=n.cloneRange();a.setStart(o.node,i.startOffset),a.setEnd(o.node,o.caretOffset),N(e,t,n,i.query,i.trigger,a)}function O(e,t){const r=e.editor;if(r.getAttribute("contenteditable")==="false")return!1;let n=v(r);n||(n=document.createRange(),n.selectNodeContents(r),n.collapse(!1),y(r,n));const o=n.cloneRange();return o.collapse(!0),N(e,t,n,"",t.triggerChar,o),!0}function te(e){return!(e.metaKey||e.ctrlKey)||e.altKey?!1:e.key==="/"||e.code==="Slash"}function ne(e,t){return{editor:e,panel:null,list:null,replaceRange:null,items:t.items,filteredItems:[],activeIndex:0,query:"",trigger:t.triggerChar,isOpen:!1,instanceId:++z,anchorRange:null}}function w(e,t){const r=g.get(e);if(r)return r.items=t.items,r;const n=ne(e,t);return g.set(e,n),n}function re(e){const t=g.get(e);t&&(t.panel?.parentNode&&t.panel.parentNode.removeChild(t.panel),g.delete(e))}function C(e,t,r){if(p.has(e))return;const n={input:()=>{ee(t,r)},keydown:o=>{if(t.editor.getAttribute("contenteditable")==="false"){c(t);return}if(!t.isOpen&&te(o)){o.preventDefault(),O(t,r);return}if(t.isOpen){if(o.key==="ArrowDown"){o.preventDefault(),R(t,1);return}if(o.key==="ArrowUp"){o.preventDefault(),R(t,-1);return}if(o.key==="Enter"||o.key==="Tab"){if(t.filteredItems.length===0){o.key==="Tab"&&o.preventDefault(),c(t);return}o.preventDefault(),M(t,t.activeIndex);return}if(o.key==="Escape"){o.preventDefault(),c(t);return}}},blur:()=>{window.setTimeout(()=>{const o=document.activeElement;t.panel&&o&&t.panel.contains(o)||c(t)},0)},mousedown:o=>{if(!t.isOpen||!t.panel)return;const i=o.target;i&&!t.panel.contains(i)&&!e.contains(i)&&c(t)},selectionchange:()=>{if(!t.isOpen)return;const o=v(e);if(!o||!o.collapsed){c(t);return}t.anchorRange=o.cloneRange(),T(t)},reposition:()=>{T(t)}};e.addEventListener("input",n.input),e.addEventListener("keydown",n.keydown),e.addEventListener("blur",n.blur),document.addEventListener("mousedown",n.mousedown,!0),document.addEventListener("selectionchange",n.selectionchange),window.addEventListener("resize",n.reposition,{passive:!0}),window.addEventListener("scroll",n.reposition,!0),p.set(e,n)}function oe(e){const t=p.get(e);t&&(e.removeEventListener("input",t.input),e.removeEventListener("keydown",t.keydown),e.removeEventListener("blur",t.blur),document.removeEventListener("mousedown",t.mousedown,!0),document.removeEventListener("selectionchange",t.selectionchange),window.removeEventListener("resize",t.reposition),window.removeEventListener("scroll",t.reposition,!0),p.delete(e))}function ie(e){b||(b=!0,f=t=>{const r=t.target;if(!(r instanceof Node))return;const o=P(r)?.closest(s)||null;if(!o)return;const i=w(o,e);C(o,i,e)},document.addEventListener("focusin",f,!0))}function ae(){!b||!f||(document.removeEventListener("focusin",f,!0),b=!1,f=null)}const le=(e={})=>{B();const t=D(e);return{name:"slashCommands",toolbar:[{id:"slashCommands",label:"Slash Commands",command:"openSlashCommands",icon:'<svg width="24" height="24" focusable="false" aria-hidden="true"><path d="M8.7 20a1 1 0 0 1-.7-.3c-.4-.4-.4-1 0-1.4L15.6 5a1 1 0 0 1 1.4 1.4L9.4 19.7a1 1 0 0 1-.7.3Zm7.8 0c-.3 0-.5 0-.7-.3l-1.8-1.8a1 1 0 1 1 1.4-1.4l1.8 1.8a1 1 0 0 1-.7 1.7Zm-9-12a1 1 0 0 1-.7-1.7L8.6 4.5A1 1 0 1 1 10 6L8.2 7.8a1 1 0 0 1-.7.3Z"></path></svg>'}],commands:{openSlashCommands:(r,n)=>{const o=_(n);if(!o)return!1;const i=w(o,t);return C(o,i,t),O(i,t)}},keymap:{"Mod-/":"openSlashCommands","Mod-Shift-7":"openSlashCommands"},init:()=>{h+=1,ie(t),Array.from(document.querySelectorAll(s)).forEach(n=>{const o=w(n,t);C(n,o,t)})},destroy:()=>{h=Math.max(0,h-1),Array.from(document.querySelectorAll(s)).forEach(n=>{const o=g.get(n);o&&(c(o),oe(n),re(n))}),h===0&&ae()}}};exports.SlashCommandsPlugin=le; |
| function O(e, t) { | ||
| const r = Array.from({ length: t }).map(() => "<th><p><br></p></th>").join(""), n = Array.from({ length: e }).map( | ||
| () => `<tr>${Array.from({ length: t }).map(() => "<td><p><br></p></td>").join("")}</tr>` | ||
| ).join(""); | ||
| return `<table class="rte-table"><thead><tr>${r}</tr></thead><tbody>${n}</tbody></table><p><br></p>`; | ||
| } | ||
| function q() { | ||
| return [ | ||
| { | ||
| id: "paragraph", | ||
| label: "Paragraph", | ||
| description: "Switch to paragraph text", | ||
| command: "paragraph", | ||
| keywords: ["text", "normal", "p"] | ||
| }, | ||
| { | ||
| id: "h1", | ||
| label: "Heading 1", | ||
| description: "Large section heading", | ||
| command: "heading1", | ||
| keywords: ["title", "header", "h1"] | ||
| }, | ||
| { | ||
| id: "h2", | ||
| label: "Heading 2", | ||
| description: "Medium section heading", | ||
| command: "heading2", | ||
| keywords: ["subtitle", "header", "h2"] | ||
| }, | ||
| { | ||
| id: "h3", | ||
| label: "Heading 3", | ||
| description: "Small section heading", | ||
| command: "heading3", | ||
| keywords: ["header", "h3"] | ||
| }, | ||
| { | ||
| id: "bulleted-list", | ||
| label: "Bulleted List", | ||
| description: "Create a bullet list", | ||
| command: "toggleBulletList", | ||
| keywords: ["list", "ul", "bullet"] | ||
| }, | ||
| { | ||
| id: "numbered-list", | ||
| label: "Numbered List", | ||
| description: "Create a numbered list", | ||
| command: "toggleOrderedList", | ||
| keywords: ["list", "ol", "numbered"] | ||
| }, | ||
| { | ||
| id: "blockquote", | ||
| label: "Blockquote", | ||
| description: "Insert a quote block", | ||
| command: "toggleBlockquote", | ||
| keywords: ["quote", "citation"] | ||
| }, | ||
| { | ||
| id: "table-3x3", | ||
| label: "Table 3x3", | ||
| description: "Insert a 3 x 3 table", | ||
| action: ({ insertHTML: e }) => e(O(3, 3)), | ||
| keywords: ["table", "grid", "rows", "columns"] | ||
| }, | ||
| { | ||
| id: "horizontal-rule", | ||
| label: "Divider", | ||
| description: "Insert a horizontal rule", | ||
| command: "insertHorizontalRule", | ||
| keywords: ["hr", "separator", "line"] | ||
| }, | ||
| { | ||
| id: "bold", | ||
| label: "Bold", | ||
| description: "Toggle bold formatting", | ||
| command: "toggleBold", | ||
| keywords: ["strong", "b"] | ||
| }, | ||
| { | ||
| id: "italic", | ||
| label: "Italic", | ||
| description: "Toggle italic formatting", | ||
| command: "toggleItalic", | ||
| keywords: ["emphasis", "i"] | ||
| }, | ||
| { | ||
| id: "underline", | ||
| label: "Underline", | ||
| description: "Toggle underline formatting", | ||
| command: "toggleUnderline", | ||
| keywords: ["u"] | ||
| }, | ||
| { | ||
| id: "strikethrough", | ||
| label: "Strikethrough", | ||
| description: "Toggle strikethrough formatting", | ||
| command: "toggleStrikethrough", | ||
| keywords: ["strike", "s"] | ||
| }, | ||
| { | ||
| id: "clear-formatting", | ||
| label: "Clear Formatting", | ||
| description: "Remove text formatting", | ||
| command: "clearFormatting", | ||
| keywords: ["reset", "plain"] | ||
| } | ||
| ]; | ||
| } | ||
| function $(e) { | ||
| const t = [], r = /* @__PURE__ */ new Set(); | ||
| return e.forEach((n) => { | ||
| const o = String(n.id || "").trim(), i = String(n.label || "").trim(); | ||
| !o || !i || r.has(o) || (r.add(o), t.push({ | ||
| ...n, | ||
| id: o, | ||
| label: i, | ||
| description: n.description ? String(n.description) : void 0, | ||
| keywords: Array.isArray(n.keywords) ? n.keywords.map((a) => String(a)).filter(Boolean) : void 0 | ||
| })); | ||
| }), t; | ||
| } | ||
| function D(e) { | ||
| const t = (e.triggerChar || "/")[0] || "/", r = e.includeDefaultItems !== !1, n = r ? [...e.items || [], ...q()] : e.items || []; | ||
| return { | ||
| triggerChar: t, | ||
| minChars: Math.max(0, e.minChars ?? 0), | ||
| maxQueryLength: Math.max(1, e.maxQueryLength ?? 48), | ||
| maxSuggestions: Math.max(1, e.maxSuggestions ?? 10), | ||
| requireBoundary: e.requireBoundary !== !1, | ||
| includeDefaultItems: r, | ||
| items: $(n), | ||
| itemRenderer: e.itemRenderer, | ||
| emptyStateText: e.emptyStateText || "No commands found", | ||
| panelLabel: e.panelLabel || "Slash commands" | ||
| }; | ||
| } | ||
| const u = '[data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark'; | ||
| let v = !1; | ||
| function B() { | ||
| if (v || typeof document > "u") return; | ||
| v = !0; | ||
| const e = document.createElement("style"); | ||
| e.id = "rte-slash-commands-styles", e.textContent = ` | ||
| .rte-slash-panel { | ||
| width: min(225px, calc(100vw - 16px)); | ||
| max-height: min(360px, calc(100vh - 24px)); | ||
| overflow: hidden; | ||
| border: 1px solid #d9dfeb; | ||
| border-radius: 0px; | ||
| background: #ffffff; | ||
| box-shadow: 0 18px 40px rgba(15, 23, 42, 0.2); | ||
| z-index: 2147483646; | ||
| } | ||
| .rte-slash-list { | ||
| max-height: min(340px, calc(100vh - 32px)); | ||
| overflow: auto; | ||
| padding: 0px; | ||
| display: grid; | ||
| gap: 1px; | ||
| } | ||
| .rte-slash-item { | ||
| width: 100%; | ||
| border: none; | ||
| background: transparent; | ||
| color: #0f172a; | ||
| border-radius: 0px; | ||
| padding: 6px 9px; | ||
| text-align: left; | ||
| display: grid; | ||
| gap: 0px; | ||
| cursor: pointer; | ||
| font: inherit; | ||
| } | ||
| .rte-slash-item:hover, | ||
| .rte-slash-item.active { | ||
| background: #eff6ff; | ||
| color: #1d4ed8; | ||
| } | ||
| .rte-slash-item-title { | ||
| font-size: 13px; | ||
| font-weight: 600; | ||
| line-height: 1.35; | ||
| } | ||
| .rte-slash-item-description { | ||
| font-size: 12px; | ||
| color: #64748b; | ||
| line-height: 1.35; | ||
| } | ||
| .rte-slash-item mark { | ||
| background: rgba(59, 130, 246, 0.16); | ||
| color: inherit; | ||
| padding: 0 2px; | ||
| border-radius: 3px; | ||
| } | ||
| .rte-slash-empty { | ||
| font-size: 13px; | ||
| color: #64748b; | ||
| text-align: center; | ||
| padding: 12px; | ||
| } | ||
| ${u} .rte-slash-panel { | ||
| border-color: #364152; | ||
| background: #1f2937; | ||
| box-shadow: 0 22px 44px rgba(0, 0, 0, 0.48); | ||
| } | ||
| ${u} .rte-slash-item { | ||
| color: #e5e7eb; | ||
| } | ||
| ${u} .rte-slash-item:hover, | ||
| ${u} .rte-slash-item.active { | ||
| background: #334155; | ||
| color: #bfdbfe; | ||
| } | ||
| ${u} .rte-slash-item-description, | ||
| ${u} .rte-slash-empty { | ||
| color: #9ca3af; | ||
| } | ||
| `, document.head.appendChild(e); | ||
| } | ||
| const s = ".rte-content, .editora-content", g = /* @__PURE__ */ new WeakMap(), p = /* @__PURE__ */ new WeakMap(); | ||
| let b = !1, f = null, h = 0, z = 0; | ||
| function P(e) { | ||
| return e ? e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement : null; | ||
| } | ||
| function I(e) { | ||
| return e.closest("[data-editora-editor], .rte-editor, .editora-editor, editora-editor") || e; | ||
| } | ||
| function F(e) { | ||
| if (e?.contentElement instanceof HTMLElement) return e.contentElement; | ||
| if (e?.editorElement instanceof HTMLElement) { | ||
| const n = e.editorElement; | ||
| if (n.matches(s)) return n; | ||
| const o = n.querySelector(s); | ||
| if (o instanceof HTMLElement) return o; | ||
| } | ||
| const t = window.getSelection(); | ||
| if (t && t.rangeCount > 0) { | ||
| const n = t.getRangeAt(0).startContainer, i = (n.nodeType === Node.ELEMENT_NODE ? n : n.parentElement)?.closest(s); | ||
| if (i) return i; | ||
| } | ||
| const r = document.activeElement; | ||
| if (r) { | ||
| if (r.matches(s)) return r; | ||
| const n = r.closest(s); | ||
| if (n) return n; | ||
| } | ||
| return document.querySelector(s); | ||
| } | ||
| function m(e) { | ||
| return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); | ||
| } | ||
| function _(e) { | ||
| return e ? /\s|[([{"'`]/.test(e) : !0; | ||
| } | ||
| function E(e) { | ||
| const t = window.getSelection(); | ||
| if (!t || t.rangeCount === 0) return null; | ||
| const r = t.getRangeAt(0); | ||
| return e.contains(r.commonAncestorContainer) ? r.cloneRange() : null; | ||
| } | ||
| function y(e, t) { | ||
| const r = window.getSelection(); | ||
| r && (r.removeAllRanges(), r.addRange(t), e.focus({ preventScroll: !0 })); | ||
| } | ||
| function j(e) { | ||
| if (!e.collapsed) return null; | ||
| const t = e.startContainer, r = e.startOffset; | ||
| if (t.nodeType === Node.TEXT_NODE) { | ||
| const n = t; | ||
| return { | ||
| node: n, | ||
| textBefore: n.data.slice(0, r), | ||
| caretOffset: r | ||
| }; | ||
| } | ||
| if (t.nodeType === Node.ELEMENT_NODE) { | ||
| const n = t; | ||
| if (r > 0) { | ||
| const o = n.childNodes[r - 1]; | ||
| if (o && o.nodeType === Node.TEXT_NODE) { | ||
| const i = o; | ||
| return { | ||
| node: i, | ||
| textBefore: i.data, | ||
| caretOffset: i.length | ||
| }; | ||
| } | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| function K(e, t, r, n) { | ||
| const o = e.lastIndexOf(t); | ||
| if (o < 0 || n && !_(e[o - 1])) | ||
| return null; | ||
| const i = e.slice(o + 1); | ||
| return /\s/.test(i) || i.length > r ? null : { | ||
| trigger: t, | ||
| query: i, | ||
| startOffset: o | ||
| }; | ||
| } | ||
| function Q(e, t) { | ||
| const r = t.cloneRange(); | ||
| r.collapse(!1); | ||
| const n = r.getClientRects(); | ||
| if (n.length > 0) | ||
| return n[n.length - 1]; | ||
| const o = document.createElement("span"); | ||
| o.textContent = "", r.insertNode(o); | ||
| const i = o.getBoundingClientRect(); | ||
| return o.remove(), e.normalize(), i; | ||
| } | ||
| function A(e, t) { | ||
| if (!e.panel) return; | ||
| const r = Q(e.editor, t), n = e.panel; | ||
| n.style.display = "block", n.classList.add("show"), n.style.left = "0px", n.style.top = "0px"; | ||
| const o = n.getBoundingClientRect(), i = window.innerWidth, a = window.innerHeight; | ||
| let l = Math.max(8, Math.min(r.left, i - o.width - 8)), d = r.bottom + 8; | ||
| d + o.height > a - 8 && (d = Math.max(8, r.top - o.height - 8)), n.style.position = "fixed", n.style.left = `${l}px`, n.style.top = `${d}px`; | ||
| } | ||
| function k(e, t) { | ||
| if (!t) return m(e); | ||
| const r = e.toLowerCase(), n = t.toLowerCase(), o = r.indexOf(n); | ||
| if (o < 0) return m(e); | ||
| const i = m(e.slice(0, o)), a = m(e.slice(o, o + t.length)), l = m(e.slice(o + t.length)); | ||
| return `${i}<mark>${a}</mark>${l}`; | ||
| } | ||
| function U(e, t) { | ||
| if (e.panel && e.list) return; | ||
| const r = document.createElement("div"); | ||
| r.className = "rte-slash-panel", r.style.display = "none", r.setAttribute("role", "dialog"), r.setAttribute("aria-modal", "false"); | ||
| const n = document.createElement("div"); | ||
| n.className = "rte-slash-list", n.setAttribute("role", "listbox"), n.setAttribute("aria-label", t.panelLabel), r.appendChild(n), document.body.appendChild(r), e.panel = r, e.list = n, r.addEventListener("mousedown", (o) => { | ||
| o.preventDefault(); | ||
| }), r.addEventListener("click", (o) => { | ||
| const i = o.target; | ||
| if (!i) return; | ||
| const a = i.closest(".rte-slash-item"); | ||
| if (!a) return; | ||
| const l = Number(a.getAttribute("data-index")); | ||
| Number.isFinite(l) && M(e, l); | ||
| }); | ||
| } | ||
| function c(e) { | ||
| e.panel && (e.panel.style.display = "none", e.panel.classList.remove("show"), e.isOpen = !1, e.filteredItems = [], e.activeIndex = 0, e.query = "", e.replaceRange = null, e.anchorRange = null); | ||
| } | ||
| function W(e, t, r) { | ||
| if (!t) return e.slice(0, r); | ||
| const n = t.toLowerCase(); | ||
| return e.filter((i) => [ | ||
| i.id, | ||
| i.label, | ||
| i.description || "", | ||
| i.command || "", | ||
| ...i.keywords || [] | ||
| ].join(" ").toLowerCase().includes(n)).slice(0, r); | ||
| } | ||
| function Z(e, t) { | ||
| if (!e.list) return; | ||
| const r = e.list; | ||
| if (r.innerHTML = "", e.filteredItems.length === 0) { | ||
| const n = document.createElement("div"); | ||
| n.className = "rte-slash-empty", n.textContent = t.emptyStateText, r.appendChild(n), r.removeAttribute("aria-activedescendant"); | ||
| return; | ||
| } | ||
| e.filteredItems.forEach((n, o) => { | ||
| const i = document.createElement("button"); | ||
| i.type = "button", i.className = "rte-slash-item", i.setAttribute("role", "option"), i.setAttribute("data-index", String(o)), i.setAttribute("id", `rte-slash-item-${e.instanceId}-${o}`), i.setAttribute("aria-selected", o === e.activeIndex ? "true" : "false"), i.setAttribute("aria-label", n.description ? `${n.label} - ${n.description}` : n.label), o === e.activeIndex && i.classList.add("active"), t.itemRenderer ? i.innerHTML = t.itemRenderer(n, e.query) : i.innerHTML = ` | ||
| <span class="rte-slash-item-title">${k(n.label, e.query)}</span> | ||
| ${n.description ? `<span class="rte-slash-item-description">${k(n.description, e.query)}</span>` : ""} | ||
| `, r.appendChild(i); | ||
| }), e.filteredItems.length > 0 && r.setAttribute("aria-activedescendant", `rte-slash-item-${e.instanceId}-${e.activeIndex}`); | ||
| } | ||
| function G(e, t) { | ||
| if (t === e.innerHTML) return; | ||
| const r = window.execEditorCommand || window.executeEditorCommand; | ||
| if (typeof r == "function") | ||
| try { | ||
| r("recordDomTransaction", e, t, e.innerHTML); | ||
| } catch { | ||
| } | ||
| } | ||
| function V(e) { | ||
| e.dispatchEvent(new Event("input", { bubbles: !0 })); | ||
| } | ||
| function L(e, t) { | ||
| e.focus({ preventScroll: !0 }); | ||
| try { | ||
| if (document.execCommand("insertHTML", !1, t)) | ||
| return !0; | ||
| } catch { | ||
| } | ||
| const r = window.getSelection(); | ||
| if (!r || r.rangeCount === 0) return !1; | ||
| const n = r.getRangeAt(0); | ||
| if (!e.contains(n.commonAncestorContainer)) return !1; | ||
| n.deleteContents(); | ||
| const o = document.createElement("template"); | ||
| o.innerHTML = t; | ||
| const i = o.content, a = i.lastChild; | ||
| if (n.insertNode(i), a) { | ||
| const l = document.createRange(); | ||
| l.setStartAfter(a), l.collapse(!0), y(e, l); | ||
| } | ||
| return !0; | ||
| } | ||
| function X(e, t) { | ||
| e.focus({ preventScroll: !0 }); | ||
| try { | ||
| if (document.execCommand("insertText", !1, t)) | ||
| return !0; | ||
| } catch { | ||
| } | ||
| const r = window.getSelection(); | ||
| if (!r || r.rangeCount === 0) return !1; | ||
| const n = r.getRangeAt(0); | ||
| if (!e.contains(n.commonAncestorContainer)) return !1; | ||
| n.deleteContents(); | ||
| const o = document.createTextNode(t); | ||
| n.insertNode(o); | ||
| const i = document.createRange(); | ||
| return i.setStart(o, o.length), i.collapse(!0), y(e, i), !0; | ||
| } | ||
| function J(e, t) { | ||
| switch (e.toLowerCase()) { | ||
| case "paragraph": | ||
| case "p": | ||
| return document.execCommand("formatBlock", !1, "<p>"); | ||
| case "heading1": | ||
| case "h1": | ||
| return document.execCommand("formatBlock", !1, "<h1>"); | ||
| case "heading2": | ||
| case "h2": | ||
| return document.execCommand("formatBlock", !1, "<h2>"); | ||
| case "heading3": | ||
| case "h3": | ||
| return document.execCommand("formatBlock", !1, "<h3>"); | ||
| case "blockquote": | ||
| case "toggleblockquote": | ||
| return document.execCommand("formatBlock", !1, "<blockquote>"); | ||
| case "bulletlist": | ||
| case "togglebulletlist": | ||
| case "insertunorderedlist": | ||
| return document.execCommand("insertUnorderedList"); | ||
| case "numberedlist": | ||
| case "toggleorderedlist": | ||
| case "insertorderedlist": | ||
| return document.execCommand("insertOrderedList"); | ||
| case "horizontalrule": | ||
| case "divider": | ||
| case "inserthorizontalrule": | ||
| return document.execCommand("insertHorizontalRule"); | ||
| case "bold": | ||
| case "togglebold": | ||
| return document.execCommand("bold"); | ||
| case "italic": | ||
| case "toggleitalic": | ||
| return document.execCommand("italic"); | ||
| case "underline": | ||
| case "toggleunderline": | ||
| return document.execCommand("underline"); | ||
| case "strikethrough": | ||
| case "togglestrikethrough": | ||
| return document.execCommand("strikeThrough"); | ||
| case "clearformatting": | ||
| case "removeformat": | ||
| return document.execCommand("removeFormat"); | ||
| default: | ||
| try { | ||
| return document.execCommand(e, !1, t); | ||
| } catch { | ||
| return !1; | ||
| } | ||
| } | ||
| } | ||
| function S(e, t, r) { | ||
| const n = I(e); | ||
| if (n && typeof n.execCommand == "function") | ||
| try { | ||
| if (n.execCommand(t, r) !== !1) return !0; | ||
| } catch { | ||
| } | ||
| const o = window.execEditorCommand || window.executeEditorCommand; | ||
| if (typeof o == "function") | ||
| try { | ||
| if (o(t, r, { | ||
| editorElement: n, | ||
| contentElement: e | ||
| }) !== !1) return !0; | ||
| } catch { | ||
| } | ||
| return J(t, r); | ||
| } | ||
| async function Y(e, t) { | ||
| const r = e.editor, n = I(r), o = { | ||
| editor: r, | ||
| editorRoot: n, | ||
| query: e.query, | ||
| trigger: e.trigger, | ||
| executeCommand: (i, a) => S(r, i, a), | ||
| insertHTML: (i) => L(r, i) | ||
| }; | ||
| return t.action ? await Promise.resolve(t.action(o)) !== !1 : t.insertHTML ? L(r, t.insertHTML) : t.command ? S(r, t.command, t.commandValue) : !1; | ||
| } | ||
| async function M(e, t) { | ||
| if (t < 0 || t >= e.filteredItems.length || !e.replaceRange) return; | ||
| const r = e.filteredItems[t], n = e.editor, o = n.innerHTML, i = `${e.trigger}${e.query}`; | ||
| if (!window.getSelection()) return; | ||
| const l = e.replaceRange.cloneRange(); | ||
| if (!n.contains(l.commonAncestorContainer)) return; | ||
| l.deleteContents(); | ||
| const d = l.cloneRange(); | ||
| d.collapse(!0), y(n, d); | ||
| let x = !1; | ||
| try { | ||
| x = await Y(e, r); | ||
| } catch { | ||
| x = !1; | ||
| } | ||
| c(e), x ? (V(n), G(n, o)) : i && X(n, i), n.focus({ preventScroll: !0 }); | ||
| } | ||
| function R(e, t) { | ||
| if (e.filteredItems.length === 0) return; | ||
| const r = e.filteredItems.length; | ||
| if (e.activeIndex = ((e.activeIndex + t) % r + r) % r, !e.list) return; | ||
| const n = Array.from(e.list.querySelectorAll(".rte-slash-item")); | ||
| n.forEach((i, a) => { | ||
| const l = a === e.activeIndex; | ||
| i.classList.toggle("active", l), i.setAttribute("aria-selected", l ? "true" : "false"); | ||
| }); | ||
| const o = n[e.activeIndex]; | ||
| o && (e.list.setAttribute("aria-activedescendant", o.id), o.scrollIntoView({ block: "nearest" })); | ||
| } | ||
| function T(e) { | ||
| if (!(!e.isOpen || !e.panel || !e.anchorRange)) { | ||
| if (!e.editor.isConnected) { | ||
| c(e); | ||
| return; | ||
| } | ||
| A(e, e.anchorRange); | ||
| } | ||
| } | ||
| function N(e, t, r, n, o, i) { | ||
| U(e, t), e.query = n, e.trigger = o, e.replaceRange = i.cloneRange(), e.anchorRange = r.cloneRange(), e.filteredItems = W(e.items, n, t.maxSuggestions), e.activeIndex = 0, e.isOpen = !0, e.panel && (Z(e, t), A(e, r)); | ||
| } | ||
| function ee(e, t) { | ||
| const r = e.editor; | ||
| if (r.getAttribute("contenteditable") === "false") { | ||
| c(e); | ||
| return; | ||
| } | ||
| const n = E(r); | ||
| if (!n || !n.collapsed) { | ||
| c(e); | ||
| return; | ||
| } | ||
| const o = j(n); | ||
| if (!o) { | ||
| c(e); | ||
| return; | ||
| } | ||
| const i = K( | ||
| o.textBefore, | ||
| t.triggerChar, | ||
| t.maxQueryLength, | ||
| t.requireBoundary | ||
| ); | ||
| if (!i) { | ||
| c(e); | ||
| return; | ||
| } | ||
| if (i.query.length < t.minChars) { | ||
| c(e); | ||
| return; | ||
| } | ||
| const a = n.cloneRange(); | ||
| a.setStart(o.node, i.startOffset), a.setEnd(o.node, o.caretOffset), N(e, t, n, i.query, i.trigger, a); | ||
| } | ||
| function H(e, t) { | ||
| const r = e.editor; | ||
| if (r.getAttribute("contenteditable") === "false") | ||
| return !1; | ||
| let n = E(r); | ||
| n || (n = document.createRange(), n.selectNodeContents(r), n.collapse(!1), y(r, n)); | ||
| const o = n.cloneRange(); | ||
| return o.collapse(!0), N(e, t, n, "", t.triggerChar, o), !0; | ||
| } | ||
| function te(e) { | ||
| return !(e.metaKey || e.ctrlKey) || e.altKey ? !1 : e.key === "/" || e.code === "Slash"; | ||
| } | ||
| function ne(e, t) { | ||
| return { | ||
| editor: e, | ||
| panel: null, | ||
| list: null, | ||
| replaceRange: null, | ||
| items: t.items, | ||
| filteredItems: [], | ||
| activeIndex: 0, | ||
| query: "", | ||
| trigger: t.triggerChar, | ||
| isOpen: !1, | ||
| instanceId: ++z, | ||
| anchorRange: null | ||
| }; | ||
| } | ||
| function w(e, t) { | ||
| const r = g.get(e); | ||
| if (r) | ||
| return r.items = t.items, r; | ||
| const n = ne(e, t); | ||
| return g.set(e, n), n; | ||
| } | ||
| function re(e) { | ||
| const t = g.get(e); | ||
| t && (t.panel?.parentNode && t.panel.parentNode.removeChild(t.panel), g.delete(e)); | ||
| } | ||
| function C(e, t, r) { | ||
| if (p.has(e)) return; | ||
| const n = { | ||
| input: () => { | ||
| ee(t, r); | ||
| }, | ||
| keydown: (o) => { | ||
| if (t.editor.getAttribute("contenteditable") === "false") { | ||
| c(t); | ||
| return; | ||
| } | ||
| if (!t.isOpen && te(o)) { | ||
| o.preventDefault(), H(t, r); | ||
| return; | ||
| } | ||
| if (t.isOpen) { | ||
| if (o.key === "ArrowDown") { | ||
| o.preventDefault(), R(t, 1); | ||
| return; | ||
| } | ||
| if (o.key === "ArrowUp") { | ||
| o.preventDefault(), R(t, -1); | ||
| return; | ||
| } | ||
| if (o.key === "Enter" || o.key === "Tab") { | ||
| if (t.filteredItems.length === 0) { | ||
| o.key === "Tab" && o.preventDefault(), c(t); | ||
| return; | ||
| } | ||
| o.preventDefault(), M(t, t.activeIndex); | ||
| return; | ||
| } | ||
| if (o.key === "Escape") { | ||
| o.preventDefault(), c(t); | ||
| return; | ||
| } | ||
| } | ||
| }, | ||
| blur: () => { | ||
| window.setTimeout(() => { | ||
| const o = document.activeElement; | ||
| t.panel && o && t.panel.contains(o) || c(t); | ||
| }, 0); | ||
| }, | ||
| mousedown: (o) => { | ||
| if (!t.isOpen || !t.panel) return; | ||
| const i = o.target; | ||
| i && !t.panel.contains(i) && !e.contains(i) && c(t); | ||
| }, | ||
| selectionchange: () => { | ||
| if (!t.isOpen) return; | ||
| const o = E(e); | ||
| if (!o || !o.collapsed) { | ||
| c(t); | ||
| return; | ||
| } | ||
| t.anchorRange = o.cloneRange(), T(t); | ||
| }, | ||
| reposition: () => { | ||
| T(t); | ||
| } | ||
| }; | ||
| e.addEventListener("input", n.input), e.addEventListener("keydown", n.keydown), e.addEventListener("blur", n.blur), document.addEventListener("mousedown", n.mousedown, !0), document.addEventListener("selectionchange", n.selectionchange), window.addEventListener("resize", n.reposition, { passive: !0 }), window.addEventListener("scroll", n.reposition, !0), p.set(e, n); | ||
| } | ||
| function oe(e) { | ||
| const t = p.get(e); | ||
| t && (e.removeEventListener("input", t.input), e.removeEventListener("keydown", t.keydown), e.removeEventListener("blur", t.blur), document.removeEventListener("mousedown", t.mousedown, !0), document.removeEventListener("selectionchange", t.selectionchange), window.removeEventListener("resize", t.reposition), window.removeEventListener("scroll", t.reposition, !0), p.delete(e)); | ||
| } | ||
| function ie(e) { | ||
| b || (b = !0, f = (t) => { | ||
| const r = t.target; | ||
| if (!(r instanceof Node)) return; | ||
| const o = P(r)?.closest(s) || null; | ||
| if (!o) return; | ||
| const i = w(o, e); | ||
| C(o, i, e); | ||
| }, document.addEventListener("focusin", f, !0)); | ||
| } | ||
| function ae() { | ||
| !b || !f || (document.removeEventListener("focusin", f, !0), b = !1, f = null); | ||
| } | ||
| const le = (e = {}) => { | ||
| B(); | ||
| const t = D(e); | ||
| return { | ||
| name: "slashCommands", | ||
| toolbar: [ | ||
| { | ||
| id: "slashCommands", | ||
| label: "Slash Commands", | ||
| command: "openSlashCommands", | ||
| icon: '<svg width="24" height="24" focusable="false" aria-hidden="true"><path d="M8.7 20a1 1 0 0 1-.7-.3c-.4-.4-.4-1 0-1.4L15.6 5a1 1 0 0 1 1.4 1.4L9.4 19.7a1 1 0 0 1-.7.3Zm7.8 0c-.3 0-.5 0-.7-.3l-1.8-1.8a1 1 0 1 1 1.4-1.4l1.8 1.8a1 1 0 0 1-.7 1.7Zm-9-12a1 1 0 0 1-.7-1.7L8.6 4.5A1 1 0 1 1 10 6L8.2 7.8a1 1 0 0 1-.7.3Z"></path></svg>' | ||
| } | ||
| ], | ||
| commands: { | ||
| openSlashCommands: (r, n) => { | ||
| const o = F(n); | ||
| if (!o) return !1; | ||
| const i = w(o, t); | ||
| return C(o, i, t), H(i, t); | ||
| } | ||
| }, | ||
| keymap: { | ||
| "Mod-/": "openSlashCommands", | ||
| "Mod-Shift-7": "openSlashCommands" | ||
| }, | ||
| init: () => { | ||
| h += 1, ie(t), Array.from(document.querySelectorAll(s)).forEach((n) => { | ||
| const o = w(n, t); | ||
| C(n, o, t); | ||
| }); | ||
| }, | ||
| destroy: () => { | ||
| h = Math.max(0, h - 1), Array.from(document.querySelectorAll(s)).forEach((n) => { | ||
| const o = g.get(n); | ||
| o && (c(o), oe(n), re(n)); | ||
| }), h === 0 && ae(); | ||
| } | ||
| }; | ||
| }; | ||
| export { | ||
| le as SlashCommandsPlugin | ||
| }; |
| "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const y=".rte-content, .editora-content",ee="[data-editora-editor], .rte-editor, .editora-editor, editora-editor",se="__editoraCommandEditorRoot",le="rte-smart-paste-styles",u="rte-smart-paste-panel",h="smart-paste",S="smartPaste",E=':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)',Ee=typeof NodeFilter<"u"?NodeFilter.SHOW_COMMENT:128,ie="__editoraSmartPasteHandled",ke=new Set(["script","style","meta","link","object","embed","iframe","svg","canvas","math","form","input","button","textarea","select","option"]),Ce=new Set(["table","thead","tbody","tfoot","tr","td","th","colgroup","col"]),Te=new Set(["span","font"]),Pe=/^(https?:|mailto:|tel:|#|\/)/i,Ae=/^data:image\/(?:png|gif|jpeg|jpg|webp);base64,/i,we=new Set(["color","background-color","font-weight","font-style","text-decoration","text-align","font-size","font-family","line-height","letter-spacing","word-spacing","white-space","vertical-align","margin-left","margin-right","margin-top","margin-bottom","padding-left","padding-right","padding-top","padding-bottom","text-indent","border","border-top","border-right","border-bottom","border-left","border-color","border-width","border-style","list-style-type"]),Le={panelTitle:"Smart Paste",panelAriaLabel:"Smart paste panel",enabledText:"Smart paste is enabled",disabledText:"Smart paste is disabled",toggleOnText:"Disable Smart Paste",toggleOffText:"Enable Smart Paste",cycleProfileText:"Cycle Profile",profileLabel:"Profile",fidelityText:"Fidelity",balancedText:"Balanced",plainText:"Plain Text",lastPasteHeading:"Last Paste Result",lastPasteEmptyText:"Paste content to see cleanup metrics.",lastPasteSourceLabel:"Source",lastPasteProfileLabel:"Profile",lastPasteRemovedLabel:"Removed",lastPasteCharsLabel:"Output Chars",closeText:"Close",shortcutText:"Shortcuts: Ctrl/Cmd+Alt+Shift+S/V/G",readonlyMessage:"Editor is read-only. Smart paste was skipped."},Y={fidelity:{keepStyles:!0,keepClasses:!1,keepDataAttributes:!1,preserveTables:!0},balanced:{keepStyles:!1,keepClasses:!1,keepDataAttributes:!1,preserveTables:!0},plain:{keepStyles:!1,keepClasses:!1,keepDataAttributes:!1,preserveTables:!1}},d=new WeakMap,L=new WeakMap,g=new Map,q=new WeakMap,j=new WeakMap,_=new Set;let I=0,$e=0,$=null,m=null,P=null,A=null,T=null,w=null;function X(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function Me(e){return e.replace(/\u00A0/g," ").replace(/\r\n?/g,` | ||
| `)}function z(e){return e==="balanced"||e==="plain"?e:"fidelity"}function Z(e,t){return{keepStyles:e?.keepStyles??t.keepStyles,keepClasses:e?.keepClasses??t.keepClasses,keepDataAttributes:e?.keepDataAttributes??t.keepDataAttributes,preserveTables:e?.preserveTables??t.preserveTables}}function K(e={}){const t=e.profileOptions||{};return{enabled:e.enabled!==!1,defaultProfile:z(e.defaultProfile),maxHtmlLength:Math.max(8e3,Math.min(8e5,Number(e.maxHtmlLength??22e4))),removeComments:e.removeComments!==!1,normalizeWhitespace:e.normalizeWhitespace!==!1,labels:{...Le,...e.labels||{}},normalizeText:e.normalizeText||Me,profileOptions:{fidelity:Z(t.fidelity,Y.fidelity),balanced:Z(t.balanced,Y.balanced),plain:Z(t.plain,Y.plain)}}}function ce(e){return{enabled:e.enabled,defaultProfile:e.defaultProfile,maxHtmlLength:e.maxHtmlLength,removeComments:e.removeComments,normalizeWhitespace:e.normalizeWhitespace,labels:{...e.labels},normalizeText:e.normalizeText,profileOptions:{fidelity:{...e.profileOptions.fidelity},balanced:{...e.profileOptions.balanced},plain:{...e.profileOptions.plain}}}}function te(e){return e.closest(ee)||e}function H(e){if(!e)return null;if(e.matches(y))return e;const t=e.querySelector(y);return t instanceof HTMLElement?t:null}function Oe(){if(typeof window>"u")return null;const e=window[se];if(!(e instanceof HTMLElement))return null;window[se]=null;const t=H(e);if(t)return t;const a=e.closest(ee);if(a){const n=H(a);if(n)return n}const r=e.closest(y);return r instanceof HTMLElement?r:null}function Re(e){const t=e.closest("[data-editora-editor]");if(t&&H(t)===e)return t;let a=e;for(;a;){if(a.matches(ee)&&(a===e||H(a)===e))return a;a=a.parentElement}return te(e)}function pe(e){return e?e.nodeType===Node.ELEMENT_NODE?e:e.parentElement:null}function C(e,t=!0,a=!0){if(V(),e?.contentElement instanceof HTMLElement)return e.contentElement;if(e?.editorElement instanceof HTMLElement){const s=H(e.editorElement);if(s)return s}const r=Oe();if(r)return r;const n=window.getSelection();if(n&&n.rangeCount>0){const l=pe(n.getRangeAt(0).startContainer)?.closest(y);if(l)return l}const o=document.activeElement;if(o){if(o.matches(y))return o;const s=o.closest(y);if(s)return s}if(a){if(m&&m.isConnected)return m;m&&!m.isConnected&&(m=null)}return t?document.querySelector(y):null}function _e(e){const t=e.target;if(t){const r=t.closest(y);if(r)return r}const a=window.getSelection();if(a&&a.rangeCount>0){const n=pe(a.getRangeAt(0).startContainer)?.closest(y);if(n)return n}return null}function B(e){return e?(e.getAttribute("data-theme")||e.getAttribute("theme")||"").toLowerCase()==="dark"?!0:e.classList.contains("dark")||e.classList.contains("editora-theme-dark")||e.classList.contains("rte-theme-dark"):!1}function ze(e){const t=te(e);if(B(t))return!0;const a=t.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark");return B(a)?!0:B(document.documentElement)||B(document.body)}function F(e,t){e.classList.remove("rte-smart-paste-theme-dark"),ze(t)&&e.classList.add("rte-smart-paste-theme-dark")}function de(e){return e.getAttribute("contenteditable")==="false"||e.getAttribute("data-readonly")==="true"}function D(e,t,a){const r=Re(e);Array.from(r.querySelectorAll(`.rte-toolbar-button[data-command="${t}"], .editora-toolbar-button[data-command="${t}"]`)).forEach(o=>{o.classList.toggle("active",a),o.setAttribute("data-active",a?"true":"false"),o.setAttribute("aria-pressed",a?"true":"false")})}function p(e,t){d.has(e)||d.set(e,t);let a=L.get(e);return a||(a={enabled:t.enabled,profile:t.defaultProfile,lastReport:null},L.set(e,a)),Qe(e),_.add(e),a}function me(e){const t=j.get(e);t&&(e.removeEventListener("paste",t,!0),j.delete(e))}function be(e){me(e),g.get(e)?.remove(),g.delete(e),q.delete(e),d.delete(e),L.delete(e),_.delete(e),m===e&&(m=null)}function V(){Array.from(_).forEach(t=>{t.isConnected||be(t)})}function He(e){for(let t=0;t<e.length;t+=1){const a=e[t];if(!(a.type!=="childList"||a.removedNodes.length===0))for(let r=0;r<a.removedNodes.length;r+=1){const n=a.removedNodes[r];if(n.nodeType!==Node.ELEMENT_NODE)continue;const o=n;if(o.matches?.(y)||o.matches?.(`.${u}`)||o.querySelector?.(y)||o.querySelector?.(`.${u}`))return!0}}return!1}function re(e){return q.get(e)===!0}function O(e,t){const a=e.querySelector(".rte-smart-paste-live");a&&(a.textContent=t)}function J(e,t){const a=t.normalizeText(e);return t.normalizeWhitespace?a.split(` | ||
| `).map(n=>n.replace(/[\t ]+/g," ").trimEnd()).join(` | ||
| `).replace(/\n{3,}/g,` | ||
| `).trim():a}function De(e){return/class=["'][^"']*Mso|xmlns:w=|urn:schemas-microsoft-com:office|<o:p\b/i.test(e)}function Ne(e){return/id=["']docs-internal-guid|docs-\w+|data-sheets-value|data-sheets-userformat/i.test(e)}function qe(e,t){return e?De(e)?"word":Ne(e)?"google-docs":"html":t?"plain":"html"}function Ie(e){return e.split(/\s+/).map(a=>a.trim()).filter(Boolean).filter(a=>!/^mso/i.test(a)).filter(a=>!/^docs-/i.test(a)).filter(a=>!/^c\d+$/i.test(a)).join(" ")}function Be(e){if(!e)return{value:"",changed:!1};const t=e.split(";"),a=[];let r=!1;return t.forEach(n=>{const o=n.indexOf(":");if(o<=0){n.trim()&&(r=!0);return}const s=n.slice(0,o).trim().toLowerCase(),l=n.slice(o+1).trim();if(!s||!l){r=!0;return}if(!we.has(s)){r=!0;return}if(/expression\s*\(|javascript\s*:|vbscript\s*:|url\s*\(/i.test(l)){r=!0;return}a.push(`${s}: ${l}`)}),{value:a.join("; "),changed:r}}function ue(e){const t=e.trim();return t&&(Pe.test(t)||Ae.test(t))?t:""}function fe(e){const t=e.parentNode;if(t){for(;e.firstChild;)t.insertBefore(e.firstChild,e);t.removeChild(e)}}function We(e,t,a,r){const n=e.tagName.toLowerCase();if(ke.has(n)){r.removedElements+=1,e.remove();return}if(!t.preserveTables&&Ce.has(n)){const s=e.textContent||"",l=document.createTextNode(s);e.replaceWith(l),r.removedElements+=1;return}if(Array.from(e.attributes).forEach(s=>{const l=s.name.toLowerCase(),i=s.value;if(l.startsWith("on")){e.removeAttribute(s.name),r.removedAttributes+=1;return}if(l==="style"){if(!t.keepStyles){e.removeAttribute(s.name),r.removedAttributes+=1;return}const c=Be(i);if(!c.value){e.removeAttribute(s.name),r.removedAttributes+=1,c.changed&&(r.normalizedStyles+=1);return}(c.changed||c.value!==i)&&(e.setAttribute("style",c.value),r.normalizedStyles+=1);return}if(l==="class"){if(!t.keepClasses){e.removeAttribute(s.name),r.removedAttributes+=1;return}const c=Ie(i);if(!c){e.removeAttribute(s.name),r.removedAttributes+=1;return}c!==i&&(e.setAttribute("class",c),r.removedAttributes+=1);return}if(l.startsWith("data-")&&!t.keepDataAttributes){e.removeAttribute(s.name),r.removedAttributes+=1;return}if(l==="id"||l==="xmlns"||l.startsWith("xml")){e.removeAttribute(s.name),r.removedAttributes+=1;return}if((a==="word"||a==="google-docs")&&(l==="lang"||l==="dir")){e.removeAttribute(s.name),r.removedAttributes+=1;return}if(l==="href"||l==="src"||l==="xlink:href"){const c=ue(i);if(!c){e.removeAttribute(s.name),r.removedAttributes+=1;return}c!==i&&e.setAttribute(s.name,c)}}),n==="a"){if(!e.getAttribute("href")){fe(e),r.removedElements+=1;return}e.getAttribute("target")==="_blank"&&e.setAttribute("rel","noopener noreferrer")}if(n==="img"){const s=e.getAttribute("src");if(!s||!ue(s)){r.removedElements+=1,e.remove();return}}if(Te.has(n)&&!e.attributes.length&&!e.className&&!e.style.cssText){const s=e.children.length>0,l=(e.textContent||"").trim().length>0;if(!s&&!l){e.remove(),r.removedElements+=1;return}!s&&l&&(fe(e),r.removedElements+=1)}}function Ke(e,t,a,r,n){const o=document.createElement("template");o.innerHTML=e;const s={removedElements:0,removedAttributes:0,removedComments:0,normalizedStyles:0};if(r.removeComments)try{const f=document.createTreeWalker(o.content,Ee,null),b=[];let k=f.nextNode();for(;k;)b.push(k),k=f.nextNode();b.forEach(v=>{v.remove(),s.removedComments+=1})}catch{}Array.from(o.content.querySelectorAll("*")).forEach(f=>{f.isConnected&&We(f,t,a,s)});let i=o.innerHTML;r.normalizeWhitespace&&n!=="fidelity"?i=i.replace(/\s{2,}/g," ").replace(/>\s+</g,"><").trim():r.normalizeWhitespace&&(i=i.trim());const c=(o.content.textContent||"").trim().length;return{html:i,textLength:c,counters:s}}function ge(e){const t=window.getSelection();if(!t||t.rangeCount===0)return null;const a=t.getRangeAt(0);return e.contains(a.commonAncestorContainer)?a:null}function he(e,t){if(!e.isConnected)return;const a=window.getSelection();a&&(a.removeAllRanges(),a.addRange(t))}function Ve(e,t){e.focus({preventScroll:!0});try{if(document.execCommand("insertHTML",!1,t))return!0}catch{}const a=ge(e);if(!a)return!1;a.deleteContents();const r=document.createElement("template");r.innerHTML=t;const n=r.content,o=n.lastChild;if(a.insertNode(n),o){const s=document.createRange();s.setStartAfter(o),s.collapse(!0),he(e,s)}return!0}function je(e,t){e.focus({preventScroll:!0});try{if(document.execCommand("insertText",!1,t))return!0}catch{}const a=ge(e);if(!a)return!1;a.deleteContents();const r=document.createTextNode(t);a.insertNode(r);const n=document.createRange();return n.setStart(r,r.length),n.collapse(!0),he(e,n),!0}function Fe(e,t){if(t===e.innerHTML)return;const a=window.execEditorCommand||window.executeEditorCommand;if(typeof a=="function")try{a("recordDomTransaction",e,t,e.innerHTML)}catch{}}function Ge(e){e.dispatchEvent(new Event("input",{bubbles:!0}))}function W(e,t,a,r,n,o){return{source:e,profile:t,inputHtmlLength:a,outputHtmlLength:r,outputTextLength:n,removedElements:o.removedElements,removedAttributes:o.removedAttributes,removedComments:o.removedComments,normalizedStyles:o.normalizedStyles,createdAt:new Date().toISOString()}}function Ue(e,t,a,r){const n=qe(e,t);if(a==="plain"){const l=t||e.replace(/<[^>]*>/g," "),i=J(l,r);return{mode:"text",value:i,report:W(n,a,e.length,0,i.length,{removedElements:0,removedAttributes:0,removedComments:0,normalizedStyles:0})}}if(!e||e.length>r.maxHtmlLength){const l=J(t||e.replace(/<[^>]*>/g," "),r);return{mode:"text",value:l,report:W(n,a,e.length,0,l.length,{removedElements:0,removedAttributes:0,removedComments:0,normalizedStyles:0})}}const o=r.profileOptions[a],s=Ke(e,o,n,r,a);if(!s.html){const l=J(t||e.replace(/<[^>]*>/g," "),r);return{mode:"text",value:l,report:W(n,a,e.length,0,l.length,s.counters)}}return{mode:"html",value:s.html,report:W(n,a,e.length,s.html.length,s.textLength,s.counters)}}function G(e,t){return e==="balanced"?t.balancedText:e==="plain"?t.plainText:t.fidelityText}function ae(e){return e==="fidelity"?"balanced":e==="balanced"?"plain":"fidelity"}function Ye(e,t){e.setAttribute("aria-label",t.labels.panelAriaLabel);const a=e.querySelector(".rte-smart-paste-title");a&&(a.textContent=t.labels.panelTitle);const r=e.querySelector('[data-action="close"]');r&&r.setAttribute("aria-label",t.labels.closeText);const n=e.querySelector('[data-action="toggle-enabled"]');if(n){const Se=n.getAttribute("data-enabled")==="true";n.textContent=Se?t.labels.toggleOnText:t.labels.toggleOffText}const o=e.querySelector('[data-action="cycle-profile"]');o&&(o.textContent=t.labels.cycleProfileText);const s=e.querySelector(".rte-smart-paste-profile-heading");s&&(s.textContent=t.labels.profileLabel);const l=e.querySelector('.rte-smart-paste-profile[role="group"]');l&&l.setAttribute("aria-label",t.labels.profileLabel);const i=e.querySelector('[data-action="set-profile"][data-profile="fidelity"]');i&&(i.textContent=t.labels.fidelityText);const c=e.querySelector('[data-action="set-profile"][data-profile="balanced"]');c&&(c.textContent=t.labels.balancedText);const f=e.querySelector('[data-action="set-profile"][data-profile="plain"]');f&&(f.textContent=t.labels.plainText);const b=e.querySelector(".rte-smart-paste-report-title");b&&(b.textContent=t.labels.lastPasteHeading);const k=e.querySelector(".rte-smart-paste-empty");k&&(k.textContent=t.labels.lastPasteEmptyText);const v=e.querySelector('[data-key="source-label"]');v&&(v.textContent=t.labels.lastPasteSourceLabel);const U=e.querySelector('[data-key="profile-label"]');U&&(U.textContent=t.labels.lastPasteProfileLabel);const M=e.querySelector('[data-key="removed-label"]');M&&(M.textContent=t.labels.lastPasteRemovedLabel);const oe=e.querySelector('[data-key="chars-label"]');oe&&(oe.textContent=t.labels.lastPasteCharsLabel);const ne=e.querySelector(".rte-smart-paste-shortcut");ne&&(ne.textContent=t.labels.shortcutText)}function x(e){const t=g.get(e),a=d.get(e)||$,r=L.get(e);if(!t||!a||!r)return;Ye(t,a);const n=t.querySelector(".rte-smart-paste-status");n&&(n.textContent=r.enabled?a.labels.enabledText:a.labels.disabledText);const o=t.querySelector('[data-action="toggle-enabled"]');o&&(o.setAttribute("data-enabled",r.enabled?"true":"false"),o.textContent=r.enabled?a.labels.toggleOnText:a.labels.toggleOffText,o.setAttribute("aria-pressed",r.enabled?"true":"false")),Array.from(t.querySelectorAll('[data-action="set-profile"][data-profile]')).forEach(v=>{const M=z(v.getAttribute("data-profile"))===r.profile;v.classList.toggle("active",M),v.setAttribute("aria-pressed",M?"true":"false")});const l=t.querySelector(".rte-smart-paste-empty"),i=t.querySelector(".rte-smart-paste-report"),c=t.querySelector('[data-key="source-value"]'),f=t.querySelector('[data-key="profile-value"]'),b=t.querySelector('[data-key="removed-value"]'),k=t.querySelector('[data-key="chars-value"]');if(!r.lastReport){l&&(l.hidden=!1),i&&(i.hidden=!0);return}if(l&&(l.hidden=!0),i&&(i.hidden=!1),c&&(c.textContent=r.lastReport.source),f&&(f.textContent=G(r.lastReport.profile,a.labels)),b){const v=r.lastReport.removedElements+r.lastReport.removedAttributes+r.lastReport.removedComments+r.lastReport.normalizedStyles;b.textContent=String(v)}k&&(k.textContent=String(r.lastReport.outputTextLength))}function Q(e,t){if(!t.classList.contains("show"))return;const a=te(e).getBoundingClientRect(),r=Math.min(window.innerWidth-20,360),n=Math.max(10,window.innerWidth-r-10),o=Math.min(Math.max(10,a.right-r),n),s=Math.max(10,Math.min(window.innerHeight-10,a.top+12));t.style.width=`${r}px`,t.style.left=`${o}px`,t.style.top=`${s}px`,t.style.maxHeight=`${Math.max(240,window.innerHeight-20)}px`}function N(e,t=!1){const a=g.get(e);a&&(a.classList.remove("show"),q.set(e,!1),D(e,"toggleSmartPastePanel",!1),t&&e.focus({preventScroll:!0}))}function Xe(e){const t=g.get(e);if(t)return t;const a=d.get(e)||$||K(),r=`rte-smart-paste-panel-${$e++}`,n=document.createElement("section");return n.className=u,n.id=r,n.setAttribute("role","dialog"),n.setAttribute("aria-modal","false"),n.setAttribute("aria-label",a.labels.panelAriaLabel),n.innerHTML=` | ||
| <header class="rte-smart-paste-header"> | ||
| <h2 class="rte-smart-paste-title">${X(a.labels.panelTitle)}</h2> | ||
| <button type="button" class="rte-smart-paste-icon-btn" data-action="close" aria-label="${X(a.labels.closeText)}">✕</button> | ||
| </header> | ||
| <div class="rte-smart-paste-body"> | ||
| <p class="rte-smart-paste-status"></p> | ||
| <div class="rte-smart-paste-controls"> | ||
| <button type="button" class="rte-smart-paste-btn rte-smart-paste-btn-primary" data-action="toggle-enabled" data-enabled="true"></button> | ||
| <button type="button" class="rte-smart-paste-btn" data-action="cycle-profile"></button> | ||
| </div> | ||
| <div class="rte-smart-paste-profile" role="group" aria-label="${X(a.labels.profileLabel)}"> | ||
| <p class="rte-smart-paste-profile-heading"></p> | ||
| <div class="rte-smart-paste-profile-grid"> | ||
| <button type="button" class="rte-smart-paste-chip" data-action="set-profile" data-profile="fidelity" aria-pressed="false"></button> | ||
| <button type="button" class="rte-smart-paste-chip" data-action="set-profile" data-profile="balanced" aria-pressed="false"></button> | ||
| <button type="button" class="rte-smart-paste-chip" data-action="set-profile" data-profile="plain" aria-pressed="false"></button> | ||
| </div> | ||
| </div> | ||
| <section class="rte-smart-paste-metrics" aria-live="polite"> | ||
| <h3 class="rte-smart-paste-report-title"></h3> | ||
| <p class="rte-smart-paste-empty"></p> | ||
| <dl class="rte-smart-paste-report" hidden> | ||
| <div class="rte-smart-paste-line"><dt data-key="source-label"></dt><dd data-key="source-value"></dd></div> | ||
| <div class="rte-smart-paste-line"><dt data-key="profile-label"></dt><dd data-key="profile-value"></dd></div> | ||
| <div class="rte-smart-paste-line"><dt data-key="removed-label"></dt><dd data-key="removed-value"></dd></div> | ||
| <div class="rte-smart-paste-line"><dt data-key="chars-label"></dt><dd data-key="chars-value"></dd></div> | ||
| </dl> | ||
| </section> | ||
| <p class="rte-smart-paste-shortcut"></p> | ||
| </div> | ||
| <div class="rte-smart-paste-live" aria-live="polite" aria-atomic="true"></div> | ||
| `,n.addEventListener("click",o=>{const l=o.target?.closest("[data-action]");if(!l)return;const i=l.getAttribute("data-action");if(i){if(i==="close"){N(e,!0);return}if(i==="toggle-enabled"){const c=p(e,d.get(e)||a);c.enabled=!c.enabled,D(e,"toggleSmartPasteEnabled",c.enabled),x(e),O(n,c.enabled?a.labels.enabledText:a.labels.disabledText);return}if(i==="cycle-profile"){const c=p(e,d.get(e)||a);c.profile=ae(c.profile),x(e),O(n,`${a.labels.profileLabel}: ${G(c.profile,a.labels)}`);return}if(i==="set-profile"){const c=p(e,d.get(e)||a);c.profile=z(l.getAttribute("data-profile")),x(e),O(n,`${a.labels.profileLabel}: ${G(c.profile,a.labels)}`)}}}),n.addEventListener("keydown",o=>{if(o.key==="Escape"){o.preventDefault(),N(e,!0);return}if(o.key!=="ArrowRight"&&o.key!=="ArrowLeft")return;const s=Array.from(n.querySelectorAll('[data-action="set-profile"][data-profile]'));if(s.length===0)return;const l=s.findIndex(f=>f===document.activeElement);if(l<0)return;const i=o.key==="ArrowRight"?1:-1,c=(l+i+s.length)%s.length;o.preventDefault(),s[c].focus()}),F(n,e),document.body.appendChild(n),g.set(e,n),q.set(e,!1),x(e),n}function ye(e){const t=Xe(e);g.forEach((r,n)=>{n!==e&&N(n,!1)}),t.classList.add("show"),q.set(e,!0),D(e,"toggleSmartPastePanel",!0),F(t,e),Q(e,t),t.querySelector('[data-action="toggle-enabled"]')?.focus()}function xe(e,t){const a=re(e);return(typeof t=="boolean"?t:!a)?ye(e):N(e,!1),!0}function ve(e){return{enabled:e.enabled,profile:e.profile,lastReport:e.lastReport?{...e.lastReport}:null}}function Ze(e,t){const a=d.get(e)||$;if(!a)return!1;const r=p(e,a);if(!r.enabled||de(e)){const b=g.get(e);return b&&de(e)&&O(b,a.labels.readonlyMessage),!1}const n=t.clipboardData;if(!n)return!1;const o=n.getData("text/html")||"",s=n.getData("text/plain")||"";if(!o&&!s)return!1;const l=Ue(o,s,r.profile,a);if(!l.value)return!1;const i=e.innerHTML;if(!(l.mode==="html"?Ve(e,l.value):je(e,l.value)))return!1;r.lastReport={...l.report},L.set(e,r),Fe(e,i),Ge(e),e.dispatchEvent(new CustomEvent("editora:smart-paste",{bubbles:!0,detail:ve(r)})),x(e);const f=g.get(e);if(f){const b=l.report.removedElements+l.report.removedAttributes+l.report.removedComments+l.report.normalizedStyles;O(f,`${a.labels.panelTitle}: ${G(r.profile,a.labels)}. ${a.labels.lastPasteRemovedLabel}: ${b}.`)}return!0}function Je(e){return t=>{t.defaultPrevented||t[ie]===!0||(m=e,!Ze(e,t))||(t[ie]=!0,t.preventDefault(),typeof t.stopImmediatePropagation=="function"?t.stopImmediatePropagation():t.stopPropagation())}}function Qe(e){if(j.has(e))return;const t=Je(e);e.addEventListener("paste",t,!0),j.set(e,t)}function R(e){const t=L.get(e);D(e,"toggleSmartPastePanel",re(e)),D(e,"toggleSmartPasteEnabled",t?.enabled===!0)}function et(e){const t=e.key.toLowerCase();return(e.metaKey||e.ctrlKey)&&e.altKey&&e.shiftKey&&t==="s"}function tt(e){const t=e.key.toLowerCase();return(e.metaKey||e.ctrlKey)&&e.altKey&&e.shiftKey&&t==="v"}function rt(e){const t=e.key.toLowerCase();return(e.metaKey||e.ctrlKey)&&e.altKey&&e.shiftKey&&t==="g"}function at(e){$=e,P||(P=t=>{V();const r=t.target?.closest(y);if(!r)return;const n=d.get(r)||e;p(r,n),d.set(r,n),m=r,R(r);const o=g.get(r);o&&(F(o,r),Q(r,o),x(r))},document.addEventListener("focusin",P,!0)),A||(A=t=>{if(t.defaultPrevented||t.target?.closest(`.${u} input, .${u} textarea, .${u} select`))return;const r=_e(t);if(!r)return;const n=d.get(r)||$||e;if(p(r,n),d.set(r,n),m=r,t.key==="Escape"&&re(r)){t.preventDefault(),N(r,!0);return}if(et(t)){t.preventDefault(),t.stopPropagation(),xe(r);return}if(tt(t)){t.preventDefault(),t.stopPropagation();const o=p(r,n);o.profile=ae(o.profile),x(r);return}if(rt(t)){t.preventDefault(),t.stopPropagation();const o=p(r,n);o.enabled=!o.enabled,R(r),x(r)}},document.addEventListener("keydown",A,!0)),T||(T=()=>{V(),g.forEach((t,a)=>{!a.isConnected||!t.isConnected||(F(t,a),Q(a,t))})},window.addEventListener("scroll",T,!0),window.addEventListener("resize",T)),!w&&typeof MutationObserver<"u"&&document.body&&(w=new MutationObserver(t=>{He(t)&&V()}),w.observe(document.body,{childList:!0,subtree:!0}))}function ot(){P&&(document.removeEventListener("focusin",P,!0),P=null),A&&(document.removeEventListener("keydown",A,!0),A=null),T&&(window.removeEventListener("scroll",T,!0),window.removeEventListener("resize",T),T=null),w&&(w.disconnect(),w=null),g.forEach(e=>e.remove()),g.clear(),_.forEach(e=>me(e)),_.clear(),$=null,m=null}function nt(){if(typeof document>"u"||document.getElementById(le))return;const e=document.createElement("style");e.id=le,e.textContent=` | ||
| .rte-toolbar-group-items.${h}, | ||
| .editora-toolbar-group-items.${h}, | ||
| .rte-toolbar-group-items.${S}, | ||
| .editora-toolbar-group-items.${S} { | ||
| display: flex; | ||
| border: 1px solid #ccc; | ||
| border-radius: 3px; | ||
| background: #fff; | ||
| } | ||
| .rte-toolbar-group-items.${h} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${h} .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${S} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${S} .editora-toolbar-button { | ||
| border: none; | ||
| border-right: 1px solid #ccc; | ||
| border-radius: 0; | ||
| } | ||
| .rte-toolbar-group-items.${h} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${h} .editora-toolbar-item:last-child .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${S} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${S} .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| .rte-toolbar-button[data-command="toggleSmartPasteEnabled"].active, | ||
| .editora-toolbar-button[data-command="toggleSmartPasteEnabled"].active { | ||
| background-color: #ccc; | ||
| } | ||
| ${E} .rte-toolbar-group-items.${h}, | ||
| ${E} .editora-toolbar-group-items.${h}, | ||
| ${E} .rte-toolbar-group-items.${S}, | ||
| ${E} .editora-toolbar-group-items.${S}, | ||
| .${u}.rte-smart-paste-theme-dark { | ||
| border-color: #566275; | ||
| } | ||
| ${E} .rte-toolbar-group-items.${h} .rte-toolbar-button svg, | ||
| ${E} .editora-toolbar-group-items.${h} .editora-toolbar-button svg, | ||
| ${E} .rte-toolbar-group-items.${S} .rte-toolbar-button svg, | ||
| ${E} .editora-toolbar-group-items.${S} .editora-toolbar-button svg { | ||
| fill: none; | ||
| } | ||
| ${E} .rte-toolbar-group-items.${h} .rte-toolbar-button, | ||
| ${E} .editora-toolbar-group-items.${h} .editora-toolbar-button | ||
| { | ||
| border-color: #566275; | ||
| } | ||
| .${u} { | ||
| position: fixed; | ||
| z-index: 12000; | ||
| display: none; | ||
| width: min(360px, calc(100vw - 20px)); | ||
| max-height: calc(100vh - 20px); | ||
| border: 1px solid #d1d5db; | ||
| border-radius: 14px; | ||
| background: #ffffff; | ||
| color: #111827; | ||
| box-shadow: 0 18px 45px rgba(15, 23, 42, 0.25); | ||
| overflow: hidden; | ||
| } | ||
| .${u}.show { | ||
| display: flex; | ||
| flex-direction: column; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark { | ||
| border-color: #334155; | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| box-shadow: 0 20px 46px rgba(2, 6, 23, 0.68); | ||
| } | ||
| .rte-smart-paste-header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| padding: 12px 14px; | ||
| border-bottom: 1px solid #e5e7eb; | ||
| background: linear-gradient(180deg, #f9fafb 0%, #f3f4f6 100%); | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-header { | ||
| border-color: #1e293b; | ||
| background: linear-gradient(180deg, #111827 0%, #0f172a 100%); | ||
| } | ||
| .rte-smart-paste-title { | ||
| margin: 0; | ||
| font-size: 15px; | ||
| line-height: 1.2; | ||
| font-weight: 700; | ||
| } | ||
| .rte-smart-paste-icon-btn { | ||
| width: 34px; | ||
| height: 34px; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| font-weight: 600; | ||
| padding: 0; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| cursor: pointer; | ||
| } | ||
| .rte-smart-paste-icon-btn:hover, | ||
| .rte-smart-paste-icon-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-icon-btn { | ||
| background: #0f172a; | ||
| border-color: #475569; | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-icon-btn:hover, | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-icon-btn:focus-visible { | ||
| border-color: #60a5fa; | ||
| box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.24); | ||
| } | ||
| .rte-smart-paste-body { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 10px; | ||
| padding: 12px; | ||
| overflow: auto; | ||
| } | ||
| .rte-smart-paste-status { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #475569; | ||
| font-weight: 600; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-status { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-smart-paste-controls { | ||
| display: flex; | ||
| gap: 8px; | ||
| flex-wrap: wrap; | ||
| } | ||
| .rte-smart-paste-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| height: 34px; | ||
| padding: 0 10px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| cursor: pointer; | ||
| } | ||
| .rte-smart-paste-btn:hover, | ||
| .rte-smart-paste-btn:focus-visible { | ||
| border-color: #94a3b8; | ||
| background: #f8fafc; | ||
| outline: none; | ||
| } | ||
| .rte-smart-paste-btn-primary { | ||
| border-color: #0284c7; | ||
| background: #0ea5e9; | ||
| color: #f8fafc; | ||
| } | ||
| .rte-smart-paste-btn-primary:hover, | ||
| .rte-smart-paste-btn-primary:focus-visible { | ||
| border-color: #0369a1; | ||
| background: #0284c7; | ||
| color: #ffffff; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-btn { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-btn:hover, | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-btn:focus-visible { | ||
| border-color: #475569; | ||
| background: #1e293b; | ||
| } | ||
| .rte-smart-paste-profile { | ||
| display: grid; | ||
| gap: 6px; | ||
| } | ||
| .rte-smart-paste-profile-heading { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| font-weight: 700; | ||
| color: #334155; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-profile-heading { | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-smart-paste-profile-grid { | ||
| display: grid; | ||
| grid-template-columns: repeat(3, minmax(0, 1fr)); | ||
| gap: 8px; | ||
| } | ||
| .rte-smart-paste-chip { | ||
| height: 34px; | ||
| border-radius: 9px; | ||
| border: 1px solid #cbd5e1; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| cursor: pointer; | ||
| } | ||
| .rte-smart-paste-chip:hover, | ||
| .rte-smart-paste-chip:focus-visible { | ||
| border-color: #0284c7; | ||
| outline: none; | ||
| } | ||
| .rte-smart-paste-chip.active { | ||
| border-color: #0284c7; | ||
| background: rgba(14, 165, 233, 0.14); | ||
| color: #0c4a6e; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-chip { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-chip.active { | ||
| border-color: #38bdf8; | ||
| background: rgba(14, 165, 233, 0.2); | ||
| color: #e0f2fe; | ||
| } | ||
| .rte-smart-paste-metrics { | ||
| border: 1px solid #e2e8f0; | ||
| border-radius: 10px; | ||
| padding: 10px; | ||
| background: #f8fafc; | ||
| display: grid; | ||
| gap: 8px; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-metrics { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| } | ||
| .rte-smart-paste-report-title { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.3; | ||
| font-weight: 700; | ||
| } | ||
| .rte-smart-paste-empty { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #475569; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-empty { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-smart-paste-report { | ||
| margin: 0; | ||
| display: grid; | ||
| gap: 6px; | ||
| } | ||
| .rte-smart-paste-line { | ||
| display: flex; | ||
| justify-content: space-between; | ||
| gap: 10px; | ||
| font-size: 12px; | ||
| line-height: 1.3; | ||
| } | ||
| .rte-smart-paste-line dt { | ||
| margin: 0; | ||
| color: #475569; | ||
| font-weight: 600; | ||
| } | ||
| .rte-smart-paste-line dd { | ||
| margin: 0; | ||
| font-weight: 700; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-line dt { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-smart-paste-shortcut { | ||
| margin: 2px 0 0; | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-shortcut { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-smart-paste-live { | ||
| position: absolute; | ||
| width: 1px; | ||
| height: 1px; | ||
| margin: -1px; | ||
| padding: 0; | ||
| overflow: hidden; | ||
| clip: rect(0 0 0 0); | ||
| border: 0; | ||
| } | ||
| @media (max-width: 768px) { | ||
| .${u} { | ||
| left: 10px !important; | ||
| right: 10px; | ||
| top: 10px !important; | ||
| width: auto !important; | ||
| max-height: calc(100vh - 20px); | ||
| } | ||
| .rte-smart-paste-profile-grid { | ||
| grid-template-columns: 1fr; | ||
| } | ||
| } | ||
| `,document.head.appendChild(e)}const st=(e={})=>{const t=K(e),a=new Set;return nt(),{name:"smartPaste",toolbar:[{id:"smartPasteGroup",label:"Smart Paste",type:"group",command:"smartPaste",items:[{id:"smartPaste",label:"Smart Paste Panel",command:"toggleSmartPastePanel",shortcut:"Mod-Alt-Shift-s",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M8.5 4.5h7l3 3V18a2.5 2.5 0 0 1-2.5 2.5h-7A2.5 2.5 0 0 1 6.5 18V7a2.5 2.5 0 0 1 2-2.45Z" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round"/><path d="M15.5 4.5V8h3" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/><path d="M9.3 12h5.4M9.3 15h5.4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>'},{id:"smartPasteProfile",label:"Cycle Smart Paste Profile",command:"cycleSmartPasteProfile",shortcut:"Mod-Alt-Shift-v",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M4.5 7.5h10" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><circle cx="17.5" cy="7.5" r="2" stroke="currentColor" stroke-width="1.6"/><path d="M4.5 12h5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><circle cx="12.5" cy="12" r="2" stroke="currentColor" stroke-width="1.6"/><path d="M4.5 16.5h12" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><circle cx="9.5" cy="16.5" r="2" stroke="currentColor" stroke-width="1.6"/></svg>'},{id:"smartPasteToggle",label:"Toggle Smart Paste",command:"toggleSmartPasteEnabled",shortcut:"Mod-Alt-Shift-g",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><rect x="3.5" y="8" width="17" height="8" rx="4" stroke="currentColor" stroke-width="1.6"/><circle cx="8" cy="12" r="2.6" fill="currentColor"/><path d="M14.5 12h3" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>'}]}],commands:{smartPaste:(r,n)=>{const o=C(n,!1,!1);if(!o)return!1;const s=d.get(o)||t;return p(o,s),d.set(o,s),m=o,ye(o),!0},toggleSmartPastePanel:(r,n)=>{const o=C(n,!1,!1);if(!o)return!1;const s=d.get(o)||t;return p(o,s),d.set(o,s),m=o,xe(o,typeof r=="boolean"?r:void 0)},cycleSmartPasteProfile:(r,n)=>{const o=C(n,!1,!1);if(!o)return!1;const s=d.get(o)||t,l=p(o,s);return d.set(o,s),l.profile=ae(l.profile),x(o),!0},setSmartPasteProfile:(r,n)=>{const o=C(n,!1,!1);if(!o)return!1;const s=d.get(o)||t,l=p(o,s);return d.set(o,s),l.profile=z(r),x(o),!0},toggleSmartPasteEnabled:(r,n)=>{const o=C(n,!1,!1);if(!o)return!1;const s=d.get(o)||t,l=p(o,s);return d.set(o,s),l.enabled=typeof r=="boolean"?r:!l.enabled,R(o),x(o),!0},setSmartPasteOptions:(r,n)=>{const o=C(n,!1,!1);if(!o||!r||typeof r!="object")return!1;const s=d.get(o)||t,l=ce(s),i=K({...l,...r,labels:{...s.labels,...r.labels||{}},profileOptions:{...l.profileOptions,...r.profileOptions||{},fidelity:{...l.profileOptions?.fidelity||{},...r.profileOptions?.fidelity||{}},balanced:{...l.profileOptions?.balanced||{},...r.profileOptions?.balanced||{}},plain:{...l.profileOptions?.plain||{},...r.profileOptions?.plain||{}}},normalizeText:r.normalizeText||s.normalizeText});d.set(o,i);const c=p(o,i);return typeof r.enabled=="boolean"&&(c.enabled=r.enabled),r.defaultProfile&&(c.profile=z(r.defaultProfile)),x(o),R(o),!0},getSmartPasteState:(r,n)=>{const o=C(n,!1,!1);if(!o)return!1;const s=d.get(o)||t,l=p(o,s),i=ve(l);if(typeof r=="function")try{r(i)}catch{}return o.__smartPasteState=i,o.dispatchEvent(new CustomEvent("editora:smart-paste-state",{bubbles:!0,detail:i})),!0}},keymap:{"Mod-Alt-Shift-s":"toggleSmartPastePanel","Mod-Alt-Shift-S":"toggleSmartPastePanel","Mod-Alt-Shift-v":"cycleSmartPasteProfile","Mod-Alt-Shift-V":"cycleSmartPasteProfile","Mod-Alt-Shift-g":"toggleSmartPasteEnabled","Mod-Alt-Shift-G":"toggleSmartPasteEnabled"},init:function(n){I+=1;const o=this&&typeof this.__pluginConfig=="object"?K({...ce(t),...this.__pluginConfig}):t;at(o);const s=C(n?.editorElement?{editorElement:n.editorElement}:void 0,!1,!1);if(!s)return;m=s,a.add(s);const l=p(s,o);l.enabled=o.enabled,l.profile=o.defaultProfile,d.set(s,o),R(s)},destroy:()=>{a.forEach(r=>be(r)),a.clear(),I=Math.max(0,I-1),!(I>0)&&ot()}}};exports.SmartPastePlugin=st; |
| const y = ".rte-content, .editora-content", ee = "[data-editora-editor], .rte-editor, .editora-editor, editora-editor", se = "__editoraCommandEditorRoot", le = "rte-smart-paste-styles", u = "rte-smart-paste-panel", h = "smart-paste", S = "smartPaste", E = ':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)', Ee = typeof NodeFilter < "u" ? NodeFilter.SHOW_COMMENT : 128, ie = "__editoraSmartPasteHandled", ke = /* @__PURE__ */ new Set([ | ||
| "script", | ||
| "style", | ||
| "meta", | ||
| "link", | ||
| "object", | ||
| "embed", | ||
| "iframe", | ||
| "svg", | ||
| "canvas", | ||
| "math", | ||
| "form", | ||
| "input", | ||
| "button", | ||
| "textarea", | ||
| "select", | ||
| "option" | ||
| ]), Ce = /* @__PURE__ */ new Set(["table", "thead", "tbody", "tfoot", "tr", "td", "th", "colgroup", "col"]), Te = /* @__PURE__ */ new Set(["span", "font"]), Ae = /^(https?:|mailto:|tel:|#|\/)/i, Pe = /^data:image\/(?:png|gif|jpeg|jpg|webp);base64,/i, we = /* @__PURE__ */ new Set([ | ||
| "color", | ||
| "background-color", | ||
| "font-weight", | ||
| "font-style", | ||
| "text-decoration", | ||
| "text-align", | ||
| "font-size", | ||
| "font-family", | ||
| "line-height", | ||
| "letter-spacing", | ||
| "word-spacing", | ||
| "white-space", | ||
| "vertical-align", | ||
| "margin-left", | ||
| "margin-right", | ||
| "margin-top", | ||
| "margin-bottom", | ||
| "padding-left", | ||
| "padding-right", | ||
| "padding-top", | ||
| "padding-bottom", | ||
| "text-indent", | ||
| "border", | ||
| "border-top", | ||
| "border-right", | ||
| "border-bottom", | ||
| "border-left", | ||
| "border-color", | ||
| "border-width", | ||
| "border-style", | ||
| "list-style-type" | ||
| ]), Le = { | ||
| panelTitle: "Smart Paste", | ||
| panelAriaLabel: "Smart paste panel", | ||
| enabledText: "Smart paste is enabled", | ||
| disabledText: "Smart paste is disabled", | ||
| toggleOnText: "Disable Smart Paste", | ||
| toggleOffText: "Enable Smart Paste", | ||
| cycleProfileText: "Cycle Profile", | ||
| profileLabel: "Profile", | ||
| fidelityText: "Fidelity", | ||
| balancedText: "Balanced", | ||
| plainText: "Plain Text", | ||
| lastPasteHeading: "Last Paste Result", | ||
| lastPasteEmptyText: "Paste content to see cleanup metrics.", | ||
| lastPasteSourceLabel: "Source", | ||
| lastPasteProfileLabel: "Profile", | ||
| lastPasteRemovedLabel: "Removed", | ||
| lastPasteCharsLabel: "Output Chars", | ||
| closeText: "Close", | ||
| shortcutText: "Shortcuts: Ctrl/Cmd+Alt+Shift+S/V/G", | ||
| readonlyMessage: "Editor is read-only. Smart paste was skipped." | ||
| }, Y = { | ||
| fidelity: { | ||
| keepStyles: !0, | ||
| keepClasses: !1, | ||
| keepDataAttributes: !1, | ||
| preserveTables: !0 | ||
| }, | ||
| balanced: { | ||
| keepStyles: !1, | ||
| keepClasses: !1, | ||
| keepDataAttributes: !1, | ||
| preserveTables: !0 | ||
| }, | ||
| plain: { | ||
| keepStyles: !1, | ||
| keepClasses: !1, | ||
| keepDataAttributes: !1, | ||
| preserveTables: !1 | ||
| } | ||
| }, d = /* @__PURE__ */ new WeakMap(), L = /* @__PURE__ */ new WeakMap(), g = /* @__PURE__ */ new Map(), q = /* @__PURE__ */ new WeakMap(), j = /* @__PURE__ */ new WeakMap(), z = /* @__PURE__ */ new Set(); | ||
| let I = 0, $e = 0, $ = null, m = null, A = null, P = null, T = null, w = null; | ||
| function X(e) { | ||
| return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); | ||
| } | ||
| function Me(e) { | ||
| return e.replace(/\u00A0/g, " ").replace(/\r\n?/g, ` | ||
| `); | ||
| } | ||
| function _(e) { | ||
| return e === "balanced" || e === "plain" ? e : "fidelity"; | ||
| } | ||
| function Z(e, t) { | ||
| return { | ||
| keepStyles: e?.keepStyles ?? t.keepStyles, | ||
| keepClasses: e?.keepClasses ?? t.keepClasses, | ||
| keepDataAttributes: e?.keepDataAttributes ?? t.keepDataAttributes, | ||
| preserveTables: e?.preserveTables ?? t.preserveTables | ||
| }; | ||
| } | ||
| function K(e = {}) { | ||
| const t = e.profileOptions || {}; | ||
| return { | ||
| enabled: e.enabled !== !1, | ||
| defaultProfile: _(e.defaultProfile), | ||
| maxHtmlLength: Math.max(8e3, Math.min(8e5, Number(e.maxHtmlLength ?? 22e4))), | ||
| removeComments: e.removeComments !== !1, | ||
| normalizeWhitespace: e.normalizeWhitespace !== !1, | ||
| labels: { | ||
| ...Le, | ||
| ...e.labels || {} | ||
| }, | ||
| normalizeText: e.normalizeText || Me, | ||
| profileOptions: { | ||
| fidelity: Z(t.fidelity, Y.fidelity), | ||
| balanced: Z(t.balanced, Y.balanced), | ||
| plain: Z(t.plain, Y.plain) | ||
| } | ||
| }; | ||
| } | ||
| function ce(e) { | ||
| return { | ||
| enabled: e.enabled, | ||
| defaultProfile: e.defaultProfile, | ||
| maxHtmlLength: e.maxHtmlLength, | ||
| removeComments: e.removeComments, | ||
| normalizeWhitespace: e.normalizeWhitespace, | ||
| labels: { ...e.labels }, | ||
| normalizeText: e.normalizeText, | ||
| profileOptions: { | ||
| fidelity: { ...e.profileOptions.fidelity }, | ||
| balanced: { ...e.profileOptions.balanced }, | ||
| plain: { ...e.profileOptions.plain } | ||
| } | ||
| }; | ||
| } | ||
| function te(e) { | ||
| return e.closest(ee) || e; | ||
| } | ||
| function H(e) { | ||
| if (!e) return null; | ||
| if (e.matches(y)) return e; | ||
| const t = e.querySelector(y); | ||
| return t instanceof HTMLElement ? t : null; | ||
| } | ||
| function Oe() { | ||
| if (typeof window > "u") return null; | ||
| const e = window[se]; | ||
| if (!(e instanceof HTMLElement)) return null; | ||
| window[se] = null; | ||
| const t = H(e); | ||
| if (t) return t; | ||
| const a = e.closest(ee); | ||
| if (a) { | ||
| const n = H(a); | ||
| if (n) return n; | ||
| } | ||
| const r = e.closest(y); | ||
| return r instanceof HTMLElement ? r : null; | ||
| } | ||
| function Re(e) { | ||
| const t = e.closest("[data-editora-editor]"); | ||
| if (t && H(t) === e) | ||
| return t; | ||
| let a = e; | ||
| for (; a; ) { | ||
| if (a.matches(ee) && (a === e || H(a) === e)) | ||
| return a; | ||
| a = a.parentElement; | ||
| } | ||
| return te(e); | ||
| } | ||
| function pe(e) { | ||
| return e ? e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement : null; | ||
| } | ||
| function C(e, t = !0, a = !0) { | ||
| if (V(), e?.contentElement instanceof HTMLElement) return e.contentElement; | ||
| if (e?.editorElement instanceof HTMLElement) { | ||
| const s = H(e.editorElement); | ||
| if (s) return s; | ||
| } | ||
| const r = Oe(); | ||
| if (r) return r; | ||
| const n = window.getSelection(); | ||
| if (n && n.rangeCount > 0) { | ||
| const l = pe(n.getRangeAt(0).startContainer)?.closest(y); | ||
| if (l) return l; | ||
| } | ||
| const o = document.activeElement; | ||
| if (o) { | ||
| if (o.matches(y)) return o; | ||
| const s = o.closest(y); | ||
| if (s) return s; | ||
| } | ||
| if (a) { | ||
| if (m && m.isConnected) return m; | ||
| m && !m.isConnected && (m = null); | ||
| } | ||
| return t ? document.querySelector(y) : null; | ||
| } | ||
| function ze(e) { | ||
| const t = e.target; | ||
| if (t) { | ||
| const r = t.closest(y); | ||
| if (r) return r; | ||
| } | ||
| const a = window.getSelection(); | ||
| if (a && a.rangeCount > 0) { | ||
| const n = pe(a.getRangeAt(0).startContainer)?.closest(y); | ||
| if (n) return n; | ||
| } | ||
| return null; | ||
| } | ||
| function B(e) { | ||
| return e ? (e.getAttribute("data-theme") || e.getAttribute("theme") || "").toLowerCase() === "dark" ? !0 : e.classList.contains("dark") || e.classList.contains("editora-theme-dark") || e.classList.contains("rte-theme-dark") : !1; | ||
| } | ||
| function _e(e) { | ||
| const t = te(e); | ||
| if (B(t)) return !0; | ||
| const a = t.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark"); | ||
| return B(a) ? !0 : B(document.documentElement) || B(document.body); | ||
| } | ||
| function F(e, t) { | ||
| e.classList.remove("rte-smart-paste-theme-dark"), _e(t) && e.classList.add("rte-smart-paste-theme-dark"); | ||
| } | ||
| function de(e) { | ||
| return e.getAttribute("contenteditable") === "false" || e.getAttribute("data-readonly") === "true"; | ||
| } | ||
| function D(e, t, a) { | ||
| const r = Re(e); | ||
| Array.from( | ||
| r.querySelectorAll( | ||
| `.rte-toolbar-button[data-command="${t}"], .editora-toolbar-button[data-command="${t}"]` | ||
| ) | ||
| ).forEach((o) => { | ||
| o.classList.toggle("active", a), o.setAttribute("data-active", a ? "true" : "false"), o.setAttribute("aria-pressed", a ? "true" : "false"); | ||
| }); | ||
| } | ||
| function p(e, t) { | ||
| d.has(e) || d.set(e, t); | ||
| let a = L.get(e); | ||
| return a || (a = { | ||
| enabled: t.enabled, | ||
| profile: t.defaultProfile, | ||
| lastReport: null | ||
| }, L.set(e, a)), Qe(e), z.add(e), a; | ||
| } | ||
| function me(e) { | ||
| const t = j.get(e); | ||
| t && (e.removeEventListener("paste", t, !0), j.delete(e)); | ||
| } | ||
| function be(e) { | ||
| me(e), g.get(e)?.remove(), g.delete(e), q.delete(e), d.delete(e), L.delete(e), z.delete(e), m === e && (m = null); | ||
| } | ||
| function V() { | ||
| Array.from(z).forEach((t) => { | ||
| t.isConnected || be(t); | ||
| }); | ||
| } | ||
| function He(e) { | ||
| for (let t = 0; t < e.length; t += 1) { | ||
| const a = e[t]; | ||
| if (!(a.type !== "childList" || a.removedNodes.length === 0)) | ||
| for (let r = 0; r < a.removedNodes.length; r += 1) { | ||
| const n = a.removedNodes[r]; | ||
| if (n.nodeType !== Node.ELEMENT_NODE) continue; | ||
| const o = n; | ||
| if (o.matches?.(y) || o.matches?.(`.${u}`) || o.querySelector?.(y) || o.querySelector?.(`.${u}`)) | ||
| return !0; | ||
| } | ||
| } | ||
| return !1; | ||
| } | ||
| function re(e) { | ||
| return q.get(e) === !0; | ||
| } | ||
| function O(e, t) { | ||
| const a = e.querySelector(".rte-smart-paste-live"); | ||
| a && (a.textContent = t); | ||
| } | ||
| function J(e, t) { | ||
| const a = t.normalizeText(e); | ||
| return t.normalizeWhitespace ? a.split(` | ||
| `).map((n) => n.replace(/[\t ]+/g, " ").trimEnd()).join(` | ||
| `).replace(/\n{3,}/g, ` | ||
| `).trim() : a; | ||
| } | ||
| function De(e) { | ||
| return /class=["'][^"']*Mso|xmlns:w=|urn:schemas-microsoft-com:office|<o:p\b/i.test(e); | ||
| } | ||
| function Ne(e) { | ||
| return /id=["']docs-internal-guid|docs-\w+|data-sheets-value|data-sheets-userformat/i.test(e); | ||
| } | ||
| function qe(e, t) { | ||
| return e ? De(e) ? "word" : Ne(e) ? "google-docs" : "html" : t ? "plain" : "html"; | ||
| } | ||
| function Ie(e) { | ||
| return e.split(/\s+/).map((a) => a.trim()).filter(Boolean).filter((a) => !/^mso/i.test(a)).filter((a) => !/^docs-/i.test(a)).filter((a) => !/^c\d+$/i.test(a)).join(" "); | ||
| } | ||
| function Be(e) { | ||
| if (!e) return { value: "", changed: !1 }; | ||
| const t = e.split(";"), a = []; | ||
| let r = !1; | ||
| return t.forEach((n) => { | ||
| const o = n.indexOf(":"); | ||
| if (o <= 0) { | ||
| n.trim() && (r = !0); | ||
| return; | ||
| } | ||
| const s = n.slice(0, o).trim().toLowerCase(), l = n.slice(o + 1).trim(); | ||
| if (!s || !l) { | ||
| r = !0; | ||
| return; | ||
| } | ||
| if (!we.has(s)) { | ||
| r = !0; | ||
| return; | ||
| } | ||
| if (/expression\s*\(|javascript\s*:|vbscript\s*:|url\s*\(/i.test(l)) { | ||
| r = !0; | ||
| return; | ||
| } | ||
| a.push(`${s}: ${l}`); | ||
| }), { | ||
| value: a.join("; "), | ||
| changed: r | ||
| }; | ||
| } | ||
| function ue(e) { | ||
| const t = e.trim(); | ||
| return t && (Ae.test(t) || Pe.test(t)) ? t : ""; | ||
| } | ||
| function fe(e) { | ||
| const t = e.parentNode; | ||
| if (t) { | ||
| for (; e.firstChild; ) | ||
| t.insertBefore(e.firstChild, e); | ||
| t.removeChild(e); | ||
| } | ||
| } | ||
| function We(e, t, a, r) { | ||
| const n = e.tagName.toLowerCase(); | ||
| if (ke.has(n)) { | ||
| r.removedElements += 1, e.remove(); | ||
| return; | ||
| } | ||
| if (!t.preserveTables && Ce.has(n)) { | ||
| const s = e.textContent || "", l = document.createTextNode(s); | ||
| e.replaceWith(l), r.removedElements += 1; | ||
| return; | ||
| } | ||
| if (Array.from(e.attributes).forEach((s) => { | ||
| const l = s.name.toLowerCase(), i = s.value; | ||
| if (l.startsWith("on")) { | ||
| e.removeAttribute(s.name), r.removedAttributes += 1; | ||
| return; | ||
| } | ||
| if (l === "style") { | ||
| if (!t.keepStyles) { | ||
| e.removeAttribute(s.name), r.removedAttributes += 1; | ||
| return; | ||
| } | ||
| const c = Be(i); | ||
| if (!c.value) { | ||
| e.removeAttribute(s.name), r.removedAttributes += 1, c.changed && (r.normalizedStyles += 1); | ||
| return; | ||
| } | ||
| (c.changed || c.value !== i) && (e.setAttribute("style", c.value), r.normalizedStyles += 1); | ||
| return; | ||
| } | ||
| if (l === "class") { | ||
| if (!t.keepClasses) { | ||
| e.removeAttribute(s.name), r.removedAttributes += 1; | ||
| return; | ||
| } | ||
| const c = Ie(i); | ||
| if (!c) { | ||
| e.removeAttribute(s.name), r.removedAttributes += 1; | ||
| return; | ||
| } | ||
| c !== i && (e.setAttribute("class", c), r.removedAttributes += 1); | ||
| return; | ||
| } | ||
| if (l.startsWith("data-") && !t.keepDataAttributes) { | ||
| e.removeAttribute(s.name), r.removedAttributes += 1; | ||
| return; | ||
| } | ||
| if (l === "id" || l === "xmlns" || l.startsWith("xml")) { | ||
| e.removeAttribute(s.name), r.removedAttributes += 1; | ||
| return; | ||
| } | ||
| if ((a === "word" || a === "google-docs") && (l === "lang" || l === "dir")) { | ||
| e.removeAttribute(s.name), r.removedAttributes += 1; | ||
| return; | ||
| } | ||
| if (l === "href" || l === "src" || l === "xlink:href") { | ||
| const c = ue(i); | ||
| if (!c) { | ||
| e.removeAttribute(s.name), r.removedAttributes += 1; | ||
| return; | ||
| } | ||
| c !== i && e.setAttribute(s.name, c); | ||
| } | ||
| }), n === "a") { | ||
| if (!e.getAttribute("href")) { | ||
| fe(e), r.removedElements += 1; | ||
| return; | ||
| } | ||
| e.getAttribute("target") === "_blank" && e.setAttribute("rel", "noopener noreferrer"); | ||
| } | ||
| if (n === "img") { | ||
| const s = e.getAttribute("src"); | ||
| if (!s || !ue(s)) { | ||
| r.removedElements += 1, e.remove(); | ||
| return; | ||
| } | ||
| } | ||
| if (Te.has(n) && !e.attributes.length && !e.className && !e.style.cssText) { | ||
| const s = e.children.length > 0, l = (e.textContent || "").trim().length > 0; | ||
| if (!s && !l) { | ||
| e.remove(), r.removedElements += 1; | ||
| return; | ||
| } | ||
| !s && l && (fe(e), r.removedElements += 1); | ||
| } | ||
| } | ||
| function Ke(e, t, a, r, n) { | ||
| const o = document.createElement("template"); | ||
| o.innerHTML = e; | ||
| const s = { | ||
| removedElements: 0, | ||
| removedAttributes: 0, | ||
| removedComments: 0, | ||
| normalizedStyles: 0 | ||
| }; | ||
| if (r.removeComments) | ||
| try { | ||
| const f = document.createTreeWalker(o.content, Ee, null), b = []; | ||
| let k = f.nextNode(); | ||
| for (; k; ) | ||
| b.push(k), k = f.nextNode(); | ||
| b.forEach((v) => { | ||
| v.remove(), s.removedComments += 1; | ||
| }); | ||
| } catch { | ||
| } | ||
| Array.from(o.content.querySelectorAll("*")).forEach((f) => { | ||
| f.isConnected && We(f, t, a, s); | ||
| }); | ||
| let i = o.innerHTML; | ||
| r.normalizeWhitespace && n !== "fidelity" ? i = i.replace(/\s{2,}/g, " ").replace(/>\s+</g, "><").trim() : r.normalizeWhitespace && (i = i.trim()); | ||
| const c = (o.content.textContent || "").trim().length; | ||
| return { | ||
| html: i, | ||
| textLength: c, | ||
| counters: s | ||
| }; | ||
| } | ||
| function ge(e) { | ||
| const t = window.getSelection(); | ||
| if (!t || t.rangeCount === 0) return null; | ||
| const a = t.getRangeAt(0); | ||
| return e.contains(a.commonAncestorContainer) ? a : null; | ||
| } | ||
| function he(e, t) { | ||
| if (!e.isConnected) return; | ||
| const a = window.getSelection(); | ||
| a && (a.removeAllRanges(), a.addRange(t)); | ||
| } | ||
| function Ve(e, t) { | ||
| e.focus({ preventScroll: !0 }); | ||
| try { | ||
| if (document.execCommand("insertHTML", !1, t)) | ||
| return !0; | ||
| } catch { | ||
| } | ||
| const a = ge(e); | ||
| if (!a) return !1; | ||
| a.deleteContents(); | ||
| const r = document.createElement("template"); | ||
| r.innerHTML = t; | ||
| const n = r.content, o = n.lastChild; | ||
| if (a.insertNode(n), o) { | ||
| const s = document.createRange(); | ||
| s.setStartAfter(o), s.collapse(!0), he(e, s); | ||
| } | ||
| return !0; | ||
| } | ||
| function je(e, t) { | ||
| e.focus({ preventScroll: !0 }); | ||
| try { | ||
| if (document.execCommand("insertText", !1, t)) | ||
| return !0; | ||
| } catch { | ||
| } | ||
| const a = ge(e); | ||
| if (!a) return !1; | ||
| a.deleteContents(); | ||
| const r = document.createTextNode(t); | ||
| a.insertNode(r); | ||
| const n = document.createRange(); | ||
| return n.setStart(r, r.length), n.collapse(!0), he(e, n), !0; | ||
| } | ||
| function Fe(e, t) { | ||
| if (t === e.innerHTML) return; | ||
| const a = window.execEditorCommand || window.executeEditorCommand; | ||
| if (typeof a == "function") | ||
| try { | ||
| a("recordDomTransaction", e, t, e.innerHTML); | ||
| } catch { | ||
| } | ||
| } | ||
| function Ge(e) { | ||
| e.dispatchEvent(new Event("input", { bubbles: !0 })); | ||
| } | ||
| function W(e, t, a, r, n, o) { | ||
| return { | ||
| source: e, | ||
| profile: t, | ||
| inputHtmlLength: a, | ||
| outputHtmlLength: r, | ||
| outputTextLength: n, | ||
| removedElements: o.removedElements, | ||
| removedAttributes: o.removedAttributes, | ||
| removedComments: o.removedComments, | ||
| normalizedStyles: o.normalizedStyles, | ||
| createdAt: (/* @__PURE__ */ new Date()).toISOString() | ||
| }; | ||
| } | ||
| function Ue(e, t, a, r) { | ||
| const n = qe(e, t); | ||
| if (a === "plain") { | ||
| const l = t || e.replace(/<[^>]*>/g, " "), i = J(l, r); | ||
| return { | ||
| mode: "text", | ||
| value: i, | ||
| report: W( | ||
| n, | ||
| a, | ||
| e.length, | ||
| 0, | ||
| i.length, | ||
| { | ||
| removedElements: 0, | ||
| removedAttributes: 0, | ||
| removedComments: 0, | ||
| normalizedStyles: 0 | ||
| } | ||
| ) | ||
| }; | ||
| } | ||
| if (!e || e.length > r.maxHtmlLength) { | ||
| const l = J(t || e.replace(/<[^>]*>/g, " "), r); | ||
| return { | ||
| mode: "text", | ||
| value: l, | ||
| report: W( | ||
| n, | ||
| a, | ||
| e.length, | ||
| 0, | ||
| l.length, | ||
| { | ||
| removedElements: 0, | ||
| removedAttributes: 0, | ||
| removedComments: 0, | ||
| normalizedStyles: 0 | ||
| } | ||
| ) | ||
| }; | ||
| } | ||
| const o = r.profileOptions[a], s = Ke(e, o, n, r, a); | ||
| if (!s.html) { | ||
| const l = J(t || e.replace(/<[^>]*>/g, " "), r); | ||
| return { | ||
| mode: "text", | ||
| value: l, | ||
| report: W(n, a, e.length, 0, l.length, s.counters) | ||
| }; | ||
| } | ||
| return { | ||
| mode: "html", | ||
| value: s.html, | ||
| report: W( | ||
| n, | ||
| a, | ||
| e.length, | ||
| s.html.length, | ||
| s.textLength, | ||
| s.counters | ||
| ) | ||
| }; | ||
| } | ||
| function G(e, t) { | ||
| return e === "balanced" ? t.balancedText : e === "plain" ? t.plainText : t.fidelityText; | ||
| } | ||
| function ae(e) { | ||
| return e === "fidelity" ? "balanced" : e === "balanced" ? "plain" : "fidelity"; | ||
| } | ||
| function Ye(e, t) { | ||
| e.setAttribute("aria-label", t.labels.panelAriaLabel); | ||
| const a = e.querySelector(".rte-smart-paste-title"); | ||
| a && (a.textContent = t.labels.panelTitle); | ||
| const r = e.querySelector('[data-action="close"]'); | ||
| r && r.setAttribute("aria-label", t.labels.closeText); | ||
| const n = e.querySelector('[data-action="toggle-enabled"]'); | ||
| if (n) { | ||
| const Se = n.getAttribute("data-enabled") === "true"; | ||
| n.textContent = Se ? t.labels.toggleOnText : t.labels.toggleOffText; | ||
| } | ||
| const o = e.querySelector('[data-action="cycle-profile"]'); | ||
| o && (o.textContent = t.labels.cycleProfileText); | ||
| const s = e.querySelector(".rte-smart-paste-profile-heading"); | ||
| s && (s.textContent = t.labels.profileLabel); | ||
| const l = e.querySelector('.rte-smart-paste-profile[role="group"]'); | ||
| l && l.setAttribute("aria-label", t.labels.profileLabel); | ||
| const i = e.querySelector('[data-action="set-profile"][data-profile="fidelity"]'); | ||
| i && (i.textContent = t.labels.fidelityText); | ||
| const c = e.querySelector('[data-action="set-profile"][data-profile="balanced"]'); | ||
| c && (c.textContent = t.labels.balancedText); | ||
| const f = e.querySelector('[data-action="set-profile"][data-profile="plain"]'); | ||
| f && (f.textContent = t.labels.plainText); | ||
| const b = e.querySelector(".rte-smart-paste-report-title"); | ||
| b && (b.textContent = t.labels.lastPasteHeading); | ||
| const k = e.querySelector(".rte-smart-paste-empty"); | ||
| k && (k.textContent = t.labels.lastPasteEmptyText); | ||
| const v = e.querySelector('[data-key="source-label"]'); | ||
| v && (v.textContent = t.labels.lastPasteSourceLabel); | ||
| const U = e.querySelector('[data-key="profile-label"]'); | ||
| U && (U.textContent = t.labels.lastPasteProfileLabel); | ||
| const M = e.querySelector('[data-key="removed-label"]'); | ||
| M && (M.textContent = t.labels.lastPasteRemovedLabel); | ||
| const oe = e.querySelector('[data-key="chars-label"]'); | ||
| oe && (oe.textContent = t.labels.lastPasteCharsLabel); | ||
| const ne = e.querySelector(".rte-smart-paste-shortcut"); | ||
| ne && (ne.textContent = t.labels.shortcutText); | ||
| } | ||
| function x(e) { | ||
| const t = g.get(e), a = d.get(e) || $, r = L.get(e); | ||
| if (!t || !a || !r) return; | ||
| Ye(t, a); | ||
| const n = t.querySelector(".rte-smart-paste-status"); | ||
| n && (n.textContent = r.enabled ? a.labels.enabledText : a.labels.disabledText); | ||
| const o = t.querySelector('[data-action="toggle-enabled"]'); | ||
| o && (o.setAttribute("data-enabled", r.enabled ? "true" : "false"), o.textContent = r.enabled ? a.labels.toggleOnText : a.labels.toggleOffText, o.setAttribute("aria-pressed", r.enabled ? "true" : "false")), Array.from( | ||
| t.querySelectorAll('[data-action="set-profile"][data-profile]') | ||
| ).forEach((v) => { | ||
| const M = _(v.getAttribute("data-profile")) === r.profile; | ||
| v.classList.toggle("active", M), v.setAttribute("aria-pressed", M ? "true" : "false"); | ||
| }); | ||
| const l = t.querySelector(".rte-smart-paste-empty"), i = t.querySelector(".rte-smart-paste-report"), c = t.querySelector('[data-key="source-value"]'), f = t.querySelector('[data-key="profile-value"]'), b = t.querySelector('[data-key="removed-value"]'), k = t.querySelector('[data-key="chars-value"]'); | ||
| if (!r.lastReport) { | ||
| l && (l.hidden = !1), i && (i.hidden = !0); | ||
| return; | ||
| } | ||
| if (l && (l.hidden = !0), i && (i.hidden = !1), c && (c.textContent = r.lastReport.source), f && (f.textContent = G(r.lastReport.profile, a.labels)), b) { | ||
| const v = r.lastReport.removedElements + r.lastReport.removedAttributes + r.lastReport.removedComments + r.lastReport.normalizedStyles; | ||
| b.textContent = String(v); | ||
| } | ||
| k && (k.textContent = String(r.lastReport.outputTextLength)); | ||
| } | ||
| function Q(e, t) { | ||
| if (!t.classList.contains("show")) return; | ||
| const a = te(e).getBoundingClientRect(), r = Math.min(window.innerWidth - 20, 360), n = Math.max(10, window.innerWidth - r - 10), o = Math.min(Math.max(10, a.right - r), n), s = Math.max(10, Math.min(window.innerHeight - 10, a.top + 12)); | ||
| t.style.width = `${r}px`, t.style.left = `${o}px`, t.style.top = `${s}px`, t.style.maxHeight = `${Math.max(240, window.innerHeight - 20)}px`; | ||
| } | ||
| function N(e, t = !1) { | ||
| const a = g.get(e); | ||
| a && (a.classList.remove("show"), q.set(e, !1), D(e, "toggleSmartPastePanel", !1), t && e.focus({ preventScroll: !0 })); | ||
| } | ||
| function Xe(e) { | ||
| const t = g.get(e); | ||
| if (t) return t; | ||
| const a = d.get(e) || $ || K(), r = `rte-smart-paste-panel-${$e++}`, n = document.createElement("section"); | ||
| return n.className = u, n.id = r, n.setAttribute("role", "dialog"), n.setAttribute("aria-modal", "false"), n.setAttribute("aria-label", a.labels.panelAriaLabel), n.innerHTML = ` | ||
| <header class="rte-smart-paste-header"> | ||
| <h2 class="rte-smart-paste-title">${X(a.labels.panelTitle)}</h2> | ||
| <button type="button" class="rte-smart-paste-icon-btn" data-action="close" aria-label="${X(a.labels.closeText)}">✕</button> | ||
| </header> | ||
| <div class="rte-smart-paste-body"> | ||
| <p class="rte-smart-paste-status"></p> | ||
| <div class="rte-smart-paste-controls"> | ||
| <button type="button" class="rte-smart-paste-btn rte-smart-paste-btn-primary" data-action="toggle-enabled" data-enabled="true"></button> | ||
| <button type="button" class="rte-smart-paste-btn" data-action="cycle-profile"></button> | ||
| </div> | ||
| <div class="rte-smart-paste-profile" role="group" aria-label="${X(a.labels.profileLabel)}"> | ||
| <p class="rte-smart-paste-profile-heading"></p> | ||
| <div class="rte-smart-paste-profile-grid"> | ||
| <button type="button" class="rte-smart-paste-chip" data-action="set-profile" data-profile="fidelity" aria-pressed="false"></button> | ||
| <button type="button" class="rte-smart-paste-chip" data-action="set-profile" data-profile="balanced" aria-pressed="false"></button> | ||
| <button type="button" class="rte-smart-paste-chip" data-action="set-profile" data-profile="plain" aria-pressed="false"></button> | ||
| </div> | ||
| </div> | ||
| <section class="rte-smart-paste-metrics" aria-live="polite"> | ||
| <h3 class="rte-smart-paste-report-title"></h3> | ||
| <p class="rte-smart-paste-empty"></p> | ||
| <dl class="rte-smart-paste-report" hidden> | ||
| <div class="rte-smart-paste-line"><dt data-key="source-label"></dt><dd data-key="source-value"></dd></div> | ||
| <div class="rte-smart-paste-line"><dt data-key="profile-label"></dt><dd data-key="profile-value"></dd></div> | ||
| <div class="rte-smart-paste-line"><dt data-key="removed-label"></dt><dd data-key="removed-value"></dd></div> | ||
| <div class="rte-smart-paste-line"><dt data-key="chars-label"></dt><dd data-key="chars-value"></dd></div> | ||
| </dl> | ||
| </section> | ||
| <p class="rte-smart-paste-shortcut"></p> | ||
| </div> | ||
| <div class="rte-smart-paste-live" aria-live="polite" aria-atomic="true"></div> | ||
| `, n.addEventListener("click", (o) => { | ||
| const l = o.target?.closest("[data-action]"); | ||
| if (!l) return; | ||
| const i = l.getAttribute("data-action"); | ||
| if (i) { | ||
| if (i === "close") { | ||
| N(e, !0); | ||
| return; | ||
| } | ||
| if (i === "toggle-enabled") { | ||
| const c = p(e, d.get(e) || a); | ||
| c.enabled = !c.enabled, D(e, "toggleSmartPasteEnabled", c.enabled), x(e), O(n, c.enabled ? a.labels.enabledText : a.labels.disabledText); | ||
| return; | ||
| } | ||
| if (i === "cycle-profile") { | ||
| const c = p(e, d.get(e) || a); | ||
| c.profile = ae(c.profile), x(e), O(n, `${a.labels.profileLabel}: ${G(c.profile, a.labels)}`); | ||
| return; | ||
| } | ||
| if (i === "set-profile") { | ||
| const c = p(e, d.get(e) || a); | ||
| c.profile = _(l.getAttribute("data-profile")), x(e), O(n, `${a.labels.profileLabel}: ${G(c.profile, a.labels)}`); | ||
| } | ||
| } | ||
| }), n.addEventListener("keydown", (o) => { | ||
| if (o.key === "Escape") { | ||
| o.preventDefault(), N(e, !0); | ||
| return; | ||
| } | ||
| if (o.key !== "ArrowRight" && o.key !== "ArrowLeft") return; | ||
| const s = Array.from( | ||
| n.querySelectorAll('[data-action="set-profile"][data-profile]') | ||
| ); | ||
| if (s.length === 0) return; | ||
| const l = s.findIndex((f) => f === document.activeElement); | ||
| if (l < 0) return; | ||
| const i = o.key === "ArrowRight" ? 1 : -1, c = (l + i + s.length) % s.length; | ||
| o.preventDefault(), s[c].focus(); | ||
| }), F(n, e), document.body.appendChild(n), g.set(e, n), q.set(e, !1), x(e), n; | ||
| } | ||
| function ye(e) { | ||
| const t = Xe(e); | ||
| g.forEach((r, n) => { | ||
| n !== e && N(n, !1); | ||
| }), t.classList.add("show"), q.set(e, !0), D(e, "toggleSmartPastePanel", !0), F(t, e), Q(e, t), t.querySelector('[data-action="toggle-enabled"]')?.focus(); | ||
| } | ||
| function xe(e, t) { | ||
| const a = re(e); | ||
| return (typeof t == "boolean" ? t : !a) ? ye(e) : N(e, !1), !0; | ||
| } | ||
| function ve(e) { | ||
| return { | ||
| enabled: e.enabled, | ||
| profile: e.profile, | ||
| lastReport: e.lastReport ? { ...e.lastReport } : null | ||
| }; | ||
| } | ||
| function Ze(e, t) { | ||
| const a = d.get(e) || $; | ||
| if (!a) return !1; | ||
| const r = p(e, a); | ||
| if (!r.enabled || de(e)) { | ||
| const b = g.get(e); | ||
| return b && de(e) && O(b, a.labels.readonlyMessage), !1; | ||
| } | ||
| const n = t.clipboardData; | ||
| if (!n) return !1; | ||
| const o = n.getData("text/html") || "", s = n.getData("text/plain") || ""; | ||
| if (!o && !s) return !1; | ||
| const l = Ue(o, s, r.profile, a); | ||
| if (!l.value) return !1; | ||
| const i = e.innerHTML; | ||
| if (!(l.mode === "html" ? Ve(e, l.value) : je(e, l.value))) return !1; | ||
| r.lastReport = { ...l.report }, L.set(e, r), Fe(e, i), Ge(e), e.dispatchEvent( | ||
| new CustomEvent("editora:smart-paste", { | ||
| bubbles: !0, | ||
| detail: ve(r) | ||
| }) | ||
| ), x(e); | ||
| const f = g.get(e); | ||
| if (f) { | ||
| const b = l.report.removedElements + l.report.removedAttributes + l.report.removedComments + l.report.normalizedStyles; | ||
| O( | ||
| f, | ||
| `${a.labels.panelTitle}: ${G(r.profile, a.labels)}. ${a.labels.lastPasteRemovedLabel}: ${b}.` | ||
| ); | ||
| } | ||
| return !0; | ||
| } | ||
| function Je(e) { | ||
| return (t) => { | ||
| t.defaultPrevented || t[ie] === !0 || (m = e, !Ze(e, t)) || (t[ie] = !0, t.preventDefault(), typeof t.stopImmediatePropagation == "function" ? t.stopImmediatePropagation() : t.stopPropagation()); | ||
| }; | ||
| } | ||
| function Qe(e) { | ||
| if (j.has(e)) return; | ||
| const t = Je(e); | ||
| e.addEventListener("paste", t, !0), j.set(e, t); | ||
| } | ||
| function R(e) { | ||
| const t = L.get(e); | ||
| D(e, "toggleSmartPastePanel", re(e)), D(e, "toggleSmartPasteEnabled", t?.enabled === !0); | ||
| } | ||
| function et(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "s"; | ||
| } | ||
| function tt(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "v"; | ||
| } | ||
| function rt(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "g"; | ||
| } | ||
| function at(e) { | ||
| $ = e, A || (A = (t) => { | ||
| V(); | ||
| const r = t.target?.closest(y); | ||
| if (!r) return; | ||
| const n = d.get(r) || e; | ||
| p(r, n), d.set(r, n), m = r, R(r); | ||
| const o = g.get(r); | ||
| o && (F(o, r), Q(r, o), x(r)); | ||
| }, document.addEventListener("focusin", A, !0)), P || (P = (t) => { | ||
| if (t.defaultPrevented || t.target?.closest(`.${u} input, .${u} textarea, .${u} select`)) return; | ||
| const r = ze(t); | ||
| if (!r) return; | ||
| const n = d.get(r) || $ || e; | ||
| if (p(r, n), d.set(r, n), m = r, t.key === "Escape" && re(r)) { | ||
| t.preventDefault(), N(r, !0); | ||
| return; | ||
| } | ||
| if (et(t)) { | ||
| t.preventDefault(), t.stopPropagation(), xe(r); | ||
| return; | ||
| } | ||
| if (tt(t)) { | ||
| t.preventDefault(), t.stopPropagation(); | ||
| const o = p(r, n); | ||
| o.profile = ae(o.profile), x(r); | ||
| return; | ||
| } | ||
| if (rt(t)) { | ||
| t.preventDefault(), t.stopPropagation(); | ||
| const o = p(r, n); | ||
| o.enabled = !o.enabled, R(r), x(r); | ||
| } | ||
| }, document.addEventListener("keydown", P, !0)), T || (T = () => { | ||
| V(), g.forEach((t, a) => { | ||
| !a.isConnected || !t.isConnected || (F(t, a), Q(a, t)); | ||
| }); | ||
| }, window.addEventListener("scroll", T, !0), window.addEventListener("resize", T)), !w && typeof MutationObserver < "u" && document.body && (w = new MutationObserver((t) => { | ||
| He(t) && V(); | ||
| }), w.observe(document.body, { | ||
| childList: !0, | ||
| subtree: !0 | ||
| })); | ||
| } | ||
| function ot() { | ||
| A && (document.removeEventListener("focusin", A, !0), A = null), P && (document.removeEventListener("keydown", P, !0), P = null), T && (window.removeEventListener("scroll", T, !0), window.removeEventListener("resize", T), T = null), w && (w.disconnect(), w = null), g.forEach((e) => e.remove()), g.clear(), z.forEach((e) => me(e)), z.clear(), $ = null, m = null; | ||
| } | ||
| function nt() { | ||
| if (typeof document > "u" || document.getElementById(le)) return; | ||
| const e = document.createElement("style"); | ||
| e.id = le, e.textContent = ` | ||
| .rte-toolbar-group-items.${h}, | ||
| .editora-toolbar-group-items.${h}, | ||
| .rte-toolbar-group-items.${S}, | ||
| .editora-toolbar-group-items.${S} { | ||
| display: flex; | ||
| border: 1px solid #ccc; | ||
| border-radius: 3px; | ||
| background: #fff; | ||
| } | ||
| .rte-toolbar-group-items.${h} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${h} .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${S} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${S} .editora-toolbar-button { | ||
| border: none; | ||
| border-right: 1px solid #ccc; | ||
| border-radius: 0; | ||
| } | ||
| .rte-toolbar-group-items.${h} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${h} .editora-toolbar-item:last-child .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${S} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${S} .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| .rte-toolbar-button[data-command="toggleSmartPasteEnabled"].active, | ||
| .editora-toolbar-button[data-command="toggleSmartPasteEnabled"].active { | ||
| background-color: #ccc; | ||
| } | ||
| ${E} .rte-toolbar-group-items.${h}, | ||
| ${E} .editora-toolbar-group-items.${h}, | ||
| ${E} .rte-toolbar-group-items.${S}, | ||
| ${E} .editora-toolbar-group-items.${S}, | ||
| .${u}.rte-smart-paste-theme-dark { | ||
| border-color: #566275; | ||
| } | ||
| ${E} .rte-toolbar-group-items.${h} .rte-toolbar-button svg, | ||
| ${E} .editora-toolbar-group-items.${h} .editora-toolbar-button svg, | ||
| ${E} .rte-toolbar-group-items.${S} .rte-toolbar-button svg, | ||
| ${E} .editora-toolbar-group-items.${S} .editora-toolbar-button svg { | ||
| fill: none; | ||
| } | ||
| ${E} .rte-toolbar-group-items.${h} .rte-toolbar-button, | ||
| ${E} .editora-toolbar-group-items.${h} .editora-toolbar-button | ||
| { | ||
| border-color: #566275; | ||
| } | ||
| .${u} { | ||
| position: fixed; | ||
| z-index: 12000; | ||
| display: none; | ||
| width: min(360px, calc(100vw - 20px)); | ||
| max-height: calc(100vh - 20px); | ||
| border: 1px solid #d1d5db; | ||
| border-radius: 14px; | ||
| background: #ffffff; | ||
| color: #111827; | ||
| box-shadow: 0 18px 45px rgba(15, 23, 42, 0.25); | ||
| overflow: hidden; | ||
| } | ||
| .${u}.show { | ||
| display: flex; | ||
| flex-direction: column; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark { | ||
| border-color: #334155; | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| box-shadow: 0 20px 46px rgba(2, 6, 23, 0.68); | ||
| } | ||
| .rte-smart-paste-header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| padding: 12px 14px; | ||
| border-bottom: 1px solid #e5e7eb; | ||
| background: linear-gradient(180deg, #f9fafb 0%, #f3f4f6 100%); | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-header { | ||
| border-color: #1e293b; | ||
| background: linear-gradient(180deg, #111827 0%, #0f172a 100%); | ||
| } | ||
| .rte-smart-paste-title { | ||
| margin: 0; | ||
| font-size: 15px; | ||
| line-height: 1.2; | ||
| font-weight: 700; | ||
| } | ||
| .rte-smart-paste-icon-btn { | ||
| width: 34px; | ||
| height: 34px; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| font-weight: 600; | ||
| padding: 0; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| cursor: pointer; | ||
| } | ||
| .rte-smart-paste-icon-btn:hover, | ||
| .rte-smart-paste-icon-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-icon-btn { | ||
| background: #0f172a; | ||
| border-color: #475569; | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-icon-btn:hover, | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-icon-btn:focus-visible { | ||
| border-color: #60a5fa; | ||
| box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.24); | ||
| } | ||
| .rte-smart-paste-body { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 10px; | ||
| padding: 12px; | ||
| overflow: auto; | ||
| } | ||
| .rte-smart-paste-status { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #475569; | ||
| font-weight: 600; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-status { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-smart-paste-controls { | ||
| display: flex; | ||
| gap: 8px; | ||
| flex-wrap: wrap; | ||
| } | ||
| .rte-smart-paste-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| height: 34px; | ||
| padding: 0 10px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| cursor: pointer; | ||
| } | ||
| .rte-smart-paste-btn:hover, | ||
| .rte-smart-paste-btn:focus-visible { | ||
| border-color: #94a3b8; | ||
| background: #f8fafc; | ||
| outline: none; | ||
| } | ||
| .rte-smart-paste-btn-primary { | ||
| border-color: #0284c7; | ||
| background: #0ea5e9; | ||
| color: #f8fafc; | ||
| } | ||
| .rte-smart-paste-btn-primary:hover, | ||
| .rte-smart-paste-btn-primary:focus-visible { | ||
| border-color: #0369a1; | ||
| background: #0284c7; | ||
| color: #ffffff; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-btn { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-btn:hover, | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-btn:focus-visible { | ||
| border-color: #475569; | ||
| background: #1e293b; | ||
| } | ||
| .rte-smart-paste-profile { | ||
| display: grid; | ||
| gap: 6px; | ||
| } | ||
| .rte-smart-paste-profile-heading { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| font-weight: 700; | ||
| color: #334155; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-profile-heading { | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-smart-paste-profile-grid { | ||
| display: grid; | ||
| grid-template-columns: repeat(3, minmax(0, 1fr)); | ||
| gap: 8px; | ||
| } | ||
| .rte-smart-paste-chip { | ||
| height: 34px; | ||
| border-radius: 9px; | ||
| border: 1px solid #cbd5e1; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| font-size: 12px; | ||
| font-weight: 600; | ||
| cursor: pointer; | ||
| } | ||
| .rte-smart-paste-chip:hover, | ||
| .rte-smart-paste-chip:focus-visible { | ||
| border-color: #0284c7; | ||
| outline: none; | ||
| } | ||
| .rte-smart-paste-chip.active { | ||
| border-color: #0284c7; | ||
| background: rgba(14, 165, 233, 0.14); | ||
| color: #0c4a6e; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-chip { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-chip.active { | ||
| border-color: #38bdf8; | ||
| background: rgba(14, 165, 233, 0.2); | ||
| color: #e0f2fe; | ||
| } | ||
| .rte-smart-paste-metrics { | ||
| border: 1px solid #e2e8f0; | ||
| border-radius: 10px; | ||
| padding: 10px; | ||
| background: #f8fafc; | ||
| display: grid; | ||
| gap: 8px; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-metrics { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| } | ||
| .rte-smart-paste-report-title { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.3; | ||
| font-weight: 700; | ||
| } | ||
| .rte-smart-paste-empty { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #475569; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-empty { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-smart-paste-report { | ||
| margin: 0; | ||
| display: grid; | ||
| gap: 6px; | ||
| } | ||
| .rte-smart-paste-line { | ||
| display: flex; | ||
| justify-content: space-between; | ||
| gap: 10px; | ||
| font-size: 12px; | ||
| line-height: 1.3; | ||
| } | ||
| .rte-smart-paste-line dt { | ||
| margin: 0; | ||
| color: #475569; | ||
| font-weight: 600; | ||
| } | ||
| .rte-smart-paste-line dd { | ||
| margin: 0; | ||
| font-weight: 700; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-line dt { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-smart-paste-shortcut { | ||
| margin: 2px 0 0; | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| } | ||
| .${u}.rte-smart-paste-theme-dark .rte-smart-paste-shortcut { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-smart-paste-live { | ||
| position: absolute; | ||
| width: 1px; | ||
| height: 1px; | ||
| margin: -1px; | ||
| padding: 0; | ||
| overflow: hidden; | ||
| clip: rect(0 0 0 0); | ||
| border: 0; | ||
| } | ||
| @media (max-width: 768px) { | ||
| .${u} { | ||
| left: 10px !important; | ||
| right: 10px; | ||
| top: 10px !important; | ||
| width: auto !important; | ||
| max-height: calc(100vh - 20px); | ||
| } | ||
| .rte-smart-paste-profile-grid { | ||
| grid-template-columns: 1fr; | ||
| } | ||
| } | ||
| `, document.head.appendChild(e); | ||
| } | ||
| const st = (e = {}) => { | ||
| const t = K(e), a = /* @__PURE__ */ new Set(); | ||
| return nt(), { | ||
| name: "smartPaste", | ||
| toolbar: [ | ||
| { | ||
| id: "smartPasteGroup", | ||
| label: "Smart Paste", | ||
| type: "group", | ||
| command: "smartPaste", | ||
| items: [ | ||
| { | ||
| id: "smartPaste", | ||
| label: "Smart Paste Panel", | ||
| command: "toggleSmartPastePanel", | ||
| shortcut: "Mod-Alt-Shift-s", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M8.5 4.5h7l3 3V18a2.5 2.5 0 0 1-2.5 2.5h-7A2.5 2.5 0 0 1 6.5 18V7a2.5 2.5 0 0 1 2-2.45Z" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round"/><path d="M15.5 4.5V8h3" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/><path d="M9.3 12h5.4M9.3 15h5.4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>' | ||
| }, | ||
| { | ||
| id: "smartPasteProfile", | ||
| label: "Cycle Smart Paste Profile", | ||
| command: "cycleSmartPasteProfile", | ||
| shortcut: "Mod-Alt-Shift-v", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M4.5 7.5h10" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><circle cx="17.5" cy="7.5" r="2" stroke="currentColor" stroke-width="1.6"/><path d="M4.5 12h5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><circle cx="12.5" cy="12" r="2" stroke="currentColor" stroke-width="1.6"/><path d="M4.5 16.5h12" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><circle cx="9.5" cy="16.5" r="2" stroke="currentColor" stroke-width="1.6"/></svg>' | ||
| }, | ||
| { | ||
| id: "smartPasteToggle", | ||
| label: "Toggle Smart Paste", | ||
| command: "toggleSmartPasteEnabled", | ||
| shortcut: "Mod-Alt-Shift-g", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><rect x="3.5" y="8" width="17" height="8" rx="4" stroke="currentColor" stroke-width="1.6"/><circle cx="8" cy="12" r="2.6" fill="currentColor"/><path d="M14.5 12h3" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>' | ||
| } | ||
| ] | ||
| } | ||
| ], | ||
| commands: { | ||
| smartPaste: (r, n) => { | ||
| const o = C(n, !1, !1); | ||
| if (!o) return !1; | ||
| const s = d.get(o) || t; | ||
| return p(o, s), d.set(o, s), m = o, ye(o), !0; | ||
| }, | ||
| toggleSmartPastePanel: (r, n) => { | ||
| const o = C(n, !1, !1); | ||
| if (!o) return !1; | ||
| const s = d.get(o) || t; | ||
| return p(o, s), d.set(o, s), m = o, xe(o, typeof r == "boolean" ? r : void 0); | ||
| }, | ||
| cycleSmartPasteProfile: (r, n) => { | ||
| const o = C(n, !1, !1); | ||
| if (!o) return !1; | ||
| const s = d.get(o) || t, l = p(o, s); | ||
| return d.set(o, s), l.profile = ae(l.profile), x(o), !0; | ||
| }, | ||
| setSmartPasteProfile: (r, n) => { | ||
| const o = C(n, !1, !1); | ||
| if (!o) return !1; | ||
| const s = d.get(o) || t, l = p(o, s); | ||
| return d.set(o, s), l.profile = _(r), x(o), !0; | ||
| }, | ||
| toggleSmartPasteEnabled: (r, n) => { | ||
| const o = C(n, !1, !1); | ||
| if (!o) return !1; | ||
| const s = d.get(o) || t, l = p(o, s); | ||
| return d.set(o, s), l.enabled = typeof r == "boolean" ? r : !l.enabled, R(o), x(o), !0; | ||
| }, | ||
| setSmartPasteOptions: (r, n) => { | ||
| const o = C(n, !1, !1); | ||
| if (!o || !r || typeof r != "object") return !1; | ||
| const s = d.get(o) || t, l = ce(s), i = K({ | ||
| ...l, | ||
| ...r, | ||
| labels: { | ||
| ...s.labels, | ||
| ...r.labels || {} | ||
| }, | ||
| profileOptions: { | ||
| ...l.profileOptions, | ||
| ...r.profileOptions || {}, | ||
| fidelity: { | ||
| ...l.profileOptions?.fidelity || {}, | ||
| ...r.profileOptions?.fidelity || {} | ||
| }, | ||
| balanced: { | ||
| ...l.profileOptions?.balanced || {}, | ||
| ...r.profileOptions?.balanced || {} | ||
| }, | ||
| plain: { | ||
| ...l.profileOptions?.plain || {}, | ||
| ...r.profileOptions?.plain || {} | ||
| } | ||
| }, | ||
| normalizeText: r.normalizeText || s.normalizeText | ||
| }); | ||
| d.set(o, i); | ||
| const c = p(o, i); | ||
| return typeof r.enabled == "boolean" && (c.enabled = r.enabled), r.defaultProfile && (c.profile = _(r.defaultProfile)), x(o), R(o), !0; | ||
| }, | ||
| getSmartPasteState: (r, n) => { | ||
| const o = C(n, !1, !1); | ||
| if (!o) return !1; | ||
| const s = d.get(o) || t, l = p(o, s), i = ve(l); | ||
| if (typeof r == "function") | ||
| try { | ||
| r(i); | ||
| } catch { | ||
| } | ||
| return o.__smartPasteState = i, o.dispatchEvent( | ||
| new CustomEvent("editora:smart-paste-state", { | ||
| bubbles: !0, | ||
| detail: i | ||
| }) | ||
| ), !0; | ||
| } | ||
| }, | ||
| keymap: { | ||
| "Mod-Alt-Shift-s": "toggleSmartPastePanel", | ||
| "Mod-Alt-Shift-S": "toggleSmartPastePanel", | ||
| "Mod-Alt-Shift-v": "cycleSmartPasteProfile", | ||
| "Mod-Alt-Shift-V": "cycleSmartPasteProfile", | ||
| "Mod-Alt-Shift-g": "toggleSmartPasteEnabled", | ||
| "Mod-Alt-Shift-G": "toggleSmartPasteEnabled" | ||
| }, | ||
| init: function(n) { | ||
| I += 1; | ||
| const o = this && typeof this.__pluginConfig == "object" ? K({ ...ce(t), ...this.__pluginConfig }) : t; | ||
| at(o); | ||
| const s = C( | ||
| n?.editorElement ? { editorElement: n.editorElement } : void 0, | ||
| !1, | ||
| !1 | ||
| ); | ||
| if (!s) return; | ||
| m = s, a.add(s); | ||
| const l = p(s, o); | ||
| l.enabled = o.enabled, l.profile = o.defaultProfile, d.set(s, o), R(s); | ||
| }, | ||
| destroy: () => { | ||
| a.forEach((r) => be(r)), a.clear(), I = Math.max(0, I - 1), !(I > 0) && ot(); | ||
| } | ||
| }; | ||
| }; | ||
| export { | ||
| st as SmartPastePlugin | ||
| }; |
| "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const p=".rte-content, .editora-content",g='.rte-track-insert[data-track-change="insert"]',f='.rte-track-delete[data-track-change="delete"]',x=`${g}, ${f}`,H="__editoraCommandEditorRoot",B=new WeakMap,N=new WeakMap,L=new WeakMap,D=new Set;let q=!1,h=null,j=!1,T={},F=!1;const J=typeof InputEvent<"u"&&typeof InputEvent.prototype=="object"&&"inputType"in InputEvent.prototype,Q=new Set(["IMG","TABLE","VIDEO","AUDIO","SVG","MATH","HR","IFRAME","INPUT","TEXTAREA","SELECT","BUTTON","CANVAS"]);function ee(e){if(!e)return null;const t=e.querySelector('[contenteditable="true"]');return t instanceof HTMLElement?t:null}function te(){if(typeof window>"u")return null;const e=window[H];if(!(e instanceof HTMLElement))return null;window[H]=null;const t=e.closest("[data-editora-editor], .rte-editor, .editora-editor, editora-editor")||(e.matches("[data-editora-editor], .rte-editor, .editora-editor, editora-editor")?e:null);if(t){const r=ee(t);if(r)return r;if(t.getAttribute("contenteditable")==="true")return t}if(e.getAttribute("contenteditable")==="true")return e;const n=e.closest('[contenteditable="true"]');return n instanceof HTMLElement?n:null}function ne(e){if(e?.contentElement instanceof HTMLElement)return e.contentElement;if(e?.editorElement instanceof HTMLElement){const o=e.editorElement;if(o.getAttribute("contenteditable")==="true")return o;const a=o.querySelector('[contenteditable="true"]');if(a instanceof HTMLElement)return a}const t=te();if(t&&document.contains(t))return t;const n=window.getSelection();if(n&&n.rangeCount>0){const o=n.getRangeAt(0).startContainer,c=(o.nodeType===Node.ELEMENT_NODE?o:o.parentElement)?.closest(p);if(c)return c}const r=document.activeElement;if(r){if(r.matches(p))return r;const o=r.closest(p);if(o)return o}return h?.isConnected?h:document.querySelector(p)}function w(e,t){k(e),_(e);let n=B.get(e);return n||(n={enabled:!!t.enabledByDefault,author:t.author?.trim()||"system",includeTimestamp:t.includeTimestamp!==!1},B.set(e,n),n.enabled&&(M(e,n),y(e,n.enabled))),S(e,"toggleTrackChanges",n.enabled),n}function y(e,t){e.classList.toggle("rte-track-changes-enabled",t),t?e.setAttribute("data-track-changes","true"):e.removeAttribute("data-track-changes")}function re(e){return e.closest("[data-editora-editor], .rte-editor, .editora-editor, editora-editor")||e}function S(e,t,n){const r=re(e);Array.from(r.querySelectorAll(`.rte-toolbar-button[data-command="${t}"], .editora-toolbar-button[data-command="${t}"]`)).forEach(a=>{a.classList.toggle("active",n),a.setAttribute("data-active",n?"true":"false"),a.setAttribute("aria-pressed",n?"true":"false"),a.setAttribute("title",n?"Track Changes (On)":"Track Changes (Off)")})}function ae(e){e.dispatchEvent(new Event("input",{bubbles:!0}))}function oe(e,t){if(t===e.innerHTML)return;const n=window.execEditorCommand||window.executeEditorCommand;if(typeof n=="function")try{n("recordDomTransaction",e,t,e.innerHTML)}catch{}}function m(e,t){ae(e),oe(e,t)}function ce(e,t){return e.startContainer===t.startContainer&&e.startOffset===t.startOffset&&e.endContainer===t.endContainer&&e.endOffset===t.endOffset}function G(e){return{author:e.author,timestamp:e.includeTimestamp?new Date().toISOString():""}}function se(e,t){const n=document.createElement("span");n.className="rte-track-insert",n.setAttribute("data-track-change","insert"),n.setAttribute("contenteditable","false");const r=G(t);return n.setAttribute("data-track-author",r.author),r.timestamp&&n.setAttribute("data-track-time",r.timestamp),n.appendChild(document.createTextNode(e)),n}function k(e){Array.from(e.querySelectorAll(g)).forEach(n=>{n.setAttribute("contenteditable","false")})}function E(e){return e?e.nodeType===Node.ELEMENT_NODE?e:e.parentElement:null}function le(e,t){const n=e.startContainer,r=e.startOffset;if(n.nodeType===Node.TEXT_NODE){const o=n,a=o.previousSibling||o.nextSibling;if(a instanceof HTMLElement&&a.matches(g)&&t.contains(a))return a}if(n.nodeType===Node.ELEMENT_NODE){const o=n,a=o.childNodes[r-1];if(a instanceof HTMLElement&&a.matches(g)&&t.contains(a))return a;const c=o.childNodes[r];if(c instanceof HTMLElement&&c.matches(g)&&t.contains(c))return c}return null}function P(e,t,n){const r=t.lastChild;r&&r.nodeType===Node.TEXT_NODE?r.data+=n:t.appendChild(document.createTextNode(n)),C(e,t)}function ie(e,t){const n=document.createElement("span");n.className="rte-track-delete",n.setAttribute("data-track-change","delete"),n.setAttribute("contenteditable","false");const r=G(t);return n.setAttribute("data-track-author",r.author),r.timestamp&&n.setAttribute("data-track-time",r.timestamp),n.appendChild(e),n}function b(e){const t=window.getSelection();if(!t||t.rangeCount===0)return null;const n=t.getRangeAt(0);return e.contains(n.commonAncestorContainer)?n:null}function ue(){F||typeof document>"u"||(F=!0,document.addEventListener("selectionchange",()=>{const e=window.getSelection();if(!e||e.rangeCount===0)return;const t=e.getRangeAt(0),r=E(t.startContainer)?.closest(p)||null;r&&(L.set(r,t.cloneRange()),h=r)},!0))}function C(e,t){if(!t.parentNode){e.focus({preventScroll:!0});return}const n=window.getSelection();if(!n)return;const r=document.createRange();r.setStartAfter(t),r.collapse(!0),n.removeAllRanges(),n.addRange(r),e.focus({preventScroll:!0})}function O(e,t){if(!t.parentNode){e.focus({preventScroll:!0});return}const n=window.getSelection();if(!n)return;const r=document.createRange();r.setStartBefore(t),r.collapse(!0),n.removeAllRanges(),n.addRange(r),e.focus({preventScroll:!0})}function de(e,t,n){const r=window.getSelection();if(!r)return;const o=document.createRange();o.setStart(t,Math.max(0,n)),o.collapse(!0),r.removeAllRanges(),r.addRange(o),e.focus({preventScroll:!0})}function V(e){let t=b(e);if(!t){const c=L.get(e);c&&e.contains(c.commonAncestorContainer)&&(t=c.cloneRange())}if(!t||!t.collapsed)return;const n=E(t.startContainer);if(!n)return;const r=n.closest(g);if(!r||!e.contains(r)||!r.parentNode)return;const o=window.getSelection();if(!o)return;const a=document.createRange();a.setStartAfter(r),a.collapse(!0),o.removeAllRanges(),o.addRange(a),e.focus({preventScroll:!0})}function K(e,t){const n=e.innerHTML;k(e),V(e),e.focus({preventScroll:!0});const r=t==="insertLineBreak"?"insertLineBreak":"insertParagraph",o=document.execCommand(r,!1);return k(e),m(e,n),o!==!1}function fe(e){const t=b(e);if(t&&t.collapsed)return t;const n=L.get(e);return n&&n.collapsed&&e.contains(n.commonAncestorContainer)?n.cloneRange():null}function ge(e){return e.matches(g)||e.matches(f)?(e.textContent||"").replace(/\u200B/g,"").trim().length>0:Q.has(e.tagName)}function W(e,t){if(t!=="insertParagraph")return!1;const n=fe(e);if(!n)return!1;const r=E(n.startContainer);if(!r)return!1;const o=r.closest("li");return!(o instanceof HTMLElement)||!e.contains(o)||(o.textContent||"").replace(/\u200B/g,"").trim().length>0?!1:!Array.from(o.querySelectorAll("*")).some(s=>ge(s))}function me(e){const t=document.createRange(),n=window.getSelection();if(n&&n.rangeCount>0){const r=n.getRangeAt(0);if(e.contains(r.commonAncestorContainer))return t.setStart(r.endContainer,r.endOffset),t.collapse(!0),t}return t.selectNodeContents(e),t.collapse(!1),t}function he(e){return(e.textContent||"").length>0?!0:Array.from(e.childNodes).some(n=>{if(n.nodeType!==Node.ELEMENT_NODE)return!1;const r=n;return["BR","IMG","TABLE","VIDEO","AUDIO","SVG","MATH"].includes(r.tagName)})}function pe(e){return Array.from(e.childNodes).some(t=>{if(t.nodeType===Node.TEXT_NODE)return(t.textContent||"").length>0;if(t.nodeType!==Node.ELEMENT_NODE)return!1;const n=t;return["BR","IMG","TABLE","VIDEO","AUDIO","SVG","MATH"].includes(n.tagName)})}function Ee(e,t,n){if(!e.collapsed)return null;const r=e.startContainer,o=e.startOffset;let a=null;if(r.nodeType===Node.TEXT_NODE){const c=r;t==="backward"&&o===0?a=c.previousSibling:t==="forward"&&o===c.length&&(a=c.nextSibling)}else if(r.nodeType===Node.ELEMENT_NODE){const c=r;t==="backward"&&o>0?a=c.childNodes[o-1]||null:t==="forward"&&o<c.childNodes.length&&(a=c.childNodes[o]||null)}return!(a instanceof HTMLElement)||!a.matches(g)||!n.contains(a)?null:a}function ke(e,t){const n=document.createTreeWalker(e,NodeFilter.SHOW_TEXT),r=[];let o=n.nextNode();for(;o;){const a=o;a.data.length>0&&r.push(a),o=n.nextNode()}return r.length===0?null:t?r[r.length-1]:r[0]}function Te(e,t,n){const r=Ee(t,n,e);return r?v(e,r,n):!1}function v(e,t,n){const r=t.parentNode;if(!r)return!1;const o=Array.prototype.indexOf.call(r.childNodes,t),a=ke(t,n==="backward");return a?(n==="backward"?a.data=a.data.slice(0,-1):a.data=a.data.slice(1),a.data.length===0&&a.remove(),pe(t)?(n==="backward"?C(e,t):O(e,t),!0):(t.remove(),de(e,r,o),!0)):!1}function Z(e){if(e.startContainer!==e.endContainer||e.startContainer.nodeType!==Node.ELEMENT_NODE)return null;const t=e.startContainer;return e.endOffset-e.startOffset!==1?null:t.childNodes[e.startOffset]||null}function I(e,t){const n=Z(e);return!(n instanceof HTMLElement)||!n.matches(f)||!t.contains(n)?null:n}function be(e,t){const n=Z(e);return!(n instanceof HTMLElement)||!n.matches(g)||!t.contains(n)?null:n}function Ce(e,t){if(t.collapsed){const c=E(t.startContainer)?.closest(f);if(c&&e.contains(c)){const s=document.createRange();return s.setStartAfter(c),s.collapse(!0),s}return t}const n=I(t,e);if(n){const a=document.createRange();return a.setStartAfter(n),a.collapse(!0),a}const r=E(t.startContainer)?.closest(f),o=E(t.endContainer)?.closest(f);if(r&&o&&r===o&&e.contains(r)){const a=document.createRange();return a.setStartAfter(r),a.collapse(!0),a}return t}function Ae(e,t){const r=Array.from(t.querySelectorAll(g)).filter(s=>{try{return e.intersectsNode(s)}catch{return!1}});if(r.length!==1)return null;const o=r[0],a=(e.toString()||"").replace(/\s+/g,""),c=(o.textContent||"").replace(/\s+/g,"");return!c||a!==c?null:o}function U(e,t,n){if(t.collapsed)return null;const r=t.cloneContents();if(!he(r))return null;const o=ie(r,n);return t.deleteContents(),t.insertNode(o),C(e,o),o}function Ne(e,t,n){if(!t.collapsed)return t;const r=t.startContainer,o=t.startOffset;if(r.nodeType===Node.TEXT_NODE){const s=r;if(n==="backward"&&o>0){const l=t.cloneRange();return l.setStart(s,o-1),l}if(n==="forward"&&o<s.length){const l=t.cloneRange();return l.setEnd(s,o+1),l}}if(r.nodeType===Node.ELEMENT_NODE){const s=r;if(n==="backward"&&o>0)for(let l=o-1;l>=0;l-=1){const i=s.childNodes[l];if(!i||i instanceof HTMLElement&&i.matches(f))continue;const u=t.cloneRange();if(i.nodeType===Node.TEXT_NODE){const d=i;if(d.length===0)continue;u.setStart(d,d.length-1),u.setEnd(d,d.length)}else u.setStartBefore(i),u.setEndAfter(i);return u}if(n==="forward"&&o<s.childNodes.length)for(let l=o;l<s.childNodes.length;l+=1){const i=s.childNodes[l];if(!i||i instanceof HTMLElement&&i.matches(f))continue;const u=t.cloneRange();if(i.nodeType===Node.TEXT_NODE){const d=i;if(d.length===0)continue;u.setStart(d,0),u.setEnd(d,1)}else u.setStartBefore(i),u.setEndAfter(i);return u}}const a=window.getSelection();if(!a||typeof a.modify!="function")return null;const c=t.cloneRange();a.removeAllRanges(),a.addRange(c);try{if(a.modify("extend",n,"character"),a.rangeCount===0)return null;const s=a.getRangeAt(0).cloneRange();if(s.collapsed||!e.contains(s.commonAncestorContainer))return null;const l=I(s,e);return l?(n==="backward"?O(e,l):C(e,l),null):s}catch{return null}finally{a.removeAllRanges(),a.addRange(c)}}function z(e,t,n){let r=b(e);if(!r)return!1;const o=Ce(e,r.cloneRange());if(!ce(o,r)){const d=window.getSelection();d&&(d.removeAllRanges(),d.addRange(o)),r=o}const a=e.innerHTML;r.collapsed||U(e,r.cloneRange(),t);const s=E(r.startContainer)?.closest(g);if(r.collapsed&&s&&e.contains(s))return P(e,s,n),m(e,a),!0;const l=r.collapsed?le(r,e):null;if(l)return P(e,l,n),m(e,a),!0;const i=me(e),u=se(n,t);return i.insertNode(u),C(e,u),m(e,a),!0}function $(e,t,n){const r=b(e);if(!r)return!1;const o=n.includes("Backward")?"backward":"forward",a=e.innerHTML;if(r.collapsed&&Te(e,r.cloneRange(),o))return m(e,a),!0;const c=be(r,e);if(c&&v(e,c,o))return m(e,a),!0;if(!r.collapsed){const u=Ae(r,e);if(u&&v(e,u,o))return m(e,a),!0}const s=r.collapsed?Ne(e,r.cloneRange(),o):r.cloneRange();if(!s)return!1;const l=I(s,e);return l?(o==="backward"?O(e,l):C(e,l),!0):U(e,s,t)?(_(e),m(e,a),!0):!1}function R(e){const t=e.parentNode;if(t){for(;e.firstChild;)t.insertBefore(e.firstChild,e);t.removeChild(e)}}function _(e){Array.from(e.querySelectorAll(f)).forEach(r=>{r.setAttribute("contenteditable","false"),Array.from(r.querySelectorAll(f)).forEach(a=>{a!==r&&R(a)})});let n=!0;for(;n;)n=!1,Array.from(e.querySelectorAll(f)).forEach(o=>{if(!o.isConnected)return;let a=o.nextSibling;for(;a&&a.nodeType===Node.TEXT_NODE&&!(a.textContent||"").trim();)a=a.nextSibling;if(a instanceof HTMLElement&&a.matches(f)){for(;a.firstChild;)o.appendChild(a.firstChild);a.remove(),n=!0}o.firstChild||(o.remove(),n=!0)})}function Y(e){return Array.from(e.querySelectorAll(x))}function ye(e){const t=b(e);if(!t)return[];const n=new Set,r=t.startContainer.nodeType===Node.ELEMENT_NODE?t.startContainer:t.startContainer.parentElement,o=t.endContainer.nodeType===Node.ELEMENT_NODE?t.endContainer:t.endContainer.parentElement,a=r?.closest(x);a&&e.contains(a)&&n.add(a);const c=o?.closest(x);return c&&e.contains(c)&&n.add(c),Y(e).filter(l=>{try{return t.intersectsNode(l)}catch{return!1}}).forEach(l=>n.add(l)),Array.from(n)}function A(e,t,n){const r=n==="all"?Y(e):ye(e);if(r.length===0)return!1;const o=e.innerHTML;return r.forEach(a=>{if(!a.isConnected)return;const c=a.matches(g),s=a.matches(f);if(!(!c&&!s)){if(t==="accept"){c?R(a):a.remove();return}c?a.remove():(a.removeAttribute("contenteditable"),R(a))}}),_(e),m(e,o),!0}function Se(e){return e instanceof Node&&(e.nodeType===Node.ELEMENT_NODE?e:e.parentElement)?.closest(p)||null}function Me(){j||typeof document>"u"||(j=!0,document.addEventListener("focusin",e=>{if(!T.enabledByDefault)return;const t=Se(e.target);if(!t)return;h=t;const n=w(t,T);n.enabled?(M(t,n),y(t,!0),S(t,"toggleTrackChanges",!0)):k(t)},!0))}function xe(e,t){return n=>{if(!t.enabled||e.getAttribute("data-track-changes")!=="true")return;h=e;const r=n.inputType||"";if(r==="insertParagraph"||r==="insertLineBreak"){if(W(e,r))return;n.preventDefault(),K(e,r);return}if(r.startsWith("delete")){n.preventDefault(),$(e,t,r);return}if(r==="insertText"||r==="insertCompositionText"){const o=n.data||"";if(!o)return;n.preventDefault(),z(e,t,o)}}}function we(e,t){return n=>{if(!t.enabled||e.getAttribute("data-track-changes")!=="true"||n.key!=="Enter"||J)return;const r=n.shiftKey?"insertLineBreak":"insertParagraph";W(e,r)||(h=e,n.preventDefault(),n.stopPropagation(),K(e,r))}}function ve(e,t){return n=>{if(n.__editoraSmartPasteHandled===!0||n.defaultPrevented||!t.enabled||e.getAttribute("data-track-changes")!=="true")return;const r=n.clipboardData?.getData("text/plain")||"";r&&(n.preventDefault(),h=e,z(e,t,r))}}function Re(e,t){return n=>{if(!t.enabled||e.getAttribute("data-track-changes")!=="true")return;const r=b(e);if(!r||r.collapsed)return;const o=r.toString();n.clipboardData&&(n.clipboardData.setData("text/plain",o),n.preventDefault()),h=e,$(e,t,"deleteByCut")}}function M(e,t){if(N.has(e))return;k(e);const n={beforeInput:xe(e,t),keydown:we(e,t),paste:ve(e,t),cut:Re(e,t)};e.addEventListener("beforeinput",n.beforeInput),e.addEventListener("keydown",n.keydown),e.addEventListener("paste",n.paste),e.addEventListener("cut",n.cut),N.set(e,n),D.add(e)}function X(e){const t=N.get(e);t&&(e.removeEventListener("beforeinput",t.beforeInput),e.removeEventListener("keydown",t.keydown),e.removeEventListener("paste",t.paste),e.removeEventListener("cut",t.cut),N.delete(e),D.delete(e))}function Le(){if(q||typeof document>"u")return;q=!0;const e=document.createElement("style");e.id="rte-track-changes-styles",e.textContent=` | ||
| .rte-track-insert[data-track-change="insert"] { | ||
| background: rgba(22, 163, 74, 0.2); | ||
| color: inherit; | ||
| text-decoration: underline; | ||
| text-decoration-color: #16a34a; | ||
| text-decoration-thickness: 2px; | ||
| border-radius: 2px; | ||
| padding: 0 1px; | ||
| white-space: pre-wrap; | ||
| } | ||
| .rte-track-delete[data-track-change="delete"] { | ||
| background: rgba(220, 38, 38, 0.16); | ||
| color: inherit; | ||
| text-decoration: line-through; | ||
| text-decoration-color: #dc2626; | ||
| text-decoration-thickness: 2px; | ||
| border-radius: 2px; | ||
| padding: 0 1px; | ||
| white-space: pre-wrap; | ||
| cursor: pointer; | ||
| } | ||
| .editora-theme-dark .rte-track-insert[data-track-change="insert"], | ||
| .rte-theme-dark .rte-track-insert[data-track-change="insert"] { | ||
| background: rgba(74, 222, 128, 0.2); | ||
| text-decoration-color: #4ade80; | ||
| } | ||
| .editora-theme-dark .rte-track-delete[data-track-change="delete"], | ||
| .rte-theme-dark .rte-track-delete[data-track-change="delete"] { | ||
| background: rgba(248, 113, 113, 0.18); | ||
| text-decoration-color: #f87171; | ||
| } | ||
| .rte-content[data-track-changes="true"], | ||
| .editora-content[data-track-changes="true"] { | ||
| caret-color: currentColor; | ||
| } | ||
| .rte-toolbar-group-items.track-changes, | ||
| .editora-toolbar-group-items.track-changes { | ||
| display: flex; | ||
| border: 1px solid #ccc; | ||
| border-radius: 3px; | ||
| background: #fff; | ||
| } | ||
| .rte-toolbar-group-items.track-changes .rte-toolbar-button, | ||
| .editora-toolbar-group-items.track-changes .editora-toolbar-button { | ||
| border: none; | ||
| border-radius: 0px; | ||
| } | ||
| .rte-toolbar-group-items.track-changes .rte-toolbar-button, | ||
| .editora-toolbar-group-items.track-changes .editora-toolbar-button { | ||
| border-right: 1px solid #ccc; | ||
| } | ||
| .rte-toolbar-group-items.track-changes .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.track-changes .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| :is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark) .rte-toolbar-group-items.track-changes, | ||
| :is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark) .editora-toolbar-group-items.track-changes { | ||
| border-color: #566275; | ||
| } | ||
| :is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark) .rte-toolbar-group-items.track-changes .rte-toolbar-button, | ||
| :is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark) .editora-toolbar-group-items.track-changes .editora-toolbar-button { | ||
| border-right-color: #566275; | ||
| } | ||
| .rte-toolbar-button[data-command="toggleTrackChanges"].active, | ||
| .editora-toolbar-button[data-command="toggleTrackChanges"].active { | ||
| background-color: #ccc; | ||
| } | ||
| `,document.head.appendChild(e)}const De=(e={})=>{Le(),ue(),T={...T,...e},Me(),T.enabledByDefault&&typeof document<"u"&&(typeof requestAnimationFrame=="function"?requestAnimationFrame:o=>window.setTimeout(o,0))(()=>{Array.from(document.querySelectorAll(p)).forEach(a=>{const c=w(a,T);c.enabled?(M(a,c),y(a,!0),S(a,"toggleTrackChanges",!0)):k(a)})});const t=r=>{const o=ne(r);return o?(h=o,o):null},n=r=>{const o=t(r);if(!o)return null;const a=w(o,e);return{editor:o,state:a}};return{name:"trackChanges",toolbar:[{label:"Track Changes",command:"toggleTrackChanges",type:"group",items:[{label:"Track Changes",command:"toggleTrackChanges",icon:'<svg width="24" height="24" focusable="false"><path d="M4 6h10a1 1 0 1 1 0 2H4a1 1 0 1 1 0-2Zm0 5h7a1 1 0 1 1 0 2H4a1 1 0 1 1 0-2Zm0 5h8a1 1 0 1 1 0 2H4a1 1 0 1 1 0-2Zm13.3-3.6 1.3 1.3 2.9-2.9a1 1 0 1 1 1.4 1.4l-3.6 3.6a1 1 0 0 1-1.4 0l-2-2a1 1 0 1 1 1.4-1.4Z"></path></svg>',shortcut:"Mod-Shift-t"},{label:"Accept All Changes",command:"acceptAllTrackChanges",icon:'<svg width="24" height="24" focusable="false"><path d="M9.2 16.2 5.8 12.8a1 1 0 1 1 1.4-1.4l2.1 2.1 7.5-7.5a1 1 0 1 1 1.4 1.4l-8.2 8.2a1 1 0 0 1-1.4 0Z"></path></svg>'},{label:"Reject All Changes",command:"rejectAllTrackChanges",icon:'<svg width="24" height="24" focusable="false"><path d="M7.8 7.8a1 1 0 0 1 1.4 0L12 10.6l2.8-2.8a1 1 0 1 1 1.4 1.4L13.4 12l2.8 2.8a1 1 0 1 1-1.4 1.4L12 13.4l-2.8 2.8a1 1 0 1 1-1.4-1.4l2.8-2.8-2.8-2.8a1 1 0 0 1 0-1.4Z"></path></svg>'}]}],commands:{toggleTrackChanges:(r,o)=>{const a=n(o);if(!a)return!1;const{editor:c,state:s}=a;return s.enabled=!s.enabled,s.enabled?M(c,s):(X(c),k(c),V(c)),y(c,s.enabled),S(c,"toggleTrackChanges",s.enabled),c.dispatchEvent(new CustomEvent("editora:track-changes-toggle",{bubbles:!0,detail:{enabled:s.enabled,author:s.author}})),s.enabled},acceptAllTrackChanges:(r,o)=>{const a=n(o);return a?A(a.editor,"accept","all"):!1},rejectAllTrackChanges:(r,o)=>{const a=n(o);return a?A(a.editor,"reject","all"):!1},acceptSelectedTrackChanges:(r,o)=>{const a=n(o);return a?A(a.editor,"accept","selection"):!1},rejectSelectedTrackChanges:(r,o)=>{const a=n(o);return a?A(a.editor,"reject","selection"):!1}},keymap:{"Mod-Shift-t":"toggleTrackChanges","Mod-Shift-T":"toggleTrackChanges"},destroy:()=>{Array.from(D).forEach(r=>X(r))}}};exports.TrackChangesPlugin=De; |
| const p = ".rte-content, .editora-content", g = '.rte-track-insert[data-track-change="insert"]', f = '.rte-track-delete[data-track-change="delete"]', x = `${g}, ${f}`, _ = "__editoraCommandEditorRoot", B = /* @__PURE__ */ new WeakMap(), N = /* @__PURE__ */ new WeakMap(), L = /* @__PURE__ */ new WeakMap(), D = /* @__PURE__ */ new Set(); | ||
| let q = !1, h = null, F = !1, T = {}, j = !1; | ||
| const J = typeof InputEvent < "u" && typeof InputEvent.prototype == "object" && "inputType" in InputEvent.prototype, Q = /* @__PURE__ */ new Set([ | ||
| "IMG", | ||
| "TABLE", | ||
| "VIDEO", | ||
| "AUDIO", | ||
| "SVG", | ||
| "MATH", | ||
| "HR", | ||
| "IFRAME", | ||
| "INPUT", | ||
| "TEXTAREA", | ||
| "SELECT", | ||
| "BUTTON", | ||
| "CANVAS" | ||
| ]); | ||
| function ee(e) { | ||
| if (!e) return null; | ||
| const t = e.querySelector('[contenteditable="true"]'); | ||
| return t instanceof HTMLElement ? t : null; | ||
| } | ||
| function te() { | ||
| if (typeof window > "u") return null; | ||
| const e = window[_]; | ||
| if (!(e instanceof HTMLElement)) return null; | ||
| window[_] = null; | ||
| const t = e.closest("[data-editora-editor], .rte-editor, .editora-editor, editora-editor") || (e.matches("[data-editora-editor], .rte-editor, .editora-editor, editora-editor") ? e : null); | ||
| if (t) { | ||
| const r = ee(t); | ||
| if (r) return r; | ||
| if (t.getAttribute("contenteditable") === "true") return t; | ||
| } | ||
| if (e.getAttribute("contenteditable") === "true") | ||
| return e; | ||
| const n = e.closest('[contenteditable="true"]'); | ||
| return n instanceof HTMLElement ? n : null; | ||
| } | ||
| function ne(e) { | ||
| if (e?.contentElement instanceof HTMLElement) return e.contentElement; | ||
| if (e?.editorElement instanceof HTMLElement) { | ||
| const o = e.editorElement; | ||
| if (o.getAttribute("contenteditable") === "true") return o; | ||
| const a = o.querySelector('[contenteditable="true"]'); | ||
| if (a instanceof HTMLElement) return a; | ||
| } | ||
| const t = te(); | ||
| if (t && document.contains(t)) return t; | ||
| const n = window.getSelection(); | ||
| if (n && n.rangeCount > 0) { | ||
| const o = n.getRangeAt(0).startContainer, c = (o.nodeType === Node.ELEMENT_NODE ? o : o.parentElement)?.closest(p); | ||
| if (c) return c; | ||
| } | ||
| const r = document.activeElement; | ||
| if (r) { | ||
| if (r.matches(p)) return r; | ||
| const o = r.closest(p); | ||
| if (o) return o; | ||
| } | ||
| return h?.isConnected ? h : document.querySelector(p); | ||
| } | ||
| function w(e, t) { | ||
| k(e), H(e); | ||
| let n = B.get(e); | ||
| return n || (n = { | ||
| enabled: !!t.enabledByDefault, | ||
| author: t.author?.trim() || "system", | ||
| includeTimestamp: t.includeTimestamp !== !1 | ||
| }, B.set(e, n), n.enabled && (M(e, n), y(e, n.enabled))), S(e, "toggleTrackChanges", n.enabled), n; | ||
| } | ||
| function y(e, t) { | ||
| e.classList.toggle("rte-track-changes-enabled", t), t ? e.setAttribute("data-track-changes", "true") : e.removeAttribute("data-track-changes"); | ||
| } | ||
| function re(e) { | ||
| return e.closest("[data-editora-editor], .rte-editor, .editora-editor, editora-editor") || e; | ||
| } | ||
| function S(e, t, n) { | ||
| const r = re(e); | ||
| Array.from( | ||
| r.querySelectorAll( | ||
| `.rte-toolbar-button[data-command="${t}"], .editora-toolbar-button[data-command="${t}"]` | ||
| ) | ||
| ).forEach((a) => { | ||
| a.classList.toggle("active", n), a.setAttribute("data-active", n ? "true" : "false"), a.setAttribute("aria-pressed", n ? "true" : "false"), a.setAttribute("title", n ? "Track Changes (On)" : "Track Changes (Off)"); | ||
| }); | ||
| } | ||
| function ae(e) { | ||
| e.dispatchEvent(new Event("input", { bubbles: !0 })); | ||
| } | ||
| function oe(e, t) { | ||
| if (t === e.innerHTML) return; | ||
| const n = window.execEditorCommand || window.executeEditorCommand; | ||
| if (typeof n == "function") | ||
| try { | ||
| n("recordDomTransaction", e, t, e.innerHTML); | ||
| } catch { | ||
| } | ||
| } | ||
| function m(e, t) { | ||
| ae(e), oe(e, t); | ||
| } | ||
| function ce(e, t) { | ||
| return e.startContainer === t.startContainer && e.startOffset === t.startOffset && e.endContainer === t.endContainer && e.endOffset === t.endOffset; | ||
| } | ||
| function G(e) { | ||
| return { | ||
| author: e.author, | ||
| timestamp: e.includeTimestamp ? (/* @__PURE__ */ new Date()).toISOString() : "" | ||
| }; | ||
| } | ||
| function se(e, t) { | ||
| const n = document.createElement("span"); | ||
| n.className = "rte-track-insert", n.setAttribute("data-track-change", "insert"), n.setAttribute("contenteditable", "false"); | ||
| const r = G(t); | ||
| return n.setAttribute("data-track-author", r.author), r.timestamp && n.setAttribute("data-track-time", r.timestamp), n.appendChild(document.createTextNode(e)), n; | ||
| } | ||
| function k(e) { | ||
| Array.from(e.querySelectorAll(g)).forEach((n) => { | ||
| n.setAttribute("contenteditable", "false"); | ||
| }); | ||
| } | ||
| function E(e) { | ||
| return e ? e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement : null; | ||
| } | ||
| function le(e, t) { | ||
| const n = e.startContainer, r = e.startOffset; | ||
| if (n.nodeType === Node.TEXT_NODE) { | ||
| const o = n, a = o.previousSibling || o.nextSibling; | ||
| if (a instanceof HTMLElement && a.matches(g) && t.contains(a)) | ||
| return a; | ||
| } | ||
| if (n.nodeType === Node.ELEMENT_NODE) { | ||
| const o = n, a = o.childNodes[r - 1]; | ||
| if (a instanceof HTMLElement && a.matches(g) && t.contains(a)) | ||
| return a; | ||
| const c = o.childNodes[r]; | ||
| if (c instanceof HTMLElement && c.matches(g) && t.contains(c)) | ||
| return c; | ||
| } | ||
| return null; | ||
| } | ||
| function P(e, t, n) { | ||
| const r = t.lastChild; | ||
| r && r.nodeType === Node.TEXT_NODE ? r.data += n : t.appendChild(document.createTextNode(n)), C(e, t); | ||
| } | ||
| function ie(e, t) { | ||
| const n = document.createElement("span"); | ||
| n.className = "rte-track-delete", n.setAttribute("data-track-change", "delete"), n.setAttribute("contenteditable", "false"); | ||
| const r = G(t); | ||
| return n.setAttribute("data-track-author", r.author), r.timestamp && n.setAttribute("data-track-time", r.timestamp), n.appendChild(e), n; | ||
| } | ||
| function b(e) { | ||
| const t = window.getSelection(); | ||
| if (!t || t.rangeCount === 0) return null; | ||
| const n = t.getRangeAt(0); | ||
| return e.contains(n.commonAncestorContainer) ? n : null; | ||
| } | ||
| function ue() { | ||
| j || typeof document > "u" || (j = !0, document.addEventListener( | ||
| "selectionchange", | ||
| () => { | ||
| const e = window.getSelection(); | ||
| if (!e || e.rangeCount === 0) return; | ||
| const t = e.getRangeAt(0), r = E(t.startContainer)?.closest(p) || null; | ||
| r && (L.set(r, t.cloneRange()), h = r); | ||
| }, | ||
| !0 | ||
| )); | ||
| } | ||
| function C(e, t) { | ||
| if (!t.parentNode) { | ||
| e.focus({ preventScroll: !0 }); | ||
| return; | ||
| } | ||
| const n = window.getSelection(); | ||
| if (!n) return; | ||
| const r = document.createRange(); | ||
| r.setStartAfter(t), r.collapse(!0), n.removeAllRanges(), n.addRange(r), e.focus({ preventScroll: !0 }); | ||
| } | ||
| function O(e, t) { | ||
| if (!t.parentNode) { | ||
| e.focus({ preventScroll: !0 }); | ||
| return; | ||
| } | ||
| const n = window.getSelection(); | ||
| if (!n) return; | ||
| const r = document.createRange(); | ||
| r.setStartBefore(t), r.collapse(!0), n.removeAllRanges(), n.addRange(r), e.focus({ preventScroll: !0 }); | ||
| } | ||
| function de(e, t, n) { | ||
| const r = window.getSelection(); | ||
| if (!r) return; | ||
| const o = document.createRange(); | ||
| o.setStart(t, Math.max(0, n)), o.collapse(!0), r.removeAllRanges(), r.addRange(o), e.focus({ preventScroll: !0 }); | ||
| } | ||
| function V(e) { | ||
| let t = b(e); | ||
| if (!t) { | ||
| const c = L.get(e); | ||
| c && e.contains(c.commonAncestorContainer) && (t = c.cloneRange()); | ||
| } | ||
| if (!t || !t.collapsed) return; | ||
| const n = E(t.startContainer); | ||
| if (!n) return; | ||
| const r = n.closest(g); | ||
| if (!r || !e.contains(r) || !r.parentNode) return; | ||
| const o = window.getSelection(); | ||
| if (!o) return; | ||
| const a = document.createRange(); | ||
| a.setStartAfter(r), a.collapse(!0), o.removeAllRanges(), o.addRange(a), e.focus({ preventScroll: !0 }); | ||
| } | ||
| function K(e, t) { | ||
| const n = e.innerHTML; | ||
| k(e), V(e), e.focus({ preventScroll: !0 }); | ||
| const r = t === "insertLineBreak" ? "insertLineBreak" : "insertParagraph", o = document.execCommand(r, !1); | ||
| return k(e), m(e, n), o !== !1; | ||
| } | ||
| function fe(e) { | ||
| const t = b(e); | ||
| if (t && t.collapsed) return t; | ||
| const n = L.get(e); | ||
| return n && n.collapsed && e.contains(n.commonAncestorContainer) ? n.cloneRange() : null; | ||
| } | ||
| function ge(e) { | ||
| return e.matches(g) || e.matches(f) ? (e.textContent || "").replace(/\u200B/g, "").trim().length > 0 : Q.has(e.tagName); | ||
| } | ||
| function W(e, t) { | ||
| if (t !== "insertParagraph") return !1; | ||
| const n = fe(e); | ||
| if (!n) return !1; | ||
| const r = E(n.startContainer); | ||
| if (!r) return !1; | ||
| const o = r.closest("li"); | ||
| return !(o instanceof HTMLElement) || !e.contains(o) || (o.textContent || "").replace(/\u200B/g, "").trim().length > 0 ? !1 : !Array.from(o.querySelectorAll("*")).some( | ||
| (s) => ge(s) | ||
| ); | ||
| } | ||
| function me(e) { | ||
| const t = document.createRange(), n = window.getSelection(); | ||
| if (n && n.rangeCount > 0) { | ||
| const r = n.getRangeAt(0); | ||
| if (e.contains(r.commonAncestorContainer)) | ||
| return t.setStart(r.endContainer, r.endOffset), t.collapse(!0), t; | ||
| } | ||
| return t.selectNodeContents(e), t.collapse(!1), t; | ||
| } | ||
| function he(e) { | ||
| return (e.textContent || "").length > 0 ? !0 : Array.from(e.childNodes).some((n) => { | ||
| if (n.nodeType !== Node.ELEMENT_NODE) return !1; | ||
| const r = n; | ||
| return ["BR", "IMG", "TABLE", "VIDEO", "AUDIO", "SVG", "MATH"].includes(r.tagName); | ||
| }); | ||
| } | ||
| function pe(e) { | ||
| return Array.from(e.childNodes).some((t) => { | ||
| if (t.nodeType === Node.TEXT_NODE) | ||
| return (t.textContent || "").length > 0; | ||
| if (t.nodeType !== Node.ELEMENT_NODE) return !1; | ||
| const n = t; | ||
| return ["BR", "IMG", "TABLE", "VIDEO", "AUDIO", "SVG", "MATH"].includes(n.tagName); | ||
| }); | ||
| } | ||
| function Ee(e, t, n) { | ||
| if (!e.collapsed) return null; | ||
| const r = e.startContainer, o = e.startOffset; | ||
| let a = null; | ||
| if (r.nodeType === Node.TEXT_NODE) { | ||
| const c = r; | ||
| t === "backward" && o === 0 ? a = c.previousSibling : t === "forward" && o === c.length && (a = c.nextSibling); | ||
| } else if (r.nodeType === Node.ELEMENT_NODE) { | ||
| const c = r; | ||
| t === "backward" && o > 0 ? a = c.childNodes[o - 1] || null : t === "forward" && o < c.childNodes.length && (a = c.childNodes[o] || null); | ||
| } | ||
| return !(a instanceof HTMLElement) || !a.matches(g) || !n.contains(a) ? null : a; | ||
| } | ||
| function ke(e, t) { | ||
| const n = document.createTreeWalker(e, NodeFilter.SHOW_TEXT), r = []; | ||
| let o = n.nextNode(); | ||
| for (; o; ) { | ||
| const a = o; | ||
| a.data.length > 0 && r.push(a), o = n.nextNode(); | ||
| } | ||
| return r.length === 0 ? null : t ? r[r.length - 1] : r[0]; | ||
| } | ||
| function Te(e, t, n) { | ||
| const r = Ee(t, n, e); | ||
| return r ? v(e, r, n) : !1; | ||
| } | ||
| function v(e, t, n) { | ||
| const r = t.parentNode; | ||
| if (!r) return !1; | ||
| const o = Array.prototype.indexOf.call(r.childNodes, t), a = ke(t, n === "backward"); | ||
| return a ? (n === "backward" ? a.data = a.data.slice(0, -1) : a.data = a.data.slice(1), a.data.length === 0 && a.remove(), pe(t) ? (n === "backward" ? C(e, t) : O(e, t), !0) : (t.remove(), de(e, r, o), !0)) : !1; | ||
| } | ||
| function Z(e) { | ||
| if (e.startContainer !== e.endContainer || e.startContainer.nodeType !== Node.ELEMENT_NODE) return null; | ||
| const t = e.startContainer; | ||
| return e.endOffset - e.startOffset !== 1 ? null : t.childNodes[e.startOffset] || null; | ||
| } | ||
| function I(e, t) { | ||
| const n = Z(e); | ||
| return !(n instanceof HTMLElement) || !n.matches(f) || !t.contains(n) ? null : n; | ||
| } | ||
| function be(e, t) { | ||
| const n = Z(e); | ||
| return !(n instanceof HTMLElement) || !n.matches(g) || !t.contains(n) ? null : n; | ||
| } | ||
| function Ce(e, t) { | ||
| if (t.collapsed) { | ||
| const c = E(t.startContainer)?.closest(f); | ||
| if (c && e.contains(c)) { | ||
| const s = document.createRange(); | ||
| return s.setStartAfter(c), s.collapse(!0), s; | ||
| } | ||
| return t; | ||
| } | ||
| const n = I(t, e); | ||
| if (n) { | ||
| const a = document.createRange(); | ||
| return a.setStartAfter(n), a.collapse(!0), a; | ||
| } | ||
| const r = E(t.startContainer)?.closest(f), o = E(t.endContainer)?.closest(f); | ||
| if (r && o && r === o && e.contains(r)) { | ||
| const a = document.createRange(); | ||
| return a.setStartAfter(r), a.collapse(!0), a; | ||
| } | ||
| return t; | ||
| } | ||
| function Ae(e, t) { | ||
| const r = Array.from(t.querySelectorAll(g)).filter((s) => { | ||
| try { | ||
| return e.intersectsNode(s); | ||
| } catch { | ||
| return !1; | ||
| } | ||
| }); | ||
| if (r.length !== 1) return null; | ||
| const o = r[0], a = (e.toString() || "").replace(/\s+/g, ""), c = (o.textContent || "").replace(/\s+/g, ""); | ||
| return !c || a !== c ? null : o; | ||
| } | ||
| function U(e, t, n) { | ||
| if (t.collapsed) return null; | ||
| const r = t.cloneContents(); | ||
| if (!he(r)) return null; | ||
| const o = ie(r, n); | ||
| return t.deleteContents(), t.insertNode(o), C(e, o), o; | ||
| } | ||
| function Ne(e, t, n) { | ||
| if (!t.collapsed) return t; | ||
| const r = t.startContainer, o = t.startOffset; | ||
| if (r.nodeType === Node.TEXT_NODE) { | ||
| const s = r; | ||
| if (n === "backward" && o > 0) { | ||
| const l = t.cloneRange(); | ||
| return l.setStart(s, o - 1), l; | ||
| } | ||
| if (n === "forward" && o < s.length) { | ||
| const l = t.cloneRange(); | ||
| return l.setEnd(s, o + 1), l; | ||
| } | ||
| } | ||
| if (r.nodeType === Node.ELEMENT_NODE) { | ||
| const s = r; | ||
| if (n === "backward" && o > 0) | ||
| for (let l = o - 1; l >= 0; l -= 1) { | ||
| const i = s.childNodes[l]; | ||
| if (!i || i instanceof HTMLElement && i.matches(f)) | ||
| continue; | ||
| const u = t.cloneRange(); | ||
| if (i.nodeType === Node.TEXT_NODE) { | ||
| const d = i; | ||
| if (d.length === 0) continue; | ||
| u.setStart(d, d.length - 1), u.setEnd(d, d.length); | ||
| } else | ||
| u.setStartBefore(i), u.setEndAfter(i); | ||
| return u; | ||
| } | ||
| if (n === "forward" && o < s.childNodes.length) | ||
| for (let l = o; l < s.childNodes.length; l += 1) { | ||
| const i = s.childNodes[l]; | ||
| if (!i || i instanceof HTMLElement && i.matches(f)) | ||
| continue; | ||
| const u = t.cloneRange(); | ||
| if (i.nodeType === Node.TEXT_NODE) { | ||
| const d = i; | ||
| if (d.length === 0) continue; | ||
| u.setStart(d, 0), u.setEnd(d, 1); | ||
| } else | ||
| u.setStartBefore(i), u.setEndAfter(i); | ||
| return u; | ||
| } | ||
| } | ||
| const a = window.getSelection(); | ||
| if (!a || typeof a.modify != "function") | ||
| return null; | ||
| const c = t.cloneRange(); | ||
| a.removeAllRanges(), a.addRange(c); | ||
| try { | ||
| if (a.modify("extend", n, "character"), a.rangeCount === 0) | ||
| return null; | ||
| const s = a.getRangeAt(0).cloneRange(); | ||
| if (s.collapsed || !e.contains(s.commonAncestorContainer)) | ||
| return null; | ||
| const l = I(s, e); | ||
| return l ? (n === "backward" ? O(e, l) : C(e, l), null) : s; | ||
| } catch { | ||
| return null; | ||
| } finally { | ||
| a.removeAllRanges(), a.addRange(c); | ||
| } | ||
| } | ||
| function z(e, t, n) { | ||
| let r = b(e); | ||
| if (!r) return !1; | ||
| const o = Ce(e, r.cloneRange()); | ||
| if (!ce(o, r)) { | ||
| const d = window.getSelection(); | ||
| d && (d.removeAllRanges(), d.addRange(o)), r = o; | ||
| } | ||
| const a = e.innerHTML; | ||
| r.collapsed || U(e, r.cloneRange(), t); | ||
| const s = E(r.startContainer)?.closest(g); | ||
| if (r.collapsed && s && e.contains(s)) | ||
| return P(e, s, n), m(e, a), !0; | ||
| const l = r.collapsed ? le(r, e) : null; | ||
| if (l) | ||
| return P(e, l, n), m(e, a), !0; | ||
| const i = me(e), u = se(n, t); | ||
| return i.insertNode(u), C(e, u), m(e, a), !0; | ||
| } | ||
| function $(e, t, n) { | ||
| const r = b(e); | ||
| if (!r) return !1; | ||
| const o = n.includes("Backward") ? "backward" : "forward", a = e.innerHTML; | ||
| if (r.collapsed && Te(e, r.cloneRange(), o)) | ||
| return m(e, a), !0; | ||
| const c = be(r, e); | ||
| if (c && v(e, c, o)) | ||
| return m(e, a), !0; | ||
| if (!r.collapsed) { | ||
| const u = Ae(r, e); | ||
| if (u && v(e, u, o)) | ||
| return m(e, a), !0; | ||
| } | ||
| const s = r.collapsed ? Ne(e, r.cloneRange(), o) : r.cloneRange(); | ||
| if (!s) return !1; | ||
| const l = I(s, e); | ||
| return l ? (o === "backward" ? O(e, l) : C(e, l), !0) : U(e, s, t) ? (H(e), m(e, a), !0) : !1; | ||
| } | ||
| function R(e) { | ||
| const t = e.parentNode; | ||
| if (t) { | ||
| for (; e.firstChild; ) | ||
| t.insertBefore(e.firstChild, e); | ||
| t.removeChild(e); | ||
| } | ||
| } | ||
| function H(e) { | ||
| Array.from(e.querySelectorAll(f)).forEach((r) => { | ||
| r.setAttribute("contenteditable", "false"), Array.from(r.querySelectorAll(f)).forEach((a) => { | ||
| a !== r && R(a); | ||
| }); | ||
| }); | ||
| let n = !0; | ||
| for (; n; ) | ||
| n = !1, Array.from(e.querySelectorAll(f)).forEach((o) => { | ||
| if (!o.isConnected) return; | ||
| let a = o.nextSibling; | ||
| for (; a && a.nodeType === Node.TEXT_NODE && !(a.textContent || "").trim(); ) | ||
| a = a.nextSibling; | ||
| if (a instanceof HTMLElement && a.matches(f)) { | ||
| for (; a.firstChild; ) | ||
| o.appendChild(a.firstChild); | ||
| a.remove(), n = !0; | ||
| } | ||
| o.firstChild || (o.remove(), n = !0); | ||
| }); | ||
| } | ||
| function Y(e) { | ||
| return Array.from(e.querySelectorAll(x)); | ||
| } | ||
| function ye(e) { | ||
| const t = b(e); | ||
| if (!t) return []; | ||
| const n = /* @__PURE__ */ new Set(), r = t.startContainer.nodeType === Node.ELEMENT_NODE ? t.startContainer : t.startContainer.parentElement, o = t.endContainer.nodeType === Node.ELEMENT_NODE ? t.endContainer : t.endContainer.parentElement, a = r?.closest(x); | ||
| a && e.contains(a) && n.add(a); | ||
| const c = o?.closest(x); | ||
| return c && e.contains(c) && n.add(c), Y(e).filter((l) => { | ||
| try { | ||
| return t.intersectsNode(l); | ||
| } catch { | ||
| return !1; | ||
| } | ||
| }).forEach((l) => n.add(l)), Array.from(n); | ||
| } | ||
| function A(e, t, n) { | ||
| const r = n === "all" ? Y(e) : ye(e); | ||
| if (r.length === 0) return !1; | ||
| const o = e.innerHTML; | ||
| return r.forEach((a) => { | ||
| if (!a.isConnected) return; | ||
| const c = a.matches(g), s = a.matches(f); | ||
| if (!(!c && !s)) { | ||
| if (t === "accept") { | ||
| c ? R(a) : a.remove(); | ||
| return; | ||
| } | ||
| c ? a.remove() : (a.removeAttribute("contenteditable"), R(a)); | ||
| } | ||
| }), H(e), m(e, o), !0; | ||
| } | ||
| function Se(e) { | ||
| return e instanceof Node && (e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement)?.closest(p) || null; | ||
| } | ||
| function Me() { | ||
| F || typeof document > "u" || (F = !0, document.addEventListener( | ||
| "focusin", | ||
| (e) => { | ||
| if (!T.enabledByDefault) return; | ||
| const t = Se(e.target); | ||
| if (!t) return; | ||
| h = t; | ||
| const n = w(t, T); | ||
| n.enabled ? (M(t, n), y(t, !0), S(t, "toggleTrackChanges", !0)) : k(t); | ||
| }, | ||
| !0 | ||
| )); | ||
| } | ||
| function xe(e, t) { | ||
| return (n) => { | ||
| if (!t.enabled || e.getAttribute("data-track-changes") !== "true") return; | ||
| h = e; | ||
| const r = n.inputType || ""; | ||
| if (r === "insertParagraph" || r === "insertLineBreak") { | ||
| if (W(e, r)) | ||
| return; | ||
| n.preventDefault(), K(e, r); | ||
| return; | ||
| } | ||
| if (r.startsWith("delete")) { | ||
| n.preventDefault(), $(e, t, r); | ||
| return; | ||
| } | ||
| if (r === "insertText" || r === "insertCompositionText") { | ||
| const o = n.data || ""; | ||
| if (!o) return; | ||
| n.preventDefault(), z(e, t, o); | ||
| } | ||
| }; | ||
| } | ||
| function we(e, t) { | ||
| return (n) => { | ||
| if (!t.enabled || e.getAttribute("data-track-changes") !== "true" || n.key !== "Enter" || J) return; | ||
| const r = n.shiftKey ? "insertLineBreak" : "insertParagraph"; | ||
| W(e, r) || (h = e, n.preventDefault(), n.stopPropagation(), K(e, r)); | ||
| }; | ||
| } | ||
| function ve(e, t) { | ||
| return (n) => { | ||
| if (n.__editoraSmartPasteHandled === !0 || n.defaultPrevented || !t.enabled || e.getAttribute("data-track-changes") !== "true") return; | ||
| const r = n.clipboardData?.getData("text/plain") || ""; | ||
| r && (n.preventDefault(), h = e, z(e, t, r)); | ||
| }; | ||
| } | ||
| function Re(e, t) { | ||
| return (n) => { | ||
| if (!t.enabled || e.getAttribute("data-track-changes") !== "true") return; | ||
| const r = b(e); | ||
| if (!r || r.collapsed) return; | ||
| const o = r.toString(); | ||
| n.clipboardData && (n.clipboardData.setData("text/plain", o), n.preventDefault()), h = e, $(e, t, "deleteByCut"); | ||
| }; | ||
| } | ||
| function M(e, t) { | ||
| if (N.has(e)) return; | ||
| k(e); | ||
| const n = { | ||
| beforeInput: xe(e, t), | ||
| keydown: we(e, t), | ||
| paste: ve(e, t), | ||
| cut: Re(e, t) | ||
| }; | ||
| e.addEventListener("beforeinput", n.beforeInput), e.addEventListener("keydown", n.keydown), e.addEventListener("paste", n.paste), e.addEventListener("cut", n.cut), N.set(e, n), D.add(e); | ||
| } | ||
| function X(e) { | ||
| const t = N.get(e); | ||
| t && (e.removeEventListener("beforeinput", t.beforeInput), e.removeEventListener("keydown", t.keydown), e.removeEventListener("paste", t.paste), e.removeEventListener("cut", t.cut), N.delete(e), D.delete(e)); | ||
| } | ||
| function Le() { | ||
| if (q || typeof document > "u") return; | ||
| q = !0; | ||
| const e = document.createElement("style"); | ||
| e.id = "rte-track-changes-styles", e.textContent = ` | ||
| .rte-track-insert[data-track-change="insert"] { | ||
| background: rgba(22, 163, 74, 0.2); | ||
| color: inherit; | ||
| text-decoration: underline; | ||
| text-decoration-color: #16a34a; | ||
| text-decoration-thickness: 2px; | ||
| border-radius: 2px; | ||
| padding: 0 1px; | ||
| white-space: pre-wrap; | ||
| } | ||
| .rte-track-delete[data-track-change="delete"] { | ||
| background: rgba(220, 38, 38, 0.16); | ||
| color: inherit; | ||
| text-decoration: line-through; | ||
| text-decoration-color: #dc2626; | ||
| text-decoration-thickness: 2px; | ||
| border-radius: 2px; | ||
| padding: 0 1px; | ||
| white-space: pre-wrap; | ||
| cursor: pointer; | ||
| } | ||
| .editora-theme-dark .rte-track-insert[data-track-change="insert"], | ||
| .rte-theme-dark .rte-track-insert[data-track-change="insert"] { | ||
| background: rgba(74, 222, 128, 0.2); | ||
| text-decoration-color: #4ade80; | ||
| } | ||
| .editora-theme-dark .rte-track-delete[data-track-change="delete"], | ||
| .rte-theme-dark .rte-track-delete[data-track-change="delete"] { | ||
| background: rgba(248, 113, 113, 0.18); | ||
| text-decoration-color: #f87171; | ||
| } | ||
| .rte-content[data-track-changes="true"], | ||
| .editora-content[data-track-changes="true"] { | ||
| caret-color: currentColor; | ||
| } | ||
| .rte-toolbar-group-items.track-changes, | ||
| .editora-toolbar-group-items.track-changes { | ||
| display: flex; | ||
| border: 1px solid #ccc; | ||
| border-radius: 3px; | ||
| background: #fff; | ||
| } | ||
| .rte-toolbar-group-items.track-changes .rte-toolbar-button, | ||
| .editora-toolbar-group-items.track-changes .editora-toolbar-button { | ||
| border: none; | ||
| border-radius: 0px; | ||
| } | ||
| .rte-toolbar-group-items.track-changes .rte-toolbar-button, | ||
| .editora-toolbar-group-items.track-changes .editora-toolbar-button { | ||
| border-right: 1px solid #ccc; | ||
| } | ||
| .rte-toolbar-group-items.track-changes .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.track-changes .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| :is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark) .rte-toolbar-group-items.track-changes, | ||
| :is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark) .editora-toolbar-group-items.track-changes { | ||
| border-color: #566275; | ||
| } | ||
| :is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark) .rte-toolbar-group-items.track-changes .rte-toolbar-button, | ||
| :is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark) .editora-toolbar-group-items.track-changes .editora-toolbar-button { | ||
| border-right-color: #566275; | ||
| } | ||
| .rte-toolbar-button[data-command="toggleTrackChanges"].active, | ||
| .editora-toolbar-button[data-command="toggleTrackChanges"].active { | ||
| background-color: #ccc; | ||
| } | ||
| `, document.head.appendChild(e); | ||
| } | ||
| const De = (e = {}) => { | ||
| Le(), ue(), T = { ...T, ...e }, Me(), T.enabledByDefault && typeof document < "u" && (typeof requestAnimationFrame == "function" ? requestAnimationFrame : (o) => window.setTimeout(o, 0))(() => { | ||
| Array.from(document.querySelectorAll(p)).forEach((a) => { | ||
| const c = w(a, T); | ||
| c.enabled ? (M(a, c), y(a, !0), S(a, "toggleTrackChanges", !0)) : k(a); | ||
| }); | ||
| }); | ||
| const t = (r) => { | ||
| const o = ne(r); | ||
| return o ? (h = o, o) : null; | ||
| }, n = (r) => { | ||
| const o = t(r); | ||
| if (!o) return null; | ||
| const a = w(o, e); | ||
| return { editor: o, state: a }; | ||
| }; | ||
| return { | ||
| name: "trackChanges", | ||
| toolbar: [ | ||
| { | ||
| label: "Track Changes", | ||
| command: "toggleTrackChanges", | ||
| type: "group", | ||
| items: [ | ||
| { | ||
| label: "Track Changes", | ||
| command: "toggleTrackChanges", | ||
| icon: '<svg width="24" height="24" focusable="false"><path d="M4 6h10a1 1 0 1 1 0 2H4a1 1 0 1 1 0-2Zm0 5h7a1 1 0 1 1 0 2H4a1 1 0 1 1 0-2Zm0 5h8a1 1 0 1 1 0 2H4a1 1 0 1 1 0-2Zm13.3-3.6 1.3 1.3 2.9-2.9a1 1 0 1 1 1.4 1.4l-3.6 3.6a1 1 0 0 1-1.4 0l-2-2a1 1 0 1 1 1.4-1.4Z"></path></svg>', | ||
| shortcut: "Mod-Shift-t" | ||
| }, | ||
| { | ||
| label: "Accept All Changes", | ||
| command: "acceptAllTrackChanges", | ||
| icon: '<svg width="24" height="24" focusable="false"><path d="M9.2 16.2 5.8 12.8a1 1 0 1 1 1.4-1.4l2.1 2.1 7.5-7.5a1 1 0 1 1 1.4 1.4l-8.2 8.2a1 1 0 0 1-1.4 0Z"></path></svg>' | ||
| }, | ||
| { | ||
| label: "Reject All Changes", | ||
| command: "rejectAllTrackChanges", | ||
| icon: '<svg width="24" height="24" focusable="false"><path d="M7.8 7.8a1 1 0 0 1 1.4 0L12 10.6l2.8-2.8a1 1 0 1 1 1.4 1.4L13.4 12l2.8 2.8a1 1 0 1 1-1.4 1.4L12 13.4l-2.8 2.8a1 1 0 1 1-1.4-1.4l2.8-2.8-2.8-2.8a1 1 0 0 1 0-1.4Z"></path></svg>' | ||
| } | ||
| ] | ||
| } | ||
| ], | ||
| commands: { | ||
| toggleTrackChanges: (r, o) => { | ||
| const a = n(o); | ||
| if (!a) return !1; | ||
| const { editor: c, state: s } = a; | ||
| return s.enabled = !s.enabled, s.enabled ? M(c, s) : (X(c), k(c), V(c)), y(c, s.enabled), S(c, "toggleTrackChanges", s.enabled), c.dispatchEvent(new CustomEvent("editora:track-changes-toggle", { | ||
| bubbles: !0, | ||
| detail: { | ||
| enabled: s.enabled, | ||
| author: s.author | ||
| } | ||
| })), s.enabled; | ||
| }, | ||
| acceptAllTrackChanges: (r, o) => { | ||
| const a = n(o); | ||
| return a ? A(a.editor, "accept", "all") : !1; | ||
| }, | ||
| rejectAllTrackChanges: (r, o) => { | ||
| const a = n(o); | ||
| return a ? A(a.editor, "reject", "all") : !1; | ||
| }, | ||
| acceptSelectedTrackChanges: (r, o) => { | ||
| const a = n(o); | ||
| return a ? A(a.editor, "accept", "selection") : !1; | ||
| }, | ||
| rejectSelectedTrackChanges: (r, o) => { | ||
| const a = n(o); | ||
| return a ? A(a.editor, "reject", "selection") : !1; | ||
| } | ||
| }, | ||
| keymap: { | ||
| "Mod-Shift-t": "toggleTrackChanges", | ||
| "Mod-Shift-T": "toggleTrackChanges" | ||
| }, | ||
| destroy: () => { | ||
| Array.from(D).forEach((r) => X(r)); | ||
| } | ||
| }; | ||
| }; | ||
| export { | ||
| De as TrackChangesPlugin | ||
| }; |
| "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const S=".rte-content, .editora-content",ke="[data-editora-editor], .rte-editor, .editora-editor, editora-editor",Te="__editoraCommandEditorRoot",ve="rte-translation-workflow-styles",u="rte-translation-workflow-panel",y="translation-workflow",$="translationWorkflow",h=':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)',$e=["p","h1","h2","h3","h4","h5","h6","li","td","th","blockquote","figcaption"].join(", "),Me=new Set(["ArrowUp","ArrowDown","Home","End"]),Ee=[{locale:"en",label:"English",minLengthRatio:.6,maxLengthRatio:1.4,requireDifferentFromSource:!1,preserveTokens:!0},{locale:"fr",label:"French",minLengthRatio:.75,maxLengthRatio:1.7,requireDifferentFromSource:!0,preserveTokens:!0},{locale:"de",label:"German",minLengthRatio:.8,maxLengthRatio:1.9,requireDifferentFromSource:!0,preserveTokens:!0},{locale:"es",label:"Spanish",minLengthRatio:.7,maxLengthRatio:1.7,requireDifferentFromSource:!0,preserveTokens:!0},{locale:"it",label:"Italian",minLengthRatio:.7,maxLengthRatio:1.7,requireDifferentFromSource:!0,preserveTokens:!0},{locale:"ja",label:"Japanese",minLengthRatio:.45,maxLengthRatio:1.2,requireDifferentFromSource:!0,preserveTokens:!0},{locale:"zh",label:"Chinese",minLengthRatio:.4,maxLengthRatio:1.2,requireDifferentFromSource:!0,preserveTokens:!0}],Ne={panelTitle:"Translation Workflow",panelAriaLabel:"Translation workflow panel",sourceLocaleLabel:"Source Locale",targetLocaleLabel:"Target Locale",validateText:"Validate Locale",captureSourceText:"Capture Source",lockSelectedText:"Lock Selected",unlockSelectedText:"Unlock Selected",lockSegmentAriaLabel:"Lock segment",unlockSegmentAriaLabel:"Unlock segment",realtimeOnText:"Realtime On",realtimeOffText:"Realtime Off",closeText:"Close",summaryPrefix:"Locale QA",noIssuesText:"No locale validation issues.",issuesLabel:"Locale issues",segmentsLabel:"Segments",sourcePreviewLabel:"Source",targetPreviewLabel:"Target",helperText:"Select segments, lock finalized ones, and run locale validation before handoff.",shortcutText:"Shortcuts: Ctrl/Cmd+Alt+Shift+L (panel), Ctrl/Cmd+Alt+Shift+V (validate), Ctrl/Cmd+Alt+Shift+K (lock segment)",readonlySegmentMessage:"This segment is locked. Unlock before editing.",sourceCapturedMessage:"Source snapshot captured from current content.",selectedSegmentPrefix:"Selected Segment",missingTargetMessage:"Segment is empty in target locale.",tokenMismatchMessage:"Tokens/placeholders do not match source segment.",untranslatedMessage:"Segment appears untranslated (same as source).",lengthOutOfRangeMessage:"Translation length is outside expected locale range."},c=new WeakMap,re=new WeakMap,P=new WeakMap,p=new Map,j=new WeakMap,le=new WeakMap,U=new Set;let X=0,_e=0,Ae=0,Fe=0,k=null,x=null,D=null,z=null,O=null,N=null,I=null,_=null;function m(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function We(e){return e.replace(/\u00A0/g," ").replace(/\s+/g," ").trim()}function C(e,t,r){return Number.isFinite(e)?Math.max(t,Math.min(r,e)):t}function A(e){return(e||"").trim()||"en-US"}function W(e){return e.trim().toLowerCase()}function Ke(e){return e.replace(/"/g,""")}function Ve(e,t=120){return e.length<=t?e:`${e.slice(0,Math.max(0,t-1)).trimEnd()}…`}function Re(e){const t=e.match(/\{\{[^{}]+\}\}|%[A-Z0-9_]+%|\$\{[^{}]+\}/gi);return!t||t.length===0?[]:t.map(r=>r.trim()).filter(Boolean)}function je(e,t){const r=Re(e).sort(),n=Re(t).sort();if(r.length!==n.length)return!1;for(let a=0;a<r.length;a+=1)if(r[a]!==n[a])return!1;return!0}function Ue(e,t){const r=Array.isArray(t)&&t.length>0?t:Ee,n=[],a=new Set;return r.forEach(o=>{const l=W(o.locale||"");if(!l)return;const s=l;a.has(s)||(a.add(s),n.push({locale:s,label:(o.label||l).trim()||l,minLengthRatio:C(Number(o.minLengthRatio??.5),.1,3),maxLengthRatio:C(Number(o.maxLengthRatio??1.8),.2,4),requireDifferentFromSource:o.requireDifferentFromSource!==!1,preserveTokens:o.preserveTokens!==!1}))}),e.forEach(o=>{const l=W(o);if(a.has(l))return;const s=Ee.find(i=>l.startsWith(i.locale));n.push(s?{...s,locale:l,label:o}:{locale:l,label:o,minLengthRatio:.5,maxLengthRatio:1.8,requireDifferentFromSource:!0,preserveTokens:!0})}),n}function oe(e={}){const t=e.normalizeText||We,r=A(e.sourceLocale||"en-US"),n=A(e.targetLocale||"fr-FR"),a=new Set([r,n]);(Array.isArray(e.locales)?e.locales:[]).forEach(s=>{if(typeof s!="string")return;const i=A(s);a.add(i)});const o=Array.from(a),l=Ue(o,e.localeRules);return{sourceLocale:r,targetLocale:n,locales:o,localeRules:l,enableRealtime:e.enableRealtime!==!1,debounceMs:C(Number(e.debounceMs??260),60,2e3),maxIssues:C(Number(e.maxIssues??120),5,1e3),maxSegments:C(Number(e.maxSegments??600),20,3e3),minSourceLengthForRatio:C(Number(e.minSourceLengthForRatio??8),2,100),segmentSelector:(e.segmentSelector||$e).trim()||$e,labels:{...Ne,...e.labels||{}},normalizeText:t}}function Ge(e){return{sourceLocale:e.sourceLocale,targetLocale:e.targetLocale,locales:[...e.locales],localeRules:e.localeRules.map(t=>({locale:t.locale,label:t.label,minLengthRatio:t.minLengthRatio,maxLengthRatio:t.maxLengthRatio,requireDifferentFromSource:t.requireDifferentFromSource,preserveTokens:t.preserveTokens})),enableRealtime:e.enableRealtime,debounceMs:e.debounceMs,maxIssues:e.maxIssues,maxSegments:e.maxSegments,minSourceLengthForRatio:e.minSourceLengthForRatio,segmentSelector:e.segmentSelector,labels:{...e.labels},normalizeText:e.normalizeText}}function xe(e){return e.closest(ke)||e}function K(e){if(!e)return null;if(e.matches(S))return e;const t=e.querySelector(S);return t instanceof HTMLElement?t:null}function Ye(){if(typeof window>"u")return null;const e=window[Te];if(!(e instanceof HTMLElement))return null;window[Te]=null;const t=K(e);if(t)return t;const r=e.closest(ke);if(r){const a=K(r);if(a)return a}const n=e.closest(S);return n instanceof HTMLElement?n:null}function Ze(e){const t=e.closest("[data-editora-editor]");if(t&&K(t)===e)return t;let r=e;for(;r;){if(r.matches(ke)&&(r===e||K(r)===e))return r;r=r.parentElement}return xe(e)}function Ce(e){return e?e.nodeType===Node.ELEMENT_NODE?e:e.parentElement:null}function ee(e){return e?(e.getAttribute("data-theme")||e.getAttribute("theme")||"").toLowerCase()==="dark"?!0:e.classList.contains("dark")||e.classList.contains("editora-theme-dark")||e.classList.contains("rte-theme-dark"):!1}function Je(e){const t=xe(e);if(ee(t))return!0;const r=t.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark");return ee(r)?!0:ee(document.documentElement)||ee(document.body)}function ge(e,t){e.classList.remove("rte-translation-workflow-theme-dark"),Je(t)&&e.classList.add("rte-translation-workflow-theme-dark")}function Qe(e){for(let t=0;t<e.length;t+=1){const r=e[t];if(!(r.type!=="childList"||r.removedNodes.length===0))for(let n=0;n<r.removedNodes.length;n+=1){const a=r.removedNodes[n];if(a.nodeType!==Node.ELEMENT_NODE)continue;const o=a;if(o.matches?.(S)||o.matches?.(`.${u}`)||o.querySelector?.(S)||o.querySelector?.(`.${u}`))return!0}}return!1}function ae(){Array.from(U).forEach(t=>{t.isConnected||Se(t)})}function T(e,t=!0,r=!0){if(ae(),e?.contentElement instanceof HTMLElement)return e.contentElement;if(e?.editorElement instanceof HTMLElement){const s=K(e.editorElement);if(s)return s}const n=Ye();if(n)return n;const a=window.getSelection();if(a&&a.rangeCount>0){const s=Ce(a.getRangeAt(0).startContainer)?.closest(S);if(s)return s}const o=document.activeElement;if(o){if(o.matches(S))return o;const s=o.closest(S);if(s)return s}if(r&&x&&x.isConnected)return x;if(!t)return null;const l=document.querySelector(S);return l instanceof HTMLElement?l:null}function Xe(e){const t=e.target;if(t){const n=t.closest(`.${u}`);if(n){const o=Array.from(p.entries()).find(([,l])=>l===n);if(o)return o[0]}const a=t.closest(S);if(a)return a}const r=document.activeElement;if(r){const n=r.closest(`.${u}`);if(n){const o=Array.from(p.entries()).find(([,l])=>l===n);if(o)return o[0]}const a=r.closest(S);if(a)return a}return null}function fe(e,t,r){const n=Ze(e);Array.from(n.querySelectorAll(`.rte-toolbar-button[data-command="${t}"], .editora-toolbar-button[data-command="${t}"]`)).forEach(o=>{o.classList.toggle("active",r),o.setAttribute("data-active",r?"true":"false"),o.setAttribute("aria-pressed",r?"true":"false")})}function we(e){const t=le.get(e);typeof t=="number"&&(window.clearTimeout(t),le.delete(e))}function et(e,t){const r=W(t),n=e.localeRules.find(l=>W(l.locale)===r);if(n)return n;const a=r.split("-")[0],o=e.localeRules.find(l=>W(l.locale).split("-")[0]===a);return o||{locale:r,label:t,minLengthRatio:.5,maxLengthRatio:1.8,requireDifferentFromSource:!0,preserveTokens:!0}}function te(e,t,r,n={}){return Ae+=1,{id:`translation-workflow-issue-${Ae}`,type:e,severity:t,message:r,...n}}function ie(e,t){if(t){e.hasAttribute("data-translation-prev-contenteditable")||e.setAttribute("data-translation-prev-contenteditable",e.hasAttribute("contenteditable")&&e.getAttribute("contenteditable")||"inherit"),e.setAttribute("data-translation-locked","true"),e.setAttribute("contenteditable","false"),e.setAttribute("aria-readonly","true"),e.classList.add("rte-translation-segment-locked");return}if(e.removeAttribute("data-translation-locked"),e.removeAttribute("aria-readonly"),e.classList.remove("rte-translation-segment-locked"),e.hasAttribute("data-translation-prev-contenteditable")){const r=e.getAttribute("data-translation-prev-contenteditable")||"";r==="inherit"?e.setAttribute("contenteditable","true"):e.setAttribute("contenteditable",r),e.removeAttribute("data-translation-prev-contenteditable")}else e.setAttribute("contenteditable","true")}function ce(e,t){return e.querySelector(`[data-translation-segment-id="${Ke(t)}"]`)}function He(e){const t=window.getSelection();if(!t||t.rangeCount===0)return null;const r=Ce(t.getRangeAt(0).startContainer);return!r||!e.contains(r)?null:r.closest("[data-translation-segment-id]")}function tt(e,t){const r=Array.from(e.querySelectorAll(t));if(r.length<=1)return r;const n=new Set(r);return r.filter(a=>{let o=a.parentElement;for(;o&&o!==e;){if(n.has(o))return!1;o=o.parentElement}return!0})}function nt(e,t,r){let n=(r||"").trim();if(!n||t.has(n)){do n=`translation-segment-${_e++}`;while(t.has(n));e.setAttribute("data-translation-segment-id",n)}return n}function me(e,t){if(t.lockedSegmentIds.size===0)return!1;let r=!1;return t.lockedSegmentIds.forEach(n=>{const a=ce(e,n);if(!a)return;ie(a,!0);const o=t.lockedHtmlBySegmentId.get(n);if(typeof o=="string"){a.innerHTML!==o&&(a.innerHTML=o,r=!0);return}t.lockedHtmlBySegmentId.set(n,a.innerHTML)}),r}function M(e,t,r){const n=tt(e,t.segmentSelector),a=[],o=new Set;for(let l=0;l<n.length&&!(a.length>=t.maxSegments);l+=1){const s=n[l],i=nt(s,o,s.getAttribute("data-translation-segment-id")),d=r.lockedSegmentIds.has(i),g=s.getAttribute("data-translation-locked")==="true",w=d||g;if(w)if(r.lockedSegmentIds.add(i),ie(s,!0),!r.lockedHtmlBySegmentId.has(i))r.lockedHtmlBySegmentId.set(i,s.innerHTML);else{const q=r.lockedHtmlBySegmentId.get(i)||"";s.innerHTML!==q&&(s.innerHTML=q)}else r.lockedHtmlBySegmentId.delete(i);const v=t.normalizeText(s.textContent||"");if(!v)continue;r.sourceTextBySegmentId.has(i)||r.sourceTextBySegmentId.set(i,v);const G=r.sourceTextBySegmentId.get(i)||v;a.push({id:i,tagName:s.tagName.toLowerCase(),index:a.length,text:v,sourceText:G,locked:w}),o.add(i)}return Array.from(r.sourceTextBySegmentId.keys()).forEach(l=>{o.has(l)||r.sourceTextBySegmentId.delete(l)}),Array.from(r.lockedSegmentIds.keys()).forEach(l=>{o.has(l)||r.lockedSegmentIds.delete(l)}),Array.from(r.lockedHtmlBySegmentId.keys()).forEach(l=>{(!o.has(l)||!r.lockedSegmentIds.has(l))&&r.lockedHtmlBySegmentId.delete(l)}),(!r.selectedSegmentId||!a.some(l=>l.id===r.selectedSegmentId))&&(r.selectedSegmentId=a[0]?.id||null),a}function b(e,t){c.has(e)||c.set(e,t);let r=P.get(e);return r||(r={sourceLocale:t.sourceLocale,targetLocale:t.targetLocale,selectedSegmentId:null,realtimeEnabled:t.enableRealtime,segments:[],issues:[],sourceTextBySegmentId:new Map,lockedSegmentIds:new Set,lockedHtmlBySegmentId:new Map,snapshot:"",lastRunAt:null},P.set(e,r)),U.add(e),r}function Se(e){we(e);const t=p.get(e);t&&t.remove(),p.delete(e),j.delete(e);const r=P.get(e);r&&(r.lockedSegmentIds.forEach(n=>{const a=ce(e,n);a&&ie(a,!1)}),r.lockedHtmlBySegmentId.clear()),c.delete(e),re.delete(e),P.delete(e),U.delete(e),x===e&&(x=null)}function ye(e){return j.get(e)===!0}function be(e,t){if(!t.classList.contains("show"))return;const r=xe(e).getBoundingClientRect(),n=Math.min(window.innerWidth-20,520),a=Math.max(10,window.innerWidth-n-10),o=Math.min(Math.max(10,r.right-n),a),l=Math.max(10,Math.min(window.innerHeight-10,r.top+12));t.style.width=`${n}px`,t.style.left=`${o}px`,t.style.top=`${l}px`,t.style.maxHeight=`${Math.max(260,window.innerHeight-20)}px`}function H(e,t){const r=e.querySelector(".rte-translation-live");r&&(r.textContent=t)}function rt(e,t){return`${e.innerHTML}::${t.sourceLocale}::${t.targetLocale}::${Array.from(t.lockedSegmentIds).sort().join("|")}`}function ot(e,t,r){const n=[],a=et(r,t.targetLocale);for(let o=0;o<e.length&&!(n.length>=r.maxIssues);o+=1){const l=e[o],s=r.normalizeText(l.sourceText||""),i=r.normalizeText(l.text||"");if(!i){n.push(te("missing-target","error",r.labels.missingTargetMessage,{segmentId:l.id,sourceText:s,targetText:i,suggestion:"Provide translated content for this segment before export."}));continue}if(a.preserveTokens&&s&&!je(s,i)&&(n.push(te("token-mismatch","error",r.labels.tokenMismatchMessage,{segmentId:l.id,sourceText:s,targetText:i,suggestion:"Preserve placeholders/tokens exactly (for example {{name}}, %ID%, ${value})."})),n.length>=r.maxIssues)||a.requireDifferentFromSource&&s&&r.normalizeText(s)===r.normalizeText(i)&&(n.push(te("untranslated","warning",r.labels.untranslatedMessage,{segmentId:l.id,sourceText:s,targetText:i,suggestion:"Translate the segment or mark it intentionally unchanged."})),n.length>=r.maxIssues))break;if(s.length>=r.minSourceLengthForRatio){const d=i.length/Math.max(1,s.length);(d<a.minLengthRatio||d>a.maxLengthRatio)&&n.push(te("length-out-of-range","warning",r.labels.lengthOutOfRangeMessage,{segmentId:l.id,sourceText:s,targetText:i,suggestion:`Expected ratio for ${a.label}: ${a.minLengthRatio.toFixed(2)} - ${a.maxLengthRatio.toFixed(2)}.`}))}}return n}function Pe(e){const t=c.get(e)||k,r=P.get(e);return{sourceLocale:r?.sourceLocale||t?.sourceLocale||"en-US",targetLocale:r?.targetLocale||t?.targetLocale||"fr-FR",realtimeEnabled:r?.realtimeEnabled===!0,selectedSegmentId:r?.selectedSegmentId||null,segmentCount:r?.segments.length||0,lockedSegmentCount:r?r.segments.filter(n=>n.locked).length:0,issues:r?.issues?r.issues.map(n=>({...n})):[],segments:r?.segments.map(n=>({id:n.id,tagName:n.tagName,index:n.index,sourceLength:n.sourceText.length,targetLength:n.text.length,locked:n.locked}))||[],lastRunAt:r?.lastRunAt||null}}function E(e){const t=P.get(e),r=t&&t.selectedSegmentId?t.segments.find(n=>n.id===t.selectedSegmentId):null;fe(e,"toggleTranslationWorkflowPanel",ye(e)),fe(e,"toggleTranslationRealtime",t?.realtimeEnabled===!0),fe(e,"toggleTranslationSegmentLock",r?.locked===!0)}function at(e,t){const r=ce(e,t);if(!r)return;try{r.scrollIntoView({block:"nearest",inline:"nearest"})}catch{}const n=window.getSelection();if(!(!n||typeof document.createRange!="function"))try{const a=document.createRange();a.selectNodeContents(r),a.collapse(!0),n.removeAllRanges(),n.addRange(a),e.focus({preventScroll:!0})}catch{}}function R(e){const t=p.get(e);if(!t)return;const r=c.get(e)||k;if(!r)return;const n=b(e,r),a=t.querySelector(".rte-translation-source-label");a&&(a.textContent=r.labels.sourceLocaleLabel);const o=t.querySelector(".rte-translation-target-label");o&&(o.textContent=r.labels.targetLocaleLabel);const l=t.querySelector('[data-field="source-locale"]'),s=t.querySelector('[data-field="target-locale"]'),i=r.locales.map(f=>`<option value="${m(f)}">${m(f)}</option>`).join("");l&&(l.innerHTML=i,l.value=n.sourceLocale),s&&(s.innerHTML=i,s.value=n.targetLocale);const d=t.querySelector(".rte-translation-summary");if(d){const f=n.issues.length,B=n.selectedSegmentId?` • ${r.labels.selectedSegmentPrefix}: ${n.selectedSegmentId}`:"";d.textContent=`${r.labels.summaryPrefix}: ${n.sourceLocale} → ${n.targetLocale} • ${f} issue${f===1?"":"s"}${B}`}const g=t.querySelector(".rte-translation-helper");g&&(g.textContent=r.labels.helperText);const w=t.querySelector(".rte-translation-shortcut");w&&(w.textContent=r.labels.shortcutText);const v=t.querySelector('[data-action="run-validation"]');v&&(v.textContent=r.labels.validateText);const G=t.querySelector('[data-action="capture-source"]');G&&(G.textContent=r.labels.captureSourceText);const q=t.querySelector('[data-action="toggle-realtime"]');q&&(q.textContent=n.realtimeEnabled?r.labels.realtimeOnText:r.labels.realtimeOffText,q.setAttribute("aria-pressed",n.realtimeEnabled?"true":"false"));const Y=t.querySelector('[data-action="lock-selected"]'),ue=n.selectedSegmentId&&n.segments.find(f=>f.id===n.selectedSegmentId)||null;Y&&(Y.textContent=ue?.locked?r.labels.unlockSelectedText:r.labels.lockSelectedText,Y.disabled=!ue,Y.setAttribute("aria-pressed",ue?.locked?"true":"false"));const Le=t.querySelector('[data-action="close"]');Le&&Le.setAttribute("aria-label",r.labels.closeText);const Z=t.querySelector(".rte-translation-issues"),F=t.querySelector(".rte-translation-empty");Z&&(Z.setAttribute("aria-label",r.labels.issuesLabel),n.issues.length===0?(Z.innerHTML="",F&&(F.hidden=!1,F.textContent=r.labels.noIssuesText)):(F&&(F.hidden=!0),Z.innerHTML=n.issues.map(f=>` | ||
| <li class="rte-translation-issue ${f.severity==="error"?"error":f.severity==="warning"?"warning":"info"}" role="listitem" data-segment-id="${m(f.segmentId||"")}"> | ||
| <p class="rte-translation-issue-message">${m(f.message)}</p> | ||
| ${f.suggestion?`<p class="rte-translation-issue-suggestion">${m(f.suggestion)}</p>`:""} | ||
| </li> | ||
| `).join("")));const de=t.querySelector(".rte-translation-segments");de&&(de.setAttribute("aria-label",r.labels.segmentsLabel),de.innerHTML=n.segments.map(f=>{const B=f.id===n.selectedSegmentId?"selected":"",Oe=f.locked?"locked":"";return` | ||
| <li class="rte-translation-segment-item ${B} ${Oe}" role="option" aria-selected="${f.id===n.selectedSegmentId?"true":"false"}" data-segment-id="${m(f.id)}"> | ||
| <button type="button" class="rte-translation-segment-select" data-action="select-segment" data-segment-id="${m(f.id)}" title="${m(f.text)}"> | ||
| <span class="rte-translation-segment-meta">#${f.index+1} • ${m(f.tagName)}</span> | ||
| <span class="rte-translation-segment-text">${m(Ve(f.text,110))}</span> | ||
| </button> | ||
| <button type="button" class="rte-translation-segment-lock" data-action="toggle-lock" data-segment-id="${m(f.id)}" aria-label="${f.locked?r.labels.unlockSegmentAriaLabel:r.labels.lockSegmentAriaLabel}" aria-pressed="${f.locked?"true":"false"}"></button> | ||
| </li> | ||
| `}).join(""));const J=t.querySelector(".rte-translation-source-preview"),Q=t.querySelector(".rte-translation-target-preview");if(J||Q){const f=n.selectedSegmentId&&n.segments.find(B=>B.id===n.selectedSegmentId)||null;J&&(J.textContent=f?.sourceText||"—",J.setAttribute("aria-label",r.labels.sourcePreviewLabel)),Q&&(Q.textContent=f?.text||"—",Q.setAttribute("aria-label",r.labels.targetPreviewLabel))}t.setAttribute("aria-label",r.labels.panelAriaLabel)}function qe(e){const t=c.get(e)||k;if(!t)return;we(e);const r=window.setTimeout(()=>{le.delete(e),L(e,"realtime",!1)},t.debounceMs);le.set(e,r)}function L(e,t,r){const n=c.get(e)||k;if(!n)return[];const a=b(e,n),o=me(e,a);a.segments=M(e,n,a);const l=rt(e,a);if(!r&&a.snapshot===l)return a.issues;a.issues=ot(a.segments,a,n),a.lastRunAt=new Date().toISOString(),a.snapshot=l,R(e),E(e),e.dispatchEvent(new CustomEvent("editora:translation-workflow-validation",{bubbles:!0,detail:{reason:t,state:Pe(e)}}));const s=p.get(e);if(s){if(o)return H(s,n.labels.readonlySegmentMessage),a.issues;H(s,a.issues.length===0?n.labels.noIssuesText:`${a.issues.length} issue${a.issues.length===1?"":"s"} detected.`)}return a.issues}function Be(e){const t=c.get(e)||k;if(!t)return!1;const r=b(e,t),n=M(e,t,r);n.forEach(o=>{r.sourceTextBySegmentId.set(o.id,o.text)}),r.snapshot="",L(e,"capture-source",!0);const a=p.get(e);return a&&H(a,t.labels.sourceCapturedMessage),e.dispatchEvent(new CustomEvent("editora:translation-source-captured",{bubbles:!0,detail:{sourceLocale:r.sourceLocale,segmentCount:n.length}})),!0}function se(e,t,r){const n=c.get(e)||k;if(!n)return!1;const a=b(e,n);a.segments=M(e,n,a);const o=He(e)?.getAttribute("data-translation-segment-id")||null,l=t||o||a.selectedSegmentId||a.segments[0]?.id||null;if(!l)return!1;const s=ce(e,l);if(!s)return!1;const i=typeof r=="boolean"?r:!a.lockedSegmentIds.has(l);return i?(a.lockedSegmentIds.add(l),a.lockedHtmlBySegmentId.set(l,s.innerHTML)):(a.lockedSegmentIds.delete(l),a.lockedHtmlBySegmentId.delete(l)),ie(s,i),a.selectedSegmentId=l,a.snapshot="",L(e,"lock-segment",!0),e.dispatchEvent(new CustomEvent("editora:translation-segment-lock",{bubbles:!0,detail:{segmentId:l,locked:i}})),!0}function De(e,t){const r=c.get(e)||k;if(!r)return!1;const n=b(e,r),a=typeof t=="boolean"?t:!n.realtimeEnabled;return n.realtimeEnabled=a,a?qe(e):we(e),R(e),E(e),!0}function pe(e,t,r=!0){const n=c.get(e)||k;if(!n)return!1;const a=b(e,n);return a.segments=M(e,n,a),a.segments.some(o=>o.id===t)?(a.selectedSegmentId=t,R(e),E(e),r&&at(e,t),!0):!1}function ne(e,t){const r=c.get(e)||k;if(!r)return!1;const n=b(e,r);if(n.segments=M(e,r,n),n.segments.length===0)return!1;const a=Math.max(0,n.segments.findIndex(s=>s.id===n.selectedSegmentId));let o=a;t==="start"?o=0:t==="end"?o=n.segments.length-1:o=C(a+t,0,n.segments.length-1);const l=n.segments[o];return l?pe(e,l.id,!0):!1}function V(e,t=!1){const r=p.get(e);r&&(r.classList.remove("show"),j.set(e,!1),E(e),t&&e.focus({preventScroll:!0}))}function he(e){const t=ut(e);p.forEach((n,a)=>{a!==e&&V(a,!1)}),t.classList.add("show"),j.set(e,!0),L(e,"panel-open",!1),R(e),be(e,t),E(e),t.querySelector('[data-field="target-locale"]')?.focus()}function ze(e,t){const r=ye(e);return(typeof t=="boolean"?t:!r)?he(e):V(e,!1),!0}function lt(e){const t=e.key.toLowerCase();return(e.metaKey||e.ctrlKey)&&e.altKey&&e.shiftKey&&t==="l"}function st(e){const t=e.key.toLowerCase();return(e.metaKey||e.ctrlKey)&&e.altKey&&e.shiftKey&&t==="v"}function it(e){const t=e.key.toLowerCase();return(e.metaKey||e.ctrlKey)&&e.altKey&&e.shiftKey&&t==="k"}function ct(e){return e.key.length===1&&!e.metaKey&&!e.ctrlKey&&!e.altKey?!0:e.key==="Backspace"||e.key==="Delete"||e.key==="Enter"}function Ie(e){return e instanceof HTMLElement?e.closest('[data-translation-locked="true"]'):null}function ut(e){const t=p.get(e);if(t)return t;const r=c.get(e)||k||oe();b(e,r);const n=`rte-translation-workflow-panel-${Fe++}`,a=`${n}-source`,o=`${n}-target`,l=document.createElement("section");return l.className=u,l.id=n,l.setAttribute("role","dialog"),l.setAttribute("aria-modal","false"),l.setAttribute("aria-label",r.labels.panelAriaLabel),l.innerHTML=` | ||
| <header class="rte-translation-header"> | ||
| <h2 class="rte-translation-title">${m(r.labels.panelTitle)}</h2> | ||
| <button type="button" class="rte-translation-icon-btn" data-action="close" aria-label="${m(r.labels.closeText)}">✕</button> | ||
| </header> | ||
| <div class="rte-translation-body"> | ||
| <div class="rte-translation-locales"> | ||
| <div class="rte-translation-locale-field"> | ||
| <label class="rte-translation-source-label" for="${m(a)}"></label> | ||
| <select id="${m(a)}" class="rte-translation-select" data-field="source-locale"></select> | ||
| </div> | ||
| <div class="rte-translation-locale-field"> | ||
| <label class="rte-translation-target-label" for="${m(o)}"></label> | ||
| <select id="${m(o)}" class="rte-translation-select" data-field="target-locale"></select> | ||
| </div> | ||
| </div> | ||
| <p class="rte-translation-summary"></p> | ||
| <div class="rte-translation-actions"> | ||
| <button type="button" class="rte-translation-btn rte-translation-btn-primary" data-action="run-validation"></button> | ||
| <button type="button" class="rte-translation-btn" data-action="capture-source"></button> | ||
| <button type="button" class="rte-translation-btn" data-action="lock-selected"></button> | ||
| <button type="button" class="rte-translation-btn" data-action="toggle-realtime" aria-pressed="false"></button> | ||
| </div> | ||
| <p class="rte-translation-helper"></p> | ||
| <p class="rte-translation-shortcut"></p> | ||
| <div class="rte-translation-grid"> | ||
| <section class="rte-translation-segments-wrap" aria-label="${m(r.labels.segmentsLabel)}"> | ||
| <h3 class="rte-translation-subtitle">${m(r.labels.segmentsLabel)}</h3> | ||
| <ul class="rte-translation-segments" role="listbox" tabindex="0" aria-label="${m(r.labels.segmentsLabel)}"></ul> | ||
| </section> | ||
| <section class="rte-translation-preview-wrap"> | ||
| <h3 class="rte-translation-subtitle">${m(r.labels.sourcePreviewLabel)} / ${m(r.labels.targetPreviewLabel)}</h3> | ||
| <div class="rte-translation-preview-block"> | ||
| <p class="rte-translation-preview-label">${m(r.labels.sourcePreviewLabel)}</p> | ||
| <p class="rte-translation-source-preview"></p> | ||
| </div> | ||
| <div class="rte-translation-preview-block"> | ||
| <p class="rte-translation-preview-label">${m(r.labels.targetPreviewLabel)}</p> | ||
| <p class="rte-translation-target-preview"></p> | ||
| </div> | ||
| </section> | ||
| </div> | ||
| <section class="rte-translation-issues-wrap"> | ||
| <h3 class="rte-translation-subtitle">${m(r.labels.issuesLabel)}</h3> | ||
| <ul class="rte-translation-issues" role="list" aria-label="${m(r.labels.issuesLabel)}"></ul> | ||
| <p class="rte-translation-empty" hidden></p> | ||
| </section> | ||
| </div> | ||
| <div class="rte-translation-live" aria-live="polite" aria-atomic="true"></div> | ||
| `,l.addEventListener("click",s=>{const i=s.target;if(!i)return;const d=i.closest("[data-action]");if(!d){const v=i.closest(".rte-translation-issue[data-segment-id]")?.getAttribute("data-segment-id")||"";v&&pe(e,v,!0);return}const g=d.getAttribute("data-action");if(g==="close"){V(e,!0);return}if(g==="run-validation"){L(e,"panel-button",!0);return}if(g==="capture-source"){Be(e);return}if(g==="lock-selected"){se(e);return}if(g==="toggle-realtime"){De(e);return}if(g==="select-segment"){const w=d.getAttribute("data-segment-id")||"";w&&pe(e,w,!0);return}if(g==="toggle-lock"){const w=d.getAttribute("data-segment-id")||"";w&&se(e,w)}}),l.addEventListener("change",s=>{const i=s.target;if(!(i instanceof HTMLSelectElement))return;const d=c.get(e)||k;if(!d)return;const g=b(e,d);if(i.getAttribute("data-field")==="source-locale"){g.sourceLocale=A(i.value),g.snapshot="",L(e,"source-locale-change",!0);return}i.getAttribute("data-field")==="target-locale"&&(g.targetLocale=A(i.value),g.snapshot="",L(e,"target-locale-change",!0))}),l.addEventListener("keydown",s=>{const i=s.target;if(s.key==="Escape"){s.preventDefault(),V(e,!0);return}!i?.closest(".rte-translation-segments")||!Me.has(s.key)||(s.preventDefault(),s.key==="ArrowUp"?ne(e,-1):s.key==="ArrowDown"?ne(e,1):s.key==="Home"?ne(e,"start"):s.key==="End"&&ne(e,"end"))}),ge(l,e),document.body.appendChild(l),p.set(e,l),j.set(e,!1),R(e),l}function dt(e){k=e,D||(D=t=>{ae();const n=t.target?.closest(S);if(!n)return;const a=c.get(n)||e,o=b(n,a);c.set(n,a),x=n;const l=He(n)?.getAttribute("data-translation-segment-id")||null;l&&(o.selectedSegmentId=l),E(n);const s=p.get(n);s&&(ge(s,n),be(n,s),R(n))},document.addEventListener("focusin",D,!0)),z||(z=t=>{const n=t.target?.closest(S);if(!n)return;const a=c.get(n)||k;if(!a)return;const o=b(n,a),l=me(n,o);if(o.segments=M(n,a,o),!o.realtimeEnabled){if(l){const s=p.get(n);s&&H(s,a.labels.readonlySegmentMessage)}R(n),E(n);return}qe(n)},document.addEventListener("input",z,!0)),O||(O=t=>{const r=t,n=r.target,a=n?.closest(S);if(!a)return;const o=Ie(n);if(!o||!a.contains(o))return;r.preventDefault();const l=p.get(a),s=c.get(a)||k;l&&s&&H(l,s.labels.readonlySegmentMessage)},document.addEventListener("beforeinput",O,!0)),N||(N=t=>{if(t.defaultPrevented)return;const r=t.target;if(r?.closest(`.${u}`)&&t.key!=="Escape"&&!Me.has(t.key))return;const a=t.key==="Escape",o=lt(t),l=st(t),s=it(t),i=Ie(r);if(!a&&!o&&!l&&!s&&!i)return;const d=Xe(t);if(!d)return;const g=c.get(d)||k||e;if(b(d,g),c.set(d,g),x=d,a&&ye(d)){t.preventDefault(),V(d,!0);return}if(i&&d.contains(i)&&ct(t)){t.preventDefault();const w=p.get(d);w&&H(w,g.labels.readonlySegmentMessage);return}if(o){t.preventDefault(),t.stopPropagation(),ze(d);return}if(l){t.preventDefault(),t.stopPropagation(),L(d,"shortcut",!0);return}s&&(t.preventDefault(),t.stopPropagation(),se(d))},document.addEventListener("keydown",N,!0)),I||(I=()=>{ae(),p.forEach((t,r)=>{!r.isConnected||!t.isConnected||(ge(t,r),be(r,t))})},window.addEventListener("scroll",I,!0),window.addEventListener("resize",I)),!_&&typeof MutationObserver<"u"&&document.body&&(_=new MutationObserver(t=>{Qe(t)&&ae(),t.some(n=>n.type==="characterData"?!0:n.type==="childList"&&(n.addedNodes.length>0||n.removedNodes.length>0))&&U.forEach(n=>{const a=P.get(n);if(!a||a.lockedSegmentIds.size===0||!me(n,a))return;a.snapshot="";const l=c.get(n)||k,s=p.get(n);s&&l&&H(s,l.labels.readonlySegmentMessage),l&&(a.segments=M(n,l,a),R(n),E(n))})}),_.observe(document.body,{childList:!0,subtree:!0,characterData:!0}))}function ft(){D&&(document.removeEventListener("focusin",D,!0),D=null),z&&(document.removeEventListener("input",z,!0),z=null),O&&(document.removeEventListener("beforeinput",O,!0),O=null),N&&(document.removeEventListener("keydown",N,!0),N=null),I&&(window.removeEventListener("scroll",I,!0),window.removeEventListener("resize",I),I=null),_&&(_.disconnect(),_=null),p.forEach(t=>t.remove()),p.clear(),Array.from(U).forEach(t=>Se(t)),k=null,x=null}function gt(){if(typeof document>"u"||document.getElementById(ve))return;const e=document.createElement("style");e.id=ve,e.textContent=` | ||
| .rte-toolbar-group-items.${y}, | ||
| .editora-toolbar-group-items.${y}, | ||
| .rte-toolbar-group-items.${$}, | ||
| .editora-toolbar-group-items.${$} { | ||
| display: flex; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 4px; | ||
| background: #ffffff; | ||
| } | ||
| .rte-toolbar-group-items.${y} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${y} .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${$} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${$} .editora-toolbar-button { | ||
| border: none; | ||
| border-right: 1px solid #cbd5e1; | ||
| border-radius: 0; | ||
| } | ||
| .rte-toolbar-group-items.${y} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${y} .editora-toolbar-item:last-child .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${$} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${$} .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| ${h} .rte-toolbar-group-items.${y}, | ||
| ${h} .editora-toolbar-group-items.${y}, | ||
| ${h} .rte-toolbar-group-items.${$}, | ||
| ${h} .editora-toolbar-group-items.${$} { | ||
| border-color: #566275; | ||
| } | ||
| .rte-toolbar-button[data-command="toggleTranslationWorkflowPanel"].active, | ||
| .editora-toolbar-button[data-command="toggleTranslationWorkflowPanel"].active, | ||
| .rte-toolbar-button[data-command="toggleTranslationSegmentLock"].active, | ||
| .editora-toolbar-button[data-command="toggleTranslationSegmentLock"].active, | ||
| .rte-toolbar-button[data-command="toggleTranslationRealtime"].active, | ||
| .editora-toolbar-button[data-command="toggleTranslationRealtime"].active { | ||
| background: #ccc; | ||
| } | ||
| ${h} .rte-toolbar-group-items.${y} .rte-toolbar-button svg, | ||
| ${h} .editora-toolbar-group-items.${y} .editora-toolbar-button svg, | ||
| ${h} .rte-toolbar-group-items.${$} .rte-toolbar-button svg, | ||
| ${h} .editora-toolbar-group-items.${$} .editora-toolbar-button svg | ||
| { | ||
| fill: none; | ||
| } | ||
| ${h} .rte-toolbar-group-items.${y} .rte-toolbar-button, | ||
| ${h} .editora-toolbar-group-items.${y} .editora-toolbar-button | ||
| { | ||
| border-color: #566275; | ||
| } | ||
| ${h} .rte-toolbar-button[data-command="toggleTranslationWorkflowPanel"].active, | ||
| ${h} .editora-toolbar-button[data-command="toggleTranslationWorkflowPanel"].active, | ||
| ${h} .rte-toolbar-button[data-command="toggleTranslationSegmentLock"].active, | ||
| ${h} .editora-toolbar-button[data-command="toggleTranslationSegmentLock"].active, | ||
| ${h} .rte-toolbar-button[data-command="toggleTranslationRealtime"].active, | ||
| ${h} .editora-toolbar-button[data-command="toggleTranslationRealtime"].active { | ||
| background: linear-gradient(180deg, #5eaaf6 0%, #4a95de 100%); | ||
| } | ||
| .${u} { | ||
| position: fixed; | ||
| z-index: 12000; | ||
| display: none; | ||
| width: min(520px, calc(100vw - 20px)); | ||
| max-height: calc(100vh - 20px); | ||
| border: 1px solid #d1d5db; | ||
| border-radius: 14px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| box-shadow: 0 24px 48px rgba(15, 23, 42, 0.24); | ||
| overflow: hidden; | ||
| } | ||
| .${u}.show { | ||
| display: flex; | ||
| flex-direction: column; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark { | ||
| border-color: #334155; | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| box-shadow: 0 24px 52px rgba(2, 6, 23, 0.68); | ||
| } | ||
| .rte-translation-header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| padding: 12px 14px; | ||
| border-bottom: 1px solid #e2e8f0; | ||
| background: linear-gradient(180deg, #eff6ff 0%, #e2e8f0 100%); | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-header { | ||
| border-color: #1e293b; | ||
| background: linear-gradient(180deg, #111827 0%, #0f172a 100%); | ||
| } | ||
| .rte-translation-title { | ||
| margin: 0; | ||
| font-size: 15px; | ||
| line-height: 1.2; | ||
| font-weight: 700; | ||
| } | ||
| .rte-translation-icon-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| min-height: 34px; | ||
| width: 34px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| font-weight: 600; | ||
| padding: 0; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| cursor: pointer; | ||
| } | ||
| .rte-translation-icon-btn:hover, | ||
| .rte-translation-icon-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-icon-btn { | ||
| border-color: #475569; | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-icon-btn:hover, | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-icon-btn:focus-visible { | ||
| border-color: #60a5fa; | ||
| box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.24); | ||
| } | ||
| .rte-translation-body { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 8px; | ||
| padding: 12px; | ||
| overflow: auto; | ||
| } | ||
| .rte-translation-locales { | ||
| display: grid; | ||
| grid-template-columns: repeat(2, minmax(0, 1fr)); | ||
| gap: 8px; | ||
| } | ||
| .rte-translation-locale-field { | ||
| display: grid; | ||
| gap: 4px; | ||
| } | ||
| .rte-translation-source-label, | ||
| .rte-translation-target-label { | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| color: #334155; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-source-label, | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-target-label { | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-translation-select { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| min-height: 34px; | ||
| padding: 0 10px; | ||
| font-size: 13px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| } | ||
| .rte-translation-select:focus-visible { | ||
| border-color: #0e7490; | ||
| box-shadow: 0 0 0 3px rgba(14, 116, 144, 0.18); | ||
| outline: none; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-select { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #e2e8f0; | ||
| } | ||
| .rte-translation-summary, | ||
| .rte-translation-helper, | ||
| .rte-translation-shortcut { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #475569; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-summary, | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-helper, | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-shortcut { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-translation-actions { | ||
| display: grid; | ||
| grid-template-columns: repeat(4, minmax(0, 1fr)); | ||
| gap: 8px; | ||
| } | ||
| .rte-translation-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| min-height: 34px; | ||
| padding: 0 8px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| cursor: pointer; | ||
| } | ||
| .rte-translation-btn:disabled { | ||
| opacity: 0.6; | ||
| cursor: not-allowed; | ||
| } | ||
| .rte-translation-btn-primary { | ||
| border-color: #0e7490; | ||
| background: #0e7490; | ||
| color: #f8fafc; | ||
| } | ||
| .rte-translation-btn:hover, | ||
| .rte-translation-btn:focus-visible { | ||
| border-color: #94a3b8; | ||
| outline: none; | ||
| } | ||
| .rte-translation-btn-primary:hover, | ||
| .rte-translation-btn-primary:focus-visible { | ||
| border-color: #155e75; | ||
| background: #155e75; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-btn { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-btn-primary { | ||
| border-color: #22d3ee; | ||
| background: #0e7490; | ||
| color: #ecfeff; | ||
| } | ||
| .rte-translation-grid { | ||
| display: grid; | ||
| grid-template-columns: 1fr 1fr; | ||
| gap: 8px; | ||
| } | ||
| .rte-translation-segments-wrap, | ||
| .rte-translation-preview-wrap, | ||
| .rte-translation-issues-wrap { | ||
| border: 1px solid #e2e8f0; | ||
| border-radius: 10px; | ||
| background: #f8fafc; | ||
| padding: 8px; | ||
| min-height: 120px; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-segments-wrap, | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-preview-wrap, | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-issues-wrap { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| } | ||
| .rte-translation-subtitle { | ||
| margin: 0 0 6px; | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| color: #334155; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-subtitle { | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-translation-segments { | ||
| margin: 0; | ||
| padding: 0; | ||
| list-style: none; | ||
| display: grid; | ||
| gap: 6px; | ||
| max-height: 220px; | ||
| overflow: auto; | ||
| outline: none; | ||
| } | ||
| .rte-translation-segment-item { | ||
| display: grid; | ||
| grid-template-columns: 1fr auto; | ||
| gap: 6px; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| background: #ffffff; | ||
| padding: 6px; | ||
| } | ||
| .rte-translation-segment-item.selected { | ||
| border-color: #0e7490; | ||
| box-shadow: 0 0 0 2px rgba(14, 116, 144, 0.16); | ||
| } | ||
| .rte-translation-segment-item.locked { | ||
| border-color: #f59e0b; | ||
| background: #fffbeb; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-segment-item { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-segment-item.locked { | ||
| border-color: rgba(245, 158, 11, 0.72); | ||
| background: rgba(120, 53, 15, 0.28); | ||
| } | ||
| .rte-translation-segment-select { | ||
| border: none; | ||
| background: transparent; | ||
| color: inherit; | ||
| text-align: left; | ||
| padding: 0; | ||
| cursor: pointer; | ||
| display: grid; | ||
| gap: 2px; | ||
| } | ||
| .rte-translation-segment-meta { | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| font-weight: 700; | ||
| } | ||
| .rte-translation-segment-text { | ||
| font-size: 12px; | ||
| color: #334155; | ||
| line-height: 1.3; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-segment-meta { | ||
| color: #94a3b8; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-segment-text { | ||
| color: #e2e8f0; | ||
| } | ||
| .rte-translation-segment-lock { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| width: 28px; | ||
| min-height: 28px; | ||
| background: #ffffff; | ||
| cursor: pointer; | ||
| position: relative; | ||
| color: inherit; | ||
| font-size: 0; | ||
| } | ||
| .rte-translation-segment-lock::before { | ||
| content: '🔒'; | ||
| font-size: 14px; | ||
| position: absolute; | ||
| inset: 0; | ||
| display: grid; | ||
| place-items: center; | ||
| opacity: 0.35; | ||
| } | ||
| .rte-translation-segment-lock[aria-pressed="true"]::before { | ||
| opacity: 1; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-segment-lock { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| } | ||
| .rte-translation-preview-block { | ||
| display: grid; | ||
| gap: 4px; | ||
| margin-bottom: 8px; | ||
| } | ||
| .rte-translation-preview-label { | ||
| margin: 0; | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| font-weight: 700; | ||
| } | ||
| .rte-translation-source-preview, | ||
| .rte-translation-target-preview { | ||
| margin: 0; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| background: #ffffff; | ||
| padding: 8px; | ||
| font-size: 12px; | ||
| min-height: 56px; | ||
| white-space: pre-wrap; | ||
| line-height: 1.35; | ||
| color: #1f2937; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-preview-label { | ||
| color: #94a3b8; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-source-preview, | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-target-preview { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .rte-translation-issues { | ||
| margin: 0; | ||
| padding: 0; | ||
| list-style: none; | ||
| display: grid; | ||
| gap: 6px; | ||
| max-height: 200px; | ||
| overflow: auto; | ||
| } | ||
| .rte-translation-issue { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| background: #ffffff; | ||
| padding: 8px; | ||
| display: grid; | ||
| gap: 4px; | ||
| cursor: pointer; | ||
| } | ||
| .rte-translation-issue.error { | ||
| border-color: #ef4444; | ||
| background: #fef2f2; | ||
| } | ||
| .rte-translation-issue.warning { | ||
| border-color: #f59e0b; | ||
| background: #fffbeb; | ||
| } | ||
| .rte-translation-issue.info { | ||
| border-color: #0ea5e9; | ||
| background: #f0f9ff; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-issue { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-issue.error { | ||
| border-color: rgba(239, 68, 68, 0.7); | ||
| background: rgba(127, 29, 29, 0.28); | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-issue.warning { | ||
| border-color: rgba(245, 158, 11, 0.72); | ||
| background: rgba(120, 53, 15, 0.28); | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-issue.info { | ||
| border-color: rgba(14, 165, 233, 0.7); | ||
| background: rgba(7, 89, 133, 0.28); | ||
| } | ||
| .rte-translation-issue-message, | ||
| .rte-translation-issue-suggestion { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #1f2937; | ||
| } | ||
| .rte-translation-issue-suggestion { | ||
| color: #475569; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-issue-message { | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-issue-suggestion { | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-translation-empty { | ||
| margin: 8px; | ||
| font-size: 12px; | ||
| color: #64748b; | ||
| } | ||
| .rte-translation-live { | ||
| position: absolute; | ||
| width: 1px; | ||
| height: 1px; | ||
| margin: -1px; | ||
| padding: 0; | ||
| overflow: hidden; | ||
| clip: rect(0 0 0 0); | ||
| border: 0; | ||
| } | ||
| [data-translation-locked="true"].rte-translation-segment-locked { | ||
| outline: 2px dashed rgba(245, 158, 11, 0.65); | ||
| outline-offset: 2px; | ||
| background: rgba(255, 251, 235, 0.8); | ||
| border-radius: 4px; | ||
| } | ||
| ${h} [data-translation-locked="true"].rte-translation-segment-locked { | ||
| outline-color: rgba(245, 158, 11, 0.75); | ||
| background: rgba(120, 53, 15, 0.22); | ||
| } | ||
| @media (max-width: 920px) { | ||
| .${u} { | ||
| left: 10px !important; | ||
| right: 10px; | ||
| top: 10px !important; | ||
| width: auto !important; | ||
| max-height: calc(100vh - 20px); | ||
| } | ||
| .rte-translation-locales, | ||
| .rte-translation-actions, | ||
| .rte-translation-grid { | ||
| grid-template-columns: 1fr; | ||
| } | ||
| } | ||
| `,document.head.appendChild(e)}const mt=(e={})=>{const t=oe(e),r=new Set;return gt(),{name:"translationWorkflow",toolbar:[{id:"translationWorkflowGroup",label:"Translation Workflow",type:"group",command:"translationWorkflow",items:[{id:"toggleTranslationWorkflowPanel",label:"Translation Workflow",command:"toggleTranslationWorkflowPanel",shortcut:"Mod-Alt-Shift-l",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M4 6.5a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2H8l-4 3V6.5Z" stroke="currentColor" stroke-width="1.6"/><path d="M20 17.5a2 2 0 0 1-2 2h-8a2 2 0 0 1-2-2v-1.5" stroke="currentColor" stroke-width="1.6"/><path d="m13 8 2 2m0 0 2-2m-2 2V4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>'},{id:"runTranslationLocaleValidation",label:"Run Locale Validation",command:"runTranslationLocaleValidation",shortcut:"Mod-Alt-Shift-v",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><rect x="4.5" y="4" width="12" height="16" rx="2" stroke="currentColor" stroke-width="1.6"/><path d="M8 8h5.5M8 11h4M8 14h3" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><path d="m15.5 15.5 1.7 1.7 3.3-3.3" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>'},{id:"toggleTranslationSegmentLock",label:"Toggle Segment Lock",command:"toggleTranslationSegmentLock",shortcut:"Mod-Alt-Shift-k",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><rect x="5" y="10" width="14" height="10" rx="2" stroke="currentColor" stroke-width="1.6"/><path d="M8.5 10V7.5a3.5 3.5 0 1 1 7 0V10" stroke="currentColor" stroke-width="1.6"/><circle cx="12" cy="15" r="1.2" fill="currentColor"/></svg>'},{id:"toggleTranslationRealtime",label:"Toggle Translation Realtime",command:"toggleTranslationRealtime",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M4.5 12a7.5 7.5 0 1 1 7.5 7.5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><path d="M9.5 19.5H5.5v-4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/><path d="M12 8v4l2.5 2" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>'}]}],commands:{translationWorkflow:(n,a)=>{const o=T(a,!1,!1);if(!o)return!1;const l=c.get(o)||t;return b(o,l),c.set(o,l),x=o,he(o),!0},openTranslationWorkflowPanel:(n,a)=>{const o=T(a,!1,!1);if(!o)return!1;const l=c.get(o)||t;return b(o,l),c.set(o,l),x=o,he(o),!0},toggleTranslationWorkflowPanel:(n,a)=>{const o=T(a,!1,!1);if(!o)return!1;const l=c.get(o)||t;return b(o,l),c.set(o,l),x=o,ze(o,typeof n=="boolean"?n:void 0)},runTranslationLocaleValidation:(n,a)=>{const o=T(a,!1,!1);if(!o)return!1;const l=c.get(o)||t;return b(o,l),c.set(o,l),x=o,L(o,"command",!0),!0},toggleTranslationRealtime:(n,a)=>{const o=T(a,!1,!1);if(!o)return!1;const l=c.get(o)||t;return b(o,l),c.set(o,l),x=o,De(o,typeof n=="boolean"?n:void 0)},toggleTranslationSegmentLock:(n,a)=>{const o=T(a,!1,!1);if(!o)return!1;const l=c.get(o)||t;b(o,l),c.set(o,l),x=o;const s=typeof n=="boolean"?n:n?.locked,i=typeof n=="object"?n?.segmentId:void 0;return se(o,i,s)},setTranslationLocales:(n,a)=>{const o=T(a,!1,!1);if(!o||!n||typeof n!="object")return!1;const l=c.get(o)||t,s=b(o,l);return c.set(o,l),typeof n.sourceLocale=="string"&&n.sourceLocale.trim()&&(s.sourceLocale=A(n.sourceLocale)),typeof n.targetLocale=="string"&&n.targetLocale.trim()&&(s.targetLocale=A(n.targetLocale)),s.snapshot="",L(o,"set-locales",!0),!0},captureTranslationSourceSnapshot:(n,a)=>{const o=T(a,!1,!1);if(!o)return!1;const l=c.get(o)||t;return b(o,l),c.set(o,l),x=o,Be(o)},setTranslationWorkflowOptions:(n,a)=>{const o=T(a,!1,!1);if(!o||!n||typeof n!="object")return!1;const l=c.get(o)||t,s=re.get(o)||Ge(l),i={...s,...n,labels:{...s.labels||{},...n.labels||{}},localeRules:Array.isArray(n.localeRules)?n.localeRules:s.localeRules,locales:Array.isArray(n.locales)?n.locales:s.locales,normalizeText:n.normalizeText||l.normalizeText},d=oe(i);c.set(o,d),re.set(o,i);const g=b(o,d);return typeof n.enableRealtime=="boolean"&&(g.realtimeEnabled=n.enableRealtime),typeof n.sourceLocale=="string"&&n.sourceLocale.trim()&&(g.sourceLocale=A(n.sourceLocale)),typeof n.targetLocale=="string"&&n.targetLocale.trim()&&(g.targetLocale=A(n.targetLocale)),g.snapshot="",L(o,"set-options",!0),R(o),E(o),!0},getTranslationWorkflowState:(n,a)=>{const o=T(a,!1,!1);if(!o)return!1;const l=c.get(o)||t;b(o,l);const s=Pe(o);if(typeof n=="function")try{n(s)}catch{}return o.__translationWorkflowState=s,o.dispatchEvent(new CustomEvent("editora:translation-workflow-state",{bubbles:!0,detail:s})),!0}},keymap:{"Mod-Alt-Shift-l":"toggleTranslationWorkflowPanel","Mod-Alt-Shift-L":"toggleTranslationWorkflowPanel","Mod-Alt-Shift-v":"runTranslationLocaleValidation","Mod-Alt-Shift-V":"runTranslationLocaleValidation","Mod-Alt-Shift-k":"toggleTranslationSegmentLock","Mod-Alt-Shift-K":"toggleTranslationSegmentLock"},init:function(a){X+=1;const o=this&&typeof this.__pluginConfig=="object"?{...e,...this.__pluginConfig}:e,l=oe(o);dt(l);const s=T(a?.editorElement?{editorElement:a.editorElement}:void 0,!1,!1);if(!s)return;x=s,r.add(s);const i=b(s,l);c.set(s,l),re.set(s,o),i.segments=M(s,l,i),L(s,"init",!0),E(s)},destroy:()=>{r.forEach(n=>Se(n)),r.clear(),X=Math.max(0,X-1),!(X>0)&&ft()}}};exports.TranslationWorkflowPlugin=mt; |
| const S = ".rte-content, .editora-content", ke = "[data-editora-editor], .rte-editor, .editora-editor, editora-editor", Te = "__editoraCommandEditorRoot", ve = "rte-translation-workflow-styles", u = "rte-translation-workflow-panel", y = "translation-workflow", $ = "translationWorkflow", h = ':is([data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark)', $e = [ | ||
| "p", | ||
| "h1", | ||
| "h2", | ||
| "h3", | ||
| "h4", | ||
| "h5", | ||
| "h6", | ||
| "li", | ||
| "td", | ||
| "th", | ||
| "blockquote", | ||
| "figcaption" | ||
| ].join(", "), Me = /* @__PURE__ */ new Set(["ArrowUp", "ArrowDown", "Home", "End"]), Ee = [ | ||
| { | ||
| locale: "en", | ||
| label: "English", | ||
| minLengthRatio: 0.6, | ||
| maxLengthRatio: 1.4, | ||
| requireDifferentFromSource: !1, | ||
| preserveTokens: !0 | ||
| }, | ||
| { | ||
| locale: "fr", | ||
| label: "French", | ||
| minLengthRatio: 0.75, | ||
| maxLengthRatio: 1.7, | ||
| requireDifferentFromSource: !0, | ||
| preserveTokens: !0 | ||
| }, | ||
| { | ||
| locale: "de", | ||
| label: "German", | ||
| minLengthRatio: 0.8, | ||
| maxLengthRatio: 1.9, | ||
| requireDifferentFromSource: !0, | ||
| preserveTokens: !0 | ||
| }, | ||
| { | ||
| locale: "es", | ||
| label: "Spanish", | ||
| minLengthRatio: 0.7, | ||
| maxLengthRatio: 1.7, | ||
| requireDifferentFromSource: !0, | ||
| preserveTokens: !0 | ||
| }, | ||
| { | ||
| locale: "it", | ||
| label: "Italian", | ||
| minLengthRatio: 0.7, | ||
| maxLengthRatio: 1.7, | ||
| requireDifferentFromSource: !0, | ||
| preserveTokens: !0 | ||
| }, | ||
| { | ||
| locale: "ja", | ||
| label: "Japanese", | ||
| minLengthRatio: 0.45, | ||
| maxLengthRatio: 1.2, | ||
| requireDifferentFromSource: !0, | ||
| preserveTokens: !0 | ||
| }, | ||
| { | ||
| locale: "zh", | ||
| label: "Chinese", | ||
| minLengthRatio: 0.4, | ||
| maxLengthRatio: 1.2, | ||
| requireDifferentFromSource: !0, | ||
| preserveTokens: !0 | ||
| } | ||
| ], Oe = { | ||
| panelTitle: "Translation Workflow", | ||
| panelAriaLabel: "Translation workflow panel", | ||
| sourceLocaleLabel: "Source Locale", | ||
| targetLocaleLabel: "Target Locale", | ||
| validateText: "Validate Locale", | ||
| captureSourceText: "Capture Source", | ||
| lockSelectedText: "Lock Selected", | ||
| unlockSelectedText: "Unlock Selected", | ||
| lockSegmentAriaLabel: "Lock segment", | ||
| unlockSegmentAriaLabel: "Unlock segment", | ||
| realtimeOnText: "Realtime On", | ||
| realtimeOffText: "Realtime Off", | ||
| closeText: "Close", | ||
| summaryPrefix: "Locale QA", | ||
| noIssuesText: "No locale validation issues.", | ||
| issuesLabel: "Locale issues", | ||
| segmentsLabel: "Segments", | ||
| sourcePreviewLabel: "Source", | ||
| targetPreviewLabel: "Target", | ||
| helperText: "Select segments, lock finalized ones, and run locale validation before handoff.", | ||
| shortcutText: "Shortcuts: Ctrl/Cmd+Alt+Shift+L (panel), Ctrl/Cmd+Alt+Shift+V (validate), Ctrl/Cmd+Alt+Shift+K (lock segment)", | ||
| readonlySegmentMessage: "This segment is locked. Unlock before editing.", | ||
| sourceCapturedMessage: "Source snapshot captured from current content.", | ||
| selectedSegmentPrefix: "Selected Segment", | ||
| missingTargetMessage: "Segment is empty in target locale.", | ||
| tokenMismatchMessage: "Tokens/placeholders do not match source segment.", | ||
| untranslatedMessage: "Segment appears untranslated (same as source).", | ||
| lengthOutOfRangeMessage: "Translation length is outside expected locale range." | ||
| }, c = /* @__PURE__ */ new WeakMap(), re = /* @__PURE__ */ new WeakMap(), q = /* @__PURE__ */ new WeakMap(), p = /* @__PURE__ */ new Map(), j = /* @__PURE__ */ new WeakMap(), le = /* @__PURE__ */ new WeakMap(), U = /* @__PURE__ */ new Set(); | ||
| let X = 0, _e = 0, Ae = 0, Fe = 0, k = null, x = null, D = null, z = null, N = null, O = null, I = null, _ = null; | ||
| function m(e) { | ||
| return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); | ||
| } | ||
| function We(e) { | ||
| return e.replace(/\u00A0/g, " ").replace(/\s+/g, " ").trim(); | ||
| } | ||
| function C(e, t, r) { | ||
| return Number.isFinite(e) ? Math.max(t, Math.min(r, e)) : t; | ||
| } | ||
| function A(e) { | ||
| return (e || "").trim() || "en-US"; | ||
| } | ||
| function W(e) { | ||
| return e.trim().toLowerCase(); | ||
| } | ||
| function Ke(e) { | ||
| return e.replace(/"/g, """); | ||
| } | ||
| function Ve(e, t = 120) { | ||
| return e.length <= t ? e : `${e.slice(0, Math.max(0, t - 1)).trimEnd()}…`; | ||
| } | ||
| function Re(e) { | ||
| const t = e.match(/\{\{[^{}]+\}\}|%[A-Z0-9_]+%|\$\{[^{}]+\}/gi); | ||
| return !t || t.length === 0 ? [] : t.map((r) => r.trim()).filter(Boolean); | ||
| } | ||
| function je(e, t) { | ||
| const r = Re(e).sort(), n = Re(t).sort(); | ||
| if (r.length !== n.length) return !1; | ||
| for (let a = 0; a < r.length; a += 1) | ||
| if (r[a] !== n[a]) return !1; | ||
| return !0; | ||
| } | ||
| function Ue(e, t) { | ||
| const r = Array.isArray(t) && t.length > 0 ? t : Ee, n = [], a = /* @__PURE__ */ new Set(); | ||
| return r.forEach((o) => { | ||
| const l = W(o.locale || ""); | ||
| if (!l) return; | ||
| const s = l; | ||
| a.has(s) || (a.add(s), n.push({ | ||
| locale: s, | ||
| label: (o.label || l).trim() || l, | ||
| minLengthRatio: C(Number(o.minLengthRatio ?? 0.5), 0.1, 3), | ||
| maxLengthRatio: C(Number(o.maxLengthRatio ?? 1.8), 0.2, 4), | ||
| requireDifferentFromSource: o.requireDifferentFromSource !== !1, | ||
| preserveTokens: o.preserveTokens !== !1 | ||
| })); | ||
| }), e.forEach((o) => { | ||
| const l = W(o); | ||
| if (a.has(l)) return; | ||
| const s = Ee.find((i) => l.startsWith(i.locale)); | ||
| n.push( | ||
| s ? { ...s, locale: l, label: o } : { | ||
| locale: l, | ||
| label: o, | ||
| minLengthRatio: 0.5, | ||
| maxLengthRatio: 1.8, | ||
| requireDifferentFromSource: !0, | ||
| preserveTokens: !0 | ||
| } | ||
| ); | ||
| }), n; | ||
| } | ||
| function oe(e = {}) { | ||
| const t = e.normalizeText || We, r = A(e.sourceLocale || "en-US"), n = A(e.targetLocale || "fr-FR"), a = /* @__PURE__ */ new Set([r, n]); | ||
| (Array.isArray(e.locales) ? e.locales : []).forEach((s) => { | ||
| if (typeof s != "string") return; | ||
| const i = A(s); | ||
| a.add(i); | ||
| }); | ||
| const o = Array.from(a), l = Ue(o, e.localeRules); | ||
| return { | ||
| sourceLocale: r, | ||
| targetLocale: n, | ||
| locales: o, | ||
| localeRules: l, | ||
| enableRealtime: e.enableRealtime !== !1, | ||
| debounceMs: C(Number(e.debounceMs ?? 260), 60, 2e3), | ||
| maxIssues: C(Number(e.maxIssues ?? 120), 5, 1e3), | ||
| maxSegments: C(Number(e.maxSegments ?? 600), 20, 3e3), | ||
| minSourceLengthForRatio: C(Number(e.minSourceLengthForRatio ?? 8), 2, 100), | ||
| segmentSelector: (e.segmentSelector || $e).trim() || $e, | ||
| labels: { | ||
| ...Oe, | ||
| ...e.labels || {} | ||
| }, | ||
| normalizeText: t | ||
| }; | ||
| } | ||
| function Ge(e) { | ||
| return { | ||
| sourceLocale: e.sourceLocale, | ||
| targetLocale: e.targetLocale, | ||
| locales: [...e.locales], | ||
| localeRules: e.localeRules.map((t) => ({ | ||
| locale: t.locale, | ||
| label: t.label, | ||
| minLengthRatio: t.minLengthRatio, | ||
| maxLengthRatio: t.maxLengthRatio, | ||
| requireDifferentFromSource: t.requireDifferentFromSource, | ||
| preserveTokens: t.preserveTokens | ||
| })), | ||
| enableRealtime: e.enableRealtime, | ||
| debounceMs: e.debounceMs, | ||
| maxIssues: e.maxIssues, | ||
| maxSegments: e.maxSegments, | ||
| minSourceLengthForRatio: e.minSourceLengthForRatio, | ||
| segmentSelector: e.segmentSelector, | ||
| labels: { ...e.labels }, | ||
| normalizeText: e.normalizeText | ||
| }; | ||
| } | ||
| function xe(e) { | ||
| return e.closest(ke) || e; | ||
| } | ||
| function K(e) { | ||
| if (!e) return null; | ||
| if (e.matches(S)) return e; | ||
| const t = e.querySelector(S); | ||
| return t instanceof HTMLElement ? t : null; | ||
| } | ||
| function Ye() { | ||
| if (typeof window > "u") return null; | ||
| const e = window[Te]; | ||
| if (!(e instanceof HTMLElement)) return null; | ||
| window[Te] = null; | ||
| const t = K(e); | ||
| if (t) return t; | ||
| const r = e.closest(ke); | ||
| if (r) { | ||
| const a = K(r); | ||
| if (a) return a; | ||
| } | ||
| const n = e.closest(S); | ||
| return n instanceof HTMLElement ? n : null; | ||
| } | ||
| function Ze(e) { | ||
| const t = e.closest("[data-editora-editor]"); | ||
| if (t && K(t) === e) | ||
| return t; | ||
| let r = e; | ||
| for (; r; ) { | ||
| if (r.matches(ke) && (r === e || K(r) === e)) | ||
| return r; | ||
| r = r.parentElement; | ||
| } | ||
| return xe(e); | ||
| } | ||
| function Ce(e) { | ||
| return e ? e.nodeType === Node.ELEMENT_NODE ? e : e.parentElement : null; | ||
| } | ||
| function ee(e) { | ||
| return e ? (e.getAttribute("data-theme") || e.getAttribute("theme") || "").toLowerCase() === "dark" ? !0 : e.classList.contains("dark") || e.classList.contains("editora-theme-dark") || e.classList.contains("rte-theme-dark") : !1; | ||
| } | ||
| function Je(e) { | ||
| const t = xe(e); | ||
| if (ee(t)) return !0; | ||
| const r = t.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark"); | ||
| return ee(r) ? !0 : ee(document.documentElement) || ee(document.body); | ||
| } | ||
| function ge(e, t) { | ||
| e.classList.remove("rte-translation-workflow-theme-dark"), Je(t) && e.classList.add("rte-translation-workflow-theme-dark"); | ||
| } | ||
| function Qe(e) { | ||
| for (let t = 0; t < e.length; t += 1) { | ||
| const r = e[t]; | ||
| if (!(r.type !== "childList" || r.removedNodes.length === 0)) | ||
| for (let n = 0; n < r.removedNodes.length; n += 1) { | ||
| const a = r.removedNodes[n]; | ||
| if (a.nodeType !== Node.ELEMENT_NODE) continue; | ||
| const o = a; | ||
| if (o.matches?.(S) || o.matches?.(`.${u}`) || o.querySelector?.(S) || o.querySelector?.(`.${u}`)) | ||
| return !0; | ||
| } | ||
| } | ||
| return !1; | ||
| } | ||
| function ae() { | ||
| Array.from(U).forEach((t) => { | ||
| t.isConnected || Se(t); | ||
| }); | ||
| } | ||
| function T(e, t = !0, r = !0) { | ||
| if (ae(), e?.contentElement instanceof HTMLElement) return e.contentElement; | ||
| if (e?.editorElement instanceof HTMLElement) { | ||
| const s = K(e.editorElement); | ||
| if (s) return s; | ||
| } | ||
| const n = Ye(); | ||
| if (n) return n; | ||
| const a = window.getSelection(); | ||
| if (a && a.rangeCount > 0) { | ||
| const s = Ce(a.getRangeAt(0).startContainer)?.closest( | ||
| S | ||
| ); | ||
| if (s) return s; | ||
| } | ||
| const o = document.activeElement; | ||
| if (o) { | ||
| if (o.matches(S)) return o; | ||
| const s = o.closest(S); | ||
| if (s) return s; | ||
| } | ||
| if (r && x && x.isConnected) | ||
| return x; | ||
| if (!t) return null; | ||
| const l = document.querySelector(S); | ||
| return l instanceof HTMLElement ? l : null; | ||
| } | ||
| function Xe(e) { | ||
| const t = e.target; | ||
| if (t) { | ||
| const n = t.closest(`.${u}`); | ||
| if (n) { | ||
| const o = Array.from(p.entries()).find(([, l]) => l === n); | ||
| if (o) return o[0]; | ||
| } | ||
| const a = t.closest(S); | ||
| if (a) return a; | ||
| } | ||
| const r = document.activeElement; | ||
| if (r) { | ||
| const n = r.closest(`.${u}`); | ||
| if (n) { | ||
| const o = Array.from(p.entries()).find(([, l]) => l === n); | ||
| if (o) return o[0]; | ||
| } | ||
| const a = r.closest(S); | ||
| if (a) return a; | ||
| } | ||
| return null; | ||
| } | ||
| function fe(e, t, r) { | ||
| const n = Ze(e); | ||
| Array.from( | ||
| n.querySelectorAll( | ||
| `.rte-toolbar-button[data-command="${t}"], .editora-toolbar-button[data-command="${t}"]` | ||
| ) | ||
| ).forEach((o) => { | ||
| o.classList.toggle("active", r), o.setAttribute("data-active", r ? "true" : "false"), o.setAttribute("aria-pressed", r ? "true" : "false"); | ||
| }); | ||
| } | ||
| function we(e) { | ||
| const t = le.get(e); | ||
| typeof t == "number" && (window.clearTimeout(t), le.delete(e)); | ||
| } | ||
| function et(e, t) { | ||
| const r = W(t), n = e.localeRules.find((l) => W(l.locale) === r); | ||
| if (n) return n; | ||
| const a = r.split("-")[0], o = e.localeRules.find((l) => W(l.locale).split("-")[0] === a); | ||
| return o || { | ||
| locale: r, | ||
| label: t, | ||
| minLengthRatio: 0.5, | ||
| maxLengthRatio: 1.8, | ||
| requireDifferentFromSource: !0, | ||
| preserveTokens: !0 | ||
| }; | ||
| } | ||
| function te(e, t, r, n = {}) { | ||
| return Ae += 1, { | ||
| id: `translation-workflow-issue-${Ae}`, | ||
| type: e, | ||
| severity: t, | ||
| message: r, | ||
| ...n | ||
| }; | ||
| } | ||
| function ie(e, t) { | ||
| if (t) { | ||
| e.hasAttribute("data-translation-prev-contenteditable") || e.setAttribute( | ||
| "data-translation-prev-contenteditable", | ||
| e.hasAttribute("contenteditable") && e.getAttribute("contenteditable") || "inherit" | ||
| ), e.setAttribute("data-translation-locked", "true"), e.setAttribute("contenteditable", "false"), e.setAttribute("aria-readonly", "true"), e.classList.add("rte-translation-segment-locked"); | ||
| return; | ||
| } | ||
| if (e.removeAttribute("data-translation-locked"), e.removeAttribute("aria-readonly"), e.classList.remove("rte-translation-segment-locked"), e.hasAttribute("data-translation-prev-contenteditable")) { | ||
| const r = e.getAttribute("data-translation-prev-contenteditable") || ""; | ||
| r === "inherit" ? e.setAttribute("contenteditable", "true") : e.setAttribute("contenteditable", r), e.removeAttribute("data-translation-prev-contenteditable"); | ||
| } else | ||
| e.setAttribute("contenteditable", "true"); | ||
| } | ||
| function ce(e, t) { | ||
| return e.querySelector(`[data-translation-segment-id="${Ke(t)}"]`); | ||
| } | ||
| function He(e) { | ||
| const t = window.getSelection(); | ||
| if (!t || t.rangeCount === 0) return null; | ||
| const r = Ce(t.getRangeAt(0).startContainer); | ||
| return !r || !e.contains(r) ? null : r.closest("[data-translation-segment-id]"); | ||
| } | ||
| function tt(e, t) { | ||
| const r = Array.from(e.querySelectorAll(t)); | ||
| if (r.length <= 1) return r; | ||
| const n = new Set(r); | ||
| return r.filter((a) => { | ||
| let o = a.parentElement; | ||
| for (; o && o !== e; ) { | ||
| if (n.has(o)) | ||
| return !1; | ||
| o = o.parentElement; | ||
| } | ||
| return !0; | ||
| }); | ||
| } | ||
| function nt(e, t, r) { | ||
| let n = (r || "").trim(); | ||
| if (!n || t.has(n)) { | ||
| do | ||
| n = `translation-segment-${_e++}`; | ||
| while (t.has(n)); | ||
| e.setAttribute("data-translation-segment-id", n); | ||
| } | ||
| return n; | ||
| } | ||
| function me(e, t) { | ||
| if (t.lockedSegmentIds.size === 0) return !1; | ||
| let r = !1; | ||
| return t.lockedSegmentIds.forEach((n) => { | ||
| const a = ce(e, n); | ||
| if (!a) return; | ||
| ie(a, !0); | ||
| const o = t.lockedHtmlBySegmentId.get(n); | ||
| if (typeof o == "string") { | ||
| a.innerHTML !== o && (a.innerHTML = o, r = !0); | ||
| return; | ||
| } | ||
| t.lockedHtmlBySegmentId.set(n, a.innerHTML); | ||
| }), r; | ||
| } | ||
| function M(e, t, r) { | ||
| const n = tt(e, t.segmentSelector), a = [], o = /* @__PURE__ */ new Set(); | ||
| for (let l = 0; l < n.length && !(a.length >= t.maxSegments); l += 1) { | ||
| const s = n[l], i = nt(s, o, s.getAttribute("data-translation-segment-id")), d = r.lockedSegmentIds.has(i), g = s.getAttribute("data-translation-locked") === "true", w = d || g; | ||
| if (w) | ||
| if (r.lockedSegmentIds.add(i), ie(s, !0), !r.lockedHtmlBySegmentId.has(i)) | ||
| r.lockedHtmlBySegmentId.set(i, s.innerHTML); | ||
| else { | ||
| const B = r.lockedHtmlBySegmentId.get(i) || ""; | ||
| s.innerHTML !== B && (s.innerHTML = B); | ||
| } | ||
| else | ||
| r.lockedHtmlBySegmentId.delete(i); | ||
| const v = t.normalizeText(s.textContent || ""); | ||
| if (!v) continue; | ||
| r.sourceTextBySegmentId.has(i) || r.sourceTextBySegmentId.set(i, v); | ||
| const G = r.sourceTextBySegmentId.get(i) || v; | ||
| a.push({ | ||
| id: i, | ||
| tagName: s.tagName.toLowerCase(), | ||
| index: a.length, | ||
| text: v, | ||
| sourceText: G, | ||
| locked: w | ||
| }), o.add(i); | ||
| } | ||
| return Array.from(r.sourceTextBySegmentId.keys()).forEach((l) => { | ||
| o.has(l) || r.sourceTextBySegmentId.delete(l); | ||
| }), Array.from(r.lockedSegmentIds.keys()).forEach((l) => { | ||
| o.has(l) || r.lockedSegmentIds.delete(l); | ||
| }), Array.from(r.lockedHtmlBySegmentId.keys()).forEach((l) => { | ||
| (!o.has(l) || !r.lockedSegmentIds.has(l)) && r.lockedHtmlBySegmentId.delete(l); | ||
| }), (!r.selectedSegmentId || !a.some((l) => l.id === r.selectedSegmentId)) && (r.selectedSegmentId = a[0]?.id || null), a; | ||
| } | ||
| function b(e, t) { | ||
| c.has(e) || c.set(e, t); | ||
| let r = q.get(e); | ||
| return r || (r = { | ||
| sourceLocale: t.sourceLocale, | ||
| targetLocale: t.targetLocale, | ||
| selectedSegmentId: null, | ||
| realtimeEnabled: t.enableRealtime, | ||
| segments: [], | ||
| issues: [], | ||
| sourceTextBySegmentId: /* @__PURE__ */ new Map(), | ||
| lockedSegmentIds: /* @__PURE__ */ new Set(), | ||
| lockedHtmlBySegmentId: /* @__PURE__ */ new Map(), | ||
| snapshot: "", | ||
| lastRunAt: null | ||
| }, q.set(e, r)), U.add(e), r; | ||
| } | ||
| function Se(e) { | ||
| we(e); | ||
| const t = p.get(e); | ||
| t && t.remove(), p.delete(e), j.delete(e); | ||
| const r = q.get(e); | ||
| r && (r.lockedSegmentIds.forEach((n) => { | ||
| const a = ce(e, n); | ||
| a && ie(a, !1); | ||
| }), r.lockedHtmlBySegmentId.clear()), c.delete(e), re.delete(e), q.delete(e), U.delete(e), x === e && (x = null); | ||
| } | ||
| function ye(e) { | ||
| return j.get(e) === !0; | ||
| } | ||
| function be(e, t) { | ||
| if (!t.classList.contains("show")) return; | ||
| const r = xe(e).getBoundingClientRect(), n = Math.min(window.innerWidth - 20, 520), a = Math.max(10, window.innerWidth - n - 10), o = Math.min(Math.max(10, r.right - n), a), l = Math.max(10, Math.min(window.innerHeight - 10, r.top + 12)); | ||
| t.style.width = `${n}px`, t.style.left = `${o}px`, t.style.top = `${l}px`, t.style.maxHeight = `${Math.max(260, window.innerHeight - 20)}px`; | ||
| } | ||
| function H(e, t) { | ||
| const r = e.querySelector(".rte-translation-live"); | ||
| r && (r.textContent = t); | ||
| } | ||
| function rt(e, t) { | ||
| return `${e.innerHTML}::${t.sourceLocale}::${t.targetLocale}::${Array.from(t.lockedSegmentIds).sort().join("|")}`; | ||
| } | ||
| function ot(e, t, r) { | ||
| const n = [], a = et(r, t.targetLocale); | ||
| for (let o = 0; o < e.length && !(n.length >= r.maxIssues); o += 1) { | ||
| const l = e[o], s = r.normalizeText(l.sourceText || ""), i = r.normalizeText(l.text || ""); | ||
| if (!i) { | ||
| n.push( | ||
| te("missing-target", "error", r.labels.missingTargetMessage, { | ||
| segmentId: l.id, | ||
| sourceText: s, | ||
| targetText: i, | ||
| suggestion: "Provide translated content for this segment before export." | ||
| }) | ||
| ); | ||
| continue; | ||
| } | ||
| if (a.preserveTokens && s && !je(s, i) && (n.push( | ||
| te("token-mismatch", "error", r.labels.tokenMismatchMessage, { | ||
| segmentId: l.id, | ||
| sourceText: s, | ||
| targetText: i, | ||
| suggestion: "Preserve placeholders/tokens exactly (for example {{name}}, %ID%, ${value})." | ||
| }) | ||
| ), n.length >= r.maxIssues) || a.requireDifferentFromSource && s && r.normalizeText(s) === r.normalizeText(i) && (n.push( | ||
| te("untranslated", "warning", r.labels.untranslatedMessage, { | ||
| segmentId: l.id, | ||
| sourceText: s, | ||
| targetText: i, | ||
| suggestion: "Translate the segment or mark it intentionally unchanged." | ||
| }) | ||
| ), n.length >= r.maxIssues)) | ||
| break; | ||
| if (s.length >= r.minSourceLengthForRatio) { | ||
| const d = i.length / Math.max(1, s.length); | ||
| (d < a.minLengthRatio || d > a.maxLengthRatio) && n.push( | ||
| te("length-out-of-range", "warning", r.labels.lengthOutOfRangeMessage, { | ||
| segmentId: l.id, | ||
| sourceText: s, | ||
| targetText: i, | ||
| suggestion: `Expected ratio for ${a.label}: ${a.minLengthRatio.toFixed(2)} - ${a.maxLengthRatio.toFixed(2)}.` | ||
| }) | ||
| ); | ||
| } | ||
| } | ||
| return n; | ||
| } | ||
| function qe(e) { | ||
| const t = c.get(e) || k, r = q.get(e); | ||
| return { | ||
| sourceLocale: r?.sourceLocale || t?.sourceLocale || "en-US", | ||
| targetLocale: r?.targetLocale || t?.targetLocale || "fr-FR", | ||
| realtimeEnabled: r?.realtimeEnabled === !0, | ||
| selectedSegmentId: r?.selectedSegmentId || null, | ||
| segmentCount: r?.segments.length || 0, | ||
| lockedSegmentCount: r ? r.segments.filter((n) => n.locked).length : 0, | ||
| issues: r?.issues ? r.issues.map((n) => ({ ...n })) : [], | ||
| segments: r?.segments.map((n) => ({ | ||
| id: n.id, | ||
| tagName: n.tagName, | ||
| index: n.index, | ||
| sourceLength: n.sourceText.length, | ||
| targetLength: n.text.length, | ||
| locked: n.locked | ||
| })) || [], | ||
| lastRunAt: r?.lastRunAt || null | ||
| }; | ||
| } | ||
| function E(e) { | ||
| const t = q.get(e), r = t && t.selectedSegmentId ? t.segments.find((n) => n.id === t.selectedSegmentId) : null; | ||
| fe(e, "toggleTranslationWorkflowPanel", ye(e)), fe(e, "toggleTranslationRealtime", t?.realtimeEnabled === !0), fe(e, "toggleTranslationSegmentLock", r?.locked === !0); | ||
| } | ||
| function at(e, t) { | ||
| const r = ce(e, t); | ||
| if (!r) return; | ||
| try { | ||
| r.scrollIntoView({ block: "nearest", inline: "nearest" }); | ||
| } catch { | ||
| } | ||
| const n = window.getSelection(); | ||
| if (!(!n || typeof document.createRange != "function")) | ||
| try { | ||
| const a = document.createRange(); | ||
| a.selectNodeContents(r), a.collapse(!0), n.removeAllRanges(), n.addRange(a), e.focus({ preventScroll: !0 }); | ||
| } catch { | ||
| } | ||
| } | ||
| function R(e) { | ||
| const t = p.get(e); | ||
| if (!t) return; | ||
| const r = c.get(e) || k; | ||
| if (!r) return; | ||
| const n = b(e, r), a = t.querySelector(".rte-translation-source-label"); | ||
| a && (a.textContent = r.labels.sourceLocaleLabel); | ||
| const o = t.querySelector(".rte-translation-target-label"); | ||
| o && (o.textContent = r.labels.targetLocaleLabel); | ||
| const l = t.querySelector('[data-field="source-locale"]'), s = t.querySelector('[data-field="target-locale"]'), i = r.locales.map((f) => `<option value="${m(f)}">${m(f)}</option>`).join(""); | ||
| l && (l.innerHTML = i, l.value = n.sourceLocale), s && (s.innerHTML = i, s.value = n.targetLocale); | ||
| const d = t.querySelector(".rte-translation-summary"); | ||
| if (d) { | ||
| const f = n.issues.length, P = n.selectedSegmentId ? ` • ${r.labels.selectedSegmentPrefix}: ${n.selectedSegmentId}` : ""; | ||
| d.textContent = `${r.labels.summaryPrefix}: ${n.sourceLocale} → ${n.targetLocale} • ${f} issue${f === 1 ? "" : "s"}${P}`; | ||
| } | ||
| const g = t.querySelector(".rte-translation-helper"); | ||
| g && (g.textContent = r.labels.helperText); | ||
| const w = t.querySelector(".rte-translation-shortcut"); | ||
| w && (w.textContent = r.labels.shortcutText); | ||
| const v = t.querySelector('[data-action="run-validation"]'); | ||
| v && (v.textContent = r.labels.validateText); | ||
| const G = t.querySelector('[data-action="capture-source"]'); | ||
| G && (G.textContent = r.labels.captureSourceText); | ||
| const B = t.querySelector('[data-action="toggle-realtime"]'); | ||
| B && (B.textContent = n.realtimeEnabled ? r.labels.realtimeOnText : r.labels.realtimeOffText, B.setAttribute("aria-pressed", n.realtimeEnabled ? "true" : "false")); | ||
| const Y = t.querySelector('[data-action="lock-selected"]'), ue = n.selectedSegmentId && n.segments.find((f) => f.id === n.selectedSegmentId) || null; | ||
| Y && (Y.textContent = ue?.locked ? r.labels.unlockSelectedText : r.labels.lockSelectedText, Y.disabled = !ue, Y.setAttribute("aria-pressed", ue?.locked ? "true" : "false")); | ||
| const Le = t.querySelector('[data-action="close"]'); | ||
| Le && Le.setAttribute("aria-label", r.labels.closeText); | ||
| const Z = t.querySelector(".rte-translation-issues"), F = t.querySelector(".rte-translation-empty"); | ||
| Z && (Z.setAttribute("aria-label", r.labels.issuesLabel), n.issues.length === 0 ? (Z.innerHTML = "", F && (F.hidden = !1, F.textContent = r.labels.noIssuesText)) : (F && (F.hidden = !0), Z.innerHTML = n.issues.map((f) => ` | ||
| <li class="rte-translation-issue ${f.severity === "error" ? "error" : f.severity === "warning" ? "warning" : "info"}" role="listitem" data-segment-id="${m( | ||
| f.segmentId || "" | ||
| )}"> | ||
| <p class="rte-translation-issue-message">${m(f.message)}</p> | ||
| ${f.suggestion ? `<p class="rte-translation-issue-suggestion">${m(f.suggestion)}</p>` : ""} | ||
| </li> | ||
| `).join(""))); | ||
| const de = t.querySelector(".rte-translation-segments"); | ||
| de && (de.setAttribute("aria-label", r.labels.segmentsLabel), de.innerHTML = n.segments.map((f) => { | ||
| const P = f.id === n.selectedSegmentId ? "selected" : "", Ne = f.locked ? "locked" : ""; | ||
| return ` | ||
| <li class="rte-translation-segment-item ${P} ${Ne}" role="option" aria-selected="${f.id === n.selectedSegmentId ? "true" : "false"}" data-segment-id="${m(f.id)}"> | ||
| <button type="button" class="rte-translation-segment-select" data-action="select-segment" data-segment-id="${m( | ||
| f.id | ||
| )}" title="${m(f.text)}"> | ||
| <span class="rte-translation-segment-meta">#${f.index + 1} • ${m(f.tagName)}</span> | ||
| <span class="rte-translation-segment-text">${m(Ve(f.text, 110))}</span> | ||
| </button> | ||
| <button type="button" class="rte-translation-segment-lock" data-action="toggle-lock" data-segment-id="${m( | ||
| f.id | ||
| )}" aria-label="${f.locked ? r.labels.unlockSegmentAriaLabel : r.labels.lockSegmentAriaLabel}" aria-pressed="${f.locked ? "true" : "false"}"></button> | ||
| </li> | ||
| `; | ||
| }).join("")); | ||
| const J = t.querySelector(".rte-translation-source-preview"), Q = t.querySelector(".rte-translation-target-preview"); | ||
| if (J || Q) { | ||
| const f = n.selectedSegmentId && n.segments.find((P) => P.id === n.selectedSegmentId) || null; | ||
| J && (J.textContent = f?.sourceText || "—", J.setAttribute("aria-label", r.labels.sourcePreviewLabel)), Q && (Q.textContent = f?.text || "—", Q.setAttribute("aria-label", r.labels.targetPreviewLabel)); | ||
| } | ||
| t.setAttribute("aria-label", r.labels.panelAriaLabel); | ||
| } | ||
| function Be(e) { | ||
| const t = c.get(e) || k; | ||
| if (!t) return; | ||
| we(e); | ||
| const r = window.setTimeout(() => { | ||
| le.delete(e), L(e, "realtime", !1); | ||
| }, t.debounceMs); | ||
| le.set(e, r); | ||
| } | ||
| function L(e, t, r) { | ||
| const n = c.get(e) || k; | ||
| if (!n) return []; | ||
| const a = b(e, n), o = me(e, a); | ||
| a.segments = M(e, n, a); | ||
| const l = rt(e, a); | ||
| if (!r && a.snapshot === l) | ||
| return a.issues; | ||
| a.issues = ot(a.segments, a, n), a.lastRunAt = (/* @__PURE__ */ new Date()).toISOString(), a.snapshot = l, R(e), E(e), e.dispatchEvent( | ||
| new CustomEvent("editora:translation-workflow-validation", { | ||
| bubbles: !0, | ||
| detail: { | ||
| reason: t, | ||
| state: qe(e) | ||
| } | ||
| }) | ||
| ); | ||
| const s = p.get(e); | ||
| if (s) { | ||
| if (o) | ||
| return H(s, n.labels.readonlySegmentMessage), a.issues; | ||
| H( | ||
| s, | ||
| a.issues.length === 0 ? n.labels.noIssuesText : `${a.issues.length} issue${a.issues.length === 1 ? "" : "s"} detected.` | ||
| ); | ||
| } | ||
| return a.issues; | ||
| } | ||
| function Pe(e) { | ||
| const t = c.get(e) || k; | ||
| if (!t) return !1; | ||
| const r = b(e, t), n = M(e, t, r); | ||
| n.forEach((o) => { | ||
| r.sourceTextBySegmentId.set(o.id, o.text); | ||
| }), r.snapshot = "", L(e, "capture-source", !0); | ||
| const a = p.get(e); | ||
| return a && H(a, t.labels.sourceCapturedMessage), e.dispatchEvent( | ||
| new CustomEvent("editora:translation-source-captured", { | ||
| bubbles: !0, | ||
| detail: { | ||
| sourceLocale: r.sourceLocale, | ||
| segmentCount: n.length | ||
| } | ||
| }) | ||
| ), !0; | ||
| } | ||
| function se(e, t, r) { | ||
| const n = c.get(e) || k; | ||
| if (!n) return !1; | ||
| const a = b(e, n); | ||
| a.segments = M(e, n, a); | ||
| const o = He(e)?.getAttribute("data-translation-segment-id") || null, l = t || o || a.selectedSegmentId || a.segments[0]?.id || null; | ||
| if (!l) return !1; | ||
| const s = ce(e, l); | ||
| if (!s) return !1; | ||
| const i = typeof r == "boolean" ? r : !a.lockedSegmentIds.has(l); | ||
| return i ? (a.lockedSegmentIds.add(l), a.lockedHtmlBySegmentId.set(l, s.innerHTML)) : (a.lockedSegmentIds.delete(l), a.lockedHtmlBySegmentId.delete(l)), ie(s, i), a.selectedSegmentId = l, a.snapshot = "", L(e, "lock-segment", !0), e.dispatchEvent( | ||
| new CustomEvent("editora:translation-segment-lock", { | ||
| bubbles: !0, | ||
| detail: { | ||
| segmentId: l, | ||
| locked: i | ||
| } | ||
| }) | ||
| ), !0; | ||
| } | ||
| function De(e, t) { | ||
| const r = c.get(e) || k; | ||
| if (!r) return !1; | ||
| const n = b(e, r), a = typeof t == "boolean" ? t : !n.realtimeEnabled; | ||
| return n.realtimeEnabled = a, a ? Be(e) : we(e), R(e), E(e), !0; | ||
| } | ||
| function pe(e, t, r = !0) { | ||
| const n = c.get(e) || k; | ||
| if (!n) return !1; | ||
| const a = b(e, n); | ||
| return a.segments = M(e, n, a), a.segments.some((o) => o.id === t) ? (a.selectedSegmentId = t, R(e), E(e), r && at(e, t), !0) : !1; | ||
| } | ||
| function ne(e, t) { | ||
| const r = c.get(e) || k; | ||
| if (!r) return !1; | ||
| const n = b(e, r); | ||
| if (n.segments = M(e, r, n), n.segments.length === 0) return !1; | ||
| const a = Math.max( | ||
| 0, | ||
| n.segments.findIndex((s) => s.id === n.selectedSegmentId) | ||
| ); | ||
| let o = a; | ||
| t === "start" ? o = 0 : t === "end" ? o = n.segments.length - 1 : o = C(a + t, 0, n.segments.length - 1); | ||
| const l = n.segments[o]; | ||
| return l ? pe(e, l.id, !0) : !1; | ||
| } | ||
| function V(e, t = !1) { | ||
| const r = p.get(e); | ||
| r && (r.classList.remove("show"), j.set(e, !1), E(e), t && e.focus({ preventScroll: !0 })); | ||
| } | ||
| function he(e) { | ||
| const t = ut(e); | ||
| p.forEach((n, a) => { | ||
| a !== e && V(a, !1); | ||
| }), t.classList.add("show"), j.set(e, !0), L(e, "panel-open", !1), R(e), be(e, t), E(e), t.querySelector('[data-field="target-locale"]')?.focus(); | ||
| } | ||
| function ze(e, t) { | ||
| const r = ye(e); | ||
| return (typeof t == "boolean" ? t : !r) ? he(e) : V(e, !1), !0; | ||
| } | ||
| function lt(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "l"; | ||
| } | ||
| function st(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "v"; | ||
| } | ||
| function it(e) { | ||
| const t = e.key.toLowerCase(); | ||
| return (e.metaKey || e.ctrlKey) && e.altKey && e.shiftKey && t === "k"; | ||
| } | ||
| function ct(e) { | ||
| return e.key.length === 1 && !e.metaKey && !e.ctrlKey && !e.altKey ? !0 : e.key === "Backspace" || e.key === "Delete" || e.key === "Enter"; | ||
| } | ||
| function Ie(e) { | ||
| return e instanceof HTMLElement ? e.closest('[data-translation-locked="true"]') : null; | ||
| } | ||
| function ut(e) { | ||
| const t = p.get(e); | ||
| if (t) return t; | ||
| const r = c.get(e) || k || oe(); | ||
| b(e, r); | ||
| const n = `rte-translation-workflow-panel-${Fe++}`, a = `${n}-source`, o = `${n}-target`, l = document.createElement("section"); | ||
| return l.className = u, l.id = n, l.setAttribute("role", "dialog"), l.setAttribute("aria-modal", "false"), l.setAttribute("aria-label", r.labels.panelAriaLabel), l.innerHTML = ` | ||
| <header class="rte-translation-header"> | ||
| <h2 class="rte-translation-title">${m(r.labels.panelTitle)}</h2> | ||
| <button type="button" class="rte-translation-icon-btn" data-action="close" aria-label="${m( | ||
| r.labels.closeText | ||
| )}">✕</button> | ||
| </header> | ||
| <div class="rte-translation-body"> | ||
| <div class="rte-translation-locales"> | ||
| <div class="rte-translation-locale-field"> | ||
| <label class="rte-translation-source-label" for="${m(a)}"></label> | ||
| <select id="${m(a)}" class="rte-translation-select" data-field="source-locale"></select> | ||
| </div> | ||
| <div class="rte-translation-locale-field"> | ||
| <label class="rte-translation-target-label" for="${m(o)}"></label> | ||
| <select id="${m(o)}" class="rte-translation-select" data-field="target-locale"></select> | ||
| </div> | ||
| </div> | ||
| <p class="rte-translation-summary"></p> | ||
| <div class="rte-translation-actions"> | ||
| <button type="button" class="rte-translation-btn rte-translation-btn-primary" data-action="run-validation"></button> | ||
| <button type="button" class="rte-translation-btn" data-action="capture-source"></button> | ||
| <button type="button" class="rte-translation-btn" data-action="lock-selected"></button> | ||
| <button type="button" class="rte-translation-btn" data-action="toggle-realtime" aria-pressed="false"></button> | ||
| </div> | ||
| <p class="rte-translation-helper"></p> | ||
| <p class="rte-translation-shortcut"></p> | ||
| <div class="rte-translation-grid"> | ||
| <section class="rte-translation-segments-wrap" aria-label="${m(r.labels.segmentsLabel)}"> | ||
| <h3 class="rte-translation-subtitle">${m(r.labels.segmentsLabel)}</h3> | ||
| <ul class="rte-translation-segments" role="listbox" tabindex="0" aria-label="${m( | ||
| r.labels.segmentsLabel | ||
| )}"></ul> | ||
| </section> | ||
| <section class="rte-translation-preview-wrap"> | ||
| <h3 class="rte-translation-subtitle">${m(r.labels.sourcePreviewLabel)} / ${m( | ||
| r.labels.targetPreviewLabel | ||
| )}</h3> | ||
| <div class="rte-translation-preview-block"> | ||
| <p class="rte-translation-preview-label">${m(r.labels.sourcePreviewLabel)}</p> | ||
| <p class="rte-translation-source-preview"></p> | ||
| </div> | ||
| <div class="rte-translation-preview-block"> | ||
| <p class="rte-translation-preview-label">${m(r.labels.targetPreviewLabel)}</p> | ||
| <p class="rte-translation-target-preview"></p> | ||
| </div> | ||
| </section> | ||
| </div> | ||
| <section class="rte-translation-issues-wrap"> | ||
| <h3 class="rte-translation-subtitle">${m(r.labels.issuesLabel)}</h3> | ||
| <ul class="rte-translation-issues" role="list" aria-label="${m(r.labels.issuesLabel)}"></ul> | ||
| <p class="rte-translation-empty" hidden></p> | ||
| </section> | ||
| </div> | ||
| <div class="rte-translation-live" aria-live="polite" aria-atomic="true"></div> | ||
| `, l.addEventListener("click", (s) => { | ||
| const i = s.target; | ||
| if (!i) return; | ||
| const d = i.closest("[data-action]"); | ||
| if (!d) { | ||
| const v = i.closest(".rte-translation-issue[data-segment-id]")?.getAttribute("data-segment-id") || ""; | ||
| v && pe(e, v, !0); | ||
| return; | ||
| } | ||
| const g = d.getAttribute("data-action"); | ||
| if (g === "close") { | ||
| V(e, !0); | ||
| return; | ||
| } | ||
| if (g === "run-validation") { | ||
| L(e, "panel-button", !0); | ||
| return; | ||
| } | ||
| if (g === "capture-source") { | ||
| Pe(e); | ||
| return; | ||
| } | ||
| if (g === "lock-selected") { | ||
| se(e); | ||
| return; | ||
| } | ||
| if (g === "toggle-realtime") { | ||
| De(e); | ||
| return; | ||
| } | ||
| if (g === "select-segment") { | ||
| const w = d.getAttribute("data-segment-id") || ""; | ||
| w && pe(e, w, !0); | ||
| return; | ||
| } | ||
| if (g === "toggle-lock") { | ||
| const w = d.getAttribute("data-segment-id") || ""; | ||
| w && se(e, w); | ||
| } | ||
| }), l.addEventListener("change", (s) => { | ||
| const i = s.target; | ||
| if (!(i instanceof HTMLSelectElement)) return; | ||
| const d = c.get(e) || k; | ||
| if (!d) return; | ||
| const g = b(e, d); | ||
| if (i.getAttribute("data-field") === "source-locale") { | ||
| g.sourceLocale = A(i.value), g.snapshot = "", L(e, "source-locale-change", !0); | ||
| return; | ||
| } | ||
| i.getAttribute("data-field") === "target-locale" && (g.targetLocale = A(i.value), g.snapshot = "", L(e, "target-locale-change", !0)); | ||
| }), l.addEventListener("keydown", (s) => { | ||
| const i = s.target; | ||
| if (s.key === "Escape") { | ||
| s.preventDefault(), V(e, !0); | ||
| return; | ||
| } | ||
| !i?.closest(".rte-translation-segments") || !Me.has(s.key) || (s.preventDefault(), s.key === "ArrowUp" ? ne(e, -1) : s.key === "ArrowDown" ? ne(e, 1) : s.key === "Home" ? ne(e, "start") : s.key === "End" && ne(e, "end")); | ||
| }), ge(l, e), document.body.appendChild(l), p.set(e, l), j.set(e, !1), R(e), l; | ||
| } | ||
| function dt(e) { | ||
| k = e, D || (D = (t) => { | ||
| ae(); | ||
| const n = t.target?.closest(S); | ||
| if (!n) return; | ||
| const a = c.get(n) || e, o = b(n, a); | ||
| c.set(n, a), x = n; | ||
| const l = He(n)?.getAttribute("data-translation-segment-id") || null; | ||
| l && (o.selectedSegmentId = l), E(n); | ||
| const s = p.get(n); | ||
| s && (ge(s, n), be(n, s), R(n)); | ||
| }, document.addEventListener("focusin", D, !0)), z || (z = (t) => { | ||
| const n = t.target?.closest(S); | ||
| if (!n) return; | ||
| const a = c.get(n) || k; | ||
| if (!a) return; | ||
| const o = b(n, a), l = me(n, o); | ||
| if (o.segments = M(n, a, o), !o.realtimeEnabled) { | ||
| if (l) { | ||
| const s = p.get(n); | ||
| s && H(s, a.labels.readonlySegmentMessage); | ||
| } | ||
| R(n), E(n); | ||
| return; | ||
| } | ||
| Be(n); | ||
| }, document.addEventListener("input", z, !0)), N || (N = (t) => { | ||
| const r = t, n = r.target, a = n?.closest(S); | ||
| if (!a) return; | ||
| const o = Ie(n); | ||
| if (!o || !a.contains(o)) return; | ||
| r.preventDefault(); | ||
| const l = p.get(a), s = c.get(a) || k; | ||
| l && s && H(l, s.labels.readonlySegmentMessage); | ||
| }, document.addEventListener("beforeinput", N, !0)), O || (O = (t) => { | ||
| if (t.defaultPrevented) return; | ||
| const r = t.target; | ||
| if (r?.closest(`.${u}`) && t.key !== "Escape" && !Me.has(t.key)) return; | ||
| const a = t.key === "Escape", o = lt(t), l = st(t), s = it(t), i = Ie(r); | ||
| if (!a && !o && !l && !s && !i) | ||
| return; | ||
| const d = Xe(t); | ||
| if (!d) return; | ||
| const g = c.get(d) || k || e; | ||
| if (b(d, g), c.set(d, g), x = d, a && ye(d)) { | ||
| t.preventDefault(), V(d, !0); | ||
| return; | ||
| } | ||
| if (i && d.contains(i) && ct(t)) { | ||
| t.preventDefault(); | ||
| const w = p.get(d); | ||
| w && H(w, g.labels.readonlySegmentMessage); | ||
| return; | ||
| } | ||
| if (o) { | ||
| t.preventDefault(), t.stopPropagation(), ze(d); | ||
| return; | ||
| } | ||
| if (l) { | ||
| t.preventDefault(), t.stopPropagation(), L(d, "shortcut", !0); | ||
| return; | ||
| } | ||
| s && (t.preventDefault(), t.stopPropagation(), se(d)); | ||
| }, document.addEventListener("keydown", O, !0)), I || (I = () => { | ||
| ae(), p.forEach((t, r) => { | ||
| !r.isConnected || !t.isConnected || (ge(t, r), be(r, t)); | ||
| }); | ||
| }, window.addEventListener("scroll", I, !0), window.addEventListener("resize", I)), !_ && typeof MutationObserver < "u" && document.body && (_ = new MutationObserver((t) => { | ||
| Qe(t) && ae(), t.some((n) => n.type === "characterData" ? !0 : n.type === "childList" && (n.addedNodes.length > 0 || n.removedNodes.length > 0)) && U.forEach((n) => { | ||
| const a = q.get(n); | ||
| if (!a || a.lockedSegmentIds.size === 0 || !me(n, a)) return; | ||
| a.snapshot = ""; | ||
| const l = c.get(n) || k, s = p.get(n); | ||
| s && l && H(s, l.labels.readonlySegmentMessage), l && (a.segments = M(n, l, a), R(n), E(n)); | ||
| }); | ||
| }), _.observe(document.body, { | ||
| childList: !0, | ||
| subtree: !0, | ||
| characterData: !0 | ||
| })); | ||
| } | ||
| function ft() { | ||
| D && (document.removeEventListener("focusin", D, !0), D = null), z && (document.removeEventListener("input", z, !0), z = null), N && (document.removeEventListener("beforeinput", N, !0), N = null), O && (document.removeEventListener("keydown", O, !0), O = null), I && (window.removeEventListener("scroll", I, !0), window.removeEventListener("resize", I), I = null), _ && (_.disconnect(), _ = null), p.forEach((t) => t.remove()), p.clear(), Array.from(U).forEach((t) => Se(t)), k = null, x = null; | ||
| } | ||
| function gt() { | ||
| if (typeof document > "u" || document.getElementById(ve)) return; | ||
| const e = document.createElement("style"); | ||
| e.id = ve, e.textContent = ` | ||
| .rte-toolbar-group-items.${y}, | ||
| .editora-toolbar-group-items.${y}, | ||
| .rte-toolbar-group-items.${$}, | ||
| .editora-toolbar-group-items.${$} { | ||
| display: flex; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 4px; | ||
| background: #ffffff; | ||
| } | ||
| .rte-toolbar-group-items.${y} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${y} .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${$} .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${$} .editora-toolbar-button { | ||
| border: none; | ||
| border-right: 1px solid #cbd5e1; | ||
| border-radius: 0; | ||
| } | ||
| .rte-toolbar-group-items.${y} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${y} .editora-toolbar-item:last-child .editora-toolbar-button, | ||
| .rte-toolbar-group-items.${$} .rte-toolbar-item:last-child .rte-toolbar-button, | ||
| .editora-toolbar-group-items.${$} .editora-toolbar-item:last-child .editora-toolbar-button { | ||
| border-right: none; | ||
| } | ||
| ${h} .rte-toolbar-group-items.${y}, | ||
| ${h} .editora-toolbar-group-items.${y}, | ||
| ${h} .rte-toolbar-group-items.${$}, | ||
| ${h} .editora-toolbar-group-items.${$} { | ||
| border-color: #566275; | ||
| } | ||
| .rte-toolbar-button[data-command="toggleTranslationWorkflowPanel"].active, | ||
| .editora-toolbar-button[data-command="toggleTranslationWorkflowPanel"].active, | ||
| .rte-toolbar-button[data-command="toggleTranslationSegmentLock"].active, | ||
| .editora-toolbar-button[data-command="toggleTranslationSegmentLock"].active, | ||
| .rte-toolbar-button[data-command="toggleTranslationRealtime"].active, | ||
| .editora-toolbar-button[data-command="toggleTranslationRealtime"].active { | ||
| background: #ccc; | ||
| } | ||
| ${h} .rte-toolbar-group-items.${y} .rte-toolbar-button svg, | ||
| ${h} .editora-toolbar-group-items.${y} .editora-toolbar-button svg, | ||
| ${h} .rte-toolbar-group-items.${$} .rte-toolbar-button svg, | ||
| ${h} .editora-toolbar-group-items.${$} .editora-toolbar-button svg | ||
| { | ||
| fill: none; | ||
| } | ||
| ${h} .rte-toolbar-group-items.${y} .rte-toolbar-button, | ||
| ${h} .editora-toolbar-group-items.${y} .editora-toolbar-button | ||
| { | ||
| border-color: #566275; | ||
| } | ||
| ${h} .rte-toolbar-button[data-command="toggleTranslationWorkflowPanel"].active, | ||
| ${h} .editora-toolbar-button[data-command="toggleTranslationWorkflowPanel"].active, | ||
| ${h} .rte-toolbar-button[data-command="toggleTranslationSegmentLock"].active, | ||
| ${h} .editora-toolbar-button[data-command="toggleTranslationSegmentLock"].active, | ||
| ${h} .rte-toolbar-button[data-command="toggleTranslationRealtime"].active, | ||
| ${h} .editora-toolbar-button[data-command="toggleTranslationRealtime"].active { | ||
| background: linear-gradient(180deg, #5eaaf6 0%, #4a95de 100%); | ||
| } | ||
| .${u} { | ||
| position: fixed; | ||
| z-index: 12000; | ||
| display: none; | ||
| width: min(520px, calc(100vw - 20px)); | ||
| max-height: calc(100vh - 20px); | ||
| border: 1px solid #d1d5db; | ||
| border-radius: 14px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| box-shadow: 0 24px 48px rgba(15, 23, 42, 0.24); | ||
| overflow: hidden; | ||
| } | ||
| .${u}.show { | ||
| display: flex; | ||
| flex-direction: column; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark { | ||
| border-color: #334155; | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| box-shadow: 0 24px 52px rgba(2, 6, 23, 0.68); | ||
| } | ||
| .rte-translation-header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: 8px; | ||
| padding: 12px 14px; | ||
| border-bottom: 1px solid #e2e8f0; | ||
| background: linear-gradient(180deg, #eff6ff 0%, #e2e8f0 100%); | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-header { | ||
| border-color: #1e293b; | ||
| background: linear-gradient(180deg, #111827 0%, #0f172a 100%); | ||
| } | ||
| .rte-translation-title { | ||
| margin: 0; | ||
| font-size: 15px; | ||
| line-height: 1.2; | ||
| font-weight: 700; | ||
| } | ||
| .rte-translation-icon-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| min-height: 34px; | ||
| width: 34px; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| font-weight: 600; | ||
| padding: 0; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| cursor: pointer; | ||
| } | ||
| .rte-translation-icon-btn:hover, | ||
| .rte-translation-icon-btn:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-icon-btn { | ||
| border-color: #475569; | ||
| background: #0f172a; | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-icon-btn:hover, | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-icon-btn:focus-visible { | ||
| border-color: #60a5fa; | ||
| box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.24); | ||
| } | ||
| .rte-translation-body { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 8px; | ||
| padding: 12px; | ||
| overflow: auto; | ||
| } | ||
| .rte-translation-locales { | ||
| display: grid; | ||
| grid-template-columns: repeat(2, minmax(0, 1fr)); | ||
| gap: 8px; | ||
| } | ||
| .rte-translation-locale-field { | ||
| display: grid; | ||
| gap: 4px; | ||
| } | ||
| .rte-translation-source-label, | ||
| .rte-translation-target-label { | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| color: #334155; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-source-label, | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-target-label { | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-translation-select { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| min-height: 34px; | ||
| padding: 0 10px; | ||
| font-size: 13px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| } | ||
| .rte-translation-select:focus-visible { | ||
| border-color: #0e7490; | ||
| box-shadow: 0 0 0 3px rgba(14, 116, 144, 0.18); | ||
| outline: none; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-select { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| color: #e2e8f0; | ||
| } | ||
| .rte-translation-summary, | ||
| .rte-translation-helper, | ||
| .rte-translation-shortcut { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #475569; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-summary, | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-helper, | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-shortcut { | ||
| color: #94a3b8; | ||
| } | ||
| .rte-translation-actions { | ||
| display: grid; | ||
| grid-template-columns: repeat(4, minmax(0, 1fr)); | ||
| gap: 8px; | ||
| } | ||
| .rte-translation-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| min-height: 34px; | ||
| padding: 0 8px; | ||
| background: #ffffff; | ||
| color: inherit; | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| cursor: pointer; | ||
| } | ||
| .rte-translation-btn:disabled { | ||
| opacity: 0.6; | ||
| cursor: not-allowed; | ||
| } | ||
| .rte-translation-btn-primary { | ||
| border-color: #0e7490; | ||
| background: #0e7490; | ||
| color: #f8fafc; | ||
| } | ||
| .rte-translation-btn:hover, | ||
| .rte-translation-btn:focus-visible { | ||
| border-color: #94a3b8; | ||
| outline: none; | ||
| } | ||
| .rte-translation-btn-primary:hover, | ||
| .rte-translation-btn-primary:focus-visible { | ||
| border-color: #155e75; | ||
| background: #155e75; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-btn { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-btn-primary { | ||
| border-color: #22d3ee; | ||
| background: #0e7490; | ||
| color: #ecfeff; | ||
| } | ||
| .rte-translation-grid { | ||
| display: grid; | ||
| grid-template-columns: 1fr 1fr; | ||
| gap: 8px; | ||
| } | ||
| .rte-translation-segments-wrap, | ||
| .rte-translation-preview-wrap, | ||
| .rte-translation-issues-wrap { | ||
| border: 1px solid #e2e8f0; | ||
| border-radius: 10px; | ||
| background: #f8fafc; | ||
| padding: 8px; | ||
| min-height: 120px; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-segments-wrap, | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-preview-wrap, | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-issues-wrap { | ||
| border-color: #334155; | ||
| background: #0b1220; | ||
| } | ||
| .rte-translation-subtitle { | ||
| margin: 0 0 6px; | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| color: #334155; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-subtitle { | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-translation-segments { | ||
| margin: 0; | ||
| padding: 0; | ||
| list-style: none; | ||
| display: grid; | ||
| gap: 6px; | ||
| max-height: 220px; | ||
| overflow: auto; | ||
| outline: none; | ||
| } | ||
| .rte-translation-segment-item { | ||
| display: grid; | ||
| grid-template-columns: 1fr auto; | ||
| gap: 6px; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| background: #ffffff; | ||
| padding: 6px; | ||
| } | ||
| .rte-translation-segment-item.selected { | ||
| border-color: #0e7490; | ||
| box-shadow: 0 0 0 2px rgba(14, 116, 144, 0.16); | ||
| } | ||
| .rte-translation-segment-item.locked { | ||
| border-color: #f59e0b; | ||
| background: #fffbeb; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-segment-item { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-segment-item.locked { | ||
| border-color: rgba(245, 158, 11, 0.72); | ||
| background: rgba(120, 53, 15, 0.28); | ||
| } | ||
| .rte-translation-segment-select { | ||
| border: none; | ||
| background: transparent; | ||
| color: inherit; | ||
| text-align: left; | ||
| padding: 0; | ||
| cursor: pointer; | ||
| display: grid; | ||
| gap: 2px; | ||
| } | ||
| .rte-translation-segment-meta { | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| font-weight: 700; | ||
| } | ||
| .rte-translation-segment-text { | ||
| font-size: 12px; | ||
| color: #334155; | ||
| line-height: 1.3; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-segment-meta { | ||
| color: #94a3b8; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-segment-text { | ||
| color: #e2e8f0; | ||
| } | ||
| .rte-translation-segment-lock { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| width: 28px; | ||
| min-height: 28px; | ||
| background: #ffffff; | ||
| cursor: pointer; | ||
| position: relative; | ||
| color: inherit; | ||
| font-size: 0; | ||
| } | ||
| .rte-translation-segment-lock::before { | ||
| content: '🔒'; | ||
| font-size: 14px; | ||
| position: absolute; | ||
| inset: 0; | ||
| display: grid; | ||
| place-items: center; | ||
| opacity: 0.35; | ||
| } | ||
| .rte-translation-segment-lock[aria-pressed="true"]::before { | ||
| opacity: 1; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-segment-lock { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| } | ||
| .rte-translation-preview-block { | ||
| display: grid; | ||
| gap: 4px; | ||
| margin-bottom: 8px; | ||
| } | ||
| .rte-translation-preview-label { | ||
| margin: 0; | ||
| font-size: 11px; | ||
| color: #64748b; | ||
| font-weight: 700; | ||
| } | ||
| .rte-translation-source-preview, | ||
| .rte-translation-target-preview { | ||
| margin: 0; | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| background: #ffffff; | ||
| padding: 8px; | ||
| font-size: 12px; | ||
| min-height: 56px; | ||
| white-space: pre-wrap; | ||
| line-height: 1.35; | ||
| color: #1f2937; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-preview-label { | ||
| color: #94a3b8; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-source-preview, | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-target-preview { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .rte-translation-issues { | ||
| margin: 0; | ||
| padding: 0; | ||
| list-style: none; | ||
| display: grid; | ||
| gap: 6px; | ||
| max-height: 200px; | ||
| overflow: auto; | ||
| } | ||
| .rte-translation-issue { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| background: #ffffff; | ||
| padding: 8px; | ||
| display: grid; | ||
| gap: 4px; | ||
| cursor: pointer; | ||
| } | ||
| .rte-translation-issue.error { | ||
| border-color: #ef4444; | ||
| background: #fef2f2; | ||
| } | ||
| .rte-translation-issue.warning { | ||
| border-color: #f59e0b; | ||
| background: #fffbeb; | ||
| } | ||
| .rte-translation-issue.info { | ||
| border-color: #0ea5e9; | ||
| background: #f0f9ff; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-issue { | ||
| border-color: #334155; | ||
| background: #111827; | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-issue.error { | ||
| border-color: rgba(239, 68, 68, 0.7); | ||
| background: rgba(127, 29, 29, 0.28); | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-issue.warning { | ||
| border-color: rgba(245, 158, 11, 0.72); | ||
| background: rgba(120, 53, 15, 0.28); | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-issue.info { | ||
| border-color: rgba(14, 165, 233, 0.7); | ||
| background: rgba(7, 89, 133, 0.28); | ||
| } | ||
| .rte-translation-issue-message, | ||
| .rte-translation-issue-suggestion { | ||
| margin: 0; | ||
| font-size: 12px; | ||
| line-height: 1.35; | ||
| color: #1f2937; | ||
| } | ||
| .rte-translation-issue-suggestion { | ||
| color: #475569; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-issue-message { | ||
| color: #e2e8f0; | ||
| } | ||
| .${u}.rte-translation-workflow-theme-dark .rte-translation-issue-suggestion { | ||
| color: #cbd5e1; | ||
| } | ||
| .rte-translation-empty { | ||
| margin: 8px; | ||
| font-size: 12px; | ||
| color: #64748b; | ||
| } | ||
| .rte-translation-live { | ||
| position: absolute; | ||
| width: 1px; | ||
| height: 1px; | ||
| margin: -1px; | ||
| padding: 0; | ||
| overflow: hidden; | ||
| clip: rect(0 0 0 0); | ||
| border: 0; | ||
| } | ||
| [data-translation-locked="true"].rte-translation-segment-locked { | ||
| outline: 2px dashed rgba(245, 158, 11, 0.65); | ||
| outline-offset: 2px; | ||
| background: rgba(255, 251, 235, 0.8); | ||
| border-radius: 4px; | ||
| } | ||
| ${h} [data-translation-locked="true"].rte-translation-segment-locked { | ||
| outline-color: rgba(245, 158, 11, 0.75); | ||
| background: rgba(120, 53, 15, 0.22); | ||
| } | ||
| @media (max-width: 920px) { | ||
| .${u} { | ||
| left: 10px !important; | ||
| right: 10px; | ||
| top: 10px !important; | ||
| width: auto !important; | ||
| max-height: calc(100vh - 20px); | ||
| } | ||
| .rte-translation-locales, | ||
| .rte-translation-actions, | ||
| .rte-translation-grid { | ||
| grid-template-columns: 1fr; | ||
| } | ||
| } | ||
| `, document.head.appendChild(e); | ||
| } | ||
| const mt = (e = {}) => { | ||
| const t = oe(e), r = /* @__PURE__ */ new Set(); | ||
| return gt(), { | ||
| name: "translationWorkflow", | ||
| toolbar: [ | ||
| { | ||
| id: "translationWorkflowGroup", | ||
| label: "Translation Workflow", | ||
| type: "group", | ||
| command: "translationWorkflow", | ||
| items: [ | ||
| { | ||
| id: "toggleTranslationWorkflowPanel", | ||
| label: "Translation Workflow", | ||
| command: "toggleTranslationWorkflowPanel", | ||
| shortcut: "Mod-Alt-Shift-l", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M4 6.5a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2H8l-4 3V6.5Z" stroke="currentColor" stroke-width="1.6"/><path d="M20 17.5a2 2 0 0 1-2 2h-8a2 2 0 0 1-2-2v-1.5" stroke="currentColor" stroke-width="1.6"/><path d="m13 8 2 2m0 0 2-2m-2 2V4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>' | ||
| }, | ||
| { | ||
| id: "runTranslationLocaleValidation", | ||
| label: "Run Locale Validation", | ||
| command: "runTranslationLocaleValidation", | ||
| shortcut: "Mod-Alt-Shift-v", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><rect x="4.5" y="4" width="12" height="16" rx="2" stroke="currentColor" stroke-width="1.6"/><path d="M8 8h5.5M8 11h4M8 14h3" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><path d="m15.5 15.5 1.7 1.7 3.3-3.3" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>' | ||
| }, | ||
| { | ||
| id: "toggleTranslationSegmentLock", | ||
| label: "Toggle Segment Lock", | ||
| command: "toggleTranslationSegmentLock", | ||
| shortcut: "Mod-Alt-Shift-k", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><rect x="5" y="10" width="14" height="10" rx="2" stroke="currentColor" stroke-width="1.6"/><path d="M8.5 10V7.5a3.5 3.5 0 1 1 7 0V10" stroke="currentColor" stroke-width="1.6"/><circle cx="12" cy="15" r="1.2" fill="currentColor"/></svg>' | ||
| }, | ||
| { | ||
| id: "toggleTranslationRealtime", | ||
| label: "Toggle Translation Realtime", | ||
| command: "toggleTranslationRealtime", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><path d="M4.5 12a7.5 7.5 0 1 1 7.5 7.5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><path d="M9.5 19.5H5.5v-4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/><path d="M12 8v4l2.5 2" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>' | ||
| } | ||
| ] | ||
| } | ||
| ], | ||
| commands: { | ||
| translationWorkflow: (n, a) => { | ||
| const o = T(a, !1, !1); | ||
| if (!o) return !1; | ||
| const l = c.get(o) || t; | ||
| return b(o, l), c.set(o, l), x = o, he(o), !0; | ||
| }, | ||
| openTranslationWorkflowPanel: (n, a) => { | ||
| const o = T(a, !1, !1); | ||
| if (!o) return !1; | ||
| const l = c.get(o) || t; | ||
| return b(o, l), c.set(o, l), x = o, he(o), !0; | ||
| }, | ||
| toggleTranslationWorkflowPanel: (n, a) => { | ||
| const o = T(a, !1, !1); | ||
| if (!o) return !1; | ||
| const l = c.get(o) || t; | ||
| return b(o, l), c.set(o, l), x = o, ze(o, typeof n == "boolean" ? n : void 0); | ||
| }, | ||
| runTranslationLocaleValidation: (n, a) => { | ||
| const o = T(a, !1, !1); | ||
| if (!o) return !1; | ||
| const l = c.get(o) || t; | ||
| return b(o, l), c.set(o, l), x = o, L(o, "command", !0), !0; | ||
| }, | ||
| toggleTranslationRealtime: (n, a) => { | ||
| const o = T(a, !1, !1); | ||
| if (!o) return !1; | ||
| const l = c.get(o) || t; | ||
| return b(o, l), c.set(o, l), x = o, De(o, typeof n == "boolean" ? n : void 0); | ||
| }, | ||
| toggleTranslationSegmentLock: (n, a) => { | ||
| const o = T(a, !1, !1); | ||
| if (!o) return !1; | ||
| const l = c.get(o) || t; | ||
| b(o, l), c.set(o, l), x = o; | ||
| const s = typeof n == "boolean" ? n : n?.locked, i = typeof n == "object" ? n?.segmentId : void 0; | ||
| return se(o, i, s); | ||
| }, | ||
| setTranslationLocales: (n, a) => { | ||
| const o = T(a, !1, !1); | ||
| if (!o || !n || typeof n != "object") return !1; | ||
| const l = c.get(o) || t, s = b(o, l); | ||
| return c.set(o, l), typeof n.sourceLocale == "string" && n.sourceLocale.trim() && (s.sourceLocale = A(n.sourceLocale)), typeof n.targetLocale == "string" && n.targetLocale.trim() && (s.targetLocale = A(n.targetLocale)), s.snapshot = "", L(o, "set-locales", !0), !0; | ||
| }, | ||
| captureTranslationSourceSnapshot: (n, a) => { | ||
| const o = T(a, !1, !1); | ||
| if (!o) return !1; | ||
| const l = c.get(o) || t; | ||
| return b(o, l), c.set(o, l), x = o, Pe(o); | ||
| }, | ||
| setTranslationWorkflowOptions: (n, a) => { | ||
| const o = T(a, !1, !1); | ||
| if (!o || !n || typeof n != "object") return !1; | ||
| const l = c.get(o) || t, s = re.get(o) || Ge(l), i = { | ||
| ...s, | ||
| ...n, | ||
| labels: { | ||
| ...s.labels || {}, | ||
| ...n.labels || {} | ||
| }, | ||
| localeRules: Array.isArray(n.localeRules) ? n.localeRules : s.localeRules, | ||
| locales: Array.isArray(n.locales) ? n.locales : s.locales, | ||
| normalizeText: n.normalizeText || l.normalizeText | ||
| }, d = oe(i); | ||
| c.set(o, d), re.set(o, i); | ||
| const g = b(o, d); | ||
| return typeof n.enableRealtime == "boolean" && (g.realtimeEnabled = n.enableRealtime), typeof n.sourceLocale == "string" && n.sourceLocale.trim() && (g.sourceLocale = A(n.sourceLocale)), typeof n.targetLocale == "string" && n.targetLocale.trim() && (g.targetLocale = A(n.targetLocale)), g.snapshot = "", L(o, "set-options", !0), R(o), E(o), !0; | ||
| }, | ||
| getTranslationWorkflowState: (n, a) => { | ||
| const o = T(a, !1, !1); | ||
| if (!o) return !1; | ||
| const l = c.get(o) || t; | ||
| b(o, l); | ||
| const s = qe(o); | ||
| if (typeof n == "function") | ||
| try { | ||
| n(s); | ||
| } catch { | ||
| } | ||
| return o.__translationWorkflowState = s, o.dispatchEvent( | ||
| new CustomEvent("editora:translation-workflow-state", { | ||
| bubbles: !0, | ||
| detail: s | ||
| }) | ||
| ), !0; | ||
| } | ||
| }, | ||
| keymap: { | ||
| "Mod-Alt-Shift-l": "toggleTranslationWorkflowPanel", | ||
| "Mod-Alt-Shift-L": "toggleTranslationWorkflowPanel", | ||
| "Mod-Alt-Shift-v": "runTranslationLocaleValidation", | ||
| "Mod-Alt-Shift-V": "runTranslationLocaleValidation", | ||
| "Mod-Alt-Shift-k": "toggleTranslationSegmentLock", | ||
| "Mod-Alt-Shift-K": "toggleTranslationSegmentLock" | ||
| }, | ||
| init: function(a) { | ||
| X += 1; | ||
| const o = this && typeof this.__pluginConfig == "object" ? { ...e, ...this.__pluginConfig } : e, l = oe(o); | ||
| dt(l); | ||
| const s = T( | ||
| a?.editorElement ? { editorElement: a.editorElement } : void 0, | ||
| !1, | ||
| !1 | ||
| ); | ||
| if (!s) return; | ||
| x = s, r.add(s); | ||
| const i = b(s, l); | ||
| c.set(s, l), re.set(s, o), i.segments = M(s, l, i), L(s, "init", !0), E(s); | ||
| }, | ||
| destroy: () => { | ||
| r.forEach((n) => Se(n)), r.clear(), X = Math.max(0, X - 1), !(X > 0) && ft(); | ||
| } | ||
| }; | ||
| }; | ||
| export { | ||
| mt as TranslationWorkflowPlugin | ||
| }; |
| "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const $=".rte-content, .editora-content",d='[data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark',l="rte-version-diff-overlay",U="rte-version-diff-styles",ae={title:"Version Diff",baseline:"Baseline",current:"Current",noChanges:"No changes detected between baseline and current content.",loading:"Preparing diff...",tabInline:"Inline Diff",tabSideBySide:"Side by Side",refresh:"Refresh",setBaseline:"Set Current as Baseline",close:"Close",mode:"Mode",ignoreWhitespace:"Ignore whitespace",largeDocFallback:"Large document fallback mode applied for performance."},w=new WeakMap,V=new WeakMap;let j=0,S=null,z=null,R=null,M=null,H=null,D=null;function u(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function le(e){return{...ae,...e||{}}}function N(e,i=!0){if(e?.contentElement instanceof HTMLElement)return e.contentElement;if(e?.editorElement instanceof HTMLElement){const t=e.editorElement;if(t.matches($))return t;const o=t.querySelector($);if(o instanceof HTMLElement)return o}const n=window.getSelection();if(n&&n.rangeCount>0){const t=n.getRangeAt(0).startContainer,f=(t.nodeType===Node.ELEMENT_NODE?t:t.parentElement)?.closest($);if(f)return f}const r=document.activeElement;if(r){if(r.matches($))return r;const t=r.closest($);if(t)return t}return D&&D.isConnected?D:i?document.querySelector($):null}function O(e){return e.closest("[data-editora-editor], .rte-editor, .editora-editor, editora-editor")||e}function K(e){if(!e)return!1;const i=e.getAttribute("data-theme")||e.getAttribute("theme");if(i&&i.toLowerCase()==="dark")return!0;const n=e.classList;return n.contains("dark")||n.contains("editora-theme-dark")||n.contains("rte-theme-dark")}function Y(e){const i=O(e);if(K(i))return!0;const n=i.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark");return!!(K(n)||K(document.documentElement)||K(document.body))}function fe(e){const i=document.createElement("textarea");return i.innerHTML=e,i.value}function W(e){const n=O(e).getAttribute("data-initial-content");return n?fe(n):e.innerHTML}function Z(e){return e.replace(/\r\n?/g,` | ||
| `)}function J(e){const i=document.createElement("div"),n=e.replace(/<br\s*\/?>/gi,` | ||
| `).replace(/<\/(p|div|h1|h2|h3|h4|h5|h6|li|tr|blockquote|pre|section|article)>/gi,`$& | ||
| `);i.innerHTML=n;const r=i.textContent||"";return Z(r).replace(/\u00a0/g," ").replace(/\n{3,}/g,` | ||
| `).trim()}function Q(e,i,n){let r=Z(e);if(n&&(r=r.replace(/[ \t]+/g," ").replace(/\n{3,}/g,` | ||
| `).trim()),!r)return[];if(i==="line")return r.split(` | ||
| `);if(n)return r.split(/\s+/).filter(Boolean);const t=[],o=r.split(` | ||
| `);return o.forEach((f,g)=>{const c=f.split(/[ \t]+/).filter(Boolean);t.push(...c),g<o.length-1&&t.push(` | ||
| `)}),t}function de(e,i,n){if(e.length===0)return"";if(i==="line")return e.join(` | ||
| `);if(n)return e.join(" ");let r="";for(let t=0;t<e.length;t+=1){const o=e[t];if(o===` | ||
| `){r=r.replace(/[ \t]+$/g,""),r+=` | ||
| `;continue}r.length>0&&!r.endsWith(` | ||
| `)&&(r+=" "),r+=o}return r}function ce(e,i,n){const r=[];return e.forEach(t=>{const o=r[r.length-1];if(o&&o.type===t.type){o.tokens.push(t.token);return}r.push({type:t.type,tokens:[t.token]})}),r.map(t=>({type:t.type,value:de(t.tokens,i,n),count:t.tokens.length}))}function ue(e,i){let n=0;for(;n<e.length&&n<i.length&&e[n]===i[n];)n+=1;let r=e.length-1,t=i.length-1;for(;r>=n&&t>=n&&e[r]===i[t];)r-=1,t-=1;const o=e.slice(0,n),f=r<e.length-1?e.slice(r+1):[],g=n<=r?e.slice(n,r+1):[],c=n<=t?i.slice(n,t+1):[];return{prefix:o,suffix:f,aMiddle:g,bMiddle:c}}function pe(e,i,n,r,t,o){if(e.length===0&&i.length===0)return{segments:[],insertedCount:0,deletedCount:0,equalCount:0,usedFallback:!1};const{prefix:f,suffix:g,aMiddle:c,bMiddle:b}=ue(e,i);let m=[];f.forEach(a=>m.push({type:"equal",token:a}));const F=c.length*b.length,T=c.length>o||b.length>o||F>t;if(T)c.forEach(a=>m.push({type:"delete",token:a})),b.forEach(a=>m.push({type:"insert",token:a}));else{const a=Array.from({length:c.length+1},()=>new Uint32Array(b.length+1));for(let y=c.length-1;y>=0;y-=1){const B=a[y],I=a[y+1];for(let k=b.length-1;k>=0;k-=1)B[k]=c[y]===b[k]?I[k+1]+1:Math.max(I[k],B[k+1])}let h=0,p=0;for(;h<c.length&&p<b.length;)c[h]===b[p]?(m.push({type:"equal",token:c[h]}),h+=1,p+=1):a[h+1][p]>=a[h][p+1]?(m.push({type:"delete",token:c[h]}),h+=1):(m.push({type:"insert",token:b[p]}),p+=1);for(;h<c.length;)m.push({type:"delete",token:c[h]}),h+=1;for(;p<b.length;)m.push({type:"insert",token:b[p]}),p+=1}g.forEach(a=>m.push({type:"equal",token:a}));const q=ce(m,n,r);let A=0,L=0,P=0;return q.forEach(a=>{a.type==="insert"&&(A+=a.count),a.type==="delete"&&(L+=a.count),a.type==="equal"&&(P+=a.count)}),{segments:q,insertedCount:A,deletedCount:L,equalCount:P,usedFallback:T}}function ee(e){return u(e.value).replace(/\n/g,` | ||
| `)}function be(e,i){return e.length===0?`<p class="rte-version-diff-empty">${u(i.noChanges)}</p>`:e.map(n=>`<span class="${n.type==="equal"?"rte-version-diff-equal":n.type==="insert"?"rte-version-diff-insert":"rte-version-diff-delete"}">${ee(n)}</span>`).join("")}function he(e,i){if(e.length===0){const t=`<p class="rte-version-diff-empty">${u(i.noChanges)}</p>`;return{baselineHtml:t,currentHtml:t}}const n=[],r=[];return e.forEach(t=>{const o=ee(t);if(t.type==="equal"){n.push(`<span class="rte-version-diff-equal">${o}</span>`),r.push(`<span class="rte-version-diff-equal">${o}</span>`);return}if(t.type==="delete"){n.push(`<span class="rte-version-diff-delete">${o}</span>`);return}r.push(`<span class="rte-version-diff-insert">${o}</span>`)}),{baselineHtml:n.join(""),currentHtml:r.join("")}}function ve(e){const i=e.metaKey||e.ctrlKey,r=(typeof e.key=="string"?e.key:"").toLowerCase(),t=typeof e.code=="string"?e.code.toLowerCase():"",o=i&&e.altKey&&!e.shiftKey&&(r==="d"||t==="keyd"),f=!e.metaKey&&!e.ctrlKey&&!e.altKey&&!e.shiftKey&&(r==="f8"||t==="f8");return o||f}function me(){if(typeof document>"u"||document.getElementById(U))return;const e=document.createElement("style");e.id=U,e.textContent=` | ||
| .${l} { | ||
| position: fixed; | ||
| inset: 0; | ||
| background: rgba(15, 23, 42, 0.55); | ||
| z-index: 2147483646; | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| padding: 20px; | ||
| } | ||
| .rte-version-diff-dialog { | ||
| width: min(980px, 96vw); | ||
| max-height: min(90vh, 860px); | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| border: 1px solid #d7dee8; | ||
| border-radius: 8px; | ||
| display: flex; | ||
| flex-direction: column; | ||
| box-shadow: 0 24px 48px rgba(15, 23, 42, 0.3); | ||
| overflow: hidden; | ||
| } | ||
| .rte-version-diff-header, | ||
| .rte-version-diff-footer { | ||
| padding: 12px 14px; | ||
| border-bottom: 1px solid #e2e8f0; | ||
| background: #f8fafc; | ||
| display: flex; | ||
| align-items: center; | ||
| gap: 10px; | ||
| flex-wrap: wrap; | ||
| } | ||
| .rte-version-diff-footer { | ||
| border-top: 1px solid #e2e8f0; | ||
| border-bottom: none; | ||
| justify-content: space-between; | ||
| } | ||
| .rte-version-diff-title { | ||
| margin: 0; | ||
| font-size: 16px; | ||
| font-weight: 700; | ||
| flex: 1; | ||
| } | ||
| .rte-version-diff-controls { | ||
| display: flex; | ||
| align-items: center; | ||
| gap: 10px; | ||
| flex-wrap: wrap; | ||
| } | ||
| .rte-version-diff-select, | ||
| .rte-version-diff-btn { | ||
| border: 1px solid #cbd5e1; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| border-radius: 6px; | ||
| min-height: 34px; | ||
| padding: 6px 10px; | ||
| font-size: 13px; | ||
| cursor: pointer; | ||
| } | ||
| .rte-version-diff-btn:hover, | ||
| .rte-version-diff-btn:focus-visible, | ||
| .rte-version-diff-select:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .rte-version-diff-btn-primary { | ||
| background: #2563eb; | ||
| border-color: #2563eb; | ||
| color: #ffffff; | ||
| } | ||
| .rte-version-diff-btn-primary:hover { | ||
| background: #1d4ed8; | ||
| } | ||
| .rte-version-diff-close-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| min-height: 34px; | ||
| min-width: 34px; | ||
| width: 34px; | ||
| height: 34px; | ||
| padding: 0; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| font-weight: 600; | ||
| } | ||
| .rte-version-diff-close-btn:hover, | ||
| .rte-version-diff-close-btn:focus-visible { | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| background: #ffffff; | ||
| outline: none; | ||
| } | ||
| .rte-version-diff-tabs { | ||
| display: flex; | ||
| gap: 6px; | ||
| border-bottom: 1px solid #e2e8f0; | ||
| background: #f8fafc; | ||
| padding: 8px 14px; | ||
| } | ||
| .rte-version-diff-tab { | ||
| border: 1px solid #cbd5e1; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| border-radius: 6px; | ||
| min-height: 32px; | ||
| padding: 4px 10px; | ||
| font-size: 13px; | ||
| cursor: pointer; | ||
| } | ||
| .rte-version-diff-tab[aria-selected="true"] { | ||
| background: #dbeafe; | ||
| border-color: #60a5fa; | ||
| color: #1e3a8a; | ||
| } | ||
| .rte-version-diff-body { | ||
| flex: 1; | ||
| overflow: auto; | ||
| padding: 10px 14px 14px; | ||
| background: #ffffff; | ||
| } | ||
| .rte-version-diff-summary { | ||
| font-size: 12px; | ||
| color: #475569; | ||
| margin-bottom: 10px; | ||
| display: flex; | ||
| gap: 14px; | ||
| flex-wrap: wrap; | ||
| } | ||
| .rte-version-diff-panel { | ||
| display: none; | ||
| } | ||
| .rte-version-diff-panel.active { | ||
| display: block; | ||
| } | ||
| .rte-version-diff-inline, | ||
| .rte-version-diff-side-pane { | ||
| border: 1px solid #dbe3ec; | ||
| border-radius: 6px; | ||
| padding: 10px; | ||
| min-height: 140px; | ||
| max-height: 50vh; | ||
| overflow: auto; | ||
| white-space: pre-wrap; | ||
| word-break: break-word; | ||
| font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; | ||
| font-size: 12px; | ||
| line-height: 1.5; | ||
| background: #ffffff; | ||
| } | ||
| .rte-version-diff-side-grid { | ||
| display: grid; | ||
| grid-template-columns: 1fr 1fr; | ||
| gap: 10px; | ||
| } | ||
| .rte-version-diff-pane-title { | ||
| margin: 0 0 6px; | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| color: #334155; | ||
| } | ||
| .rte-version-diff-equal { color: inherit; } | ||
| .rte-version-diff-insert { | ||
| background: rgba(22, 163, 74, 0.18); | ||
| color: #14532d; | ||
| border-radius: 2px; | ||
| } | ||
| .rte-version-diff-delete { | ||
| background: rgba(220, 38, 38, 0.18); | ||
| color: #7f1d1d; | ||
| text-decoration: line-through; | ||
| border-radius: 2px; | ||
| } | ||
| .rte-version-diff-empty { | ||
| margin: 0; | ||
| color: #64748b; | ||
| font-size: 13px; | ||
| } | ||
| ${d} .rte-version-diff-dialog, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-dialog { | ||
| background: #1f2937; | ||
| color: #e5e7eb; | ||
| border-color: #334155; | ||
| } | ||
| ${d} .rte-version-diff-header, | ||
| ${d} .rte-version-diff-footer, | ||
| ${d} .rte-version-diff-tabs, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-header, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-footer, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-tabs { | ||
| background: #111827; | ||
| border-color: #334155; | ||
| } | ||
| ${d} .rte-version-diff-body, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-body { | ||
| background: #1f2937; | ||
| } | ||
| ${d} .rte-version-diff-select, | ||
| ${d} .rte-version-diff-btn, | ||
| ${d} .rte-version-diff-tab, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-select, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-btn, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-tab { | ||
| background: #0f172a; | ||
| color: #e5e7eb; | ||
| border-color: #475569; | ||
| } | ||
| ${d} .rte-version-diff-close-btn, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-close-btn { | ||
| background: #0f172a; | ||
| border-color: #475569; | ||
| color: #e2e8f0; | ||
| } | ||
| ${d} .rte-version-diff-close-btn:hover, | ||
| ${d} .rte-version-diff-close-btn:focus-visible, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-close-btn:hover, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-close-btn:focus-visible { | ||
| border-color: #60a5fa; | ||
| box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.24); | ||
| outline: none; | ||
| } | ||
| ${d} .rte-version-diff-tab[aria-selected="true"], | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-tab[aria-selected="true"] { | ||
| background: #1e3a8a; | ||
| border-color: #3b82f6; | ||
| color: #dbeafe; | ||
| } | ||
| ${d} .rte-version-diff-inline, | ||
| ${d} .rte-version-diff-side-pane, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-inline, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-side-pane { | ||
| background: #0f172a; | ||
| border-color: #334155; | ||
| color: #e5e7eb; | ||
| } | ||
| ${d} .rte-version-diff-pane-title, | ||
| ${d} .rte-version-diff-summary, | ||
| ${d} .rte-version-diff-empty, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-pane-title, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-summary, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-empty { | ||
| color: #94a3b8; | ||
| } | ||
| ${d} .rte-version-diff-insert, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-insert { | ||
| background: rgba(22, 163, 74, 0.25); | ||
| color: #bbf7d0; | ||
| } | ||
| ${d} .rte-version-diff-delete, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-delete { | ||
| background: rgba(220, 38, 38, 0.25); | ||
| color: #fecaca; | ||
| } | ||
| :is(${d}) .rte-toolbar-item .rte-toolbar-button[data-command="openVersionDiff"] svg{ | ||
| fill: none; | ||
| } | ||
| `,document.head.appendChild(e)}async function ge(e,i,n){if(n!=null)return n;if(typeof i.getBaselineHtml=="function"){const o=O(e),f=await Promise.resolve(i.getBaselineHtml({editor:e,editorRoot:o}));if(typeof f=="string")return f}const r=w.get(e);if(typeof r=="string")return r;if(typeof i.baselineHtml=="string")return i.baselineHtml;const t=W(e);return w.set(e,t),t}function ye(e){e.querySelector('button:not([disabled]), select:not([disabled]), input:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])')?.focus()}function ke(e,i){if(e.key!=="Tab")return;const n=Array.from(i.querySelectorAll('button:not([disabled]), select:not([disabled]), input:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])')).filter(f=>!f.hasAttribute("disabled"));if(n.length===0)return;const r=n[0],t=n[n.length-1],o=document.activeElement;e.shiftKey&&o===r?(e.preventDefault(),t.focus()):!e.shiftKey&&o===t&&(e.preventDefault(),r.focus())}function te(){z&&(z(),z=null)}function X(e){!e||w.has(e)||w.set(e,W(e))}function xe(e){return{baselineHtml:e.baselineHtml,getBaselineHtml:e.getBaselineHtml,mode:e.mode||"word",ignoreWhitespace:e.ignoreWhitespace!==!1,maxTokens:Math.max(200,e.maxTokens??1200),maxMatrixSize:Math.max(5e4,e.maxMatrixSize??1e6),labels:le(e.labels)}}function re(e,i,n){te(),D=e,V.set(e,i);const r=document.createElement("div");r.className=l,Y(e)&&r.classList.add("rte-version-diff-theme-dark");const t=document.createElement("section");t.className="rte-version-diff-dialog",t.setAttribute("role","dialog"),t.setAttribute("aria-modal","true"),t.setAttribute("aria-labelledby","rte-version-diff-title");const o=i.labels;let f=n?.mode||i.mode,g=n?.ignoreWhitespace??i.ignoreWhitespace,c="inline";t.innerHTML=` | ||
| <header class="rte-version-diff-header"> | ||
| <h2 id="rte-version-diff-title" class="rte-version-diff-title">${u(o.title)}</h2> | ||
| <div class="rte-version-diff-controls"> | ||
| <label> | ||
| <span>${u(o.mode)}:</span> | ||
| <select class="rte-version-diff-select" aria-label="${u(o.mode)}"> | ||
| <option value="word">Word</option> | ||
| <option value="line">Line</option> | ||
| </select> | ||
| </label> | ||
| <label class="rte-version-diff-checkbox"> | ||
| <input type="checkbox" class="rte-version-diff-ignore-ws" ${g?"checked":""}> | ||
| ${u(o.ignoreWhitespace)} | ||
| </label> | ||
| <button type="button" class="rte-version-diff-btn rte-version-diff-set-baseline" aria-label="${u(o.setBaseline)}">${u(o.setBaseline)}</button> | ||
| <button type="button" class="rte-version-diff-btn" data-action="refresh" aria-label="${u(o.refresh)}">${u(o.refresh)}</button> | ||
| <button type="button" class="rte-version-diff-btn rte-version-diff-close-btn" data-action="close" aria-label="${u(o.close)}">✕</button> | ||
| </div> | ||
| </header> | ||
| <div class="rte-version-diff-tabs" role="tablist" aria-label="Diff views"> | ||
| <button type="button" role="tab" class="rte-version-diff-tab" data-tab="inline" aria-selected="true">${u(o.tabInline)}</button> | ||
| <button type="button" role="tab" class="rte-version-diff-tab" data-tab="side" aria-selected="false">${u(o.tabSideBySide)}</button> | ||
| </div> | ||
| <main class="rte-version-diff-body"> | ||
| <div class="rte-version-diff-summary" aria-live="polite"></div> | ||
| <section class="rte-version-diff-panel active" data-panel="inline" role="tabpanel"> | ||
| <div class="rte-version-diff-inline" aria-label="Inline diff result"></div> | ||
| </section> | ||
| <section class="rte-version-diff-panel" data-panel="side" role="tabpanel"> | ||
| <div class="rte-version-diff-side-grid"> | ||
| <div> | ||
| <h3 class="rte-version-diff-pane-title">${u(o.baseline)}</h3> | ||
| <div class="rte-version-diff-side-pane" data-side="baseline" aria-label="${u(o.baseline)}"></div> | ||
| </div> | ||
| <div> | ||
| <h3 class="rte-version-diff-pane-title">${u(o.current)}</h3> | ||
| <div class="rte-version-diff-side-pane" data-side="current" aria-label="${u(o.current)}"></div> | ||
| </div> | ||
| </div> | ||
| </section> | ||
| </main> | ||
| <footer class="rte-version-diff-footer"> | ||
| <small>Shortcut: Ctrl/Cmd + Alt + D (fallback: F8)</small> | ||
| <small>Esc: close</small> | ||
| </footer> | ||
| `,r.appendChild(t),document.body.appendChild(r);const b=t.querySelector(".rte-version-diff-select");b.value=f;const m=t.querySelector(".rte-version-diff-ignore-ws"),F=t.querySelector(".rte-version-diff-summary"),T=t.querySelector(".rte-version-diff-inline"),q=t.querySelector('[data-side="baseline"]'),A=t.querySelector('[data-side="current"]');let L=0;const P=()=>{const s=`<p class="rte-version-diff-empty">${u(o.loading)}</p>`;T.innerHTML=s,q.innerHTML=s,A.innerHTML=s,F.textContent=""},a=async s=>{L+=1;const v=L;r.classList.toggle("rte-version-diff-theme-dark",Y(e)),P();const x=e.innerHTML;let E="";try{E=await ge(e,i,s??n?.baselineHtml)}catch{E=w.get(e)??W(e)}if(v!==L||!r.isConnected)return;const ne=J(E),ie=J(x),oe=Q(ne,f,g),se=Q(ie,f,g),C=pe(oe,se,f,g,i.maxMatrixSize,i.maxTokens),_=he(C.segments,o);T.innerHTML=be(C.segments,o),q.innerHTML=_.baselineHtml,A.innerHTML=_.currentHtml;const G=[`+${C.insertedCount} inserted`,`-${C.deletedCount} deleted`,`${C.equalCount} unchanged`];C.usedFallback&&G.push(o.largeDocFallback),F.textContent=G.join(" | ")},h=s=>{c=s,t.querySelectorAll(".rte-version-diff-tab").forEach(v=>{const x=v.getAttribute("data-tab")===s;v.setAttribute("aria-selected",x?"true":"false"),v.tabIndex=x?0:-1}),t.querySelectorAll(".rte-version-diff-panel").forEach(v=>{v.classList.toggle("active",v.getAttribute("data-panel")===s)})},p=()=>{r.removeEventListener("keydown",I,!0),r.removeEventListener("click",B),document.removeEventListener("keydown",y,!0),r.parentNode&&r.parentNode.removeChild(r),z=null,e.focus({preventScroll:!0})},y=s=>{s.key==="Escape"&&(s.preventDefault(),s.stopPropagation(),p())},B=s=>{s.target===r&&p()},I=s=>{if(s.key==="Escape"){s.preventDefault(),p();return}if(ke(s,t),s.target&&s.target.classList.contains("rte-version-diff-tab")&&(s.key==="ArrowRight"||s.key==="ArrowLeft")){s.preventDefault();const v=c==="inline"?"side":"inline";h(v),t.querySelector(`.rte-version-diff-tab[data-tab="${v}"]`)?.focus()}};t.addEventListener("click",s=>{const v=s.target,x=v.getAttribute("data-action");if(x==="close"){p();return}if(x==="refresh"){a();return}const E=v.getAttribute("data-tab");(E==="inline"||E==="side")&&h(E)}),b.addEventListener("change",()=>{f=b.value==="line"?"line":"word",a()}),m.addEventListener("change",()=>{g=m.checked,a()}),t.querySelector(".rte-version-diff-set-baseline").addEventListener("click",()=>{w.set(e,e.innerHTML),a(e.innerHTML)}),r.addEventListener("keydown",I,!0),r.addEventListener("click",B),document.addEventListener("keydown",y,!0),z=p,ye(t),a()}function $e(e){R=e,!S&&(S=i=>{if(!ve(i))return;if(document.querySelector(`.${l}`)){i.preventDefault();return}if(!!i.target?.closest("input, textarea, select"))return;const t=N(void 0,!1);if(!t||t.getAttribute("contenteditable")==="false")return;i.preventDefault(),i.stopPropagation();const o=V.get(t)||R||e;re(t,o)},document.addEventListener("keydown",S,!0))}function Ee(){S&&(document.removeEventListener("keydown",S,!0),S=null,R=null)}function we(){M||(M=e=>{const n=e.target?.closest($);n&&(D=n,X(n))},document.addEventListener("focusin",M,!0)),H||(H=e=>{const r=e.target?.closest($);r&&r.getAttribute("contenteditable")!=="false"&&(D=r,X(r))},document.addEventListener("beforeinput",H,!0))}function Le(){M&&(document.removeEventListener("focusin",M,!0),M=null),H&&(document.removeEventListener("beforeinput",H,!0),H=null)}const Ce=(e={})=>{const i=xe(e);return me(),{name:"versionDiff",toolbar:[{id:"versionDiff",label:"Version Diff",command:"openVersionDiff",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><rect x="3.5" y="4.5" width="7" height="15" rx="1.5" stroke="currentColor" stroke-width="1.8"></rect><rect x="13.5" y="4.5" width="7" height="15" rx="1.5" stroke="currentColor" stroke-width="1.8"></rect><path d="M5.5 12h3" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"></path><path d="M15.5 12h3m-1.5-1.5v3" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"></path></svg>'}],commands:{openVersionDiff:(n,r)=>{const t=N(r);return t?(V.set(t,i),re(t,i,n),!0):!1},setVersionDiffBaseline:(n,r)=>{const t=N(r);if(!t)return!1;V.set(t,i);const o=typeof n=="string"?n:typeof n?.html=="string"?n.html:t.innerHTML;return w.set(t,o),!0}},keymap:{"Mod-Alt-d":"openVersionDiff","Mod-Alt-D":"openVersionDiff",F8:"openVersionDiff"},init:()=>{j+=1,$e(i),we()},destroy:()=>{j=Math.max(0,j-1),j===0&&(te(),Ee(),Le())}}};exports.VersionDiffPlugin=Ce; |
| const $ = ".rte-content, .editora-content", d = '[data-theme="dark"], .dark, .editora-theme-dark, .rte-theme-dark', l = "rte-version-diff-overlay", U = "rte-version-diff-styles", ae = { | ||
| title: "Version Diff", | ||
| baseline: "Baseline", | ||
| current: "Current", | ||
| noChanges: "No changes detected between baseline and current content.", | ||
| loading: "Preparing diff...", | ||
| tabInline: "Inline Diff", | ||
| tabSideBySide: "Side by Side", | ||
| refresh: "Refresh", | ||
| setBaseline: "Set Current as Baseline", | ||
| close: "Close", | ||
| mode: "Mode", | ||
| ignoreWhitespace: "Ignore whitespace", | ||
| largeDocFallback: "Large document fallback mode applied for performance." | ||
| }, w = /* @__PURE__ */ new WeakMap(), R = /* @__PURE__ */ new WeakMap(); | ||
| let j = 0, H = null, z = null, V = null, S = null, M = null, D = null; | ||
| function u(e) { | ||
| return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); | ||
| } | ||
| function le(e) { | ||
| return { | ||
| ...ae, | ||
| ...e || {} | ||
| }; | ||
| } | ||
| function N(e, i = !0) { | ||
| if (e?.contentElement instanceof HTMLElement) return e.contentElement; | ||
| if (e?.editorElement instanceof HTMLElement) { | ||
| const t = e.editorElement; | ||
| if (t.matches($)) return t; | ||
| const o = t.querySelector($); | ||
| if (o instanceof HTMLElement) return o; | ||
| } | ||
| const n = window.getSelection(); | ||
| if (n && n.rangeCount > 0) { | ||
| const t = n.getRangeAt(0).startContainer, f = (t.nodeType === Node.ELEMENT_NODE ? t : t.parentElement)?.closest($); | ||
| if (f) return f; | ||
| } | ||
| const r = document.activeElement; | ||
| if (r) { | ||
| if (r.matches($)) return r; | ||
| const t = r.closest($); | ||
| if (t) return t; | ||
| } | ||
| return D && D.isConnected ? D : i ? document.querySelector($) : null; | ||
| } | ||
| function O(e) { | ||
| return e.closest("[data-editora-editor], .rte-editor, .editora-editor, editora-editor") || e; | ||
| } | ||
| function P(e) { | ||
| if (!e) return !1; | ||
| const i = e.getAttribute("data-theme") || e.getAttribute("theme"); | ||
| if (i && i.toLowerCase() === "dark") return !0; | ||
| const n = e.classList; | ||
| return n.contains("dark") || n.contains("editora-theme-dark") || n.contains("rte-theme-dark"); | ||
| } | ||
| function Y(e) { | ||
| const i = O(e); | ||
| if (P(i)) return !0; | ||
| const n = i.closest("[data-theme], [theme], .dark, .editora-theme-dark, .rte-theme-dark"); | ||
| return !!(P(n) || P(document.documentElement) || P(document.body)); | ||
| } | ||
| function fe(e) { | ||
| const i = document.createElement("textarea"); | ||
| return i.innerHTML = e, i.value; | ||
| } | ||
| function W(e) { | ||
| const n = O(e).getAttribute("data-initial-content"); | ||
| return n ? fe(n) : e.innerHTML; | ||
| } | ||
| function Z(e) { | ||
| return e.replace(/\r\n?/g, ` | ||
| `); | ||
| } | ||
| function J(e) { | ||
| const i = document.createElement("div"), n = e.replace(/<br\s*\/?>/gi, ` | ||
| `).replace(/<\/(p|div|h1|h2|h3|h4|h5|h6|li|tr|blockquote|pre|section|article)>/gi, `$& | ||
| `); | ||
| i.innerHTML = n; | ||
| const r = i.textContent || ""; | ||
| return Z(r).replace(/\u00a0/g, " ").replace(/\n{3,}/g, ` | ||
| `).trim(); | ||
| } | ||
| function Q(e, i, n) { | ||
| let r = Z(e); | ||
| if (n && (r = r.replace(/[ \t]+/g, " ").replace(/\n{3,}/g, ` | ||
| `).trim()), !r) return []; | ||
| if (i === "line") | ||
| return r.split(` | ||
| `); | ||
| if (n) | ||
| return r.split(/\s+/).filter(Boolean); | ||
| const t = [], o = r.split(` | ||
| `); | ||
| return o.forEach((f, g) => { | ||
| const c = f.split(/[ \t]+/).filter(Boolean); | ||
| t.push(...c), g < o.length - 1 && t.push(` | ||
| `); | ||
| }), t; | ||
| } | ||
| function de(e, i, n) { | ||
| if (e.length === 0) return ""; | ||
| if (i === "line") return e.join(` | ||
| `); | ||
| if (n) return e.join(" "); | ||
| let r = ""; | ||
| for (let t = 0; t < e.length; t += 1) { | ||
| const o = e[t]; | ||
| if (o === ` | ||
| `) { | ||
| r = r.replace(/[ \t]+$/g, ""), r += ` | ||
| `; | ||
| continue; | ||
| } | ||
| r.length > 0 && !r.endsWith(` | ||
| `) && (r += " "), r += o; | ||
| } | ||
| return r; | ||
| } | ||
| function ce(e, i, n) { | ||
| const r = []; | ||
| return e.forEach((t) => { | ||
| const o = r[r.length - 1]; | ||
| if (o && o.type === t.type) { | ||
| o.tokens.push(t.token); | ||
| return; | ||
| } | ||
| r.push({ type: t.type, tokens: [t.token] }); | ||
| }), r.map((t) => ({ | ||
| type: t.type, | ||
| value: de(t.tokens, i, n), | ||
| count: t.tokens.length | ||
| })); | ||
| } | ||
| function ue(e, i) { | ||
| let n = 0; | ||
| for (; n < e.length && n < i.length && e[n] === i[n]; ) | ||
| n += 1; | ||
| let r = e.length - 1, t = i.length - 1; | ||
| for (; r >= n && t >= n && e[r] === i[t]; ) | ||
| r -= 1, t -= 1; | ||
| const o = e.slice(0, n), f = r < e.length - 1 ? e.slice(r + 1) : [], g = n <= r ? e.slice(n, r + 1) : [], c = n <= t ? i.slice(n, t + 1) : []; | ||
| return { prefix: o, suffix: f, aMiddle: g, bMiddle: c }; | ||
| } | ||
| function pe(e, i, n, r, t, o) { | ||
| if (e.length === 0 && i.length === 0) | ||
| return { segments: [], insertedCount: 0, deletedCount: 0, equalCount: 0, usedFallback: !1 }; | ||
| const { prefix: f, suffix: g, aMiddle: c, bMiddle: b } = ue(e, i); | ||
| let v = []; | ||
| f.forEach((a) => v.push({ type: "equal", token: a })); | ||
| const F = c.length * b.length, T = c.length > o || b.length > o || F > t; | ||
| if (T) | ||
| c.forEach((a) => v.push({ type: "delete", token: a })), b.forEach((a) => v.push({ type: "insert", token: a })); | ||
| else { | ||
| const a = Array.from({ length: c.length + 1 }, () => new Uint32Array(b.length + 1)); | ||
| for (let y = c.length - 1; y >= 0; y -= 1) { | ||
| const B = a[y], I = a[y + 1]; | ||
| for (let x = b.length - 1; x >= 0; x -= 1) | ||
| B[x] = c[y] === b[x] ? I[x + 1] + 1 : Math.max(I[x], B[x + 1]); | ||
| } | ||
| let h = 0, p = 0; | ||
| for (; h < c.length && p < b.length; ) | ||
| c[h] === b[p] ? (v.push({ type: "equal", token: c[h] }), h += 1, p += 1) : a[h + 1][p] >= a[h][p + 1] ? (v.push({ type: "delete", token: c[h] }), h += 1) : (v.push({ type: "insert", token: b[p] }), p += 1); | ||
| for (; h < c.length; ) | ||
| v.push({ type: "delete", token: c[h] }), h += 1; | ||
| for (; p < b.length; ) | ||
| v.push({ type: "insert", token: b[p] }), p += 1; | ||
| } | ||
| g.forEach((a) => v.push({ type: "equal", token: a })); | ||
| const q = ce(v, n, r); | ||
| let A = 0, L = 0, K = 0; | ||
| return q.forEach((a) => { | ||
| a.type === "insert" && (A += a.count), a.type === "delete" && (L += a.count), a.type === "equal" && (K += a.count); | ||
| }), { | ||
| segments: q, | ||
| insertedCount: A, | ||
| deletedCount: L, | ||
| equalCount: K, | ||
| usedFallback: T | ||
| }; | ||
| } | ||
| function ee(e) { | ||
| return u(e.value).replace(/\n/g, ` | ||
| `); | ||
| } | ||
| function be(e, i) { | ||
| return e.length === 0 ? `<p class="rte-version-diff-empty">${u(i.noChanges)}</p>` : e.map((n) => `<span class="${n.type === "equal" ? "rte-version-diff-equal" : n.type === "insert" ? "rte-version-diff-insert" : "rte-version-diff-delete"}">${ee(n)}</span>`).join(""); | ||
| } | ||
| function he(e, i) { | ||
| if (e.length === 0) { | ||
| const t = `<p class="rte-version-diff-empty">${u(i.noChanges)}</p>`; | ||
| return { baselineHtml: t, currentHtml: t }; | ||
| } | ||
| const n = [], r = []; | ||
| return e.forEach((t) => { | ||
| const o = ee(t); | ||
| if (t.type === "equal") { | ||
| n.push(`<span class="rte-version-diff-equal">${o}</span>`), r.push(`<span class="rte-version-diff-equal">${o}</span>`); | ||
| return; | ||
| } | ||
| if (t.type === "delete") { | ||
| n.push(`<span class="rte-version-diff-delete">${o}</span>`); | ||
| return; | ||
| } | ||
| r.push(`<span class="rte-version-diff-insert">${o}</span>`); | ||
| }), { | ||
| baselineHtml: n.join(""), | ||
| currentHtml: r.join("") | ||
| }; | ||
| } | ||
| function me(e) { | ||
| const i = e.metaKey || e.ctrlKey, r = (typeof e.key == "string" ? e.key : "").toLowerCase(), t = typeof e.code == "string" ? e.code.toLowerCase() : "", o = i && e.altKey && !e.shiftKey && (r === "d" || t === "keyd"), f = !e.metaKey && !e.ctrlKey && !e.altKey && !e.shiftKey && (r === "f8" || t === "f8"); | ||
| return o || f; | ||
| } | ||
| function ve() { | ||
| if (typeof document > "u" || document.getElementById(U)) return; | ||
| const e = document.createElement("style"); | ||
| e.id = U, e.textContent = ` | ||
| .${l} { | ||
| position: fixed; | ||
| inset: 0; | ||
| background: rgba(15, 23, 42, 0.55); | ||
| z-index: 2147483646; | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| padding: 20px; | ||
| } | ||
| .rte-version-diff-dialog { | ||
| width: min(980px, 96vw); | ||
| max-height: min(90vh, 860px); | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| border: 1px solid #d7dee8; | ||
| border-radius: 8px; | ||
| display: flex; | ||
| flex-direction: column; | ||
| box-shadow: 0 24px 48px rgba(15, 23, 42, 0.3); | ||
| overflow: hidden; | ||
| } | ||
| .rte-version-diff-header, | ||
| .rte-version-diff-footer { | ||
| padding: 12px 14px; | ||
| border-bottom: 1px solid #e2e8f0; | ||
| background: #f8fafc; | ||
| display: flex; | ||
| align-items: center; | ||
| gap: 10px; | ||
| flex-wrap: wrap; | ||
| } | ||
| .rte-version-diff-footer { | ||
| border-top: 1px solid #e2e8f0; | ||
| border-bottom: none; | ||
| justify-content: space-between; | ||
| } | ||
| .rte-version-diff-title { | ||
| margin: 0; | ||
| font-size: 16px; | ||
| font-weight: 700; | ||
| flex: 1; | ||
| } | ||
| .rte-version-diff-controls { | ||
| display: flex; | ||
| align-items: center; | ||
| gap: 10px; | ||
| flex-wrap: wrap; | ||
| } | ||
| .rte-version-diff-select, | ||
| .rte-version-diff-btn { | ||
| border: 1px solid #cbd5e1; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| border-radius: 6px; | ||
| min-height: 34px; | ||
| padding: 6px 10px; | ||
| font-size: 13px; | ||
| cursor: pointer; | ||
| } | ||
| .rte-version-diff-btn:hover, | ||
| .rte-version-diff-btn:focus-visible, | ||
| .rte-version-diff-select:focus-visible { | ||
| outline: none; | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| } | ||
| .rte-version-diff-btn-primary { | ||
| background: #2563eb; | ||
| border-color: #2563eb; | ||
| color: #ffffff; | ||
| } | ||
| .rte-version-diff-btn-primary:hover { | ||
| background: #1d4ed8; | ||
| } | ||
| .rte-version-diff-close-btn { | ||
| border: 1px solid #cbd5e1; | ||
| border-radius: 6px; | ||
| min-height: 34px; | ||
| min-width: 34px; | ||
| width: 34px; | ||
| height: 34px; | ||
| padding: 0; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| font-weight: 600; | ||
| } | ||
| .rte-version-diff-close-btn:hover, | ||
| .rte-version-diff-close-btn:focus-visible { | ||
| border-color: #3b82f6; | ||
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); | ||
| background: #ffffff; | ||
| outline: none; | ||
| } | ||
| .rte-version-diff-tabs { | ||
| display: flex; | ||
| gap: 6px; | ||
| border-bottom: 1px solid #e2e8f0; | ||
| background: #f8fafc; | ||
| padding: 8px 14px; | ||
| } | ||
| .rte-version-diff-tab { | ||
| border: 1px solid #cbd5e1; | ||
| background: #ffffff; | ||
| color: #0f172a; | ||
| border-radius: 6px; | ||
| min-height: 32px; | ||
| padding: 4px 10px; | ||
| font-size: 13px; | ||
| cursor: pointer; | ||
| } | ||
| .rte-version-diff-tab[aria-selected="true"] { | ||
| background: #dbeafe; | ||
| border-color: #60a5fa; | ||
| color: #1e3a8a; | ||
| } | ||
| .rte-version-diff-body { | ||
| flex: 1; | ||
| overflow: auto; | ||
| padding: 10px 14px 14px; | ||
| background: #ffffff; | ||
| } | ||
| .rte-version-diff-summary { | ||
| font-size: 12px; | ||
| color: #475569; | ||
| margin-bottom: 10px; | ||
| display: flex; | ||
| gap: 14px; | ||
| flex-wrap: wrap; | ||
| } | ||
| .rte-version-diff-panel { | ||
| display: none; | ||
| } | ||
| .rte-version-diff-panel.active { | ||
| display: block; | ||
| } | ||
| .rte-version-diff-inline, | ||
| .rte-version-diff-side-pane { | ||
| border: 1px solid #dbe3ec; | ||
| border-radius: 6px; | ||
| padding: 10px; | ||
| min-height: 140px; | ||
| max-height: 50vh; | ||
| overflow: auto; | ||
| white-space: pre-wrap; | ||
| word-break: break-word; | ||
| font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; | ||
| font-size: 12px; | ||
| line-height: 1.5; | ||
| background: #ffffff; | ||
| } | ||
| .rte-version-diff-side-grid { | ||
| display: grid; | ||
| grid-template-columns: 1fr 1fr; | ||
| gap: 10px; | ||
| } | ||
| .rte-version-diff-pane-title { | ||
| margin: 0 0 6px; | ||
| font-size: 12px; | ||
| font-weight: 700; | ||
| color: #334155; | ||
| } | ||
| .rte-version-diff-equal { color: inherit; } | ||
| .rte-version-diff-insert { | ||
| background: rgba(22, 163, 74, 0.18); | ||
| color: #14532d; | ||
| border-radius: 2px; | ||
| } | ||
| .rte-version-diff-delete { | ||
| background: rgba(220, 38, 38, 0.18); | ||
| color: #7f1d1d; | ||
| text-decoration: line-through; | ||
| border-radius: 2px; | ||
| } | ||
| .rte-version-diff-empty { | ||
| margin: 0; | ||
| color: #64748b; | ||
| font-size: 13px; | ||
| } | ||
| ${d} .rte-version-diff-dialog, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-dialog { | ||
| background: #1f2937; | ||
| color: #e5e7eb; | ||
| border-color: #334155; | ||
| } | ||
| ${d} .rte-version-diff-header, | ||
| ${d} .rte-version-diff-footer, | ||
| ${d} .rte-version-diff-tabs, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-header, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-footer, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-tabs { | ||
| background: #111827; | ||
| border-color: #334155; | ||
| } | ||
| ${d} .rte-version-diff-body, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-body { | ||
| background: #1f2937; | ||
| } | ||
| ${d} .rte-version-diff-select, | ||
| ${d} .rte-version-diff-btn, | ||
| ${d} .rte-version-diff-tab, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-select, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-btn, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-tab { | ||
| background: #0f172a; | ||
| color: #e5e7eb; | ||
| border-color: #475569; | ||
| } | ||
| ${d} .rte-version-diff-close-btn, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-close-btn { | ||
| background: #0f172a; | ||
| border-color: #475569; | ||
| color: #e2e8f0; | ||
| } | ||
| ${d} .rte-version-diff-close-btn:hover, | ||
| ${d} .rte-version-diff-close-btn:focus-visible, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-close-btn:hover, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-close-btn:focus-visible { | ||
| border-color: #60a5fa; | ||
| box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.24); | ||
| outline: none; | ||
| } | ||
| ${d} .rte-version-diff-tab[aria-selected="true"], | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-tab[aria-selected="true"] { | ||
| background: #1e3a8a; | ||
| border-color: #3b82f6; | ||
| color: #dbeafe; | ||
| } | ||
| ${d} .rte-version-diff-inline, | ||
| ${d} .rte-version-diff-side-pane, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-inline, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-side-pane { | ||
| background: #0f172a; | ||
| border-color: #334155; | ||
| color: #e5e7eb; | ||
| } | ||
| ${d} .rte-version-diff-pane-title, | ||
| ${d} .rte-version-diff-summary, | ||
| ${d} .rte-version-diff-empty, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-pane-title, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-summary, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-empty { | ||
| color: #94a3b8; | ||
| } | ||
| ${d} .rte-version-diff-insert, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-insert { | ||
| background: rgba(22, 163, 74, 0.25); | ||
| color: #bbf7d0; | ||
| } | ||
| ${d} .rte-version-diff-delete, | ||
| .${l}.rte-version-diff-theme-dark .rte-version-diff-delete { | ||
| background: rgba(220, 38, 38, 0.25); | ||
| color: #fecaca; | ||
| } | ||
| :is(${d}) .rte-toolbar-item .rte-toolbar-button[data-command="openVersionDiff"] svg{ | ||
| fill: none; | ||
| } | ||
| `, document.head.appendChild(e); | ||
| } | ||
| async function ge(e, i, n) { | ||
| if (n != null) return n; | ||
| if (typeof i.getBaselineHtml == "function") { | ||
| const o = O(e), f = await Promise.resolve(i.getBaselineHtml({ editor: e, editorRoot: o })); | ||
| if (typeof f == "string") return f; | ||
| } | ||
| const r = w.get(e); | ||
| if (typeof r == "string") return r; | ||
| if (typeof i.baselineHtml == "string") return i.baselineHtml; | ||
| const t = W(e); | ||
| return w.set(e, t), t; | ||
| } | ||
| function ye(e) { | ||
| e.querySelector( | ||
| 'button:not([disabled]), select:not([disabled]), input:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])' | ||
| )?.focus(); | ||
| } | ||
| function xe(e, i) { | ||
| if (e.key !== "Tab") return; | ||
| const n = Array.from(i.querySelectorAll( | ||
| 'button:not([disabled]), select:not([disabled]), input:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])' | ||
| )).filter((f) => !f.hasAttribute("disabled")); | ||
| if (n.length === 0) return; | ||
| const r = n[0], t = n[n.length - 1], o = document.activeElement; | ||
| e.shiftKey && o === r ? (e.preventDefault(), t.focus()) : !e.shiftKey && o === t && (e.preventDefault(), r.focus()); | ||
| } | ||
| function te() { | ||
| z && (z(), z = null); | ||
| } | ||
| function X(e) { | ||
| !e || w.has(e) || w.set(e, W(e)); | ||
| } | ||
| function ke(e) { | ||
| return { | ||
| baselineHtml: e.baselineHtml, | ||
| getBaselineHtml: e.getBaselineHtml, | ||
| mode: e.mode || "word", | ||
| ignoreWhitespace: e.ignoreWhitespace !== !1, | ||
| maxTokens: Math.max(200, e.maxTokens ?? 1200), | ||
| maxMatrixSize: Math.max(5e4, e.maxMatrixSize ?? 1e6), | ||
| labels: le(e.labels) | ||
| }; | ||
| } | ||
| function re(e, i, n) { | ||
| te(), D = e, R.set(e, i); | ||
| const r = document.createElement("div"); | ||
| r.className = l, Y(e) && r.classList.add("rte-version-diff-theme-dark"); | ||
| const t = document.createElement("section"); | ||
| t.className = "rte-version-diff-dialog", t.setAttribute("role", "dialog"), t.setAttribute("aria-modal", "true"), t.setAttribute("aria-labelledby", "rte-version-diff-title"); | ||
| const o = i.labels; | ||
| let f = n?.mode || i.mode, g = n?.ignoreWhitespace ?? i.ignoreWhitespace, c = "inline"; | ||
| t.innerHTML = ` | ||
| <header class="rte-version-diff-header"> | ||
| <h2 id="rte-version-diff-title" class="rte-version-diff-title">${u(o.title)}</h2> | ||
| <div class="rte-version-diff-controls"> | ||
| <label> | ||
| <span>${u(o.mode)}:</span> | ||
| <select class="rte-version-diff-select" aria-label="${u(o.mode)}"> | ||
| <option value="word">Word</option> | ||
| <option value="line">Line</option> | ||
| </select> | ||
| </label> | ||
| <label class="rte-version-diff-checkbox"> | ||
| <input type="checkbox" class="rte-version-diff-ignore-ws" ${g ? "checked" : ""}> | ||
| ${u(o.ignoreWhitespace)} | ||
| </label> | ||
| <button type="button" class="rte-version-diff-btn rte-version-diff-set-baseline" aria-label="${u(o.setBaseline)}">${u(o.setBaseline)}</button> | ||
| <button type="button" class="rte-version-diff-btn" data-action="refresh" aria-label="${u(o.refresh)}">${u(o.refresh)}</button> | ||
| <button type="button" class="rte-version-diff-btn rte-version-diff-close-btn" data-action="close" aria-label="${u(o.close)}">✕</button> | ||
| </div> | ||
| </header> | ||
| <div class="rte-version-diff-tabs" role="tablist" aria-label="Diff views"> | ||
| <button type="button" role="tab" class="rte-version-diff-tab" data-tab="inline" aria-selected="true">${u(o.tabInline)}</button> | ||
| <button type="button" role="tab" class="rte-version-diff-tab" data-tab="side" aria-selected="false">${u(o.tabSideBySide)}</button> | ||
| </div> | ||
| <main class="rte-version-diff-body"> | ||
| <div class="rte-version-diff-summary" aria-live="polite"></div> | ||
| <section class="rte-version-diff-panel active" data-panel="inline" role="tabpanel"> | ||
| <div class="rte-version-diff-inline" aria-label="Inline diff result"></div> | ||
| </section> | ||
| <section class="rte-version-diff-panel" data-panel="side" role="tabpanel"> | ||
| <div class="rte-version-diff-side-grid"> | ||
| <div> | ||
| <h3 class="rte-version-diff-pane-title">${u(o.baseline)}</h3> | ||
| <div class="rte-version-diff-side-pane" data-side="baseline" aria-label="${u(o.baseline)}"></div> | ||
| </div> | ||
| <div> | ||
| <h3 class="rte-version-diff-pane-title">${u(o.current)}</h3> | ||
| <div class="rte-version-diff-side-pane" data-side="current" aria-label="${u(o.current)}"></div> | ||
| </div> | ||
| </div> | ||
| </section> | ||
| </main> | ||
| <footer class="rte-version-diff-footer"> | ||
| <small>Shortcut: Ctrl/Cmd + Alt + D (fallback: F8)</small> | ||
| <small>Esc: close</small> | ||
| </footer> | ||
| `, r.appendChild(t), document.body.appendChild(r); | ||
| const b = t.querySelector(".rte-version-diff-select"); | ||
| b.value = f; | ||
| const v = t.querySelector(".rte-version-diff-ignore-ws"), F = t.querySelector(".rte-version-diff-summary"), T = t.querySelector(".rte-version-diff-inline"), q = t.querySelector('[data-side="baseline"]'), A = t.querySelector('[data-side="current"]'); | ||
| let L = 0; | ||
| const K = () => { | ||
| const s = `<p class="rte-version-diff-empty">${u(o.loading)}</p>`; | ||
| T.innerHTML = s, q.innerHTML = s, A.innerHTML = s, F.textContent = ""; | ||
| }, a = async (s) => { | ||
| L += 1; | ||
| const m = L; | ||
| r.classList.toggle("rte-version-diff-theme-dark", Y(e)), K(); | ||
| const k = e.innerHTML; | ||
| let E = ""; | ||
| try { | ||
| E = await ge(e, i, s ?? n?.baselineHtml); | ||
| } catch { | ||
| E = w.get(e) ?? W(e); | ||
| } | ||
| if (m !== L || !r.isConnected) return; | ||
| const ne = J(E), ie = J(k), oe = Q(ne, f, g), se = Q(ie, f, g), C = pe( | ||
| oe, | ||
| se, | ||
| f, | ||
| g, | ||
| i.maxMatrixSize, | ||
| i.maxTokens | ||
| ), _ = he(C.segments, o); | ||
| T.innerHTML = be(C.segments, o), q.innerHTML = _.baselineHtml, A.innerHTML = _.currentHtml; | ||
| const G = [ | ||
| `+${C.insertedCount} inserted`, | ||
| `-${C.deletedCount} deleted`, | ||
| `${C.equalCount} unchanged` | ||
| ]; | ||
| C.usedFallback && G.push(o.largeDocFallback), F.textContent = G.join(" | "); | ||
| }, h = (s) => { | ||
| c = s, t.querySelectorAll(".rte-version-diff-tab").forEach((m) => { | ||
| const k = m.getAttribute("data-tab") === s; | ||
| m.setAttribute("aria-selected", k ? "true" : "false"), m.tabIndex = k ? 0 : -1; | ||
| }), t.querySelectorAll(".rte-version-diff-panel").forEach((m) => { | ||
| m.classList.toggle("active", m.getAttribute("data-panel") === s); | ||
| }); | ||
| }, p = () => { | ||
| r.removeEventListener("keydown", I, !0), r.removeEventListener("click", B), document.removeEventListener("keydown", y, !0), r.parentNode && r.parentNode.removeChild(r), z = null, e.focus({ preventScroll: !0 }); | ||
| }, y = (s) => { | ||
| s.key === "Escape" && (s.preventDefault(), s.stopPropagation(), p()); | ||
| }, B = (s) => { | ||
| s.target === r && p(); | ||
| }, I = (s) => { | ||
| if (s.key === "Escape") { | ||
| s.preventDefault(), p(); | ||
| return; | ||
| } | ||
| if (xe(s, t), s.target && s.target.classList.contains("rte-version-diff-tab") && (s.key === "ArrowRight" || s.key === "ArrowLeft")) { | ||
| s.preventDefault(); | ||
| const m = c === "inline" ? "side" : "inline"; | ||
| h(m), t.querySelector(`.rte-version-diff-tab[data-tab="${m}"]`)?.focus(); | ||
| } | ||
| }; | ||
| t.addEventListener("click", (s) => { | ||
| const m = s.target, k = m.getAttribute("data-action"); | ||
| if (k === "close") { | ||
| p(); | ||
| return; | ||
| } | ||
| if (k === "refresh") { | ||
| a(); | ||
| return; | ||
| } | ||
| const E = m.getAttribute("data-tab"); | ||
| (E === "inline" || E === "side") && h(E); | ||
| }), b.addEventListener("change", () => { | ||
| f = b.value === "line" ? "line" : "word", a(); | ||
| }), v.addEventListener("change", () => { | ||
| g = v.checked, a(); | ||
| }), t.querySelector(".rte-version-diff-set-baseline").addEventListener("click", () => { | ||
| w.set(e, e.innerHTML), a(e.innerHTML); | ||
| }), r.addEventListener("keydown", I, !0), r.addEventListener("click", B), document.addEventListener("keydown", y, !0), z = p, ye(t), a(); | ||
| } | ||
| function $e(e) { | ||
| V = e, !H && (H = (i) => { | ||
| if (!me(i)) return; | ||
| if (document.querySelector(`.${l}`)) { | ||
| i.preventDefault(); | ||
| return; | ||
| } | ||
| if (!!i.target?.closest("input, textarea, select")) return; | ||
| const t = N(void 0, !1); | ||
| if (!t || t.getAttribute("contenteditable") === "false") return; | ||
| i.preventDefault(), i.stopPropagation(); | ||
| const o = R.get(t) || V || e; | ||
| re(t, o); | ||
| }, document.addEventListener("keydown", H, !0)); | ||
| } | ||
| function Ee() { | ||
| H && (document.removeEventListener("keydown", H, !0), H = null, V = null); | ||
| } | ||
| function we() { | ||
| S || (S = (e) => { | ||
| const n = e.target?.closest($); | ||
| n && (D = n, X(n)); | ||
| }, document.addEventListener("focusin", S, !0)), M || (M = (e) => { | ||
| const r = e.target?.closest($); | ||
| r && r.getAttribute("contenteditable") !== "false" && (D = r, X(r)); | ||
| }, document.addEventListener("beforeinput", M, !0)); | ||
| } | ||
| function Le() { | ||
| S && (document.removeEventListener("focusin", S, !0), S = null), M && (document.removeEventListener("beforeinput", M, !0), M = null); | ||
| } | ||
| const Ce = (e = {}) => { | ||
| const i = ke(e); | ||
| return ve(), { | ||
| name: "versionDiff", | ||
| toolbar: [ | ||
| { | ||
| id: "versionDiff", | ||
| label: "Version Diff", | ||
| command: "openVersionDiff", | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true"><rect x="3.5" y="4.5" width="7" height="15" rx="1.5" stroke="currentColor" stroke-width="1.8"></rect><rect x="13.5" y="4.5" width="7" height="15" rx="1.5" stroke="currentColor" stroke-width="1.8"></rect><path d="M5.5 12h3" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"></path><path d="M15.5 12h3m-1.5-1.5v3" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"></path></svg>' | ||
| } | ||
| ], | ||
| commands: { | ||
| openVersionDiff: (n, r) => { | ||
| const t = N(r); | ||
| return t ? (R.set(t, i), re(t, i, n), !0) : !1; | ||
| }, | ||
| setVersionDiffBaseline: (n, r) => { | ||
| const t = N(r); | ||
| if (!t) return !1; | ||
| R.set(t, i); | ||
| const o = typeof n == "string" ? n : typeof n?.html == "string" ? n.html : t.innerHTML; | ||
| return w.set(t, o), !0; | ||
| } | ||
| }, | ||
| keymap: { | ||
| "Mod-Alt-d": "openVersionDiff", | ||
| "Mod-Alt-D": "openVersionDiff", | ||
| F8: "openVersionDiff" | ||
| }, | ||
| init: () => { | ||
| j += 1, $e(i), we(); | ||
| }, | ||
| destroy: () => { | ||
| j = Math.max(0, j - 1), j === 0 && (te(), Ee(), Le()); | ||
| } | ||
| }; | ||
| }; | ||
| export { | ||
| Ce as VersionDiffPlugin | ||
| }; |
+21
| MIT License | ||
| Copyright (c) 2026 Ajay Kumar | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. |
@@ -1,1 +0,1 @@ | ||
| "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const t=require("./heading.cjs.js"),r=require("./bold.cjs.js"),g=require("./italic.cjs.js"),u=require("./underline.cjs.js"),o=require("./strikethrough.cjs.js"),a=require("./list.cjs.js"),s=require("./checklist.cjs.js"),c=require("./history.cjs.js"),P=require("./link.cjs.js"),m=require("./blockquote.cjs.js"),d=require("./clear-formatting.cjs.js"),C=require("./code.cjs.js"),q=require("./table.cjs.js"),p=require("./font-size.cjs.js"),h=require("./font-family.cjs.js"),T=require("./text-alignment.cjs.js"),M=require("./text-color.cjs.js"),k=require("./background-color.cjs.js"),f=require("./line-height.cjs.js"),b=require("./indent.cjs.js"),A=require("./direction.cjs.js"),F=require("./capitalization.cjs.js"),S=require("./math.cjs.js"),y=require("./special-characters.cjs.js"),E=require("./emojis.cjs.js"),D=require("./embed-iframe.cjs.js"),B=require("./anchor.cjs.js"),n=require("./media-manager.cjs.js"),l=require("./index-tqLTHcO6.js"),H=require("./preview.cjs.js"),I=require("./fullscreen.cjs.js"),z=require("./print.cjs.js"),L=require("./page-break.cjs.js"),v=require("./footnote.cjs.js"),x=require("./code-sample.cjs.js"),G=require("./merge-tag.cjs.js"),e=require("./template.cjs.js"),j=require("./comments.cjs.js"),U=require("./spell-check.cjs.js"),_=require("./a11y-checker.cjs.js"),i=require("./shared-config.cjs.js");exports.HeadingPlugin=t.HeadingPlugin;exports.BoldPlugin=r.BoldPlugin;exports.ItalicPlugin=g.ItalicPlugin;exports.UnderlinePlugin=u.UnderlinePlugin;exports.StrikethroughPlugin=o.StrikethroughPlugin;exports.ListPlugin=a.ListPlugin;exports.ChecklistPlugin=s.ChecklistPlugin;exports.HistoryPlugin=c.HistoryPlugin;exports.LinkPlugin=P.LinkPlugin;exports.BlockquotePlugin=m.BlockquotePlugin;exports.ClearFormattingPlugin=d.ClearFormattingPlugin;exports.CodePlugin=C.CodePlugin;exports.TablePlugin=q.TablePlugin;exports.FontSizePlugin=p.FontSizePlugin;exports.FontFamilyPlugin=h.FontFamilyPlugin;exports.TextAlignmentPlugin=T.TextAlignmentPlugin;exports.TextColorPlugin=M.TextColorPlugin;exports.BackgroundColorPlugin=k.BackgroundColorPlugin;exports.LineHeightPlugin=f.LineHeightPlugin;exports.IndentPlugin=b.IndentPlugin;exports.DirectionPlugin=A.DirectionPlugin;exports.CapitalizationPlugin=F.CapitalizationPlugin;exports.MathPlugin=S.MathPlugin;exports.SpecialCharactersPlugin=y.SpecialCharactersPlugin;exports.EmojisPlugin=E.EmojisPlugin;exports.EmbedIframePlugin=D.EmbedIframePlugin;exports.AnchorPlugin=B.AnchorPlugin;exports.MediaManagerPlugin=n.MediaManagerPlugin;exports.getMediaManagerConfig=n.getMediaManagerConfig;exports.setMediaManagerConfig=n.setMediaManagerConfig;exports.DocumentManagerPlugin=l.DocumentManagerPlugin;exports.getDocumentManagerConfig=l.getDocumentManagerConfig;exports.setDocumentManagerConfig=l.setDocumentManagerConfig;exports.PreviewPlugin=H.PreviewPlugin;exports.FullscreenPlugin=I.FullscreenPlugin;exports.PrintPlugin=z.PrintPlugin;exports.PageBreakPlugin=L.PageBreakPlugin;exports.FootnotePlugin=v.FootnotePlugin;exports.CodeSamplePlugin=x.CodeSamplePlugin;exports.MergeTagPlugin=G.MergeTagPlugin;exports.PREDEFINED_TEMPLATES=e.PREDEFINED_TEMPLATES;exports.TemplatePlugin=e.TemplatePlugin;exports.addCustomTemplate=e.addCustomTemplate;exports.getAllTemplates=e.getAllTemplates;exports.getTemplateCategories=e.getTemplateCategories;exports.getTemplatesByCategory=e.getTemplatesByCategory;exports.sanitizeTemplate=e.sanitizeTemplate;exports.searchTemplates=e.searchTemplates;exports.validateTemplate=e.validateTemplate;exports.CommentsPlugin=j.CommentsPlugin;exports.SpellCheckPlugin=U.SpellCheckPlugin;exports.A11yCheckerPlugin=_.A11yCheckerPlugin;exports.buildApiUrl=i.buildApiUrl;exports.getGlobalApiConfig=i.getGlobalApiConfig;exports.getGlobalApiHeaders=i.getGlobalApiHeaders;exports.setGlobalApiConfig=i.setGlobalApiConfig; | ||
| "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const l=require("./heading.cjs.js"),r=require("./bold.cjs.js"),o=require("./italic.cjs.js"),u=require("./underline.cjs.js"),g=require("./strikethrough.cjs.js"),a=require("./list.cjs.js"),s=require("./checklist.cjs.js"),P=require("./history.cjs.js"),c=require("./link.cjs.js"),m=require("./blockquote.cjs.js"),d=require("./clear-formatting.cjs.js"),C=require("./code.cjs.js"),q=require("./table.cjs.js"),p=require("./font-size.cjs.js"),h=require("./font-family.cjs.js"),k=require("./text-alignment.cjs.js"),T=require("./text-color.cjs.js"),f=require("./background-color.cjs.js"),M=require("./line-height.cjs.js"),b=require("./indent.cjs.js"),S=require("./direction.cjs.js"),A=require("./capitalization.cjs.js"),D=require("./math.cjs.js"),y=require("./special-characters.cjs.js"),B=require("./emojis.cjs.js"),F=require("./embed-iframe.cjs.js"),E=require("./anchor.cjs.js"),I=require("./mentions.cjs.js"),v=require("./track-changes.cjs.js"),L=require("./version-diff.cjs.js"),w=require("./conditional-content.cjs.js"),H=require("./data-binding.cjs.js"),z=require("./content-rules.cjs.js"),R=require("./citations.cjs.js"),x=require("./approval-workflow.cjs.js"),G=require("./pii-redaction.cjs.js"),W=require("./smart-paste.cjs.js"),j=require("./blocks-library.cjs.js"),U=require("./doc-schema.cjs.js"),_=require("./translation-workflow.cjs.js"),N=require("./slash-commands.cjs.js"),n=require("./media-manager.cjs.js"),t=require("./index-tqLTHcO6.js"),V=require("./preview.cjs.js"),O=require("./fullscreen.cjs.js"),J=require("./print.cjs.js"),K=require("./page-break.cjs.js"),Q=require("./footnote.cjs.js"),X=require("./code-sample.cjs.js"),Y=require("./merge-tag.cjs.js"),e=require("./template.cjs.js"),Z=require("./comments.cjs.js"),$=require("./spell-check.cjs.js"),ee=require("./a11y-checker.cjs.js"),i=require("./shared-config.cjs.js");exports.HeadingPlugin=l.HeadingPlugin;exports.BoldPlugin=r.BoldPlugin;exports.ItalicPlugin=o.ItalicPlugin;exports.UnderlinePlugin=u.UnderlinePlugin;exports.StrikethroughPlugin=g.StrikethroughPlugin;exports.ListPlugin=a.ListPlugin;exports.ChecklistPlugin=s.ChecklistPlugin;exports.HistoryPlugin=P.HistoryPlugin;exports.LinkPlugin=c.LinkPlugin;exports.BlockquotePlugin=m.BlockquotePlugin;exports.ClearFormattingPlugin=d.ClearFormattingPlugin;exports.CodePlugin=C.CodePlugin;exports.TablePlugin=q.TablePlugin;exports.FontSizePlugin=p.FontSizePlugin;exports.FontFamilyPlugin=h.FontFamilyPlugin;exports.TextAlignmentPlugin=k.TextAlignmentPlugin;exports.TextColorPlugin=T.TextColorPlugin;exports.BackgroundColorPlugin=f.BackgroundColorPlugin;exports.LineHeightPlugin=M.LineHeightPlugin;exports.IndentPlugin=b.IndentPlugin;exports.DirectionPlugin=S.DirectionPlugin;exports.CapitalizationPlugin=A.CapitalizationPlugin;exports.MathPlugin=D.MathPlugin;exports.SpecialCharactersPlugin=y.SpecialCharactersPlugin;exports.EmojisPlugin=B.EmojisPlugin;exports.EmbedIframePlugin=F.EmbedIframePlugin;exports.AnchorPlugin=E.AnchorPlugin;exports.MentionPlugin=I.MentionPlugin;exports.TrackChangesPlugin=v.TrackChangesPlugin;exports.VersionDiffPlugin=L.VersionDiffPlugin;exports.ConditionalContentPlugin=w.ConditionalContentPlugin;exports.DataBindingPlugin=H.DataBindingPlugin;exports.ContentRulesPlugin=z.ContentRulesPlugin;exports.CitationsPlugin=R.CitationsPlugin;exports.ApprovalWorkflowPlugin=x.ApprovalWorkflowPlugin;exports.PIIRedactionPlugin=G.PIIRedactionPlugin;exports.SmartPastePlugin=W.SmartPastePlugin;exports.BlocksLibraryPlugin=j.BlocksLibraryPlugin;exports.DocSchemaPlugin=U.DocSchemaPlugin;exports.TranslationWorkflowPlugin=_.TranslationWorkflowPlugin;exports.SlashCommandsPlugin=N.SlashCommandsPlugin;exports.MediaManagerPlugin=n.MediaManagerPlugin;exports.getMediaManagerConfig=n.getMediaManagerConfig;exports.setMediaManagerConfig=n.setMediaManagerConfig;exports.DocumentManagerPlugin=t.DocumentManagerPlugin;exports.getDocumentManagerConfig=t.getDocumentManagerConfig;exports.setDocumentManagerConfig=t.setDocumentManagerConfig;exports.PreviewPlugin=V.PreviewPlugin;exports.FullscreenPlugin=O.FullscreenPlugin;exports.PrintPlugin=J.PrintPlugin;exports.PageBreakPlugin=K.PageBreakPlugin;exports.FootnotePlugin=Q.FootnotePlugin;exports.CodeSamplePlugin=X.CodeSamplePlugin;exports.MergeTagPlugin=Y.MergeTagPlugin;exports.PREDEFINED_TEMPLATES=e.PREDEFINED_TEMPLATES;exports.TemplatePlugin=e.TemplatePlugin;exports.addCustomTemplate=e.addCustomTemplate;exports.getAllTemplates=e.getAllTemplates;exports.getTemplateCategories=e.getTemplateCategories;exports.getTemplatesByCategory=e.getTemplatesByCategory;exports.sanitizeTemplate=e.sanitizeTemplate;exports.searchTemplates=e.searchTemplates;exports.validateTemplate=e.validateTemplate;exports.CommentsPlugin=Z.CommentsPlugin;exports.SpellCheckPlugin=$.SpellCheckPlugin;exports.A11yCheckerPlugin=ee.A11yCheckerPlugin;exports.buildApiUrl=i.buildApiUrl;exports.getGlobalApiConfig=i.getGlobalApiConfig;exports.getGlobalApiHeaders=i.getGlobalApiHeaders;exports.setGlobalApiConfig=i.setGlobalApiConfig; |
+109
-81
@@ -1,99 +0,127 @@ | ||
| import { HeadingPlugin as r } from "./heading.esm.js"; | ||
| import { HeadingPlugin as e } from "./heading.esm.js"; | ||
| import { BoldPlugin as i } from "./bold.esm.js"; | ||
| import { ItalicPlugin as n } from "./italic.esm.js"; | ||
| import { ItalicPlugin as l } from "./italic.esm.js"; | ||
| import { UnderlinePlugin as m } from "./underline.esm.js"; | ||
| import { StrikethroughPlugin as a } from "./strikethrough.esm.js"; | ||
| import { ListPlugin as f } from "./list.esm.js"; | ||
| import { ListPlugin as u } from "./list.esm.js"; | ||
| import { ChecklistPlugin as x } from "./checklist.esm.js"; | ||
| import { HistoryPlugin as C } from "./history.esm.js"; | ||
| import { LinkPlugin as c } from "./link.esm.js"; | ||
| import { BlockquotePlugin as M } from "./blockquote.esm.js"; | ||
| import { ClearFormattingPlugin as A } from "./clear-formatting.esm.js"; | ||
| import { LinkPlugin as d } from "./link.esm.js"; | ||
| import { BlockquotePlugin as h } from "./blockquote.esm.js"; | ||
| import { ClearFormattingPlugin as k } from "./clear-formatting.esm.js"; | ||
| import { CodePlugin as D } from "./code.esm.js"; | ||
| import { TablePlugin as F } from "./table.esm.js"; | ||
| import { FontSizePlugin as S } from "./font-size.esm.js"; | ||
| import { FontFamilyPlugin as B } from "./font-family.esm.js"; | ||
| import { TextAlignmentPlugin as I } from "./text-alignment.esm.js"; | ||
| import { TextColorPlugin as z } from "./text-color.esm.js"; | ||
| import { BackgroundColorPlugin as v } from "./background-color.esm.js"; | ||
| import { LineHeightPlugin as j } from "./line-height.esm.js"; | ||
| import { IndentPlugin as w } from "./indent.esm.js"; | ||
| import { DirectionPlugin as R } from "./direction.esm.js"; | ||
| import { CapitalizationPlugin as J } from "./capitalization.esm.js"; | ||
| import { MathPlugin as O } from "./math.esm.js"; | ||
| import { SpecialCharactersPlugin as V } from "./special-characters.esm.js"; | ||
| import { TablePlugin as b } from "./table.esm.js"; | ||
| import { FontSizePlugin as E } from "./font-size.esm.js"; | ||
| import { FontFamilyPlugin as y } from "./font-family.esm.js"; | ||
| import { TextAlignmentPlugin as L } from "./text-alignment.esm.js"; | ||
| import { TextColorPlugin as v } from "./text-color.esm.js"; | ||
| import { BackgroundColorPlugin as z } from "./background-color.esm.js"; | ||
| import { LineHeightPlugin as R } from "./line-height.esm.js"; | ||
| import { IndentPlugin as W } from "./indent.esm.js"; | ||
| import { DirectionPlugin as q } from "./direction.esm.js"; | ||
| import { CapitalizationPlugin as V } from "./capitalization.esm.js"; | ||
| import { MathPlugin as J } from "./math.esm.js"; | ||
| import { SpecialCharactersPlugin as O } from "./special-characters.esm.js"; | ||
| import { EmojisPlugin as X } from "./emojis.esm.js"; | ||
| import { EmbedIframePlugin as Z } from "./embed-iframe.esm.js"; | ||
| import { AnchorPlugin as ee } from "./anchor.esm.js"; | ||
| import { MediaManagerPlugin as re, getMediaManagerConfig as te, setMediaManagerConfig as ie } from "./media-manager.esm.js"; | ||
| import { D as ne, g as ge, s as me } from "./index-BFsKNTTj.mjs"; | ||
| import { PreviewPlugin as ae } from "./preview.esm.js"; | ||
| import { FullscreenPlugin as fe } from "./fullscreen.esm.js"; | ||
| import { PrintPlugin as xe } from "./print.esm.js"; | ||
| import { PageBreakPlugin as Ce } from "./page-break.esm.js"; | ||
| import { FootnotePlugin as ce } from "./footnote.esm.js"; | ||
| import { CodeSamplePlugin as Me } from "./code-sample.esm.js"; | ||
| import { MergeTagPlugin as Ae } from "./merge-tag.esm.js"; | ||
| import { PREDEFINED_TEMPLATES as De, TemplatePlugin as Ee, addCustomTemplate as Fe, getAllTemplates as be, getTemplateCategories as Se, getTemplatesByCategory as ye, sanitizeTemplate as Be, searchTemplates as He, validateTemplate as Ie } from "./template.esm.js"; | ||
| import { CommentsPlugin as ze } from "./comments.esm.js"; | ||
| import { SpellCheckPlugin as ve } from "./spell-check.esm.js"; | ||
| import { A11yCheckerPlugin as je } from "./a11y-checker.esm.js"; | ||
| import { buildApiUrl as we, getGlobalApiConfig as Ne, getGlobalApiHeaders as Re, setGlobalApiConfig as _e } from "./shared-config.esm.js"; | ||
| import { AnchorPlugin as oo } from "./anchor.esm.js"; | ||
| import { MentionPlugin as eo } from "./mentions.esm.js"; | ||
| import { TrackChangesPlugin as io } from "./track-changes.esm.js"; | ||
| import { VersionDiffPlugin as lo } from "./version-diff.esm.js"; | ||
| import { ConditionalContentPlugin as mo } from "./conditional-content.esm.js"; | ||
| import { DataBindingPlugin as ao } from "./data-binding.esm.js"; | ||
| import { ContentRulesPlugin as uo } from "./content-rules.esm.js"; | ||
| import { CitationsPlugin as xo } from "./citations.esm.js"; | ||
| import { ApprovalWorkflowPlugin as Co } from "./approval-workflow.esm.js"; | ||
| import { PIIRedactionPlugin as To } from "./pii-redaction.esm.js"; | ||
| import { SmartPastePlugin as Mo } from "./smart-paste.esm.js"; | ||
| import { BlocksLibraryPlugin as Ao } from "./blocks-library.esm.js"; | ||
| import { DocSchemaPlugin as So } from "./doc-schema.esm.js"; | ||
| import { TranslationWorkflowPlugin as Bo } from "./translation-workflow.esm.js"; | ||
| import { SlashCommandsPlugin as Fo } from "./slash-commands.esm.js"; | ||
| import { MediaManagerPlugin as Io, getMediaManagerConfig as Lo, setMediaManagerConfig as Ho } from "./media-manager.esm.js"; | ||
| import { D as wo, g as zo, s as Go } from "./index-BFsKNTTj.mjs"; | ||
| import { PreviewPlugin as Uo } from "./preview.esm.js"; | ||
| import { FullscreenPlugin as jo } from "./fullscreen.esm.js"; | ||
| import { PrintPlugin as No } from "./print.esm.js"; | ||
| import { PageBreakPlugin as _o } from "./page-break.esm.js"; | ||
| import { FootnotePlugin as Ko } from "./footnote.esm.js"; | ||
| import { CodeSamplePlugin as Qo } from "./code-sample.esm.js"; | ||
| import { MergeTagPlugin as Yo } from "./merge-tag.esm.js"; | ||
| import { PREDEFINED_TEMPLATES as $o, TemplatePlugin as or, addCustomTemplate as rr, getAllTemplates as er, getTemplateCategories as tr, getTemplatesByCategory as ir, sanitizeTemplate as nr, searchTemplates as lr, validateTemplate as gr } from "./template.esm.js"; | ||
| import { CommentsPlugin as pr } from "./comments.esm.js"; | ||
| import { SpellCheckPlugin as fr } from "./spell-check.esm.js"; | ||
| import { A11yCheckerPlugin as Pr } from "./a11y-checker.esm.js"; | ||
| import { buildApiUrl as sr, getGlobalApiConfig as Cr, getGlobalApiHeaders as cr, setGlobalApiConfig as dr } from "./shared-config.esm.js"; | ||
| export { | ||
| je as A11yCheckerPlugin, | ||
| ee as AnchorPlugin, | ||
| v as BackgroundColorPlugin, | ||
| M as BlockquotePlugin, | ||
| Pr as A11yCheckerPlugin, | ||
| oo as AnchorPlugin, | ||
| Co as ApprovalWorkflowPlugin, | ||
| z as BackgroundColorPlugin, | ||
| h as BlockquotePlugin, | ||
| Ao as BlocksLibraryPlugin, | ||
| i as BoldPlugin, | ||
| J as CapitalizationPlugin, | ||
| V as CapitalizationPlugin, | ||
| x as ChecklistPlugin, | ||
| A as ClearFormattingPlugin, | ||
| xo as CitationsPlugin, | ||
| k as ClearFormattingPlugin, | ||
| D as CodePlugin, | ||
| Me as CodeSamplePlugin, | ||
| ze as CommentsPlugin, | ||
| R as DirectionPlugin, | ||
| ne as DocumentManagerPlugin, | ||
| Qo as CodeSamplePlugin, | ||
| pr as CommentsPlugin, | ||
| mo as ConditionalContentPlugin, | ||
| uo as ContentRulesPlugin, | ||
| ao as DataBindingPlugin, | ||
| q as DirectionPlugin, | ||
| So as DocSchemaPlugin, | ||
| wo as DocumentManagerPlugin, | ||
| Z as EmbedIframePlugin, | ||
| X as EmojisPlugin, | ||
| B as FontFamilyPlugin, | ||
| S as FontSizePlugin, | ||
| ce as FootnotePlugin, | ||
| fe as FullscreenPlugin, | ||
| r as HeadingPlugin, | ||
| y as FontFamilyPlugin, | ||
| E as FontSizePlugin, | ||
| Ko as FootnotePlugin, | ||
| jo as FullscreenPlugin, | ||
| e as HeadingPlugin, | ||
| C as HistoryPlugin, | ||
| w as IndentPlugin, | ||
| n as ItalicPlugin, | ||
| j as LineHeightPlugin, | ||
| c as LinkPlugin, | ||
| f as ListPlugin, | ||
| O as MathPlugin, | ||
| re as MediaManagerPlugin, | ||
| Ae as MergeTagPlugin, | ||
| De as PREDEFINED_TEMPLATES, | ||
| Ce as PageBreakPlugin, | ||
| ae as PreviewPlugin, | ||
| xe as PrintPlugin, | ||
| V as SpecialCharactersPlugin, | ||
| ve as SpellCheckPlugin, | ||
| W as IndentPlugin, | ||
| l as ItalicPlugin, | ||
| R as LineHeightPlugin, | ||
| d as LinkPlugin, | ||
| u as ListPlugin, | ||
| J as MathPlugin, | ||
| Io as MediaManagerPlugin, | ||
| eo as MentionPlugin, | ||
| Yo as MergeTagPlugin, | ||
| To as PIIRedactionPlugin, | ||
| $o as PREDEFINED_TEMPLATES, | ||
| _o as PageBreakPlugin, | ||
| Uo as PreviewPlugin, | ||
| No as PrintPlugin, | ||
| Fo as SlashCommandsPlugin, | ||
| Mo as SmartPastePlugin, | ||
| O as SpecialCharactersPlugin, | ||
| fr as SpellCheckPlugin, | ||
| a as StrikethroughPlugin, | ||
| F as TablePlugin, | ||
| Ee as TemplatePlugin, | ||
| I as TextAlignmentPlugin, | ||
| z as TextColorPlugin, | ||
| b as TablePlugin, | ||
| or as TemplatePlugin, | ||
| L as TextAlignmentPlugin, | ||
| v as TextColorPlugin, | ||
| io as TrackChangesPlugin, | ||
| Bo as TranslationWorkflowPlugin, | ||
| m as UnderlinePlugin, | ||
| Fe as addCustomTemplate, | ||
| we as buildApiUrl, | ||
| be as getAllTemplates, | ||
| ge as getDocumentManagerConfig, | ||
| Ne as getGlobalApiConfig, | ||
| Re as getGlobalApiHeaders, | ||
| te as getMediaManagerConfig, | ||
| Se as getTemplateCategories, | ||
| ye as getTemplatesByCategory, | ||
| Be as sanitizeTemplate, | ||
| He as searchTemplates, | ||
| me as setDocumentManagerConfig, | ||
| _e as setGlobalApiConfig, | ||
| ie as setMediaManagerConfig, | ||
| Ie as validateTemplate | ||
| lo as VersionDiffPlugin, | ||
| rr as addCustomTemplate, | ||
| sr as buildApiUrl, | ||
| er as getAllTemplates, | ||
| zo as getDocumentManagerConfig, | ||
| Cr as getGlobalApiConfig, | ||
| cr as getGlobalApiHeaders, | ||
| Lo as getMediaManagerConfig, | ||
| tr as getTemplateCategories, | ||
| ir as getTemplatesByCategory, | ||
| nr as sanitizeTemplate, | ||
| lr as searchTemplates, | ||
| Go as setDocumentManagerConfig, | ||
| dr as setGlobalApiConfig, | ||
| Ho as setMediaManagerConfig, | ||
| gr as validateTemplate | ||
| }; |
@@ -1,2 +0,2 @@ | ||
| "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const d='.rte-page-break[data-type="page-break"]',g=".rte-content, .editora-content";let p=null,m=!1;const h=(e,n)=>{if(n===e.innerHTML)return;const t=window.execEditorCommand||window.executeEditorCommand;if(typeof t=="function")try{t("recordDomTransaction",e,n,e.innerHTML)}catch{}},x=new Set(["DIV","P","BLOCKQUOTE","PRE","H1","H2","H3","H4","H5","H6","LI","TD","TH"]),w=()=>{p||typeof document>"u"||(p=document.createElement("style"),p.textContent=` | ||
| "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const d='.rte-page-break[data-type="page-break"]',f=".rte-content, .editora-content";let p=null,m=!1;const h=(e,n)=>{if(n===e.innerHTML)return;const t=window.execEditorCommand||window.executeEditorCommand;if(typeof t=="function")try{t("recordDomTransaction",e,n,e.innerHTML)}catch{}},x=new Set(["DIV","P","BLOCKQUOTE","PRE","H1","H2","H3","H4","H5","H6","LI","TD","TH"]),C=()=>{p||typeof document>"u"||(p=document.createElement("style"),p.textContent=` | ||
| .rte-page-break { | ||
@@ -72,2 +72,2 @@ display: block; | ||
| } | ||
| `,document.head.appendChild(p))},N=()=>{const e=window.getSelection();if(!e||e.rangeCount===0)return null;const n=e.getRangeAt(0);return(n.startContainer.nodeType===Node.ELEMENT_NODE?n.startContainer:n.startContainer.parentElement)?.closest(g)||null},v=()=>{const e=N();if(e)return e;const t=document.activeElement?.closest(g);return t||document.querySelector(g)},C=(e,n)=>{let t=e;for(;t&&t!==n;){if(t.nodeType===Node.ELEMENT_NODE){const r=t;if(x.has(r.tagName))return r}t=t.parentNode}return null},S=()=>{const e=document.createElement("div");return e.className="rte-page-break",e.setAttribute("data-page-break","true"),e.setAttribute("data-type","page-break"),e.setAttribute("contenteditable","false"),e.setAttribute("tabindex","0"),e.setAttribute("role","separator"),e.setAttribute("aria-label","Page break"),e},T=e=>{let n=e.nextElementSibling;for(;n&&n.matches(d);){const r=n;n=n.nextElementSibling,r.remove()}let t=e.previousElementSibling;for(;t&&t.matches(d);){const r=t;t=t.previousElementSibling,r.remove()}},k=e=>{const n=e.nextElementSibling;if(n&&!n.matches(d))return n;const t=document.createElement("p");return t.innerHTML="<br>",e.parentNode?.insertBefore(t,e.nextSibling),t},u=e=>{const n=window.getSelection();if(!n)return;const t=document.createRange();e.nodeType,Node.TEXT_NODE,t.setStart(e,0),t.collapse(!0),n.removeAllRanges(),n.addRange(t)},b=e=>{const n=window.getSelection();if(!n)return;const t=document.createRange();if(e.nodeType===Node.TEXT_NODE){const r=e;t.setStart(r,r.data.length)}else t.selectNodeContents(e),t.collapse(!1);n.removeAllRanges(),n.addRange(t)},f=(e,n)=>{let t=e;for(;t;){if(!(t instanceof HTMLElement&&t.matches(d)))return t;t=n==="previous"?t.previousSibling:t.nextSibling}return null},L=e=>{const n=window.getSelection();if(!n||!e.parentNode)return;const t=e.parentNode,r=Array.from(t.childNodes).indexOf(e);if(r<0)return;const o=document.createRange();o.setStart(t,r),o.setEnd(t,r+1),n.removeAllRanges(),n.addRange(o),e.focus({preventScroll:!0})},A=e=>{if(e.collapsed||e.startContainer!==e.endContainer||e.endOffset!==e.startOffset+1||!(e.startContainer instanceof Element||e.startContainer instanceof DocumentFragment))return null;const n=e.startContainer.childNodes[e.startOffset];return n instanceof HTMLElement&&n.matches(d)?n:null},R=(e,n,t)=>{if(!e.collapsed)return null;const{startContainer:r,startOffset:o}=e,a=i=>i instanceof HTMLElement&&i.matches(d)?i:null,c=i=>{if(r.nodeType===Node.ELEMENT_NODE){const l=r;if(i==="previous"){if(o>0)return l.childNodes[o-1]||null}else if(o<l.childNodes.length)return l.childNodes[o]||null}if(r.nodeType===Node.TEXT_NODE&&(i==="previous"&&o<r.data.length||i==="next"&&o>0))return null;let s=r;for(;s&&s!==n;){const l=i==="previous"?s.previousSibling:s.nextSibling;if(l)return l;s=s.parentNode}return null};if(r.nodeType===Node.ELEMENT_NODE){const i=r;return t==="Backspace"&&o>0?a(i.childNodes[o-1]||null):t==="Delete"?a(i.childNodes[o]||null):null}if(r.nodeType===Node.TEXT_NODE){const i=r;if(t==="Backspace"&&o===0){const s=a(i.previousSibling);return s||a(c("previous"))}if(t==="Delete"&&o===i.data.length){const s=a(i.nextSibling);return s||a(c("next"))}}return a(c(t==="Backspace"?"previous":"next"))},E=(e,n)=>{const t=e.closest(g),r=t?.innerHTML??"",o=e.previousSibling,a=e.nextSibling;e.remove();const c=f(o,"previous"),i=f(a,"next");if(n==="Backspace"){if(c)b(c);else if(i)u(i);else if(t){const s=document.createElement("p");s.innerHTML="<br>",t.appendChild(s),u(s)}}else if(i)u(i);else if(c)b(c);else if(t){const s=document.createElement("p");s.innerHTML="<br>",t.appendChild(s),u(s)}return t&&(h(t,r),t.dispatchEvent(new Event("input",{bubbles:!0}))),!0},y=()=>{const e=v();if(!e)return!1;const n=e.innerHTML,t=window.getSelection();if(!t)return!1;let r;t.rangeCount>0&&e.contains(t.getRangeAt(0).commonAncestorContainer)?r=t.getRangeAt(0):(r=document.createRange(),r.selectNodeContents(e),r.collapse(!1),t.removeAllRanges(),t.addRange(r));const o=C(r.endContainer,e)||C(r.startContainer,e),a=S();o&&o.parentNode?o.parentNode.insertBefore(a,o.nextSibling):e.appendChild(a),T(a);const c=k(a);return u(c),h(e,n),e.dispatchEvent(new Event("input",{bubbles:!0})),!0},B=()=>{m||typeof document>"u"||(m=!0,document.addEventListener("click",e=>{const t=e.target?.closest(d);t&&(e.preventDefault(),e.stopPropagation(),L(t))}),document.addEventListener("keydown",e=>{const n=e.key;if(!["Backspace","Delete","ArrowUp","ArrowDown","ArrowLeft","ArrowRight"].includes(n))return;const t=window.getSelection();if(!t||t.rangeCount===0)return;const r=t.getRangeAt(0),o=v();if(!o||!o.contains(r.commonAncestorContainer))return;const a=A(r);if(a){if(n==="Backspace"||n==="Delete"){e.preventDefault(),e.stopPropagation(),E(a,n);return}if(n==="ArrowRight"||n==="ArrowDown"){e.preventDefault();const c=f(a.nextSibling,"next")||k(a);u(c);return}if(n==="ArrowLeft"||n==="ArrowUp"){e.preventDefault();const c=f(a.previousSibling,"previous");c?b(c):u(o);return}}if(n==="Backspace"||n==="Delete"){const c=R(r,o,n);if(!c)return;e.preventDefault(),e.stopPropagation(),E(c,n)}}))},P=()=>(w(),B(),{name:"pageBreak",toolbar:[{label:"Page Break",command:"insertPageBreak",icon:'<svg fill="#000000" width="24px" height="24px" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><path d="M1,6 L3,6 C3.55228475,6 4,6.44771525 4,7 C4,7.55228475 3.55228475,8 3,8 L1,8 C0.44771525,8 0,7.55228475 0,7 C0,6.44771525 0.44771525,6 1,6 Z M11,6 L13,6 C13.5522847,6 14,6.44771525 14,7 C14,7.55228475 13.5522847,8 13,8 L11,8 C10.4477153,8 10,7.55228475 10,7 C10,6.44771525 10.4477153,6 11,6 Z M6,6 L8,6 C8.55228475,6 9,6.44771525 9,7 C9,7.55228475 8.55228475,8 8,8 L6,8 C5.44771525,8 5,7.55228475 5,7 C5,6.44771525 5.44771525,6 6,6 Z M0,1 C0,0.44771525 0.44771525,-2.26485497e-13 1,-2.26485497e-13 C1.55228475,-2.26485497e-13 2,0.44771525 2,1 L2,3.0142458 L12,3.0142458 L12,1 C12,0.44771525 12.4477153,-2.26485497e-13 13,-2.26485497e-13 C13.5522847,-2.26485497e-13 14,0.44771525 14,1 L14,3.0142458 C14,4.1188153 13.1045695,5.0142458 12,5.0142458 L2,5.0142458 C0.8954305,5.0142458 0,4.1188153 0,3.0142458 L0,1 Z M0,13.0142458 L0,11 C0,9.8954305 0.8954305,9 2,9 L12,9 C13.1045695,9 14,9.8954305 14,11 L14,13.0142458 C14,13.5665305 13.5522847,14.0142458 13,14.0142458 C12.4477153,14.0142458 12,13.5665305 12,13.0142458 L12,11 L2,11 L2,13.0142458 C2,13.5665305 1.55228475,14.0142458 1,14.0142458 C0.44771525,14.0142458 0,13.5665305 0,13.0142458 Z"></path></g></svg>',shortcut:"Mod-Enter"}],commands:{insertPageBreak:y},keymap:{"Mod-Enter":"insertPageBreak"}});exports.PageBreakPlugin=P; | ||
| `,document.head.appendChild(p))},N=()=>{const e=window.getSelection();if(!e||e.rangeCount===0)return null;const n=e.getRangeAt(0);return(n.startContainer.nodeType===Node.ELEMENT_NODE?n.startContainer:n.startContainer.parentElement)?.closest(f)||null},v=()=>{const e=N();if(e)return e;const t=document.activeElement?.closest(f);return t||document.querySelector(f)},E=(e,n)=>{let t=e;for(;t&&t!==n;){if(t.nodeType===Node.ELEMENT_NODE){const r=t;if(x.has(r.tagName))return r}t=t.parentNode}return null},T=()=>{const e=document.createElement("div");return e.className="rte-page-break",e.setAttribute("data-page-break","true"),e.setAttribute("data-type","page-break"),e.setAttribute("contenteditable","false"),e.setAttribute("tabindex","0"),e.setAttribute("role","separator"),e.setAttribute("aria-label","Page break"),e},S=e=>{let n=e.nextElementSibling;for(;n&&n.matches(d);){const r=n;n=n.nextElementSibling,r.remove()}let t=e.previousElementSibling;for(;t&&t.matches(d);){const r=t;t=t.previousElementSibling,r.remove()}},w=e=>{const n=e.nextElementSibling;if(n&&!n.matches(d))return n;const t=document.createElement("p");return t.innerHTML="<br>",e.parentNode?.insertBefore(t,e.nextSibling),t},u=e=>{const n=window.getSelection();if(!n)return;const t=document.createRange();e.nodeType,Node.TEXT_NODE,t.setStart(e,0),t.collapse(!0),n.removeAllRanges(),n.addRange(t)},b=e=>{const n=window.getSelection();if(!n)return;const t=document.createRange();if(e.nodeType===Node.TEXT_NODE){const r=e;t.setStart(r,r.data.length)}else t.selectNodeContents(e),t.collapse(!1);n.removeAllRanges(),n.addRange(t)},g=(e,n)=>{let t=e;for(;t;){if(!(t instanceof HTMLElement&&t.matches(d)))return t;t=n==="previous"?t.previousSibling:t.nextSibling}return null},A=e=>{const n=window.getSelection();if(!n||!e.parentNode)return;const t=e.parentNode,r=Array.from(t.childNodes).indexOf(e);if(r<0)return;const o=document.createRange();o.setStart(t,r),o.setEnd(t,r+1),n.removeAllRanges(),n.addRange(o),e.focus({preventScroll:!0})},y=e=>{if(e.collapsed||e.startContainer!==e.endContainer||e.endOffset!==e.startOffset+1||!(e.startContainer instanceof Element||e.startContainer instanceof DocumentFragment))return null;const n=e.startContainer.childNodes[e.startOffset];return n instanceof HTMLElement&&n.matches(d)?n:null},B=(e,n,t)=>{if(!e.collapsed)return null;const{startContainer:r,startOffset:o}=e,a=i=>i instanceof HTMLElement&&i.matches(d)?i:null,c=i=>{if(r.nodeType===Node.ELEMENT_NODE){const l=r;if(i==="previous"){if(o>0)return l.childNodes[o-1]||null}else if(o<l.childNodes.length)return l.childNodes[o]||null}if(r.nodeType===Node.TEXT_NODE&&(i==="previous"&&o<r.data.length||i==="next"&&o>0))return null;let s=r;for(;s&&s!==n;){const l=i==="previous"?s.previousSibling:s.nextSibling;if(l)return l;s=s.parentNode}return null};if(r.nodeType===Node.ELEMENT_NODE){const i=r;return t==="Backspace"&&o>0?a(i.childNodes[o-1]||null):t==="Delete"?a(i.childNodes[o]||null):null}if(r.nodeType===Node.TEXT_NODE){const i=r;if(t==="Backspace"&&o===0){const s=a(i.previousSibling);return s||a(c("previous"))}if(t==="Delete"&&o===i.data.length){const s=a(i.nextSibling);return s||a(c("next"))}}return a(c(t==="Backspace"?"previous":"next"))},k=(e,n)=>{const t=e.closest(f),r=t?.innerHTML??"",o=e.previousSibling,a=e.nextSibling;e.remove();const c=g(o,"previous"),i=g(a,"next");if(n==="Backspace"){if(c)b(c);else if(i)u(i);else if(t){const s=document.createElement("p");s.innerHTML="<br>",t.appendChild(s),u(s)}}else if(i)u(i);else if(c)b(c);else if(t){const s=document.createElement("p");s.innerHTML="<br>",t.appendChild(s),u(s)}return t&&(h(t,r),t.dispatchEvent(new Event("input",{bubbles:!0}))),!0},P=()=>{const e=v();if(!e)return!1;const n=e.innerHTML,t=window.getSelection();if(!t)return!1;let r;t.rangeCount>0&&e.contains(t.getRangeAt(0).commonAncestorContainer)?r=t.getRangeAt(0):(r=document.createRange(),r.selectNodeContents(e),r.collapse(!1),t.removeAllRanges(),t.addRange(r));const o=E(r.endContainer,e)||E(r.startContainer,e),a=T();o&&o.parentNode?o.parentNode.insertBefore(a,o.nextSibling):e.appendChild(a),S(a);const c=w(a);return u(c),h(e,n),e.dispatchEvent(new Event("input",{bubbles:!0})),!0},D=()=>{m||typeof document>"u"||(m=!0,document.addEventListener("click",e=>{const t=e.target?.closest(d);t&&(e.preventDefault(),e.stopPropagation(),A(t))}),document.addEventListener("keydown",e=>{const n=e.key;if(!["Backspace","Delete","ArrowUp","ArrowDown","ArrowLeft","ArrowRight"].includes(n))return;const t=window.getSelection();if(!t||t.rangeCount===0)return;const r=t.getRangeAt(0),o=v();if(!o||!o.contains(r.commonAncestorContainer))return;const a=y(r);if(a){if(n==="Backspace"||n==="Delete"){e.preventDefault(),e.stopPropagation(),k(a,n);return}if(n==="ArrowRight"||n==="ArrowDown"){e.preventDefault();const c=g(a.nextSibling,"next")||w(a);u(c);return}if(n==="ArrowLeft"||n==="ArrowUp"){e.preventDefault();const c=g(a.previousSibling,"previous");c?b(c):u(o);return}}if(n==="Backspace"||n==="Delete"){const c=B(r,o,n);if(!c)return;e.preventDefault(),e.stopPropagation(),k(c,n)}}))},R=()=>(C(),D(),{name:"pageBreak",toolbar:[{label:"Page Break",command:"insertPageBreak",icon:'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"><path d="M5 5H19" stroke="currentColor" stroke-width="1.9" stroke-linecap="round"/><path d="M5 9H19" stroke="currentColor" stroke-width="1.9" stroke-linecap="round"/><path d="M5 15H19" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-dasharray="3.2 3.2"/><path d="M5 19H19" stroke="currentColor" stroke-width="1.9" stroke-linecap="round"/></svg>',shortcut:"Mod-Enter"}],commands:{insertPageBreak:P},keymap:{"Mod-Enter":"insertPageBreak"}});exports.PageBreakPlugin=R; |
+32
-32
@@ -1,2 +0,2 @@ | ||
| const u = '.rte-page-break[data-type="page-break"]', g = ".rte-content, .editora-content"; | ||
| const u = '.rte-page-break[data-type="page-break"]', f = ".rte-content, .editora-content"; | ||
| let p = null, m = !1; | ||
@@ -25,3 +25,3 @@ const h = (e, n) => { | ||
| "TH" | ||
| ]), w = () => { | ||
| ]), C = () => { | ||
| p || typeof document > "u" || (p = document.createElement("style"), p.textContent = ` | ||
@@ -103,9 +103,9 @@ .rte-page-break { | ||
| const n = e.getRangeAt(0); | ||
| return (n.startContainer.nodeType === Node.ELEMENT_NODE ? n.startContainer : n.startContainer.parentElement)?.closest(g) || null; | ||
| }, k = () => { | ||
| return (n.startContainer.nodeType === Node.ELEMENT_NODE ? n.startContainer : n.startContainer.parentElement)?.closest(f) || null; | ||
| }, v = () => { | ||
| const e = N(); | ||
| if (e) return e; | ||
| const t = document.activeElement?.closest(g); | ||
| return t || document.querySelector(g); | ||
| }, C = (e, n) => { | ||
| const t = document.activeElement?.closest(f); | ||
| return t || document.querySelector(f); | ||
| }, E = (e, n) => { | ||
| let t = e; | ||
@@ -135,3 +135,3 @@ for (; t && t !== n; ) { | ||
| } | ||
| }, v = (e) => { | ||
| }, w = (e) => { | ||
| const n = e.nextElementSibling; | ||
@@ -157,3 +157,3 @@ if (n && !n.matches(u)) | ||
| n.removeAllRanges(), n.addRange(t); | ||
| }, f = (e, n) => { | ||
| }, g = (e, n) => { | ||
| let t = e; | ||
@@ -166,3 +166,3 @@ for (; t; ) { | ||
| return null; | ||
| }, L = (e) => { | ||
| }, A = (e) => { | ||
| const n = window.getSelection(); | ||
@@ -174,7 +174,7 @@ if (!n || !e.parentNode) return; | ||
| o.setStart(t, r), o.setEnd(t, r + 1), n.removeAllRanges(), n.addRange(o), e.focus({ preventScroll: !0 }); | ||
| }, A = (e) => { | ||
| }, y = (e) => { | ||
| if (e.collapsed || e.startContainer !== e.endContainer || e.endOffset !== e.startOffset + 1 || !(e.startContainer instanceof Element || e.startContainer instanceof DocumentFragment)) return null; | ||
| const n = e.startContainer.childNodes[e.startOffset]; | ||
| return n instanceof HTMLElement && n.matches(u) ? n : null; | ||
| }, R = (e, n, t) => { | ||
| }, B = (e, n, t) => { | ||
| if (!e.collapsed) return null; | ||
@@ -216,6 +216,6 @@ const { startContainer: r, startOffset: o } = e, a = (i) => i instanceof HTMLElement && i.matches(u) ? i : null, c = (i) => { | ||
| return a(c(t === "Backspace" ? "previous" : "next")); | ||
| }, E = (e, n) => { | ||
| const t = e.closest(g), r = t?.innerHTML ?? "", o = e.previousSibling, a = e.nextSibling; | ||
| }, k = (e, n) => { | ||
| const t = e.closest(f), r = t?.innerHTML ?? "", o = e.previousSibling, a = e.nextSibling; | ||
| e.remove(); | ||
| const c = f(o, "previous"), i = f(a, "next"); | ||
| const c = g(o, "previous"), i = g(a, "next"); | ||
| if (n === "Backspace") { | ||
@@ -239,4 +239,4 @@ if (c) | ||
| return t && (h(t, r), t.dispatchEvent(new Event("input", { bubbles: !0 }))), !0; | ||
| }, y = () => { | ||
| const e = k(); | ||
| }, D = () => { | ||
| const e = v(); | ||
| if (!e) return !1; | ||
@@ -247,10 +247,10 @@ const n = e.innerHTML, t = window.getSelection(); | ||
| t.rangeCount > 0 && e.contains(t.getRangeAt(0).commonAncestorContainer) ? r = t.getRangeAt(0) : (r = document.createRange(), r.selectNodeContents(e), r.collapse(!1), t.removeAllRanges(), t.addRange(r)); | ||
| const o = C(r.endContainer, e) || C(r.startContainer, e), a = T(); | ||
| const o = E(r.endContainer, e) || E(r.startContainer, e), a = T(); | ||
| o && o.parentNode ? o.parentNode.insertBefore(a, o.nextSibling) : e.appendChild(a), S(a); | ||
| const c = v(a); | ||
| const c = w(a); | ||
| return d(c), h(e, n), e.dispatchEvent(new Event("input", { bubbles: !0 })), !0; | ||
| }, B = () => { | ||
| }, R = () => { | ||
| m || typeof document > "u" || (m = !0, document.addEventListener("click", (e) => { | ||
| const t = e.target?.closest(u); | ||
| t && (e.preventDefault(), e.stopPropagation(), L(t)); | ||
| t && (e.preventDefault(), e.stopPropagation(), A(t)); | ||
| }), document.addEventListener("keydown", (e) => { | ||
@@ -262,8 +262,8 @@ const n = e.key; | ||
| if (!t || t.rangeCount === 0) return; | ||
| const r = t.getRangeAt(0), o = k(); | ||
| const r = t.getRangeAt(0), o = v(); | ||
| if (!o || !o.contains(r.commonAncestorContainer)) return; | ||
| const a = A(r); | ||
| const a = y(r); | ||
| if (a) { | ||
| if (n === "Backspace" || n === "Delete") { | ||
| e.preventDefault(), e.stopPropagation(), E(a, n); | ||
| e.preventDefault(), e.stopPropagation(), k(a, n); | ||
| return; | ||
@@ -273,3 +273,3 @@ } | ||
| e.preventDefault(); | ||
| const c = f(a.nextSibling, "next") || v(a); | ||
| const c = g(a.nextSibling, "next") || w(a); | ||
| d(c); | ||
@@ -280,3 +280,3 @@ return; | ||
| e.preventDefault(); | ||
| const c = f(a.previousSibling, "previous"); | ||
| const c = g(a.previousSibling, "previous"); | ||
| c ? b(c) : d(o); | ||
@@ -287,3 +287,3 @@ return; | ||
| if (n === "Backspace" || n === "Delete") { | ||
| const c = R( | ||
| const c = B( | ||
| r, | ||
@@ -294,6 +294,6 @@ o, | ||
| if (!c) return; | ||
| e.preventDefault(), e.stopPropagation(), E(c, n); | ||
| e.preventDefault(), e.stopPropagation(), k(c, n); | ||
| } | ||
| })); | ||
| }, D = () => (w(), B(), { | ||
| }, P = () => (C(), R(), { | ||
| name: "pageBreak", | ||
@@ -304,3 +304,3 @@ toolbar: [ | ||
| command: "insertPageBreak", | ||
| icon: '<svg fill="#000000" width="24px" height="24px" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><path d="M1,6 L3,6 C3.55228475,6 4,6.44771525 4,7 C4,7.55228475 3.55228475,8 3,8 L1,8 C0.44771525,8 0,7.55228475 0,7 C0,6.44771525 0.44771525,6 1,6 Z M11,6 L13,6 C13.5522847,6 14,6.44771525 14,7 C14,7.55228475 13.5522847,8 13,8 L11,8 C10.4477153,8 10,7.55228475 10,7 C10,6.44771525 10.4477153,6 11,6 Z M6,6 L8,6 C8.55228475,6 9,6.44771525 9,7 C9,7.55228475 8.55228475,8 8,8 L6,8 C5.44771525,8 5,7.55228475 5,7 C5,6.44771525 5.44771525,6 6,6 Z M0,1 C0,0.44771525 0.44771525,-2.26485497e-13 1,-2.26485497e-13 C1.55228475,-2.26485497e-13 2,0.44771525 2,1 L2,3.0142458 L12,3.0142458 L12,1 C12,0.44771525 12.4477153,-2.26485497e-13 13,-2.26485497e-13 C13.5522847,-2.26485497e-13 14,0.44771525 14,1 L14,3.0142458 C14,4.1188153 13.1045695,5.0142458 12,5.0142458 L2,5.0142458 C0.8954305,5.0142458 0,4.1188153 0,3.0142458 L0,1 Z M0,13.0142458 L0,11 C0,9.8954305 0.8954305,9 2,9 L12,9 C13.1045695,9 14,9.8954305 14,11 L14,13.0142458 C14,13.5665305 13.5522847,14.0142458 13,14.0142458 C12.4477153,14.0142458 12,13.5665305 12,13.0142458 L12,11 L2,11 L2,13.0142458 C2,13.5665305 1.55228475,14.0142458 1,14.0142458 C0.44771525,14.0142458 0,13.5665305 0,13.0142458 Z"></path></g></svg>', | ||
| icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"><path d="M5 5H19" stroke="currentColor" stroke-width="1.9" stroke-linecap="round"/><path d="M5 9H19" stroke="currentColor" stroke-width="1.9" stroke-linecap="round"/><path d="M5 15H19" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-dasharray="3.2 3.2"/><path d="M5 19H19" stroke="currentColor" stroke-width="1.9" stroke-linecap="round"/></svg>', | ||
| shortcut: "Mod-Enter" | ||
@@ -310,3 +310,3 @@ } | ||
| commands: { | ||
| insertPageBreak: y | ||
| insertPageBreak: D | ||
| }, | ||
@@ -318,3 +318,3 @@ keymap: { | ||
| export { | ||
| D as PageBreakPlugin | ||
| P as PageBreakPlugin | ||
| }; |
@@ -1,2 +0,2 @@ | ||
| "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});let c=!1;const g=()=>{if(typeof document>"u")return;const r="rte-preview-plugin-styles";if(document.getElementById(r))return;const t=document.createElement("style");t.id=r,t.textContent=` | ||
| "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});let p=!1;const g=()=>{if(typeof document>"u")return;const i="rte-preview-plugin-styles";if(document.getElementById(i))return;const t=document.createElement("style");t.id=i,t.textContent=` | ||
| /* Preview Editor Dialog Styles */ | ||
@@ -220,3 +220,3 @@ .rte-preview-editor-overlay { | ||
| } | ||
| `,document.head.appendChild(t)},v=()=>{const r=window.getSelection();if(r&&r.rangeCount>0){let e=r.getRangeAt(0).startContainer;for(;e&&e!==document.body;){if(e.nodeType===Node.ELEMENT_NODE){const o=e;if(o.getAttribute("contenteditable")==="true")return o}e=e.parentNode}}const t=document.activeElement;if(t){if(t.getAttribute("contenteditable")==="true")return t;const e=t.closest('[contenteditable="true"]');if(e)return e}return document.querySelector('[contenteditable="true"]')},h=()=>{const r=v();if(!r)return"";const t=r.cloneNode(!0);return[".rte-floating-toolbar",".rte-selection-marker",".rte-toolbar",".rte-resize-handle","[data-rte-internal]"].forEach(o=>{t.querySelectorAll(o).forEach(i=>i.remove())}),t.innerHTML},u=r=>{const t=document.createElement("div");return t.innerHTML=r,t.querySelectorAll('script, iframe[src^="javascript:"], object, embed, form[action^="javascript:"]').forEach(i=>i.remove()),t.querySelectorAll("*").forEach(i=>{Array.from(i.attributes).forEach(n=>{n.name.startsWith("on")&&i.removeAttribute(n.name),(n.name==="href"||n.name==="src")&&n.value.startsWith("javascript:")&&i.removeAttribute(n.name)})}),t.innerHTML},w=()=>{if(typeof window>"u"||c)return;c=!0,g();const r=h(),t=u(r),e=document.createElement("div");e.className="rte-preview-editor-overlay",e.setAttribute("role","dialog"),e.setAttribute("aria-modal","true"),e.setAttribute("aria-labelledby","preview-editor-title");const o=document.createElement("div");o.className="rte-preview-editor-modal";const i=document.createElement("div");i.className="rte-preview-editor-header",i.innerHTML=` | ||
| `,document.head.appendChild(t)},v=()=>{const i=window.getSelection();if(i&&i.rangeCount>0){let e=i.getRangeAt(0).startContainer;for(;e&&e!==document.body;){if(e.nodeType===Node.ELEMENT_NODE){const n=e;if(n.getAttribute("contenteditable")==="true")return n}e=e.parentNode}}const t=document.activeElement;if(t){if(t.getAttribute("contenteditable")==="true")return t;const e=t.closest('[contenteditable="true"]');if(e)return e}return document.querySelector('[contenteditable="true"]')},h=()=>{const i=v();if(!i)return"";const t=i.cloneNode(!0);return[".rte-floating-toolbar",".rte-selection-marker",".rte-toolbar",".rte-resize-handle","[data-rte-internal]"].forEach(n=>{t.querySelectorAll(n).forEach(r=>r.remove())}),t.innerHTML},u=i=>{const t=document.createElement("div");return t.innerHTML=i,t.querySelectorAll('script, iframe[src^="javascript:"], object, embed, form[action^="javascript:"]').forEach(r=>r.remove()),t.querySelectorAll("*").forEach(r=>{Array.from(r.attributes).forEach(o=>{o.name.startsWith("on")&&r.removeAttribute(o.name),(o.name==="href"||o.name==="src")&&o.value.startsWith("javascript:")&&r.removeAttribute(o.name),o.name.toLowerCase()==="contenteditable"&&r.removeAttribute(o.name)}),r.setAttribute("contenteditable","false")}),t.innerHTML},w=()=>{if(typeof window>"u"||p)return;p=!0,g();const i=h(),t=u(i),e=document.createElement("div");e.className="rte-preview-editor-overlay",e.setAttribute("role","dialog"),e.setAttribute("aria-modal","true"),e.setAttribute("aria-labelledby","preview-editor-title");const n=document.createElement("div");n.className="rte-preview-editor-modal";const r=document.createElement("div");r.className="rte-preview-editor-header",r.innerHTML=` | ||
| <h2 id="preview-editor-title">Preview Editor</h2> | ||
@@ -231,2 +231,2 @@ <div class="rte-preview-editor-header-actions"> | ||
| </div> | ||
| `;const n=document.createElement("div");n.className="rte-preview-editor-body";const a=document.createElement("div");a.className="rte-preview-editor-content";const l=document.createElement("div");l.className="rte-preview-editor-light-editor",l.innerHTML=t,a.appendChild(l),n.appendChild(a),o.appendChild(i),o.appendChild(n),e.appendChild(o);const p=()=>{e.parentNode&&e.parentNode.removeChild(e),c=!1,document.removeEventListener("keydown",s)},s=d=>{d.key==="Escape"&&(d.preventDefault(),d.stopPropagation(),p())},m=i.querySelector(".rte-preview-editor-close-btn");m&&m.addEventListener("click",d=>{d.preventDefault(),d.stopPropagation(),p()}),e.addEventListener("click",d=>{d.target===e&&p()}),document.addEventListener("keydown",s),document.body.appendChild(e)},f=()=>({name:"preview",toolbar:[{label:"Preview",command:"togglePreview",icon:'<svg fill="#000000" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24px" height="24px" viewBox="0 0 92 92" enable-background="new 0 0 92 92" xml:space="preserve"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <path id="XMLID_1239_" d="M91.3,43.8C90.6,42.8,74.4,19,46,19C17.6,19,1.4,42.8,0.7,43.8c-0.9,1.3-0.9,3.1,0,4.5 C1.4,49.2,17.6,73,46,73c28.4,0,44.6-23.8,45.3-24.8C92.2,46.9,92.2,45.1,91.3,43.8z M46,65C26.7,65,13.5,51.4,9,46 c4.5-5.5,17.6-19,37-19c19.3,0,32.5,13.6,37,19C78.4,51.5,65.3,65,46,65z M48.3,29.6c-4.4-0.6-8.7,0.5-12.3,3.2c0,0,0,0,0,0 c-7.3,5.5-8.8,15.9-3.3,23.2c2.7,3.6,6.5,5.8,10.9,6.5c0.8,0.1,1.6,0.2,2.3,0.2c3.6,0,7-1.2,9.9-3.3c7.3-5.5,8.8-15.9,3.3-23.2 C56.6,32.5,52.7,30.2,48.3,29.6z M52.3,54.5c-2.2,1.7-5,2.4-7.8,2c-2.8-0.4-5.3-1.9-7-4.1C34.1,47.7,35,41,39.7,37.5 c2.2-1.7,5-2.4,7.8-2c2.8,0.4,5.3,1.9,7,4.1C57.9,44.3,57,51,52.3,54.5z M51.9,40c0.8,0.7,1.2,1.8,1.2,2.8c0,1-0.4,2.1-1.2,2.8 c-0.7,0.7-1.8,1.2-2.8,1.2c-1.1,0-2.1-0.4-2.8-1.2c-0.8-0.8-1.2-1.8-1.2-2.8c0-1.1,0.4-2.1,1.2-2.8c0.7-0.8,1.8-1.2,2.8-1.2 C50.2,38.9,51.2,39.3,51.9,40z"></path> </g></svg>'}],commands:{togglePreview:()=>(w(),!0)},keymap:{}});exports.PreviewPlugin=f; | ||
| `;const o=document.createElement("div");o.className="rte-preview-editor-body";const a=document.createElement("div");a.className="rte-preview-editor-content";const l=document.createElement("div");l.className="rte-preview-editor-light-editor",l.innerHTML=t,a.appendChild(l),o.appendChild(a),n.appendChild(r),n.appendChild(o),e.appendChild(n);const c=()=>{e.parentNode&&e.parentNode.removeChild(e),p=!1,document.removeEventListener("keydown",s)},s=d=>{d.key==="Escape"&&(d.preventDefault(),d.stopPropagation(),c())},m=r.querySelector(".rte-preview-editor-close-btn");m&&m.addEventListener("click",d=>{d.preventDefault(),d.stopPropagation(),c()}),e.addEventListener("click",d=>{d.target===e&&c()}),document.addEventListener("keydown",s),document.body.appendChild(e)},f=()=>({name:"preview",toolbar:[{label:"Preview",command:"togglePreview",icon:'<svg fill="#000000" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24px" height="24px" viewBox="0 0 92 92" enable-background="new 0 0 92 92" xml:space="preserve"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <path id="XMLID_1239_" d="M91.3,43.8C90.6,42.8,74.4,19,46,19C17.6,19,1.4,42.8,0.7,43.8c-0.9,1.3-0.9,3.1,0,4.5 C1.4,49.2,17.6,73,46,73c28.4,0,44.6-23.8,45.3-24.8C92.2,46.9,92.2,45.1,91.3,43.8z M46,65C26.7,65,13.5,51.4,9,46 c4.5-5.5,17.6-19,37-19c19.3,0,32.5,13.6,37,19C78.4,51.5,65.3,65,46,65z M48.3,29.6c-4.4-0.6-8.7,0.5-12.3,3.2c0,0,0,0,0,0 c-7.3,5.5-8.8,15.9-3.3,23.2c2.7,3.6,6.5,5.8,10.9,6.5c0.8,0.1,1.6,0.2,2.3,0.2c3.6,0,7-1.2,9.9-3.3c7.3-5.5,8.8-15.9,3.3-23.2 C56.6,32.5,52.7,30.2,48.3,29.6z M52.3,54.5c-2.2,1.7-5,2.4-7.8,2c-2.8-0.4-5.3-1.9-7-4.1C34.1,47.7,35,41,39.7,37.5 c2.2-1.7,5-2.4,7.8-2c2.8,0.4,5.3,1.9,7,4.1C57.9,44.3,57,51,52.3,54.5z M51.9,40c0.8,0.7,1.2,1.8,1.2,2.8c0,1-0.4,2.1-1.2,2.8 c-0.7,0.7-1.8,1.2-2.8,1.2c-1.1,0-2.1-0.4-2.8-1.2c-0.8-0.8-1.2-1.8-1.2-2.8c0-1.1,0.4-2.1,1.2-2.8c0.7-0.8,1.8-1.2,2.8-1.2 C50.2,38.9,51.2,39.3,51.9,40z"></path> </g></svg>'}],commands:{togglePreview:()=>(w(),!0)},keymap:{}});exports.PreviewPlugin=f; |
+29
-29
| let c = !1; | ||
| const g = () => { | ||
| if (typeof document > "u") return; | ||
| const r = "rte-preview-plugin-styles"; | ||
| if (document.getElementById(r)) return; | ||
| const i = "rte-preview-plugin-styles"; | ||
| if (document.getElementById(i)) return; | ||
| const t = document.createElement("style"); | ||
| t.id = r, t.textContent = ` | ||
| t.id = i, t.textContent = ` | ||
| /* Preview Editor Dialog Styles */ | ||
@@ -228,10 +228,10 @@ .rte-preview-editor-overlay { | ||
| }, v = () => { | ||
| const r = window.getSelection(); | ||
| if (r && r.rangeCount > 0) { | ||
| let e = r.getRangeAt(0).startContainer; | ||
| const i = window.getSelection(); | ||
| if (i && i.rangeCount > 0) { | ||
| let e = i.getRangeAt(0).startContainer; | ||
| for (; e && e !== document.body; ) { | ||
| if (e.nodeType === Node.ELEMENT_NODE) { | ||
| const o = e; | ||
| if (o.getAttribute("contenteditable") === "true") | ||
| return o; | ||
| const n = e; | ||
| if (n.getAttribute("contenteditable") === "true") | ||
| return n; | ||
| } | ||
@@ -250,5 +250,5 @@ e = e.parentNode; | ||
| }, h = () => { | ||
| const r = v(); | ||
| if (!r) return ""; | ||
| const t = r.cloneNode(!0); | ||
| const i = v(); | ||
| if (!i) return ""; | ||
| const t = i.cloneNode(!0); | ||
| return [ | ||
@@ -260,13 +260,13 @@ ".rte-floating-toolbar", | ||
| "[data-rte-internal]" | ||
| ].forEach((o) => { | ||
| t.querySelectorAll(o).forEach((i) => i.remove()); | ||
| ].forEach((n) => { | ||
| t.querySelectorAll(n).forEach((r) => r.remove()); | ||
| }), t.innerHTML; | ||
| }, w = (r) => { | ||
| }, w = (i) => { | ||
| const t = document.createElement("div"); | ||
| return t.innerHTML = r, t.querySelectorAll( | ||
| return t.innerHTML = i, t.querySelectorAll( | ||
| 'script, iframe[src^="javascript:"], object, embed, form[action^="javascript:"]' | ||
| ).forEach((i) => i.remove()), t.querySelectorAll("*").forEach((i) => { | ||
| Array.from(i.attributes).forEach((n) => { | ||
| n.name.startsWith("on") && i.removeAttribute(n.name), (n.name === "href" || n.name === "src") && n.value.startsWith("javascript:") && i.removeAttribute(n.name); | ||
| }); | ||
| ).forEach((r) => r.remove()), t.querySelectorAll("*").forEach((r) => { | ||
| Array.from(r.attributes).forEach((o) => { | ||
| o.name.startsWith("on") && r.removeAttribute(o.name), (o.name === "href" || o.name === "src") && o.value.startsWith("javascript:") && r.removeAttribute(o.name), o.name.toLowerCase() === "contenteditable" && r.removeAttribute(o.name); | ||
| }), r.setAttribute("contenteditable", "false"); | ||
| }), t.innerHTML; | ||
@@ -276,8 +276,8 @@ }, u = () => { | ||
| c = !0, g(); | ||
| const r = h(), t = w(r), e = document.createElement("div"); | ||
| const i = h(), t = w(i), e = document.createElement("div"); | ||
| e.className = "rte-preview-editor-overlay", e.setAttribute("role", "dialog"), e.setAttribute("aria-modal", "true"), e.setAttribute("aria-labelledby", "preview-editor-title"); | ||
| const o = document.createElement("div"); | ||
| o.className = "rte-preview-editor-modal"; | ||
| const i = document.createElement("div"); | ||
| i.className = "rte-preview-editor-header", i.innerHTML = ` | ||
| const n = document.createElement("div"); | ||
| n.className = "rte-preview-editor-modal"; | ||
| const r = document.createElement("div"); | ||
| r.className = "rte-preview-editor-header", r.innerHTML = ` | ||
| <h2 id="preview-editor-title">Preview Editor</h2> | ||
@@ -293,8 +293,8 @@ <div class="rte-preview-editor-header-actions"> | ||
| `; | ||
| const n = document.createElement("div"); | ||
| n.className = "rte-preview-editor-body"; | ||
| const o = document.createElement("div"); | ||
| o.className = "rte-preview-editor-body"; | ||
| const a = document.createElement("div"); | ||
| a.className = "rte-preview-editor-content"; | ||
| const l = document.createElement("div"); | ||
| l.className = "rte-preview-editor-light-editor", l.innerHTML = t, a.appendChild(l), n.appendChild(a), o.appendChild(i), o.appendChild(n), e.appendChild(o); | ||
| l.className = "rte-preview-editor-light-editor", l.innerHTML = t, a.appendChild(l), o.appendChild(a), n.appendChild(r), n.appendChild(o), e.appendChild(n); | ||
| const p = () => { | ||
@@ -304,3 +304,3 @@ e.parentNode && e.parentNode.removeChild(e), c = !1, document.removeEventListener("keydown", s); | ||
| d.key === "Escape" && (d.preventDefault(), d.stopPropagation(), p()); | ||
| }, m = i.querySelector(".rte-preview-editor-close-btn"); | ||
| }, m = r.querySelector(".rte-preview-editor-close-btn"); | ||
| m && m.addEventListener("click", (d) => { | ||
@@ -307,0 +307,0 @@ d.preventDefault(), d.stopPropagation(), p(); |
+798
-0
@@ -43,2 +43,786 @@ import type { Plugin } from "@editora/core"; | ||
| export interface TrackChangesPluginOptions { | ||
| author?: string; | ||
| enabledByDefault?: boolean; | ||
| includeTimestamp?: boolean; | ||
| } | ||
| export type VersionDiffMode = "word" | "line"; | ||
| export interface VersionDiffLabels { | ||
| title?: string; | ||
| baseline?: string; | ||
| current?: string; | ||
| noChanges?: string; | ||
| loading?: string; | ||
| tabInline?: string; | ||
| tabSideBySide?: string; | ||
| refresh?: string; | ||
| setBaseline?: string; | ||
| close?: string; | ||
| mode?: string; | ||
| ignoreWhitespace?: string; | ||
| largeDocFallback?: string; | ||
| } | ||
| export interface VersionDiffOpenArgs { | ||
| baselineHtml?: string; | ||
| mode?: VersionDiffMode; | ||
| ignoreWhitespace?: boolean; | ||
| } | ||
| export interface VersionDiffPluginOptions { | ||
| baselineHtml?: string; | ||
| getBaselineHtml?: (context: { editor: HTMLElement; editorRoot: HTMLElement }) => string | Promise<string>; | ||
| mode?: VersionDiffMode; | ||
| ignoreWhitespace?: boolean; | ||
| maxTokens?: number; | ||
| maxMatrixSize?: number; | ||
| labels?: VersionDiffLabels; | ||
| } | ||
| export interface ConditionalContentLabels { | ||
| dialogTitleInsert?: string; | ||
| dialogTitleEdit?: string; | ||
| conditionLabel?: string; | ||
| conditionPlaceholder?: string; | ||
| audienceLabel?: string; | ||
| audiencePlaceholder?: string; | ||
| localeLabel?: string; | ||
| localePlaceholder?: string; | ||
| elseLabel?: string; | ||
| saveText?: string; | ||
| cancelText?: string; | ||
| blockIfLabel?: string; | ||
| blockElseLabel?: string; | ||
| allAudiencesText?: string; | ||
| allLocalesText?: string; | ||
| } | ||
| export interface ConditionalBlockConfig { | ||
| condition?: string; | ||
| audience?: string[]; | ||
| locale?: string[]; | ||
| hasElse?: boolean; | ||
| } | ||
| export interface ConditionalContentDialogArgs extends ConditionalBlockConfig { | ||
| target?: "insert" | "edit"; | ||
| } | ||
| export interface ConditionalContentPluginOptions { | ||
| defaultCondition?: string; | ||
| defaultAudience?: string[]; | ||
| defaultLocale?: string[]; | ||
| enableElseByDefault?: boolean; | ||
| labels?: ConditionalContentLabels; | ||
| context?: Record<string, unknown> | (() => Record<string, unknown>); | ||
| getContext?: (context: { editor: HTMLElement; editorRoot: HTMLElement }) => Record<string, unknown> | Promise<Record<string, unknown>>; | ||
| currentAudience?: string | string[]; | ||
| currentLocale?: string | string[]; | ||
| evaluateCondition?: (condition: string, context: Record<string, unknown>) => boolean; | ||
| } | ||
| export type DataBindingFormat = "text" | "number" | "currency" | "date" | "json"; | ||
| export interface DataBindingLabels { | ||
| dialogTitleInsert?: string; | ||
| dialogTitleEdit?: string; | ||
| keyLabel?: string; | ||
| keyPlaceholder?: string; | ||
| fallbackLabel?: string; | ||
| fallbackPlaceholder?: string; | ||
| formatLabel?: string; | ||
| currencyLabel?: string; | ||
| currencyPlaceholder?: string; | ||
| saveText?: string; | ||
| cancelText?: string; | ||
| previewOnText?: string; | ||
| previewOffText?: string; | ||
| tokenAriaPrefix?: string; | ||
| } | ||
| export interface DataBindingTokenConfig { | ||
| key: string; | ||
| fallback?: string; | ||
| format?: DataBindingFormat; | ||
| currency?: string; | ||
| } | ||
| export interface DataBindingDialogArgs extends Partial<DataBindingTokenConfig> { | ||
| target?: "insert" | "edit"; | ||
| } | ||
| export interface DataBindingApiRequestContext { | ||
| editor: HTMLElement; | ||
| editorRoot: HTMLElement; | ||
| signal: AbortSignal; | ||
| } | ||
| export interface DataBindingApiConfig { | ||
| url: string; | ||
| method?: string; | ||
| headers?: Record<string, string> | ((ctx: DataBindingApiRequestContext) => Record<string, string>); | ||
| credentials?: RequestCredentials; | ||
| mode?: RequestMode; | ||
| cache?: RequestCache; | ||
| params?: Record<string, string> | ((ctx: DataBindingApiRequestContext) => Record<string, string>); | ||
| body?: | ||
| | Record<string, unknown> | ||
| | BodyInit | ||
| | ((ctx: DataBindingApiRequestContext) => Record<string, unknown> | BodyInit | undefined); | ||
| buildRequest?: (ctx: DataBindingApiRequestContext) => { url: string; init?: RequestInit }; | ||
| responseType?: "json" | "text"; | ||
| responsePath?: string; | ||
| transformResponse?: (response: unknown, ctx: DataBindingApiRequestContext) => Record<string, unknown>; | ||
| timeoutMs?: number; | ||
| onError?: (error: unknown, ctx: DataBindingApiRequestContext) => void; | ||
| } | ||
| export interface DataBindingPluginOptions { | ||
| data?: Record<string, unknown> | (() => Record<string, unknown> | Promise<Record<string, unknown>>); | ||
| getData?: (context: { editor: HTMLElement; editorRoot: HTMLElement }) => Record<string, unknown> | Promise<Record<string, unknown>>; | ||
| api?: DataBindingApiConfig; | ||
| cacheTtlMs?: number; | ||
| labels?: DataBindingLabels; | ||
| defaultFormat?: DataBindingFormat; | ||
| defaultFallback?: string; | ||
| locale?: string; | ||
| numberFormatOptions?: Intl.NumberFormatOptions; | ||
| dateFormatOptions?: Intl.DateTimeFormatOptions; | ||
| } | ||
| export type ContentRulesSeverity = "error" | "warning" | "info"; | ||
| export interface ContentRuleIssue { | ||
| id: string; | ||
| ruleId: string; | ||
| severity: ContentRulesSeverity; | ||
| message: string; | ||
| excerpt?: string; | ||
| suggestion?: string; | ||
| locateText?: string; | ||
| selector?: string; | ||
| } | ||
| export interface ContentRulesLabels { | ||
| panelTitle?: string; | ||
| panelAriaLabel?: string; | ||
| runAuditText?: string; | ||
| realtimeOnText?: string; | ||
| realtimeOffText?: string; | ||
| closeText?: string; | ||
| noIssuesText?: string; | ||
| summaryPrefix?: string; | ||
| locateText?: string; | ||
| bannedWordMessage?: string; | ||
| requiredHeadingMessage?: string; | ||
| sentenceLengthMessage?: string; | ||
| readabilityMessage?: string; | ||
| } | ||
| export interface ContentRulesContext { | ||
| editor: HTMLElement; | ||
| editorRoot: HTMLElement; | ||
| text: string; | ||
| html: string; | ||
| wordCount: number; | ||
| sentenceCount: number; | ||
| readabilityScore: number; | ||
| } | ||
| export interface ContentRuleDefinition { | ||
| id: string; | ||
| severity?: ContentRulesSeverity; | ||
| evaluate: (context: ContentRulesContext) => ContentRuleIssue[] | Promise<ContentRuleIssue[]>; | ||
| } | ||
| export interface ContentRulesPluginOptions { | ||
| bannedWords?: string[]; | ||
| requiredHeadings?: string[]; | ||
| maxSentenceWords?: number; | ||
| minReadabilityScore?: number; | ||
| maxIssues?: number; | ||
| debounceMs?: number; | ||
| enableRealtime?: boolean; | ||
| labels?: ContentRulesLabels; | ||
| normalizeText?: (value: string) => string; | ||
| customRules?: ContentRuleDefinition[]; | ||
| } | ||
| export type CitationStyle = "apa" | "mla" | "chicago"; | ||
| export interface CitationRecord { | ||
| id: string; | ||
| author: string; | ||
| year?: string; | ||
| title: string; | ||
| source?: string; | ||
| url?: string; | ||
| note?: string; | ||
| } | ||
| export interface CitationInput { | ||
| id?: string; | ||
| author: string; | ||
| year?: string; | ||
| title: string; | ||
| source?: string; | ||
| url?: string; | ||
| note?: string; | ||
| } | ||
| export interface CitationsLabels { | ||
| panelTitle?: string; | ||
| panelAriaLabel?: string; | ||
| styleLabel?: string; | ||
| authorLabel?: string; | ||
| yearLabel?: string; | ||
| titleLabel?: string; | ||
| sourceLabel?: string; | ||
| urlLabel?: string; | ||
| noteLabel?: string; | ||
| insertText?: string; | ||
| refreshText?: string; | ||
| closeText?: string; | ||
| bibliographyTitle?: string; | ||
| footnotesTitle?: string; | ||
| noCitationsText?: string; | ||
| styleButtonPrefix?: string; | ||
| recentHeading?: string; | ||
| deleteRecentText?: string; | ||
| summaryPrefix?: string; | ||
| invalidMessage?: string; | ||
| } | ||
| export interface CitationsPluginOptions { | ||
| defaultStyle?: CitationStyle; | ||
| enableFootnoteSync?: boolean; | ||
| debounceMs?: number; | ||
| maxRecentCitations?: number; | ||
| labels?: CitationsLabels; | ||
| normalizeText?: (value: string) => string; | ||
| generateCitationId?: (context: { editor: HTMLElement; index: number }) => string; | ||
| } | ||
| export type ApprovalStatus = "draft" | "review" | "approved"; | ||
| export interface ApprovalComment { | ||
| id: string; | ||
| author: string; | ||
| message: string; | ||
| kind: "comment" | "system"; | ||
| createdAt: string; | ||
| } | ||
| export interface ApprovalSignoff { | ||
| id: string; | ||
| author: string; | ||
| comment?: string; | ||
| createdAt: string; | ||
| } | ||
| export interface ApprovalWorkflowState { | ||
| status: ApprovalStatus; | ||
| locked: boolean; | ||
| comments: ApprovalComment[]; | ||
| signoffs: ApprovalSignoff[]; | ||
| updatedAt: string; | ||
| } | ||
| export interface ApprovalWorkflowLabels { | ||
| panelTitle?: string; | ||
| panelAriaLabel?: string; | ||
| statusLabel?: string; | ||
| statusDraftText?: string; | ||
| statusReviewText?: string; | ||
| statusApprovedText?: string; | ||
| requestReviewText?: string; | ||
| approveText?: string; | ||
| reopenDraftText?: string; | ||
| addCommentText?: string; | ||
| actorLabel?: string; | ||
| actorPlaceholder?: string; | ||
| commentLabel?: string; | ||
| commentPlaceholder?: string; | ||
| closeText?: string; | ||
| commentsHeading?: string; | ||
| signoffsHeading?: string; | ||
| noCommentsText?: string; | ||
| noSignoffsText?: string; | ||
| summaryPrefix?: string; | ||
| lockedSuffix?: string; | ||
| shortcutText?: string; | ||
| approveCommentRequiredText?: string; | ||
| } | ||
| export interface ApprovalWorkflowPluginOptions { | ||
| defaultStatus?: ApprovalStatus; | ||
| lockOnApproval?: boolean; | ||
| maxHistoryEntries?: number; | ||
| requireCommentOnApprove?: boolean; | ||
| defaultActor?: string; | ||
| labels?: ApprovalWorkflowLabels; | ||
| normalizeText?: (value: string) => string; | ||
| } | ||
| export type PIIRedactionType = "email" | "phone" | "ssn" | "credit-card" | "ipv4" | "api-key" | "jwt"; | ||
| export type PIIRedactionSeverity = "high" | "medium" | "low"; | ||
| export type PIIRedactionMode = "token" | "mask"; | ||
| export interface PIIFinding { | ||
| id: string; | ||
| type: PIIRedactionType; | ||
| severity: PIIRedactionSeverity; | ||
| match: string; | ||
| masked: string; | ||
| occurrence: number; | ||
| excerpt?: string; | ||
| suggestion?: string; | ||
| } | ||
| export interface PIIRedactionStats { | ||
| total: number; | ||
| high: number; | ||
| medium: number; | ||
| low: number; | ||
| redactedCount: number; | ||
| byType: Record<PIIRedactionType, number>; | ||
| } | ||
| export interface PIIRedactionLabels { | ||
| panelTitle?: string; | ||
| panelAriaLabel?: string; | ||
| scanText?: string; | ||
| redactAllText?: string; | ||
| redactText?: string; | ||
| locateText?: string; | ||
| realtimeOnText?: string; | ||
| realtimeOffText?: string; | ||
| closeText?: string; | ||
| noFindingsText?: string; | ||
| summaryPrefix?: string; | ||
| shortcutText?: string; | ||
| readonlyRedactionText?: string; | ||
| matchLabel?: string; | ||
| maskedLabel?: string; | ||
| excerptLabel?: string; | ||
| } | ||
| export interface PIIRedactionDetectorConfig { | ||
| enabled?: boolean; | ||
| severity?: PIIRedactionSeverity; | ||
| pattern?: RegExp; | ||
| } | ||
| export interface PIIRedactionPluginOptions { | ||
| enableRealtime?: boolean; | ||
| debounceMs?: number; | ||
| maxFindings?: number; | ||
| maskChar?: string; | ||
| revealStart?: number; | ||
| revealEnd?: number; | ||
| redactionMode?: PIIRedactionMode; | ||
| redactionToken?: string; | ||
| detectors?: Partial<Record<PIIRedactionType, boolean | PIIRedactionDetectorConfig>>; | ||
| labels?: PIIRedactionLabels; | ||
| normalizeText?: (value: string) => string; | ||
| skipInCodeBlocks?: boolean; | ||
| } | ||
| export type SmartPasteProfile = "fidelity" | "balanced" | "plain"; | ||
| export type SmartPasteSource = "word" | "google-docs" | "html" | "plain"; | ||
| export interface SmartPasteLabels { | ||
| panelTitle?: string; | ||
| panelAriaLabel?: string; | ||
| enabledText?: string; | ||
| disabledText?: string; | ||
| toggleOnText?: string; | ||
| toggleOffText?: string; | ||
| cycleProfileText?: string; | ||
| profileLabel?: string; | ||
| fidelityText?: string; | ||
| balancedText?: string; | ||
| plainText?: string; | ||
| lastPasteHeading?: string; | ||
| lastPasteEmptyText?: string; | ||
| lastPasteSourceLabel?: string; | ||
| lastPasteProfileLabel?: string; | ||
| lastPasteRemovedLabel?: string; | ||
| lastPasteCharsLabel?: string; | ||
| closeText?: string; | ||
| shortcutText?: string; | ||
| readonlyMessage?: string; | ||
| } | ||
| export interface SmartPasteProfileOptions { | ||
| keepStyles?: boolean; | ||
| keepClasses?: boolean; | ||
| keepDataAttributes?: boolean; | ||
| preserveTables?: boolean; | ||
| } | ||
| export interface SmartPastePluginOptions { | ||
| enabled?: boolean; | ||
| defaultProfile?: SmartPasteProfile; | ||
| maxHtmlLength?: number; | ||
| removeComments?: boolean; | ||
| normalizeWhitespace?: boolean; | ||
| profileOptions?: Partial<Record<SmartPasteProfile, SmartPasteProfileOptions>>; | ||
| labels?: SmartPasteLabels; | ||
| normalizeText?: (value: string) => string; | ||
| } | ||
| export interface SmartPasteReport { | ||
| source: SmartPasteSource; | ||
| profile: SmartPasteProfile; | ||
| inputHtmlLength: number; | ||
| outputHtmlLength: number; | ||
| outputTextLength: number; | ||
| removedElements: number; | ||
| removedAttributes: number; | ||
| removedComments: number; | ||
| normalizedStyles: number; | ||
| createdAt: string; | ||
| } | ||
| export interface BlocksLibraryItem { | ||
| id: string; | ||
| label: string; | ||
| html: string; | ||
| description?: string; | ||
| category?: string; | ||
| tags?: string[]; | ||
| keywords?: string[]; | ||
| } | ||
| export interface BlocksLibraryItemInput { | ||
| id?: string; | ||
| label: string; | ||
| html: string; | ||
| description?: string; | ||
| category?: string; | ||
| tags?: string[]; | ||
| keywords?: string[]; | ||
| } | ||
| export interface BlocksLibraryLabels { | ||
| panelTitle?: string; | ||
| panelAriaLabel?: string; | ||
| searchLabel?: string; | ||
| searchPlaceholder?: string; | ||
| categoryLabel?: string; | ||
| allCategoriesText?: string; | ||
| recentHeading?: string; | ||
| insertText?: string; | ||
| closeText?: string; | ||
| noResultsText?: string; | ||
| summaryPrefix?: string; | ||
| loadingText?: string; | ||
| loadErrorText?: string; | ||
| readonlyMessage?: string; | ||
| shortcutText?: string; | ||
| helperText?: string; | ||
| lastInsertedPrefix?: string; | ||
| resultsListLabel?: string; | ||
| } | ||
| export interface BlocksLibraryRequestContext { | ||
| editor: HTMLElement; | ||
| editorRoot: HTMLElement; | ||
| signal: AbortSignal; | ||
| } | ||
| export interface BlocksLibraryPluginOptions { | ||
| blocks?: BlocksLibraryItemInput[]; | ||
| defaultCategory?: string; | ||
| maxResults?: number; | ||
| maxRecentBlocks?: number; | ||
| debounceMs?: number; | ||
| cacheTtlMs?: number; | ||
| labels?: BlocksLibraryLabels; | ||
| normalizeText?: (value: string) => string; | ||
| sanitizeBlockHtml?: (html: string, block: BlocksLibraryItemInput) => string; | ||
| getBlocks?: ( | ||
| context: BlocksLibraryRequestContext, | ||
| ) => BlocksLibraryItemInput[] | Promise<BlocksLibraryItemInput[]>; | ||
| } | ||
| export interface BlocksLibraryRuntimeState { | ||
| query: string; | ||
| category: string; | ||
| selectedBlockId: string | null; | ||
| totalMatches: number; | ||
| visibleMatches: number; | ||
| recentBlockIds: string[]; | ||
| lastInsertedBlockId: string | null; | ||
| loading: boolean; | ||
| loadError: string | null; | ||
| } | ||
| export type DocSchemaIssueType = "missing-section" | "duplicate-section" | "out-of-order" | "unknown-heading"; | ||
| export type DocSchemaIssueSeverity = "error" | "warning" | "info"; | ||
| export interface DocSchemaIssue { | ||
| id: string; | ||
| type: DocSchemaIssueType; | ||
| severity: DocSchemaIssueSeverity; | ||
| message: string; | ||
| sectionId?: string; | ||
| sectionTitle?: string; | ||
| headingText?: string; | ||
| suggestion?: string; | ||
| } | ||
| export interface DocSchemaSection { | ||
| id?: string; | ||
| title: string; | ||
| aliases?: string[]; | ||
| minOccurrences?: number; | ||
| maxOccurrences?: number; | ||
| placeholder?: string; | ||
| } | ||
| export interface DocSchemaDefinition { | ||
| id?: string; | ||
| label: string; | ||
| description?: string; | ||
| strictOrder?: boolean; | ||
| allowUnknownHeadings?: boolean; | ||
| sections: DocSchemaSection[]; | ||
| } | ||
| export interface DocSchemaLabels { | ||
| panelTitle?: string; | ||
| panelAriaLabel?: string; | ||
| schemaLabel?: string; | ||
| schemaDescriptionPrefix?: string; | ||
| validateText?: string; | ||
| insertMissingText?: string; | ||
| realtimeOnText?: string; | ||
| realtimeOffText?: string; | ||
| closeText?: string; | ||
| noIssuesText?: string; | ||
| summaryPrefix?: string; | ||
| issueListLabel?: string; | ||
| shortcutText?: string; | ||
| helperText?: string; | ||
| readonlyMessage?: string; | ||
| defaultPlaceholderText?: string; | ||
| missingSectionMessage?: string; | ||
| duplicateSectionMessage?: string; | ||
| outOfOrderMessage?: string; | ||
| unknownHeadingMessage?: string; | ||
| insertedSummaryPrefix?: string; | ||
| } | ||
| export interface DocSchemaPluginOptions { | ||
| schemas?: DocSchemaDefinition[]; | ||
| defaultSchemaId?: string; | ||
| enableRealtime?: boolean; | ||
| debounceMs?: number; | ||
| maxIssues?: number; | ||
| labels?: DocSchemaLabels; | ||
| normalizeText?: (value: string) => string; | ||
| } | ||
| export interface DocSchemaRuntimeState { | ||
| activeSchemaId: string | null; | ||
| activeSchemaLabel: string | null; | ||
| realtimeEnabled: boolean; | ||
| issues: DocSchemaIssue[]; | ||
| headingCount: number; | ||
| recognizedHeadingCount: number; | ||
| missingCount: number; | ||
| lastRunAt: string | null; | ||
| } | ||
| export type TranslationWorkflowIssueType = | ||
| | "missing-target" | ||
| | "token-mismatch" | ||
| | "untranslated" | ||
| | "length-out-of-range"; | ||
| export type TranslationWorkflowIssueSeverity = "error" | "warning" | "info"; | ||
| export interface TranslationWorkflowIssue { | ||
| id: string; | ||
| type: TranslationWorkflowIssueType; | ||
| severity: TranslationWorkflowIssueSeverity; | ||
| message: string; | ||
| segmentId?: string; | ||
| sourceText?: string; | ||
| targetText?: string; | ||
| suggestion?: string; | ||
| } | ||
| export interface TranslationWorkflowSegment { | ||
| id: string; | ||
| tagName: string; | ||
| index: number; | ||
| text: string; | ||
| sourceText: string; | ||
| locked: boolean; | ||
| } | ||
| export interface TranslationWorkflowSegmentState { | ||
| id: string; | ||
| tagName: string; | ||
| index: number; | ||
| sourceLength: number; | ||
| targetLength: number; | ||
| locked: boolean; | ||
| } | ||
| export interface TranslationWorkflowLocaleRule { | ||
| locale: string; | ||
| label?: string; | ||
| minLengthRatio?: number; | ||
| maxLengthRatio?: number; | ||
| requireDifferentFromSource?: boolean; | ||
| preserveTokens?: boolean; | ||
| } | ||
| export interface TranslationWorkflowLabels { | ||
| panelTitle?: string; | ||
| panelAriaLabel?: string; | ||
| sourceLocaleLabel?: string; | ||
| targetLocaleLabel?: string; | ||
| validateText?: string; | ||
| captureSourceText?: string; | ||
| lockSelectedText?: string; | ||
| unlockSelectedText?: string; | ||
| lockSegmentAriaLabel?: string; | ||
| unlockSegmentAriaLabel?: string; | ||
| realtimeOnText?: string; | ||
| realtimeOffText?: string; | ||
| closeText?: string; | ||
| summaryPrefix?: string; | ||
| noIssuesText?: string; | ||
| issuesLabel?: string; | ||
| segmentsLabel?: string; | ||
| sourcePreviewLabel?: string; | ||
| targetPreviewLabel?: string; | ||
| helperText?: string; | ||
| shortcutText?: string; | ||
| readonlySegmentMessage?: string; | ||
| sourceCapturedMessage?: string; | ||
| selectedSegmentPrefix?: string; | ||
| missingTargetMessage?: string; | ||
| tokenMismatchMessage?: string; | ||
| untranslatedMessage?: string; | ||
| lengthOutOfRangeMessage?: string; | ||
| } | ||
| export interface TranslationWorkflowPluginOptions { | ||
| sourceLocale?: string; | ||
| targetLocale?: string; | ||
| locales?: string[]; | ||
| localeRules?: TranslationWorkflowLocaleRule[]; | ||
| enableRealtime?: boolean; | ||
| debounceMs?: number; | ||
| maxIssues?: number; | ||
| maxSegments?: number; | ||
| minSourceLengthForRatio?: number; | ||
| segmentSelector?: string; | ||
| labels?: TranslationWorkflowLabels; | ||
| normalizeText?: (value: string) => string; | ||
| } | ||
| export interface TranslationWorkflowRuntimeState { | ||
| sourceLocale: string; | ||
| targetLocale: string; | ||
| realtimeEnabled: boolean; | ||
| selectedSegmentId: string | null; | ||
| segmentCount: number; | ||
| lockedSegmentCount: number; | ||
| issues: TranslationWorkflowIssue[]; | ||
| segments: TranslationWorkflowSegmentState[]; | ||
| lastRunAt: string | null; | ||
| } | ||
| export interface MentionItem { | ||
| id: string; | ||
| label: string; | ||
| value?: string; | ||
| meta?: string; | ||
| } | ||
| export interface MentionApiRequestContext { | ||
| query: string; | ||
| trigger: string; | ||
| limit: number; | ||
| signal: AbortSignal; | ||
| } | ||
| export interface MentionApiConfig { | ||
| url: string; | ||
| method?: string; | ||
| headers?: Record<string, string> | ((ctx: MentionApiRequestContext) => Record<string, string>); | ||
| credentials?: RequestCredentials; | ||
| mode?: RequestMode; | ||
| cache?: RequestCache; | ||
| queryParam?: string; | ||
| triggerParam?: string; | ||
| limitParam?: string; | ||
| staticParams?: Record<string, string>; | ||
| body?: Record<string, unknown> | BodyInit | ((ctx: MentionApiRequestContext) => Record<string, unknown> | BodyInit | undefined); | ||
| buildRequest?: (ctx: MentionApiRequestContext) => { url: string; init?: RequestInit }; | ||
| responseType?: "json" | "text"; | ||
| responsePath?: string; | ||
| mapItem?: (raw: unknown, index: number) => MentionItem | null; | ||
| transformResponse?: (response: unknown, ctx: MentionApiRequestContext) => MentionItem[]; | ||
| debounceMs?: number; | ||
| timeoutMs?: number; | ||
| onError?: (error: unknown, ctx: MentionApiRequestContext) => void; | ||
| } | ||
| export interface MentionPluginOptions { | ||
| triggerChars?: string[]; | ||
| minChars?: number; | ||
| maxQueryLength?: number; | ||
| maxSuggestions?: number; | ||
| items?: MentionItem[]; | ||
| api?: MentionApiConfig; | ||
| search?: (query: string, trigger: string) => MentionItem[] | Promise<MentionItem[]>; | ||
| itemRenderer?: (item: MentionItem, query: string) => string; | ||
| emptyStateText?: string; | ||
| noResultsText?: string; | ||
| loadingText?: string; | ||
| insertSpaceAfterMention?: boolean; | ||
| } | ||
| export interface SlashCommandActionContext { | ||
| editor: HTMLElement; | ||
| editorRoot: HTMLElement; | ||
| query: string; | ||
| trigger: string; | ||
| executeCommand: (command: string, value?: any) => boolean; | ||
| insertHTML: (html: string) => boolean; | ||
| } | ||
| export interface SlashCommandItem { | ||
| id: string; | ||
| label: string; | ||
| description?: string; | ||
| keywords?: string[]; | ||
| command?: string; | ||
| commandValue?: any; | ||
| insertHTML?: string; | ||
| action?: (context: SlashCommandActionContext) => boolean | void | Promise<boolean | void>; | ||
| } | ||
| export interface SlashCommandsPluginOptions { | ||
| triggerChar?: string; | ||
| minChars?: number; | ||
| maxQueryLength?: number; | ||
| maxSuggestions?: number; | ||
| requireBoundary?: boolean; | ||
| includeDefaultItems?: boolean; | ||
| items?: SlashCommandItem[]; | ||
| itemRenderer?: (item: SlashCommandItem, query: string) => string; | ||
| emptyStateText?: string; | ||
| panelLabel?: string; | ||
| } | ||
| export interface Template { | ||
@@ -81,2 +865,16 @@ id: string; | ||
| export function AnchorPlugin(): Plugin; | ||
| export function MentionPlugin(options?: MentionPluginOptions): Plugin; | ||
| export function TrackChangesPlugin(options?: TrackChangesPluginOptions): Plugin; | ||
| export function VersionDiffPlugin(options?: VersionDiffPluginOptions): Plugin; | ||
| export function ConditionalContentPlugin(options?: ConditionalContentPluginOptions): Plugin; | ||
| export function DataBindingPlugin(options?: DataBindingPluginOptions): Plugin; | ||
| export function ContentRulesPlugin(options?: ContentRulesPluginOptions): Plugin; | ||
| export function CitationsPlugin(options?: CitationsPluginOptions): Plugin; | ||
| export function ApprovalWorkflowPlugin(options?: ApprovalWorkflowPluginOptions): Plugin; | ||
| export function PIIRedactionPlugin(options?: PIIRedactionPluginOptions): Plugin; | ||
| export function SmartPastePlugin(options?: SmartPastePluginOptions): Plugin; | ||
| export function BlocksLibraryPlugin(options?: BlocksLibraryPluginOptions): Plugin; | ||
| export function DocSchemaPlugin(options?: DocSchemaPluginOptions): Plugin; | ||
| export function TranslationWorkflowPlugin(options?: TranslationWorkflowPluginOptions): Plugin; | ||
| export function SlashCommandsPlugin(options?: SlashCommandsPluginOptions): Plugin; | ||
@@ -83,0 +881,0 @@ export function MediaManagerPlugin(): Plugin; |
+104
-5
| { | ||
| "name": "@editora/plugins", | ||
| "version": "1.0.8", | ||
| "version": "1.0.9", | ||
| "description": "40+ Free Premium Plugins for Editora Rich Text Editor. Table editor, code formatting, accessibility, math, media, and more. Free enterprise plugin collection.", | ||
@@ -57,2 +57,8 @@ "author": "Ajay Kumar <ajaykr089@gmail.com>", | ||
| }, | ||
| "./enterprise": { | ||
| "types": "./index.d.ts", | ||
| "import": "./dist/enterprise.esm.js", | ||
| "require": "./dist/enterprise.cjs.js", | ||
| "default": "./dist/enterprise.esm.js" | ||
| }, | ||
| "./shared-config": { | ||
@@ -76,2 +82,20 @@ "types": "./index.d.ts", | ||
| }, | ||
| "./approval-workflow": { | ||
| "types": "./index.d.ts", | ||
| "import": "./dist/approval-workflow.esm.js", | ||
| "require": "./dist/approval-workflow.cjs.js", | ||
| "default": "./dist/approval-workflow.esm.js" | ||
| }, | ||
| "./pii-redaction": { | ||
| "types": "./index.d.ts", | ||
| "import": "./dist/pii-redaction.esm.js", | ||
| "require": "./dist/pii-redaction.cjs.js", | ||
| "default": "./dist/pii-redaction.esm.js" | ||
| }, | ||
| "./smart-paste": { | ||
| "types": "./index.d.ts", | ||
| "import": "./dist/smart-paste.esm.js", | ||
| "require": "./dist/smart-paste.cjs.js", | ||
| "default": "./dist/smart-paste.esm.js" | ||
| }, | ||
| "./background-color": { | ||
@@ -89,2 +113,8 @@ "types": "./index.d.ts", | ||
| }, | ||
| "./blocks-library": { | ||
| "types": "./index.d.ts", | ||
| "import": "./dist/blocks-library.esm.js", | ||
| "require": "./dist/blocks-library.cjs.js", | ||
| "default": "./dist/blocks-library.esm.js" | ||
| }, | ||
| "./bold": { | ||
@@ -102,2 +132,38 @@ "types": "./index.d.ts", | ||
| }, | ||
| "./conditional-content": { | ||
| "types": "./index.d.ts", | ||
| "import": "./dist/conditional-content.esm.js", | ||
| "require": "./dist/conditional-content.cjs.js", | ||
| "default": "./dist/conditional-content.esm.js" | ||
| }, | ||
| "./content-rules": { | ||
| "types": "./index.d.ts", | ||
| "import": "./dist/content-rules.esm.js", | ||
| "require": "./dist/content-rules.cjs.js", | ||
| "default": "./dist/content-rules.esm.js" | ||
| }, | ||
| "./citations": { | ||
| "types": "./index.d.ts", | ||
| "import": "./dist/citations.esm.js", | ||
| "require": "./dist/citations.cjs.js", | ||
| "default": "./dist/citations.esm.js" | ||
| }, | ||
| "./data-binding": { | ||
| "types": "./index.d.ts", | ||
| "import": "./dist/data-binding.esm.js", | ||
| "require": "./dist/data-binding.cjs.js", | ||
| "default": "./dist/data-binding.esm.js" | ||
| }, | ||
| "./doc-schema": { | ||
| "types": "./index.d.ts", | ||
| "import": "./dist/doc-schema.esm.js", | ||
| "require": "./dist/doc-schema.cjs.js", | ||
| "default": "./dist/doc-schema.esm.js" | ||
| }, | ||
| "./translation-workflow": { | ||
| "types": "./index.d.ts", | ||
| "import": "./dist/translation-workflow.esm.js", | ||
| "require": "./dist/translation-workflow.cjs.js", | ||
| "default": "./dist/translation-workflow.esm.js" | ||
| }, | ||
| "./checklist": { | ||
@@ -235,2 +301,8 @@ "types": "./index.d.ts", | ||
| }, | ||
| "./mentions": { | ||
| "types": "./index.d.ts", | ||
| "import": "./dist/mentions.esm.js", | ||
| "require": "./dist/mentions.cjs.js", | ||
| "default": "./dist/mentions.esm.js" | ||
| }, | ||
| "./merge-tag": { | ||
@@ -272,2 +344,8 @@ "types": "./index.d.ts", | ||
| }, | ||
| "./slash-commands": { | ||
| "types": "./index.d.ts", | ||
| "import": "./dist/slash-commands.esm.js", | ||
| "require": "./dist/slash-commands.cjs.js", | ||
| "default": "./dist/slash-commands.esm.js" | ||
| }, | ||
| "./strikethrough": { | ||
@@ -285,2 +363,14 @@ "types": "./index.d.ts", | ||
| }, | ||
| "./track-changes": { | ||
| "types": "./index.d.ts", | ||
| "import": "./dist/track-changes.esm.js", | ||
| "require": "./dist/track-changes.cjs.js", | ||
| "default": "./dist/track-changes.esm.js" | ||
| }, | ||
| "./version-diff": { | ||
| "types": "./index.d.ts", | ||
| "import": "./dist/version-diff.esm.js", | ||
| "require": "./dist/version-diff.cjs.js", | ||
| "default": "./dist/version-diff.esm.js" | ||
| }, | ||
| "./template": { | ||
@@ -321,6 +411,15 @@ "types": "./index.d.ts", | ||
| "build": "vite build", | ||
| "typecheck:build": "tsc -p tsconfig.build.json --noEmit", | ||
| "typecheck:build": "node ../../node_modules/typescript/bin/tsc -p tsconfig.build.json --noEmit", | ||
| "dev": "vite build --watch", | ||
| "clean": "rm -rf dist", | ||
| "prepublishOnly": "npm run typecheck:build && npm run build" | ||
| "prepublishOnly": "npm run typecheck:build && npm run build", | ||
| "test:content-rules": "node ../../node_modules/jest/bin/jest.js -c ./jest.config.cjs --watchman=false --runTestsByPath ./content-rules/src/ContentRulesPlugin.native.test.js", | ||
| "test:citations": "node ../../node_modules/jest/bin/jest.js -c ./jest.config.cjs --watchman=false --runTestsByPath ./citations/src/CitationsPlugin.native.test.js", | ||
| "test:approval-workflow": "node ../../node_modules/jest/bin/jest.js -c ./jest.config.cjs --watchman=false --runTestsByPath ./approval-workflow/src/ApprovalWorkflowPlugin.native.test.js", | ||
| "test:pii-redaction": "node ../../node_modules/jest/bin/jest.js -c ./jest.config.cjs --watchman=false --runTestsByPath ./pii-redaction/src/PIIRedactionPlugin.native.test.js", | ||
| "test:smart-paste": "node ../../node_modules/jest/bin/jest.js -c ./jest.config.cjs --watchman=false --runTestsByPath ./smart-paste/src/SmartPastePlugin.native.test.js", | ||
| "test:blocks-library": "node ../../node_modules/jest/bin/jest.js -c ./jest.config.cjs --watchman=false --runTestsByPath ./blocks-library/src/BlocksLibraryPlugin.native.test.js", | ||
| "test:doc-schema": "node ../../node_modules/jest/bin/jest.js -c ./jest.config.cjs --watchman=false --runTestsByPath ./doc-schema/src/DocSchemaPlugin.native.test.js", | ||
| "test:translation-workflow": "node ../../node_modules/jest/bin/jest.js -c ./jest.config.cjs --watchman=false --runTestsByPath ./translation-workflow/src/TranslationWorkflowPlugin.native.test.js", | ||
| "verify:citations": "npm run typecheck:build && npm run test:citations && npm run test:content-rules && npm run test:approval-workflow && npm run test:pii-redaction && npm run test:smart-paste && npm run test:blocks-library && npm run test:doc-schema && npm run test:translation-workflow && npm run build" | ||
| }, | ||
@@ -335,3 +434,3 @@ "peerDependencies": { | ||
| "devDependencies": { | ||
| "@editora/core": "^1.0.7", | ||
| "@editora/core": "^1.0.8", | ||
| "@types/katex": "^0.16.8", | ||
@@ -344,3 +443,3 @@ "typescript": "^5.0.0", | ||
| }, | ||
| "gitHead": "694494db58b809f0dcf24501696284faa1ab68a5" | ||
| "gitHead": "80e0808ae4909de63b8e0f1dd915b06b33a8ed44" | ||
| } |
+22
-0
@@ -84,2 +84,11 @@ # @editora/plugins | ||
| ### Entry Paths (All Free + Customizable) | ||
| Every plugin entry path is MIT-licensed, free to use, and customizable: | ||
| - `@editora/plugins`: full plugin catalog | ||
| - `@editora/plugins/lite`: common/core plugin subset for lean bundles | ||
| - `@editora/plugins/enterprise`: advanced/specialized workflow plugins | ||
| - `@editora/plugins/<plugin-name>`: targeted per-plugin imports | ||
| ### Recommended Imports For Smaller Bundles | ||
@@ -95,2 +104,5 @@ | ||
| // Enterprise preset entry (advanced/specialized plugins) | ||
| import { MentionPlugin, TrackChangesPlugin, SmartPastePlugin } from '@editora/plugins/enterprise'; | ||
| // Per-plugin subpath entry (most explicit) | ||
@@ -110,2 +122,12 @@ import { BoldPlugin } from '@editora/plugins/bold'; | ||
| ### Enterprise Preset Details | ||
| `@editora/plugins/enterprise` includes advanced plugins for governance, compliance, workflow, and QA: | ||
| - Collaboration/workflow: `TrackChangesPlugin`, `VersionDiffPlugin`, `CommentsPlugin`, `ApprovalWorkflowPlugin` | ||
| - Validation/compliance: `ContentRulesPlugin`, `DocSchemaPlugin`, `A11yCheckerPlugin`, `SpellCheckPlugin`, `PIIRedactionPlugin` | ||
| - Structured/dynamic authoring: `ConditionalContentPlugin`, `DataBindingPlugin`, `MergeTagPlugin`, `TemplatePlugin`, `CitationsPlugin` | ||
| - Productivity/runtime intelligence: `SmartPastePlugin`, `SlashCommandsPlugin`, `MentionPlugin`, `BlocksLibraryPlugin`, `TranslationWorkflowPlugin` | ||
| - Manager-backed advanced plugins: `MediaManagerPlugin`, `DocumentManagerPlugin` | ||
| ### Basic Formatting | ||
@@ -112,0 +134,0 @@ |
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 6 instances in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
5817525
21.38%141
28.18%96259
29.73%697
3.26%81
35%103
27.16%58
5.45%