@ckeditor/ckeditor5-code-block 0.0.0-nightly-20240604.1 → 0.0.0-nightly-20240605.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.
package/README.md CHANGED
@@ -15,12 +15,6 @@ Check out the [demo in the code block feature guide](https://ckeditor.com/docs/c
15
15
 
16
16
  See the [`@ckeditor/ckeditor5-code-block` package](https://ckeditor.com/docs/ckeditor5/latest/api/code-block.html) page as well as the [code block feature](https://ckeditor.com/docs/ckeditor5/latest/features/code-blocks.html) guide in the [CKEditor 5 documentation](https://ckeditor.com/docs/ckeditor5/latest/).
17
17
 
18
- ## Installation
19
-
20
- ```bash
21
- npm install ckeditor5
22
- ```
23
-
24
18
  ## License
25
19
 
26
20
  Licensed under the terms of [GNU General Public License Version 2 or later](http://www.gnu.org/licenses/gpl.html). For full details about the license, please check the `LICENSE.md` file or [https://ckeditor.com/legal/ckeditor-oss-license](https://ckeditor.com/legal/ckeditor-oss-license).
@@ -2,4 +2,4 @@
2
2
  /*!
3
3
  * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
4
4
  * For licensing, see LICENSE.md.
5
- */(()=>{var e={535:(e,t,n)=>{"use strict";n.d(t,{A:()=>r});var o=n(935),i=n.n(o)()((function(e){return e[1]}));i.push([e.id,".ck-content pre{background:hsla(0,0%,78%,.3);border:1px solid #c4c4c4;border-radius:2px;color:#353535;direction:ltr;font-style:normal;min-width:200px;padding:1em;tab-size:4;text-align:left;white-space:pre-wrap}.ck-content pre code{background:unset;border-radius:0;padding:0}.ck.ck-editor__editable pre{position:relative}.ck.ck-editor__editable pre[data-language]:after{content:attr(data-language);position:absolute}:root{--ck-color-code-block-label-background:#757575}.ck.ck-editor__editable pre[data-language]:after{background:var(--ck-color-code-block-label-background);color:#fff;font-family:var(--ck-font-face);font-size:10px;line-height:16px;padding:var(--ck-spacing-tiny) var(--ck-spacing-medium);right:10px;top:-1px;white-space:nowrap}.ck.ck-code-block-dropdown .ck-dropdown__panel{max-height:250px;overflow-x:hidden;overflow-y:auto}",""]);const r=i},935: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,o){"string"==typeof e&&(e=[[null,e,""]]);var i={};if(o)for(var r=0;r<this.length;r++){var c=this[r][0];null!=c&&(i[c]=!0)}for(var a=0;a<e.length;a++){var s=[].concat(e[a]);o&&i[s[0]]||(n&&(s[2]?s[2]="".concat(n," and ").concat(s[2]):s[2]=n),t.push(s))}},t}},591:(e,t,n)=>{"use strict";var o,i=function(){return void 0===o&&(o=Boolean(window&&document&&document.all&&!window.atob)),o},r=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]}}(),c=[];function a(e){for(var t=-1,n=0;n<c.length;n++)if(c[n].identifier===e){t=n;break}return t}function s(e,t){for(var n={},o=[],i=0;i<e.length;i++){var r=e[i],s=t.base?r[0]+t.base:r[0],l=n[s]||0,d="".concat(s," ").concat(l);n[s]=l+1;var u=a(d),g={css:r[1],media:r[2],sourceMap:r[3]};-1!==u?(c[u].references++,c[u].updater(g)):c.push({identifier:d,updater:h(g,t),references:1}),o.push(d)}return o}function l(e){var t=document.createElement("style"),o=e.attributes||{};if(void 0===o.nonce){var i=n.nc;i&&(o.nonce=i)}if(Object.keys(o).forEach((function(e){t.setAttribute(e,o[e])})),"function"==typeof e.insert)e.insert(t);else{var c=r(e.insert||"head");if(!c)throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");c.appendChild(t)}return t}var d,u=(d=[],function(e,t){return d[e]=t,d.filter(Boolean).join("\n")});function g(e,t,n,o){var i=n?"":o.media?"@media ".concat(o.media," {").concat(o.css,"}"):o.css;if(e.styleSheet)e.styleSheet.cssText=u(t,i);else{var r=document.createTextNode(i),c=e.childNodes;c[t]&&e.removeChild(c[t]),c.length?e.insertBefore(r,c[t]):e.appendChild(r)}}function f(e,t,n){var o=n.css,i=n.media,r=n.sourceMap;if(i?e.setAttribute("media",i):e.removeAttribute("media"),r&&"undefined"!=typeof btoa&&(o+="\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(r))))," */")),e.styleSheet)e.styleSheet.cssText=o;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(o))}}var p=null,m=0;function h(e,t){var n,o,i;if(t.singleton){var r=m++;n=p||(p=l(t)),o=g.bind(null,n,r,!1),i=g.bind(null,n,r,!0)}else n=l(t),o=f.bind(null,n,t),i=function(){!function(e){if(null===e.parentNode)return!1;e.parentNode.removeChild(e)}(n)};return o(e),function(t){if(t){if(t.css===e.css&&t.media===e.media&&t.sourceMap===e.sourceMap)return;o(e=t)}else i()}}e.exports=function(e,t){(t=t||{}).singleton||"boolean"==typeof t.singleton||(t.singleton=i());var n=s(e=e||[],t);return function(e){if(e=e||[],"[object Array]"===Object.prototype.toString.call(e)){for(var o=0;o<n.length;o++){var i=a(n[o]);c[i].references--}for(var r=s(e,t),l=0;l<n.length;l++){var d=a(n[l]);0===c[d].references&&(c[d].updater(),c.splice(d,1))}n=r}}}},782:(e,t,n)=>{e.exports=n(237)("./src/core.js")},783:(e,t,n)=>{e.exports=n(237)("./src/engine.js")},507:(e,t,n)=>{e.exports=n(237)("./src/enter.js")},311:(e,t,n)=>{e.exports=n(237)("./src/ui.js")},584:(e,t,n)=>{e.exports=n(237)("./src/utils.js")},237:e=>{"use strict";e.exports=CKEditor5.dll}},t={};function n(o){var i=t[o];if(void 0!==i)return i.exports;var r=t[o]={id:o,exports:{}};return e[o](r,r.exports,n),r.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 o in t)n.o(t,o)&&!n.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})},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})},n.nc=void 0;var o={};(()=>{"use strict";n.r(o),n.d(o,{CodeBlock:()=>_,CodeBlockEditing:()=>k,CodeBlockUI:()=>E});var e=n(782),t=n(507),i=n(783),r=n(584);function c(e){const t=e.t,n=e.config.get("codeBlock.languages");for(const e of n)"Plain text"===e.label&&(e.label=t("Plain text")),void 0===e.class&&(e.class=`language-${e.language}`);return n}function a(e,t,n){const o={};for(const i of e)if("class"===t){o[i[t].split(" ").shift()]=i[n]}else o[i[t]]=i[n];return o}function s(e){return e.data.match(/^(\s*)/)[0]}function l(e){const t=e.document.selection,n=[];if(t.isCollapsed)return[t.anchor];const o=t.getFirstRange().getWalker({ignoreElementEnd:!0,direction:"backward"});for(const{item:t}of o){if(!t.is("$textProxy"))continue;const{parent:o,startOffset:i}=t.textNode;if(!o.is("element","codeBlock"))continue;const r=s(t.textNode),c=e.createPositionAt(o,i+r.length);n.push(c)}return n}function d(e){const t=(0,r.first)(e.getSelectedBlocks());return!!t&&t.is("element","codeBlock")}function u(e,t){return!t.is("rootElement")&&!e.isLimit(t)&&e.checkChild(t.parent,"codeBlock")}function g(e,t,n,o){const i=a(t,"language","label"),r=n.getAttribute("language");if(r in i){const t=i[r];return e("enter"===o?"Entering %0 code snippet":"Leaving %0 code snippet",t)}return e("enter"===o?"Entering code snippet":"Leaving code snippet")}class f extends e.Command{constructor(e){super(e),this._lastLanguage=null}refresh(){this.value=this._getValue(),this.isEnabled=this._checkEnabled()}execute(e={}){const t=this.editor,n=t.model,o=n.document.selection,i=c(t)[0],r=Array.from(o.getSelectedBlocks()),a=null==e.forceValue?!this.value:e.forceValue,s=function(e,t,n){if(e.language)return e.language;if(e.usePreviousLanguageChoice&&t)return t;return n}(e,this._lastLanguage,i.language);n.change((e=>{a?this._applyCodeBlock(e,r,s):this._removeCodeBlock(e,r)}))}_getValue(){const e=this.editor.model.document.selection,t=(0,r.first)(e.getSelectedBlocks());return!!!(!t||!t.is("element","codeBlock"))&&t.getAttribute("language")}_checkEnabled(){if(this.value)return!0;const e=this.editor.model.document.selection,t=this.editor.model.schema,n=(0,r.first)(e.getSelectedBlocks());return!!n&&u(t,n)}_applyCodeBlock(e,t,n){this._lastLanguage=n;const o=this.editor.model.schema,i=t.filter((e=>u(o,e)));for(const t of i)e.rename(t,"codeBlock"),e.setAttribute("language",n,t),o.removeDisallowedAttributes([t],e),Array.from(t.getChildren()).filter((e=>!o.checkChild(t,e))).forEach((t=>e.remove(t)));i.reverse().forEach(((t,n)=>{const o=i[n+1];t.previousSibling===o&&(e.appendElement("softBreak",o),e.merge(e.createPositionBefore(t)))}))}_removeCodeBlock(e,t){const n=t.filter((e=>e.is("element","codeBlock")));for(const t of n){const n=e.createRangeOn(t);for(const t of Array.from(n.getItems()).reverse())if(t.is("element","softBreak")&&t.parent.is("element","codeBlock")){const{position:n}=e.split(e.createPositionBefore(t)),o=n.nodeAfter;e.rename(o,"paragraph"),e.removeAttribute("language",o),e.remove(t)}e.rename(t,"paragraph"),e.removeAttribute("language",t)}}}class p extends e.Command{constructor(e){super(e),this._indentSequence=e.config.get("codeBlock.indentSequence")}refresh(){this.isEnabled=this._checkEnabled()}execute(){const e=this.editor.model;e.change((t=>{const n=l(e);for(const o of n){const n=t.createText(this._indentSequence);e.insertContent(n,o)}}))}_checkEnabled(){return!!this._indentSequence&&d(this.editor.model.document.selection)}}class m extends e.Command{constructor(e){super(e),this._indentSequence=e.config.get("codeBlock.indentSequence")}refresh(){this.isEnabled=this._checkEnabled()}execute(){const e=this.editor.model;e.change((()=>{const t=l(e);for(const n of t){const t=h(e,n,this._indentSequence);t&&e.deleteContent(e.createSelection(t))}}))}_checkEnabled(){if(!this._indentSequence)return!1;const e=this.editor.model;return!!d(e.document.selection)&&l(e).some((t=>h(e,t,this._indentSequence)))}}function h(e,t,n){const o=function(e){let t=e.parent.getChild(e.index);t&&!t.is("element","softBreak")||(t=e.nodeBefore);if(!t||t.is("element","softBreak"))return null;return t}(t);if(!o)return null;const i=s(o),r=i.lastIndexOf(n);if(r+n.length!==i.length)return null;if(-1===r)return null;const{parent:c,startOffset:a}=o;return e.createRange(e.createPositionAt(c,a+r),e.createPositionAt(c,a+r+n.length))}function b(e,t,n=!1){const o=a(t,"language","class"),i=a(t,"language","label");return(t,r,c)=>{const{writer:a,mapper:s,consumable:l}=c;if(!l.consume(r.item,"insert"))return;const d=r.item.getAttribute("language"),u=s.toViewPosition(e.createPositionBefore(r.item)),g={};n&&(g["data-language"]=i[d],g.spellcheck="false");const f=o[d]?{class:o[d]}:void 0,p=a.createContainerElement("code",f),m=a.createContainerElement("pre",g,p);a.insert(u,m),s.bindElements(r.item,p)}}const v="paragraph";class k extends e.Plugin{static get pluginName(){return"CodeBlockEditing"}static get requires(){return[t.ShiftEnter]}constructor(e){super(e),e.config.define("codeBlock",{languages:[{language:"plaintext",label:"Plain text"},{language:"c",label:"C"},{language:"cs",label:"C#"},{language:"cpp",label:"C++"},{language:"css",label:"CSS"},{language:"diff",label:"Diff"},{language:"html",label:"HTML"},{language:"java",label:"Java"},{language:"javascript",label:"JavaScript"},{language:"php",label:"PHP"},{language:"python",label:"Python"},{language:"ruby",label:"Ruby"},{language:"typescript",label:"TypeScript"},{language:"xml",label:"XML"}],indentSequence:"\t"})}init(){const e=this.editor,t=e.model.schema,n=e.model,o=e.editing.view,r=c(e);e.commands.add("codeBlock",new f(e)),e.commands.add("indentCodeBlock",new p(e)),e.commands.add("outdentCodeBlock",new m(e)),this.listenTo(o.document,"tab",((t,n)=>{const o=n.shiftKey?"outdentCodeBlock":"indentCodeBlock";e.commands.get(o).isEnabled&&(e.execute(o),n.stopPropagation(),n.preventDefault(),t.stop())}),{context:"pre"}),t.register("codeBlock",{allowWhere:"$block",allowChildren:"$text",disallowChildren:"$inlineObject",allowAttributes:["language"],allowAttributesOf:"$listItem",isBlock:!0}),t.addAttributeCheck((e=>{if(e.endsWith("codeBlock $text"))return!1})),e.editing.downcastDispatcher.on("insert:codeBlock",b(n,r,!0)),e.data.downcastDispatcher.on("insert:codeBlock",b(n,r)),e.data.downcastDispatcher.on("insert:softBreak",function(e){return(t,n,o)=>{if("codeBlock"!==n.item.parent.name)return;const{writer:i,mapper:r,consumable:c}=o;if(!c.consume(n.item,"insert"))return;const a=r.toViewPosition(e.createPositionBefore(n.item));i.insert(a,i.createText("\n"))}}(n),{priority:"high"}),e.data.upcastDispatcher.on("element:code",function(e,t){const n=a(t,"class","language"),o=t[0].language;return(e,t,i)=>{const r=t.viewItem,c=r.parent;if(!c||!c.is("element","pre"))return;if(t.modelCursor.findAncestor("codeBlock"))return;const{consumable:a,writer:s}=i;if(!a.test(r,{name:!0}))return;const l=s.createElement("codeBlock"),d=[...r.getClassNames()];d.length||d.push("");for(const e of d){const t=n[e];if(t){s.setAttribute("language",t,l);break}}l.hasAttribute("language")||s.setAttribute("language",o,l),i.convertChildren(r,l),i.safeInsert(l,t.modelCursor)&&(a.consume(r,{name:!0}),i.updateConversionResult(l,t))}}(0,r)),e.data.upcastDispatcher.on("text",((e,t,{consumable:n,writer:o})=>{let i=t.modelCursor;if(!n.test(t.viewItem))return;if(!i.findAncestor("codeBlock"))return;n.consume(t.viewItem);const r=t.viewItem.data.split("\n").map((e=>o.createText(e))),c=r[r.length-1];for(const e of r)if(o.insert(e,i),i=i.getShiftedBy(e.offsetSize),e!==c){const e=o.createElement("softBreak");o.insert(e,i),i=o.createPositionAfter(e)}t.modelRange=o.createRange(t.modelCursor,i),t.modelCursor=i})),e.data.upcastDispatcher.on("element:pre",((e,t,{consumable:n})=>{const o=t.viewItem;if(o.findAncestor("pre"))return;const i=Array.from(o.getChildren()),r=i.find((e=>e.is("element","code")));if(r)for(const e of i)e!==r&&e.is("$text")&&n.consume(e,{name:!0})}),{priority:"high"}),this.listenTo(e.editing.view.document,"clipboardInput",((t,o)=>{let r=n.createRange(n.document.selection.anchor);if(o.targetRanges&&(r=e.editing.mapper.toModelRange(o.targetRanges[0])),!r.start.parent.is("element","codeBlock"))return;const c=o.dataTransfer.getData("text/plain"),a=new i.UpcastWriter(e.editing.view.document);o.content=function(e,t){const n=e.createDocumentFragment(),o=t.split("\n"),i=o.reduce(((t,n,i)=>(t.push(n),i<o.length-1&&t.push(e.createElement("br")),t)),[]);return e.appendChild(i,n),n}(a,c)})),this.listenTo(n,"getSelectedContent",((e,[o])=>{const i=o.anchor;!o.isCollapsed&&i.parent.is("element","codeBlock")&&i.hasSameParentAs(o.focus)&&n.change((n=>{const r=e.return;if(i.parent.is("element")&&(r.childCount>1||o.containsEntireContent(i.parent))){const t=n.createElement("codeBlock",i.parent.getAttributes());n.append(r,t);const o=n.createDocumentFragment();return n.append(t,o),void(e.return=o)}const c=r.getChild(0);t.checkAttribute(c,"code")&&n.setAttribute("code",!0,c)}))}))}afterInit(){const e=this.editor,t=e.commands,n=t.get("indent"),o=t.get("outdent");n&&n.registerChildCommand(t.get("indentCodeBlock"),{priority:"highest"}),o&&o.registerChildCommand(t.get("outdentCodeBlock")),this.listenTo(e.editing.view.document,"enter",((t,n)=>{e.model.document.selection.getLastPosition().parent.is("element","codeBlock")&&(function(e,t){const n=e.model,o=n.document,i=e.editing.view,r=o.selection.getLastPosition(),c=r.nodeAfter;if(t||!o.selection.isCollapsed||!r.isAtStart)return!1;if(!w(c))return!1;return e.model.change((t=>{e.execute("enter");const n=o.selection.anchor.parent.previousSibling;t.rename(n,v),t.setSelection(n,"in"),e.model.schema.removeDisallowedAttributes([n],t),t.remove(c)})),i.scrollToTheSelection(),!0}(e,n.isSoft)||function(e,t){const n=e.model,o=n.document,i=e.editing.view,r=o.selection.getLastPosition(),c=r.nodeBefore;let a;if(t||!o.selection.isCollapsed||!r.isAtEnd||!c||!c.previousSibling)return!1;if(w(c)&&w(c.previousSibling))a=n.createRange(n.createPositionBefore(c.previousSibling),n.createPositionAfter(c));else if(B(c)&&w(c.previousSibling)&&w(c.previousSibling.previousSibling))a=n.createRange(n.createPositionBefore(c.previousSibling.previousSibling),n.createPositionAfter(c));else{if(!(B(c)&&w(c.previousSibling)&&B(c.previousSibling.previousSibling)&&c.previousSibling.previousSibling&&w(c.previousSibling.previousSibling.previousSibling)))return!1;a=n.createRange(n.createPositionBefore(c.previousSibling.previousSibling.previousSibling),n.createPositionAfter(c))}return e.model.change((t=>{t.remove(a),e.execute("enter");const n=o.selection.anchor.parent;t.rename(n,v),e.model.schema.removeDisallowedAttributes([n],t)})),i.scrollToTheSelection(),!0}(e,n.isSoft)||function(e){const t=e.model,n=t.document,o=n.selection.getLastPosition(),i=o.nodeBefore||o.textNode;let r;i&&i.is("$text")&&(r=s(i));e.model.change((t=>{e.execute("shiftEnter"),r&&t.insertText(r,n.selection.anchor)}))}(e),n.preventDefault(),t.stop())}),{context:"pre"}),this._initAriaAnnouncements()}_initAriaAnnouncements(){const{model:e,ui:t,t:n}=this.editor,o=c(this.editor);let i=null;e.document.selection.on("change:range",(()=>{const r=e.document.selection.focus.parent;t&&i!==r&&r.is("element")&&(i&&i.is("element","codeBlock")&&t.ariaLiveAnnouncer.announce(g(n,o,i,"leave")),r.is("element","codeBlock")&&t.ariaLiveAnnouncer.announce(g(n,o,r,"enter")),i=r)}))}}function B(e){return e&&e.is("$text")&&!e.data.match(/\S/)}function w(e){return e&&e.is("element","softBreak")}var C=n(311),x=n(591),S=n.n(x),y=n(535),A={injectType:"singletonStyleTag",attributes:{"data-cke":!0},insert:"head",singleton:!0};S()(y.A,A);y.A.locals;class E extends e.Plugin{static get pluginName(){return"CodeBlockUI"}init(){const t=this.editor,n=t.t,o=t.ui.componentFactory,i=c(t),r=this._getLanguageListItemDefinitions(i),a=t.commands.get("codeBlock");o.add("codeBlock",(o=>{const i=(0,C.createDropdown)(o,C.SplitButtonView),c=i.buttonView,s=n("Insert code block");return c.set({label:s,tooltip:!0,icon:e.icons.codeBlock,isToggleable:!0}),c.bind("isOn").to(a,"value",(e=>!!e)),c.on("execute",(()=>{t.execute("codeBlock",{usePreviousLanguageChoice:!0}),t.editing.view.focus()})),i.on("execute",(e=>{t.execute("codeBlock",{language:e.source._codeBlockLanguage,forceValue:!0}),t.editing.view.focus()})),i.class="ck-code-block-dropdown",i.bind("isEnabled").to(a),(0,C.addListToDropdown)(i,r,{role:"menu",ariaLabel:s}),i})),o.add("menuBar:codeBlock",(o=>{const i=new C.MenuBarMenuView(o);i.buttonView.set({label:n("Code block"),icon:e.icons.codeBlock}),i.bind("isEnabled").to(a);const c=new C.MenuBarMenuListView(o);c.set({ariaLabel:n("Insert code block")});for(const e of r){const n=new C.MenuBarMenuListItemView(o,i),r=new C.MenuBarMenuListItemButtonView(o);r.bind(...Object.keys(e.model)).to(e.model),r.bind("ariaChecked").to(r,"isOn"),r.delegate("execute").to(i),r.on("execute",(()=>{t.execute("codeBlock",{language:e.model._codeBlockLanguage,forceValue:a.value!=e.model._codeBlockLanguage}),t.editing.view.focus()})),n.children.add(r),c.items.add(n)}return i.panelView.children.add(c),i}))}_getLanguageListItemDefinitions(e){const t=this.editor.commands.get("codeBlock"),n=new r.Collection;for(const o of e){const e={type:"button",model:new C.ViewModel({_codeBlockLanguage:o.language,label:o.label,role:"menuitemradio",withText:!0})};e.model.bind("isOn").to(t,"value",(t=>t===e.model._codeBlockLanguage)),n.add(e)}return n}}class _ extends e.Plugin{static get requires(){return[k,E]}static get pluginName(){return"CodeBlock"}}})(),(window.CKEditor5=window.CKEditor5||{}).codeBlock=o})();
5
+ */(()=>{var e={535:(e,t,n)=>{"use strict";n.d(t,{A:()=>r});var o=n(935),i=n.n(o)()((function(e){return e[1]}));i.push([e.id,".ck-content pre{background:hsla(0,0%,78%,.3);border:1px solid #c4c4c4;border-radius:2px;color:#353535;direction:ltr;font-style:normal;min-width:200px;padding:1em;tab-size:4;text-align:left;white-space:pre-wrap}.ck-content pre code{background:unset;border-radius:0;padding:0}.ck.ck-editor__editable pre{position:relative}.ck.ck-editor__editable pre[data-language]:after{content:attr(data-language);position:absolute}:root{--ck-color-code-block-label-background:#757575}.ck.ck-editor__editable pre[data-language]:after{background:var(--ck-color-code-block-label-background);color:#fff;font-family:var(--ck-font-face);font-size:10px;line-height:16px;padding:var(--ck-spacing-tiny) var(--ck-spacing-medium);right:10px;top:-1px;white-space:nowrap}.ck.ck-code-block-dropdown .ck-dropdown__panel{max-height:250px;overflow-x:hidden;overflow-y:auto}",""]);const r=i},935: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,o){"string"==typeof e&&(e=[[null,e,""]]);var i={};if(o)for(var r=0;r<this.length;r++){var c=this[r][0];null!=c&&(i[c]=!0)}for(var a=0;a<e.length;a++){var s=[].concat(e[a]);o&&i[s[0]]||(n&&(s[2]?s[2]="".concat(n," and ").concat(s[2]):s[2]=n),t.push(s))}},t}},591:(e,t,n)=>{"use strict";var o,i=function(){return void 0===o&&(o=Boolean(window&&document&&document.all&&!window.atob)),o},r=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]}}(),c=[];function a(e){for(var t=-1,n=0;n<c.length;n++)if(c[n].identifier===e){t=n;break}return t}function s(e,t){for(var n={},o=[],i=0;i<e.length;i++){var r=e[i],s=t.base?r[0]+t.base:r[0],l=n[s]||0,d="".concat(s," ").concat(l);n[s]=l+1;var u=a(d),g={css:r[1],media:r[2],sourceMap:r[3]};-1!==u?(c[u].references++,c[u].updater(g)):c.push({identifier:d,updater:h(g,t),references:1}),o.push(d)}return o}function l(e){var t=document.createElement("style"),o=e.attributes||{};if(void 0===o.nonce){var i=n.nc;i&&(o.nonce=i)}if(Object.keys(o).forEach((function(e){t.setAttribute(e,o[e])})),"function"==typeof e.insert)e.insert(t);else{var c=r(e.insert||"head");if(!c)throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");c.appendChild(t)}return t}var d,u=(d=[],function(e,t){return d[e]=t,d.filter(Boolean).join("\n")});function g(e,t,n,o){var i=n?"":o.media?"@media ".concat(o.media," {").concat(o.css,"}"):o.css;if(e.styleSheet)e.styleSheet.cssText=u(t,i);else{var r=document.createTextNode(i),c=e.childNodes;c[t]&&e.removeChild(c[t]),c.length?e.insertBefore(r,c[t]):e.appendChild(r)}}function f(e,t,n){var o=n.css,i=n.media,r=n.sourceMap;if(i?e.setAttribute("media",i):e.removeAttribute("media"),r&&"undefined"!=typeof btoa&&(o+="\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(r))))," */")),e.styleSheet)e.styleSheet.cssText=o;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(o))}}var p=null,m=0;function h(e,t){var n,o,i;if(t.singleton){var r=m++;n=p||(p=l(t)),o=g.bind(null,n,r,!1),i=g.bind(null,n,r,!0)}else n=l(t),o=f.bind(null,n,t),i=function(){!function(e){if(null===e.parentNode)return!1;e.parentNode.removeChild(e)}(n)};return o(e),function(t){if(t){if(t.css===e.css&&t.media===e.media&&t.sourceMap===e.sourceMap)return;o(e=t)}else i()}}e.exports=function(e,t){(t=t||{}).singleton||"boolean"==typeof t.singleton||(t.singleton=i());var n=s(e=e||[],t);return function(e){if(e=e||[],"[object Array]"===Object.prototype.toString.call(e)){for(var o=0;o<n.length;o++){var i=a(n[o]);c[i].references--}for(var r=s(e,t),l=0;l<n.length;l++){var d=a(n[l]);0===c[d].references&&(c[d].updater(),c.splice(d,1))}n=r}}}},782:(e,t,n)=>{e.exports=n(237)("./src/core.js")},783:(e,t,n)=>{e.exports=n(237)("./src/engine.js")},507:(e,t,n)=>{e.exports=n(237)("./src/enter.js")},311:(e,t,n)=>{e.exports=n(237)("./src/ui.js")},584:(e,t,n)=>{e.exports=n(237)("./src/utils.js")},237:e=>{"use strict";e.exports=CKEditor5.dll}},t={};function n(o){var i=t[o];if(void 0!==i)return i.exports;var r=t[o]={id:o,exports:{}};return e[o](r,r.exports,n),r.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 o in t)n.o(t,o)&&!n.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})},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})},n.nc=void 0;var o={};(()=>{"use strict";n.r(o),n.d(o,{CodeBlock:()=>_,CodeBlockEditing:()=>k,CodeBlockUI:()=>E});var e=n(782),t=n(507),i=n(783),r=n(584);function c(e){const t=e.t,n=e.config.get("codeBlock.languages");for(const e of n)"Plain text"===e.label&&(e.label=t("Plain text")),void 0===e.class&&(e.class=`language-${e.language}`);return n}function a(e,t,n){const o={};for(const i of e)if("class"===t){o[i[t].split(" ").shift()]=i[n]}else o[i[t]]=i[n];return o}function s(e){return e.data.match(/^(\s*)/)[0]}function l(e){const t=e.document.selection,n=[];if(t.isCollapsed)return[t.anchor];const o=t.getFirstRange().getWalker({ignoreElementEnd:!0,direction:"backward"});for(const{item:t}of o){if(!t.is("$textProxy"))continue;const{parent:o,startOffset:i}=t.textNode;if(!o.is("element","codeBlock"))continue;const r=s(t.textNode),c=e.createPositionAt(o,i+r.length);n.push(c)}return n}function d(e){const t=(0,r.first)(e.getSelectedBlocks());return!!t&&t.is("element","codeBlock")}function u(e,t){return!t.is("rootElement")&&!e.isLimit(t)&&e.checkChild(t.parent,"codeBlock")}function g(e,t,n,o){const i=a(t,"language","label"),r=n.getAttribute("language");if(r in i){const t=i[r];return e("enter"===o?"Entering %0 code snippet":"Leaving %0 code snippet",t)}return e("enter"===o?"Entering code snippet":"Leaving code snippet")}class f extends e.Command{constructor(e){super(e),this._lastLanguage=null}refresh(){this.value=this._getValue(),this.isEnabled=this._checkEnabled()}execute(e={}){const t=this.editor,n=t.model,o=n.document.selection,i=c(t)[0],r=Array.from(o.getSelectedBlocks()),a=null==e.forceValue?!this.value:e.forceValue,s=function(e,t,n){if(e.language)return e.language;if(e.usePreviousLanguageChoice&&t)return t;return n}(e,this._lastLanguage,i.language);n.change((e=>{a?this._applyCodeBlock(e,r,s):this._removeCodeBlock(e,r)}))}_getValue(){const e=this.editor.model.document.selection,t=(0,r.first)(e.getSelectedBlocks());return!!!(!t||!t.is("element","codeBlock"))&&t.getAttribute("language")}_checkEnabled(){if(this.value)return!0;const e=this.editor.model.document.selection,t=this.editor.model.schema,n=(0,r.first)(e.getSelectedBlocks());return!!n&&u(t,n)}_applyCodeBlock(e,t,n){this._lastLanguage=n;const o=this.editor.model.schema,i=t.filter((e=>u(o,e)));for(const t of i)e.rename(t,"codeBlock"),e.setAttribute("language",n,t),o.removeDisallowedAttributes([t],e),Array.from(t.getChildren()).filter((e=>!o.checkChild(t,e))).forEach((t=>e.remove(t)));i.reverse().forEach(((t,n)=>{const o=i[n+1];t.previousSibling===o&&(e.appendElement("softBreak",o),e.merge(e.createPositionBefore(t)))}))}_removeCodeBlock(e,t){const n=t.filter((e=>e.is("element","codeBlock")));for(const t of n){const n=e.createRangeOn(t);for(const t of Array.from(n.getItems()).reverse())if(t.is("element","softBreak")&&t.parent.is("element","codeBlock")){const{position:n}=e.split(e.createPositionBefore(t)),o=n.nodeAfter;e.rename(o,"paragraph"),e.removeAttribute("language",o),e.remove(t)}e.rename(t,"paragraph"),e.removeAttribute("language",t)}}}class p extends e.Command{constructor(e){super(e),this._indentSequence=e.config.get("codeBlock.indentSequence")}refresh(){this.isEnabled=this._checkEnabled()}execute(){const e=this.editor.model;e.change((t=>{const n=l(e);for(const o of n){const n=t.createText(this._indentSequence);e.insertContent(n,o)}}))}_checkEnabled(){return!!this._indentSequence&&d(this.editor.model.document.selection)}}class m extends e.Command{constructor(e){super(e),this._indentSequence=e.config.get("codeBlock.indentSequence")}refresh(){this.isEnabled=this._checkEnabled()}execute(){const e=this.editor.model;e.change((()=>{const t=l(e);for(const n of t){const t=h(e,n,this._indentSequence);t&&e.deleteContent(e.createSelection(t))}}))}_checkEnabled(){if(!this._indentSequence)return!1;const e=this.editor.model;return!!d(e.document.selection)&&l(e).some((t=>h(e,t,this._indentSequence)))}}function h(e,t,n){const o=function(e){let t=e.parent.getChild(e.index);t&&!t.is("element","softBreak")||(t=e.nodeBefore);if(!t||t.is("element","softBreak"))return null;return t}(t);if(!o)return null;const i=s(o),r=i.lastIndexOf(n);if(r+n.length!==i.length)return null;if(-1===r)return null;const{parent:c,startOffset:a}=o;return e.createRange(e.createPositionAt(c,a+r),e.createPositionAt(c,a+r+n.length))}function b(e,t,n=!1){const o=a(t,"language","class"),i=a(t,"language","label");return(t,r,c)=>{const{writer:a,mapper:s,consumable:l}=c;if(!l.consume(r.item,"insert"))return;const d=r.item.getAttribute("language"),u=s.toViewPosition(e.createPositionBefore(r.item)),g={};n&&(g["data-language"]=i[d],g.spellcheck="false");const f=o[d]?{class:o[d]}:void 0,p=a.createContainerElement("code",f),m=a.createContainerElement("pre",g,p);a.insert(u,m),s.bindElements(r.item,p)}}const v="paragraph";class k extends e.Plugin{static get pluginName(){return"CodeBlockEditing"}static get requires(){return[t.ShiftEnter]}constructor(e){super(e),e.config.define("codeBlock",{languages:[{language:"plaintext",label:"Plain text"},{language:"c",label:"C"},{language:"cs",label:"C#"},{language:"cpp",label:"C++"},{language:"css",label:"CSS"},{language:"diff",label:"Diff"},{language:"html",label:"HTML"},{language:"java",label:"Java"},{language:"javascript",label:"JavaScript"},{language:"php",label:"PHP"},{language:"python",label:"Python"},{language:"ruby",label:"Ruby"},{language:"typescript",label:"TypeScript"},{language:"xml",label:"XML"}],indentSequence:"\t"})}init(){const e=this.editor,t=e.model.schema,n=e.model,o=e.editing.view,r=e.plugins.has("ListEditing")?e.plugins.get("ListEditing"):null,s=c(e);e.commands.add("codeBlock",new f(e)),e.commands.add("indentCodeBlock",new p(e)),e.commands.add("outdentCodeBlock",new m(e)),this.listenTo(o.document,"tab",((t,n)=>{const o=n.shiftKey?"outdentCodeBlock":"indentCodeBlock";e.commands.get(o).isEnabled&&(e.execute(o),n.stopPropagation(),n.preventDefault(),t.stop())}),{context:"pre"}),t.register("codeBlock",{allowWhere:"$block",allowChildren:"$text",isBlock:!0,allowAttributes:["language"]}),t.addAttributeCheck(((e,t)=>!!(e.endsWith("codeBlock")&&r&&r.getListAttributeNames().includes(t))||!e.endsWith("codeBlock $text")&&void 0)),e.model.schema.addChildCheck(((e,t)=>{if(e.endsWith("codeBlock")&&t.isObject)return!1})),e.editing.downcastDispatcher.on("insert:codeBlock",b(n,s,!0)),e.data.downcastDispatcher.on("insert:codeBlock",b(n,s)),e.data.downcastDispatcher.on("insert:softBreak",function(e){return(t,n,o)=>{if("codeBlock"!==n.item.parent.name)return;const{writer:i,mapper:r,consumable:c}=o;if(!c.consume(n.item,"insert"))return;const a=r.toViewPosition(e.createPositionBefore(n.item));i.insert(a,i.createText("\n"))}}(n),{priority:"high"}),e.data.upcastDispatcher.on("element:code",function(e,t){const n=a(t,"class","language"),o=t[0].language;return(e,t,i)=>{const r=t.viewItem,c=r.parent;if(!c||!c.is("element","pre"))return;if(t.modelCursor.findAncestor("codeBlock"))return;const{consumable:a,writer:s}=i;if(!a.test(r,{name:!0}))return;const l=s.createElement("codeBlock"),d=[...r.getClassNames()];d.length||d.push("");for(const e of d){const t=n[e];if(t){s.setAttribute("language",t,l);break}}l.hasAttribute("language")||s.setAttribute("language",o,l),i.convertChildren(r,l),i.safeInsert(l,t.modelCursor)&&(a.consume(r,{name:!0}),i.updateConversionResult(l,t))}}(0,s)),e.data.upcastDispatcher.on("text",((e,t,{consumable:n,writer:o})=>{let i=t.modelCursor;if(!n.test(t.viewItem))return;if(!i.findAncestor("codeBlock"))return;n.consume(t.viewItem);const r=t.viewItem.data.split("\n").map((e=>o.createText(e))),c=r[r.length-1];for(const e of r)if(o.insert(e,i),i=i.getShiftedBy(e.offsetSize),e!==c){const e=o.createElement("softBreak");o.insert(e,i),i=o.createPositionAfter(e)}t.modelRange=o.createRange(t.modelCursor,i),t.modelCursor=i})),e.data.upcastDispatcher.on("element:pre",((e,t,{consumable:n})=>{const o=t.viewItem;if(o.findAncestor("pre"))return;const i=Array.from(o.getChildren()),r=i.find((e=>e.is("element","code")));if(r)for(const e of i)e!==r&&e.is("$text")&&n.consume(e,{name:!0})}),{priority:"high"}),this.listenTo(e.editing.view.document,"clipboardInput",((t,o)=>{let r=n.createRange(n.document.selection.anchor);if(o.targetRanges&&(r=e.editing.mapper.toModelRange(o.targetRanges[0])),!r.start.parent.is("element","codeBlock"))return;const c=o.dataTransfer.getData("text/plain"),a=new i.UpcastWriter(e.editing.view.document);o.content=function(e,t){const n=e.createDocumentFragment(),o=t.split("\n"),i=o.reduce(((t,n,i)=>(t.push(n),i<o.length-1&&t.push(e.createElement("br")),t)),[]);return e.appendChild(i,n),n}(a,c)})),this.listenTo(n,"getSelectedContent",((e,[o])=>{const i=o.anchor;!o.isCollapsed&&i.parent.is("element","codeBlock")&&i.hasSameParentAs(o.focus)&&n.change((n=>{const r=e.return;if(i.parent.is("element")&&(r.childCount>1||o.containsEntireContent(i.parent))){const t=n.createElement("codeBlock",i.parent.getAttributes());n.append(r,t);const o=n.createDocumentFragment();return n.append(t,o),void(e.return=o)}const c=r.getChild(0);t.checkAttribute(c,"code")&&n.setAttribute("code",!0,c)}))}))}afterInit(){const e=this.editor,t=e.commands,n=t.get("indent"),o=t.get("outdent");n&&n.registerChildCommand(t.get("indentCodeBlock"),{priority:"highest"}),o&&o.registerChildCommand(t.get("outdentCodeBlock")),this.listenTo(e.editing.view.document,"enter",((t,n)=>{e.model.document.selection.getLastPosition().parent.is("element","codeBlock")&&(function(e,t){const n=e.model,o=n.document,i=e.editing.view,r=o.selection.getLastPosition(),c=r.nodeAfter;if(t||!o.selection.isCollapsed||!r.isAtStart)return!1;if(!w(c))return!1;return e.model.change((t=>{e.execute("enter");const n=o.selection.anchor.parent.previousSibling;t.rename(n,v),t.setSelection(n,"in"),e.model.schema.removeDisallowedAttributes([n],t),t.remove(c)})),i.scrollToTheSelection(),!0}(e,n.isSoft)||function(e,t){const n=e.model,o=n.document,i=e.editing.view,r=o.selection.getLastPosition(),c=r.nodeBefore;let a;if(t||!o.selection.isCollapsed||!r.isAtEnd||!c||!c.previousSibling)return!1;if(w(c)&&w(c.previousSibling))a=n.createRange(n.createPositionBefore(c.previousSibling),n.createPositionAfter(c));else if(B(c)&&w(c.previousSibling)&&w(c.previousSibling.previousSibling))a=n.createRange(n.createPositionBefore(c.previousSibling.previousSibling),n.createPositionAfter(c));else{if(!(B(c)&&w(c.previousSibling)&&B(c.previousSibling.previousSibling)&&c.previousSibling.previousSibling&&w(c.previousSibling.previousSibling.previousSibling)))return!1;a=n.createRange(n.createPositionBefore(c.previousSibling.previousSibling.previousSibling),n.createPositionAfter(c))}return e.model.change((t=>{t.remove(a),e.execute("enter");const n=o.selection.anchor.parent;t.rename(n,v),e.model.schema.removeDisallowedAttributes([n],t)})),i.scrollToTheSelection(),!0}(e,n.isSoft)||function(e){const t=e.model,n=t.document,o=n.selection.getLastPosition(),i=o.nodeBefore||o.textNode;let r;i&&i.is("$text")&&(r=s(i));e.model.change((t=>{e.execute("shiftEnter"),r&&t.insertText(r,n.selection.anchor)}))}(e),n.preventDefault(),t.stop())}),{context:"pre"}),this._initAriaAnnouncements()}_initAriaAnnouncements(){const{model:e,ui:t,t:n}=this.editor,o=c(this.editor);let i=null;e.document.selection.on("change:range",(()=>{const r=e.document.selection.focus.parent;t&&i!==r&&r.is("element")&&(i&&i.is("element","codeBlock")&&t.ariaLiveAnnouncer.announce(g(n,o,i,"leave")),r.is("element","codeBlock")&&t.ariaLiveAnnouncer.announce(g(n,o,r,"enter")),i=r)}))}}function B(e){return e&&e.is("$text")&&!e.data.match(/\S/)}function w(e){return e&&e.is("element","softBreak")}var C=n(311),x=n(591),S=n.n(x),y=n(535),A={injectType:"singletonStyleTag",attributes:{"data-cke":!0},insert:"head",singleton:!0};S()(y.A,A);y.A.locals;class E extends e.Plugin{static get pluginName(){return"CodeBlockUI"}init(){const t=this.editor,n=t.t,o=t.ui.componentFactory,i=c(t),r=this._getLanguageListItemDefinitions(i),a=t.commands.get("codeBlock");o.add("codeBlock",(o=>{const i=(0,C.createDropdown)(o,C.SplitButtonView),c=i.buttonView,s=n("Insert code block");return c.set({label:s,tooltip:!0,icon:e.icons.codeBlock,isToggleable:!0}),c.bind("isOn").to(a,"value",(e=>!!e)),c.on("execute",(()=>{t.execute("codeBlock",{usePreviousLanguageChoice:!0}),t.editing.view.focus()})),i.on("execute",(e=>{t.execute("codeBlock",{language:e.source._codeBlockLanguage,forceValue:!0}),t.editing.view.focus()})),i.class="ck-code-block-dropdown",i.bind("isEnabled").to(a),(0,C.addListToDropdown)(i,r,{role:"menu",ariaLabel:s}),i})),o.add("menuBar:codeBlock",(o=>{const i=new C.MenuBarMenuView(o);i.buttonView.set({label:n("Code block"),icon:e.icons.codeBlock}),i.bind("isEnabled").to(a);const c=new C.MenuBarMenuListView(o);c.set({ariaLabel:n("Insert code block")});for(const e of r){const n=new C.MenuBarMenuListItemView(o,i),r=new C.MenuBarMenuListItemButtonView(o);r.bind(...Object.keys(e.model)).to(e.model),r.bind("ariaChecked").to(r,"isOn"),r.delegate("execute").to(i),r.on("execute",(()=>{t.execute("codeBlock",{language:e.model._codeBlockLanguage,forceValue:a.value!=e.model._codeBlockLanguage}),t.editing.view.focus()})),n.children.add(r),c.items.add(n)}return i.panelView.children.add(c),i}))}_getLanguageListItemDefinitions(e){const t=this.editor.commands.get("codeBlock"),n=new r.Collection;for(const o of e){const e={type:"button",model:new C.ViewModel({_codeBlockLanguage:o.language,label:o.label,role:"menuitemradio",withText:!0})};e.model.bind("isOn").to(t,"value",(t=>t===e.model._codeBlockLanguage)),n.add(e)}return n}}class _ extends e.Plugin{static get requires(){return[k,E]}static get pluginName(){return"CodeBlock"}}})(),(window.CKEditor5=window.CKEditor5||{}).codeBlock=o})();
package/dist/index.js CHANGED
@@ -224,37 +224,26 @@ import { createDropdown, SplitButtonView, addListToDropdown, MenuBarMenuView, Me
224
224
  return t('Leaving code snippet');
225
225
  }
