@ckeditor/ckeditor5-code-block 30.0.0 → 31.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.
@@ -2,4 +2,4 @@
2
2
  * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
3
3
  * For licensing, see LICENSE.md.
4
4
  */
5
- !function(e){const t=e.en=e.en||{};t.dictionary=Object.assign(t.dictionary||{},{"Insert code block":"Insert code block","Plain text":"Plain text"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={})),window.CKEditor5=window.CKEditor5||{},window.CKEditor5.codeBlock=function(e){var t={};function n(o){if(t[o])return t[o].exports;var r=t[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},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 o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(o,r,function(t){return e[t]}.bind(null,r));return o},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=9)}([function(e,t,n){e.exports=n(2)("./src/core.js")},function(e,t,n){e.exports=n(2)("./src/utils.js")},function(e,t){e.exports=CKEditor5.dll},function(e,t,n){e.exports=n(2)("./src/ui.js")},function(e,t,n){e.exports=n(2)("./src/enter.js")},function(e,t,n){e.exports=n(2)("./src/engine.js")},function(e,t,n){var o=n(7),r=n(8);"string"==typeof(r=r.__esModule?r.default:r)&&(r=[[e.i,r,""]]);var i={injectType:"singletonStyleTag",attributes:{"data-cke":!0},insert:"head",singleton:!0};o(r,i);e.exports=r.locals||{}},function(e,t,n){"use strict";var o,r=function(){return void 0===o&&(o=Boolean(window&&document&&document.all&&!window.atob)),o},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]}}(),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=[],r=0;r<e.length;r++){var i=e[r],s=t.base?i[0]+t.base:i[0],l=n[s]||0,d="".concat(s," ").concat(l);n[s]=l+1;var u=a(d),f={css:i[1],media:i[2],sourceMap:i[3]};-1!==u?(c[u].references++,c[u].updater(f)):c.push({identifier:d,updater:h(f,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 r=n.nc;r&&(o.nonce=r)}if(Object.keys(o).forEach((function(e){t.setAttribute(e,o[e])})),"function"==typeof e.insert)e.insert(t);else{var c=i(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 f(e,t,n,o){var r=n?"":o.media?"@media ".concat(o.media," {").concat(o.css,"}"):o.css;if(e.styleSheet)e.styleSheet.cssText=u(t,r);else{var i=document.createTextNode(r),c=e.childNodes;c[t]&&e.removeChild(c[t]),c.length?e.insertBefore(i,c[t]):e.appendChild(i)}}function g(e,t,n){var o=n.css,r=n.media,i=n.sourceMap;if(r?e.setAttribute("media",r):e.removeAttribute("media"),i&&"undefined"!=typeof btoa&&(o+="\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(i))))," */")),e.styleSheet)e.styleSheet.cssText=o;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(o))}}var m=null,p=0;function h(e,t){var n,o,r;if(t.singleton){var i=p++;n=m||(m=l(t)),o=f.bind(null,n,i,!1),r=f.bind(null,n,i,!0)}else n=l(t),o=g.bind(null,n,t),r=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 r()}}e.exports=function(e,t){(t=t||{}).singleton||"boolean"==typeof t.singleton||(t.singleton=r());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 r=a(n[o]);c[r].references--}for(var i=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=i}}}},function(e,t){e.exports=".ck-content pre{padding:1em;color:#353535;background:hsla(0,0%,78%,.3);border:1px solid #c4c4c4;border-radius:2px;text-align:left;direction:ltr;tab-size:4;white-space:pre-wrap;font-style:normal;min-width:200px}.ck-content pre code{background:unset;padding:0;border-radius: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{top:-1px;right:10px;background:var(--ck-color-code-block-label-background);font-size:10px;font-family:var(--ck-font-face);line-height:16px;padding:var(--ck-spacing-tiny) var(--ck-spacing-medium);color:#fff;white-space:nowrap}.ck.ck-code-block-dropdown .ck-dropdown__panel{max-height:250px;overflow-y:auto;overflow-x:hidden}"},function(e,t,n){"use strict";n.r(t),n.d(t,"CodeBlock",(function(){return w})),n.d(t,"CodeBlockEditing",(function(){return k})),n.d(t,"CodeBlockUI",(function(){return B}));var o=n(0),r=n(4),i=n(5),c=n(1);function a(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 s(e,t,n){const o={};for(const r of e)"class"===t?o[r[t].split(" ").shift()]=r[n]:o[r[t]]=r[n];return o}function l(e){return e.data.match(/^(\s*)/)[0]}function d(e){const t=e.document.selection,n=[];if(t.isCollapsed)n.push(t.anchor);else{const o=t.getFirstRange().getWalker({ignoreElementEnd:!0,direction:"backward"});for(const{item:t}of o)if(t.is("$textProxy")&&t.parent.is("element","codeBlock")){const o=l(t.textNode),{parent:r,startOffset:i}=t.textNode,c=e.createPositionAt(r,i+o.length);n.push(c)}}return n}function u(e){const t=Object(c.first)(e.getSelectedBlocks());return t&&t.is("element","codeBlock")}class f extends o.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,r=a(t)[0],i=Array.from(o.getSelectedBlocks()),c=void 0===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,r.language);n.change(e=>{c?this._applyCodeBlock(e,i,s):this._removeCodeBlock(e,i)})}_getValue(){const e=this.editor.model.document.selection,t=Object(c.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=Object(c.first)(e.getSelectedBlocks());return!!n&&g(t,n)}_applyCodeBlock(e,t,n){this._lastLanguage=n;const o=this.editor.model.schema,r=t.filter(e=>g(o,e));for(const t of r)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));r.reverse().forEach((t,n)=>{const o=r[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));e.rename(n.nodeAfter,"paragraph"),e.removeAttribute("language",n.nodeAfter),e.remove(t)}e.rename(t,"paragraph"),e.removeAttribute("language",t)}}}function g(e,t){return!t.is("rootElement")&&!e.isLimit(t)&&e.checkChild(t.parent,"codeBlock")}class m extends o.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=d(e);for(const e of n)t.insertText(this._indentSequence,e)})}_checkEnabled(){return!!this._indentSequence&&u(this.editor.model.document.selection)}}class p extends o.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=d(e);for(const e of n){const n=h(this.editor.model,e,this._indentSequence);n&&t.remove(n)}})}_checkEnabled(){if(!this._indentSequence)return!1;const e=this.editor.model;return!!u(e.document.selection)&&d(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 r=l(o),i=r.lastIndexOf(n);if(i+n.length!==r.length)return null;if(-1===i)return null;const{parent:c,startOffset:a}=o;return e.createRange(e.createPositionAt(c,a+i),e.createPositionAt(c,a+i+n.length))}function b(e,t,n=!1){const o=s(t,"language","class"),r=s(t,"language","label");return(t,i,c)=>{const{writer:a,mapper:s,consumable:l}=c;if(!l.consume(i.item,"insert"))return;const d=i.item.getAttribute("language"),u=s.toViewPosition(e.createPositionBefore(i.item)),f={};n&&(f["data-language"]=r[d],f.spellcheck="false");const g=a.createContainerElement("pre",f),m=a.createContainerElement("code",{class:o[d]||null});a.insert(a.createPositionAt(g,0),m),a.insert(u,g),s.bindElements(i.item,m)}}class k extends o.Plugin{static get pluginName(){return"CodeBlockEditing"}static get requires(){return[r.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,a(e));e.commands.add("codeBlock",new f(e)),e.commands.add("indentCodeBlock",new m(e)),e.commands.add("outdentCodeBlock",new p(e));const r=e=>(t,n)=>{this.editor.commands.get(e).isEnabled&&(this.editor.execute(e),n())};e.keystrokes.set("Tab",r("indentCodeBlock")),e.keystrokes.set("Shift+Tab",r("outdentCodeBlock")),t.register("codeBlock",{allowWhere:"$block",allowChildren:"$text",isBlock:!0,allowAttributes:["language"]}),t.addAttributeCheck(e=>{if(e.endsWith("codeBlock $text"))return!1}),e.model.schema.addChildCheck((e,t)=>{if(e.endsWith("codeBlock")&&t.isObject)return!1}),e.editing.downcastDispatcher.on("insert:codeBlock",b(n,o,!0)),e.data.downcastDispatcher.on("insert:codeBlock",b(n,o)),e.data.downcastDispatcher.on("insert:softBreak",function(e){return(t,n,o)=>{if("codeBlock"!==n.item.parent.name)return;const{writer:r,mapper:i,consumable:c}=o;if(!c.consume(n.item,"insert"))return;const a=i.toViewPosition(e.createPositionBefore(n.item));r.insert(a,r.createText("\n"))}}(n),{priority:"high"}),e.data.upcastDispatcher.on("element:code",function(e,t){const n=s(t,"class","language"),o=t[0].language;return(e,t,r)=>{const i=t.viewItem,c=i.parent;if(!c||!c.is("element","pre"))return;if(t.modelCursor.findAncestor("codeBlock"))return;const{consumable:a,writer:s}=r;if(!a.test(i,{name:!0}))return;const l=s.createElement("codeBlock"),d=[...i.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),r.convertChildren(i,l),r.safeInsert(l,t.modelCursor)&&(a.consume(i,{name:!0}),r.updateConversionResult(l,t))}}(0,o)),e.data.upcastDispatcher.on("text",(e,t,{consumable:n,writer:o})=>{let r=t.modelCursor;if(!n.test(t.viewItem))return;if(!r.findAncestor("codeBlock"))return;n.consume(t.viewItem);const i=t.viewItem.data.split("\n").map(e=>o.createText(e)),c=i[i.length-1];for(const e of i)if(o.insert(e,r),r=r.getShiftedBy(e.offsetSize),e!==c){const e=o.createElement("softBreak");o.insert(e,r),r=o.createPositionAfter(e)}t.modelRange=o.createRange(t.modelCursor,r),t.modelCursor=r}),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"),r=o.reduce((t,n,r)=>(t.push(n),r<o.length-1&&t.push(e.createElement("br")),t),[]);return e.appendChild(r,n),n}(a,c)}),this.listenTo(n,"getSelectedContent",(e,[o])=>{const r=o.anchor;!o.isCollapsed&&r.parent.is("element","codeBlock")&&r.hasSameParentAs(o.focus)&&n.change(n=>{const i=e.return;if(i.childCount>1||o.containsEntireContent(r.parent)){const t=n.createElement("codeBlock",r.parent.getAttributes());n.append(i,t);const o=n.createDocumentFragment();n.append(t,o),e.return=o}else{const e=i.getChild(0);t.checkAttribute(e,"code")&&n.setAttribute("code",!0,e)}})})}afterInit(){const e=this.editor,t=e.commands,n=t.get("indent"),o=t.get("outdent");n&&n.registerChildCommand(t.get("indentCodeBlock")),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.document,o=e.editing.view,r=n.selection.getLastPosition(),i=r.nodeAfter;if(t||!n.selection.isCollapsed||!r.isAtStart)return!1;if(!i||!i.is("element","softBreak"))return!1;return e.model.change(t=>{e.execute("enter");const o=n.selection.anchor.parent.previousSibling;t.rename(o,"paragraph"),t.setSelection(o,"in"),e.model.schema.removeDisallowedAttributes([o],t),t.remove(i)}),o.scrollToTheSelection(),!0}(e,n.isSoft)||function(e,t){const n=e.model,o=n.document,r=e.editing.view,i=o.selection.getLastPosition(),c=i.nodeBefore;let a;if(t||!o.selection.isCollapsed||!i.isAtEnd||!c)return!1;if(c.is("element","softBreak"))a=n.createRangeOn(c);else{if(!c.is("$text")||c.data.match(/\S/)||!c.previousSibling||!c.previousSibling.is("element","softBreak"))return!1;a=n.createRange(n.createPositionBefore(c.previousSibling),n.createPositionAfter(c))}return e.model.change(t=>{t.remove(a),e.execute("enter");const n=o.selection.anchor.parent;t.rename(n,"paragraph"),e.model.schema.removeDisallowedAttributes([n],t)}),r.scrollToTheSelection(),!0}(e,n.isSoft)||function(e){const t=e.model.document,n=t.selection.getLastPosition(),o=n.nodeBefore||n.textNode;let r;o&&o.is("$text")&&(r=l(o));e.model.change(n=>{e.execute("shiftEnter"),r&&n.insertText(r,t.selection.anchor)})}(e),n.preventDefault(),t.stop())},{context:"pre"})}}var v=n(3);n(6);class B extends o.Plugin{static get pluginName(){return"CodeBlockUI"}init(){const e=this.editor,t=e.t,n=e.ui.componentFactory,o=a(e);n.add("codeBlock",n=>{const r=e.commands.get("codeBlock"),i=Object(v.createDropdown)(n,v.SplitButtonView),c=i.buttonView;return c.set({label:t("Insert code block"),tooltip:!0,icon:'<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M12.87 12.61a.75.75 0 0 1-.089.976l-.085.07-3.154 2.254 3.412 2.414a.75.75 0 0 1 .237.95l-.057.095a.75.75 0 0 1-.95.237l-.096-.058-4.272-3.022-.003-1.223 4.01-2.867a.75.75 0 0 1 1.047.174zm2.795-.231.095.057 4.011 2.867-.003 1.223-4.272 3.022-.095.058a.75.75 0 0 1-.88-.151l-.07-.086-.058-.095a.75.75 0 0 1 .15-.88l.087-.07 3.412-2.414-3.154-2.253-.085-.071a.75.75 0 0 1 .862-1.207zM16 0a2 2 0 0 1 2 2v9.354l-.663-.492-.837-.001V2a.5.5 0 0 0-.5-.5H2a.5.5 0 0 0-.5.5v15a.5.5 0 0 0 .5.5h3.118L7.156 19H2a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h14zM5.009 15l.003 1H3v-1h2.009zm2.188-2-1.471 1H5v-1h2.197zM10 11v.095L8.668 12H7v-1h3zm4-2v1H7V9h7zm0-2v1H7V7h7zm-4-2v1H5V5h5zM6 3v1H3V3h3z"/></svg>',isToggleable:!0}),c.bind("isOn").to(r,"value",e=>!!e),c.on("execute",()=>{e.execute("codeBlock",{usePreviousLanguageChoice:!0}),e.editing.view.focus()}),i.on("execute",t=>{e.execute("codeBlock",{language:t.source._codeBlockLanguage,forceValue:!0}),e.editing.view.focus()}),i.class="ck-code-block-dropdown",i.bind("isEnabled").to(r),Object(v.addListToDropdown)(i,this._getLanguageListItemDefinitions(o)),i})}_getLanguageListItemDefinitions(e){const t=this.editor.commands.get("codeBlock"),n=new c.Collection;for(const o of e){const e={type:"button",model:new v.Model({_codeBlockLanguage:o.language,label:o.label,withText:!0})};e.model.bind("isOn").to(t,"value",t=>t===e.model._codeBlockLanguage),n.add(e)}return n}}class w extends o.Plugin{static get requires(){return[k,B]}static get pluginName(){return"CodeBlock"}}}]);
5
+ !function(e){const t=e.en=e.en||{};t.dictionary=Object.assign(t.dictionary||{},{"Insert code block":"Insert code block","Plain text":"Plain text"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={})),window.CKEditor5=window.CKEditor5||{},window.CKEditor5.codeBlock=function(e){var t={};function n(o){if(t[o])return t[o].exports;var i=t[o]={i:o,l:!1,exports:{}};return e[o].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},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 o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(o,i,function(t){return e[t]}.bind(null,i));return o},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=9)}([function(e,t,n){e.exports=n(2)("./src/core.js")},function(e,t,n){e.exports=n(2)("./src/utils.js")},function(e,t){e.exports=CKEditor5.dll},function(e,t,n){e.exports=n(2)("./src/ui.js")},function(e,t,n){e.exports=n(2)("./src/enter.js")},function(e,t,n){e.exports=n(2)("./src/engine.js")},function(e,t,n){var o=n(7),i=n(8);"string"==typeof(i=i.__esModule?i.default:i)&&(i=[[e.i,i,""]]);var r={injectType:"singletonStyleTag",attributes:{"data-cke":!0},insert:"head",singleton:!0};o(i,r);e.exports=i.locals||{}},function(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 m=null,p=0;function h(e,t){var n,o,i;if(t.singleton){var r=p++;n=m||(m=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}}}},function(e,t){e.exports=".ck-content pre{padding:1em;color:#353535;background:hsla(0,0%,78%,.3);border:1px solid #c4c4c4;border-radius:2px;text-align:left;direction:ltr;tab-size:4;white-space:pre-wrap;font-style:normal;min-width:200px}.ck-content pre code{background:unset;padding:0;border-radius: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{top:-1px;right:10px;background:var(--ck-color-code-block-label-background);font-size:10px;font-family:var(--ck-font-face);line-height:16px;padding:var(--ck-spacing-tiny) var(--ck-spacing-medium);color:#fff;white-space:nowrap}.ck.ck-code-block-dropdown .ck-dropdown__panel{max-height:250px;overflow-y:auto;overflow-x:hidden}"},function(e,t,n){"use strict";n.r(t),n.d(t,"CodeBlock",(function(){return C})),n.d(t,"CodeBlockEditing",(function(){return v})),n.d(t,"CodeBlockUI",(function(){return x}));var o=n(0),i=n(4),r=n(5),c=n(1);function a(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 s(e,t,n){const o={};for(const i of e)"class"===t?o[i[t].split(" ").shift()]=i[n]:o[i[t]]=i[n];return o}function l(e){return e.data.match(/^(\s*)/)[0]}function d(e){const t=e.document.selection,n=[];if(t.isCollapsed)n.push(t.anchor);else{const o=t.getFirstRange().getWalker({ignoreElementEnd:!0,direction:"backward"});for(const{item:t}of o)if(t.is("$textProxy")&&t.parent.is("element","codeBlock")){const o=l(t.textNode),{parent:i,startOffset:r}=t.textNode,c=e.createPositionAt(i,r+o.length);n.push(c)}}return n}function u(e){const t=Object(c.first)(e.getSelectedBlocks());return t&&t.is("element","codeBlock")}class g extends o.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=a(t)[0],r=Array.from(o.getSelectedBlocks()),c=void 0===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=>{c?this._applyCodeBlock(e,r,s):this._removeCodeBlock(e,r)})}_getValue(){const e=this.editor.model.document.selection,t=Object(c.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=Object(c.first)(e.getSelectedBlocks());return!!n&&f(t,n)}_applyCodeBlock(e,t,n){this._lastLanguage=n;const o=this.editor.model.schema,i=t.filter(e=>f(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));e.rename(n.nodeAfter,"paragraph"),e.removeAttribute("language",n.nodeAfter),e.remove(t)}e.rename(t,"paragraph"),e.removeAttribute("language",t)}}}function f(e,t){return!t.is("rootElement")&&!e.isLimit(t)&&e.checkChild(t.parent,"codeBlock")}class m extends o.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=d(e);for(const e of n)t.insertText(this._indentSequence,e)})}_checkEnabled(){return!!this._indentSequence&&u(this.editor.model.document.selection)}}class p extends o.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=d(e);for(const e of n){const n=h(this.editor.model,e,this._indentSequence);n&&t.remove(n)}})}_checkEnabled(){if(!this._indentSequence)return!1;const e=this.editor.model;return!!u(e.document.selection)&&d(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=l(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=s(t,"language","class"),i=s(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=a.createContainerElement("pre",g),m=a.createContainerElement("code",{class:o[d]||null});a.insert(a.createPositionAt(f,0),m),a.insert(u,f),s.bindElements(r.item,m)}}class v extends o.Plugin{static get pluginName(){return"CodeBlockEditing"}static get requires(){return[i.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,a(e));e.commands.add("codeBlock",new g(e)),e.commands.add("indentCodeBlock",new m(e)),e.commands.add("outdentCodeBlock",new p(e));const i=e=>(t,n)=>{this.editor.commands.get(e).isEnabled&&(this.editor.execute(e),n())};e.keystrokes.set("Tab",i("indentCodeBlock")),e.keystrokes.set("Shift+Tab",i("outdentCodeBlock")),t.register("codeBlock",{allowWhere:"$block",allowChildren:"$text",isBlock:!0,allowAttributes:["language"]}),t.addAttributeCheck(e=>{if(e.endsWith("codeBlock $text"))return!1}),e.model.schema.addChildCheck((e,t)=>{if(e.endsWith("codeBlock")&&t.isObject)return!1}),e.editing.downcastDispatcher.on("insert:codeBlock",b(n,o,!0)),e.data.downcastDispatcher.on("insert:codeBlock",b(n,o)),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=s(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,o)),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}),this.listenTo(e.editing.view.document,"clipboardInput",(t,o)=>{let i=n.createRange(n.document.selection.anchor);if(o.targetRanges&&(i=e.editing.mapper.toModelRange(o.targetRanges[0])),!i.start.parent.is("element","codeBlock"))return;const c=o.dataTransfer.getData("text/plain"),a=new r.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(r.childCount>1||o.containsEntireContent(i.parent)){const t=n.createElement("codeBlock",i.parent.getAttributes());n.append(r,t);const o=n.createDocumentFragment();n.append(t,o),e.return=o}else{const e=r.getChild(0);t.checkAttribute(e,"code")&&n.setAttribute("code",!0,e)}})})}afterInit(){const e=this.editor,t=e.commands,n=t.get("indent"),o=t.get("outdent");n&&n.registerChildCommand(t.get("indentCodeBlock")),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.document,o=e.editing.view,i=n.selection.getLastPosition(),r=i.nodeAfter;if(t||!n.selection.isCollapsed||!i.isAtStart)return!1;if(!B(r))return!1;return e.model.change(t=>{e.execute("enter");const o=n.selection.anchor.parent.previousSibling;t.rename(o,"paragraph"),t.setSelection(o,"in"),e.model.schema.removeDisallowedAttributes([o],t),t.remove(r)}),o.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(B(c)&&B(c.previousSibling))a=n.createRange(n.createPositionBefore(c.previousSibling),n.createPositionAfter(c));else if(k(c)&&B(c.previousSibling)&&B(c.previousSibling.previousSibling))a=n.createRange(n.createPositionBefore(c.previousSibling.previousSibling),n.createPositionAfter(c));else{if(!(k(c)&&B(c.previousSibling)&&k(c.previousSibling.previousSibling)&&B(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,"paragraph"),e.model.schema.removeDisallowedAttributes([n],t)}),i.scrollToTheSelection(),!0}(e,n.isSoft)||function(e){const t=e.model.document,n=t.selection.getLastPosition(),o=n.nodeBefore||n.textNode;let i;o&&o.is("$text")&&(i=l(o));e.model.change(n=>{e.execute("shiftEnter"),i&&n.insertText(i,t.selection.anchor)})}(e),n.preventDefault(),t.stop())},{context:"pre"})}}function k(e){return e&&e.is("$text")&&!e.data.match(/\S/)}function B(e){return e&&e.is("element","softBreak")}var w=n(3);n(6);class x extends o.Plugin{static get pluginName(){return"CodeBlockUI"}init(){const e=this.editor,t=e.t,n=e.ui.componentFactory,o=a(e);n.add("codeBlock",n=>{const i=e.commands.get("codeBlock"),r=Object(w.createDropdown)(n,w.SplitButtonView),c=r.buttonView;return c.set({label:t("Insert code block"),tooltip:!0,icon:'<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M12.87 12.61a.75.75 0 0 1-.089.976l-.085.07-3.154 2.254 3.412 2.414a.75.75 0 0 1 .237.95l-.057.095a.75.75 0 0 1-.95.237l-.096-.058-4.272-3.022-.003-1.223 4.01-2.867a.75.75 0 0 1 1.047.174zm2.795-.231.095.057 4.011 2.867-.003 1.223-4.272 3.022-.095.058a.75.75 0 0 1-.88-.151l-.07-.086-.058-.095a.75.75 0 0 1 .15-.88l.087-.07 3.412-2.414-3.154-2.253-.085-.071a.75.75 0 0 1 .862-1.207zM16 0a2 2 0 0 1 2 2v9.354l-.663-.492-.837-.001V2a.5.5 0 0 0-.5-.5H2a.5.5 0 0 0-.5.5v15a.5.5 0 0 0 .5.5h3.118L7.156 19H2a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h14zM5.009 15l.003 1H3v-1h2.009zm2.188-2-1.471 1H5v-1h2.197zM10 11v.095L8.668 12H7v-1h3zm4-2v1H7V9h7zm0-2v1H7V7h7zm-4-2v1H5V5h5zM6 3v1H3V3h3z"/></svg>',isToggleable:!0}),c.bind("isOn").to(i,"value",e=>!!e),c.on("execute",()=>{e.execute("codeBlock",{usePreviousLanguageChoice:!0}),e.editing.view.focus()}),r.on("execute",t=>{e.execute("codeBlock",{language:t.source._codeBlockLanguage,forceValue:!0}),e.editing.view.focus()}),r.class="ck-code-block-dropdown",r.bind("isEnabled").to(i),Object(w.addListToDropdown)(r,this._getLanguageListItemDefinitions(o)),r})}_getLanguageListItemDefinitions(e){const t=this.editor.commands.get("codeBlock"),n=new c.Collection;for(const o of e){const e={type:"button",model:new w.Model({_codeBlockLanguage:o.language,label:o.label,withText:!0})};e.model.bind("isOn").to(t,"value",t=>t===e.model._codeBlockLanguage),n.add(e)}return n}}class C extends o.Plugin{static get requires(){return[v,x]}static get pluginName(){return"CodeBlock"}}}]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ckeditor/ckeditor5-code-block",
3
- "version": "30.0.0",
3
+ "version": "31.0.0",
4
4
  "description": "Code block feature for CKEditor 5.",
