8889841cjs/inline-editor.min.js000064400000042367150513064500011055 0ustar00(function(a,b){function c(a,c){var d=" to exec \u300C"+a+"\u300D command"+(c?" with value: "+c:"");try{b.execCommand(a,!1,c)}catch(a){return P.log("fail"+d,!0)}P.log("success"+d)}function d(a,b,d){var e=B(a);if(e)return a._range.selectNode(e),a._range.collapse(!1),"insertimage"===b&&a._menu&&L(a._menu,!0),c(b,d)}function e(a,b){var d=C(a),e=d.map(function(a){return a.nodeName.toLowerCase()});return-1!==e.indexOf(b)&&(b="p"),c("formatblock",b)}function f(a,b,d){return d="<"+b+">"+(d||O.toString())+"",c("insertHTML",d)}function g(a,b,d){return a.config.linksInNewWindow&&"unlink"!==b?(d=""+O.toString()+"",c("insertHTML",d)):c(b,d)}function h(a,b,c,d){var e=a.config.titles[b]||"",f=document.createElement("div");f.classList.add("pen-icon"),f.setAttribute("title",e),"parent"===c?(f.classList.add("pen-group-icon"),f.setAttribute("data-group-toggle",b)):f.setAttribute("data-action",b),"child"===c&&f.setAttribute("data-group",d);var g=a.config.toolbarIconsDictionary[b];if(g&&g.text)f.textContent=g.text;else{var h;h=g&&g.className?g.className:a.config.toolbarIconsPrefix+b,f.innerHTML+=""}return f.outerHTML}function i(a){return Q.call(a._menu.children)}function j(a,b){var c=i(a);c.forEach(function(a){L(a,a.getAttribute("data-group")!==b)}),o(a,!b),a.refreshMenuPosition()}function k(a){j(a,null),m(a,!0),n(a,!a._urlInput||""===a._urlInput.value)}function l(a){var b=i(a);b.forEach(function(a){L(a,!0)}),m(a),o(a)}function m(a,b){var c=a._menu.querySelector(".pen-input-wrapper");c&&L(c,b)}function n(a,b){var c=a._menu.querySelector("[data-action=\"unlink\"]");c&&(L(c,b),a.refreshMenuPosition())}function o(a,b){var c=a._menu.querySelector("[data-action=\"close\"]");L(c,b),a.refreshMenuPosition()}function p(a){var c=b.createElement("div"),d=b.createElement("input"),e=b.createElement("label"),f=b.createElement("input"),g=b.createElement("i");return c.className="pen-input-wrapper",d.className="pen-url-input",d.type="url",d.placeholder="http://",e.className="pen-icon pen-input-label",f.className="pen-external-url-checkbox",f.type="checkbox",g.className=a.config.toolbarIconsDictionary.externalLink.className,e.appendChild(f),e.appendChild(g),c.appendChild(d),c.appendChild(e),c}function q(a,b,c){a.execCommand(b,c),a._range=a.getRange(),a.highlight().menu()}function r(a,b){for(var c,d=a._toolbar||a._menu;!(c=b.getAttribute("data-action"))&&b.parentNode!==d;)b=b.parentNode;var e=b.getAttribute("data-group-toggle");if(e&&j(a,e),!!c){if("close"===c)return void k(a);if(!/(?:createlink)|(?:insertimage)/.test(c))return q(a,c);if(a._urlInput){var f=a._urlInput;if(d===a._menu?l(a):(a._inputActive=!0,a.menu()),"none"!==a._menu.style.display){setTimeout(function(){f.focus()},10);var g=function(){var b=f.value;b?(a.config.linksInNewWindow=a._externalUrlCheckbox.checked,b=f.value.replace(U.whiteSpace,"").replace(U.mailTo,"mailto:$1").replace(U.http,"http://$1")):c="unlink",q(a,c,b)};f.onkeypress=function(a){13===a.which&&(a.preventDefault(),g())},a._externalUrlCheckbox.onchange=g}}}}function s(a){var c="",d=p(a).outerHTML;if(a._toolbar=a.config.toolbar,!a._toolbar){var e=a.config.list;if(!Object.values(e).length)return;P.forEach(e,function(b,d){if(Array.isArray(b)){var e=b;b=d,c+=h(a,b,"parent"),P.forEach(e,function(d){c+=h(a,d,"child",b)},!0)}else c+=h(a,b)});var f=Object.values(e);(0<=f.indexOf("createlink")||0<=f.indexOf("insertimage"))&&(c+=d),c+=h(a,"close")}else(a._toolbar.querySelectorAll("[data-action=createlink]").length||a._toolbar.querySelectorAll("[data-action=insertimage]").length)&&(c+=d);c&&(a._menu=b.createElement("div"),a._menu.setAttribute("class",a.config.class+"-menu pen-menu"),a._menu.innerHTML=c,a._urlInput=a._menu.querySelector(".pen-url-input"),a._externalUrlCheckbox=a._menu.querySelector(".pen-external-url-checkbox"),L(a._menu,!0),b.body.appendChild(a._menu))}function t(d){function f(a){d._range=d.getRange(),i(a)}var g=d._toolbar||d._menu,h=d.config.editor,i=P.delayExec(function(){g&&d.highlight().menu()}),j=function(){};if(d._menu){var k=function(){"flex"===d._menu.style.display&&d.menu()};u(d,a,"resize",k),u(d,a,"scroll",k);var l=!1;u(d,h,"mousedown",function(){l=!0}),u(d,h,"mouseleave",function(){l&&f(800),l=!1}),u(d,h,"mouseup",function(){l&&f(200),l=!1}),j=function(a){!d._menu||A(h,a.target)||A(d._menu,a.target)||(w(d,b,"click",j),i(100))}}else u(d,h,"click",function(){f(0)});u(d,h,"keyup",function(a){if(y(d),d.isEmpty())return void("advanced"===d.config.mode&&E(d));if(G(d)&&!H(d)&&"advanced"!==d.config.mode&&(h.innerHTML=h.innerHTML.replace(/\u200b/,""),F(d)),13!==a.which||a.shiftKey)return f(400);var c=B(d,!0);c&&c.nextSibling&&S.test(c.nodeName)&&c.nodeName===c.nextSibling.nodeName&&("BR"!==c.lastChild.nodeName&&c.appendChild(b.createElement("br")),P.forEach(c.nextSibling.childNodes,function(a){a&&c.appendChild(a)},!0),c.parentNode.removeChild(c.nextSibling),I(d,c.lastChild,d.getRange()))}),u(d,h,"keydown",function(a){if(h.classList.remove(d.config.placeholderClass),!(13!==a.which||a.shiftKey)){if(d.config.ignoreLineBreak)return void a.preventDefault();var e=B(d,!0);if(!e||!S.test(e.nodeName))return void("basic"===d.config.mode&&(a.preventDefault(),c("insertHTML","
")));if(e){var f=e.lastChild;if(f&&f.previousSibling&&!(f.previousSibling.textContent||f.textContent)){a.preventDefault();var g=b.createElement("p");g.innerHTML="
",e.removeChild(f),e.nextSibling?e.parentNode.insertBefore(g,e.nextSibling):e.parentNode.appendChild(g),I(d,g,d.getRange())}}}}),g&&u(d,g,"click",function(a){r(d,a.target)}),u(d,h,"focus",function(){d.isEmpty()&&"advanced"===d.config.mode&&E(d),u(d,b,"click",j)}),u(d,h,"blur",function(){y(d),d.checkContentChange()}),u(d,h,"paste",function(){setTimeout(function(){d.cleanContent()})})}function u(a,b,c,d){if(a._events.hasOwnProperty(c))a._events[c].push(d);else{a._eventTargets=a._eventTargets||[],a._eventsCache=a._eventsCache||[];var e=a._eventTargets.indexOf(b);0>e&&(e=a._eventTargets.push(b)-1),a._eventsCache[e]=a._eventsCache[e]||{},a._eventsCache[e][c]=a._eventsCache[e][c]||[],a._eventsCache[e][c].push(d),b.addEventListener(c,d,!1)}return a}function v(a,b){if(a._events.hasOwnProperty(b)){var c=Q.call(arguments,2);P.forEach(a._events[b],function(b){b.apply(a,c)})}}function w(a,b,c,d){var e=a._events[c];if(!e){var f=a._eventTargets.indexOf(b);0<=f&&(e=a._eventsCache[f][c])}if(!e)return a;var g=e.indexOf(d);return 0<=g&&e.splice(g,1),b.removeEventListener(c,d,!1),a}function x(a){return(P.forEach(this._events,function(a){a.length=0},!1),!a._eventsCache)?a:(P.forEach(a._eventsCache,function(b,c){var d=a._eventTargets[c];P.forEach(b,function(a,b){P.forEach(a,function(a){d.removeEventListener(b,a,!1)},!0)},!1)},!0),a._eventTargets=[],a._eventsCache=[],a)}function y(a){a.config.editor.classList[a.isEmpty()?"add":"remove"](a.config.placeholderClass)}function z(a){return(a||"").trim().replace(/\u200b/g,"")}function A(a,b){if(a===b)return!0;for(b=b.parentNode;b;){if(b===a)return!0;b=b.parentNode}return!1}function B(a,b){var c,d=a.config.editor;if(a._range=a._range||a.getRange(),c=a._range.commonAncestorContainer,c.hasChildNodes()&&a._range.startOffset+1===a._range.endOffset&&(c=c.childNodes[a._range.startOffset]),!c||c===d)return null;for(;c&&1!==c.nodeType&&c.parentNode!==d;)c=c.parentNode;for(;c&&b&&c.parentNode!==d;)c=c.parentNode;return A(d,c)?c:null}function C(a){return D(a).filter(function(a){return a.nodeName.match(T)})}function D(a){for(var b=[],c=B(a);c&&c!==a.config.editor;)c.nodeType===Node.ELEMENT_NODE&&b.push(c),c=c.parentNode;return b}function E(a){var c=a._range=a.getRange();a.config.editor.innerHTML="";var d=b.createElement("p");d.innerHTML="
",c.insertNode(d),I(a,d.childNodes[0],c)}function F(a){var c=a.getRange(),d=b.createTextNode("\u200B");c.selectNodeContents(a.config.editor),c.collapse(!1),c.insertNode(d),I(a,d,c)}function G(a){var b=a.getRange(),c=b.cloneRange();return c.selectNodeContents(a.config.editor),c.setStart(b.endContainer,b.endOffset),""===c.toString()}function H(a){var b=a.getRange(),c=b.cloneRange();return c.selectNodeContents(a.config.editor),c.setEnd(b.startContainer,b.startOffset),""===c.toString()}function I(a,b,c){c.setStartAfter(b),c.setEndBefore(b),c.collapse(!1),a.setRange(c)}function J(a){if(1===a.nodeType){if(V.notLink.test(a.tagName))return;P.forEach(a.childNodes,function(a){J(a)},!0)}else if(3===a.nodeType){var c=K(a.nodeValue||"");if(!c.links)return;var d=b.createDocumentFragment(),e=b.createElement("div");for(e.innerHTML=c.text;e.childNodes.length;)d.appendChild(e.childNodes[0]);a.parentNode.replaceChild(d,a)}}function K(a){var b=0;return a=a.replace(V.url,function(a){var c=a,d=a;return b++,a.length>V.maxLength&&(d=a.slice(0,V.maxLength)+"..."),V.prefix.test(c)||(c="http://"+c),""+d+""}),{links:b,text:a}}function L(a,b){a.style.display=b?"none":"flex"}var M,N,O,P={},Q=Array.prototype.slice,R={block:/^(?:p|h[1-6]|blockquote|pre)$/,inline:/^(?:justify(center|full|left|right)|strikethrough|insert(un)?orderedlist|(in|out)dent)$/,biu:/^(bold|italic|underline)$/,source:/^(?:createlink|unlink)$/,insert:/^(?:inserthorizontalrule|insertimage|insert)$/,wrap:/^(?:code)$/},S=/^(?:blockquote|pre|div)$/i,T=/(?:[pubia]|strong|em|h[1-6]|blockquote|code|[uo]l|li)/i,U={whiteSpace:/(^\s+)|(\s+$)/g,mailTo:/^(?!mailto:|.+\/|.+#|.+\?)(.*@.*\..+)$/,http:/^(?!\w+?:\/\/|mailto:|\/|\.\/|\?|#)(.*)$/},V={url:/((https?|ftp):\/\/|www\.)[^\s<]{3,}/gi,prefix:/^(?:https?|ftp):\/\//i,notLink:/^(?:img|a|input|audio|video|source|code|pre|script|head|title|style)$/i,maxLength:100},W={bold:{styleKey:"font-weight",correctValue:"normal"},italic:{styleKey:"font-style",correctValue:"normal"},underline:{styleKey:"text-decoration",correctValue:"none"}};P.is=function(a,b){return Object.prototype.toString.call(a).slice(8,-1)===b},P.forEach=function(a,b,c){if(a)if(null==c&&(c=P.is(a,"Array")),c)for(var d=0,e=a.length;d",list:["blockquote","h2","h3","p","code","insertOrderedList","insertUnorderedList","inserthorizontalrule","indent","outdent","bold","italic","underline","createlink","insertimage"],titles:{},cleanAttrs:["id","class","style","name"],cleanTags:["script"],linksInNewWindow:!1};return 1===a.nodeType?c.editor=a:a.match&&a.match(/^#[\S]+$/)?c.editor=b.getElementById(a.slice(1)):c=P.copy(c,a),c},M=function(a){if(!a)throw new Error("Can't find config");N=a.debug;var b=P.merge(a),c=b.editor;if(!c||1!==c.nodeType)throw new Error("Can't find editor");c.classList.add.apply(c.classList,b.class.split(" ")),c.setAttribute("contenteditable","true"),this.config=b,b.placeholder&&c.setAttribute(this.config.placeholderAttr,b.placeholder),y(this),this.selection=O,this._events={change:[]},s(this),t(this),this._prevContent=this.getContent(),this.markdown&&this.markdown.init(this),this.config.stay&&this.stay(this.config),this.config.input&&this.addOnSubmitListener(this.config.input),"advanced"===this.config.mode?(this.getRange().selectNodeContents(c),this.setRange()):F(this)},M.prototype.on=function(a,b){return u(this,this.config.editor,a,b),this},M.prototype.addOnSubmitListener=function(a){var b=a.form,c=this;b.addEventListener("submit",function(){a.value=c.config.saveAsMarkdown?c.toMd(c.config.editor.innerHTML):c.config.editor.innerHTML})},M.prototype.isEmpty=function(a){return a=a||this.config.editor,!a.querySelector("img")&&!a.querySelector("blockquote")&&!a.querySelector("li")&&!z(a.textContent)},M.prototype.getContent=function(){return this.isEmpty()?"":z(this.config.editor.innerHTML)},M.prototype.setContent=function(a){return this.config.editor.innerHTML=a,this.cleanContent(),this},M.prototype.checkContentChange=function(){var a=this._prevContent,b=this.getContent();a===b||(this._prevContent=b,v(this,"change",b,a))},M.prototype.getRange=function(){var a=this.config.editor,c=O.rangeCount&&O.getRangeAt(0);return c||(c=b.createRange()),A(a,c.commonAncestorContainer)||(c.selectNodeContents(a),c.collapse(!1)),c},M.prototype.setRange=function(a){a=a||this._range,a||(a=this.getRange(),a.collapse(!1));try{O.removeAllRanges(),O.addRange(a)}catch(a){}return this},M.prototype.focus=function(a){return a||this.setRange(),this.config.editor.focus(),this},M.prototype.execCommand=function(a,b){if(a=a.toLowerCase(),this.setRange(),R.block.test(a))e(this,a);else if(R.inline.test(a))c(a,b);else if(R.biu.test(a)){var h=W[a];h.backupValue=this.config.editor.style[h.styleKey],this.config.editor.style[h.styleKey]=h.correctValue,c(a,b),this.config.editor.style[h.styleKey]=h.backupValue}else R.source.test(a)?g(this,a,b):R.insert.test(a)?d(this,a,b):R.wrap.test(a)?f(this,a,b):P.log("can not find command function for name: "+a+(b?", value: "+b:""),!0);"indent"===a&&this.checkContentChange()},M.prototype.cleanContent=function(a){var b=this.config.editor;return a||(a=this.config),P.forEach(a.cleanAttrs,function(a){P.forEach(b.querySelectorAll("["+a+"]"),function(b){b.removeAttribute(a)},!0)},!0),P.forEach(a.cleanTags,function(a){P.forEach(b.querySelectorAll(a),function(a){a.parentNode.removeChild(a)},!0)},!0),y(this),this.checkContentChange(),this},M.prototype.autoLink=function(){return J(this.config.editor),this.getContent()},M.prototype.highlight=function(){var a=this._toolbar||this._menu,b=B(this);if(P.forEach(a.querySelectorAll(".active"),function(a){a.classList.remove("active")},!0),!b)return this;var c,d=D(this),e=this._urlInput,f=this._externalUrlCheckbox;return e&&a===this._menu&&(e.value="",this._externalUrlCheckbox.checked=!1),c=function(b){if(b){var c=a.querySelector("[data-action="+b+"]");return c&&c.classList.add("active")}},P.forEach(d,function(a){var b=a.nodeName.toLowerCase(),d=a.style.textAlign,g=a.style.textDecoration;(d&&("justify"===d&&(d="full"),c("justify"+d[0].toUpperCase()+d.slice(1))),"underline"===g&&c("underline"),!!b.match(T))&&("a"===b?(e.value=a.getAttribute("href"),f.checked="_blank"===a.getAttribute("target"),b="createlink"):"img"===b?(e.value=a.getAttribute("src"),b="insertimage"):"i"===b||"em"===b?b="italic":"u"===b?b="underline":"b"===b||"strong"===b?b="bold":"strike"===b?b="strikethrough":"ul"===b?b="insertUnorderedList":"ol"===b?b="insertOrderedList":"li"===b?b="indent":void 0,c(b))},!0),this},M.prototype.menu=function(){return this._menu?O.isCollapsed?(this._menu.style.display="none",this._inputActive=!1,this):!this._toolbar||this._urlInput&&this._inputActive?void k(this):this:this},M.prototype.refreshMenuPosition=function(){var a=this._range.getBoundingClientRect(),b=a.top-10,c=a.left+a.width/2,d=this._menu,e={x:0,y:0},f=this._stylesheet;if(0===a.width&&0===a.height)return this;if(void 0===this._stylesheet){var g=document.createElement("style");document.head.appendChild(g),this._stylesheet=f=g.sheet}return d.style.display="flex",e.x=c-d.clientWidth/2,e.y=b-d.clientHeight,0e.x?(e.x=0,f.insertRule(".pen-menu:after {left: "+c+"px;}",0)):f.insertRule(".pen-menu:after {left: 50%; }",0),0>e.y?(d.classList.add("pen-menu-below"),e.y=a.top+a.height+10):d.classList.remove("pen-menu-below"),d.style.top=e.y+"px",d.style.left=e.x+"px",this},M.prototype.stay=function(a){var b=this;window.onbeforeunload||(window.onbeforeunload=function(){if(!b._isDestroyed)return a.stayMsg})},M.prototype.destroy=function(){var a=this.config;x(this),a.editor.classList.remove.apply(a.editor.classList,a.class.split(" ").concat(a.placeholderClass)),a.editor.removeAttribute("contenteditable"),a.editor.removeAttribute(a.placeholderAttr);try{O.removeAllRanges(),this._menu&&this._menu.parentNode.removeChild(this._menu)}catch(a){}return this._isDestroyed=!0,this},M.prototype.rebuild=function(){return s(this),t(this),this},a.ElementorInlineEditor=function(a){if(!a)return P.log("can't find config",!0);var b=P.merge(a),c=b.editor.getAttribute("class");return c=c?c.replace(/\bpen\b/g,"")+" pen-textarea "+b.class:"pen pen-textarea",b.editor.setAttribute("class",c),b.editor.innerHTML=b.textarea,b.editor};var X={a:[/]*href=["']([^"]+|[^']+)\b[^>]*>(.*?)<\/a>/ig,"[$2]($1)"],img:[/]*src=["']([^\"+|[^']+)[^>]*>/ig,"![]($1)"],b:[/]*>(.*?)<\/b>/ig,"**$1**"],i:[/]*>(.*?)<\/i>/ig,"***$1***"],h:[/]*>(.*?)<\/h\1>/ig,function(d,a,b){return"\n"+"######".slice(0,a)+" "+b+"\n"}],li:[/<(li)\b[^>]*>(.*?)<\/\1>/ig,"* $2\n"],blockquote:[/<(blockquote)\b[^>]*>(.*?)<\/\1>/ig,"\n> $2\n"],pre:[/]*>(.*?)<\/pre>/ig,"\n```\n$1\n```\n"],code:[/]*>(.*?)<\/code>/ig,"\n`\n$1\n`\n"],p:[/]*>(.*?)<\/p>/ig,"\n$1\n"],hr:[/]*>/ig,"\n---\n"]};M.prototype.toMd=function(){var a=this.getContent().replace(/\n+/g,"").replace(/<([uo])l\b[^>]*>(.*?)<\/\1l>/ig,"$2");for(var b in X)X.hasOwnProperty(b)&&(a=a.replace.apply(a,X[b]));return a.replace(/\*{5}/g,"**")},b.getSelection&&(O=b.getSelection(),a.ElementorInlineEditor=M)})(window,document);js/inline-editor.js000064400000076772150513064500010302 0ustar00/** * Licensed under MIT, https://github.com/sofish/pen * * Customized and fixed by Elementor team */ (function(root, doc) { var InlineEditor, debugMode, selection, utils = {}; var slice = Array.prototype.slice; // allow command list var commandsReg = { block: /^(?:p|h[1-6]|blockquote|pre)$/, inline: /^(?:justify(center|full|left|right)|strikethrough|insert(un)?orderedlist|(in|out)dent)$/, biu: /^(bold|italic|underline)$/, source: /^(?:createlink|unlink)$/, insert: /^(?:inserthorizontalrule|insertimage|insert)$/, wrap: /^(?:code)$/ }; var lineBreakReg = /^(?:blockquote|pre|div)$/i, effectNodeReg = /(?:[pubia]|strong|em|h[1-6]|blockquote|code|[uo]l|li)/i; var strReg = { whiteSpace: /(^\s+)|(\s+$)/g, mailTo: /^(?!mailto:|.+\/|.+#|.+\?)(.*@.*\..+)$/, http: /^(?!\w+?:\/\/|mailto:|\/|\.\/|\?|#)(.*)$/ }; var autoLinkReg = { url: /((https?|ftp):\/\/|www\.)[^\s<]{3,}/gi, prefix: /^(?:https?|ftp):\/\//i, notLink: /^(?:img|a|input|audio|video|source|code|pre|script|head|title|style)$/i, maxLength: 100 }; var styleBackupDict = { bold: { styleKey: 'font-weight', correctValue: 'normal' }, italic: { styleKey: 'font-style', correctValue: 'normal' }, underline: { styleKey: 'text-decoration', correctValue: 'none' } }; // type detect utils.is = function(obj, type) { return Object.prototype.toString.call(obj).slice(8, -1) === type; }; utils.forEach = function(obj, iterator, arrayLike) { if (!obj) return; if (arrayLike == null) arrayLike = utils.is(obj, 'Array'); if (arrayLike) { for (var i = 0, l = obj.length; i < l; i++) iterator(obj[i], i, obj); } else { for (var key in obj) { if (obj.hasOwnProperty(key)) iterator(obj[key], key, obj); } } }; // copy props from a obj utils.copy = function(defaults, source) { utils.forEach(source, function (value, key) { defaults[key] = utils.is(value, 'Object') ? utils.copy({}, value) : utils.is(value, 'Array') ? utils.copy([], value) : value; }); return defaults; }; // log utils.log = function(message, force) { if (debugMode || force) console.log('%cPEN DEBUGGER: %c' + message, 'font-family:arial,sans-serif;color:#1abf89;line-height:2em;', 'font-family:cursor,monospace;color:#333;'); }; utils.delayExec = function (fn) { var timer = null; return function (delay) { clearTimeout(timer); timer = setTimeout(function() { fn(); }, delay || 1); }; }; // merge: make it easy to have a fallback utils.merge = function(config) { // default settings var defaults = { class: 'pen', placeholderClass: 'pen-placeholder', placeholderAttr: 'data-pen-placeholder', debug: false, toolbar: null, // custom toolbar mode: 'basic', ignoreLineBreak: false, toolbarIconsPrefix: 'fa fa-', toolbarIconsDictionary: {externalLink: 'eicon-editor-external-link'}, stay: config.stay || !config.debug, stayMsg: 'Are you going to leave here?', textarea: '', list: [ 'blockquote', 'h2', 'h3', 'p', 'code', 'insertOrderedList', 'insertUnorderedList', 'inserthorizontalrule', 'indent', 'outdent', 'bold', 'italic', 'underline', 'createlink', 'insertimage' ], titles: {}, cleanAttrs: ['id', 'class', 'style', 'name'], cleanTags: ['script'], linksInNewWindow: false }; // user-friendly config if (config.nodeType === 1) { defaults.editor = config; } else if (config.match && config.match(/^#[\S]+$/)) { defaults.editor = doc.getElementById(config.slice(1)); } else { defaults = utils.copy(defaults, config); } return defaults; }; function commandOverall(cmd, val) { var message = ' to exec 「' + cmd + '」 command' + (val ? (' with value: ' + val) : ''); try { doc.execCommand(cmd, false, val); } catch(err) { // TODO: there's an error when insert a image to document, but not a bug return utils.log('fail' + message, true); } utils.log('success' + message); } function commandInsert(ctx, name, val) { var node = getNode(ctx); if (!node) return; ctx._range.selectNode(node); ctx._range.collapse(false); // hide menu when a image was inserted if(name === 'insertimage' && ctx._menu) toggleNode(ctx._menu, true); return commandOverall(name, val); } function commandBlock(ctx, name) { var effectNodes = getEffectNodes(ctx), tagsList = effectNodes.map(function(node) { return node.nodeName.toLowerCase(); }); if (tagsList.indexOf(name) !== -1) name = 'p'; return commandOverall('formatblock', name); } function commandWrap(ctx, tag, value) { value = '<' + tag + '>' + (value||selection.toString()) + ''; return commandOverall('insertHTML', value); } function commandLink(ctx, tag, value) { if (ctx.config.linksInNewWindow && 'unlink' !== tag) { value = '' + (selection.toString()) + ''; return commandOverall('insertHTML', value); } else { return commandOverall(tag, value); } } function createTool(ctx, name, type, group) { var title = ctx.config.titles[name] || '', iconElement = document.createElement( 'div' ); iconElement.classList.add('pen-icon'); iconElement.setAttribute('title', title); if ('parent' === type) { iconElement.classList.add('pen-group-icon'); iconElement.setAttribute('data-group-toggle', name); } else { iconElement.setAttribute('data-action', name); } if('child' === type) { iconElement.setAttribute('data-group', group); } var iconDictionary = ctx.config.toolbarIconsDictionary[ name ]; if ( iconDictionary && iconDictionary.text ) { iconElement.textContent = iconDictionary.text; } else { var iconClass; if ( iconDictionary && iconDictionary.className ) { iconClass = iconDictionary.className; } else { iconClass = ctx.config.toolbarIconsPrefix + name; } iconElement.innerHTML += ''; } return iconElement.outerHTML; } function getMenuTools(ctx) { return slice.call(ctx._menu.children); } function activateGroup(ctx, group) { var tools = getMenuTools(ctx); tools.forEach(function(tool) { toggleNode(tool, tool.getAttribute('data-group') !== group); }); toggleMenuClose(ctx, ! group); ctx.refreshMenuPosition(); } function showMainMenu(ctx) { activateGroup(ctx, null); toggleLinkInput(ctx, true); toggleUnlinkTool(ctx, !ctx._urlInput || ctx._urlInput.value === ''); } function showLinkInput(ctx) { var tools = getMenuTools(ctx); tools.forEach(function(tool) { toggleNode(tool, true); }); toggleLinkInput(ctx); toggleMenuClose(ctx); } function toggleLinkInput(ctx, hide) { var linkInput = ctx._menu.querySelector('.pen-input-wrapper'); if (! linkInput) { return; } toggleNode(linkInput, hide); } function toggleUnlinkTool(ctx, hide) { var unlinkTool = ctx._menu.querySelector('[data-action="unlink"]'); if (! unlinkTool) { return; } toggleNode(unlinkTool, hide); ctx.refreshMenuPosition(); } function toggleMenuClose(ctx, hide) { var closeButton = ctx._menu.querySelector('[data-action="close"]'); toggleNode(closeButton, hide); ctx.refreshMenuPosition(); } function createLinkInput(ctx) { var inputWrapper = doc.createElement('div'), urlInput = doc.createElement('input'), newWindowLabel = doc.createElement('label'), newWindowCheckbox = doc.createElement('input'), newWindowIcon = doc.createElement('i'); inputWrapper.className = 'pen-input-wrapper'; urlInput.className = 'pen-url-input'; urlInput.type = 'url'; urlInput.placeholder = 'http://'; newWindowLabel.className = 'pen-icon pen-input-label'; newWindowCheckbox.className = 'pen-external-url-checkbox'; newWindowCheckbox.type = 'checkbox'; newWindowIcon.className = ctx.config.toolbarIconsDictionary.externalLink.className; newWindowLabel.appendChild(newWindowCheckbox); newWindowLabel.appendChild(newWindowIcon); inputWrapper.appendChild(urlInput); inputWrapper.appendChild(newWindowLabel); return inputWrapper; } function menuApply(ctx, action, value) { ctx.execCommand(action, value); ctx._range = ctx.getRange(); ctx.highlight().menu(); } function onToolbarClick(ctx, target) { var toolbar = ctx._toolbar || ctx._menu, action; while (!(action = target.getAttribute('data-action'))) { if (target.parentNode === toolbar) { break; } target = target.parentNode; } var groupToggle = target.getAttribute('data-group-toggle'); if (groupToggle) { activateGroup(ctx, groupToggle); } if (!action) return; if ('close' === action) { showMainMenu(ctx); return; } if (!/(?:createlink)|(?:insertimage)/.test(action)) return menuApply(ctx, action); if (!ctx._urlInput) return; // create link var input = ctx._urlInput; if (toolbar === ctx._menu) showLinkInput(ctx); else { ctx._inputActive = true; ctx.menu(); } if (ctx._menu.style.display === 'none') return; setTimeout(function() { input.focus(); }, 10); var createLink = function() { var inputValue = input.value; if (inputValue) { ctx.config.linksInNewWindow = ctx._externalUrlCheckbox.checked; inputValue = input.value .replace(strReg.whiteSpace, '') .replace(strReg.mailTo, 'mailto:$1') .replace(strReg.http, 'http://$1'); } else { action = 'unlink'; } menuApply(ctx, action, inputValue); }; input.onkeypress = function(e) { if (e.which === 13) { e.preventDefault(); createLink() } }; ctx._externalUrlCheckbox.onchange = createLink; } function initToolbar(ctx) { var icons = '', inputStr = createLinkInput(ctx).outerHTML; ctx._toolbar = ctx.config.toolbar; if (!ctx._toolbar) { var toolList = ctx.config.list; if (! Object.values(toolList).length) { return; } utils.forEach(toolList, function (name, key) { if (Array.isArray(name)) { var children = name; name = key; icons += createTool(ctx, name, 'parent'); utils.forEach(children, function(childName) { icons += createTool(ctx, childName, 'child', name); }, true); } else { icons += createTool(ctx, name); } }); var toolListValues = Object.values(toolList); if (toolListValues.indexOf('createlink') >= 0 || toolListValues.indexOf('insertimage') >= 0) icons += inputStr; icons += createTool(ctx, 'close'); } else if (ctx._toolbar.querySelectorAll('[data-action=createlink]').length || ctx._toolbar.querySelectorAll('[data-action=insertimage]').length) { icons += inputStr; } if (icons) { ctx._menu = doc.createElement('div'); ctx._menu.setAttribute('class', ctx.config.class + '-menu pen-menu'); ctx._menu.innerHTML = icons; ctx._urlInput = ctx._menu.querySelector('.pen-url-input'); ctx._externalUrlCheckbox = ctx._menu.querySelector('.pen-external-url-checkbox'); toggleNode(ctx._menu, true); doc.body.appendChild(ctx._menu); } } function initEvents(ctx) { var toolbar = ctx._toolbar || ctx._menu, editor = ctx.config.editor; var toggleMenu = utils.delayExec(function() { if (toolbar) { ctx.highlight().menu(); } }); var outsideClick = function() {}; function updateStatus(delay) { ctx._range = ctx.getRange(); toggleMenu(delay); } if (ctx._menu) { var setpos = function() { if (ctx._menu.style.display === 'flex') ctx.menu(); }; // change menu offset when window resize / scroll addListener(ctx, root, 'resize', setpos); addListener(ctx, root, 'scroll', setpos); // toggle toolbar on mouse select var selecting = false; addListener(ctx, editor, 'mousedown', function() { selecting = true; }); addListener(ctx, editor, 'mouseleave', function() { if (selecting) updateStatus(800); selecting = false; }); addListener(ctx, editor, 'mouseup', function() { if (selecting) updateStatus(200); selecting = false; }); // Hide menu when focusing outside of editor outsideClick = function(e) { if (ctx._menu && !containsNode(editor, e.target) && !containsNode(ctx._menu, e.target)) { removeListener(ctx, doc, 'click', outsideClick); toggleMenu(100); } }; } else { addListener(ctx, editor, 'click', function() { updateStatus(0); }); } addListener(ctx, editor, 'keyup', function(e) { checkPlaceholder(ctx); if (ctx.isEmpty()) { if (ctx.config.mode === 'advanced') { handleEmptyContent(ctx); } return; } if (isCaretAtEnd(ctx) && !isCaretAtStart(ctx) && ctx.config.mode !== 'advanced') { editor.innerHTML = editor.innerHTML.replace( /\u200b/, '' ); addEmptyCharAtEnd(ctx); } // toggle toolbar on key select if (e.which !== 13 || e.shiftKey) return updateStatus(400); var node = getNode(ctx, true); if (!node || !node.nextSibling || !lineBreakReg.test(node.nodeName)) return; if (node.nodeName !== node.nextSibling.nodeName) return; // hack for webkit, make 'enter' behavior like as firefox. if (node.lastChild.nodeName !== 'BR') node.appendChild(doc.createElement('br')); utils.forEach(node.nextSibling.childNodes, function(child) { if (child) node.appendChild(child); }, true); node.parentNode.removeChild(node.nextSibling); focusNode(ctx, node.lastChild, ctx.getRange()); }); // check line break addListener(ctx, editor, 'keydown', function(e) { editor.classList.remove(ctx.config.placeholderClass); if (e.which !== 13 || e.shiftKey) return; if ( ctx.config.ignoreLineBreak ) { e.preventDefault(); return; } var node = getNode(ctx, true); if(!node || !lineBreakReg.test(node.nodeName)) { if (ctx.config.mode === 'basic') { e.preventDefault(); commandOverall('insertHTML', '
'); } return; } if (!node) { return; } var lastChild = node.lastChild; if (!lastChild || !lastChild.previousSibling) return; if (lastChild.previousSibling.textContent || lastChild.textContent) return; // quit block mode for 2 'enter' e.preventDefault(); var p = doc.createElement('p'); p.innerHTML = '
'; node.removeChild(lastChild); if (!node.nextSibling) node.parentNode.appendChild(p); else node.parentNode.insertBefore(p, node.nextSibling); focusNode(ctx, p, ctx.getRange()); }); if (toolbar) { addListener(ctx, toolbar, 'click', function(e) { onToolbarClick(ctx, e.target); }); } addListener(ctx, editor, 'focus', function() { if (ctx.isEmpty() && ctx.config.mode === 'advanced') handleEmptyContent(ctx); addListener(ctx, doc, 'click', outsideClick); }); addListener(ctx, editor, 'blur', function() { checkPlaceholder(ctx); ctx.checkContentChange(); }); // listen for paste and clear style addListener(ctx, editor, 'paste', function() { setTimeout(function() { ctx.cleanContent(); }); }); } function addListener(ctx, target, type, listener) { if (ctx._events.hasOwnProperty(type)) { ctx._events[type].push(listener); } else { ctx._eventTargets = ctx._eventTargets || []; ctx._eventsCache = ctx._eventsCache || []; var index = ctx._eventTargets.indexOf(target); if (index < 0) index = ctx._eventTargets.push(target) - 1; ctx._eventsCache[index] = ctx._eventsCache[index] || {}; ctx._eventsCache[index][type] = ctx._eventsCache[index][type] || []; ctx._eventsCache[index][type].push(listener); target.addEventListener(type, listener, false); } return ctx; } // trigger local events function triggerListener(ctx, type) { if (!ctx._events.hasOwnProperty(type)) return; var args = slice.call(arguments, 2); utils.forEach(ctx._events[type], function (listener) { listener.apply(ctx, args); }); } function removeListener(ctx, target, type, listener) { var events = ctx._events[type]; if (!events) { var _index = ctx._eventTargets.indexOf(target); if (_index >= 0) events = ctx._eventsCache[_index][type]; } if (!events) return ctx; var index = events.indexOf(listener); if (index >= 0) events.splice(index, 1); target.removeEventListener(type, listener, false); return ctx; } function removeAllListeners(ctx) { utils.forEach(this._events, function (events) { events.length = 0; }, false); if (!ctx._eventsCache) return ctx; utils.forEach(ctx._eventsCache, function (events, index) { var target = ctx._eventTargets[index]; utils.forEach(events, function (listeners, type) { utils.forEach(listeners, function (listener) { target.removeEventListener(type, listener, false); }, true); }, false); }, true); ctx._eventTargets = []; ctx._eventsCache = []; return ctx; } function checkPlaceholder(ctx) { ctx.config.editor.classList[ctx.isEmpty() ? 'add' : 'remove'](ctx.config.placeholderClass); } function trim(str) { return (str || '').trim().replace(/\u200b/g, ''); } // node.contains is not implemented in IE10/IE11 function containsNode(parent, child) { if (parent === child) return true; child = child.parentNode; while (child) { if (child === parent) return true; child = child.parentNode; } return false; } function getNode(ctx, byRoot) { var node, root = ctx.config.editor; ctx._range = ctx._range || ctx.getRange(); node = ctx._range.commonAncestorContainer; // Fix selection detection for Firefox if (node.hasChildNodes() && ctx._range.startOffset + 1 === ctx._range.endOffset) { node = node.childNodes[ctx._range.startOffset]; } if (!node || node === root) return null; while (node && (node.nodeType !== 1) && (node.parentNode !== root)) node = node.parentNode; while (node && byRoot && (node.parentNode !== root)) node = node.parentNode; return containsNode(root, node) ? node : null; } function getEffectNodes(ctx) { return getNodeParents(ctx).filter(function(node) { return node.nodeName.match(effectNodeReg); }); } function getNodeParents(ctx) { var nodes = [], el = getNode(ctx); while (el && el !== ctx.config.editor) { if (el.nodeType === Node.ELEMENT_NODE) { nodes.push(el); } el = el.parentNode; } return nodes; } function handleEmptyContent(ctx) { var range = ctx._range = ctx.getRange(); ctx.config.editor.innerHTML = ''; var p = doc.createElement('p'); p.innerHTML = '
'; range.insertNode(p); focusNode(ctx, p.childNodes[0], range); } function addEmptyCharAtEnd(ctx) { var range = ctx.getRange(), emptyCharNode = doc.createTextNode('\u200b'); range.selectNodeContents(ctx.config.editor); range.collapse(false); range.insertNode(emptyCharNode); focusNode(ctx, emptyCharNode, range); } function isCaretAtEnd(ctx) { var range = ctx.getRange(), clonedRange = range.cloneRange(); clonedRange.selectNodeContents(ctx.config.editor); clonedRange.setStart(range.endContainer, range.endOffset); return clonedRange.toString() === ''; } function isCaretAtStart(ctx) { var range = ctx.getRange(), clonedRange = range.cloneRange(); clonedRange.selectNodeContents(ctx.config.editor); clonedRange.setEnd(range.startContainer, range.startOffset); return clonedRange.toString() === ''; } function focusNode(ctx, node, range) { range.setStartAfter(node); range.setEndBefore(node); range.collapse(false); ctx.setRange(range); } function autoLink(node) { if (node.nodeType === 1) { if (autoLinkReg.notLink.test(node.tagName)) return; utils.forEach(node.childNodes, function (child) { autoLink(child); }, true); } else if (node.nodeType === 3) { var result = urlToLink(node.nodeValue || ''); if (!result.links) return; var frag = doc.createDocumentFragment(), div = doc.createElement('div'); div.innerHTML = result.text; while (div.childNodes.length) frag.appendChild(div.childNodes[0]); node.parentNode.replaceChild(frag, node); } } function urlToLink(str) { var count = 0; str = str.replace(autoLinkReg.url, function(url) { var realUrl = url, displayUrl = url; count++; if (url.length > autoLinkReg.maxLength) displayUrl = url.slice(0, autoLinkReg.maxLength) + '...'; // Add http prefix if necessary if (!autoLinkReg.prefix.test(realUrl)) realUrl = 'http://' + realUrl; return '' + displayUrl + ''; }); return {links: count, text: str}; } function toggleNode(node, hide) { node.style.display = hide ? 'none' : 'flex'; } InlineEditor = function(config) { if (!config) throw new Error('Can\'t find config'); debugMode = config.debug; // merge user config var defaults = utils.merge(config); var editor = defaults.editor; if (!editor || editor.nodeType !== 1) throw new Error('Can\'t find editor'); // set default class editor.classList.add.apply(editor.classList, defaults.class.split(' ')); // set contenteditable editor.setAttribute('contenteditable', 'true'); // assign config this.config = defaults; // set placeholder if (defaults.placeholder) editor.setAttribute(this.config.placeholderAttr, defaults.placeholder); checkPlaceholder(this); // save the selection obj this.selection = selection; // define local events this._events = {change: []}; // enable toolbar initToolbar(this); // init events initEvents(this); // to check content change this._prevContent = this.getContent(); // enable markdown covert if (this.markdown) this.markdown.init(this); // stay on the page if (this.config.stay) this.stay(this.config); if(this.config.input) { this.addOnSubmitListener(this.config.input); } if (this.config.mode === 'advanced') { this.getRange().selectNodeContents(editor); this.setRange(); } else { addEmptyCharAtEnd(this); } }; InlineEditor.prototype.on = function(type, listener) { addListener(this, this.config.editor, type, listener); return this; }; InlineEditor.prototype.addOnSubmitListener = function(inputElement) { var form = inputElement.form; var me = this; form.addEventListener("submit", function() { inputElement.value = me.config.saveAsMarkdown ? me.toMd(me.config.editor.innerHTML) : me.config.editor.innerHTML; }); }; InlineEditor.prototype.isEmpty = function(node) { node = node || this.config.editor; return !(node.querySelector('img')) && !(node.querySelector('blockquote')) && !(node.querySelector('li')) && !trim(node.textContent); }; InlineEditor.prototype.getContent = function() { return this.isEmpty() ? '' : trim(this.config.editor.innerHTML); }; InlineEditor.prototype.setContent = function(html) { this.config.editor.innerHTML = html; this.cleanContent(); return this; }; InlineEditor.prototype.checkContentChange = function () { var prevContent = this._prevContent, currentContent = this.getContent(); if (prevContent === currentContent) return; this._prevContent = currentContent; triggerListener(this, 'change', currentContent, prevContent); }; InlineEditor.prototype.getRange = function() { var editor = this.config.editor, range = selection.rangeCount && selection.getRangeAt(0); if (!range) range = doc.createRange(); if (!containsNode(editor, range.commonAncestorContainer)) { range.selectNodeContents(editor); range.collapse(false); } return range; }; InlineEditor.prototype.setRange = function(range) { range = range || this._range; if (!range) { range = this.getRange(); range.collapse(false); // set to end } try { selection.removeAllRanges(); selection.addRange(range); } catch (e) {/* IE throws error sometimes*/} return this; }; InlineEditor.prototype.focus = function(focusStart) { if (!focusStart) this.setRange(); this.config.editor.focus(); return this; }; InlineEditor.prototype.execCommand = function(name, value) { name = name.toLowerCase(); this.setRange(); if (commandsReg.block.test(name)) { commandBlock(this, name); } else if (commandsReg.inline.test(name)) { commandOverall(name, value); } else if (commandsReg.biu.test(name)) { // Temporarily removing all override style rules // to make sure the command will be executed correctly var styleBackup = styleBackupDict[ name ]; styleBackup.backupValue = this.config.editor.style[ styleBackup.styleKey ]; this.config.editor.style[ styleBackup.styleKey ] = styleBackup.correctValue; commandOverall(name, value); this.config.editor.style[ styleBackup.styleKey ] = styleBackup.backupValue; } else if (commandsReg.source.test(name)) { commandLink(this, name, value); } else if (commandsReg.insert.test(name)) { commandInsert(this, name, value); } else if (commandsReg.wrap.test(name)) { commandWrap(this, name, value); } else { utils.log('can not find command function for name: ' + name + (value ? (', value: ' + value) : ''), true); } if (name === 'indent') this.checkContentChange(); }; // remove attrs and tags // pen.cleanContent({cleanAttrs: ['style'], cleanTags: ['id']}) InlineEditor.prototype.cleanContent = function(options) { var editor = this.config.editor; if (!options) options = this.config; utils.forEach(options.cleanAttrs, function (attr) { utils.forEach(editor.querySelectorAll('[' + attr + ']'), function(item) { item.removeAttribute(attr); }, true); }, true); utils.forEach(options.cleanTags, function (tag) { utils.forEach(editor.querySelectorAll(tag), function(item) { item.parentNode.removeChild(item); }, true); }, true); checkPlaceholder(this); this.checkContentChange(); return this; }; // auto link content, return content InlineEditor.prototype.autoLink = function() { autoLink(this.config.editor); return this.getContent(); }; // highlight menu InlineEditor.prototype.highlight = function() { var toolbar = this._toolbar || this._menu, node = getNode(this); // remove all highlights utils.forEach(toolbar.querySelectorAll('.active'), function(el) { el.classList.remove('active'); }, true); if (!node) return this; var nodeParents = getNodeParents(this), urlInput = this._urlInput, externalUrlCheckbox = this._externalUrlCheckbox, highlight; if (urlInput && toolbar === this._menu) { // reset url inputs urlInput.value = ''; this._externalUrlCheckbox.checked = false; } highlight = function(str) { if (!str) return; var el = toolbar.querySelector('[data-action=' + str + ']'); return el && el.classList.add('active'); }; utils.forEach(nodeParents, function(item) { var tag = item.nodeName.toLowerCase(), align = item.style.textAlign, textDecoration = item.style.textDecoration; if (align) { if ('justify' === align) { align = 'full'; } highlight('justify' + align[0].toUpperCase() + align.slice(1)); } if ('underline' === textDecoration) { highlight('underline'); } if (! tag.match(effectNodeReg)) { return; } switch(tag) { case 'a': urlInput.value = item.getAttribute('href'); externalUrlCheckbox.checked = item.getAttribute('target') === '_blank'; tag = 'createlink'; break; case 'img': urlInput.value = item.getAttribute('src'); tag = 'insertimage'; break; case 'i': case 'em': tag = 'italic'; break; case 'u': tag = 'underline'; break; case 'b': case 'strong': tag = 'bold'; break; case 'strike': tag = 'strikethrough'; break; case 'ul': tag = 'insertUnorderedList'; break; case 'ol': tag = 'insertOrderedList'; break; case 'li': tag = 'indent'; break; } highlight(tag); }, true); return this; }; // show menu InlineEditor.prototype.menu = function() { if (!this._menu) return this; if (selection.isCollapsed) { this._menu.style.display = 'none'; //hide menu this._inputActive = false; return this; } if (this._toolbar) { if (!this._urlInput || !this._inputActive) return this; } showMainMenu(this); }; InlineEditor.prototype.refreshMenuPosition = function() { var offset = this._range.getBoundingClientRect() , menuPadding = 10 , top = offset.top - menuPadding , left = offset.left + (offset.width / 2) , menu = this._menu , menuOffset = {x: 0, y: 0} , stylesheet = this._stylesheet; // fixes some browser double click visual discontinuity // if the offset has no width or height it should not be used if (offset.width === 0 && offset.height === 0) return this; // store the stylesheet used for positioning the menu horizontally if (this._stylesheet === undefined) { var style = document.createElement("style"); document.head.appendChild(style); this._stylesheet = stylesheet = style.sheet; } // display it to caculate its width & height menu.style.display = 'flex'; menuOffset.x = left - (menu.clientWidth / 2); menuOffset.y = top - menu.clientHeight; // check to see if menu has over-extended its bounding box. if it has, // 1) apply a new class if overflowed on top; // 2) apply a new rule if overflowed on the left if (stylesheet.cssRules.length > 0) { stylesheet.deleteRule(0); } if (menuOffset.x < 0) { menuOffset.x = 0; stylesheet.insertRule('.pen-menu:after {left: ' + left + 'px;}', 0); } else { stylesheet.insertRule('.pen-menu:after {left: 50%; }', 0); } if (menuOffset.y < 0) { menu.classList.add('pen-menu-below'); menuOffset.y = offset.top + offset.height + menuPadding; } else { menu.classList.remove('pen-menu-below'); } menu.style.top = menuOffset.y + 'px'; menu.style.left = menuOffset.x + 'px'; return this; }; InlineEditor.prototype.stay = function(config) { var ctx = this; if (!window.onbeforeunload) { window.onbeforeunload = function() { if (!ctx._isDestroyed) return config.stayMsg; }; } }; InlineEditor.prototype.destroy = function() { var config = this.config; removeAllListeners(this); config.editor.classList.remove.apply(config.editor.classList, config.class.split(' ').concat(config.placeholderClass)); config.editor.removeAttribute('contenteditable'); config.editor.removeAttribute(config.placeholderAttr); try { selection.removeAllRanges(); if (this._menu) this._menu.parentNode.removeChild(this._menu); } catch (e) {/* IE throws error sometimes*/} this._isDestroyed = true; return this; }; InlineEditor.prototype.rebuild = function() { initToolbar(this); initEvents(this); return this; }; // a fallback for old browers root.ElementorInlineEditor = function(config) { if (!config) return utils.log('can\'t find config', true); var defaults = utils.merge(config) , klass = defaults.editor.getAttribute('class'); klass = klass ? klass.replace(/\bpen\b/g, '') + ' pen-textarea ' + defaults.class : 'pen pen-textarea'; defaults.editor.setAttribute('class', klass); defaults.editor.innerHTML = defaults.textarea; return defaults.editor; }; // export content as markdown var regs = { a: [/]*href=["']([^"]+|[^']+)\b[^>]*>(.*?)<\/a>/ig, '[$2]($1)'], img: [/]*src=["']([^\"+|[^']+)[^>]*>/ig, '![]($1)'], b: [/]*>(.*?)<\/b>/ig, '**$1**'], i: [/]*>(.*?)<\/i>/ig, '***$1***'], h: [/]*>(.*?)<\/h\1>/ig, function(a, b, c) { return '\n' + ('######'.slice(0, b)) + ' ' + c + '\n'; }], li: [/<(li)\b[^>]*>(.*?)<\/\1>/ig, '* $2\n'], blockquote: [/<(blockquote)\b[^>]*>(.*?)<\/\1>/ig, '\n> $2\n'], pre: [/]*>(.*?)<\/pre>/ig, '\n```\n$1\n```\n'], code: [/]*>(.*?)<\/code>/ig, '\n`\n$1\n`\n'], p: [/]*>(.*?)<\/p>/ig, '\n$1\n'], hr: [/]*>/ig, '\n---\n'] }; InlineEditor.prototype.toMd = function() { var html = this.getContent() .replace(/\n+/g, '') // remove line break .replace(/<([uo])l\b[^>]*>(.*?)<\/\1l>/ig, '$2'); // remove ul/ol for(var p in regs) { if (regs.hasOwnProperty(p)) html = html.replace.apply(html, regs[p]); } return html.replace(/\*{5}/g, '**'); }; // make it accessible if (doc.getSelection) { selection = doc.getSelection(); root.ElementorInlineEditor = InlineEditor; } }(window, document));