@ckeditor/ckeditor5-html-embed 29.2.0 → 32.0.0

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.
Files changed (47) hide show
  1. package/LICENSE.md +2 -2
  2. package/build/html-embed.js +3 -3
  3. package/build/translations/bs.js +1 -0
  4. package/build/translations/nl.js +1 -1
  5. package/build/translations/pl.js +1 -1
  6. package/build/translations/pt-br.js +1 -1
  7. package/build/translations/uz.js +1 -0
  8. package/build/translations/zh-cn.js +1 -1
  9. package/build/translations/zh.js +1 -0
  10. package/ckeditor5-metadata.json +1 -0
  11. package/lang/translations/bs.po +45 -0
  12. package/lang/translations/cs.po +1 -1
  13. package/lang/translations/de-ch.po +1 -1
  14. package/lang/translations/de.po +1 -1
  15. package/lang/translations/en-au.po +1 -1
  16. package/lang/translations/en.po +1 -1
  17. package/lang/translations/es.po +1 -1
  18. package/lang/translations/fr.po +1 -1
  19. package/lang/translations/gl.po +1 -1
  20. package/lang/translations/hr.po +1 -1
  21. package/lang/translations/hu.po +1 -1
  22. package/lang/translations/id.po +1 -1
  23. package/lang/translations/it.po +1 -1
  24. package/lang/translations/nl.po +4 -4
  25. package/lang/translations/pl.po +3 -3
  26. package/lang/translations/pt-br.po +5 -5
  27. package/lang/translations/ro.po +1 -1
  28. package/lang/translations/ru.po +1 -1
  29. package/lang/translations/sk.po +1 -1
  30. package/lang/translations/sl.po +1 -1
  31. package/lang/translations/sr-latn.po +1 -1
  32. package/lang/translations/sr.po +1 -1
  33. package/lang/translations/uk.po +1 -1
  34. package/lang/translations/uz.po +45 -0
  35. package/lang/translations/vi.po +1 -1
  36. package/lang/translations/zh-cn.po +3 -3
  37. package/lang/translations/zh.po +45 -0
  38. package/package.json +17 -17
  39. package/src/htmlembed.js +1 -1
  40. package/src/htmlembedcommand.js +117 -0
  41. package/src/htmlembedediting.js +51 -46
  42. package/src/htmlembedui.js +3 -3
  43. package/src/index.js +1 -1
  44. package/theme/htmlembed.css +1 -1
  45. package/CHANGELOG.md +0 -4
  46. package/src/inserthtmlembedcommand.js +0 -79
  47. package/src/updatehtmlembedcommand.js +0 -64
package/LICENSE.md CHANGED
@@ -2,7 +2,7 @@ Software License Agreement
2
2
  ==========================
3
3
 
4
4
  **CKEditor 5 HTML embed feature** – https://github.com/ckeditor/ckeditor5-html-embed <br>