5
5
  "keywords": [
6
6
  "ckeditor",
@@ -12,26 +12,26 @@
12
12
  ],
13
13
  "main": "src/index.js",
14
14
  "dependencies": {
15
- "ckeditor5": "^30.0.0"
15
+ "ckeditor5": "^31.0.0"
16
16
  },
17
17
  "devDependencies": {
18
- "@ckeditor/ckeditor5-alignment": "^30.0.0",
19
- "@ckeditor/ckeditor5-autoformat": "^30.0.0",
20
- "@ckeditor/ckeditor5-basic-styles": "^30.0.0",
21
- "@ckeditor/ckeditor5-block-quote": "^30.0.0",
22
- "@ckeditor/ckeditor5-clipboard": "^30.0.0",
23
- "@ckeditor/ckeditor5-core": "^30.0.0",
18
+ "@ckeditor/ckeditor5-alignment": "^31.0.0",
19
+ "@ckeditor/ckeditor5-autoformat": "^31.0.0",
20
+ "@ckeditor/ckeditor5-basic-styles": "^31.0.0",
21
+ "@ckeditor/ckeditor5-block-quote": "^31.0.0",
22
+ "@ckeditor/ckeditor5-clipboard": "^31.0.0",
23
+ "@ckeditor/ckeditor5-core": "^31.0.0",
24
24
  "@ckeditor/ckeditor5-dev-utils": "^25.4.0",
25
- "@ckeditor/ckeditor5-engine": "^30.0.0",
26
- "@ckeditor/ckeditor5-enter": "^30.0.0",
27
- "@ckeditor/ckeditor5-editor-classic": "^30.0.0",
28
- "@ckeditor/ckeditor5-image": "^30.0.0",
29
- "@ckeditor/ckeditor5-indent": "^30.0.0",
30
- "@ckeditor/ckeditor5-markdown-gfm": "^30.0.0",
31
- "@ckeditor/ckeditor5-paragraph": "^30.0.0",
32
- "@ckeditor/ckeditor5-theme-lark": "^30.0.0",
33
- "@ckeditor/ckeditor5-undo": "^30.0.0",
34
- "@ckeditor/ckeditor5-utils": "^30.0.0",
25
+ "@ckeditor/ckeditor5-engine": "^31.0.0",
26
+ "@ckeditor/ckeditor5-enter": "^31.0.0",
27
+ "@ckeditor/ckeditor5-editor-classic": "^31.0.0",
28
+ "@ckeditor/ckeditor5-image": "^31.0.0",
29
+ "@ckeditor/ckeditor5-indent": "^31.0.0",
30
+ "@ckeditor/ckeditor5-markdown-gfm": "^31.0.0",
31
+ "@ckeditor/ckeditor5-paragraph": "^31.0.0",
32
+ "@ckeditor/ckeditor5-theme-lark": "^31.0.0",
33
+ "@ckeditor/ckeditor5-undo": "^31.0.0",
34
+ "@ckeditor/ckeditor5-utils": "^31.0.0",
35
35
  "webpack": "^4.43.0",
36
36
  "webpack-cli": "^3.3.11"
37
37
  },