226
226
 
227
- /**
228
- * The code block command plugin.
229
- */ class CodeBlockCommand extends Command {
230
- /**
231
- * Contains the last used language.
232
- */ _lastLanguage;
233
- /**
234
- * @inheritDoc
235
- */ constructor(editor){
236
- super(editor);
237
- this._lastLanguage = null;
238
- }
227
+ class CodeBlockCommand extends Command {
239
228
  /**
240
- * @inheritDoc
241
- */ refresh() {
229
+ * @inheritDoc
230
+ */ refresh() {
242
231
  this.value = this._getValue();
243
232
  this.isEnabled = this._checkEnabled();
244
233
  }
245
234
  /**
246
- * Executes the command. When the command {@link #value is on}, all topmost code blocks within
247
- * the selection will be removed. If it is off, all selected blocks will be flattened and
248
- * wrapped by a code block.
249
- *
250
- * @fires execute
251
- * @param options Command options.
252
- * @param options.language The code block language.
253
- * @param options.forceValue If set, it will force the command behavior. If `true`, the command will apply a code block,
254
- * otherwise the command will remove the code block. If not set, the command will act basing on its current value.
255
- * @param options.usePreviousLanguageChoice If set on `true` and the `options.language` is not specified, the command
256
- * will apply the previous language (if the command was already executed) when inserting the `codeBlock` element.
257
- */ execute(options = {}) {
235
+ * Executes the command. When the command {@link #value is on}, all topmost code blocks within
236
+ * the selection will be removed. If it is off, all selected blocks will be flattened and
237
+ * wrapped by a code block.
238
+ *
239
+ * @fires execute
240
+ * @param options Command options.
241
+ * @param options.language The code block language.
242
+ * @param options.forceValue If set, it will force the command behavior. If `true`, the command will apply a code block,
243
+ * otherwise the command will remove the code block. If not set, the command will act basing on its current value.
244
+ * @param options.usePreviousLanguageChoice If set on `true` and the `options.language` is not specified, the command
245
+ * will apply the previous language (if the command was already executed) when inserting the `codeBlock` element.
246
+ */ execute(options = {}) {
258
247
  const editor = this.editor;
259
248
  const model = editor.model;
260
249
  const selection = model.document.selection;
@@ -272,20 +261,20 @@ import { createDropdown, SplitButtonView, addListToDropdown, MenuBarMenuView, Me
272
261
  });
273
262
  }
274
263
  /**
275
- * Checks the command's {@link #value}.
276
- *
277
- * @returns The current value.
278
- */ _getValue() {
264
+ * Checks the command's {@link #value}.
265
+ *
266
+ * @returns The current value.
267
+ */ _getValue() {
279
268
  const selection = this.editor.model.document.selection;
280
269
  const firstBlock = first(selection.getSelectedBlocks());
281
270
  const isCodeBlock = !!(firstBlock && firstBlock.is('element', 'codeBlock'));
282
271
  return isCodeBlock ? firstBlock.getAttribute('language') : false;
283
272
  }
284
273
  /**
285
- * Checks whether the command can be enabled in the current context.
286
- *
287
- * @returns Whether the command should be enabled.
288
- */ _checkEnabled() {
274
+ * Checks whether the command can be enabled in the current context.
275
+ *
276
+ * @returns Whether the command should be enabled.
277
+ */ _checkEnabled() {
289
278
  if (this.value) {
290
279
  return true;
291
280
  }
@@ -335,6 +324,12 @@ import { createDropdown, SplitButtonView, addListToDropdown, MenuBarMenuView, Me
335
324
  writer.removeAttribute('language', block);
336
325
  }
337
326
  }
327
+ /**
328
+ * @inheritDoc
329
+ */ constructor(editor){
330
+ super(editor);
331
+ this._lastLanguage = null;
332
+ }
338
333
  }
339
334
  /**
340
335
  * Picks the language for the new code block. If any language is passed as an option,
@@ -351,27 +346,18 @@ import { createDropdown, SplitButtonView, addListToDropdown, MenuBarMenuView, Me
351
346
  return defaultLanguage;
352
347
  }
353
348
 
354
- /**
355
- * The code block indentation increase command plugin.
356
- */ class IndentCodeBlockCommand extends Command {
349
+ class IndentCodeBlockCommand extends Command {
357
350
  /**
358
- * A sequence of characters added to the line when the command is executed.
359
- */ _indentSequence;
360
- constructor(editor){
361
- super(editor);
362
- this._indentSequence = editor.config.get('codeBlock.indentSequence');
363
- }
364
- /**
365
- * @inheritDoc
366
- */ refresh() {
351
+ * @inheritDoc
352
+ */ refresh() {
367
353
  this.isEnabled = this._checkEnabled();
368
354
  }
369
355
  /**
370
- * Executes the command. When the command {@link #isEnabled is enabled}, the indentation of the
371
- * code lines in the selection will be increased.
372
- *
373
- * @fires execute
374
- */ execute() {
356
+ * Executes the command. When the command {@link #isEnabled is enabled}, the indentation of the
357
+ * code lines in the selection will be increased.
358
+ *
359
+ * @fires execute
360
+ */ execute() {
375
361
  const editor = this.editor;
376
362
  const model = editor.model;
377
363
  model.change((writer)=>{
@@ -409,8 +395,8 @@ import { createDropdown, SplitButtonView, addListToDropdown, MenuBarMenuView, Me
409
395
  });
410
396
  }
411
397
  /**
412
- * Checks whether the command can be enabled in the current context.
413
- */ _checkEnabled() {
398
+ * Checks whether the command can be enabled in the current context.
399
+ */ _checkEnabled() {
414
400
  if (!this._indentSequence) {
415
401
  return false;
416
402
  }
@@ -418,29 +404,24 @@ import { createDropdown, SplitButtonView, addListToDropdown, MenuBarMenuView, Me
418
404
  // because you can always indent code lines.
419
405
  return isModelSelectionInCodeBlock(this.editor.model.document.selection);
420
406
  }
421
- }
422
-
423
- /**
424
- * The code block indentation decrease command plugin.
425
- */ class OutdentCodeBlockCommand extends Command {
426
- /**
427
- * A sequence of characters removed from the line when the command is executed.
428
- */ _indentSequence;
429
407
  constructor(editor){
430
408
  super(editor);
431
409
  this._indentSequence = editor.config.get('codeBlock.indentSequence');
432
410
  }
411
+ }
412
+
413
+ class OutdentCodeBlockCommand extends Command {
433
414
  /**
434
- * @inheritDoc
435
- */ refresh() {
415
+ * @inheritDoc
416
+ */ refresh() {
436
417
  this.isEnabled = this._checkEnabled();
437
418
  }
438
419
  /**
439
- * Executes the command. When the command {@link #isEnabled is enabled}, the indentation of the
440
- * code lines in the selection will be decreased.
441
- *
442
- * @fires execute
443
- */ execute() {
420
+ * Executes the command. When the command {@link #isEnabled is enabled}, the indentation of the
421
+ * code lines in the selection will be decreased.
422
+ *
423
+ * @fires execute
424
+ */ execute() {
444
425
  const editor = this.editor;
445
426
  const model = editor.model;
446
427
  model.change(()=>{
@@ -479,11 +460,11 @@ import { createDropdown, SplitButtonView, addListToDropdown, MenuBarMenuView, Me
479
460
  });
480
461
  }
481
462
  /**
482
- * Checks whether the command can be enabled in the current context.
483
- *
484
- * @private
485
- * @returns {Boolean} Whether the command should be enabled.
486
- */ _checkEnabled() {
463
+ * Checks whether the command can be enabled in the current context.
464
+ *
465
+ * @private
466
+ * @returns {Boolean} Whether the command should be enabled.
467
+ */ _checkEnabled() {
487
468
  if (!this._indentSequence) {
488
469
  return false;
489
470
  }
@@ -497,6 +478,10 @@ import { createDropdown, SplitButtonView, addListToDropdown, MenuBarMenuView, Me
497
478
  return getLastOutdentableSequenceRange(model, position, this._indentSequence);
498
479
  });
499
480
  }
481
+ constructor(editor){
482
+ super(editor);
483
+ this._indentSequence = editor.config.get('codeBlock.indentSequence');
484
+ }
500
485
  }
501
486
  // For a position coming from `getIndentOutdentPositions()`, it returns the range representing
502
487
  // the last occurrence of the indent sequence among the leading whitespaces of the code line the
@@ -839,97 +824,27 @@ function getCodeLineTextNodeAtPosition(position) {
839
824
  }
840
825
 
841
826
  const DEFAULT_ELEMENT = 'paragraph';
842
- /**
843
- * The editing part of the code block feature.
844
- *
845
- * Introduces the `'codeBlock'` command and the `'codeBlock'` model element.
846
- */ class CodeBlockEditing extends Plugin {
827
+ class CodeBlockEditing extends Plugin {
847
828
  /**
848
- * @inheritDoc
849
- */ static get pluginName() {
829
+ * @inheritDoc
830
+ */ static get pluginName() {
850
831
  return 'CodeBlockEditing';
851
832
  }
852
833
  /**
853
- * @inheritDoc
854
- */ static get requires() {
834
+ * @inheritDoc
835
+ */ static get requires() {
855
836
  return [
856
837
  ShiftEnter
857
838
  ];
858
839
  }
859
840
  /**
860
- * @inheritDoc
861
- */ constructor(editor){
862
- super(editor);
863
- editor.config.define('codeBlock', {
864
- languages: [
865
- {
866
- language: 'plaintext',
867
- label: 'Plain text'
868
- },
869
- {
870
- language: 'c',
871
- label: 'C'
872
- },
873
- {
874
- language: 'cs',
875
- label: 'C#'
876
- },
877
- {
878
- language: 'cpp',
879
- label: 'C++'
880
- },
881
- {
882
- language: 'css',
883
- label: 'CSS'
884
- },
885
- {
886
- language: 'diff',
887
- label: 'Diff'
888
- },
889
- {
890
- language: 'html',
891
- label: 'HTML'
892
- },
893
- {
894
- language: 'java',
895
- label: 'Java'
896
- },
897
- {
898
- language: 'javascript',
899
- label: 'JavaScript'
900
- },
901
- {
902
- language: 'php',
903
- label: 'PHP'
904
- },
905
- {
906
- language: 'python',
907
- label: 'Python'
908
- },
909
- {
910
- language: 'ruby',
911
- label: 'Ruby'
912
- },
913
- {
914
- language: 'typescript',
915
- label: 'TypeScript'
916
- },
917
- {
918
- language: 'xml',
919
- label: 'XML'
920
- }
921
- ],
922
- // A single tab.
923
- indentSequence: '\t'
924
- });
925
- }
926
- /**
927
- * @inheritDoc
928
- */ init() {
841
+ * @inheritDoc
842
+ */ init() {
929
843
  const editor = this.editor;
930
844
  const schema = editor.model.schema;
931
845
  const model = editor.model;
932
846
  const view = editor.editing.view;
847
+ const listEditing = editor.plugins.has('ListEditing') ? editor.plugins.get('ListEditing') : null;
933
848
  const normalizedLanguagesDefs = getNormalizedAndLocalizedLanguageDefinitions(editor);
934
849
  // The main command.
935
850
  editor.commands.add('codeBlock', new CodeBlockCommand(editor));
@@ -952,21 +867,27 @@ const DEFAULT_ELEMENT = 'paragraph';
952
867
  schema.register('codeBlock', {
953
868
  allowWhere: '$block',
954
869
  allowChildren: '$text',
955
- // Disallow `$inlineObject` and its derivatives like `inlineWidget` inside `codeBlock` to ensure that only text,
956
- // not other inline elements like inline images, are allowed. This maintains the semantic integrity of code blocks.
957
- disallowChildren: '$inlineObject',
870
+ isBlock: true,
958
871
  allowAttributes: [
959
872
  'language'
960
- ],
961
- allowAttributesOf: '$listItem',
962
- isBlock: true
873
+ ]
963
874
  });
964
- // Disallow all attributes on `$text` inside `codeBlock`.
965
- schema.addAttributeCheck((context)=>{
875
+ // Allow all list* attributes on `codeBlock` (integration with DocumentList).
876
+ // Disallow all attributes on $text inside `codeBlock`.
877
+ schema.addAttributeCheck((context, attributeName)=>{
878
+ if (context.endsWith('codeBlock') && listEditing && listEditing.getListAttributeNames().includes(attributeName)) {
879
+ return true;
880
+ }
966
881
  if (context.endsWith('codeBlock $text')) {
967
882
  return false;
968
883
  }
969
884
  });
885
+ // Disallow object elements inside `codeBlock`. See #9567.
886
+ editor.model.schema.addChildCheck((context, childDefinition)=>{
887
+ if (context.endsWith('codeBlock') && childDefinition.isObject) {
888
+ return false;
889
+ }
890
+ });
970
891
  // Conversion.
971
892
  editor.editing.downcastDispatcher.on('insert:codeBlock', modelToViewCodeBlockInsertion(model, normalizedLanguagesDefs, true));
972
893
  editor.data.downcastDispatcher.on('insert:codeBlock', modelToViewCodeBlockInsertion(model, normalizedLanguagesDefs));
@@ -1025,8 +946,8 @@ const DEFAULT_ELEMENT = 'paragraph';
1025
946
  });
1026
947
  }
1027
948
  /**
1028
- * @inheritDoc
1029
- */ afterInit() {
949
+ * @inheritDoc
950
+ */ afterInit() {
1030
951
  const editor = this.editor;
1031
952
  const commands = editor.commands;
1032
953
  const indent = commands.get('indent');
@@ -1063,11 +984,11 @@ const DEFAULT_ELEMENT = 'paragraph';
1063
984
  this._initAriaAnnouncements();
1064
985
  }
1065
986
  /**
1066
- * Observe when user enters or leaves code block and set proper aria value in global live announcer.
1067
- * This allows screen readers to indicate when the user has entered and left the specified code block.
1068
- *
1069
- * @internal
1070
- */ _initAriaAnnouncements() {
987
+ * Observe when user enters or leaves code block and set proper aria value in global live announcer.
988
+ * This allows screen readers to indicate when the user has entered and left the specified code block.
989
+ *
990
+ * @internal
991
+ */ _initAriaAnnouncements() {
1071
992
  const { model, ui, t } = this.editor;
1072
993
  const languageDefs = getNormalizedAndLocalizedLanguageDefinitions(this.editor);
1073
994
  let lastFocusedCodeBlock = null;
@@ -1085,6 +1006,73 @@ const DEFAULT_ELEMENT = 'paragraph';
1085
1006
  lastFocusedCodeBlock = focusParent;
1086
1007
  });
1087
1008
  }
1009
+ /**
1010
+ * @inheritDoc
1011
+ */ constructor(editor){
1012
+ super(editor);
1013
+ editor.config.define('codeBlock', {
1014
+ languages: [
1015
+ {
1016
+ language: 'plaintext',
1017
+ label: 'Plain text'
1018
+ },
1019
+ {
1020
+ language: 'c',
1021
+ label: 'C'
1022
+ },
1023
+ {
1024
+ language: 'cs',
1025
+ label: 'C#'
1026
+ },
1027
+ {
1028
+ language: 'cpp',
1029
+ label: 'C++'
1030
+ },
1031
+ {
1032
+ language: 'css',
1033
+ label: 'CSS'
1034
+ },
1035
+ {
1036
+ language: 'diff',
1037
+ label: 'Diff'
1038
+ },
1039
+ {
1040
+ language: 'html',
1041
+ label: 'HTML'
1042
+ },
1043
+ {
1044
+ language: 'java',
1045
+ label: 'Java'
1046
+ },
1047
+ {
1048
+ language: 'javascript',
1049
+ label: 'JavaScript'
1050
+ },
1051
+ {
1052
+ language: 'php',
1053
+ label: 'PHP'
1054
+ },
1055
+ {
1056
+ language: 'python',
1057
+ label: 'Python'
1058
+ },
1059
+ {
1060
+ language: 'ruby',
1061
+ label: 'Ruby'
1062
+ },
1063
+ {
1064
+ language: 'typescript',
1065
+ label: 'TypeScript'
1066
+ },
1067
+ {
1068
+ language: 'xml',
1069
+ label: 'XML'
1070
+ }
1071
+ ],
1072
+ // A single tab.
1073
+ indentSequence: '\t'
1074
+ });
1075
+ }
1088
1076
  }
1089
1077
  /**
1090
1078
  * Normally, when the Enter (or Shift+Enter) key is pressed, a soft line break is to be added to the
@@ -1236,19 +1224,15 @@ function isSoftBreakNode(node) {
1236
1224
  return node && node.is('element', 'softBreak');
1237
1225
  }
1238
1226
 
1239
- /**
1240
- * The code block UI plugin.
1241
- *
1242
- * Introduces the `'codeBlock'` dropdown.
1243
- */ class CodeBlockUI extends Plugin {
1227
+ class CodeBlockUI extends Plugin {
1244
1228
  /**
1245
- * @inheritDoc
1246
- */ static get pluginName() {
1229
+ * @inheritDoc
1230
+ */ static get pluginName() {
1247
1231
  return 'CodeBlockUI';
1248
1232
  }
1249
1233
  /**
1250
- * @inheritDoc
1251
- */ init() {
1234
+ * @inheritDoc
1235
+ */ init() {
1252
1236
  const editor = this.editor;
1253
1237
  const t = editor.t;
1254
1238
  const componentFactory = editor.ui.componentFactory;
@@ -1319,9 +1303,9 @@ function isSoftBreakNode(node) {
1319
1303
  });
1320
1304
  }
1321
1305
  /**
1322
- * A helper returning a collection of the `codeBlock` dropdown items representing languages
1323
- * available for the user to choose from.
1324
- */ _getLanguageListItemDefinitions(normalizedLanguageDefs) {
1306
+ * A helper returning a collection of the `codeBlock` dropdown items representing languages
1307
+ * available for the user to choose from.
1308
+ */ _getLanguageListItemDefinitions(normalizedLanguageDefs) {
1325
1309
  const editor = this.editor;
1326
1310
  const command = editor.commands.get('codeBlock');
1327
1311
  const itemDefinitions = new Collection();
@@ -1344,26 +1328,18 @@ function isSoftBreakNode(node) {
1344
1328
  }
1345
1329
  }
1346
1330
 
1347
- /**
1348
- * The code block plugin.
1349
- *
1350
- * For more information about this feature check the {@glink api/code-block package page} and the
1351
- * {@glink features/code-blocks code block} feature guide.
1352
- *
1353
- * This is a "glue" plugin that loads the {@link module:code-block/codeblockediting~CodeBlockEditing code block editing feature}
1354
- * and the {@link module:code-block/codeblockui~CodeBlockUI code block UI feature}.
1355
- */ class CodeBlock extends Plugin {
1331
+ class CodeBlock extends Plugin {
1356
1332
  /**
1357
- * @inheritDoc
1358
- */ static get requires() {
1333
+ * @inheritDoc
1334
+ */ static get requires() {
1359
1335
  return [
1360
1336
  CodeBlockEditing,
1361
1337
  CodeBlockUI
1362
1338
  ];
1363
1339
  }
1364
1340
  /**
1365
- * @inheritDoc
1366
- */ static get pluginName() {
1341
+ * @inheritDoc
1342
+ */ static get pluginName() {
1367
1343
  return 'CodeBlock';
1368
1344
  }
1369
1345
  }