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) 9.92 kB
/*! * froala_editor v4.7.0 (https://www.froala.com/wysiwyg-editor) * License https://froala.com/wysiwyg-editor/terms/ * Copyright 2014-2025 Froala Labs */ !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(require("froala-editor")):"function"==typeof define&&define.amd?define(["froala-editor"],n):n(e.FroalaEditor)}(this,function(I){"use strict";I=I&&I.hasOwnProperty("default")?I["default"]:I,Object.assign(I.POPUP_TEMPLATES,{"editAnchor.popup":"[_BUTTONS_]","insertAnchor.popup":"[_BUTTONS_][_LINK_TO_ANCHOR_LAYER_]"}),Object.assign(I.DEFAULTS,{anchorEditButtons:["anchorEdit","anchorRemove"]}),I.PLUGINS.linkToAnchor=function(E){var c,b,k=E.$;function l(){var e=E.button.buildList(["closeAnchorInsert"]),n={buttons:'<div class="fr-buttons fr-link-to-anchor-header"><span>'.concat(E.language.translate("Insert Anchor"),'</span><span class="fr-align-right">').concat(e,"</span></div>"),link_to_anchor_layer:"\n <div class='fr-layer fr-active fr-link-to-anchor-layer' tabindex=\"-1\">\n <div class='fr-input-container'>\n <div class='fr-input-line fr-link-to-anchor-field'>\n <input type='text' id=\"fr-link-to-anchor-".concat(E.id,"\" placeholder='").concat(E.language.translate("Anchor Name"),"' tabIndex='1'>\n </div>\n <div class=\"fr-input-text\">").concat(E.language.translate("Enter the anchor name without space"),'</div>\n </div>\n\n <div class="fr-action-buttons">\n <button type="button" class="fr-command fr-submit" data-cmd="anchorInsert" tabIndex="2" role="button">').concat(E.language.translate("Insert"),"</button>\n </div>\n </div>\n ")};return c=E.popups.create("insertAnchor.popup",n),E.events.$on(c,".fr-link-to-anchor-field input","input",function(){p(!1)}),c}function C(e){if(!1===E.events.trigger("anchor.beforeRemove",[e]))return!1;e&&(E.selection.save(),k(e).remove(),E.selection.restore(),T())}function p(e){var n=c.find(".fr-link-to-anchor-field input, .fr-input-text");e?(n.addClass("fr-error-text"),n.focus()):(n.removeClass("fr-error-text"),c.find(".fr-input-text").text(E.language.translate("Enter the anchor name without space")))}function i(){var e=c.data("data-update-ancher");c.removeData("data-update-ancher"),E.popups.hide("insertAnchor.popup"),N(e)}function T(){E.$el.find(".fr-anchor").removeClass("fr-active"),b&&b.removeData("data-update-ancher"),E.popups.hide("editAnchor.popup")}function t(e){if(!e)return!1;b||function a(){var e=E.button.buildList(E.opts.anchorEditButtons),n={buttons:'<div class="fr-buttons fr-edit-anchor"><label class="fr-edit-anchor-label"></label><span class="fr-align-right">'.concat(e,"</span></div>")};return b=E.popups.create("editAnchor.popup",n),E.events.on("popups.hide.editAnchor.popup",function(){E.$el.find(".fr-anchor").removeClass("fr-active fr-anchor-selected")}),E.events.on("commands.undo commands.redo",function(){N(E.$el.find('a[data-cmd="anchor"].fr-active').get(0)),E.$el.find(".fr-marker-helper").remove()}),b}();var n=k(e);n.addClass("fr-active"),b.find("label.fr-edit-anchor-label").text("#"+n.attr("name")),E.popups.isVisible("editAnchor.popup")||E.popups.refresh("editAnchor.popup"),E.popups.setContainer("editAnchor.popup",E.$sc);var t=n.offset().left+n.outerWidth()/2,r=n.offset().top+n.outerHeight();b.data("data-update-ancher",e),E.popups.show("editAnchor.popup",t,r,n.outerHeight(),!0)}function N(e){if(E.$el.find(".fr-anchor").removeClass("fr-active fr-anchor-selected"),!e)return!1;k(e).addClass("fr-active");var n=E.doc.createRange();E.selection.get().removeAllRanges(),n.selectNode(e),E.selection.get().addRange(n),t(e)}function e(e){var n=e.which,t=n===I.KEYCODE.DELETE,r=n===I.KEYCODE.BACKSPACE;if(e&&E.keys.isArrow(n)||r||t){var a=n===I.KEYCODE.ARROW_LEFT||r,o=n===I.KEYCODE.ARROW_RIGHT||t;if(b&&b.isVisible()&&!r&&!t){var i=b.data("data-update-ancher"),s=k(i);if(!i)return;var c=i.nextSibling,l=i.previousSibling;return void(o?c&&c.length&&c.nodeType!==Node.ELEMENT_NODE||(s.after(I.INVISIBLE_SPACE),s.attr("data-anchor-marker","after")):l&&l.length&&l.nodeType!==Node.ELEMENT_NODE||(s.before(I.INVISIBLE_SPACE),s.attr("data-anchor-marker","before")))}var p=E.selection.get();if(!p||!p.anchorNode)return;var d=p.anchorNode,f=p.anchorOffset;if(d.nodeType===Node.TEXT_NODE)if(a&&0===f)d=d.previousSibling;else{if(!o||f!==d.textContent.length)return;d=d.nextSibling}else if(r){var u=d.childNodes[f]||d.childNodes[f-1];d=u&&u.previousElementSibling}else d=n===I.KEYCODE.ARROW_LEFT?d.previousSibling:d.nextSibling;d&&d.nodeType===Node.ELEMENT_NODE&&d.classList.contains("fr-anchor")&&(r||t?C(d):setTimeout(function(){N(d)},30));var h=E.$el.find(".fr-anchor[data-anchor-marker]");if(h.length){var v=h.attr("data-anchor-marker"),g=h.get(0),m=g.previousSibling,A=g.nextSibling;"before"===v&&m&&m.nodeType===Node.TEXT_NODE&&"\u200b"===m.textContent&&m.remove(),"after"===v&&A&&A.nodeType===Node.TEXT_NODE&&"\u200b"===A.textContent&&A.remove(),h.removeAttr("data-anchor-marker")}}E.keys.ctrlKey(e)&&n==I.KEYCODE.A&&T()}function n(){E.$el.find('a[data-cmd="anchor"]').addClass("fr-anchor")}return{_init:function r(){E.$wp&&(E.events.$on(E.$doc,"selectionchange",function(){E.$el.find("a.fr-anchor").each(function(e,n){var t=k(n),r=b&&b.isVisible();!function s(e){var n=(E.opts.iframe?E.iframe_document:E.doc).getSelection(),t=E.selection.element();if(!n||0===n.rangeCount||E.selection.isCollapsed()||t.classList.contains("fr-view"))return!1;try{if("function"==typeof n.containsNode)return n.containsNode(e,!0);var r=n.getRangeAt(0);if("function"==typeof r.intersectsNode)return r.intersectsNode(e);var a=r.startContainer,o=r.endContainer;return e.contains(a)||e.contains(o)}catch(i){return!1}}(n)||r?t.removeClass("fr-anchor-selected"):t.addClass("fr-anchor-selected")})}),E.events.on("keydown",e),E.events.on("paste.after",n),E.events.bindClick(E.$el,".fr-anchor",function(e){e.preventDefault(),e.stopPropagation();var n=e.currentTarget;return n&&N(n),!1}))},insert:function s(){var e,n=c.find(".fr-link-to-anchor-field input").val(),t=c.data("data-update-ancher");if(n.length&&!n.includes(" "))if(t&&(e=k(t)).attr("name")===n)i();else{if(E.$el.find('[data-cmd="anchor"]').filter(function(e){return e.name===n}).length)return c.find(".fr-input-text").text(E.language.translate("Anchor name already exists.")),void p(!0);if(!1===E.events.trigger("anchor.beforeInsert",[t,n]))return!1;if(t)return e.attr("name",n),void i();var r=E.$el.find(".fr-marker-helper").get(0)||E.markers.insert(),a='<a name="'.concat(n,'" class="fr-anchor" data-cmd="anchor" contenteditable="false"></a>');if(r){r.outerHTML=a;var o=E.$el.find('a[name="'.concat(n,'"]'));c.data("data-update-ancher",o.get(0)),!o[0].previousSibling&&o.before(I.INVISIBLE_SPACE),!o[0].nextSibling&&o.after(I.INVISIBLE_SPACE),o.attr("data-anchor-marker","after"),i()}}else p(!0)},update:function a(e){if(T(),e){c||l(),c.data("data-update-ancher",e),E.popups.isVisible("insertAnchor.popup")||(E.popups.refresh("insertAnchor.popup"),E.selection.save(),E.helpers.isMobile()&&(E.events.disableBlur(),E.$el.blur(),E.events.enableBlur())),E.popups.setContainer("insertAnchor.popup",E.$sc);var n=k(e),t=n.offset().left+n.outerWidth()/2,r=n.offset().top+n.outerHeight();c.find(".fr-link-to-anchor-field input").val(n.attr("name")),E.popups.show("insertAnchor.popup",t,r,n.outerHeight(),!0)}},remove:C,showPopup:function d(){var e=E.$tb.find('.fr-command[data-cmd="insertAnchor"]');if(c||l(),!c.hasClass("fr-active")){if(E.popups.refresh("insertAnchor.popup"),E.popups.setContainer("insertAnchor.popup",E.$tb),c.find(".fr-link-to-anchor-field input").val(""),p(!1),E.$el.find(".fr-marker-helper").remove(),e.isVisible()){var n=E.button.getPosition(e),t=n.left,r=n.top;E.popups.show("insertAnchor.popup",t,r,e.outerHeight())}else E.position.forSelection(c),E.popups.show("insertAnchor.popup");var a=E.$el.find(".fr-marker");if(a.length){var o=a.first(),i=o.get(0).nextSibling;if(i&&i.nodeType===Node.ELEMENT_NODE&&"COLGROUP"===i.tagName){var s=a.parents("table");s.before(I.START_MARKER),s.prev().removeClass("fr-marker").addClass("fr-marker-helper")}else o.before(I.START_MARKER),a.prev().removeClass("fr-marker").addClass("fr-marker-helper")}}},closeAnchorInsert:i,focusOnAnchor:N}},I.RegisterShortcut(I.KEYCODE.D,"insertAnchor",null,"D"),I.DefineIcon("insertAnchor",{NAME:"bookmark",SVG_KEY:"bookmark",VIEWBOX:"-5 -4 26 26"}),I.RegisterCommand("insertAnchor",{title:"Insert Anchor",icon:"insertAnchor",plugin:"linkToAnchor",type:"button",undo:!0,focus:!0,popup:!0,showOnMobile:!0,refreshAfterCallback:!0,callback:function(){this.linkToAnchor.showPopup()}}),I.RegisterCommand("anchorInsert",{undo:!0,focus:!0,plugin:"linkToAnchor",callback:function(){this.linkToAnchor.insert()},refresh:function(e){var n=this.popups.get("insertAnchor.popup"),t=n.data("data-update-ancher"),r=n.find(".fr-link-to-anchor-header span").first();t?(e.text(this.language.translate("Update")),r.text(this.language.translate("Update Anchor"))):(e.text(this.language.translate("Insert")),r.text(this.language.translate("Insert Anchor")))}}),I.DefineIcon("closeAnchorInsert",{NAME:"cancel",SVG_KEY:"cancel"}),I.RegisterCommand("closeAnchorInsert",{title:"Cancel",undo:!1,focus:!1,plugin:"linkToAnchor",callback:function(){this.linkToAnchor.closeAnchorInsert()}}),I.DefineIcon("anchorEdit",{NAME:"edit",SVG_KEY:"edit"}),I.RegisterCommand("anchorEdit",{title:"Edit Anchor",undo:!0,popup:!0,plugin:"linkToAnchor",refreshAfterCallback:!1,callback:function(){var e=this.popups.get("editAnchor.popup");this.linkToAnchor.update(e.data("data-update-ancher"))}}),I.DefineIcon("anchorRemove",{NAME:"trash",SVG_KEY:"remove"}),I.RegisterCommand("anchorRemove",{title:"Delete",undo:!0,popup:!0,plugin:"linkToAnchor",refreshAfterCallback:!1,callback:function(){var e=this.popups.get("editAnchor.popup");this.linkToAnchor.remove(e.data("data-update-ancher"))}})});