@@ -219,7 +219,7 @@ export default class CodeBlockEditing extends Plugin {
219
219
 
220
220
  // Customize the response to the <kbd>Enter</kbd> and <kbd>Shift</kbd>+<kbd>Enter</kbd>
221
221
  // key press when the selection is in the code block. Upon enter key press we can either
222
- // leave the block if it's "two enters" in a row or create a new code block line, preserving
222
+ // leave the block if it's "two or three enters" in a row or create a new code block line, preserving
223
223
  // previous line's indentation.
224
224
  this.listenTo( editor.editing.view.document, 'enter', ( evt, data ) => {
225
225
  const positionParent = editor.model.document.selection.getLastPosition().parent;
@@ -301,7 +301,7 @@ function leaveBlockStartOnEnter( editor, isSoftEnter ) {
301
301
  return false;
302
302
  }
303
303
 
304
- if ( !nodeAfter || !nodeAfter.is( 'element', 'softBreak' ) ) {
304
+ if ( !isSoftBreakNode( nodeAfter ) ) {
305
305
  return false;
306
306
  }
307
307
 
@@ -352,42 +352,61 @@ function leaveBlockEndOnEnter( editor, isSoftEnter ) {
352
352
 
353
353
  let emptyLineRangeToRemoveOnEnter;
354
354
 
355
- if ( isSoftEnter || !modelDoc.selection.isCollapsed || !lastSelectionPosition.isAtEnd || !nodeBefore ) {
355
+ if ( isSoftEnter || !modelDoc.selection.isCollapsed || !lastSelectionPosition.isAtEnd || !nodeBefore || !nodeBefore.previousSibling ) {
356
356
  return false;
357
357
  }
358
358
 
359
- // When the position is directly preceded by a soft break
359
+ // When the position is directly preceded by two soft breaks
360
360
  //
361
- // <codeBlock>foo<softBreak></softBreak>[]</codeBlock>
361
+ // <codeBlock>foo<softBreak></softBreak><softBreak></softBreak>[]</codeBlock>
362
362
  //
363
363
  // it creates the following range that will be cleaned up before leaving:
364
364
  //
365
- // <codeBlock>foo[<softBreak></softBreak>]</codeBlock>
365
+ // <codeBlock>foo[<softBreak></softBreak><softBreak></softBreak>]</codeBlock>
366
366
  //
367
- if ( nodeBefore.is( 'element', 'softBreak' ) ) {
368
- emptyLineRangeToRemoveOnEnter = model.createRangeOn( nodeBefore );
367
+ if ( isSoftBreakNode( nodeBefore ) && isSoftBreakNode( nodeBefore.previousSibling ) ) {
368
+ emptyLineRangeToRemoveOnEnter = model.createRange(
369
+ model.createPositionBefore( nodeBefore.previousSibling ), model.createPositionAfter( nodeBefore )
370
+ );
369
371
  }
370
372
 
371
- // When there's some text before the position made purely of white–space characters
373
+ // When there's some text before the position that is
374
+ // preceded by two soft breaks and made purely of white–space characters
375
+ //
376
+ // <codeBlock>foo<softBreak></softBreak><softBreak></softBreak> []</codeBlock>
372
377
  //
373
- // <codeBlock>foo<softBreak></softBreak> []</codeBlock>
378
+ // it creates the following range to clean up before leaving:
374
379
  //
375
- // but NOT when it's the first one of the kind
380
+ // <codeBlock>foo[<softBreak></softBreak><softBreak></softBreak> ]</codeBlock>
376
381
  //
377
- // <codeBlock> []</codeBlock>
382
+ else if (
383
+ isEmptyishTextNode( nodeBefore ) &&
384
+ isSoftBreakNode( nodeBefore.previousSibling ) &&
385
+ isSoftBreakNode( nodeBefore.previousSibling.previousSibling )
386
+ ) {
387
+ emptyLineRangeToRemoveOnEnter = model.createRange(
388
+ model.createPositionBefore( nodeBefore.previousSibling.previousSibling ), model.createPositionAfter( nodeBefore )
389
+ );
390
+ }
391
+
392
+ // When there's some text before the position that is made purely of white–space characters
393
+ // and is preceded by some other text made purely of white–space characters
394
+ //
395
+ // <codeBlock>foo<softBreak></softBreak> <softBreak></softBreak> []</codeBlock>
378
396
  //
379
397
  // it creates the following range to clean up before leaving:
380
398
  //
381
- // <codeBlock>foo[<softBreak></softBreak> ]</codeBlock>
399
+ // <codeBlock>foo[<softBreak></softBreak> <softBreak></softBreak> ]</codeBlock>
382
400
  //
383
401
  else if (
384
- nodeBefore.is( '$text' ) &&
385
- !nodeBefore.data.match( /\S/ ) &&
386
- nodeBefore.previousSibling &&
387
- nodeBefore.previousSibling.is( 'element', 'softBreak' )
402
+ isEmptyishTextNode( nodeBefore ) &&
403
+ isSoftBreakNode( nodeBefore.previousSibling ) &&
404
+ isEmptyishTextNode( nodeBefore.previousSibling.previousSibling ) &&
405
+ isSoftBreakNode( nodeBefore.previousSibling.previousSibling.previousSibling )
388
406
  ) {
389
407
  emptyLineRangeToRemoveOnEnter = model.createRange(
390
- model.createPositionBefore( nodeBefore.previousSibling ), model.createPositionAfter( nodeBefore )
408
+ model.createPositionBefore( nodeBefore.previousSibling.previousSibling.previousSibling ),
409
+ model.createPositionAfter( nodeBefore )
391
410
  );
392
411
  }
393
412
 
@@ -395,8 +414,9 @@ function leaveBlockEndOnEnter( editor, isSoftEnter ) {
395
414
  //
396
415
  // <codeBlock> []</codeBlock>
397
416
  // <codeBlock> a []</codeBlock>
398
- // <codeBlock>foo<softBreak></softBreak>bar[]</codeBlock>
399
- // <codeBlock>foo<softBreak></softBreak> a []</codeBlock>
417
+ // <codeBlock>foo<softBreak></softBreak>[]</codeBlock>
418
+ // <codeBlock>foo<softBreak></softBreak><softBreak></softBreak>bar[]</codeBlock>
419
+ // <codeBlock>foo<softBreak></softBreak><softBreak></softBreak> a []</codeBlock>
400
420
  //
401
421
  else {
402
422
  return false;
@@ -404,7 +424,7 @@ function leaveBlockEndOnEnter( editor, isSoftEnter ) {
404
424
 
405
425
  // We're doing everything in a single change block to have a single undo step.
406
426
  editor.model.change( writer => {
407
- // Remove the last <softBreak> and all white space characters that followed it.
427
+ // Remove the last <softBreak>s and all white space characters that followed them.
408
428
  writer.remove( emptyLineRangeToRemoveOnEnter );
409
429
 
410
430
  // "Clone" the <codeBlock> in the standard way.
@@ -422,3 +442,11 @@ function leaveBlockEndOnEnter( editor, isSoftEnter ) {
422
442
 
423
443
  return true;
424
444
  }
445
+
446
+ function isEmptyishTextNode( node ) {
447
+ return node && node.is( '$text' ) && !node.data.match( /\S/ );
448
+ }
449
+
450
+ function isSoftBreakNode( node ) {
451
+ return node && node.is( 'element', 'softBreak' );
452
+ }