@ckeditor/ckeditor5-heading 41.4.2 → 42.0.0-alpha.1
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 +6 -0
- package/build/heading.js +1 -1
- package/dist/index.js +196 -139
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/headingbuttonsui.js +2 -2
package/README.md
CHANGED
|
@@ -15,6 +15,12 @@ Check out the [demo in the heading feature guide](https://ckeditor.com/docs/cked
|
|
|
15
15
|
|
|
16
16
|
See the [`@ckeditor/ckeditor5-heading` package](https://ckeditor.com/docs/ckeditor5/latest/api/heading.html) page in [CKEditor 5 documentation](https://ckeditor.com/docs/ckeditor5/latest/).
|
|
17
17
|
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install ckeditor5
|
|
22
|
+
```
|
|
23
|
+
|
|
18
24
|
## License
|
|
19
25
|
|
|
20
26
|
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).
|
package/build/heading.js
CHANGED
|
@@ -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={707:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});var o=n(935),i=n.n(o)()((function(e){return e[1]}));i.push([e.id,".ck.ck-heading_heading1{font-size:20px}.ck.ck-heading_heading2{font-size:17px}.ck.ck-heading_heading3{font-size:14px}.ck[class*=ck-heading_heading]{font-weight:700}.ck.ck-dropdown.ck-heading-dropdown .ck-dropdown__button .ck-button__label{width:8em}.ck.ck-dropdown.ck-heading-dropdown .ck-dropdown__panel .ck-list__item{min-width:18em}",""]);const a=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 a=0;a<this.length;a++){var r=this[a][0];null!=r&&(i[r]=!0)}for(var s=0;s<e.length;s++){var d=[].concat(e[s]);o&&i[d[0]]||(n&&(d[2]?d[2]="".concat(n," and ").concat(d[2]):d[2]=n),t.push(d))}},t}},591:(e,t,n)=>{"use strict";var o,i=function(){return void 0===o&&(o=Boolean(window&&document&&document.all&&!window.atob)),o},a=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]}}(),r=[];function s(e){for(var t=-1,n=0;n<r.length;n++)if(r[n].identifier===e){t=n;break}return t}function d(e,t){for(var n={},o=[],i=0;i<e.length;i++){var a=e[i],d=t.base?a[0]+t.base:a[0],c=n[d]||0,l="".concat(d," ").concat(c);n[d]=c+1;var u=s(l),m={css:a[1],media:a[2],sourceMap:a[3]};-1!==u?(r[u].references++,r[u].updater(m)):r.push({identifier:l,updater:f(m,t),references:1}),o.push(l)}return o}function c(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 r=a(e.insert||"head");if(!r)throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");r.appendChild(t)}return t}var l,u=(l=[],function(e,t){return l[e]=t,l.filter(Boolean).join("\n")});function m(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 a=document.createTextNode(i),r=e.childNodes;r[t]&&e.removeChild(r[t]),r.length?e.insertBefore(a,r[t]):e.appendChild(a)}}function g(e,t,n){var o=n.css,i=n.media,a=n.sourceMap;if(i?e.setAttribute("media",i):e.removeAttribute("media"),a&&"undefined"!=typeof btoa&&(o+="\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(a))))," */")),e.styleSheet)e.styleSheet.cssText=o;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(o))}}var h=null,p=0;function f(e,t){var n,o,i;if(t.singleton){var a=p++;n=h||(h=c(t)),o=m.bind(null,n,a,!1),i=m.bind(null,n,a,!0)}else n=c(t),o=g.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=d(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=s(n[o]);r[i].references--}for(var a=d(e,t),c=0;c<n.length;c++){var l=s(n[c]);0===r[l].references&&(r[l].updater(),r.splice(l,1))}n=a}}}},782:(e,t,n)=>{e.exports=n(237)("./src/core.js")},783:(e,t,n)=>{e.exports=n(237)("./src/engine.js")},179:(e,t,n)=>{e.exports=n(237)("./src/paragraph.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 a=t[o]={id:o,exports:{}};return e[o](a,a.exports,n),a.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,{Heading:()=>f,HeadingButtonsUI:()=>w,HeadingEditing:()=>d,HeadingUI:()=>p,Title:()=>x});var e=n(782),t=n(179),i=n(584);class a extends e.Command{constructor(e,t){super(e),this.modelElements=t}refresh(){const e=(0,i.first)(this.editor.model.document.selection.getSelectedBlocks());this.value=!!e&&this.modelElements.includes(e.name)&&e.name,this.isEnabled=!!e&&this.modelElements.some((t=>r(e,t,this.editor.model.schema)))}execute(e){const t=this.editor.model,n=t.document,o=e.value;t.change((e=>{const i=Array.from(n.selection.getSelectedBlocks()).filter((e=>r(e,o,t.schema)));for(const t of i)t.is("element",o)||e.rename(t,o)}))}}function r(e,t,n){return n.checkChild(e.parent,t)&&!n.isObject(e)}const s="paragraph";class d extends e.Plugin{static get pluginName(){return"HeadingEditing"}constructor(e){super(e),e.config.define("heading",{options:[{model:"paragraph",title:"Paragraph",class:"ck-heading_paragraph"},{model:"heading1",view:"h2",title:"Heading 1",class:"ck-heading_heading1"},{model:"heading2",view:"h3",title:"Heading 2",class:"ck-heading_heading2"},{model:"heading3",view:"h4",title:"Heading 3",class:"ck-heading_heading3"}]})}static get requires(){return[t.Paragraph]}init(){const e=this.editor,t=e.config.get("heading.options"),n=[];for(const o of t)"paragraph"!==o.model&&(e.model.schema.register(o.model,{inheritAllFrom:"$block"}),e.conversion.elementToElement(o),n.push(o.model));this._addDefaultH1Conversion(e),e.commands.add("heading",new a(e,n))}afterInit(){const e=this.editor,t=e.commands.get("enter"),n=e.config.get("heading.options");t&&this.listenTo(t,"afterExecute",((t,o)=>{const i=e.model.document.selection.getFirstPosition().parent;n.some((e=>i.is("element",e.model)))&&!i.is("element",s)&&0===i.childCount&&o.writer.rename(i,s)}))}_addDefaultH1Conversion(e){e.conversion.for("upcast").elementToElement({model:"heading1",view:"h1",converterPriority:i.priorities.low+1})}}var c=n(311);function l(e){const t=e.t,n={Paragraph:t("Paragraph"),"Heading 1":t("Heading 1"),"Heading 2":t("Heading 2"),"Heading 3":t("Heading 3"),"Heading 4":t("Heading 4"),"Heading 5":t("Heading 5"),"Heading 6":t("Heading 6")};return e.config.get("heading.options").map((e=>{const t=n[e.title];return t&&t!=e.title&&(e.title=t),e}))}var u=n(591),m=n.n(u),g=n(707),h={injectType:"singletonStyleTag",attributes:{"data-cke":!0},insert:"head",singleton:!0};m()(g.A,h);g.A.locals;class p extends e.Plugin{static get pluginName(){return"HeadingUI"}init(){const e=this.editor,t=e.t,n=l(e),o=t("Choose heading"),a=t("Heading");e.ui.componentFactory.add("heading",(t=>{const r={},s=new i.Collection,d=e.commands.get("heading"),l=e.commands.get("paragraph"),u=[d];for(const e of n){const t={type:"button",model:new c.ViewModel({label:e.title,class:e.class,role:"menuitemradio",withText:!0})};"paragraph"===e.model?(t.model.bind("isOn").to(l,"value"),t.model.set("commandName","paragraph"),u.push(l)):(t.model.bind("isOn").to(d,"value",(t=>t===e.model)),t.model.set({commandName:"heading",commandValue:e.model})),s.add(t),r[e.model]=e.title}const m=(0,c.createDropdown)(t);return(0,c.addListToDropdown)(m,s,{ariaLabel:a,role:"menu"}),m.buttonView.set({ariaLabel:a,ariaLabelledBy:void 0,isOn:!1,withText:!0,tooltip:a}),m.extendTemplate({attributes:{class:["ck-heading-dropdown"]}}),m.bind("isEnabled").toMany(u,"isEnabled",((...e)=>e.some((e=>e)))),m.buttonView.bind("label").to(d,"value",l,"value",((e,t)=>{const n=t?"paragraph":e;return"boolean"==typeof n?o:r[n]?r[n]:o})),m.buttonView.bind("ariaLabel").to(d,"value",l,"value",((e,t)=>{const n=t?"paragraph":e;return"boolean"==typeof n?a:r[n]?`${r[n]}, ${a}`:a})),this.listenTo(m,"execute",(t=>{const{commandName:n,commandValue:o}=t.source;e.execute(n,o?{value:o}:void 0),e.editing.view.focus()})),m})),e.ui.componentFactory.add("menuBar:heading",(o=>{const i=new c.MenuBarMenuView(o),a=e.commands.get("heading"),r=e.commands.get("paragraph"),s=[a],d=new c.MenuBarMenuListView(o);i.set({class:"ck-heading-dropdown"}),d.set({ariaLabel:t("Heading"),role:"menu"}),i.buttonView.set({label:t("Heading")}),i.panelView.children.add(d);for(const t of n){const n=new c.MenuBarMenuListItemView(o,i),l=new c.MenuBarMenuListItemButtonView(o);n.children.add(l),d.items.add(n),l.set({label:t.title,role:"menuitemradio",class:t.class}),l.bind("ariaChecked").to(l,"isOn"),l.delegate("execute").to(i),l.on("execute",(()=>{const n="paragraph"===t.model?"paragraph":"heading";e.execute(n,{value:t.model}),e.editing.view.focus()})),"paragraph"===t.model?(l.bind("isOn").to(r,"value"),s.push(r)):l.bind("isOn").to(a,"value",(e=>e===t.model))}return i.bind("isEnabled").toMany(s,"isEnabled",((...e)=>e.some((e=>e)))),i}))}}class f extends e.Plugin{static get requires(){return[d,p]}static get pluginName(){return"Heading"}}const v={heading1:e.icons.heading1,heading2:e.icons.heading2,heading3:e.icons.heading3,heading4:e.icons.heading4,heading5:e.icons.heading5,heading6:e.icons.heading6};class w extends e.Plugin{init(){l(this.editor).filter((e=>"paragraph"!==e.model)).map((e=>this._createButton(e)))}_createButton(e){const t=this.editor;t.ui.componentFactory.add(e.model,(n=>{const o=new c.ButtonView(n),i=t.commands.get("heading");return o.label=e.title,o.icon=e.icon||v[e.model],o.tooltip=!0,o.isToggleable=!0,o.bind("isEnabled").to(i),o.bind("isOn").to(i,"value",(t=>t==e.model)),o.on("execute",(()=>{t.execute("heading",{value:e.model}),t.editing.view.focus()})),o}))}}var b=n(783);const y=new Set(["paragraph","heading1","heading2","heading3","heading4","heading5","heading6"]);class x extends e.Plugin{constructor(){super(...arguments),this._bodyPlaceholder=new Map}static get pluginName(){return"Title"}static get requires(){return["Paragraph"]}init(){const e=this.editor,t=e.model;t.schema.register("title",{isBlock:!0,allowIn:"$root"}),t.schema.register("title-content",{isBlock:!0,allowIn:"title",allowAttributes:["alignment"]}),t.schema.extend("$text",{allowIn:"title-content"}),t.schema.addAttributeCheck((e=>{if(e.endsWith("title-content $text"))return!1})),e.editing.mapper.on("modelToViewPosition",T(e.editing.view)),e.data.mapper.on("modelToViewPosition",T(e.editing.view)),e.conversion.for("downcast").elementToElement({model:"title-content",view:"h1"}),e.conversion.for("downcast").add((e=>e.on("insert:title",((e,t,n)=>{n.consumable.consume(t.item,e.name)})))),e.data.upcastDispatcher.on("element:h1",C,{priority:"high"}),e.data.upcastDispatcher.on("element:h2",C,{priority:"high"}),e.data.upcastDispatcher.on("element:h3",C,{priority:"high"}),t.document.registerPostFixer((e=>this._fixTitleContent(e))),t.document.registerPostFixer((e=>this._fixTitleElement(e))),t.document.registerPostFixer((e=>this._fixBodyElement(e))),t.document.registerPostFixer((e=>this._fixExtraParagraph(e))),this._attachPlaceholders(),this._attachTabPressHandling()}getTitle(e={}){const t=e.rootName?e.rootName:void 0,n=this._getTitleElement(t).getChild(0);return this.editor.data.stringify(n,e)}getBody(e={}){const t=this.editor,n=t.data,o=t.model,i=e.rootName?e.rootName:void 0,a=t.model.document.getRoot(i),r=t.editing.view,s=new b.DowncastWriter(r.document),d=o.createRangeIn(a),c=s.createDocumentFragment(),l=o.createPositionAfter(a.getChild(0)),u=o.createRange(l,o.createPositionAt(a,"end")),m=new Map;for(const e of o.markers){const t=u.getIntersection(e.getRange());t&&m.set(e.name,t)}return n.mapper.clearBindings(),n.mapper.bindElements(a,c),n.downcastDispatcher.convert(d,m,s,e),s.remove(s.createRangeOn(c.getChild(0))),t.data.processor.toData(c)}_getTitleElement(e){const t=this.editor.model.document.getRoot(e);for(const e of t.getChildren())if(P(e))return e}_fixTitleContent(e){let t=!1;for(const n of this.editor.model.document.getRootNames()){const o=this._getTitleElement(n);if(!o||1===o.maxOffset)continue;const i=Array.from(o.getChildren());i.shift();for(const t of i)e.move(e.createRangeOn(t),o,"after"),e.rename(t,"paragraph");t=!0}return t}_fixTitleElement(e){let t=!1;const n=this.editor.model;for(const o of this.editor.model.document.getRoots()){const i=Array.from(o.getChildren()).filter(P),a=i[0],r=o.getChild(0);if(r.is("element","title"))i.length>1&&(H(i,e,n),t=!0);else if(a||y.has(r.name))y.has(r.name)?E(r,e,n):e.move(e.createRangeOn(a),o,0),H(i,e,n),t=!0;else{const n=e.createElement("title");e.insert(n,o),e.insertElement("title-content",n),t=!0}}return t}_fixBodyElement(e){let t=!1;for(const n of this.editor.model.document.getRootNames()){const o=this.editor.model.document.getRoot(n);if(o.childCount<2){const i=e.createElement("paragraph");e.insert(i,o,1),this._bodyPlaceholder.set(n,i),t=!0}}return t}_fixExtraParagraph(e){let t=!1;for(const n of this.editor.model.document.getRootNames()){const o=this.editor.model.document.getRoot(n),i=this._bodyPlaceholder.get(n);k(i,o)&&(this._bodyPlaceholder.delete(n),e.remove(i),t=!0)}return t}_attachPlaceholders(){const e=this.editor,t=e.t,n=e.editing.view,o=e.sourceElement,i=e.config.get("title.placeholder")||t("Type your title"),a=e.config.get("placeholder")||o&&"textarea"===o.tagName.toLowerCase()&&o.getAttribute("placeholder")||t("Type or paste your content here.");e.editing.downcastDispatcher.on("insert:title-content",((e,t,o)=>{const a=o.mapper.toViewElement(t.item);a.placeholder=i,(0,b.enablePlaceholder)({view:n,element:a,keepOnFocus:!0})}));const r=new Map;n.document.registerPostFixer((e=>{let t=!1;for(const o of n.document.roots){if(o.isEmpty)continue;const n=o.getChild(1),i=r.get(o.rootName);n!==i&&(i&&((0,b.hidePlaceholder)(e,i),e.removeAttribute("data-placeholder",i)),e.setAttribute("data-placeholder",a,n),r.set(o.rootName,n),t=!0),t=(0,b.needsPlaceholder)(n,!0)&&2===o.childCount&&"p"===n.name?!!(0,b.showPlaceholder)(e,n)||t:!!(0,b.hidePlaceholder)(e,n)||t}return t}))}_attachTabPressHandling(){const e=this.editor,t=e.model;e.keystrokes.set("TAB",((e,n)=>{t.change((e=>{const o=t.document.selection,i=Array.from(o.getSelectedBlocks());if(1===i.length&&i[0].is("element","title-content")){const t=o.getFirstPosition().root.getChild(1);e.setSelection(t,0),n()}}))})),e.keystrokes.set("SHIFT + TAB",((n,o)=>{t.change((n=>{const a=t.document.selection;if(!a.isCollapsed)return;const r=(0,i.first)(a.getSelectedBlocks()),s=a.getFirstPosition(),d=e.model.document.getRoot(s.root.rootName),c=d.getChild(0);r===d.getChild(1)&&s.isAtStart&&(n.setSelection(c.getChild(0),0),o())}))}))}}function C(e,t,n){const o=t.modelCursor,i=t.viewItem;if(!o.isAtStart||!o.parent.is("element","$root"))return;if(!n.consumable.consume(i,{name:!0}))return;const a=n.writer,r=a.createElement("title"),s=a.createElement("title-content");a.append(s,r),a.insert(r,o),n.convertChildren(i,s),n.updateConversionResult(r,t)}function T(e){return(t,n)=>{const o=n.modelPosition.parent;if(!o.is("element","title"))return;const i=o.parent,a=n.mapper.toViewElement(i);n.viewPosition=e.createPositionAt(a,0),t.stop()}}function P(e){return e.is("element","title")}function E(e,t,n){const o=t.createElement("title");t.insert(o,e,"before"),t.insert(e,o,0),t.rename(e,"title-content"),n.schema.removeDisallowedAttributes([e],t)}function H(e,t,n){let o=!1;for(const i of e)0!==i.index&&(_(i,t,n),o=!0);return o}function _(e,t,n){const o=e.getChild(0);o.isEmpty?t.remove(e):(t.move(t.createRangeOn(o),e,"before"),t.rename(o,"paragraph"),t.remove(e),n.schema.removeDisallowedAttributes([o],t))}function k(e,t){return!(!e||!e.is("element","paragraph")||e.childCount)&&!(t.childCount<=2||t.getChild(t.childCount-1)!==e)}})(),(window.CKEditor5=window.CKEditor5||{}).heading=o})();
|
|
5
|
+
*/(()=>{var e={707:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});var o=n(935),i=n.n(o)()((function(e){return e[1]}));i.push([e.id,".ck.ck-heading_heading1{font-size:20px}.ck.ck-heading_heading2{font-size:17px}.ck.ck-heading_heading3{font-size:14px}.ck[class*=ck-heading_heading]{font-weight:700}.ck.ck-dropdown.ck-heading-dropdown .ck-dropdown__button .ck-button__label{width:8em}.ck.ck-dropdown.ck-heading-dropdown .ck-dropdown__panel .ck-list__item{min-width:18em}",""]);const a=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 a=0;a<this.length;a++){var r=this[a][0];null!=r&&(i[r]=!0)}for(var s=0;s<e.length;s++){var d=[].concat(e[s]);o&&i[d[0]]||(n&&(d[2]?d[2]="".concat(n," and ").concat(d[2]):d[2]=n),t.push(d))}},t}},591:(e,t,n)=>{"use strict";var o,i=function(){return void 0===o&&(o=Boolean(window&&document&&document.all&&!window.atob)),o},a=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]}}(),r=[];function s(e){for(var t=-1,n=0;n<r.length;n++)if(r[n].identifier===e){t=n;break}return t}function d(e,t){for(var n={},o=[],i=0;i<e.length;i++){var a=e[i],d=t.base?a[0]+t.base:a[0],c=n[d]||0,l="".concat(d," ").concat(c);n[d]=c+1;var u=s(l),m={css:a[1],media:a[2],sourceMap:a[3]};-1!==u?(r[u].references++,r[u].updater(m)):r.push({identifier:l,updater:f(m,t),references:1}),o.push(l)}return o}function c(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 r=a(e.insert||"head");if(!r)throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");r.appendChild(t)}return t}var l,u=(l=[],function(e,t){return l[e]=t,l.filter(Boolean).join("\n")});function m(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 a=document.createTextNode(i),r=e.childNodes;r[t]&&e.removeChild(r[t]),r.length?e.insertBefore(a,r[t]):e.appendChild(a)}}function g(e,t,n){var o=n.css,i=n.media,a=n.sourceMap;if(i?e.setAttribute("media",i):e.removeAttribute("media"),a&&"undefined"!=typeof btoa&&(o+="\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(a))))," */")),e.styleSheet)e.styleSheet.cssText=o;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(o))}}var h=null,p=0;function f(e,t){var n,o,i;if(t.singleton){var a=p++;n=h||(h=c(t)),o=m.bind(null,n,a,!1),i=m.bind(null,n,a,!0)}else n=c(t),o=g.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=d(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=s(n[o]);r[i].references--}for(var a=d(e,t),c=0;c<n.length;c++){var l=s(n[c]);0===r[l].references&&(r[l].updater(),r.splice(l,1))}n=a}}}},782:(e,t,n)=>{e.exports=n(237)("./src/core.js")},783:(e,t,n)=>{e.exports=n(237)("./src/engine.js")},179:(e,t,n)=>{e.exports=n(237)("./src/paragraph.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 a=t[o]={id:o,exports:{}};return e[o](a,a.exports,n),a.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,{Heading:()=>f,HeadingButtonsUI:()=>w,HeadingEditing:()=>d,HeadingUI:()=>p,Title:()=>x});var e=n(782),t=n(179),i=n(584);class a extends e.Command{constructor(e,t){super(e),this.modelElements=t}refresh(){const e=(0,i.first)(this.editor.model.document.selection.getSelectedBlocks());this.value=!!e&&this.modelElements.includes(e.name)&&e.name,this.isEnabled=!!e&&this.modelElements.some((t=>r(e,t,this.editor.model.schema)))}execute(e){const t=this.editor.model,n=t.document,o=e.value;t.change((e=>{const i=Array.from(n.selection.getSelectedBlocks()).filter((e=>r(e,o,t.schema)));for(const t of i)t.is("element",o)||e.rename(t,o)}))}}function r(e,t,n){return n.checkChild(e.parent,t)&&!n.isObject(e)}const s="paragraph";class d extends e.Plugin{static get pluginName(){return"HeadingEditing"}constructor(e){super(e),e.config.define("heading",{options:[{model:"paragraph",title:"Paragraph",class:"ck-heading_paragraph"},{model:"heading1",view:"h2",title:"Heading 1",class:"ck-heading_heading1"},{model:"heading2",view:"h3",title:"Heading 2",class:"ck-heading_heading2"},{model:"heading3",view:"h4",title:"Heading 3",class:"ck-heading_heading3"}]})}static get requires(){return[t.Paragraph]}init(){const e=this.editor,t=e.config.get("heading.options"),n=[];for(const o of t)"paragraph"!==o.model&&(e.model.schema.register(o.model,{inheritAllFrom:"$block"}),e.conversion.elementToElement(o),n.push(o.model));this._addDefaultH1Conversion(e),e.commands.add("heading",new a(e,n))}afterInit(){const e=this.editor,t=e.commands.get("enter"),n=e.config.get("heading.options");t&&this.listenTo(t,"afterExecute",((t,o)=>{const i=e.model.document.selection.getFirstPosition().parent;n.some((e=>i.is("element",e.model)))&&!i.is("element",s)&&0===i.childCount&&o.writer.rename(i,s)}))}_addDefaultH1Conversion(e){e.conversion.for("upcast").elementToElement({model:"heading1",view:"h1",converterPriority:i.priorities.low+1})}}var c=n(311);function l(e){const t=e.t,n={Paragraph:t("Paragraph"),"Heading 1":t("Heading 1"),"Heading 2":t("Heading 2"),"Heading 3":t("Heading 3"),"Heading 4":t("Heading 4"),"Heading 5":t("Heading 5"),"Heading 6":t("Heading 6")};return e.config.get("heading.options").map((e=>{const t=n[e.title];return t&&t!=e.title&&(e.title=t),e}))}var u=n(591),m=n.n(u),g=n(707),h={injectType:"singletonStyleTag",attributes:{"data-cke":!0},insert:"head",singleton:!0};m()(g.A,h);g.A.locals;class p extends e.Plugin{static get pluginName(){return"HeadingUI"}init(){const e=this.editor,t=e.t,n=l(e),o=t("Choose heading"),a=t("Heading");e.ui.componentFactory.add("heading",(t=>{const r={},s=new i.Collection,d=e.commands.get("heading"),l=e.commands.get("paragraph"),u=[d];for(const e of n){const t={type:"button",model:new c.ViewModel({label:e.title,class:e.class,role:"menuitemradio",withText:!0})};"paragraph"===e.model?(t.model.bind("isOn").to(l,"value"),t.model.set("commandName","paragraph"),u.push(l)):(t.model.bind("isOn").to(d,"value",(t=>t===e.model)),t.model.set({commandName:"heading",commandValue:e.model})),s.add(t),r[e.model]=e.title}const m=(0,c.createDropdown)(t);return(0,c.addListToDropdown)(m,s,{ariaLabel:a,role:"menu"}),m.buttonView.set({ariaLabel:a,ariaLabelledBy:void 0,isOn:!1,withText:!0,tooltip:a}),m.extendTemplate({attributes:{class:["ck-heading-dropdown"]}}),m.bind("isEnabled").toMany(u,"isEnabled",((...e)=>e.some((e=>e)))),m.buttonView.bind("label").to(d,"value",l,"value",((e,t)=>{const n=t?"paragraph":e;return"boolean"==typeof n?o:r[n]?r[n]:o})),m.buttonView.bind("ariaLabel").to(d,"value",l,"value",((e,t)=>{const n=t?"paragraph":e;return"boolean"==typeof n?a:r[n]?`${r[n]}, ${a}`:a})),this.listenTo(m,"execute",(t=>{const{commandName:n,commandValue:o}=t.source;e.execute(n,o?{value:o}:void 0),e.editing.view.focus()})),m})),e.ui.componentFactory.add("menuBar:heading",(o=>{const i=new c.MenuBarMenuView(o),a=e.commands.get("heading"),r=e.commands.get("paragraph"),s=[a],d=new c.MenuBarMenuListView(o);i.set({class:"ck-heading-dropdown"}),d.set({ariaLabel:t("Heading"),role:"menu"}),i.buttonView.set({label:t("Heading")}),i.panelView.children.add(d);for(const t of n){const n=new c.MenuBarMenuListItemView(o,i),l=new c.MenuBarMenuListItemButtonView(o);n.children.add(l),d.items.add(n),l.set({label:t.title,role:"menuitemradio",class:t.class}),l.bind("ariaChecked").to(l,"isOn"),l.delegate("execute").to(i),l.on("execute",(()=>{const n="paragraph"===t.model?"paragraph":"heading";e.execute(n,{value:t.model}),e.editing.view.focus()})),"paragraph"===t.model?(l.bind("isOn").to(r,"value"),s.push(r)):l.bind("isOn").to(a,"value",(e=>e===t.model))}return i.bind("isEnabled").toMany(s,"isEnabled",((...e)=>e.some((e=>e)))),i}))}}class f extends e.Plugin{static get requires(){return[d,p]}static get pluginName(){return"Heading"}}const v=(()=>({heading1:e.icons.heading1,heading2:e.icons.heading2,heading3:e.icons.heading3,heading4:e.icons.heading4,heading5:e.icons.heading5,heading6:e.icons.heading6}))();class w extends e.Plugin{init(){l(this.editor).filter((e=>"paragraph"!==e.model)).map((e=>this._createButton(e)))}_createButton(e){const t=this.editor;t.ui.componentFactory.add(e.model,(n=>{const o=new c.ButtonView(n),i=t.commands.get("heading");return o.label=e.title,o.icon=e.icon||v[e.model],o.tooltip=!0,o.isToggleable=!0,o.bind("isEnabled").to(i),o.bind("isOn").to(i,"value",(t=>t==e.model)),o.on("execute",(()=>{t.execute("heading",{value:e.model}),t.editing.view.focus()})),o}))}}var b=n(783);const y=new Set(["paragraph","heading1","heading2","heading3","heading4","heading5","heading6"]);class x extends e.Plugin{constructor(){super(...arguments),this._bodyPlaceholder=new Map}static get pluginName(){return"Title"}static get requires(){return["Paragraph"]}init(){const e=this.editor,t=e.model;t.schema.register("title",{isBlock:!0,allowIn:"$root"}),t.schema.register("title-content",{isBlock:!0,allowIn:"title",allowAttributes:["alignment"]}),t.schema.extend("$text",{allowIn:"title-content"}),t.schema.addAttributeCheck((e=>{if(e.endsWith("title-content $text"))return!1})),e.editing.mapper.on("modelToViewPosition",T(e.editing.view)),e.data.mapper.on("modelToViewPosition",T(e.editing.view)),e.conversion.for("downcast").elementToElement({model:"title-content",view:"h1"}),e.conversion.for("downcast").add((e=>e.on("insert:title",((e,t,n)=>{n.consumable.consume(t.item,e.name)})))),e.data.upcastDispatcher.on("element:h1",C,{priority:"high"}),e.data.upcastDispatcher.on("element:h2",C,{priority:"high"}),e.data.upcastDispatcher.on("element:h3",C,{priority:"high"}),t.document.registerPostFixer((e=>this._fixTitleContent(e))),t.document.registerPostFixer((e=>this._fixTitleElement(e))),t.document.registerPostFixer((e=>this._fixBodyElement(e))),t.document.registerPostFixer((e=>this._fixExtraParagraph(e))),this._attachPlaceholders(),this._attachTabPressHandling()}getTitle(e={}){const t=e.rootName?e.rootName:void 0,n=this._getTitleElement(t).getChild(0);return this.editor.data.stringify(n,e)}getBody(e={}){const t=this.editor,n=t.data,o=t.model,i=e.rootName?e.rootName:void 0,a=t.model.document.getRoot(i),r=t.editing.view,s=new b.DowncastWriter(r.document),d=o.createRangeIn(a),c=s.createDocumentFragment(),l=o.createPositionAfter(a.getChild(0)),u=o.createRange(l,o.createPositionAt(a,"end")),m=new Map;for(const e of o.markers){const t=u.getIntersection(e.getRange());t&&m.set(e.name,t)}return n.mapper.clearBindings(),n.mapper.bindElements(a,c),n.downcastDispatcher.convert(d,m,s,e),s.remove(s.createRangeOn(c.getChild(0))),t.data.processor.toData(c)}_getTitleElement(e){const t=this.editor.model.document.getRoot(e);for(const e of t.getChildren())if(P(e))return e}_fixTitleContent(e){let t=!1;for(const n of this.editor.model.document.getRootNames()){const o=this._getTitleElement(n);if(!o||1===o.maxOffset)continue;const i=Array.from(o.getChildren());i.shift();for(const t of i)e.move(e.createRangeOn(t),o,"after"),e.rename(t,"paragraph");t=!0}return t}_fixTitleElement(e){let t=!1;const n=this.editor.model;for(const o of this.editor.model.document.getRoots()){const i=Array.from(o.getChildren()).filter(P),a=i[0],r=o.getChild(0);if(r.is("element","title"))i.length>1&&(H(i,e,n),t=!0);else if(a||y.has(r.name))y.has(r.name)?E(r,e,n):e.move(e.createRangeOn(a),o,0),H(i,e,n),t=!0;else{const n=e.createElement("title");e.insert(n,o),e.insertElement("title-content",n),t=!0}}return t}_fixBodyElement(e){let t=!1;for(const n of this.editor.model.document.getRootNames()){const o=this.editor.model.document.getRoot(n);if(o.childCount<2){const i=e.createElement("paragraph");e.insert(i,o,1),this._bodyPlaceholder.set(n,i),t=!0}}return t}_fixExtraParagraph(e){let t=!1;for(const n of this.editor.model.document.getRootNames()){const o=this.editor.model.document.getRoot(n),i=this._bodyPlaceholder.get(n);k(i,o)&&(this._bodyPlaceholder.delete(n),e.remove(i),t=!0)}return t}_attachPlaceholders(){const e=this.editor,t=e.t,n=e.editing.view,o=e.sourceElement,i=e.config.get("title.placeholder")||t("Type your title"),a=e.config.get("placeholder")||o&&"textarea"===o.tagName.toLowerCase()&&o.getAttribute("placeholder")||t("Type or paste your content here.");e.editing.downcastDispatcher.on("insert:title-content",((e,t,o)=>{const a=o.mapper.toViewElement(t.item);a.placeholder=i,(0,b.enablePlaceholder)({view:n,element:a,keepOnFocus:!0})}));const r=new Map;n.document.registerPostFixer((e=>{let t=!1;for(const o of n.document.roots){if(o.isEmpty)continue;const n=o.getChild(1),i=r.get(o.rootName);n!==i&&(i&&((0,b.hidePlaceholder)(e,i),e.removeAttribute("data-placeholder",i)),e.setAttribute("data-placeholder",a,n),r.set(o.rootName,n),t=!0),t=(0,b.needsPlaceholder)(n,!0)&&2===o.childCount&&"p"===n.name?!!(0,b.showPlaceholder)(e,n)||t:!!(0,b.hidePlaceholder)(e,n)||t}return t}))}_attachTabPressHandling(){const e=this.editor,t=e.model;e.keystrokes.set("TAB",((e,n)=>{t.change((e=>{const o=t.document.selection,i=Array.from(o.getSelectedBlocks());if(1===i.length&&i[0].is("element","title-content")){const t=o.getFirstPosition().root.getChild(1);e.setSelection(t,0),n()}}))})),e.keystrokes.set("SHIFT + TAB",((n,o)=>{t.change((n=>{const a=t.document.selection;if(!a.isCollapsed)return;const r=(0,i.first)(a.getSelectedBlocks()),s=a.getFirstPosition(),d=e.model.document.getRoot(s.root.rootName),c=d.getChild(0);r===d.getChild(1)&&s.isAtStart&&(n.setSelection(c.getChild(0),0),o())}))}))}}function C(e,t,n){const o=t.modelCursor,i=t.viewItem;if(!o.isAtStart||!o.parent.is("element","$root"))return;if(!n.consumable.consume(i,{name:!0}))return;const a=n.writer,r=a.createElement("title"),s=a.createElement("title-content");a.append(s,r),a.insert(r,o),n.convertChildren(i,s),n.updateConversionResult(r,t)}function T(e){return(t,n)=>{const o=n.modelPosition.parent;if(!o.is("element","title"))return;const i=o.parent,a=n.mapper.toViewElement(i);n.viewPosition=e.createPositionAt(a,0),t.stop()}}function P(e){return e.is("element","title")}function E(e,t,n){const o=t.createElement("title");t.insert(o,e,"before"),t.insert(e,o,0),t.rename(e,"title-content"),n.schema.removeDisallowedAttributes([e],t)}function H(e,t,n){let o=!1;for(const i of e)0!==i.index&&(_(i,t,n),o=!0);return o}function _(e,t,n){const o=e.getChild(0);o.isEmpty?t.remove(e):(t.move(t.createRangeOn(o),e,"before"),t.rename(o,"paragraph"),t.remove(e),n.schema.removeDisallowedAttributes([o],t))}function k(e,t){return!(!e||!e.is("element","paragraph")||e.childCount)&&!(t.childCount<=2||t.getChild(t.childCount-1)!==e)}})(),(window.CKEditor5=window.CKEditor5||{}).heading=o})();
|
package/dist/index.js
CHANGED
|
@@ -8,21 +8,36 @@ import { first, priorities, Collection } from '@ckeditor/ckeditor5-utils/dist/in
|
|
|
8
8
|
import { ViewModel, createDropdown, addListToDropdown, MenuBarMenuView, MenuBarMenuListView, MenuBarMenuListItemView, MenuBarMenuListItemButtonView, ButtonView } from '@ckeditor/ckeditor5-ui/dist/index.js';
|
|
9
9
|
import { DowncastWriter, enablePlaceholder, hidePlaceholder, needsPlaceholder, showPlaceholder } from '@ckeditor/ckeditor5-engine/dist/index.js';
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
|
+
* The heading command. It is used by the {@link module:heading/heading~Heading heading feature} to apply headings.
|
|
13
|
+
*/ class HeadingCommand extends Command {
|
|
14
|
+
/**
|
|
15
|
+
* Set of defined model's elements names that this command support.
|
|
16
|
+
* See {@link module:heading/headingconfig~HeadingOption}.
|
|
17
|
+
*/ modelElements;
|
|
18
|
+
/**
|
|
19
|
+
* Creates an instance of the command.
|
|
20
|
+
*
|
|
21
|
+
* @param editor Editor instance.
|
|
22
|
+
* @param modelElements Names of the element which this command can apply in the model.
|
|
23
|
+
*/ constructor(editor, modelElements){
|
|
24
|
+
super(editor);
|
|
25
|
+
this.modelElements = modelElements;
|
|
26
|
+
}
|
|
12
27
|
/**
|
|
13
|
-
|
|
14
|
-
|
|
28
|
+
* @inheritDoc
|
|
29
|
+
*/ refresh() {
|
|
15
30
|
const block = first(this.editor.model.document.selection.getSelectedBlocks());
|
|
16
31
|
this.value = !!block && this.modelElements.includes(block.name) && block.name;
|
|
17
32
|
this.isEnabled = !!block && this.modelElements.some((heading)=>checkCanBecomeHeading(block, heading, this.editor.model.schema));
|
|
18
33
|
}
|
|
19
34
|
/**
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
35
|
+
* Executes the command. Applies the heading to the selected blocks or, if the first selected
|
|
36
|
+
* block is a heading already, turns selected headings (of this level only) to paragraphs.
|
|
37
|
+
*
|
|
38
|
+
* @param options.value Name of the element which this command will apply in the model.
|
|
39
|
+
* @fires execute
|
|
40
|
+
*/ execute(options) {
|
|
26
41
|
const model = this.editor.model;
|
|
27
42
|
const document = model.document;
|
|
28
43
|
const modelElement = options.value;
|
|
@@ -37,15 +52,6 @@ class HeadingCommand extends Command {
|
|
|
37
52
|
}
|
|
38
53
|
});
|
|
39
54
|
}
|
|
40
|
-
/**
|
|
41
|
-
* Creates an instance of the command.
|
|
42
|
-
*
|
|
43
|
-
* @param editor Editor instance.
|
|
44
|
-
* @param modelElements Names of the element which this command can apply in the model.
|
|
45
|
-
*/ constructor(editor, modelElements){
|
|
46
|
-
super(editor);
|
|
47
|
-
this.modelElements = modelElements;
|
|
48
|
-
}
|
|
49
55
|
}
|
|
50
56
|
/**
|
|
51
57
|
* Checks whether the given block can be replaced by a specific heading.
|
|
@@ -58,22 +64,58 @@ class HeadingCommand extends Command {
|
|
|
58
64
|
}
|
|
59
65
|
|
|
60
66
|
const defaultModelElement = 'paragraph';
|
|
61
|
-
|
|
67
|
+
/**
|
|
68
|
+
* The headings engine feature. It handles switching between block formats – headings and paragraph.
|
|
69
|
+
* This class represents the engine part of the heading feature. See also {@link module:heading/heading~Heading}.
|
|
70
|
+
* It introduces `heading1`-`headingN` commands which allow to convert paragraphs into headings.
|
|
71
|
+
*/ class HeadingEditing extends Plugin {
|
|
62
72
|
/**
|
|
63
|
-
|
|
64
|
-
|
|
73
|
+
* @inheritDoc
|
|
74
|
+
*/ static get pluginName() {
|
|
65
75
|
return 'HeadingEditing';
|
|
66
76
|
}
|
|
67
77
|
/**
|
|
68
|
-
|
|
69
|
-
|
|
78
|
+
* @inheritDoc
|
|
79
|
+
*/ constructor(editor){
|
|
80
|
+
super(editor);
|
|
81
|
+
editor.config.define('heading', {
|
|
82
|
+
options: [
|
|
83
|
+
{
|
|
84
|
+
model: 'paragraph',
|
|
85
|
+
title: 'Paragraph',
|
|
86
|
+
class: 'ck-heading_paragraph'
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
model: 'heading1',
|
|
90
|
+
view: 'h2',
|
|
91
|
+
title: 'Heading 1',
|
|
92
|
+
class: 'ck-heading_heading1'
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
model: 'heading2',
|
|
96
|
+
view: 'h3',
|
|
97
|
+
title: 'Heading 2',
|
|
98
|
+
class: 'ck-heading_heading2'
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
model: 'heading3',
|
|
102
|
+
view: 'h4',
|
|
103
|
+
title: 'Heading 3',
|
|
104
|
+
class: 'ck-heading_heading3'
|
|
105
|
+
}
|
|
106
|
+
]
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* @inheritDoc
|
|
111
|
+
*/ static get requires() {
|
|
70
112
|
return [
|
|
71
113
|
Paragraph
|
|
72
114
|
];
|
|
73
115
|
}
|
|
74
116
|
/**
|
|
75
|
-
|
|
76
|
-
|
|
117
|
+
* @inheritDoc
|
|
118
|
+
*/ init() {
|
|
77
119
|
const editor = this.editor;
|
|
78
120
|
const options = editor.config.get('heading.options');
|
|
79
121
|
const modelElements = [];
|
|
@@ -94,8 +136,8 @@ class HeadingEditing extends Plugin {
|
|
|
94
136
|
editor.commands.add('heading', new HeadingCommand(editor, modelElements));
|
|
95
137
|
}
|
|
96
138
|
/**
|
|
97
|
-
|
|
98
|
-
|
|
139
|
+
* @inheritDoc
|
|
140
|
+
*/ afterInit() {
|
|
99
141
|
// If the enter command is added to the editor, alter its behavior.
|
|
100
142
|
// Enter at the end of a heading element should create a paragraph.
|
|
101
143
|
const editor = this.editor;
|
|
@@ -112,10 +154,10 @@ class HeadingEditing extends Plugin {
|
|
|
112
154
|
}
|
|
113
155
|
}
|
|
114
156
|
/**
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
157
|
+
* Adds default conversion for `h1` -> `heading1` with a low priority.
|
|
158
|
+
*
|
|
159
|
+
* @param editor Editor instance on which to add the `h1` conversion.
|
|
160
|
+
*/ _addDefaultH1Conversion(editor) {
|
|
119
161
|
editor.conversion.for('upcast').elementToElement({
|
|
120
162
|
model: 'heading1',
|
|
121
163
|
view: 'h1',
|
|
@@ -124,44 +166,14 @@ class HeadingEditing extends Plugin {
|
|
|
124
166
|
converterPriority: priorities.low + 1
|
|
125
167
|
});
|
|
126
168
|
}
|
|
127
|
-
/**
|
|
128
|
-
* @inheritDoc
|
|
129
|
-
*/ constructor(editor){
|
|
130
|
-
super(editor);
|
|
131
|
-
editor.config.define('heading', {
|
|
132
|
-
options: [
|
|
133
|
-
{
|
|
134
|
-
model: 'paragraph',
|
|
135
|
-
title: 'Paragraph',
|
|
136
|
-
class: 'ck-heading_paragraph'
|
|
137
|
-
},
|
|
138
|
-
{
|
|
139
|
-
model: 'heading1',
|
|
140
|
-
view: 'h2',
|
|
141
|
-
title: 'Heading 1',
|
|
142
|
-
class: 'ck-heading_heading1'
|
|
143
|
-
},
|
|
144
|
-
{
|
|
145
|
-
model: 'heading2',
|
|
146
|
-
view: 'h3',
|
|
147
|
-
title: 'Heading 2',
|
|
148
|
-
class: 'ck-heading_heading2'
|
|
149
|
-
},
|
|
150
|
-
{
|
|
151
|
-
model: 'heading3',
|
|
152
|
-
view: 'h4',
|
|
153
|
-
title: 'Heading 3',
|
|
154
|
-
class: 'ck-heading_heading3'
|
|
155
|
-
}
|
|
156
|
-
]
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
169
|
}
|
|
160
170
|
|
|
161
171
|
/**
|
|
162
172
|
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
163
173
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
164
174
|
*/ /**
|
|
175
|
+
* @module heading/utils
|
|
176
|
+
*/ /**
|
|
165
177
|
* Returns heading options as defined in `config.heading.options` but processed to consider
|
|
166
178
|
* the editor localization, i.e. to display {@link module:heading/headingconfig~HeadingOption}
|
|
167
179
|
* in the correct language.
|
|
@@ -188,15 +200,17 @@ class HeadingEditing extends Plugin {
|
|
|
188
200
|
});
|
|
189
201
|
}
|
|
190
202
|
|
|
191
|
-
|
|
203
|
+
/**
|
|
204
|
+
* The headings UI feature. It introduces the `headings` dropdown.
|
|
205
|
+
*/ class HeadingUI extends Plugin {
|
|
192
206
|
/**
|
|
193
|
-
|
|
194
|
-
|
|
207
|
+
* @inheritDoc
|
|
208
|
+
*/ static get pluginName() {
|
|
195
209
|
return 'HeadingUI';
|
|
196
210
|
}
|
|
197
211
|
/**
|
|
198
|
-
|
|
199
|
-
|
|
212
|
+
* @inheritDoc
|
|
213
|
+
*/ init() {
|
|
200
214
|
const editor = this.editor;
|
|
201
215
|
const t = editor.t;
|
|
202
216
|
const options = getLocalizedOptions(editor);
|
|
@@ -343,40 +357,82 @@ class HeadingUI extends Plugin {
|
|
|
343
357
|
}
|
|
344
358
|
}
|
|
345
359
|
|
|
346
|
-
|
|
360
|
+
/**
|
|
361
|
+
* The headings feature.
|
|
362
|
+
*
|
|
363
|
+
* For a detailed overview, check the {@glink features/headings Headings feature} guide
|
|
364
|
+
* and the {@glink api/heading package page}.
|
|
365
|
+
*
|
|
366
|
+
* This is a "glue" plugin which loads the {@link module:heading/headingediting~HeadingEditing heading editing feature}
|
|
367
|
+
* and {@link module:heading/headingui~HeadingUI heading UI feature}.
|
|
368
|
+
*
|
|
369
|
+
* @extends module:core/plugin~Plugin
|
|
370
|
+
*/ class Heading extends Plugin {
|
|
347
371
|
/**
|
|
348
|
-
|
|
349
|
-
|
|
372
|
+
* @inheritDoc
|
|
373
|
+
*/ static get requires() {
|
|
350
374
|
return [
|
|
351
375
|
HeadingEditing,
|
|
352
376
|
HeadingUI
|
|
353
377
|
];
|
|
354
378
|
}
|
|
355
379
|
/**
|
|
356
|
-
|
|
357
|
-
|
|
380
|
+
* @inheritDoc
|
|
381
|
+
*/ static get pluginName() {
|
|
358
382
|
return 'Heading';
|
|
359
383
|
}
|
|
360
384
|
}
|
|
361
385
|
|
|
362
|
-
const defaultIcons = {
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
};
|
|
370
|
-
|
|
386
|
+
const defaultIcons = /* #__PURE__ */ (()=>({
|
|
387
|
+
heading1: icons.heading1,
|
|
388
|
+
heading2: icons.heading2,
|
|
389
|
+
heading3: icons.heading3,
|
|
390
|
+
heading4: icons.heading4,
|
|
391
|
+
heading5: icons.heading5,
|
|
392
|
+
heading6: icons.heading6
|
|
393
|
+
}))();
|
|
394
|
+
/**
|
|
395
|
+
* The `HeadingButtonsUI` plugin defines a set of UI buttons that can be used instead of the
|
|
396
|
+
* standard drop down component.
|
|
397
|
+
*
|
|
398
|
+
* This feature is not enabled by default by the {@link module:heading/heading~Heading} plugin and needs to be
|
|
399
|
+
* installed manually to the editor configuration.
|
|
400
|
+
*
|
|
401
|
+
* Plugin introduces button UI elements, which names are same as `model` property from {@link module:heading/headingconfig~HeadingOption}.
|
|
402
|
+
*
|
|
403
|
+
* ```ts
|
|
404
|
+
* ClassicEditor
|
|
405
|
+
* .create( {
|
|
406
|
+
* plugins: [ ..., Heading, Paragraph, HeadingButtonsUI, ParagraphButtonUI ]
|
|
407
|
+
* heading: {
|
|
408
|
+
* options: [
|
|
409
|
+
* { model: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },
|
|
410
|
+
* { model: 'heading1', view: 'h2', title: 'Heading 1', class: 'ck-heading_heading1' },
|
|
411
|
+
* { model: 'heading2', view: 'h3', title: 'Heading 2', class: 'ck-heading_heading2' },
|
|
412
|
+
* { model: 'heading3', view: 'h4', title: 'Heading 3', class: 'ck-heading_heading3' }
|
|
413
|
+
* ]
|
|
414
|
+
* },
|
|
415
|
+
* toolbar: [ 'paragraph', 'heading1', 'heading2', 'heading3' ]
|
|
416
|
+
* } )
|
|
417
|
+
* .then( ... )
|
|
418
|
+
* .catch( ... );
|
|
419
|
+
* ```
|
|
420
|
+
*
|
|
421
|
+
* NOTE: The `'paragraph'` button is defined in by the {@link module:paragraph/paragraphbuttonui~ParagraphButtonUI} plugin
|
|
422
|
+
* which needs to be loaded manually as well.
|
|
423
|
+
*
|
|
424
|
+
* It is possible to use custom icons by providing `icon` config option in {@link module:heading/headingconfig~HeadingOption}.
|
|
425
|
+
* For the default configuration standard icons are used.
|
|
426
|
+
*/ class HeadingButtonsUI extends Plugin {
|
|
371
427
|
/**
|
|
372
|
-
|
|
373
|
-
|
|
428
|
+
* @inheritDoc
|
|
429
|
+
*/ init() {
|
|
374
430
|
const options = getLocalizedOptions(this.editor);
|
|
375
431
|
options.filter((item)=>item.model !== 'paragraph').map((item)=>this._createButton(item));
|
|
376
432
|
}
|
|
377
433
|
/**
|
|
378
|
-
|
|
379
|
-
|
|
434
|
+
* Creates single button view from provided configuration option.
|
|
435
|
+
*/ _createButton(option) {
|
|
380
436
|
const editor = this.editor;
|
|
381
437
|
editor.ui.componentFactory.add(option.model, (locale)=>{
|
|
382
438
|
const view = new ButtonView(locale);
|
|
@@ -410,22 +466,30 @@ const titleLikeElements = new Set([
|
|
|
410
466
|
'heading5',
|
|
411
467
|
'heading6'
|
|
412
468
|
]);
|
|
413
|
-
|
|
469
|
+
/**
|
|
470
|
+
* The Title plugin.
|
|
471
|
+
*
|
|
472
|
+
* It splits the document into `Title` and `Body` sections.
|
|
473
|
+
*/ class Title extends Plugin {
|
|
414
474
|
/**
|
|
415
|
-
|
|
416
|
-
|
|
475
|
+
* A reference to an empty paragraph in the body
|
|
476
|
+
* created when there is no element in the body for the placeholder purposes.
|
|
477
|
+
*/ _bodyPlaceholder = new Map();
|
|
478
|
+
/**
|
|
479
|
+
* @inheritDoc
|
|
480
|
+
*/ static get pluginName() {
|
|
417
481
|
return 'Title';
|
|
418
482
|
}
|
|
419
483
|
/**
|
|
420
|
-
|
|
421
|
-
|
|
484
|
+
* @inheritDoc
|
|
485
|
+
*/ static get requires() {
|
|
422
486
|
return [
|
|
423
487
|
'Paragraph'
|
|
424
488
|
];
|
|
425
489
|
}
|
|
426
490
|
/**
|
|
427
|
-
|
|
428
|
-
|
|
491
|
+
* @inheritDoc
|
|
492
|
+
*/ init() {
|
|
429
493
|
const editor = this.editor;
|
|
430
494
|
const model = editor.model;
|
|
431
495
|
// To use the schema for disabling some features when the selection is inside the title element
|
|
@@ -493,33 +557,33 @@ class Title extends Plugin {
|
|
|
493
557
|
this._attachTabPressHandling();
|
|
494
558
|
}
|
|
495
559
|
/**
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
560
|
+
* Returns the title of the document. Note that because this plugin does not allow any formatting inside
|
|
561
|
+
* the title element, the output of this method will be a plain text, with no HTML tags.
|
|
562
|
+
*
|
|
563
|
+
* It is not recommended to use this method together with features that insert markers to the
|
|
564
|
+
* data output, like comments or track changes features. If such markers start in the title and end in the
|
|
565
|
+
* body, the result of this method might be incorrect.
|
|
566
|
+
*
|
|
567
|
+
* @param options Additional configuration passed to the conversion process.
|
|
568
|
+
* See {@link module:engine/controller/datacontroller~DataController#get `DataController#get`}.
|
|
569
|
+
* @returns The title of the document.
|
|
570
|
+
*/ getTitle(options = {}) {
|
|
507
571
|
const rootName = options.rootName ? options.rootName : undefined;
|
|
508
572
|
const titleElement = this._getTitleElement(rootName);
|
|
509
573
|
const titleContentElement = titleElement.getChild(0);
|
|
510
574
|
return this.editor.data.stringify(titleContentElement, options);
|
|
511
575
|
}
|
|
512
576
|
/**
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
577
|
+
* Returns the body of the document.
|
|
578
|
+
*
|
|
579
|
+
* Note that it is not recommended to use this method together with features that insert markers to the
|
|
580
|
+
* data output, like comments or track changes features. If such markers start in the title and end in the
|
|
581
|
+
* body, the result of this method might be incorrect.
|
|
582
|
+
*
|
|
583
|
+
* @param options Additional configuration passed to the conversion process.
|
|
584
|
+
* See {@link module:engine/controller/datacontroller~DataController#get `DataController#get`}.
|
|
585
|
+
* @returns The body of the document.
|
|
586
|
+
*/ getBody(options = {}) {
|
|
523
587
|
const editor = this.editor;
|
|
524
588
|
const data = editor.data;
|
|
525
589
|
const model = editor.model;
|
|
@@ -549,8 +613,8 @@ class Title extends Plugin {
|
|
|
549
613
|
return editor.data.processor.toData(viewDocumentFragment);
|
|
550
614
|
}
|
|
551
615
|
/**
|
|
552
|
-
|
|
553
|
-
|
|
616
|
+
* Returns the `title` element when it is in the document. Returns `undefined` otherwise.
|
|
617
|
+
*/ _getTitleElement(rootName) {
|
|
554
618
|
const root = this.editor.model.document.getRoot(rootName);
|
|
555
619
|
for (const child of root.getChildren()){
|
|
556
620
|
if (isTitle(child)) {
|
|
@@ -559,9 +623,9 @@ class Title extends Plugin {
|
|
|
559
623
|
}
|
|
560
624
|
}
|
|
561
625
|
/**
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
626
|
+
* Model post-fixer callback that ensures that `title` has only one `title-content` child.
|
|
627
|
+
* All additional children should be moved after the `title` element and renamed to a paragraph.
|
|
628
|
+
*/ _fixTitleContent(writer) {
|
|
565
629
|
let changed = false;
|
|
566
630
|
for (const rootName of this.editor.model.document.getRootNames()){
|
|
567
631
|
const title = this._getTitleElement(rootName);
|
|
@@ -582,9 +646,9 @@ class Title extends Plugin {
|
|
|
582
646
|
return changed;
|
|
583
647
|
}
|
|
584
648
|
/**
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
649
|
+
* Model post-fixer callback that creates a title element when it is missing,
|
|
650
|
+
* takes care of the correct position of it and removes additional title elements.
|
|
651
|
+
*/ _fixTitleElement(writer) {
|
|
588
652
|
let changed = false;
|
|
589
653
|
const model = this.editor.model;
|
|
590
654
|
for (const modelRoot of this.editor.model.document.getRoots()){
|
|
@@ -621,9 +685,9 @@ class Title extends Plugin {
|
|
|
621
685
|
return changed;
|
|
622
686
|
}
|
|
623
687
|
/**
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
688
|
+
* Model post-fixer callback that adds an empty paragraph at the end of the document
|
|
689
|
+
* when it is needed for the placeholder purposes.
|
|
690
|
+
*/ _fixBodyElement(writer) {
|
|
627
691
|
let changed = false;
|
|
628
692
|
for (const rootName of this.editor.model.document.getRootNames()){
|
|
629
693
|
const modelRoot = this.editor.model.document.getRoot(rootName);
|
|
@@ -637,9 +701,9 @@ class Title extends Plugin {
|
|
|
637
701
|
return changed;
|
|
638
702
|
}
|
|
639
703
|
/**
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
704
|
+
* Model post-fixer callback that removes a paragraph from the end of the document
|
|
705
|
+
* if it was created for the placeholder purposes and is not needed anymore.
|
|
706
|
+
*/ _fixExtraParagraph(writer) {
|
|
643
707
|
let changed = false;
|
|
644
708
|
for (const rootName of this.editor.model.document.getRootNames()){
|
|
645
709
|
const root = this.editor.model.document.getRoot(rootName);
|
|
@@ -653,8 +717,8 @@ class Title extends Plugin {
|
|
|
653
717
|
return changed;
|
|
654
718
|
}
|
|
655
719
|
/**
|
|
656
|
-
|
|
657
|
-
|
|
720
|
+
* Attaches the `Title` and `Body` placeholders to the title and/or content.
|
|
721
|
+
*/ _attachPlaceholders() {
|
|
658
722
|
const editor = this.editor;
|
|
659
723
|
const t = editor.t;
|
|
660
724
|
const view = editor.editing.view;
|
|
@@ -708,8 +772,8 @@ class Title extends Plugin {
|
|
|
708
772
|
});
|
|
709
773
|
}
|
|
710
774
|
/**
|
|
711
|
-
|
|
712
|
-
|
|
775
|
+
* Creates navigation between the title and body sections using <kbd>Tab</kbd> and <kbd>Shift</kbd>+<kbd>Tab</kbd> keys.
|
|
776
|
+
*/ _attachTabPressHandling() {
|
|
713
777
|
const editor = this.editor;
|
|
714
778
|
const model = editor.model;
|
|
715
779
|
// Pressing <kbd>Tab</kbd> inside the title should move the caret to the body.
|
|
@@ -744,13 +808,6 @@ class Title extends Plugin {
|
|
|
744
808
|
});
|
|
745
809
|
});
|
|
746
810
|
}
|
|
747
|
-
constructor(){
|
|
748
|
-
super(...arguments);
|
|
749
|
-
/**
|
|
750
|
-
* A reference to an empty paragraph in the body
|
|
751
|
-
* created when there is no element in the body for the placeholder purposes.
|
|
752
|
-
*/ this._bodyPlaceholder = new Map();
|
|
753
|
-
}
|
|
754
811
|
}
|
|
755
812
|
/**
|
|
756
813
|
* A view-to-model converter for the h1 that appears at the beginning of the document (a title element).
|