@lesjoursfr/edith 2.1.2 → 2.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/edith.css +1 -0
- package/build/edith.js +1 -0
- package/dist/core/dom.d.ts +224 -0
- package/dist/core/dom.js +480 -0
- package/dist/core/edit.d.ts +36 -0
- package/dist/core/edit.js +255 -0
- package/dist/core/events.d.ts +47 -0
- package/dist/core/events.js +100 -0
- package/dist/core/history.d.ts +14 -0
- package/dist/core/history.js +24 -0
- package/dist/core/index.d.ts +7 -0
- package/dist/core/index.js +7 -0
- package/dist/core/mode.d.ts +4 -0
- package/dist/core/mode.js +5 -0
- package/dist/core/range.d.ts +45 -0
- package/dist/core/range.js +86 -0
- package/dist/core/throttle.d.ts +53 -0
- package/dist/core/throttle.js +139 -0
- package/dist/css/edith.scss +283 -0
- package/dist/edith-options.d.ts +17 -0
- package/dist/edith-options.js +56 -0
- package/dist/edith.d.ts +30 -0
- package/dist/edith.js +76 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/ui/button.d.ts +25 -0
- package/dist/ui/button.js +165 -0
- package/dist/ui/editor.d.ts +37 -0
- package/dist/ui/editor.js +322 -0
- package/dist/ui/index.d.ts +3 -0
- package/dist/ui/index.js +3 -0
- package/dist/ui/modal.d.ts +32 -0
- package/dist/ui/modal.js +145 -0
- package/package.json +1 -1
package/build/edith.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.edith{border:1px solid #212529;border-radius:.25rem;padding:5px}.edith,.edith-toolbar{background-color:#212529}.edith-btn{background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem;color:#212529;cursor:pointer;display:inline-block;font-size:1rem;font-weight:900;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;user-select:none;vertical-align:middle}.edith-btn:disabled{color:#b7bec5;cursor:not-allowed}.edith-btn-group{display:inline-flex;position:relative;vertical-align:middle}.edith-btn-group:not(:first-child){margin-left:10px}.edith-btn-group :not(:first-child){margin-left:-1px}.edith-btn-group .edith-btn:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.edith-btn-group .edith-btn:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.edith-btn-nbsp:before{content:" ";display:block;height:16px;width:12px}.edith-tooltip{background:#000;border-radius:4px;color:#fff;font-size:13px;font-weight:700;padding:4px 8px;z-index:10}.edith-tooltip .arrow,.edith-tooltip .arrow:before{background:inherit;height:8px;position:absolute;width:8px}.edith-tooltip .arrow{visibility:hidden}.edith-tooltip .arrow:before{content:"";transform:rotate(45deg);visibility:visible}.edith-tooltip[data-popper-placement^=top]>.arrow{bottom:-4px}.edith-tooltip[data-popper-placement^=bottom]>.arrow{top:-4px}.edith-tooltip[data-popper-placement^=left]>.arrow{right:-4px}.edith-tooltip[data-popper-placement^=right]>.arrow{left:-4px}.edith-editing-area{background-color:#fff;border-radius:.25rem;margin-top:5px;padding:5px}.edith-code,.edith-visual{height:100%;outline:none;overflow:auto}.edith-hidden{display:none}.edith-visual{color:#212529}.edith-visual .edith-nbsp{color:#b7bec5}.edith-modal{background:#fff;border:2px solid #ced4da;border-radius:10px;left:calc(50% - 200px);position:fixed;top:20%;width:400px;z-index:10}.edith-modal .edith-modal-header{border-bottom:1px solid #ced4da;color:#000;font-size:20px;font-weight:700;line-height:1.4;padding:5px 10px}.edith-modal .edith-modal-content{color:#212529;margin:10px}.edith-modal .edith-modal-input{display:flex;flex-wrap:wrap;margin:10px 0}.edith-modal .edith-modal-input input,.edith-modal .edith-modal-input label{width:100%}.edith-modal .edith-modal-input input{appearance:none;background-clip:padding-box;background-color:#fff;border:1px solid #bfbfbf;border-radius:.25rem;font-size:1rem;font-weight:400;line-height:1.5;outline:0;padding:.375rem .75rem;width:100%}.edith-modal .edith-modal-input label{font-size:16px;font-weight:700;margin-bottom:5px}.edith-modal .edith-modal-checkbox{margin:10px 0}.edith-modal .edith-modal-checkbox label{display:flex}.edith-modal .edith-modal-checkbox input{appearance:none;background-color:#fff;background-position:50%;background-repeat:no-repeat;background-size:contain;border:1px solid #bfbfbf;border-radius:.25em;height:1em;margin-top:.25em;vertical-align:top;width:1em}.edith-modal .edith-modal-checkbox input:checked{background-color:#0d6efd;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3E%3C/svg%3E");border-color:#0d6efd}.edith-modal .edith-modal-footer{border-top:1px solid #ced4da;display:flex;justify-content:flex-end;padding:5px 10px}.edith-modal .edith-modal-footer :not(:last-child){margin-right:10px}.edith-modal .edith-modal-cancel,.edith-modal .edith-modal-submit{border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-size:1rem;font-weight:400;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;user-select:none;vertical-align:middle}.edith-modal .edith-modal-cancel{background-color:#fff;border-color:#212529;color:#212529}.edith-modal .edith-modal-submit{background-color:#0d6efd;border-color:#0d6efd;color:#fff}
|
package/build/edith.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("CodeMirror"),require("Popper")):"function"==typeof define&&define.amd?define(["CodeMirror","Popper"],e):"object"==typeof exports?exports.Edith=e(require("CodeMirror"),require("Popper")):t.Edith=e(t.CodeMirror,t.Popper)}(self,(function(t,e){return function(){"use strict";var n={704:function(e){e.exports=t},613:function(t){t.exports=e}},i={};function o(t){var e=i[t];if(void 0!==e)return e.exports;var s=i[t]={exports:{}};return n[t](s,s.exports,o),s.exports}o.d=function(t,e){for(var n in e)o.o(e,n)&&!o.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},o.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},o.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var s={};return function(){o.r(s),o.d(s,{Edith:function(){return Q},EdithButton:function(){return B}});function t(t,n){return e(t)&&t.tagName===n.toUpperCase()}function e(t){return t.nodeType===Node.ELEMENT_NODE}function n(t,e){return t.getAttribute(e)}function i(t,e){return"string"==typeof e?t.tagName===e.toUpperCase():e.some((e=>t.tagName===e.toUpperCase()))}function r(t,e){return t.classList.contains(e)}function a(t,{innerHTML:e,textContent:n,attributes:i}={}){const o=document.createElement(t);if(i)for(const t in i)Object.hasOwnProperty.call(i,t)&&o.setAttribute(t,i[t]);return"string"==typeof e?o.innerHTML=e:"string"==typeof n&&(o.textContent=n),o}function l(t,e){return t.replaceWith(e),e}function c(t){const e=[...t.childNodes];return t.replaceWith(...e),e}function d(t){const e=document.createTextNode(t.textContent??"");return t.replaceWith(e),e}function h(t){return["AREA","BASE","BR","COL","EMBED","HR","IMG","INPUT","KEYGEN","LINK","META","PARAM","SOURCE","TRACK","WBR"].includes(t)}function u(t,e){for(const n of[...t.childNodes])e(n)&&n.remove()}function p(t,e){if(e(t))t.remove();else for(const n of[...t.childNodes])p(n,e)}function f(t){u(t,(t=>function(t){return t.nodeType===Node.TEXT_NODE}(t)&&(null===t.textContent||0===t.textContent.trim().length)))}function m(t){u(t,(t=>function(t){return t.nodeType===Node.COMMENT_NODE}(t)))}function b(t,e){for(const n of t.getAttributeNames())void 0===e[n]&&t.removeAttribute(n);for(const n of Object.keys(e))t.setAttribute(n,e[n])}function g(t){const e=t.getAttribute("style")||"";return(i(t,"b")&&e.match(/font-weight\s*:\s*(normal|400);/)||i(t,"i")&&e.match(/font-style\s*:\s*normal;/)||i(t,["u","s"])&&e.match(/text-decoration\s*:\s*none;/))&&(t=l(t,a("span",{attributes:{style:e},innerHTML:t.innerHTML}))),e.match(/font-weight\s*:\s*(bold|700|800|900);/)?t=l(t,a("b",{innerHTML:`<span style="${e.replace(/font-weight\s*:\s*(bold|700|800|900);/,"")}">${t.innerHTML}</span>`})):e.match(/font-style\s*:\s*italic;/)?t=l(t,a("i",{innerHTML:`<span style="${e.replace(/font-style\s*:\s*italic;/,"")}">${t.innerHTML}</span>`})):e.match(/text-decoration\s*:\s*underline;/)?t=l(t,a("u",{innerHTML:`<span style="${e.replace(/text-decoration\s*:\s*underline;/,"")}">${t.innerHTML}</span>`})):e.match(/text-decoration\s*:\s*line-through;/)&&(t=l(t,a("s",{innerHTML:`<span style="${e.replace(/text-decoration\s*:\s*line-through;/,"")}">${t.innerHTML}</span>`}))),t}function v(e,n){const i=e.childNodes;for(;i.length>0&&t(i[0],n);)i[0].remove();for(;i.length>0&&t(i[i.length-1],n);)i[i.length-1].remove()}function y(t,e){for(let n of[...t.children]){if(i(n,"span")&&r(n,"edith-nbsp")){b(n,{class:"edith-nbsp",contenteditable:"false"}),n.innerHTML="¶";continue}n.hasAttribute("style")&&(n=g(n)),e[n.tagName]&&(n=l(n,a("span",{attributes:{style:n.getAttribute("style")||""},innerHTML:n.innerHTML})));const t={...e};if(i(n,["b","i","q","u","s"])&&(t[n.tagName]=!0),y(n,t),i(n,"a")){const t={};n.hasAttribute("href")&&(t.href=n.getAttribute("href")),n.hasAttribute("target")&&(t.target=n.getAttribute("target")),b(n,t)}else if(i(n,["b","i","q","u","s","br","sup"]))b(n,{});else if(i(n,["style","meta","link"]))n.remove();else if(i(n,"p")){if(null===n.textContent||0===n.textContent.trim().length){n.remove();continue}b(n,{}),v(n,"br")}else c(n)}}function E(){const t=window.getSelection();return{sel:t,range:t.rangeCount?t.getRangeAt(0):void 0}}function w(t){const e=document.createRange(),n=window.getSelection();e.setStart(t,1),e.collapse(!0),n.removeAllRanges(),n.addRange(e)}function C(t){const e=document.createRange(),n=window.getSelection();e.setStartAfter(t),e.collapse(!0),n.removeAllRanges(),n.addRange(e)}function x(t){if(1===t.length&&e(t[0])&&h(t[0].tagName))return void C(t[0]);const n=document.createRange(),i=window.getSelection();n.setStartBefore(t[0]),n.setEndAfter(t[t.length-1]),i.removeAllRanges(),i.addRange(n)}function T(t){const{range:e}=E();return void 0!==e&&(t.contains(e.startContainer)&&t.contains(e.endContainer))}function k(t,e){const n=e.parentNode,i=t.cloneRange();i.setStart(n,0);const o=i.extractContents(),s=document.createTextNode("");return o.append(s),n.prepend(o),w(s),s}function N(t,n){const i=n.parentNode,o=new Range;o.selectNodeContents(i),o.setEnd(t.startContainer,t.startOffset);const s=new Range;s.selectNodeContents(i),s.setStart(t.endContainer,t.endOffset);const r=o.extractContents(),a=s.extractContents();i.prepend(r),i.append(a);let l=e(t.commonAncestorContainer)?t.commonAncestorContainer:t.commonAncestorContainer.parentNode;for(;l.tagName!==n.tagName;)l=l.parentNode;const d=c(l);return x(d),d[0].parentNode}function M(t,n={}){const{sel:o,range:s}=E();if(void 0===s)return;if(s.collapsed){let e=o.anchorNode.parentNode;for(;!r(e,"edith-visual");){if(i(e,t))return k(s,e);e=e.parentNode}return function(t,e,n={}){const i=document.createElement(e);return"a"===e?i.textContent=n.textContent||"lien":i.innerHTML="",t.insertNode(i),"a"===e&&i.insertAdjacentText("afterend"," "),w(i),i}(s,t,n)}let a=s.commonAncestorContainer;for(;!e(a)||!r(a,"edith-visual");){if(e(a)&&i(a,t))return N(s,a);a=a.parentNode}for(const e of[...a.getElementsByTagName(t)])if(o.containsNode(e,!0)){return x(c(e)),a.normalize(),a}const l=document.createElement(t);return l.appendChild(s.extractContents()),s.insertNode(l),u(a,(t=>e(t)&&!h(t.tagName)&&(null===t.textContent||0===t.textContent.length))),function(t){const e=document.createRange(),n=window.getSelection();e.selectNodeContents(t),e.collapse(!1),n.removeAllRanges(),n.addRange(e)}(l),l}function A(t,e){const n=document.createElement("div");return n.innerHTML=t,y(n,e),n.normalize(),f(n),n.innerHTML=n.innerHTML.replace(/\s* \s*/g," ").replace(/\s+/g," ").replace(/(<\/b>[\n\r\s]*<b>|<\/i>[\n\r\s]*<i>|<\/u>[\n\r\s]*<u>|<\/s>[\n\r\s]*<s>)/g," "),m(n),n}const L="edithEvents";let S=0;var H,O;function R(t){const[e,...n]=t.split(".");return{type:e,ns:n??null}}function D(t,e,n){void 0===t[L]&&(t[L]={});for(const i of e.split(" ")){const{type:e,ns:o}=R(i),s=(++S).toString(10);t.addEventListener(e,n),t[L][s]={type:e,ns:o,handler:n}}}function I(t,e,n){void 0===t[L]&&(t[L]={});for(const i of e.split(" ")){const{type:e,ns:o}=R(i);for(const[i,s]of Object.entries(t[L]))s.type!==e&&"*"!==e||null!==o&&!s.ns?.includes(o[0])||void 0!==n&&("function"!=typeof n||n!==s.handler)||(delete t[L][i],t.removeEventListener(s.type,s.handler))}}!function(t){t.modeChanged="edith-mode-changed",t.initialized="edith-initialized"}(H||(H={}));class V{buffer=[];constructor(){}push(t){this.buffer.push(t),this.buffer.length>20&&this.buffer.shift()}pop(){return 0===this.buffer.length?null:this.buffer.pop()}}function z(t,e,n={}){let i,o,s,r,a,l=0;const c=!!n.leading,d="maxWait"in n,h=d?Math.max(n.maxWait||0,e):void 0,u=!("trailing"in n)||!!n.trailing;function p(e){const n=i,r=o;return i=o=void 0,l=e,s=t.apply(r,n),s}function f(t,e){return setTimeout(t,e)}function m(t){const n=t-a;return void 0===a||n>=e||n<0||d&&t-l>=h}function b(){const t=Date.now();if(m(t))return function(t){if(r=void 0,u&&i)return p(t);return i=o=void 0,s}(t);r=f(b,function(t){const n=t-l,i=e-(t-a);return d?Math.min(i,h-n):i}(t))}return function(...t){const n=Date.now(),h=m(n);if(i=t,o=this,a=n,h){if(void 0===r)return function(t){return l=t,r=f(b,e),c?p(t):s}(a);if(d)return r=f(b,e),p(a)}return void 0===r&&(r=f(b,e)),s}}!function(t){t[t.Visual=1]="Visual",t[t.Code=2]="Code"}(O||(O={}));const P={height:80,resizable:!1,toolbar:[["style",["bold","italic","underline","strikethrough"]]],buttons:{},initialContent:""};var j=o(613);class B{el;ctx;icon;title;onclick;showOnCodeView;popperEl;popper;constructor(t,e){this.ctx=t,this.icon=e.icon,this.title=e.title,this.onclick=e.onclick,this.showOnCodeView=!0===e.showOnCodeView}click(t){t.preventDefault(),this.onclick(this.ctx,t)}showTooltip(){if(void 0!==this.popper)return;this.popperEl=a("div",{textContent:this.title,attributes:{class:"edith-tooltip"}});const t=a("div",{attributes:{class:"arrow","data-popper-arrow":""}});this.popperEl.append(t),this.ctx.toolbar.append(this.popperEl),this.popper=(0,j.createPopper)(this.el,this.popperEl,{placement:"bottom",modifiers:[{name:"arrow",options:{padding:5}},{name:"offset",options:{offset:[0,8]}}]})}hideTooltip(){void 0!==this.popper&&(this.popper.destroy(),this.popper=void 0,this.popperEl?.remove())}onEditorModeChange(t){t.detail.mode===O.Code?this.el.setAttribute("disabled","disabled"):this.el.removeAttribute("disabled")}render(){return this.el=a("button",{attributes:{class:`edith-btn ${this.icon}`,type:"button"}}),this.el.onclick=this.click.bind(this),this.el.onmouseenter=this.showTooltip.bind(this),this.el.onmouseleave=this.hideTooltip.bind(this),!0!==this.showOnCodeView&&this.ctx.on(H.modeChanged,this.onEditorModeChange.bind(this)),this.el}}const $=Object.freeze({bold:t=>new B(t,{icon:"fa-solid fa-bold",title:"Gras",onclick:t=>{t.editor.wrapInsideTag("b")}}),italic:t=>new B(t,{icon:"fa-solid fa-italic",title:"Italique",onclick:t=>{t.editor.wrapInsideTag("i")}}),underline:t=>new B(t,{icon:"fa-solid fa-underline",title:"Souligner",onclick:t=>{t.editor.wrapInsideTag("u")}}),strikethrough:t=>new B(t,{icon:"fa-solid fa-strikethrough",title:"Barrer",onclick:t=>{t.editor.wrapInsideTag("s")}}),subscript:t=>new B(t,{icon:"fa-solid fa-subscript",title:"Indice",onclick:t=>{t.editor.wrapInsideTag("sub")}}),superscript:t=>new B(t,{icon:"fa-solid fa-superscript",title:"Exposant",onclick:t=>{t.editor.wrapInsideTag("sup")}}),nbsp:t=>new B(t,{icon:"edith-btn-nbsp",title:"Ajouter une espace insécable",onclick:t=>{t.editor.replaceByHtml('<span class="edith-nbsp" contenteditable="false">¶</span>')}}),clear:t=>new B(t,{icon:"fa-solid fa-eraser",title:"Effacer la mise en forme",onclick:t=>{t.editor.clearStyle()}}),link:t=>new B(t,{icon:"fa-solid fa-link",title:"Lien",onclick:t=>{t.editor.insertLink()}}),codeview:t=>new B(t,{icon:"fa-solid fa-code",title:"Afficher le code HTML",onclick:t=>{t.editor.toggleCodeView()},showOnCodeView:!0})});var q,K=o(704);function W(t){const e=document.createElement("div");e.setAttribute("class","edith-modal-input");const n=document.createElement("label");n.textContent=t.label;const i=document.createElement("input");return i.setAttribute("name",t.name),i.setAttribute("type","text"),null!==t.initialState&&(i.value=t.initialState.toString()),e.append(n),e.append(i),e}function _(t){const e=document.createElement("div");e.setAttribute("class","edith-modal-checkbox");const n=document.createElement("label");n.textContent=t.label;const i=document.createElement("input");return i.setAttribute("name",t.name),i.setAttribute("type","checkbox"),t.initialState&&(i.checked=!0),n.prepend(i),e.append(n),e}function U(t,e,n=null){return{fieldType:q.input,label:t,name:e,initialState:n}}function F(t,e,n=!1){return{fieldType:q.checkbox,label:t,name:e,initialState:n}}!function(t){t[t.input=1]="input",t[t.checkbox=2]="checkbox"}(q||(q={}));class G{el;ctx;title;fields;callback;constructor(t,e){this.ctx=t,this.title=e.title,this.fields=e.fields||[],this.callback=e.callback}cancel(t){t.preventDefault(),this.callback(null),this.close()}submit(t){t.preventDefault();const e={};for(const t of this.el.querySelectorAll("input"))i="name",t.hasAttribute(i)&&(e[n(t,"name")]="checkbox"===n(t,"type")?t.checked:t.value);var i;this.callback(e),this.close()}close(){this.el.remove()}show(){this.el=a("div",{attributes:{class:"edith-modal"}});const t=a("div",{attributes:{class:"edith-modal-header"}}),e=a("span",{textContent:this.title,attributes:{class:"edith-modal-title"}});t.append(e);const n=a("div",{attributes:{class:"edith-modal-content"}});for(const t of this.fields)switch(t.fieldType){case q.input:n.append(W(t));break;case q.checkbox:n.append(_(t));break;default:throw new Error(`Unknown fieldType ${t.fieldType}`)}const i=a("div",{attributes:{class:"edith-modal-footer"}}),o=a("button",{textContent:"Annuler",attributes:{class:"edith-modal-cancel",type:"button"}});i.append(o);const s=a("button",{textContent:"Valider",attributes:{class:"edith-modal-submit",type:"button"}});return i.append(s),this.el.append(t),this.el.append(n),this.el.append(i),this.ctx.modals.append(this.el),o.onclick=this.cancel.bind(this),s.onclick=this.submit.bind(this),this.el}}class J{el;ctx;content;height;resizable;mode;visualEditor;codeEditor;codeMirror;history;throttledSnapshots;constructor(t,e){this.ctx=t,this.content=e.initialContent,this.height=e.height,this.resizable=e.resizable,this.mode=O.Visual,this.history=new V,this.throttledSnapshots=function(t,e,n={}){return z(t,e,{leading:!("leading"in n)||!!n.leading,trailing:!("trailing"in n)||!!n.trailing,maxWait:e})}((()=>this.takeSnapshot()),3e3,{leading:!1,trailing:!0}),this.content=this.content.replace(/ /g,'<span class="edith-nbsp" contenteditable="false">¶</span>')}render(){this.el=a("div",{attributes:{class:"edith-editing-area",style:this.resizable?`min-height: ${this.height}px; resize: vertical`:`height: ${this.height}px`}}),this.visualEditor=a("div",{innerHTML:this.content,attributes:{class:"edith-visual",contenteditable:"true",style:this.resizable?`min-height: ${this.height-10}px`:`height: ${this.height-10}px`}}),this.el.append(this.visualEditor),this.codeEditor=a("div",{attributes:{class:"edith-code edith-hidden"}}),this.el.append(this.codeEditor);const t=this.onKeyEvent.bind(this);this.visualEditor.addEventListener("keydown",t),this.visualEditor.addEventListener("keyup",t);const e=this.onPasteEvent.bind(this);return this.visualEditor.addEventListener("paste",e),this.el}getVisualEditorElement(){return this.visualEditor}getCodeEditorElement(){return this.codeEditor}setContent(t){t=t.replace(/ /g,'<span class="edith-nbsp" contenteditable="false">¶</span>'),this.mode===O.Visual?this.visualEditor.innerHTML=t:this.codeMirror.dispatch({changes:{from:0,to:this.codeMirror.state.doc.length,insert:t}})}getContent(){const t=this.mode===O.Visual?this.visualEditor.innerHTML:this.codeMirror.state.doc.toJSON().map((t=>t.trim())).join("\n");if("<p><br></p>"===t)return"";const n=a("div",{innerHTML:t});p(n,(t=>e(t)&&!h(t.tagName)&&(null===t.textContent||0===t.textContent.length)));for(const t of n.querySelectorAll("[style]"))t.removeAttribute("style");for(const t of n.querySelectorAll("span"))0===t.attributes.length&&c(t);return n.innerHTML.replace(/\u200B/gi,"").replace(/<\/p>\s*<p>/gi,"<br>").replace(/(<p>|<\/p>)/gi,"").replace(/<span[^>]+class="edith-nbsp"[^>]*>[^<]*<\/span>/gi," ").replace(/(?:<br\s?\/?>)+$/gi,"")}takeSnapshot(){this.history.push(this.visualEditor.innerHTML)}restoreSnapshot(){this.visualEditor.innerHTML=this.history.pop()??""}wrapInsideTag(t){T(this.visualEditor)&&(M(t),this.takeSnapshot())}replaceByHtml(t){T(this.visualEditor)&&(!function(t){const{sel:e,range:n}=E();if(void 0===n)return;const i=document.createDocumentFragment(),o=a("div",{innerHTML:t});i.append(...o.childNodes);const s=i.childNodes[i.childNodes.length-1];e.deleteFromDocument(),n.insertNode(i),C(s)}(t),this.takeSnapshot())}clearStyle(){!function(){const{sel:t,range:n}=E();if(void 0!==n&&e(n.commonAncestorContainer))for(const e of[...n.commonAncestorContainer.children])t.containsNode(e,!0)&&d(e)}(),this.takeSnapshot()}insertLink(){const{sel:t,range:n}=E();if(void 0===n)return;const i=new G(this.ctx,{title:"Insérer un lien",fields:[U("Texte à afficher","text",n.toString()),U("URL du lien","href"),F("Ouvrir dans une nouvelle fenêtre","openInNewTab",!0)],callback:i=>{null!==i&&(function(t){const e=window.getSelection();e.removeAllRanges(),void 0!==t.range&&e.addRange(t.range)}({sel:t,range:n}),function(t,n,i){const o=M("a",{textContent:t});if(void 0!==o)e(o)&&(o.setAttribute("href",n),!0===i&&o.setAttribute("target","_blank"))}(i.text,i.href,i.openInNewTab))}});i.show()}toggleCodeView(){if(this.mode===O.Visual){this.mode=O.Code,this.visualEditor.classList.add("edith-hidden"),this.codeEditor.classList.remove("edith-hidden");const t=document.createElement("div");this.codeEditor.append(t),this.codeMirror=new K.EditorView({doc:this.visualEditor.innerHTML,extensions:[K.basicSetup,K.EditorView.lineWrapping,(0,K.html)({matchClosingTags:!0,autoCloseTags:!0})],parent:t})}else this.mode=O.Visual,this.codeEditor.classList.add("edith-hidden"),this.visualEditor.classList.remove("edith-hidden"),this.visualEditor.innerHTML=this.codeMirror.state.doc.toJSON().map((t=>t.trim())).join("\n"),this.codeMirror.destroy(),this.codeMirror=void 0,this.codeEditor.innerHTML="";this.ctx.trigger(H.modeChanged,{mode:this.mode})}onKeyEvent(t){(t.metaKey||t.ctrlKey?this._processKeyEventWithMeta(t):this._processKeyEvent(t))&&(t.preventDefault(),t.stopPropagation())}_processKeyEvent(t){return 13===t.keyCode?("keydown"===t.type&&this.replaceByHtml("<br />"),!0):(this.throttledSnapshots(),!1)}_processKeyEventWithMeta(t){switch(t.keyCode){case 13:return"keydown"===t.type&&this.replaceByHtml("<br />"),!0;case 32:return"keydown"===t.type&&this.replaceByHtml('<span class="edith-nbsp" contenteditable="false">¶</span>'),!0;case 66:return"keydown"===t.type&&this.wrapInsideTag("b"),!0;case 73:return"keydown"===t.type&&this.wrapInsideTag("i"),!0;case 85:return"keydown"===t.type&&this.wrapInsideTag("u"),!0;case 83:return"keydown"===t.type&&this.wrapInsideTag("s"),!0;case 90:return"keydown"===t.type&&this.restoreSnapshot(),!0}return!1}onPasteEvent(t){t.preventDefault(),t.stopPropagation();const{sel:e,range:n}=E();if(void 0===n||null===t.clipboardData)return;const o=document.createDocumentFragment();if(t.clipboardData.types.includes("text/html")){let n=e.anchorNode;const s={B:!1,I:!1,U:!1,S:!1,Q:!1};for(;null!==n&&!r(n,"edith-visual");)i(n,["b","i","u","s","q"])&&(s[(n.tagName,"Q")]=!0),n=n.parentNode;let a=t.clipboardData.getData("text/html").replace(/[\r\n]+/g," ");/^<html>\s*<body>/.test(a)||(a="<html><body>"+a+"</body></html>");const l=A(a,s);o.append(...l.childNodes)}else{const e=t.clipboardData.getData("text/plain").split(/[\r\n]+/g);for(let t=0;t<e.length;t++)0!==t&&o.append(document.createElement("br")),o.append(document.createTextNode(e[t]))}e.deleteFromDocument(),n.insertNode(o)}destroy(){this.codeMirror?.destroy(),this.codeMirror=void 0,this.el.remove()}}class Q{element;toolbar;editor;modals;constructor(t,e){var n,i;this.element=t,n=this.element,"string"==typeof(i="edith")?n.classList.add(i):n.classList.add(...i),this.toolbar=a("div",{attributes:{class:"edith-toolbar"}}),this.element.append(this.toolbar);const o=e.buttons??P.buttons,s=e.toolbar??P.toolbar;for(const{0:t,1:e}of s){const n=document.createElement("div");n.setAttribute("id",t),n.setAttribute("class","edith-btn-group"),this.toolbar.append(n);for(const t of e){const e=o[t]??$[t];n.append(e(this).render())}}this.editor=new J(this,{initialContent:e.initialContent??P.initialContent,height:e.height??P.height,resizable:e.resizable??P.resizable}),this.element.append(this.editor.render()),this.modals=a("div",{attributes:{class:"edith-modals"}}),this.element.append(this.modals),this.element.edith=this,this.trigger(H.initialized)}on(t,e){!function(t,e,n){if(t instanceof NodeList)for(const i of t)D(i,e,n);else D(t,e,n)}(this.element,t,e)}off(t,e){!function(t,e,n){if(t instanceof NodeList)for(const i of t)I(i,e,n);else I(t,e,n)}(this.element,t,e)}trigger(t,e){!function(t,e,n){t.dispatchEvent(new CustomEvent(e,{detail:n}))}(this.element,t,e)}setContent(t){this.editor.setContent(t)}getContent(){return this.editor.getContent()}destroy(){var t,e;t=this.element,"string"==typeof(e="edith")?t.classList.remove(e):t.classList.remove(...e),this.modals.remove(),this.editor.destroy(),this.toolbar.remove(),this.element.remove()}}}(),s}()}));
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
type EdithData = {
|
|
2
|
+
[key: string]: string | null;
|
|
3
|
+
};
|
|
4
|
+
declare global {
|
|
5
|
+
interface Document {
|
|
6
|
+
edithData: EdithData;
|
|
7
|
+
}
|
|
8
|
+
interface HTMLElement {
|
|
9
|
+
edithData: EdithData;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Check if a node is an HTML Element.
|
|
14
|
+
* @param {Node} node the node to test
|
|
15
|
+
* @returns {boolean} true if the node is an HTMLElement
|
|
16
|
+
*/
|
|
17
|
+
export declare function isCommentNode(node: Node): node is Comment;
|
|
18
|
+
/**
|
|
19
|
+
* Check if a node is an HTML Element.
|
|
20
|
+
* @param {Node} node the node to test
|
|
21
|
+
* @returns {boolean} true if the node is an HTMLElement
|
|
22
|
+
*/
|
|
23
|
+
export declare function isTextNode(node: Node): node is Text;
|
|
24
|
+
/**
|
|
25
|
+
* Check if a node is an HTML Element.
|
|
26
|
+
* @param {Node} node the node to test
|
|
27
|
+
* @returns {boolean} true if the node is an HTMLElement
|
|
28
|
+
*/
|
|
29
|
+
export declare function isHTMLElement(node: Node): node is HTMLElement;
|
|
30
|
+
/**
|
|
31
|
+
* Create an HTMLElement from the HTML template.
|
|
32
|
+
* @param {string} template the HTML template
|
|
33
|
+
* @returns {HTMLElement} the created HTMLElement
|
|
34
|
+
*/
|
|
35
|
+
export declare function createFromTemplate(template: string): HTMLElement;
|
|
36
|
+
/**
|
|
37
|
+
* Update the given CSS property.
|
|
38
|
+
* If the value is `null` the property will be removed.
|
|
39
|
+
* @param {HTMLElement} node the node to update
|
|
40
|
+
* @param {string|{ [key: string]: string|null }} property multi-word property names are hyphenated (kebab-case) and not camel-cased.
|
|
41
|
+
* @param {string|null} value (default to `null`)
|
|
42
|
+
* @returns {HTMLElement} the element
|
|
43
|
+
*/
|
|
44
|
+
export declare function updateCSS(node: HTMLElement, property: string | {
|
|
45
|
+
[key: string]: string | null;
|
|
46
|
+
}, value?: string | null): HTMLElement;
|
|
47
|
+
/**
|
|
48
|
+
* Check if the node has the given attribute.
|
|
49
|
+
* @param {HTMLElement} node
|
|
50
|
+
* @param {string} attribute
|
|
51
|
+
* @returns {boolean} true or false
|
|
52
|
+
*/
|
|
53
|
+
export declare function hasAttribute(node: HTMLElement, attribute: string): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Get the given attribute.
|
|
56
|
+
* @param {HTMLElement} node
|
|
57
|
+
* @param {string} attribute
|
|
58
|
+
* @returns {string|null} the value
|
|
59
|
+
*/
|
|
60
|
+
export declare function getAttribute(node: HTMLElement, attribute: string): string | null;
|
|
61
|
+
/**
|
|
62
|
+
* Set the given attribute.
|
|
63
|
+
* If the value is `null` the attribute will be removed.
|
|
64
|
+
* @param {HTMLElement} node
|
|
65
|
+
* @param {string} attribute
|
|
66
|
+
* @param {string|null} value
|
|
67
|
+
* @returns {HTMLElement} the element
|
|
68
|
+
*/
|
|
69
|
+
export declare function setAttribute(node: HTMLElement, attribute: string, value: string | null): HTMLElement;
|
|
70
|
+
/**
|
|
71
|
+
* Get the given data.
|
|
72
|
+
* This function does not change the DOM.
|
|
73
|
+
* If there is no key this function return all data
|
|
74
|
+
* @param {HTMLElement} node
|
|
75
|
+
* @param {string|undefined} key
|
|
76
|
+
* @returns {EdithData|string|null} the value
|
|
77
|
+
*/
|
|
78
|
+
export declare function getData(node: HTMLElement, key?: string): EdithData | string | null;
|
|
79
|
+
/**
|
|
80
|
+
* Set the given data.
|
|
81
|
+
* If the value is `null` the data will be removed.
|
|
82
|
+
* This function does not change the DOM.
|
|
83
|
+
* @param {HTMLElement} node
|
|
84
|
+
* @param {string} key
|
|
85
|
+
* @param {string|null} value
|
|
86
|
+
* @returns {HTMLElement} the element
|
|
87
|
+
*/
|
|
88
|
+
export declare function setData(node: HTMLElement, key: string, value: string | null): HTMLElement;
|
|
89
|
+
/**
|
|
90
|
+
* Check if the node has the given tag name, or if its tag name is in the given list.
|
|
91
|
+
* @param {HTMLElement} node the element to check
|
|
92
|
+
* @param {string|Array<string>} tags a tag name or a list of tag name
|
|
93
|
+
* @returns {boolean} true if the node has the given tag name
|
|
94
|
+
*/
|
|
95
|
+
export declare function hasTagName(node: HTMLElement, tags: string | Array<string>): boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Check if the node has the given class name.
|
|
98
|
+
* @param {HTMLElement} node the element to check
|
|
99
|
+
* @param {string} className a class name
|
|
100
|
+
* @returns {boolean} true if the node has the given class name
|
|
101
|
+
*/
|
|
102
|
+
export declare function hasClass(node: HTMLElement, className: string): boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Add the class to the node's class attribute.
|
|
105
|
+
* @param {HTMLElement} node
|
|
106
|
+
* @param {string|Array<string>} className
|
|
107
|
+
* @returns {HTMLElement} the element
|
|
108
|
+
*/
|
|
109
|
+
export declare function addClass(node: HTMLElement, className: string | Array<string>): HTMLElement;
|
|
110
|
+
/**
|
|
111
|
+
* Remove the class from the node's class attribute.
|
|
112
|
+
* @param {HTMLElement} node
|
|
113
|
+
* @param {string|Array<string>} className
|
|
114
|
+
* @returns {HTMLElement} the element
|
|
115
|
+
*/
|
|
116
|
+
export declare function removeClass(node: HTMLElement, className: string | Array<string>): HTMLElement;
|
|
117
|
+
/**
|
|
118
|
+
* Test if the node match the given selector.
|
|
119
|
+
* @param {HTMLElement} node
|
|
120
|
+
* @param {string} selector
|
|
121
|
+
* @returns {boolean} true or false
|
|
122
|
+
*/
|
|
123
|
+
export declare function is(node: HTMLElement, selector: string): boolean;
|
|
124
|
+
/**
|
|
125
|
+
* Get the node's offset.
|
|
126
|
+
* @param {HTMLElement} node
|
|
127
|
+
* @returns {{ top: number, left: number }} The node's offset
|
|
128
|
+
*/
|
|
129
|
+
export declare function offset(node: HTMLElement): {
|
|
130
|
+
top: number;
|
|
131
|
+
left: number;
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* Create a new node.
|
|
135
|
+
* @param {string} tag the tag name of the node
|
|
136
|
+
* @param {object} options optional parameters
|
|
137
|
+
* @param {string} options.innerHTML the HTML code of the node
|
|
138
|
+
* @param {string} options.textContent the text content of the node
|
|
139
|
+
* @param {object} options.attributes attributes of the node
|
|
140
|
+
* @returns {HTMLElement} the created node
|
|
141
|
+
*/
|
|
142
|
+
export declare function createNodeWith<K extends keyof HTMLElementTagNameMap>(tag: K, { innerHTML, textContent, attributes, }?: {
|
|
143
|
+
innerHTML?: string;
|
|
144
|
+
textContent?: string;
|
|
145
|
+
attributes?: {
|
|
146
|
+
[keyof: string]: string;
|
|
147
|
+
};
|
|
148
|
+
}): HTMLElementTagNameMap[K];
|
|
149
|
+
/**
|
|
150
|
+
* Replace a node.
|
|
151
|
+
* @param {HTMLElement} node the node to replace
|
|
152
|
+
* @param {HTMLElement} replacement the new node
|
|
153
|
+
* @returns {HTMLElement} the new node
|
|
154
|
+
*/
|
|
155
|
+
export declare function replaceNodeWith(node: HTMLElement, replacement: HTMLElement): HTMLElement;
|
|
156
|
+
/**
|
|
157
|
+
* Replace the node by its child nodes.
|
|
158
|
+
* @param {HTMLElement} node the node to replace
|
|
159
|
+
* @returns {Array<ChildNode>} its child nodes
|
|
160
|
+
*/
|
|
161
|
+
export declare function unwrapNode(node: HTMLElement): ChildNode[];
|
|
162
|
+
/**
|
|
163
|
+
* Replace the node by its text content.
|
|
164
|
+
* @param {HTMLElement} node the node to replace
|
|
165
|
+
* @returns {Text} the created Text node
|
|
166
|
+
*/
|
|
167
|
+
export declare function textifyNode(node: HTMLElement): Text;
|
|
168
|
+
/**
|
|
169
|
+
* Know if a tag si a self-closing tag
|
|
170
|
+
* @param {string} tagName
|
|
171
|
+
* @returns {boolean}
|
|
172
|
+
*/
|
|
173
|
+
export declare function isSelfClosing(tagName: string): boolean;
|
|
174
|
+
/**
|
|
175
|
+
* Remove all node's child nodes that pass the test implemented by the provided function.
|
|
176
|
+
* @param {ChildNode} node the node to process
|
|
177
|
+
* @param {Function} callbackFn the predicate
|
|
178
|
+
*/
|
|
179
|
+
export declare function removeNodes(node: ChildNode, callbackFn: (node: ChildNode) => boolean): void;
|
|
180
|
+
/**
|
|
181
|
+
* Remove recursively all node's child nodes that pass the test implemented by the provided function.
|
|
182
|
+
* @param {ChildNode} node the node to process
|
|
183
|
+
* @param {Function} callbackFn the predicate
|
|
184
|
+
*/
|
|
185
|
+
export declare function removeNodesRecursively(node: ChildNode, callbackFn: (node: ChildNode) => boolean): void;
|
|
186
|
+
/**
|
|
187
|
+
* Remove all node's child nodes that are empty text nodes.
|
|
188
|
+
* @param {ChildNode} node the node to process
|
|
189
|
+
*/
|
|
190
|
+
export declare function removeEmptyTextNodes(node: ChildNode): void;
|
|
191
|
+
/**
|
|
192
|
+
* Remove all node's child nodes that are comment nodes.
|
|
193
|
+
* @param {ChildNode} node the node to process
|
|
194
|
+
*/
|
|
195
|
+
export declare function removeCommentNodes(node: ChildNode): void;
|
|
196
|
+
/**
|
|
197
|
+
* Reset all node's attributes to the given list.
|
|
198
|
+
* @param {HTMLElement} node the node
|
|
199
|
+
* @param {object} targetAttributes the requested node's attributes
|
|
200
|
+
*/
|
|
201
|
+
export declare function resetAttributesTo(node: HTMLElement, targetAttributes: {
|
|
202
|
+
[keyof: string]: string;
|
|
203
|
+
}): void;
|
|
204
|
+
/**
|
|
205
|
+
* Replace the node's style attribute by some regular nodes (<b>, <i>, <u> or <s>).
|
|
206
|
+
* @param {HTMLElement} node the node to process
|
|
207
|
+
* @returns {HTMLElement} the new node
|
|
208
|
+
*/
|
|
209
|
+
export declare function replaceNodeStyleByTag(node: HTMLElement): HTMLElement;
|
|
210
|
+
/**
|
|
211
|
+
* Remove all leading & trailing node's child nodes that match the given tag.
|
|
212
|
+
* @param {HTMLElement} node the node to process
|
|
213
|
+
* @param {string} tag the tag
|
|
214
|
+
*/
|
|
215
|
+
export declare function trimTag(node: HTMLElement, tag: string): void;
|
|
216
|
+
/**
|
|
217
|
+
* Clean the DOM content of the node
|
|
218
|
+
* @param {HTMLElement} root the node to process
|
|
219
|
+
* @param {object} style active styles for the root
|
|
220
|
+
*/
|
|
221
|
+
export declare function cleanDomContent(root: HTMLElement, style: {
|
|
222
|
+
[keyof: string]: boolean;
|
|
223
|
+
}): void;
|
|
224
|
+
export {};
|