5
- Copyright (c) 2003-2021, [CKSource](http://cksource.com) Frederico Knabben. All rights reserved.
5
+ Copyright (c) 2003-2022, [CKSource](http://cksource.com) Holding sp. z o.o. All rights reserved.
6
6
 
7
7
  Licensed under the terms of [GNU General Public License Version 2 or later](http://www.gnu.org/licenses/gpl.html).
8
8
 
@@ -14,4 +14,4 @@ Where not otherwise indicated, all CKEditor content is authored by CKSource engi
14
14
  Trademarks
15
15
  ----------
16
16
 
17
- **CKEditor** is a trademark of [CKSource](http://cksource.com) Frederico Knabben. All other brand and product names are trademarks, registered trademarks or service marks of their respective holders.
17
+ **CKEditor** is a trademark of [CKSource](http://cksource.com) Holding sp. z o.o. All other brand and product names are trademarks, registered trademarks or service marks of their respective holders.
@@ -1,5 +1,5 @@
1
+ !function(e){const t=e.en=e.en||{};t.dictionary=Object.assign(t.dictionary||{},{"Edit source":"Edit source","Empty snippet content":"Empty snippet content","HTML snippet":"HTML snippet","Insert HTML":"Insert HTML","No preview available":"No preview available","Paste raw HTML here...":"Paste raw HTML here...","Save changes":"Save changes"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={})),
1
2
  /*!
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
3
+ * @license Copyright (c) 2003-2022, CKSource - Frederico Knabben. All rights reserved.
3
4
  * For licensing, see LICENSE.md.
4
- */
5
- !function(e){const t=e.en=e.en||{};t.dictionary=Object.assign(t.dictionary||{},{"Edit source":"Edit source","Empty snippet content":"Empty snippet content","HTML snippet":"HTML snippet","Insert HTML":"Insert HTML","No preview available":"No preview available","Paste raw HTML here...":"Paste raw HTML here...","Save changes":"Save changes"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={})),window.CKEditor5=window.CKEditor5||{},window.CKEditor5.htmlEmbed=function(e){var t={};function n(r){if(t[r])return t[r].exports;var a=t[r]={i:r,l:!1,exports:{}};return e[r].call(a.exports,a,a.exports,n),a.l=!0,a.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)n.d(r,a,function(t){return e[t]}.bind(null,a));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=8)}([function(e,t,n){e.exports=n(3)("./src/core.js")},function(e,t,n){e.exports=n(3)("./src/utils.js")},function(e,t,n){e.exports=n(3)("./src/widget.js")},function(e,t){e.exports=CKEditor5.dll},function(e,t,n){e.exports=n(3)("./src/ui.js")},function(e,t,n){var r=n(6),a=n(7);"string"==typeof(a=a.__esModule?a.default:a)&&(a=[[e.i,a,""]]);var i={injectType:"singletonStyleTag",attributes:{"data-cke":!0},insert:"head",singleton:!0};r(a,i);e.exports=a.locals||{}},function(e,t,n){"use strict";var r,a=function(){return void 0===r&&(r=Boolean(window&&document&&document.all&&!window.atob)),r},i=function(){var e={};return function(t){if(void 0===e[t]){var n=document.querySelector(t);if(window.HTMLIFrameElement&&n instanceof window.HTMLIFrameElement)try{n=n.contentDocument.head}catch(e){n=null}e[t]=n}return e[t]}}(),o=[];function c(e){for(var t=-1,n=0;n<o.length;n++)if(o[n].identifier===e){t=n;break}return t}function l(e,t){for(var n={},r=[],a=0;a<e.length;a++){var i=e[a],l=t.base?i[0]+t.base:i[0],d=n[l]||0,s="".concat(l," ").concat(d);n[l]=d+1;var m=c(s),u={css:i[1],media:i[2],sourceMap:i[3]};-1!==m?(o[m].references++,o[m].updater(u)):o.push({identifier:s,updater:w(u,t),references:1}),r.push(s)}return r}function d(e){var t=document.createElement("style"),r=e.attributes||{};if(void 0===r.nonce){var a=n.nc;a&&(r.nonce=a)}if(Object.keys(r).forEach((function(e){t.setAttribute(e,r[e])})),"function"==typeof e.insert)e.insert(t);else{var o=i(e.insert||"head");if(!o)throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");o.appendChild(t)}return t}var s,m=(s=[],function(e,t){return s[e]=t,s.filter(Boolean).join("\n")});function u(e,t,n,r){var a=n?"":r.media?"@media ".concat(r.media," {").concat(r.css,"}"):r.css;if(e.styleSheet)e.styleSheet.cssText=m(t,a);else{var i=document.createTextNode(a),o=e.childNodes;o[t]&&e.removeChild(o[t]),o.length?e.insertBefore(i,o[t]):e.appendChild(i)}}function b(e,t,n){var r=n.css,a=n.media,i=n.sourceMap;if(a?e.setAttribute("media",a):e.removeAttribute("media"),i&&"undefined"!=typeof btoa&&(r+="\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(i))))," */")),e.styleSheet)e.styleSheet.cssText=r;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(r))}}var p=null,h=0;function w(e,t){var n,r,a;if(t.singleton){var i=h++;n=p||(p=d(t)),r=u.bind(null,n,i,!1),a=u.bind(null,n,i,!0)}else n=d(t),r=b.bind(null,n,t),a=function(){!function(e){if(null===e.parentNode)return!1;e.parentNode.removeChild(e)}(n)};return r(e),function(t){if(t){if(t.css===e.css&&t.media===e.media&&t.sourceMap===e.sourceMap)return;r(e=t)}else a()}}e.exports=function(e,t){(t=t||{}).singleton||"boolean"==typeof t.singleton||(t.singleton=a());var n=l(e=e||[],t);return function(e){if(e=e||[],"[object Array]"===Object.prototype.toString.call(e)){for(var r=0;r<n.length;r++){var a=c(n[r]);o[a].references--}for(var i=l(e,t),d=0;d<n.length;d++){var s=c(n[d]);0===o[s].references&&(o[s].updater(),o.splice(s,1))}n=i}}}},function(e,t){e.exports=".ck-widget.raw-html-embed{margin:.9em auto;position:relative;display:flow-root;min-width:15em;font-style:normal}.ck-widget.raw-html-embed:before{position:absolute;z-index:1}.ck-widget.raw-html-embed .raw-html-embed__buttons-wrapper{position:absolute;display:flex;flex-direction:column}.ck-widget.raw-html-embed .raw-html-embed__preview{position:relative;overflow:hidden;display:flex}.ck-widget.raw-html-embed .raw-html-embed__preview-content{width:100%;position:relative;margin:auto;display:table;border-collapse:separate;border-spacing:7px}.ck-widget.raw-html-embed .raw-html-embed__preview-placeholder{position:absolute;left:0;top:0;right:0;bottom:0;display:flex;align-items:center;justify-content:center}:root{--ck-html-embed-content-width:calc(100% - var(--ck-icon-size)*1.5);--ck-html-embed-source-height:10em;--ck-html-embed-unfocused-outline-width:1px;--ck-html-embed-content-min-height:calc(var(--ck-icon-size) + var(--ck-spacing-standard));--ck-html-embed-source-disabled-background:var(--ck-color-base-foreground);--ck-html-embed-source-disabled-color:#737373}.ck-widget.raw-html-embed{font-size:var(--ck-font-size-base);background-color:var(--ck-color-base-foreground)}.ck-widget.raw-html-embed:not(.ck-widget_selected):not(:hover){outline:var(--ck-html-embed-unfocused-outline-width) dashed var(--ck-color-widget-blurred-border)}.ck-widget.raw-html-embed[dir=ltr]{text-align:left}.ck-widget.raw-html-embed[dir=rtl]{text-align:right}.ck-widget.raw-html-embed:before{content:attr(data-html-embed-label);top:calc(var(--ck-html-embed-unfocused-outline-width)*-1);left:var(--ck-spacing-standard);background:#999;transition:background var(--ck-widget-handler-animation-duration) var(--ck-widget-handler-animation-curve);padding:calc(var(--ck-spacing-tiny) + var(--ck-html-embed-unfocused-outline-width)) var(--ck-spacing-small) var(--ck-spacing-tiny);border-radius:0 0 var(--ck-border-radius) var(--ck-border-radius);color:var(--ck-color-base-background);font-size:var(--ck-font-size-tiny);font-family:var(--ck-font-face)}.ck-widget.raw-html-embed[dir=rtl]:before{left:auto;right:var(--ck-spacing-standard)}.ck-widget.raw-html-embed[dir=ltr] .ck-widget__type-around .ck-widget__type-around__button.ck-widget__type-around__button_before{margin-left:50px}.ck.ck-editor__editable.ck-blurred .ck-widget.raw-html-embed.ck-widget_selected:before{top:0;padding:var(--ck-spacing-tiny) var(--ck-spacing-small)}.ck.ck-editor__editable:not(.ck-blurred) .ck-widget.raw-html-embed.ck-widget_selected:before{top:0;padding:var(--ck-spacing-tiny) var(--ck-spacing-small);background:var(--ck-color-focus-border)}.ck.ck-editor__editable .ck-widget.raw-html-embed:not(.ck-widget_selected):hover:before{top:0;padding:var(--ck-spacing-tiny) var(--ck-spacing-small)}.ck-widget.raw-html-embed .raw-html-embed__content-wrapper{padding:var(--ck-spacing-standard)}.ck-widget.raw-html-embed .raw-html-embed__buttons-wrapper{top:var(--ck-spacing-standard);right:var(--ck-spacing-standard)}.ck-widget.raw-html-embed .raw-html-embed__buttons-wrapper .ck-button.raw-html-embed__save-button{color:var(--ck-color-button-save)}.ck-widget.raw-html-embed .raw-html-embed__buttons-wrapper .ck-button.raw-html-embed__cancel-button{color:var(--ck-color-button-cancel)}.ck-widget.raw-html-embed .raw-html-embed__buttons-wrapper .ck-button:not(:first-child){margin-top:var(--ck-spacing-small)}.ck-widget.raw-html-embed[dir=rtl] .raw-html-embed__buttons-wrapper{left:var(--ck-spacing-standard);right:auto}.ck-widget.raw-html-embed .raw-html-embed__source{box-sizing:border-box;height:var(--ck-html-embed-source-height);width:var(--ck-html-embed-content-width);resize:none;min-width:0;padding:var(--ck-spacing-standard);font-family:monospace;tab-size:4;white-space:pre-wrap;font-size:var(--ck-font-size-base);text-align:left;direction:ltr}.ck-widget.raw-html-embed .raw-html-embed__source[disabled]{background:var(--ck-html-embed-source-disabled-background);color:var(--ck-html-embed-source-disabled-color);-webkit-text-fill-color:var(--ck-html-embed-source-disabled-color);opacity:1}.ck-widget.raw-html-embed .raw-html-embed__preview{min-height:var(--ck-html-embed-content-min-height);width:var(--ck-html-embed-content-width)}.ck-editor__editable:not(.ck-read-only) .ck-widget.raw-html-embed .raw-html-embed__preview{pointer-events:none}.ck-widget.raw-html-embed .raw-html-embed__preview-content{box-sizing:border-box;background-color:var(--ck-color-base-foreground)}.ck-widget.raw-html-embed .raw-html-embed__preview-content>*{margin-left:auto;margin-right:auto}.ck-widget.raw-html-embed .raw-html-embed__preview-placeholder{color:var(--ck-html-embed-source-disabled-color)}"},function(e,t,n){"use strict";n.r(t),n.d(t,"HtmlEmbed",(function(){return b})),n.d(t,"HtmlEmbedEditing",(function(){return s})),n.d(t,"HtmlEmbedUI",(function(){return u}));var r=n(0),a=n(2),i=n(4),o=n(1);class c extends r.Command{refresh(){const e=this.editor.model,t=e.schema,n=e.document.selection;this.isEnabled=function(e,t,n){const r=function(e,t){const n=Object(a.findOptimalInsertionRange)(e,t).start.parent;if(n.isEmpty&&!n.is("element","$root"))return n.parent;return n}(e,n);return t.checkChild(r,"rawHtml")}(n,t,e)}execute(){const e=this.editor.model;e.change(t=>{const n=t.createElement("rawHtml");e.insertContent(n),t.setSelection(n,"on")})}}class l extends r.Command{refresh(){const e=d(this.editor.model.document.selection);this.isEnabled=!!e}execute(e){const t=this.editor.model,n=d(t.document.selection);t.change(t=>{t.setAttribute("value",e,n)})}}function d(e){const t=e.getSelectedElement();return t&&t.is("element","rawHtml")?t:null}n(5);class s extends r.Plugin{static get pluginName(){return"HtmlEmbedEditing"}constructor(e){super(e),e.config.define("htmlEmbed",{showPreviews:!1,sanitizeHtml:e=>(Object(o.logWarning)("html-embed-provide-sanitize-function"),{html:e,hasChanged:!1})})}init(){const e=this.editor;e.model.schema.register("rawHtml",{isObject:!0,allowWhere:"$block",allowAttributes:["value"]}),e.commands.add("updateHtmlEmbed",new l(e)),e.commands.add("insertHtmlEmbed",new c(e)),this._setupConversion()}_setupConversion(){const e=this.editor,t=e.t,n=e.editing.view,r=e.config.get("htmlEmbed");function i({domElement:e,editor:n,state:r,props:a}){e.textContent="";const i=e.ownerDocument;let l;if(r.isEditable){const t={isDisabled:!1,placeholder:a.textareaPlaceholder};l=c({domDocument:i,state:r,props:t}),e.append(l)}else if(r.showPreviews){const c={sanitizeHtml:a.sanitizeHtml};e.append(function({domDocument:e,state:n,props:r,editor:a}){const i=r.sanitizeHtml(n.getRawHtmlValue()),c=n.getRawHtmlValue().length>0?t("No preview available"):t("Empty snippet content"),l=Object(o.createElement)(e,"div",{class:"ck ck-reset_all raw-html-embed__preview-placeholder"},c),d=Object(o.createElement)(e,"div",{class:"raw-html-embed__preview-content",dir:a.locale.contentLanguageDirection}),s=e.createRange().createContextualFragment(i.html);d.appendChild(s);return Object(o.createElement)(e,"div",{class:"raw-html-embed__preview"},[l,d])}({domDocument:i,state:r,props:c,editor:n}))}else{const t={isDisabled:!0,placeholder:a.textareaPlaceholder};e.append(c({domDocument:i,state:r,props:t}))}const d={onEditClick:a.onEditClick,onSaveClick:()=>{a.onSaveClick(l.value)},onCancelClick:a.onCancelClick};e.prepend(function({editor:e,domDocument:t,state:n,props:r}){const a=Object(o.createElement)(t,"div",{class:"raw-html-embed__buttons-wrapper"}),i=m(e,"edit"),c=m(e,"save"),l=m(e,"cancel");if(n.isEditable){const e=c.cloneNode(!0),t=l.cloneNode(!0);e.addEventListener("click",e=>{e.preventDefault(),r.onSaveClick()}),t.addEventListener("click",e=>{e.preventDefault(),r.onCancelClick()}),a.appendChild(e),a.appendChild(t)}else{const e=i.cloneNode(!0);e.addEventListener("click",e=>{e.preventDefault(),r.onEditClick()}),a.appendChild(e)}return a}({editor:n,domDocument:i,state:r,props:d}))}function c({domDocument:e,state:t,props:n}){const r=Object(o.createElement)(e,"textarea",{placeholder:n.placeholder,class:"ck ck-reset ck-input ck-input-text raw-html-embed__source"});return r.disabled=n.isDisabled,r.value=t.getRawHtmlValue(),r}e.data.registerRawContentMatcher({name:"div",classes:"raw-html-embed"}),e.conversion.for("upcast").elementToElement({view:{name:"div",classes:"raw-html-embed"},model:(e,{writer:t})=>t.createElement("rawHtml",{value:e.getCustomProperty("$rawContent")})}),e.conversion.for("dataDowncast").elementToElement({model:"rawHtml",view:(e,{writer:t})=>t.createRawElement("div",{class:"raw-html-embed"},(function(t){t.innerHTML=e.getAttribute("value")||""}))}),e.conversion.for("editingDowncast").elementToElement({triggerBy:{attributes:["value"]},model:"rawHtml",view:(o,{writer:c})=>{let l,d,s;const m=c.createContainerElement("div",{class:"raw-html-embed","data-html-embed-label":t("HTML snippet"),dir:e.locale.uiLanguageDirection}),u=c.createRawElement("div",{class:"raw-html-embed__content-wrapper"},(function(t){l=t,i({domElement:t,editor:e,state:d,props:s}),l.addEventListener("mousedown",()=>{if(d.isEditable){const t=e.model;t.document.selection.getSelectedElement()!==o&&t.change(e=>e.setSelection(o,"on"))}},!0)})),b={makeEditable(){d=Object.assign({},d,{isEditable:!0}),i({domElement:l,editor:e,state:d,props:s}),n.change(e=>{e.setAttribute("data-cke-ignore-events","true",u)}),l.querySelector("textarea").focus()},save(t){t!==d.getRawHtmlValue()?(e.execute("updateHtmlEmbed",t),e.editing.view.focus()):this.cancel()},cancel(){d=Object.assign({},d,{isEditable:!1}),i({domElement:l,editor:e,state:d,props:s}),e.editing.view.focus(),n.change(e=>{e.removeAttribute("data-cke-ignore-events",u)})}};return d={showPreviews:r.showPreviews,isEditable:!1,getRawHtmlValue:()=>o.getAttribute("value")||""},s={sanitizeHtml:r.sanitizeHtml,textareaPlaceholder:t("Paste raw HTML here..."),onEditClick(){b.makeEditable()},onSaveClick(e){b.save(e)},onCancelClick(){b.cancel()}},c.insert(c.createPositionAt(m,0),u),c.setCustomProperty("rawHtmlApi",b,m),c.setCustomProperty("rawHtml",!0,m),Object(a.toWidget)(m,c,{widgetLabel:t("HTML snippet"),hasSelectionHandle:!0})}})}}function m(e,t){const n=e.locale.t,a=new i.ButtonView(e.locale),o=e.commands.get("updateHtmlEmbed");return a.set({tooltipPosition:"rtl"===e.locale.uiLanguageDirection?"e":"w",icon:r.icons.pencil,tooltip:!0}),a.render(),"edit"===t?a.set({icon:r.icons.pencil,label:n("Edit source"),class:"raw-html-embed__edit-button"}):"save"===t?(a.set({icon:r.icons.check,label:n("Save changes"),class:"raw-html-embed__save-button"}),a.bind("isEnabled").to(o,"isEnabled")):a.set({icon:r.icons.cancel,label:n("Cancel"),class:"raw-html-embed__cancel-button"}),a.destroy(),a.element.cloneNode(!0)}class u extends r.Plugin{static get pluginName(){return"HtmlEmbedUI"}init(){const e=this.editor,t=e.t;e.ui.componentFactory.add("htmlEmbed",n=>{const r=e.commands.get("insertHtmlEmbed"),a=new i.ButtonView(n);return a.set({label:t("Insert HTML"),icon:'<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M17 0a2 2 0 0 1 2 2v7a1 1 0 0 1 1 1v5a1 1 0 0 1-.883.993l-.118.006L19 17a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2l-.001-1.001-.116-.006A1 1 0 0 1 0 15v-5a1 1 0 0 1 .999-1L1 2a2 2 0 0 1 2-2h14zm.499 15.999h-15L2.5 17a.5.5 0 0 0 .5.5h14a.5.5 0 0 0 .5-.5l-.001-1.001zm-3.478-6.013-.014.014H14v.007l-1.525 1.525-1.46-1.46-.015.013V10h-1v5h1v-3.53l1.428 1.43.048.043.131-.129L14 11.421V15h1v-5h-.965l-.014-.014zM2 10H1v5h1v-2h2v2h1v-5H4v2H2v-2zm7 0H6v1h1v4h1v-4h1v-1zm8 0h-1v5h3v-1h-2v-4zm0-8.5H3a.5.5 0 0 0-.5.5l-.001 6.999h15L17.5 2a.5.5 0 0 0-.5-.5zM10 7v1H4V7h6zm3-2v1H4V5h9zm-3-2v1H4V3h6z"/></svg>',tooltip:!0}),a.bind("isEnabled").to(r,"isEnabled"),this.listenTo(a,"execute",()=>{e.execute("insertHtmlEmbed"),e.editing.view.focus();e.editing.view.document.selection.getSelectedElement().getCustomProperty("rawHtmlApi").makeEditable()}),a})}}class b extends r.Plugin{static get requires(){return[s,u,a.Widget]}static get pluginName(){return"HtmlEmbed"}}}]);
5
+ */(()=>{var e={600:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(609),a=n.n(r)()((function(e){return e[1]}));a.push([e.id,".ck-widget.raw-html-embed{margin:.9em auto;position:relative;display:flow-root;min-width:15em;font-style:normal}.ck-widget.raw-html-embed:before{position:absolute;z-index:1}.ck-widget.raw-html-embed .raw-html-embed__buttons-wrapper{position:absolute;display:flex;flex-direction:column}.ck-widget.raw-html-embed .raw-html-embed__preview{position:relative;overflow:hidden;display:flex}.ck-widget.raw-html-embed .raw-html-embed__preview-content{width:100%;position:relative;margin:auto;display:table;border-collapse:separate;border-spacing:7px}.ck-widget.raw-html-embed .raw-html-embed__preview-placeholder{position:absolute;left:0;top:0;right:0;bottom:0;display:flex;align-items:center;justify-content:center}:root{--ck-html-embed-content-width:calc(100% - var(--ck-icon-size)*1.5);--ck-html-embed-source-height:10em;--ck-html-embed-unfocused-outline-width:1px;--ck-html-embed-content-min-height:calc(var(--ck-icon-size) + var(--ck-spacing-standard));--ck-html-embed-source-disabled-background:var(--ck-color-base-foreground);--ck-html-embed-source-disabled-color:#737373}.ck-widget.raw-html-embed{font-size:var(--ck-font-size-base);background-color:var(--ck-color-base-foreground)}.ck-widget.raw-html-embed:not(.ck-widget_selected):not(:hover){outline:var(--ck-html-embed-unfocused-outline-width) dashed var(--ck-color-widget-blurred-border)}.ck-widget.raw-html-embed[dir=ltr]{text-align:left}.ck-widget.raw-html-embed[dir=rtl]{text-align:right}.ck-widget.raw-html-embed:before{content:attr(data-html-embed-label);top:calc(var(--ck-html-embed-unfocused-outline-width)*-1);left:var(--ck-spacing-standard);background:#999;transition:background var(--ck-widget-handler-animation-duration) var(--ck-widget-handler-animation-curve);padding:calc(var(--ck-spacing-tiny) + var(--ck-html-embed-unfocused-outline-width)) var(--ck-spacing-small) var(--ck-spacing-tiny);border-radius:0 0 var(--ck-border-radius) var(--ck-border-radius);color:var(--ck-color-base-background);font-size:var(--ck-font-size-tiny);font-family:var(--ck-font-face)}.ck-widget.raw-html-embed[dir=rtl]:before{left:auto;right:var(--ck-spacing-standard)}.ck-widget.raw-html-embed[dir=ltr] .ck-widget__type-around .ck-widget__type-around__button.ck-widget__type-around__button_before{margin-left:50px}.ck.ck-editor__editable.ck-blurred .ck-widget.raw-html-embed.ck-widget_selected:before{top:0;padding:var(--ck-spacing-tiny) var(--ck-spacing-small)}.ck.ck-editor__editable:not(.ck-blurred) .ck-widget.raw-html-embed.ck-widget_selected:before{top:0;padding:var(--ck-spacing-tiny) var(--ck-spacing-small);background:var(--ck-color-focus-border)}.ck.ck-editor__editable .ck-widget.raw-html-embed:not(.ck-widget_selected):hover:before{top:0;padding:var(--ck-spacing-tiny) var(--ck-spacing-small)}.ck-widget.raw-html-embed .raw-html-embed__content-wrapper{padding:var(--ck-spacing-standard)}.ck-widget.raw-html-embed .raw-html-embed__buttons-wrapper{top:var(--ck-spacing-standard);right:var(--ck-spacing-standard)}.ck-widget.raw-html-embed .raw-html-embed__buttons-wrapper .ck-button.raw-html-embed__save-button{color:var(--ck-color-button-save)}.ck-widget.raw-html-embed .raw-html-embed__buttons-wrapper .ck-button.raw-html-embed__cancel-button{color:var(--ck-color-button-cancel)}.ck-widget.raw-html-embed .raw-html-embed__buttons-wrapper .ck-button:not(:first-child){margin-top:var(--ck-spacing-small)}.ck-widget.raw-html-embed[dir=rtl] .raw-html-embed__buttons-wrapper{left:var(--ck-spacing-standard);right:auto}.ck-widget.raw-html-embed .raw-html-embed__source{box-sizing:border-box;height:var(--ck-html-embed-source-height);width:var(--ck-html-embed-content-width);resize:none;min-width:0;padding:var(--ck-spacing-standard);font-family:monospace;tab-size:4;white-space:pre-wrap;font-size:var(--ck-font-size-base);text-align:left;direction:ltr}.ck-widget.raw-html-embed .raw-html-embed__source[disabled]{background:var(--ck-html-embed-source-disabled-background);color:var(--ck-html-embed-source-disabled-color);-webkit-text-fill-color:var(--ck-html-embed-source-disabled-color);opacity:1}.ck-widget.raw-html-embed .raw-html-embed__preview{min-height:var(--ck-html-embed-content-min-height);width:var(--ck-html-embed-content-width)}.ck-editor__editable:not(.ck-read-only) .ck-widget.raw-html-embed .raw-html-embed__preview{pointer-events:none}.ck-widget.raw-html-embed .raw-html-embed__preview-content{box-sizing:border-box;background-color:var(--ck-color-base-foreground)}.ck-widget.raw-html-embed .raw-html-embed__preview-content>*{margin-left:auto;margin-right:auto}.ck-widget.raw-html-embed .raw-html-embed__preview-placeholder{color:var(--ck-html-embed-source-disabled-color)}",""]);const i=a},609:e=>{"use strict";e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var n=e(t);return t[2]?"@media ".concat(t[2]," {").concat(n,"}"):n})).join("")},t.i=function(e,n,r){"string"==typeof e&&(e=[[null,e,""]]);var a={};if(r)for(var i=0;i<this.length;i++){var o=this[i][0];null!=o&&(a[o]=!0)}for(var c=0;c<e.length;c++){var l=[].concat(e[c]);r&&a[l[0]]||(n&&(l[2]?l[2]="".concat(n," and ").concat(l[2]):l[2]=n),t.push(l))}},t}},62:(e,t,n)=>{"use strict";var r,a=function(){return void 0===r&&(r=Boolean(window&&document&&document.all&&!window.atob)),r},i=function(){var e={};return function(t){if(void 0===e[t]){var n=document.querySelector(t);if(window.HTMLIFrameElement&&n instanceof window.HTMLIFrameElement)try{n=n.contentDocument.head}catch(e){n=null}e[t]=n}return e[t]}}(),o=[];function c(e){for(var t=-1,n=0;n<o.length;n++)if(o[n].identifier===e){t=n;break}return t}function l(e,t){for(var n={},r=[],a=0;a<e.length;a++){var i=e[a],l=t.base?i[0]+t.base:i[0],d=n[l]||0,s="".concat(l," ").concat(d);n[l]=d+1;var m=c(s),u={css:i[1],media:i[2],sourceMap:i[3]};-1!==m?(o[m].references++,o[m].updater(u)):o.push({identifier:s,updater:w(u,t),references:1}),r.push(s)}return r}function d(e){var t=document.createElement("style"),r=e.attributes||{};if(void 0===r.nonce){var a=n.nc;a&&(r.nonce=a)}if(Object.keys(r).forEach((function(e){t.setAttribute(e,r[e])})),"function"==typeof e.insert)e.insert(t);else{var o=i(e.insert||"head");if(!o)throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");o.appendChild(t)}return t}var s,m=(s=[],function(e,t){return s[e]=t,s.filter(Boolean).join("\n")});function u(e,t,n,r){var a=n?"":r.media?"@media ".concat(r.media," {").concat(r.css,"}"):r.css;if(e.styleSheet)e.styleSheet.cssText=m(t,a);else{var i=document.createTextNode(a),o=e.childNodes;o[t]&&e.removeChild(o[t]),o.length?e.insertBefore(i,o[t]):e.appendChild(i)}}function b(e,t,n){var r=n.css,a=n.media,i=n.sourceMap;if(a?e.setAttribute("media",a):e.removeAttribute("media"),i&&"undefined"!=typeof btoa&&(r+="\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(i))))," */")),e.styleSheet)e.styleSheet.cssText=r;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(r))}}var h=null,p=0;function w(e,t){var n,r,a;if(t.singleton){var i=p++;n=h||(h=d(t)),r=u.bind(null,n,i,!1),a=u.bind(null,n,i,!0)}else n=d(t),r=b.bind(null,n,t),a=function(){!function(e){if(null===e.parentNode)return!1;e.parentNode.removeChild(e)}(n)};return r(e),function(t){if(t){if(t.css===e.css&&t.media===e.media&&t.sourceMap===e.sourceMap)return;r(e=t)}else a()}}e.exports=function(e,t){(t=t||{}).singleton||"boolean"==typeof t.singleton||(t.singleton=a());var n=l(e=e||[],t);return function(e){if(e=e||[],"[object Array]"===Object.prototype.toString.call(e)){for(var r=0;r<n.length;r++){var a=c(n[r]);o[a].references--}for(var i=l(e,t),d=0;d<n.length;d++){var s=c(n[d]);0===o[s].references&&(o[s].updater(),o.splice(s,1))}n=i}}}},704:(e,t,n)=>{e.exports=n(79)("./src/core.js")},273:(e,t,n)=>{e.exports=n(79)("./src/ui.js")},209:(e,t,n)=>{e.exports=n(79)("./src/utils.js")},995:(e,t,n)=>{e.exports=n(79)("./src/widget.js")},79:e=>{"use strict";e.exports=CKEditor5.dll}},t={};function n(r){var a=t[r];if(void 0!==a)return a.exports;var i=t[r]={id:r,exports:{}};return e[r](i,i.exports,n),i.exports}n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var r={};(()=>{"use strict";n.r(r),n.d(r,{HtmlEmbed:()=>p,HtmlEmbedEditing:()=>u,HtmlEmbedUI:()=>h});var e=n(704),t=n(995),a=n(273),i=n(209);class o extends e.Command{refresh(){const e=this.editor.model,n=e.schema,r=e.document.selection,a=c(r);this.isEnabled=function(e,n,r){const a=function(e,n){const r=(0,t.findOptimalInsertionRange)(e,n).start.parent;if(r.isEmpty&&!r.is("element","$root"))return r.parent;return r}(e,r);return n.checkChild(a,"rawHtml")}(r,n,e),this.value=a?a.getAttribute("value")||"":null}execute(e){const t=this.editor.model,n=t.document.selection;t.change((r=>{let a;null!==this.value?a=c(n):(a=r.createElement("rawHtml"),t.insertContent(a),r.setSelection(a,"on")),r.setAttribute("value",e,a)}))}}function c(e){const t=e.getSelectedElement();return t&&t.is("element","rawHtml")?t:null}var l=n(62),d=n.n(l),s=n(600),m={injectType:"singletonStyleTag",attributes:{"data-cke":!0},insert:"head",singleton:!0};d()(s.Z,m);s.Z.locals;class u extends e.Plugin{static get pluginName(){return"HtmlEmbedEditing"}constructor(e){super(e),e.config.define("htmlEmbed",{showPreviews:!1,sanitizeHtml:e=>((0,i.logWarning)("html-embed-provide-sanitize-function"),{html:e,hasChanged:!1})}),this._widgetButtonViewReferences=new Set}init(){const e=this.editor;e.model.schema.register("rawHtml",{isObject:!0,allowWhere:"$block",allowAttributes:["value"]}),e.commands.add("htmlEmbed",new o(e)),this._setupConversion()}_setupConversion(){const e=this.editor,n=e.t,r=e.editing.view,a=this._widgetButtonViewReferences,o=e.config.get("htmlEmbed");function c({domElement:e,editor:t,state:r,props:o}){e.textContent="";const c=e.ownerDocument;let d;if(r.isEditable){const t={isDisabled:!1,placeholder:o.textareaPlaceholder};d=l({domDocument:c,state:r,props:t}),e.append(d)}else if(r.showPreviews){const a={sanitizeHtml:o.sanitizeHtml};e.append(function({domDocument:e,state:t,props:r,editor:a}){const o=r.sanitizeHtml(t.getRawHtmlValue()),c=t.getRawHtmlValue().length>0?n("No preview available"):n("Empty snippet content"),l=(0,i.createElement)(e,"div",{class:"ck ck-reset_all raw-html-embed__preview-placeholder"},c),d=(0,i.createElement)(e,"div",{class:"raw-html-embed__preview-content",dir:a.locale.contentLanguageDirection}),s=e.createRange().createContextualFragment(o.html);d.appendChild(s);return(0,i.createElement)(e,"div",{class:"raw-html-embed__preview"},[l,d])}({domDocument:c,state:r,props:a,editor:t}))}else{const t={isDisabled:!0,placeholder:o.textareaPlaceholder};e.append(l({domDocument:c,state:r,props:t}))}const s={onEditClick:o.onEditClick,onSaveClick:()=>{o.onSaveClick(d.value)},onCancelClick:o.onCancelClick};e.prepend(function({editor:e,domDocument:t,state:n,props:r}){const o=(0,i.createElement)(t,"div",{class:"raw-html-embed__buttons-wrapper"});if(n.isEditable){const t=b(e,"save",r.onSaveClick),n=b(e,"cancel",r.onCancelClick);o.append(t.element,n.element),a.add(t).add(n)}else{const t=b(e,"edit",r.onEditClick);o.append(t.element),a.add(t)}return o}({editor:t,domDocument:c,state:r,props:s}))}function l({domDocument:e,state:t,props:n}){const r=(0,i.createElement)(e,"textarea",{placeholder:n.placeholder,class:"ck ck-reset ck-input ck-input-text raw-html-embed__source"});return r.disabled=n.isDisabled,r.value=t.getRawHtmlValue(),r}this.editor.editing.view.on("render",(()=>{for(const e of a){if(e.element.isConnected)return;e.destroy(),a.delete(e)}}),{priority:"lowest"}),e.data.registerRawContentMatcher({name:"div",classes:"raw-html-embed"}),e.conversion.for("upcast").elementToElement({view:{name:"div",classes:"raw-html-embed"},model:(e,{writer:t})=>t.createElement("rawHtml",{value:e.getCustomProperty("$rawContent")})}),e.conversion.for("dataDowncast").elementToElement({model:"rawHtml",view:(e,{writer:t})=>t.createRawElement("div",{class:"raw-html-embed"},(function(t){t.innerHTML=e.getAttribute("value")||""}))}),e.conversion.for("editingDowncast").elementToElement({triggerBy:{attributes:["value"]},model:"rawHtml",view:(a,{writer:i})=>{let l,d,s;const m=i.createContainerElement("div",{class:"raw-html-embed","data-html-embed-label":n("HTML snippet"),dir:e.locale.uiLanguageDirection}),u=i.createRawElement("div",{class:"raw-html-embed__content-wrapper"},(function(t){l=t,c({domElement:t,editor:e,state:d,props:s}),l.addEventListener("mousedown",(()=>{if(d.isEditable){const t=e.model;t.document.selection.getSelectedElement()!==a&&t.change((e=>e.setSelection(a,"on")))}}),!0)})),b={makeEditable(){d=Object.assign({},d,{isEditable:!0}),c({domElement:l,editor:e,state:d,props:s}),r.change((e=>{e.setAttribute("data-cke-ignore-events","true",u)})),l.querySelector("textarea").focus()},save(t){t!==d.getRawHtmlValue()?(e.execute("htmlEmbed",t),e.editing.view.focus()):this.cancel()},cancel(){d=Object.assign({},d,{isEditable:!1}),c({domElement:l,editor:e,state:d,props:s}),e.editing.view.focus(),r.change((e=>{e.removeAttribute("data-cke-ignore-events",u)}))}};return d={showPreviews:o.showPreviews,isEditable:!1,getRawHtmlValue:()=>a.getAttribute("value")||""},s={sanitizeHtml:o.sanitizeHtml,textareaPlaceholder:n("Paste raw HTML here..."),onEditClick(){b.makeEditable()},onSaveClick(e){b.save(e)},onCancelClick(){b.cancel()}},i.insert(i.createPositionAt(m,0),u),i.setCustomProperty("rawHtmlApi",b,m),i.setCustomProperty("rawHtml",!0,m),(0,t.toWidget)(m,i,{widgetLabel:n("HTML snippet"),hasSelectionHandle:!0})}})}}function b(t,n,r){const i=t.locale.t,o=new a.ButtonView(t.locale),c=t.commands.get("htmlEmbed");return o.set({class:`raw-html-embed__${n}-button`,icon:e.icons.pencil,tooltip:!0,tooltipPosition:"rtl"===t.locale.uiLanguageDirection?"e":"w"}),o.render(),"edit"===n?(o.set({icon:e.icons.pencil,label:i("Edit source")}),o.bind("isEnabled").to(c)):"save"===n?(o.set({icon:e.icons.check,label:i("Save changes")}),o.bind("isEnabled").to(c)):o.set({icon:e.icons.cancel,label:i("Cancel")}),o.on("execute",r),o}class h extends e.Plugin{static get pluginName(){return"HtmlEmbedUI"}init(){const e=this.editor,t=e.t;e.ui.componentFactory.add("htmlEmbed",(n=>{const r=e.commands.get("htmlEmbed"),i=new a.ButtonView(n);return i.set({label:t("Insert HTML"),icon:'<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M17 0a2 2 0 0 1 2 2v7a1 1 0 0 1 1 1v5a1 1 0 0 1-.883.993l-.118.006L19 17a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2l-.001-1.001-.116-.006A1 1 0 0 1 0 15v-5a1 1 0 0 1 .999-1L1 2a2 2 0 0 1 2-2h14zm.499 15.999h-15L2.5 17a.5.5 0 0 0 .5.5h14a.5.5 0 0 0 .5-.5l-.001-1.001zm-3.478-6.013-.014.014H14v.007l-1.525 1.525-1.46-1.46-.015.013V10h-1v5h1v-3.53l1.428 1.43.048.043.131-.129L14 11.421V15h1v-5h-.965l-.014-.014zM2 10H1v5h1v-2h2v2h1v-5H4v2H2v-2zm7 0H6v1h1v4h1v-4h1v-1zm8 0h-1v5h3v-1h-2v-4zm0-8.5H3a.5.5 0 0 0-.5.5l-.001 6.999h15L17.5 2a.5.5 0 0 0-.5-.5zM10 7v1H4V7h6zm3-2v1H4V5h9zm-3-2v1H4V3h6z"/></svg>',tooltip:!0}),i.bind("isEnabled").to(r,"isEnabled"),this.listenTo(i,"execute",(()=>{e.execute("htmlEmbed"),e.editing.view.focus();e.editing.view.document.selection.getSelectedElement().getCustomProperty("rawHtmlApi").makeEditable()})),i}))}}class p extends e.Plugin{static get requires(){return[u,h,t.Widget]}static get pluginName(){return"HtmlEmbed"}}})(),(window.CKEditor5=window.CKEditor5||{}).htmlEmbed=r})();
@@ -0,0 +1 @@
1
+ !function(e){const a=e.bs=e.bs||{};a.dictionary=Object.assign(a.dictionary||{},{"Edit source":"Uredi izvor","Empty snippet content":"HTML odlomak nema sadžaj","HTML snippet":"HTML odlomak","Insert HTML":"Umetni HTML","No preview available":"Pregled nedostupan","Paste raw HTML here...":"Zalijepi HTML ovdje...","Save changes":"Sačuvaj izmjene"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
@@ -1 +1 @@
1
- !function(e){const n=e.nl=e.nl||{};n.dictionary=Object.assign(n.dictionary||{},{"Edit source":"","Empty snippet content":"","HTML snippet":"","Insert HTML":"","No preview available":"Geen voorbeeld beschikbaar","Paste raw HTML here...":"","Save changes":""})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
1
+ !function(e){const n=e.nl=e.nl||{};n.dictionary=Object.assign(n.dictionary||{},{"Edit source":"Bron bewerken","Empty snippet content":"","HTML snippet":"","Insert HTML":"HTML invoegen","No preview available":"Geen voorbeeld beschikbaar","Paste raw HTML here...":"","Save changes":"Aanpassingen bewaren"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
@@ -1 +1 @@
1
- !function(t){const n=t.pl=t.pl||{};n.dictionary=Object.assign(n.dictionary||{},{"Edit source":"Edytuj źródło","Empty snippet content":"","HTML snippet":"","Insert HTML":"Wstaw kod HTML","No preview available":"Podgląd nie jest dostępny","Paste raw HTML here...":"Wstaw tutaj czysty kod HTML...","Save changes":"Zapisz zmiany"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
1
+ !function(t){const n=t.pl=t.pl||{};n.dictionary=Object.assign(n.dictionary||{},{"Edit source":"Edytuj źródło","Empty snippet content":"Brak kodu","HTML snippet":"Kod HTML","Insert HTML":"Wstaw kod HTML","No preview available":"Podgląd nie jest dostępny","Paste raw HTML here...":"Wstaw tutaj czysty kod HTML...","Save changes":"Zapisz zmiany"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
@@ -1 +1 @@
1
- !function(e){const t=e["pt-br"]=e["pt-br"]||{};t.dictionary=Object.assign(t.dictionary||{},{"Edit source":"Editar código","Empty snippet content":"","HTML snippet":"Snippet HTML","Insert HTML":"Inserir HTML","No preview available":"","Paste raw HTML here...":"","Save changes":"Salvar alterações"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
1
+ !function(e){const i=e["pt-br"]=e["pt-br"]||{};i.dictionary=Object.assign(i.dictionary||{},{"Edit source":"Editar código","Empty snippet content":"Trecho sem conteúdo","HTML snippet":"Trecho HTML","Insert HTML":"Inserir HTML","No preview available":"Nenhuma visualização disponível","Paste raw HTML here...":"Cole o HTML puro aqui","Save changes":"Salvar alterações"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
@@ -0,0 +1 @@
1
+ !function(i){const n=i.uz=i.uz||{};n.dictionary=Object.assign(n.dictionary||{},{"Edit source":"Kodni o'zgartirish","Empty snippet content":"","HTML snippet":"HTML snippet","Insert HTML":"HTML kiritish","No preview available":"","Paste raw HTML here...":"HTML kodini shu yerga joylashtiring...","Save changes":"O'zgarishlarni saqlash"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
@@ -1 +1 @@
1
- !function(n){const e=n["zh-cn"]=n["zh-cn"]||{};e.dictionary=Object.assign(e.dictionary||{},{"Edit source":"编辑源代码","Empty snippet content":"","HTML snippet":"HTML 代码片段","Insert HTML":"插入 HTML","No preview available":"","Paste raw HTML here...":"在这里粘贴 HTML 源代码","Save changes":"保存更改"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
1
+ !function(n){const e=n["zh-cn"]=n["zh-cn"]||{};e.dictionary=Object.assign(e.dictionary||{},{"Edit source":"编辑源代码","Empty snippet content":"空片段内容","HTML snippet":"HTML 代码片段","Insert HTML":"插入 HTML","No preview available":"预览不可用","Paste raw HTML here...":"在这里粘贴 HTML 源代码","Save changes":"保存更改"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
@@ -0,0 +1 @@
1
+ !function(e){const n=e.zh=e.zh||{};n.dictionary=Object.assign(n.dictionary||{},{"Edit source":"編輯HTML","Empty snippet content":"HTML標籤中無內容","HTML snippet":"HTML標籤","Insert HTML":"輸入HTML","No preview available":"無法顯示預覽","Paste raw HTML here...":"在此貼上純HTML","Save changes":"儲存變更"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
@@ -22,6 +22,7 @@
22
22
  "elements": "*",
23
23
  "classes": "*",
24
24
  "styles": "*",
25
+ "isAlternative": true,
25
26
  "_comment": "The plugin can output any arbitrary HTML provided by the user. That HTML is always wrapped with a `<div class=\"raw-html-embed\">` element."
26
27
  }
27
28
  ]
@@ -0,0 +1,45 @@
1
+ # Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ #
3
+ # !!! IMPORTANT !!!
4
+ #
5
+ # Before you edit this file, please keep in mind that contributing to the project
6
+ # translations is possible ONLY via the Transifex online service.
7
+ #
8
+ # To submit your translations, visit https://www.transifex.com/ckeditor/ckeditor5.
9
+ #
10
+ # To learn more, check out the official contributor's guide:
11
+ # https://ckeditor.com/docs/ckeditor5/latest/framework/guides/contributing/contributing.html
12
+ #
13
+ msgid ""
14
+ msgstr ""
15
+ "Language-Team: Bosnian (https://www.transifex.com/ckeditor/teams/11143/bs/)\n"
16
+ "Language: bs\n"
17
+ "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
18
+
19
+ msgctxt "Toolbar button tooltip for the HTML embed feature."
20
+ msgid "Insert HTML"
21
+ msgstr "Umetni HTML"
22
+
23
+ msgctxt "The HTML snippet."
24
+ msgid "HTML snippet"
25
+ msgstr "HTML odlomak"
26
+
27
+ msgctxt "A placeholder that will be displayed in the raw HTML textarea field."
28
+ msgid "Paste raw HTML here..."
29
+ msgstr "Zalijepi HTML ovdje..."
30
+
31
+ msgctxt "A label of a button that switches the HTML embed to the source editing mode."
32
+ msgid "Edit source"
33
+ msgstr "Uredi izvor"
34
+
35
+ msgctxt "A label of a button that saves the HTML embed content and navigates back to the preview."
36
+ msgid "Save changes"
37
+ msgstr "Sačuvaj izmjene"
38
+
39
+ msgctxt "An information displayed in the HTML embed preview if the content is not previewable."
40
+ msgid "No preview available"
41
+ msgstr "Pregled nedostupan"
42
+
43
+ msgctxt "An information displayed in the HTML embed preview if the HTML snippet has no content."
44
+ msgid "Empty snippet content"
45
+ msgstr "HTML odlomak nema sadžaj"
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
1
+ # Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
2
  #
3
3
  # !!! IMPORTANT !!!
4
4
  #
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
1
+ # Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
2
  #
3
3
  # !!! IMPORTANT !!!
4
4
  #
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
1
+ # Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
2
  #
3
3
  # !!! IMPORTANT !!!
4
4
  #
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
1
+ # Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
2
  #
3
3
  # !!! IMPORTANT !!!
4
4
  #
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
1
+ # Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
2
  #
3
3
  # !!! IMPORTANT !!!
4
4
  #
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
1
+ # Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
2
  #
3
3
  # !!! IMPORTANT !!!
4
4
  #
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
1
+ # Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
2
  #
3
3
  # !!! IMPORTANT !!!
4
4
  #
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
1
+ # Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
2
  #
3
3
  # !!! IMPORTANT !!!
4
4
  #
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
1
+ # Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
2
  #
3
3
  # !!! IMPORTANT !!!
4
4
  #
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
1
+ # Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
2
  #
3
3
  # !!! IMPORTANT !!!
4
4
  #
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
1
+ # Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
2
  #
3
3
  # !!! IMPORTANT !!!
4
4
  #
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
1
+ # Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
2
  #
3
3
  # !!! IMPORTANT !!!
4
4
  #
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
1
+ # Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
2
  #
3
3
  # !!! IMPORTANT !!!
4
4
  #
@@ -18,7 +18,7 @@ msgstr ""
18
18
 
19
19
  msgctxt "Toolbar button tooltip for the HTML embed feature."
20
20
  msgid "Insert HTML"
21
- msgstr ""
21
+ msgstr "HTML invoegen"
22
22
 
23
23
  msgctxt "The HTML snippet."
24
24
  msgid "HTML snippet"
@@ -30,11 +30,11 @@ msgstr ""
30
30
 
31
31
  msgctxt "A label of a button that switches the HTML embed to the source editing mode."
32
32
  msgid "Edit source"
33
- msgstr ""
33
+ msgstr "Bron bewerken"
34
34
 
35
35
  msgctxt "A label of a button that saves the HTML embed content and navigates back to the preview."
36
36
  msgid "Save changes"
37
- msgstr ""
37
+ msgstr "Aanpassingen bewaren"
38
38
 
39
39
  msgctxt "An information displayed in the HTML embed preview if the content is not previewable."
40
40
  msgid "No preview available"
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
1
+ # Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
2
  #
3
3
  # !!! IMPORTANT !!!
4
4
  #
@@ -22,7 +22,7 @@ msgstr "Wstaw kod HTML"
22
22
 
23
23
  msgctxt "The HTML snippet."
24
24
  msgid "HTML snippet"
25
- msgstr ""
25
+ msgstr "Kod HTML"
26
26
 
27
27
  msgctxt "A placeholder that will be displayed in the raw HTML textarea field."
28
28
  msgid "Paste raw HTML here..."
@@ -42,4 +42,4 @@ msgstr "Podgląd nie jest dostępny"
42
42
 
43
43
  msgctxt "An information displayed in the HTML embed preview if the HTML snippet has no content."
44
44
  msgid "Empty snippet content"
45
- msgstr ""
45
+ msgstr "Brak kodu"
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
1
+ # Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
2
  #
3
3
  # !!! IMPORTANT !!!
4
4
  #
@@ -22,11 +22,11 @@ msgstr "Inserir HTML"
22
22
 
23
23
  msgctxt "The HTML snippet."
24
24
  msgid "HTML snippet"
25
- msgstr "Snippet HTML"
25
+ msgstr "Trecho HTML"
26
26
 
27
27
  msgctxt "A placeholder that will be displayed in the raw HTML textarea field."
28
28
  msgid "Paste raw HTML here..."
29
- msgstr ""
29
+ msgstr "Cole o HTML puro aqui"
30
30
 
31
31
  msgctxt "A label of a button that switches the HTML embed to the source editing mode."
32
32
  msgid "Edit source"
@@ -38,8 +38,8 @@ msgstr "Salvar alterações"
38
38
 
39
39
  msgctxt "An information displayed in the HTML embed preview if the content is not previewable."
40
40
  msgid "No preview available"
41
- msgstr ""
41
+ msgstr "Nenhuma visualização disponível"
42
42
 
43
43
  msgctxt "An information displayed in the HTML embed preview if the HTML snippet has no content."
44
44
  msgid "Empty snippet content"
45
- msgstr ""
45
+ msgstr "Trecho sem conteúdo"
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
1
+ # Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
2
  #
3
3
  # !!! IMPORTANT !!!
4
4
  #
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
1
+ # Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
2
  #
3
3
  # !!! IMPORTANT !!!
4
4
  #
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
1
+ # Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
2
  #
3
3
  # !!! IMPORTANT !!!
4
4
  #
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
1
+ # Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
2
  #
3
3
  # !!! IMPORTANT !!!
4
4
  #
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
1
+ # Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
2
  #
3
3
  # !!! IMPORTANT !!!
4
4
  #
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
1
+ # Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
2
  #
3
3
  # !!! IMPORTANT !!!
4
4
  #
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
1
+ # Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
2
  #
3
3
  # !!! IMPORTANT !!!
4
4
  #
@@ -0,0 +1,45 @@
1
+ # Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ #
3
+ # !!! IMPORTANT !!!
4
+ #
5
+ # Before you edit this file, please keep in mind that contributing to the project
6
+ # translations is possible ONLY via the Transifex online service.
7
+ #
8
+ # To submit your translations, visit https://www.transifex.com/ckeditor/ckeditor5.
9
+ #
10
+ # To learn more, check out the official contributor's guide:
11
+ # https://ckeditor.com/docs/ckeditor5/latest/framework/guides/contributing/contributing.html
12
+ #
13
+ msgid ""
14
+ msgstr ""
15
+ "Language-Team: Uzbek (https://www.transifex.com/ckeditor/teams/11143/uz/)\n"
16
+ "Language: uz\n"
17
+ "Plural-Forms: nplurals=1; plural=0;\n"
18
+
19
+ msgctxt "Toolbar button tooltip for the HTML embed feature."
20
+ msgid "Insert HTML"
21
+ msgstr "HTML kiritish"
22
+
23
+ msgctxt "The HTML snippet."
24
+ msgid "HTML snippet"
25
+ msgstr "HTML snippet"
26
+
27
+ msgctxt "A placeholder that will be displayed in the raw HTML textarea field."
28
+ msgid "Paste raw HTML here..."
29
+ msgstr "HTML kodini shu yerga joylashtiring..."
30
+
31
+ msgctxt "A label of a button that switches the HTML embed to the source editing mode."
32
+ msgid "Edit source"
33
+ msgstr "Kodni o'zgartirish"
34
+
35
+ msgctxt "A label of a button that saves the HTML embed content and navigates back to the preview."
36
+ msgid "Save changes"
37
+ msgstr "O'zgarishlarni saqlash"
38
+
39
+ msgctxt "An information displayed in the HTML embed preview if the content is not previewable."
40
+ msgid "No preview available"
41
+ msgstr ""
42
+
43
+ msgctxt "An information displayed in the HTML embed preview if the HTML snippet has no content."
44
+ msgid "Empty snippet content"
45
+ msgstr ""
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
1
+ # Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
2
  #
3
3
  # !!! IMPORTANT !!!
4
4
  #
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
1
+ # Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
2
  #
3
3
  # !!! IMPORTANT !!!
4
4
  #
@@ -38,8 +38,8 @@ msgstr "保存更改"
38
38
 
39
39
  msgctxt "An information displayed in the HTML embed preview if the content is not previewable."
40
40
  msgid "No preview available"
41
- msgstr ""
41
+ msgstr "预览不可用"
42
42
 
43
43
  msgctxt "An information displayed in the HTML embed preview if the HTML snippet has no content."
44
44
  msgid "Empty snippet content"
45
- msgstr ""
45
+ msgstr "空片段内容"
@@ -0,0 +1,45 @@
1
+ # Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ #
3
+ # !!! IMPORTANT !!!
4
+ #
5
+ # Before you edit this file, please keep in mind that contributing to the project
6
+ # translations is possible ONLY via the Transifex online service.
7
+ #
8
+ # To submit your translations, visit https://www.transifex.com/ckeditor/ckeditor5.
9
+ #
10
+ # To learn more, check out the official contributor's guide:
11
+ # https://ckeditor.com/docs/ckeditor5/latest/framework/guides/contributing/contributing.html
12
+ #
13
+ msgid ""
14
+ msgstr ""
15
+ "Language-Team: Chinese (Taiwan) (https://www.transifex.com/ckeditor/teams/11143/zh_TW/)\n"
16
+ "Language: zh_TW\n"
17
+ "Plural-Forms: nplurals=1; plural=0;\n"
18
+
19
+ msgctxt "Toolbar button tooltip for the HTML embed feature."
20
+ msgid "Insert HTML"
21
+ msgstr "輸入HTML"
22
+
23
+ msgctxt "The HTML snippet."
24
+ msgid "HTML snippet"
25
+ msgstr "HTML標籤"
26
+
27
+ msgctxt "A placeholder that will be displayed in the raw HTML textarea field."
28
+ msgid "Paste raw HTML here..."
29
+ msgstr "在此貼上純HTML"
30
+
31
+ msgctxt "A label of a button that switches the HTML embed to the source editing mode."
32
+ msgid "Edit source"
33
+ msgstr "編輯HTML"
34
+
35
+ msgctxt "A label of a button that saves the HTML embed content and navigates back to the preview."
36
+ msgid "Save changes"
37
+ msgstr "儲存變更"
38
+
39
+ msgctxt "An information displayed in the HTML embed preview if the content is not previewable."
40
+ msgid "No preview available"
41
+ msgstr "無法顯示預覽"
42
+
43
+ msgctxt "An information displayed in the HTML embed preview if the HTML snippet has no content."
44
+ msgid "Empty snippet content"
45
+ msgstr "HTML標籤中無內容"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ckeditor/ckeditor5-html-embed",
3
- "version": "29.2.0",
3
+ "version": "32.0.0",
4
4
  "description": "HTML embed feature for CKEditor 5.",
5
5
  "keywords": [
6
6
  "ckeditor",
@@ -12,28 +12,28 @@
12
12
  ],
13
13
  "main": "src/index.js",
14
14
  "dependencies": {
15
- "ckeditor5": "^29.2.0"
15
+ "ckeditor5": "^32.0.0"
16
16
  },
17
17
  "devDependencies": {
18
- "@ckeditor/ckeditor5-basic-styles": "^29.2.0",
19
- "@ckeditor/ckeditor5-core": "^29.2.0",
20
- "@ckeditor/ckeditor5-dev-utils": "^25.4.0",
21
- "@ckeditor/ckeditor5-clipboard": "^29.2.0",
22
- "@ckeditor/ckeditor5-editor-classic": "^29.2.0",
23
- "@ckeditor/ckeditor5-engine": "^29.2.0",
24
- "@ckeditor/ckeditor5-media-embed": "^29.2.0",
25
- "@ckeditor/ckeditor5-paragraph": "^29.2.0",
26
- "@ckeditor/ckeditor5-table": "^29.2.0",
27
- "@ckeditor/ckeditor5-ui": "^29.2.0",
28
- "@ckeditor/ckeditor5-theme-lark": "^29.2.0",
29
- "@ckeditor/ckeditor5-widget": "^29.2.0",
18
+ "@ckeditor/ckeditor5-basic-styles": "^32.0.0",
19
+ "@ckeditor/ckeditor5-core": "^32.0.0",
20
+ "@ckeditor/ckeditor5-dev-utils": "^27.1.0",
21
+ "@ckeditor/ckeditor5-clipboard": "^32.0.0",
22
+ "@ckeditor/ckeditor5-editor-classic": "^32.0.0",
23
+ "@ckeditor/ckeditor5-engine": "^32.0.0",
24
+ "@ckeditor/ckeditor5-media-embed": "^32.0.0",
25
+ "@ckeditor/ckeditor5-paragraph": "^32.0.0",
26
+ "@ckeditor/ckeditor5-table": "^32.0.0",
27
+ "@ckeditor/ckeditor5-ui": "^32.0.0",
28
+ "@ckeditor/ckeditor5-theme-lark": "^32.0.0",
29
+ "@ckeditor/ckeditor5-widget": "^32.0.0",
30
30
  "lodash-es": "^4.17.15",
31
31
  "sanitize-html": "^2.1.0",
32
- "webpack": "^4.43.0",
33
- "webpack-cli": "^3.3.11"
32
+ "webpack": "^5.58.1",
33
+ "webpack-cli": "^4.9.0"
34
34
  },
35
35
  "engines": {
36
- "node": ">=12.0.0",
36
+ "node": ">=14.0.0",
37
37
  "npm": ">=5.7.1"
38
38
  },
39
39
  "author": "CKSource (http://cksource.com/)",
package/src/htmlembed.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
@@ -0,0 +1,117 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+
6
+ /**
7
+ * @module html-embed/htmlembedcommand
8
+ */
9
+
10
+ import { Command } from 'ckeditor5/src/core';
11
+ import { findOptimalInsertionRange } from 'ckeditor5/src/widget';
12
+
13
+ /**
14
+ * The insert HTML embed element command.
15
+ *
16
+ * The command is registered by {@link module:html-embed/htmlembedediting~HtmlEmbedEditing} as `'htmlEmbed'`.
17
+ *
18
+ * To insert an empty HTML embed element at the current selection, execute the command:
19
+ *
20
+ * editor.execute( 'htmlEmbed' );
21
+ *
22
+ * You can specify the initial content of a new HTML embed in the argument:
23
+ *
24
+ * editor.execute( 'htmlEmbed', '<b>Initial content.</b>' );
25
+ *
26
+ * To update the content of the HTML embed, select it in the model and pass the content in the argument:
27
+ *
28
+ * editor.execute( 'htmlEmbed', '<b>New content of an existing embed.</b>' );
29
+ *
30
+ * @extends module:core/command~Command
31
+ */
32
+ export default class HtmlEmbedCommand extends Command {
33
+ /**
34
+ * @inheritDoc
35
+ */
36
+ refresh() {
37
+ const model = this.editor.model;
38
+ const schema = model.schema;
39
+ const selection = model.document.selection;
40
+ const selectedRawHtmlElement = getSelectedRawHtmlModelWidget( selection );
41
+
42
+ this.isEnabled = isHtmlEmbedAllowedInParent( selection, schema, model );
43
+ this.value = selectedRawHtmlElement ? selectedRawHtmlElement.getAttribute( 'value' ) || '' : null;
44
+ }
45
+
46
+ /**
47
+ * Executes the command, which either:
48
+ *
49
+ * * creates and inserts a new HTML embed element if none was selected,
50
+ * * updates the content of the HTML embed if one was selected.
51
+ *
52
+ * @fires execute
53
+ * @param {String} [value] When passed, the value (content) will be set on a new embed or a selected one.
54
+ */
55
+ execute( value ) {
56
+ const model = this.editor.model;
57
+ const selection = model.document.selection;
58
+
59
+ model.change( writer => {
60
+ let htmlEmbedElement;
61
+
62
+ // If the command has a non-null value, there must be some HTML embed selected in the model.
63
+ if ( this.value !== null ) {
64
+ htmlEmbedElement = getSelectedRawHtmlModelWidget( selection );
65
+ } else {
66
+ htmlEmbedElement = writer.createElement( 'rawHtml' );
67
+
68
+ model.insertContent( htmlEmbedElement );
69
+ writer.setSelection( htmlEmbedElement, 'on' );
70
+ }
71
+
72
+ writer.setAttribute( 'value', value, htmlEmbedElement );
73
+ } );
74
+ }
75
+ }
76
+
77
+ // Checks if an HTML embed is allowed by the schema in the optimal insertion parent.
78
+ //
79
+ // @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection
80
+ // @param {module:engine/model/schema~Schema} schema
81
+ // @param {module:engine/model/model~Model} model
82
+ // @returns {Boolean}
83
+ function isHtmlEmbedAllowedInParent( selection, schema, model ) {
84
+ const parent = getInsertHtmlEmbedParent( selection, model );
85
+
86
+ return schema.checkChild( parent, 'rawHtml' );
87
+ }
88
+
89
+ // Returns a node that will be used to insert a html embed with `model.insertContent` to check if a html embed element can be placed there.
90
+ //
91
+ // @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection
92
+ // @param {module:engine/model/model~Model} model
93
+ // @returns {module:engine/model/element~Element}
94
+ function getInsertHtmlEmbedParent( selection, model ) {
95
+ const insertionRange = findOptimalInsertionRange( selection, model );
96
+ const parent = insertionRange.start.parent;
97
+
98
+ if ( parent.isEmpty && !parent.is( 'element', '$root' ) ) {
99
+ return parent.parent;
100
+ }
101
+
102
+ return parent;
103
+ }
104
+
105
+ // Returns the selected HTML embed element in the model, if any.
106
+ //
107
+ // @param {module:engine/model/selection~Selection} selection
108
+ // @returns {module:engine/model/element~Element|null}
109
+ function getSelectedRawHtmlModelWidget( selection ) {
110
+ const selectedElement = selection.getSelectedElement();
111
+
112
+ if ( selectedElement && selectedElement.is( 'element', 'rawHtml' ) ) {
113
+ return selectedElement;
114
+ }
115
+
116
+ return null;
117
+ }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
@@ -12,8 +12,7 @@ import { ButtonView } from 'ckeditor5/src/ui';
12
12
  import { toWidget } from 'ckeditor5/src/widget';
13
13
  import { logWarning, createElement } from 'ckeditor5/src/utils';
14
14
 
15
- import InsertHtmlEmbedCommand from './inserthtmlembedcommand';
16
- import UpdateHtmlEmbedCommand from './updatehtmlembedcommand';
15
+ import HtmlEmbedCommand from './htmlembedcommand';
17
16
 
18
17
  import '../theme/htmlembed.css';
19
18
 
@@ -55,6 +54,15 @@ export default class HtmlEmbedEditing extends Plugin {
55
54
  };
56
55
  }
57
56
  } );
57
+
58
+ /**
59
+ * Keeps references to {@link module:ui/button/buttonview~ButtonView edit, save, and cancel} button instances created for
60
+ * each widget so they can be destroyed if they are no longer in DOM after the editing view was re-rendered.
61
+ *
62
+ * @private
63
+ * @member {Set.<module:ui/button/buttonview~ButtonView>} #_widgetButtonViewReferences
64
+ */
65
+ this._widgetButtonViewReferences = new Set();
58
66
  }
59
67
 
60
68
  /**
@@ -70,8 +78,7 @@ export default class HtmlEmbedEditing extends Plugin {
70
78
  allowAttributes: [ 'value' ]
71
79
  } );
72
80
 
73
- editor.commands.add( 'updateHtmlEmbed', new UpdateHtmlEmbedCommand( editor ) );
74
- editor.commands.add( 'insertHtmlEmbed', new InsertHtmlEmbedCommand( editor ) );
81
+ editor.commands.add( 'htmlEmbed', new HtmlEmbedCommand( editor ) );
75
82
 
76
83
  this._setupConversion();
77
84
  }
@@ -85,9 +92,23 @@ export default class HtmlEmbedEditing extends Plugin {
85
92
  const editor = this.editor;
86
93
  const t = editor.t;
87
94
  const view = editor.editing.view;
95
+ const widgetButtonViewReferences = this._widgetButtonViewReferences;
88
96
 
89
97
  const htmlEmbedConfig = editor.config.get( 'htmlEmbed' );
90
98
 
99
+ // Destroy UI buttons created for widgets that have been removed from the view document (e.g. in the previous conversion).
100
+ // This prevents unexpected memory leaks from UI views.
101
+ this.editor.editing.view.on( 'render', () => {
102
+ for ( const buttonView of widgetButtonViewReferences ) {
103
+ if ( buttonView.element.isConnected ) {
104
+ return;
105
+ }
106
+
107
+ buttonView.destroy();
108
+ widgetButtonViewReferences.delete( buttonView );
109
+ }
110
+ }, { priority: 'lowest' } );
111
+
91
112
  // Register div.raw-html-embed as a raw content element so all of it's content will be provided
92
113
  // as a view element's custom property while data upcasting.
93
114
  editor.data.registerRawContentMatcher( {
@@ -176,7 +197,7 @@ export default class HtmlEmbedEditing extends Plugin {
176
197
  // If the value didn't change, we just cancel. If it changed,
177
198
  // it's enough to update the model – the entire widget will be reconverted.
178
199
  if ( newValue !== state.getRawHtmlValue() ) {
179
- editor.execute( 'updateHtmlEmbed', newValue );
200
+ editor.execute( 'htmlEmbed', newValue );
180
201
  editor.editing.view.focus();
181
202
  } else {
182
203
  this.cancel();
@@ -275,36 +296,18 @@ export default class HtmlEmbedEditing extends Plugin {
275
296
  const domButtonsWrapper = createElement( domDocument, 'div', {
276
297
  class: 'raw-html-embed__buttons-wrapper'
277
298
  } );
278
- // TODO these should be cached and we should only clone here these cached nodes!
279
- const domEditButton = createDomButton( editor, 'edit' );
280
- const domSaveButton = createDomButton( editor, 'save' );
281
- const domCancelButton = createDomButton( editor, 'cancel' );
282
299
 
283
300
  if ( state.isEditable ) {
284
- const clonedDomSaveButton = domSaveButton.cloneNode( true );
285
- const clonedDomCancelButton = domCancelButton.cloneNode( true );
286
-
287
- clonedDomSaveButton.addEventListener( 'click', evt => {
288
- evt.preventDefault();
289
- props.onSaveClick( );
290
- } );
301
+ const saveButtonView = createUIButton( editor, 'save', props.onSaveClick );
302
+ const cancelButtonView = createUIButton( editor, 'cancel', props.onCancelClick );
291
303
 
292
- clonedDomCancelButton.addEventListener( 'click', evt => {
293
- evt.preventDefault();
294
- props.onCancelClick( );
295
- } );
296
-
297
- domButtonsWrapper.appendChild( clonedDomSaveButton );
298
- domButtonsWrapper.appendChild( clonedDomCancelButton );
304
+ domButtonsWrapper.append( saveButtonView.element, cancelButtonView.element );
305
+ widgetButtonViewReferences.add( saveButtonView ).add( cancelButtonView );
299
306
  } else {
300
- const clonedDomEditButton = domEditButton.cloneNode( true );
301
-
302
- clonedDomEditButton.addEventListener( 'click', evt => {
303
- evt.preventDefault();
304
- props.onEditClick();
305
- } );
307
+ const editButtonView = createUIButton( editor, 'edit', props.onEditClick );
306
308
 
307
- domButtonsWrapper.appendChild( clonedDomEditButton );
309
+ domButtonsWrapper.append( editButtonView.element );
310
+ widgetButtonViewReferences.add( editButtonView );
308
311
  }
309
312
 
310
313
  return domButtonsWrapper;
@@ -355,20 +358,22 @@ export default class HtmlEmbedEditing extends Plugin {
355
358
  }
356
359
  }
357
360
 
358
- // Returns a toggle mode button DOM element that can be cloned and used in conversion.
361
+ // Returns a UI button view that can be used in conversion.
359
362
  //
360
363
  // @param {module:utils/locale~Locale} locale Editor locale.
361
364
  // @param {'edit'|'save'|'cancel'} type Type of button to create.
362
- // @returns {HTMLElement}
363
- function createDomButton( editor, type ) {
365
+ // @param {Function} onClick The callback executed on button click.
366
+ // @returns {module:ui/button/buttonview~ButtonView}
367
+ function createUIButton( editor, type, onClick ) {
364
368
  const t = editor.locale.t;
365
369
  const buttonView = new ButtonView( editor.locale );
366
- const command = editor.commands.get( 'updateHtmlEmbed' );
370
+ const command = editor.commands.get( 'htmlEmbed' );
367
371
 
368
372
  buttonView.set( {
369
- tooltipPosition: editor.locale.uiLanguageDirection === 'rtl' ? 'e' : 'w',
373
+ class: `raw-html-embed__${ type }-button`,
370
374
  icon: icons.pencil,
371
- tooltip: true
375
+ tooltip: true,
376
+ tooltipPosition: editor.locale.uiLanguageDirection === 'rtl' ? 'e' : 'w'
372
377
  } );
373
378
 
374
379
  buttonView.render();
@@ -376,25 +381,25 @@ function createDomButton( editor, type ) {
376
381
  if ( type === 'edit' ) {
377
382
  buttonView.set( {
378
383
  icon: icons.pencil,
379
- label: t( 'Edit source' ),
380
- class: 'raw-html-embed__edit-button'
384
+ label: t( 'Edit source' )
381
385
  } );
386
+
387
+ buttonView.bind( 'isEnabled' ).to( command );
382
388
  } else if ( type === 'save' ) {
383
389
  buttonView.set( {
384
390
  icon: icons.check,
385
- label: t( 'Save changes' ),
386
- class: 'raw-html-embed__save-button'
391
+ label: t( 'Save changes' )
387
392
  } );
388
- buttonView.bind( 'isEnabled' ).to( command, 'isEnabled' );
393
+
394
+ buttonView.bind( 'isEnabled' ).to( command );
389
395
  } else {
390
396
  buttonView.set( {
391
397
  icon: icons.cancel,
392
- label: t( 'Cancel' ),
393
- class: 'raw-html-embed__cancel-button'
398
+ label: t( 'Cancel' )
394
399
  } );
395
400
  }
396
401
 
397
- buttonView.destroy();
402
+ buttonView.on( 'execute', onClick );
398
403
 
399
- return buttonView.element.cloneNode( true );
404
+ return buttonView;
400
405
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
@@ -34,7 +34,7 @@ export default class HtmlEmbedUI extends Plugin {
34
34
 
35
35
  // Add the `htmlEmbed` button to feature components.
36
36
  editor.ui.componentFactory.add( 'htmlEmbed', locale => {
37
- const command = editor.commands.get( 'insertHtmlEmbed' );
37
+ const command = editor.commands.get( 'htmlEmbed' );
38
38
  const view = new ButtonView( locale );
39
39
 
40
40
  view.set( {
@@ -47,7 +47,7 @@ export default class HtmlEmbedUI extends Plugin {
47
47
 
48
48
  // Execute the command.
49
49
  this.listenTo( view, 'execute', () => {
50
- editor.execute( 'insertHtmlEmbed' );
50
+ editor.execute( 'htmlEmbed' );
51
51
  editor.editing.view.focus();
52
52
 
53
53
  const widgetWrapper = editor.editing.view.document.selection.getSelectedElement();
package/src/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
package/CHANGELOG.md DELETED
@@ -1,4 +0,0 @@
1
- Changelog
2
- =========
3
-
4
- All changes in the package are documented in the main repository. See: https://github.com/ckeditor/ckeditor5/blob/master/CHANGELOG.md.
@@ -1,79 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
3
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
- */
5
-
6
- /**
7
- * @module html-embed/inserthtmlembedcommand
8
- */
9
-
10
- import { Command } from 'ckeditor5/src/core';
11
- import { findOptimalInsertionRange } from 'ckeditor5/src/widget';
12
-
13
- /**
14
- * The insert HTML embed element command.
15
- *
16
- * The command is registered by {@link module:html-embed/htmlembedediting~HtmlEmbedEditing} as `'insertHtmlEmbed'`.
17
- *
18
- * To insert the HTML embed element at the current selection, execute the command:
19
- *
20
- * editor.execute( 'insertHtmlEmbed' );
21
- *
22
- * @extends module:core/command~Command
23
- */
24
- export default class InsertHtmlEmbedCommand extends Command {
25
- /**
26
- * @inheritDoc
27
- */
28
- refresh() {
29
- const model = this.editor.model;
30
- const schema = model.schema;
31
- const selection = model.document.selection;
32
-
33
- this.isEnabled = isHtmlEmbedAllowedInParent( selection, schema, model );
34
- }
35
-
36
- /**
37
- * Executes the command, which creates and inserts a new HTML embed element.
38
- *
39
- * @fires execute
40
- */
41
- execute() {
42
- const model = this.editor.model;
43
-
44
- model.change( writer => {
45
- const rawHtmlElement = writer.createElement( 'rawHtml' );
46
-
47
- model.insertContent( rawHtmlElement );
48
- writer.setSelection( rawHtmlElement, 'on' );
49
- } );
50
- }
51
- }
52
-
53
- // Checks if an HTML embed is allowed by the schema in the optimal insertion parent.
54
- //
55
- // @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection
56
- // @param {module:engine/model/schema~Schema} schema
57
- // @param {module:engine/model/model~Model} model Model instance.
58
- // @returns {Boolean}
59
- function isHtmlEmbedAllowedInParent( selection, schema, model ) {
60
- const parent = getInsertHtmlEmbedParent( selection, model );
61
-
62
- return schema.checkChild( parent, 'rawHtml' );
63
- }
64
-
65
- // Returns a node that will be used to insert a html embed with `model.insertContent` to check if a html embed element can be placed there.
66
- //
67
- // @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection
68
- // @param {module:engine/model/model~Model} model Model instance.
69
- // @returns {module:engine/model/element~Element}
70
- function getInsertHtmlEmbedParent( selection, model ) {
71
- const insertionRange = findOptimalInsertionRange( selection, model );
72
- const parent = insertionRange.start.parent;
73
-
74
- if ( parent.isEmpty && !parent.is( 'element', '$root' ) ) {
75
- return parent.parent;
76
- }
77
-
78
- return parent;
79
- }
@@ -1,64 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
3
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
- */
5
-
6
- /**
7
- * @module html-embed/updatehtmlembedcommand
8
- */
9
-
10
- import { Command } from 'ckeditor5/src/core';
11
-
12
- /**
13
- * The update HTML embed value command.
14
- *
15
- * The command is registered by {@link module:html-embed/htmlembedediting~HtmlEmbedEditing} as `'updateHtmlEmbed'`.
16
- *
17
- * To update the value of the HTML embed element at the current selection, execute the command:
18
- *
19
- * editor.execute( 'updateHtmlEmbed', '<b>HTML.</b>' );
20
- *
21
- * @extends module:core/command~Command
22
- */
23
- export default class UpdateHtmlEmbedCommand extends Command {
24
- /**
25
- * @inheritDoc
26
- */
27
- refresh() {
28
- const model = this.editor.model;
29
- const selection = model.document.selection;
30
- const rawHtmlElement = getSelectedRawHtmlModelWidget( selection );
31
-
32
- this.isEnabled = !!rawHtmlElement;
33
- }
34
-
35
- /**
36
- * Executes the command, which updates the `value` attribute of the embedded HTML element:
37
- *
38
- * @fires execute
39
- * @param {String} value HTML as a string.
40
- */
41
- execute( value ) {
42
- const model = this.editor.model;
43
- const selection = model.document.selection;
44
- const selectedRawHtmlElement = getSelectedRawHtmlModelWidget( selection );
45
-
46
- model.change( writer => {
47
- writer.setAttribute( 'value', value, selectedRawHtmlElement );
48
- } );
49
- }
50
- }
51
-
52
- // Returns the selected HTML embed element in the model, if any.
53
- //
54
- // @param {module:engine/model/selection~Selection} selection
55
- // @returns {module:engine/model/element~Element|null}
56
- function getSelectedRawHtmlModelWidget( selection ) {
57
- const selectedElement = selection.getSelectedElement();
58
-
59
- if ( selectedElement && selectedElement.is( 'element', 'rawHtml' ) ) {
60
- return selectedElement;
61
- }
62
-
63
- return null;
64
- }