UNPKG

froala-editor

Version:

The next generation Javascript WYSIWYG HTML rich text editor made by devs for devs. High performance and modern design make it easy to use for developers and loved by users.

7 lines (6 loc) 11.7 kB
/*! * froala_editor v5.0.1 (https://www.froala.com/wysiwyg-editor) * License https://froala.com/wysiwyg-editor/terms/ * Copyright 2014-2026 Froala Labs */ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(require("froala-editor")):"function"==typeof define&&define.amd?define(["froala-editor"],t):t(("undefined"!=typeof globalThis?globalThis:e||self).FroalaEditor)}(this,function(T){"use strict";Object.assign(T.POPUP_TEMPLATES,{"codeSnippet.error":"[_CODE_SNIPPET_LAYER_]"}),Object.assign(T.DEFAULTS,{codeSnippetLanguage:{JavaScript:"javascript",TypeScript:"typescript",Python:"python",HTML:"html",CSS:"css",Java:"java","C++":"cpp",SQL:"sql",JSON:"json"},codeSnippetDefaultLanguage:"JavaScript"}),T.PLUGINS.codeSnippet=function(d){var n,o,i,r,a="code_snippet",c=d.$;function s(){var e=d.button.build("codeSnippetLang",T.COMMANDS.codeSnippetLang,!0),t='<div class="fr-buttons fr-code-snippet-header"><span>'.concat(d.language.translate("Insert Code Snippet"),"</span></div>"),e='\n <div class="fr-layer fr-active">\n <div class="fr-code-snippet-lang fr-toolbar">\n '.concat(e,'\n </div>\n <pre><code contenteditable="true" spellcheck="false" tabIndex="1"></code></pre>\n <div class="fr-float-right">\n <button class="fr-command fr-enable-accessibility fr-modal-close" tabIndex="2" aria-label="').concat(d.language.translate("Cancel"),'">').concat(d.language.translate("Cancel"),'</button>\n <button class="fr-command fr-enable-accessibility fr-modal-close submit" tabIndex="3" aria-label="').concat(d.language.translate("Insert"),'" data-cmd="submitCodeSnippetPopup">').concat(d.language.translate("Insert"),"</button>\n </div>\n </div>\n "),t=d.modals.create(a,t,e);n=t.$modal,o=t.$head,i=t.$body,n.find(".fr-modal-wrapper").addClass("fr-code-snippet-layer fr-toolbar"),d.button.bindCommands(n,!1),n.find(".fr-toolbar").data("instance",d),d.events.$on(i,"click",'.fr-command[data-cmd="codeSnippetLang"]',f),d.events.$on(i,"input","code",u,!0),d.events.$on(i,"keydown",function(e){!e.target||"CODE"!==e.target.tagName&&"PRE"!==e.target.tagName||e.stopImmediatePropagation()},!0),d.accessibility.registerToolbar(n),d.events.$on(n,"keydown",".fr-modal-close",function(e){"Enter"!==e.key&&T.KEYCODE.ENTER!==e.which||(d.modals.hide(a),e.target&&c(e.target).hasClass("submit")&&u())})}function p(){var e,t,n;if(window.Prism)return 1;d.popups.get("codeSnippet.error")||(n=d.language.translate("Ensure that all required dependent libraries are available for the plugin to work."),n='\n <div class="fr-layer fr-active fr-error-layer">\n <div class="fr-message fr-error-message"><div>'.concat(d.language.translate(n),'</div></div>\n <div class="fr-action-buttons">\n <button class="fr-trim-button fr-plugins-ok">').concat(d.language.translate("OK"),"</button>\n </div>\n </div>"),n=d.popups.create("codeSnippet.error",{code_snippet_layer:n}),d.popups.setContainer("codeSnippet.error",d.$tb),d.events.$on(n,"click",".fr-plugins-ok",function(){d.popups.hide("codeSnippet.error")})),n=d.$tb.find('.fr-command[data-cmd="codeSnippet"]'),t=(e=d.button.getPosition(n)).left,d.popups.show("codeSnippet.error",t,e.top,n.outerHeight(),!0)}function l(){var e=0<arguments.length&&arguments[0]!==undefined&&arguments[0];n||s(),p()&&(o.find(".fr-code-snippet-header span").first().text(d.language.translate(e?"Edit Code Snippet":"Insert Code Snippet")),i.find(".submit").text(d.language.translate(e?"Update":"Insert")),e||(i.find("code")[0].innerText="",i.removeData("edit-code-block")),u(),d.selection.save(),d.modals.show(a))}function f(e){var t,n,e=e.target;e&&(n=(t=i.find(".fr-btn.fr-dropdown")).next(),["BUTTON","SPAN"].includes(e.tagName)?(n.find(".fr-command.fr-active").removeClass("fr-active").attr("aria-selected",!1),n.find('.fr-command[title="'.concat(t.text(),'"]')).addClass("fr-active").attr("aria-selected",!0)):(t.find("span").text(c(e).text()),u()))}function u(){var e=i.find("code"),t=g(i.find(".fr-btn.fr-dropdown").text()),n=e[0],e=t,t=(t=window.getSelection()).rangeCount?t.getRangeAt(0):null,o=null,a=(t&&n.contains(t.startContainer)&&((a=t.cloneRange()).selectNodeContents(n),a.setEnd(t.endContainer,t.endOffset),o=a.toString().length),t=n.innerText,n.className="language-"+e,n.textContent=t||" ",window.Prism.highlightElement(n),null!==o?function(e,t){var n,o=document.createRange(),a=window.getSelection(),i=0,r=document.createTreeWalker(e,NodeFilter.SHOW_TEXT,null);for(;n=r.nextNode();){var d=i+n.length;if(t<=d)return o.setStart(n,t-i),o.collapse(!0),a.removeAllRanges(),a.addRange(o);i=d}}(n,o):setTimeout(function(){n.focus()},0),n.parentElement);a&&"pre"===a.nodeName.toLowerCase()&&a.hasAttribute("tabindex")&&a.removeAttribute("tabindex")}function m(o){return new Promise(function(e){var t=document.createDocumentFragment(),n=document.createElement("pre");"string"==typeof o?n.innerHTML=o:n.appendChild(o.cloneNode(!0)),t.appendChild(n),window.Prism.highlightElement(n.firstChild,!1,function(){e(t)})})}function g(t){var n=d.opts.codeSnippetLanguage,e=Object.keys(n).find(function(e){return n[e]===t});return n[t]||e&&e[0]||""}function v(e,a,i){var t;e=d.events.chainTrigger("codeSnippet.beforeInsert",e),p()&&!1!==e&&(e.trim()||(e=" "),r=r||d.button.buildList(["removeCodeSnippet","copyCodeSnippet","editCodeSnippet"]),t=g(a),m('<code class="language-'.concat(t,'">').concat(e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;"),"</code>")).then(function(e){d.selection.restore(),i||d.undo.saveStep();var t,n,o="code-"+Date.now(),o=(o='\n <div class="fr-code-snippet" contenteditable="false" style="caret-color: #ECECEC;" data-code-snippet="'.concat(a,'" id="').concat(o,'">\n <div class="fr-code-header" contenteditable="false">\n <div class="fr-code-lang" contenteditable="false">').concat(a,'</div>\n <div class="fr-code-actions">\n ').concat(r,"\n </div>\n </div>\n ").concat(e.firstChild.outerHTML,"\n </div>\n ")).trim();i?i.outerHTML=o:(e=d.selection.element(),t=d.el.firstChild,n=(n=d.html.defaultTag())?"<"+n+"><br></"+n+">":"<br>",!d.core.isEmpty()&&t!=e&&t!=e.parentElement||(o=n+o),d.html.insert(o+=n,!0),d.selection.restore(),d.undo.saveStep()),d.events.trigger("codeSnippet.afterInsert",[o])}))}function e(){var e=c(this),t=e.parents(".fr-code-snippet");e.removeData("mousedown"),d.undo.saveStep(),t.replaceWith(T.MARKERS),d.selection.restore(),d.undo.saveStep(),setTimeout(function(){d.$el.focus()},0)}function t(){var e=c(this),t=e.parents(".fr-code-snippet"),n=(i||s(),i.find("code"));e.removeData("mousedown"),n.text(t.find("code").text()),i.find(".fr-btn.fr-dropdown span").text(t.find(".fr-code-lang").text()),i.data("edit-code-block",t),l(!0)}function S(){var e=c(this),t=e.parents(".fr-code-snippet").first();e.removeData("mousedown"),document.hasFocus()&&((e=t.clone(!0)).find(".fr-code-actions").remove(),t=e[0].outerHTML,e=new Blob([t],{type:"text/html"}),navigator.clipboard.write([new window.ClipboardItem({"text/html":e})]))}function b(e){var t=e.which,n=d.selection.get(),o=T.KEYCODE.BACKSPACE===t,a=T.KEYCODE.DELETE===t;if((o||a)&&!d.keys.isArrow(t)&&t!==T.KEYCODE.TAB&&t!==T.KEYCODE.ALT&&t!==T.KEYCODE.ESC){if(e.ctrlKey||e.metaKey||t===T.KEYCODE.SHIFT)return!0;var i,r=d.markers.insert();if(!r)return;if(o&&((o=r.previousSibling)&&o.nodeType===Node.ELEMENT_NODE&&c(o).hasClass("fr-code-snippet")?i=o:o&&o.nodeType===Node.TEXT_NODE&&!o.data.trim()?i=r.parentElement.previousElementSibling:n.anchorNode.nodeType===Node.ELEMENT_NODE&&(i=n.anchorNode.previousElementSibling)),(i=a&&(o=r.parentElement).lastChild.nodeType===Node.ELEMENT_NODE&&"fr-marker"===o.lastChild.className?o.nextElementSibling:i)&&"LI"===i.tagName&&(i=i.firstChild),r.remove(),i&&c(i).hasClass("fr-code-snippet"))return e.preventDefault(),e.stopPropagation(),d.undo.saveStep(),c(i).replaceWith(T.MARKERS),d.selection.restore(),d.undo.saveStep(),!1}n=d.selection.element(),a=n&&c(n).parents(".fr-code-snippet");if(a&&a.length&&t!=T.KEYCODE.F10&&!d.keys.isBrowserAction(e))return e.preventDefault(),e.stopPropagation(),!1}function h(e,t){"codeSnippetLang"===e&&(t=(e=i.find(".fr-btn.fr-dropdown")).next().find('a[data-param1="'.concat(t,'"]')).text(),e.find("span").text(t),u())}function E(e){if(e.target&&e.target.parentElement&&c(e.target.parentElement).parents(".fr-code-snippet").length)return!1}function C(){window.Prism&&d.$el.find("[data-code-snippet]").filter(function(e){return!e.className}).each(function(e,t){var n=c(t).find("code"),o=t.getAttribute("data-code-snippet");n.length&&(n.text(n[0].innerText),v(n.text(),o,t))})}function y(){d.$el.find("[data-code-snippet]").each(function(e,t){var t=c(t),n=d.doc.createElement("div");n.setAttribute("data-code-snippet-action-btn",!0),t.find(".fr-code-actions").replaceWith(n.outerHTML)})}function w(){var e=d.$el.find("[data-code-snippet-action-btn]");r=r||d.button.buildList(["removeCodeSnippet","copyCodeSnippet","editCodeSnippet"]),e.each(function(e,t){c(t).replaceWith('<div class="fr-code-actions">'.concat(r,"</div>"))})}return{_init:function(){d.events.$on(d.$el,d._mousedown,'.fr-command[data-cmd="removeCodeSnippet"]',e,!0),d.events.$on(d.$el,d._mousedown,'.fr-command[data-cmd="copyCodeSnippet"]',S,!0),d.events.$on(d.$el,d._mousedown,'.fr-command[data-cmd="editCodeSnippet"]',t,!0),d.events.on("commands.after",h),d.events.on("paste.before",E),d.events.on("html.inserted",C),d.events.on("html.beforeGet",y),d.events.on("html.afterGet",w),d.events.$on(d.$el,"beforecopy",y),d.events.on("keydown",b,!0),d.events.on("copy",function(){setTimeout(w,0)}),d.events.on("dragover drop",function(e){if(e.target&&c(e.target).closest(".fr-code-snippet").length)return e.preventDefault(),!1},!0)},insert:v,update:function(e,t,n){var o=e.find("code");e.find(".fr-code-lang").text(n),e.attr("data-code-snippet",n),o.text(t),o[0].className="language-".concat(g(n)),m(o[0]).then(function(e){o.parent().replaceWith(e)})},show:l}},T.DefineIcon("codeSnippet",{NAME:"codeSnippet",SVG_KEY:"codeSnippet",VIEWBOX:"-5 -4 26 26"}),T.RegisterCommand("codeSnippet",{title:"Code Snippet",focus:!0,undo:!0,callback:function(){this.codeSnippet.show()}}),T.DefineIcon("copyCodeSnippet",{NAME:"copy",SVG_KEY:"copy",VIEWBOX:"1 1 18 18"}),T.RegisterCommand("copyCodeSnippet",{title:"Copy",undo:!1,focus:!1,plugin:"codeSnippet"}),T.DefineIcon("editCodeSnippet",{NAME:"edit",SVG_KEY:"edit",VIEWBOX:"4 3 16 16"}),T.RegisterCommand("editCodeSnippet",{title:"Edit",undo:!1,focus:!1,plugin:"codeSnippet"}),T.DefineIcon("removeCodeSnippet",{NAME:"trash",SVG_KEY:"remove",VIEWBOX:"4 3 17 17"}),T.RegisterCommand("removeCodeSnippet",{title:"Remove",undo:!1,focus:!1,plugin:"codeSnippet"}),T.RegisterCommand("codeSnippetLang",{type:"dropdown",undo:!1,plugin:"codeSnippet",displaySelection:!0,defaultSelection:function(e){return e.opts.codeSnippetDefaultLanguage},displaySelectionWidth:250,html:function(){var e,t='<ul class="fr-dropdown-list" role="presentation">',n=this.opts.codeSnippetLanguage;for(e in n)n.hasOwnProperty(e)&&(t+='\n <li role="presentation">\n <a class="fr-command" tabIndex="-1" role="option" data-cmd="codeSnippetLang" data-param1="'.concat(n[e],'" title="').concat(e,'">').concat(e,"</a>\n </li>"));return t+="</ul>"}}),T.RegisterCommand("submitCodeSnippetPopup",{title:"Submit",undo:!1,focus:!1,plugin:"codeSnippet",callback:function(){var e=this.modals.get("code_snippet").$body,t=e.find("code"),n=e.find(".fr-btn.fr-dropdown").text(),e=e.data("edit-code-block");e?this.codeSnippet.update(e,t.text(),n):this.codeSnippet.insert(t.text(),n)}})});