@ckeditor/ckeditor5-paste-from-office 41.3.0-alpha.3 → 41.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/paste-from-office.js +1 -1
- package/package.json +2 -3
- package/src/filters/list.d.ts +1 -1
- package/src/filters/list.js +179 -135
- package/src/filters/removemsattributes.js +3 -1
- package/src/filters/utils.d.ts +25 -0
- package/src/filters/utils.js +52 -0
- package/src/index.d.ts +1 -1
- package/src/normalizers/mswordnormalizer.d.ts +2 -1
- package/src/normalizers/mswordnormalizer.js +3 -2
- package/src/pastefromoffice.js +2 -1
- package/dist/content-index.css +0 -4
- package/dist/editor-index.css +0 -4
- package/dist/index.css +0 -4
- package/dist/types/augmentation.d.ts +0 -14
- package/dist/types/filters/br.d.ts +0 -18
- package/dist/types/filters/image.d.ts +0 -28
- package/dist/types/filters/list.d.ts +0 -30
- package/dist/types/filters/parse.d.ts +0 -39
- package/dist/types/filters/removeboldwrapper.d.ts +0 -18
- package/dist/types/filters/removegooglesheetstag.d.ts +0 -18
- package/dist/types/filters/removeinvalidtablewidth.d.ts +0 -18
- package/dist/types/filters/removemsattributes.d.ts +0 -18
- package/dist/types/filters/removestyleblock.d.ts +0 -18
- package/dist/types/filters/removexmlns.d.ts +0 -18
- package/dist/types/filters/space.d.ts +0 -29
- package/dist/types/index.d.ts +0 -16
- package/dist/types/normalizer.d.ts +0 -34
- package/dist/types/normalizers/googledocsnormalizer.d.ts +0 -33
- package/dist/types/normalizers/googlesheetsnormalizer.d.ts +0 -33
- package/dist/types/normalizers/mswordnormalizer.d.ts +0 -30
- package/dist/types/pastefromoffice.d.ts +0 -40
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
3
|
* For licensing, see LICENSE.md.
|
|
4
|
-
*/(()=>{var e={331:(e,t,n)=>{e.exports=n(237)("./src/clipboard.js")},782:(e,t,n)=>{e.exports=n(237)("./src/core.js")},783:(e,t,n)=>{e.exports=n(237)("./src/engine.js")},237:e=>{"use strict";e.exports=CKEditor5.dll}},t={};function n(r){var s=t[r];if(void 0!==s)return s.exports;var i=t[r]={exports:{}};return e[r](i,i.exports,n),i.exports}n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var r={};(()=>{"use strict";n.r(r),n.d(r,{MSWordNormalizer:()=>d,PasteFromOffice:()=>C,parseHtml:()=>x});var e=n(782),t=n(331),s=n(783);function i(e,t){if(!e.childCount)return;const n=new s.UpcastWriter(e.document),r=function(e,t){const n=t.createRangeIn(e),r=new s.Matcher({name:/^p|h\d+$/,styles:{"mso-list":/.*/}}),i=[];for(const e of n)if("elementStart"===e.type&&r.match(e.item)){const t=l(e.item);i.push({element:e.item,id:t.id,order:t.order,indent:t.indent})}return i}(e,n);if(!r.length)return;let i=null,a=1;r.forEach(((e,l)=>{const u=function(e,t){if(!e)return!0;if(e.id!==t.id)return t.indent-e.indent!=1;const n=t.element.previousSibling;if(!n)return!0;return r=n,!(r.is("element","ol")||r.is("element","ul"));var r}(r[l-1],e),m=u?null:r[l-1],f=(p=e,(d=m)?p.indent-d.indent:p.indent-1);var d,p;if(u&&(i=null,a=1),!i||0!==f){const r=function(e,t){const n=new RegExp(`@list l${e.id}:level${e.indent}\\s*({[^}]*)`,"gi"),r=/mso-level-number-format:([^;]{0,100});/gi,s=/mso-level-start-at:\s{0,100}([0-9]{0,10})\s{0,100};/gi,i=n.exec(t);let c="decimal",l="ol",a=null;if(i&&i[1]){const t=r.exec(i[1]);if(t&&t[1]&&(c=t[1].trim(),l="bullet"!==c&&"image"!==c?"ol":"ul"),"bullet"===c){const t=function(e){const t=function(e){if(e.getChild(0).is("$text"))return null;for(const t of e.getChildren()){if(!t.is("element","span"))continue;const e=t.getChild(0);if(e)return e.is("$text")?e:e.getChild(0)}return null}(e);if(!t)return null;const n=t._data;if("o"===n)return"circle";if("·"===n)return"disc";if("§"===n)return"square";return null}(e.element);t&&(c=t)}else{const e=s.exec(i[1]);e&&e[1]&&(a=parseInt(e[1]))}}return{type:l,startIndex:a,style:o(c)}}(e,t);if(i){if(e.indent>a){const e=i.getChild(i.childCount-1),t=e.getChild(e.childCount-1);i=c(r,t,n),a+=1}else if(e.indent<a){const t=a-e.indent;i=function(e,t){const n=e.getAncestors({parentFirst:!0});let r=null,s=0;for(const e of n)if((e.is("element","ul")||e.is("element","ol"))&&s++,s===t){r=e;break}return r}(i,t),a=e.indent}}else i=c(r,e.element,n);e.indent<=a&&(i.is("element",r.type)||(i=n.rename(r.type,i)))}const g=function(e,t){return function(e,t){const n=new s.Matcher({name:"span",styles:{"mso-list":"Ignore"}}),r=t.createRangeIn(e);for(const e of r)"elementStart"===e.type&&n.match(e.item)&&t.remove(e.item)}(e,t),t.removeStyle("text-indent",e),t.rename("li",e)}(e.element,n);n.appendChild(g,i)}))}function o(e){if(e.startsWith("arabic-leading-zero"))return"decimal-leading-zero";switch(e){case"alpha-upper":return"upper-alpha";case"alpha-lower":return"lower-alpha";case"roman-upper":return"upper-roman";case"roman-lower":return"lower-roman";case"circle":case"disc":case"square":return e;default:return null}}function c(e,t,n){const r=t.parent,s=n.createElement(e.type),i=r.getChildIndex(t)+1;return n.insertChild(i,s,r),e.style&&n.setStyle("list-style-type",e.style,s),e.startIndex&&e.startIndex>1&&n.setAttribute("start",e.startIndex,s),s}function l(e){const t={},n=e.getStyle("mso-list");if(n){const e=n.match(/(^|\s{1,100})l(\d+)/i),r=n.match(/\s{0,100}lfo(\d+)/i),s=n.match(/\s{0,100}level(\d+)/i);e&&r&&s&&(t.id=e[2],t.order=r[1],t.indent=parseInt(s[1]))}return t}function a(e,t){if(!e.childCount)return;const n=new s.UpcastWriter(e.document),r=function(e,t){const n=t.createRangeIn(e),r=new s.Matcher({name:/v:(.+)/}),i=[];for(const e of n){if("elementStart"!=e.type)continue;const t=e.item,n=t.previousSibling,s=n&&n.is("element")?n.name:null,o=["Chart"],c=r.match(t),l=t.getAttribute("o:gfxdata"),a="v:shapetype"===s,u=l&&o.some((e=>t.getAttribute("id").includes(e)));c&&l&&!a&&!u&&i.push(e.item.getAttribute("id"))}return i}(e,n);!function(e,t,n){const r=n.createRangeIn(t),i=new s.Matcher({name:"img"}),o=[];for(const t of r)if(t.item.is("element")&&i.match(t.item)){const n=t.item,r=n.getAttribute("v:shapes")?n.getAttribute("v:shapes").split(" "):[];r.length&&r.every((t=>e.indexOf(t)>-1))?o.push(n):n.getAttribute("src")||o.push(n)}for(const e of o)n.remove(e)}(r,e,n),function(e,t,n){const r=n.createRangeIn(t),s=[];for(const t of r)if("elementStart"==t.type&&t.item.is("element","v:shape")){const n=t.item.getAttribute("id");if(e.includes(n))continue;i(t.item.parent.getChildren(),n)||s.push(t.item)}for(const e of s){const t={src:o(e)};e.hasAttribute("alt")&&(t.alt=e.getAttribute("alt"));const r=n.createElement("img",t);n.insertChild(e.index+1,r,e.parent)}function i(e,t){for(const n of e)if(n.is("element")){if("img"==n.name&&n.getAttribute("v:shapes")==t)return!0;if(i(n.getChildren(),t))return!0}return!1}function o(e){for(const t of e.getChildren())if(t.is("element")&&t.getAttribute("src"))return t.getAttribute("src")}}(r,e,n),function(e,t){const n=t.createRangeIn(e),r=new s.Matcher({name:/v:(.+)/}),i=[];for(const e of n)"elementStart"==e.type&&r.match(e.item)&&i.push(e.item);for(const e of i)t.remove(e)}(e,n);const i=function(e,t){const n=t.createRangeIn(e),r=new s.Matcher({name:"img"}),i=[];for(const e of n)e.item.is("element")&&r.match(e.item)&&e.item.getAttribute("src").startsWith("file://")&&i.push(e.item);return i}(e,n);i.length&&function(e,t,n){if(e.length===t.length)for(let r=0;r<e.length;r++){const s=`data:${t[r].type};base64,${u(t[r].hex)}`;n.setAttribute("src",s,e[r])}}(i,function(e){if(!e)return[];const t=/{\\pict[\s\S]+?\\bliptag-?\d+(\\blipupi-?\d+)?({\\\*\\blipuid\s?[\da-fA-F]+)?[\s}]*?/,n=new RegExp("(?:("+t.source+"))([\\da-fA-F\\s]+)\\}","g"),r=e.match(n),s=[];if(r)for(const e of r){let n=!1;e.includes("\\pngblip")?n="image/png":e.includes("\\jpegblip")&&(n="image/jpeg"),n&&s.push({hex:e.replace(t,"").replace(/[^\da-fA-F]/g,""),type:n})}return s}(t),n)}function u(e){return btoa(e.match(/\w{2}/g).map((e=>String.fromCharCode(parseInt(e,16)))).join(""))}const m=/<meta\s*name="?generator"?\s*content="?microsoft\s*word\s*\d+"?\/?>/i,f=/xmlns:o="urn:schemas-microsoft-com/i;class d{constructor(e){this.document=e}isActive(e){return m.test(e)||f.test(e)}execute(e){const{body:t,stylesString:n}=e._parsedData;i(t,n),a(t,e.dataTransfer.getData("text/rtf")),function(e){const t=[],n=new s.UpcastWriter(e.document);for(const{item:r}of n.createRangeIn(e))if(r.is("element")){for(const e of r.getClassNames())/\bmso/gi.exec(e)&&n.removeClass(e,r);for(const e of r.getStyleNames())/\bmso/gi.exec(e)&&n.removeStyle(e,r);r.is("element","w:sdt")&&t.push(r)}for(const e of t){const t=e.parent,r=t.getChildIndex(e);n.insertChild(r,e.getChildren(),t),n.remove(e)}}(t),e.content=t}}function p(e,t,n,{blockElements:r,inlineObjectElements:s}){let i=n.createPositionAt(e,"forward"==t?"after":"before");return i=i.getLastMatchingPosition((({item:e})=>e.is("element")&&!r.includes(e.name)&&!s.includes(e.name)),{direction:t}),"forward"==t?i.nodeAfter:i.nodeBefore}function g(e,t){return!!e&&e.is("element")&&t.includes(e.name)}const h=/id=("|')docs-internal-guid-[-0-9a-f]+("|')/i;class b{constructor(e){this.document=e}isActive(e){return h.test(e)}execute(e){const t=new s.UpcastWriter(this.document),{body:n}=e._parsedData;!function(e,t){for(const n of e.getChildren())if(n.is("element","b")&&"normal"===n.getStyle("font-weight")){const r=e.getChildIndex(n);t.remove(n),t.insertChild(r,n.getChildren(),e)}}(n,t),function(e,t){for(const n of t.createRangeIn(e)){const e=n.item;if(e.is("element","li")){const n=e.getChild(0);n&&n.is("element","p")&&t.unwrapElement(n)}}}(n,t),function(e,t){const n=new s.ViewDocument(t.document.stylesProcessor),r=new s.DomConverter(n,{renderingMode:"data"}),i=r.blockElements,o=r.inlineObjectElements,c=[];for(const n of t.createRangeIn(e)){const e=n.item;if(e.is("element","br")){const n=p(e,"forward",t,{blockElements:i,inlineObjectElements:o}),r=p(e,"backward",t,{blockElements:i,inlineObjectElements:o}),s=g(n,i);(g(r,i)||s)&&c.push(e)}}for(const e of c)e.hasClass("Apple-interchange-newline")?t.remove(e):t.replace(e,t.createElement("p"))}(n,t),e.content=n}}const y=/<google-sheets-html-origin/i;class v{constructor(e){this.document=e}isActive(e){return y.test(e)}execute(e){const t=new s.UpcastWriter(this.document),{body:n}=e._parsedData;!function(e,t){for(const n of e.getChildren())if(n.is("element","google-sheets-html-origin")){const r=e.getChildIndex(n);t.remove(n),t.insertChild(r,n.getChildren(),e)}}(n,t),function(e,t){for(const n of e.getChildren())n.is("element","table")&&n.hasAttribute("xmlns")&&t.removeAttribute("xmlns",n)}(n,t),function(e,t){for(const n of e.getChildren())n.is("element","table")&&"0px"===n.getStyle("width")&&t.removeStyle("width",n)}(n,t),function(e,t){for(const n of Array.from(e.getChildren()))n.is("element","style")&&t.remove(n)}(n,t),e.content=n}}function w(e){return e.replace(/<span(?: class="Apple-converted-space"|)>(\s+)<\/span>/g,((e,t)=>1===t.length?" ":Array(t.length+1).join(" ").substr(0,t.length)))}function x(e,t){const n=new DOMParser,r=function(e){return w(w(e)).replace(/(<span\s+style=['"]mso-spacerun:yes['"]>[^\S\r\n]*?)[\r\n]+([^\S\r\n]*<\/span>)/g,"$1$2").replace(/<span\s+style=['"]mso-spacerun:yes['"]><\/span>/g,"").replace(/(<span\s+style=['"]letter-spacing:[^'"]+?['"]>)[\r\n]+(<\/span>)/g,"$1 $2").replace(/ <\//g," </").replace(/ <o:p><\/o:p>/g," <o:p></o:p>").replace(/<o:p>( |\u00A0)<\/o:p>/g,"").replace(/>([^\S\r\n]*[\r\n]\s*)</g,"><")}(function(e){const t="</body>",n="</html>",r=e.indexOf(t);if(r<0)return e;const s=e.indexOf(n,r+t.length);return e.substring(0,r+t.length)+(s>=0?e.substring(s):"")}(e=(e=e.replace(/<!--\[if gte vml 1]>/g,"")).replace(/<o:SmartTagType(?:\s+[^\s>=]+(?:="[^"]*")?)*\s*\/?>/gi,""))),i=n.parseFromString(r,"text/html");!function(e){e.querySelectorAll("span[style*=spacerun]").forEach((e=>{const t=e,n=t.innerText.length||0;t.innerText=Array(n+1).join(" ").substr(0,n)}))}(i);const o=i.body.innerHTML,c=function(e,t){const n=new s.ViewDocument(t),r=new s.DomConverter(n,{renderingMode:"data"}),i=e.createDocumentFragment(),o=e.body.childNodes;for(;o.length>0;)i.appendChild(o[0]);return r.domToView(i,{skipComments:!0})}(i,t),l=function(e){const t=[],n=[],r=Array.from(e.getElementsByTagName("style"));for(const e of r)e.sheet&&e.sheet.cssRules&&e.sheet.cssRules.length&&(t.push(e.sheet),n.push(e.innerHTML));return{styles:t,stylesString:n.join(" ")}}(i);return{body:c,bodyString:o,styles:l.styles,stylesString:l.stylesString}}class C extends e.Plugin{static get pluginName(){return"PasteFromOffice"}static get requires(){return[t.ClipboardPipeline]}init(){const e=this.editor,t=e.plugins.get("ClipboardPipeline"),n=e.editing.view.document,r=[];r.push(new d(n)),r.push(new b(n)),r.push(new v(n)),t.on("inputTransformation",((t,s)=>{if(s._isTransformedWithPasteFromOffice)return;if(e.model.document.selection.getFirstPosition().parent.is("element","codeBlock"))return;const i=s.dataTransfer.getData("text/html"),o=r.find((e=>e.isActive(i)));o&&(s._parsedData||(s._parsedData=x(i,n.stylesProcessor)),o.execute(s),s._isTransformedWithPasteFromOffice=!0)}),{priority:"high"})}}})(),(window.CKEditor5=window.CKEditor5||{}).pasteFromOffice=r})();
|
|
4
|
+
*/(()=>{var e={331:(e,t,n)=>{e.exports=n(237)("./src/clipboard.js")},782:(e,t,n)=>{e.exports=n(237)("./src/core.js")},783:(e,t,n)=>{e.exports=n(237)("./src/engine.js")},237:e=>{"use strict";e.exports=CKEditor5.dll}},t={};function n(r){var s=t[r];if(void 0!==s)return s.exports;var i=t[r]={exports:{}};return e[r](i,i.exports,n),i.exports}n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var r={};(()=>{"use strict";n.r(r),n.d(r,{MSWordNormalizer:()=>x,PasteFromOffice:()=>P,parseHtml:()=>M});var e=n(782),t=n(331),s=n(783);function i(e){return void 0!==e&&e.endsWith("px")}function o(e){return e.toFixed(2).replace(/\.?0+$/,"")+"px"}function l(e,t,n){if(!e.childCount)return;const r=new s.UpcastWriter(e.document),l=function(e,t){const n=t.createRangeIn(e),r=[],s=new Set;for(const e of n.getItems()){if(!e.is("element")||!e.name.match(/^(p|h\d+|li|div)$/))continue;let t=g(e);if(void 0===t||0!=parseFloat(t)||Array.from(e.getClassNames()).find((e=>e.startsWith("MsoList")))||(t=void 0),e.hasStyle("mso-list")||void 0!==t&&s.has(t)){const n=f(e);r.push({element:e,id:n.id,order:n.order,indent:n.indent,marginLeft:t}),void 0!==t&&s.add(t)}else s.clear()}return r}(e,r);if(!l.length)return;const a={},u=[];for(const e of l)if(void 0!==e.indent){c(e)||(u.length=0);const s=`${e.id}:${e.indent}`,l=Math.min(e.indent-1,u.length);if(l<u.length&&u[l].id!==e.id&&(u.length=l),l<u.length-1)u.length=l+1;else{const c=m(e,t);if(l>u.length-1||u[l].listElement.name!=c.type){0==l&&"ol"==c.type&&void 0!==e.id&&a[s]&&(c.startIndex=a[s]);const t=d(c,r,n);if(i(e.marginLeft)&&(0==l||i(u[l-1].marginLeft))){let n=e.marginLeft;l>0&&(n=o(parseFloat(n)-parseFloat(u[l-1].marginLeft))),r.setStyle("padding-left",n,t)}if(0==u.length){const n=e.element.parent,s=n.getChildIndex(e.element)+1;r.insertChild(s,t,n)}else{const e=u[l-1].listItemElements;r.appendChild(t,e[e.length-1])}u[l]={...e,listElement:t,listItemElements:[]},0==l&&void 0!==e.id&&(a[s]=c.startIndex||1)}}const f="li"==e.element.name?e.element:r.createElement("li");r.appendChild(f,u[l].listElement),u[l].listItemElements.push(f),0==l&&void 0!==e.id&&a[s]++,e.element!=f&&r.appendChild(e.element,f),p(e.element,r),r.removeStyle("text-indent",e.element),r.removeStyle("margin-left",e.element)}else{const t=u.find((t=>t.marginLeft==e.marginLeft));if(t){const n=t.listItemElements;r.appendChild(e.element,n[n.length-1]),r.removeStyle("margin-left",e.element)}else u.length=0}}function c(e){const t=e.element.previousSibling;return a(t||e.element.parent)}function a(e){return e.is("element","ol")||e.is("element","ul")}function m(e,t){const n=new RegExp(`@list l${e.id}:level${e.indent}\\s*({[^}]*)`,"gi"),r=/mso-level-number-format:([^;]{0,100});/gi,s=/mso-level-start-at:\s{0,100}([0-9]{0,10})\s{0,100};/gi,i=new RegExp(`@list\\s+l${e.id}:level\\d\\s*{[^{]*mso-level-text:"%\\d\\\\.`,"gi"),o=new RegExp(`@list l${e.id}:level\\d\\s*{[^{]*mso-level-number-format:`,"gi"),l=i.exec(t),c=o.exec(t),a=l&&!c,m=n.exec(t);let d="decimal",f="ol",p=null;if(m&&m[1]){const t=r.exec(m[1]);if(t&&t[1]&&(d=t[1].trim(),f="bullet"!==d&&"image"!==d?"ol":"ul"),"bullet"===d){const t=function(e){if("li"==e.name&&"ul"==e.parent.name&&e.parent.hasAttribute("type"))return e.parent.getAttribute("type");const t=function(e){if(e.getChild(0).is("$text"))return null;for(const t of e.getChildren()){if(!t.is("element","span"))continue;const e=t.getChild(0);if(e)return e.is("$text")?e:e.getChild(0)}return null}(e);if(!t)return null;const n=t._data;if("o"===n)return"circle";if("·"===n)return"disc";if("§"===n)return"square";return null}(e.element);t&&(d=t)}else{const e=s.exec(m[1]);e&&e[1]&&(p=parseInt(e[1]))}a&&(f="ol")}return{type:f,startIndex:p,style:u(d),isLegalStyleList:a}}function u(e){if(e.startsWith("arabic-leading-zero"))return"decimal-leading-zero";switch(e){case"alpha-upper":return"upper-alpha";case"alpha-lower":return"lower-alpha";case"roman-upper":return"upper-roman";case"roman-lower":return"lower-roman";case"circle":case"disc":case"square":return e;default:return null}}function d(e,t,n){const r=t.createElement(e.type);return e.style&&t.setStyle("list-style-type",e.style,r),e.startIndex&&e.startIndex>1&&t.setAttribute("start",e.startIndex,r),e.isLegalStyleList&&n&&t.addClass("legal-list",r),r}function f(e){const t=e.getStyle("mso-list");if(void 0===t)return{};const n=t.match(/(^|\s{1,100})l(\d+)/i),r=t.match(/\s{0,100}lfo(\d+)/i),s=t.match(/\s{0,100}level(\d+)/i);return n&&r&&s?{id:n[2],order:r[1],indent:parseInt(s[1])}:{indent:1}}function p(e,t){const n=new s.Matcher({name:"span",styles:{"mso-list":"Ignore"}}),r=t.createRangeIn(e);for(const e of r)"elementStart"===e.type&&n.match(e.item)&&t.remove(e.item)}function g(e){const t=e.getStyle("margin-left");return void 0===t||t.endsWith("px")?t:function(e){const t=parseFloat(e);return e.endsWith("pt")?o(96*t/72):e.endsWith("pc")?o(12*t*96/72):e.endsWith("in")?o(96*t):e.endsWith("cm")?o(96*t/2.54):e.endsWith("mm")?o(t/10*96/2.54):e}(t)}function h(e,t){if(!e.childCount)return;const n=new s.UpcastWriter(e.document),r=function(e,t){const n=t.createRangeIn(e),r=new s.Matcher({name:/v:(.+)/}),i=[];for(const e of n){if("elementStart"!=e.type)continue;const t=e.item,n=t.previousSibling,s=n&&n.is("element")?n.name:null,o=["Chart"],l=r.match(t),c=t.getAttribute("o:gfxdata"),a="v:shapetype"===s,m=c&&o.some((e=>t.getAttribute("id").includes(e)));l&&c&&!a&&!m&&i.push(e.item.getAttribute("id"))}return i}(e,n);!function(e,t,n){const r=n.createRangeIn(t),i=new s.Matcher({name:"img"}),o=[];for(const t of r)if(t.item.is("element")&&i.match(t.item)){const n=t.item,r=n.getAttribute("v:shapes")?n.getAttribute("v:shapes").split(" "):[];r.length&&r.every((t=>e.indexOf(t)>-1))?o.push(n):n.getAttribute("src")||o.push(n)}for(const e of o)n.remove(e)}(r,e,n),function(e,t,n){const r=n.createRangeIn(t),s=[];for(const t of r)if("elementStart"==t.type&&t.item.is("element","v:shape")){const n=t.item.getAttribute("id");if(e.includes(n))continue;i(t.item.parent.getChildren(),n)||s.push(t.item)}for(const e of s){const t={src:o(e)};e.hasAttribute("alt")&&(t.alt=e.getAttribute("alt"));const r=n.createElement("img",t);n.insertChild(e.index+1,r,e.parent)}function i(e,t){for(const n of e)if(n.is("element")){if("img"==n.name&&n.getAttribute("v:shapes")==t)return!0;if(i(n.getChildren(),t))return!0}return!1}function o(e){for(const t of e.getChildren())if(t.is("element")&&t.getAttribute("src"))return t.getAttribute("src")}}(r,e,n),function(e,t){const n=t.createRangeIn(e),r=new s.Matcher({name:/v:(.+)/}),i=[];for(const e of n)"elementStart"==e.type&&r.match(e.item)&&i.push(e.item);for(const e of i)t.remove(e)}(e,n);const i=function(e,t){const n=t.createRangeIn(e),r=new s.Matcher({name:"img"}),i=[];for(const e of n)e.item.is("element")&&r.match(e.item)&&e.item.getAttribute("src").startsWith("file://")&&i.push(e.item);return i}(e,n);i.length&&function(e,t,n){if(e.length===t.length)for(let r=0;r<e.length;r++){const s=`data:${t[r].type};base64,${y(t[r].hex)}`;n.setAttribute("src",s,e[r])}}(i,function(e){if(!e)return[];const t=/{\\pict[\s\S]+?\\bliptag-?\d+(\\blipupi-?\d+)?({\\\*\\blipuid\s?[\da-fA-F]+)?[\s}]*?/,n=new RegExp("(?:("+t.source+"))([\\da-fA-F\\s]+)\\}","g"),r=e.match(n),s=[];if(r)for(const e of r){let n=!1;e.includes("\\pngblip")?n="image/png":e.includes("\\jpegblip")&&(n="image/jpeg"),n&&s.push({hex:e.replace(t,"").replace(/[^\da-fA-F]/g,""),type:n})}return s}(t),n)}function y(e){return btoa(e.match(/\w{2}/g).map((e=>String.fromCharCode(parseInt(e,16)))).join(""))}const b=/<meta\s*name="?generator"?\s*content="?microsoft\s*word\s*\d+"?\/?>/i,v=/xmlns:o="urn:schemas-microsoft-com/i;class x{constructor(e,t=!1){this.document=e,this.hasMultiLevelListPlugin=t}isActive(e){return b.test(e)||v.test(e)}execute(e){const{body:t,stylesString:n}=e._parsedData;l(t,n,this.hasMultiLevelListPlugin),h(t,e.dataTransfer.getData("text/rtf")),function(e){const t=[],n=new s.UpcastWriter(e.document);for(const{item:r}of n.createRangeIn(e))if(r.is("element")){for(const e of r.getClassNames())/\bmso/gi.exec(e)&&n.removeClass(e,r);for(const e of r.getStyleNames())/\bmso/gi.exec(e)&&n.removeStyle(e,r);(r.is("element","w:sdt")||r.is("element","w:sdtpr")&&r.isEmpty||r.is("element","o:p")&&r.isEmpty)&&t.push(r)}for(const e of t){const t=e.parent,r=t.getChildIndex(e);n.insertChild(r,e.getChildren(),t),n.remove(e)}}(t),e.content=t}}function w(e,t,n,{blockElements:r,inlineObjectElements:s}){let i=n.createPositionAt(e,"forward"==t?"after":"before");return i=i.getLastMatchingPosition((({item:e})=>e.is("element")&&!r.includes(e.name)&&!s.includes(e.name)),{direction:t}),"forward"==t?i.nodeAfter:i.nodeBefore}function C(e,t){return!!e&&e.is("element")&&t.includes(e.name)}const S=/id=("|')docs-internal-guid-[-0-9a-f]+("|')/i;class A{constructor(e){this.document=e}isActive(e){return S.test(e)}execute(e){const t=new s.UpcastWriter(this.document),{body:n}=e._parsedData;!function(e,t){for(const n of e.getChildren())if(n.is("element","b")&&"normal"===n.getStyle("font-weight")){const r=e.getChildIndex(n);t.remove(n),t.insertChild(r,n.getChildren(),e)}}(n,t),function(e,t){for(const n of t.createRangeIn(e)){const e=n.item;if(e.is("element","li")){const n=e.getChild(0);n&&n.is("element","p")&&t.unwrapElement(n)}}}(n,t),function(e,t){const n=new s.ViewDocument(t.document.stylesProcessor),r=new s.DomConverter(n,{renderingMode:"data"}),i=r.blockElements,o=r.inlineObjectElements,l=[];for(const n of t.createRangeIn(e)){const e=n.item;if(e.is("element","br")){const n=w(e,"forward",t,{blockElements:i,inlineObjectElements:o}),r=w(e,"backward",t,{blockElements:i,inlineObjectElements:o}),s=C(n,i);(C(r,i)||s)&&l.push(e)}}for(const e of l)e.hasClass("Apple-interchange-newline")?t.remove(e):t.replace(e,t.createElement("p"))}(n,t),e.content=n}}const E=/<google-sheets-html-origin/i;class I{constructor(e){this.document=e}isActive(e){return E.test(e)}execute(e){const t=new s.UpcastWriter(this.document),{body:n}=e._parsedData;!function(e,t){for(const n of e.getChildren())if(n.is("element","google-sheets-html-origin")){const r=e.getChildIndex(n);t.remove(n),t.insertChild(r,n.getChildren(),e)}}(n,t),function(e,t){for(const n of e.getChildren())n.is("element","table")&&n.hasAttribute("xmlns")&&t.removeAttribute("xmlns",n)}(n,t),function(e,t){for(const n of e.getChildren())n.is("element","table")&&"0px"===n.getStyle("width")&&t.removeStyle("width",n)}(n,t),function(e,t){for(const n of Array.from(e.getChildren()))n.is("element","style")&&t.remove(n)}(n,t),e.content=n}}function L(e){return e.replace(/<span(?: class="Apple-converted-space"|)>(\s+)<\/span>/g,((e,t)=>1===t.length?" ":Array(t.length+1).join(" ").substr(0,t.length)))}function M(e,t){const n=new DOMParser,r=function(e){return L(L(e)).replace(/(<span\s+style=['"]mso-spacerun:yes['"]>[^\S\r\n]*?)[\r\n]+([^\S\r\n]*<\/span>)/g,"$1$2").replace(/<span\s+style=['"]mso-spacerun:yes['"]><\/span>/g,"").replace(/(<span\s+style=['"]letter-spacing:[^'"]+?['"]>)[\r\n]+(<\/span>)/g,"$1 $2").replace(/ <\//g," </").replace(/ <o:p><\/o:p>/g," <o:p></o:p>").replace(/<o:p>( |\u00A0)<\/o:p>/g,"").replace(/>([^\S\r\n]*[\r\n]\s*)</g,"><")}(function(e){const t="</body>",n="</html>",r=e.indexOf(t);if(r<0)return e;const s=e.indexOf(n,r+t.length);return e.substring(0,r+t.length)+(s>=0?e.substring(s):"")}(e=(e=e.replace(/<!--\[if gte vml 1]>/g,"")).replace(/<o:SmartTagType(?:\s+[^\s>=]+(?:="[^"]*")?)*\s*\/?>/gi,""))),i=n.parseFromString(r,"text/html");!function(e){e.querySelectorAll("span[style*=spacerun]").forEach((e=>{const t=e,n=t.innerText.length||0;t.innerText=Array(n+1).join(" ").substr(0,n)}))}(i);const o=i.body.innerHTML,l=function(e,t){const n=new s.ViewDocument(t),r=new s.DomConverter(n,{renderingMode:"data"}),i=e.createDocumentFragment(),o=e.body.childNodes;for(;o.length>0;)i.appendChild(o[0]);return r.domToView(i,{skipComments:!0})}(i,t),c=function(e){const t=[],n=[],r=Array.from(e.getElementsByTagName("style"));for(const e of r)e.sheet&&e.sheet.cssRules&&e.sheet.cssRules.length&&(t.push(e.sheet),n.push(e.innerHTML));return{styles:t,stylesString:n.join(" ")}}(i);return{body:l,bodyString:o,styles:c.styles,stylesString:c.stylesString}}class P extends e.Plugin{static get pluginName(){return"PasteFromOffice"}static get requires(){return[t.ClipboardPipeline]}init(){const e=this.editor,t=e.plugins.get("ClipboardPipeline"),n=e.editing.view.document,r=[],s=this.editor.plugins.has("MultiLevelList");r.push(new x(n,s)),r.push(new A(n)),r.push(new I(n)),t.on("inputTransformation",((t,s)=>{if(s._isTransformedWithPasteFromOffice)return;if(e.model.document.selection.getFirstPosition().parent.is("element","codeBlock"))return;const i=s.dataTransfer.getData("text/html"),o=r.find((e=>e.isActive(i)));o&&(s._parsedData||(s._parsedData=M(i,n.stylesProcessor)),o.execute(s),s._isTransformedWithPasteFromOffice=!0)}),{priority:"high"})}}})(),(window.CKEditor5=window.CKEditor5||{}).pasteFromOffice=r})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ckeditor/ckeditor5-paste-from-office",
|
|
3
|
-
"version": "41.3.0
|
|
3
|
+
"version": "41.3.0",
|
|
4
4
|
"description": "Paste from Office feature for CKEditor 5.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ckeditor",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"type": "module",
|
|
14
14
|
"main": "src/index.js",
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"ckeditor5": "41.3.0
|
|
16
|
+
"ckeditor5": "41.3.0"
|
|
17
17
|
},
|
|
18
18
|
"author": "CKSource (http://cksource.com/)",
|
|
19
19
|
"license": "GPL-2.0-or-later",
|
|
@@ -25,7 +25,6 @@
|
|
|
25
25
|
"directory": "packages/ckeditor5-paste-from-office"
|
|
26
26
|
},
|
|
27
27
|
"files": [
|
|
28
|
-
"dist",
|
|
29
28
|
"lang",
|
|
30
29
|
"src/**/*.js",
|
|
31
30
|
"src/**/*.d.ts",
|
package/src/filters/list.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ import { UpcastWriter, type ViewDocumentFragment } from 'ckeditor5/src/engine.js
|
|
|
19
19
|
* @param documentFragment The view structure to be transformed.
|
|
20
20
|
* @param stylesString Styles from which list-like elements styling will be extracted.
|
|
21
21
|
*/
|
|
22
|
-
export declare function transformListItemLikeElementsIntoLists(documentFragment: ViewDocumentFragment, stylesString: string): void;
|
|
22
|
+
export declare function transformListItemLikeElementsIntoLists(documentFragment: ViewDocumentFragment, stylesString: string, hasMultiLevelListPlugin: boolean): void;
|
|
23
23
|
/**
|
|
24
24
|
* Removes paragraph wrapping content inside a list item.
|
|
25
25
|
*/
|
package/src/filters/list.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* @module paste-from-office/filters/list
|
|
7
7
|
*/
|
|
8
8
|
import { Matcher, UpcastWriter } from 'ckeditor5/src/engine.js';
|
|
9
|
+
import { convertCssLengthToPx, isPx, toPx } from './utils.js';
|
|
9
10
|
/**
|
|
10
11
|
* Transforms Word specific list-like elements to the semantic HTML lists.
|
|
11
12
|
*
|
|
@@ -19,7 +20,7 @@ import { Matcher, UpcastWriter } from 'ckeditor5/src/engine.js';
|
|
|
19
20
|
* @param documentFragment The view structure to be transformed.
|
|
20
21
|
* @param stylesString Styles from which list-like elements styling will be extracted.
|
|
21
22
|
*/
|
|
22
|
-
export function transformListItemLikeElementsIntoLists(documentFragment, stylesString) {
|
|
23
|
+
export function transformListItemLikeElementsIntoLists(documentFragment, stylesString, hasMultiLevelListPlugin) {
|
|
23
24
|
if (!documentFragment.childCount) {
|
|
24
25
|
return;
|
|
25
26
|
}
|
|
@@ -28,41 +29,103 @@ export function transformListItemLikeElementsIntoLists(documentFragment, stylesS
|
|
|
28
29
|
if (!itemLikeElements.length) {
|
|
29
30
|
return;
|
|
30
31
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if (isDifferentList) {
|
|
38
|
-
currentList = null;
|
|
39
|
-
currentIndentation = 1;
|
|
40
|
-
}
|
|
41
|
-
if (!currentList || indentationDifference !== 0) {
|
|
42
|
-
const listStyle = detectListStyle(itemLikeElement, stylesString);
|
|
43
|
-
if (!currentList) {
|
|
44
|
-
currentList = insertNewEmptyList(listStyle, itemLikeElement.element, writer);
|
|
32
|
+
const encounteredLists = {};
|
|
33
|
+
const stack = [];
|
|
34
|
+
for (const itemLikeElement of itemLikeElements) {
|
|
35
|
+
if (itemLikeElement.indent !== undefined) {
|
|
36
|
+
if (!isListContinuation(itemLikeElement)) {
|
|
37
|
+
stack.length = 0;
|
|
45
38
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
39
|
+
// Combined list ID for addressing encounter lists counters.
|
|
40
|
+
const originalListId = `${itemLikeElement.id}:${itemLikeElement.indent}`;
|
|
41
|
+
// Normalized list item indentation.
|
|
42
|
+
const indent = Math.min(itemLikeElement.indent - 1, stack.length);
|
|
43
|
+
// Trimming of the list stack on list ID change.
|
|
44
|
+
if (indent < stack.length && stack[indent].id !== itemLikeElement.id) {
|
|
45
|
+
stack.length = indent;
|
|
51
46
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
currentIndentation = itemLikeElement.indent;
|
|
47
|
+
// Trimming of the list stack on lower indent list encountered.
|
|
48
|
+
if (indent < stack.length - 1) {
|
|
49
|
+
stack.length = indent + 1;
|
|
56
50
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
51
|
+
else {
|
|
52
|
+
const listStyle = detectListStyle(itemLikeElement, stylesString);
|
|
53
|
+
// Create a new OL/UL if required (greater indent or different list type).
|
|
54
|
+
if (indent > stack.length - 1 || stack[indent].listElement.name != listStyle.type) {
|
|
55
|
+
// Check if there is some start index to set from a previous list.
|
|
56
|
+
if (indent == 0 &&
|
|
57
|
+
listStyle.type == 'ol' &&
|
|
58
|
+
itemLikeElement.id !== undefined &&
|
|
59
|
+
encounteredLists[originalListId]) {
|
|
60
|
+
listStyle.startIndex = encounteredLists[originalListId];
|
|
61
|
+
}
|
|
62
|
+
const listElement = createNewEmptyList(listStyle, writer, hasMultiLevelListPlugin);
|
|
63
|
+
// Apply list padding only if we have margins for the item and the parent item.
|
|
64
|
+
if (isPx(itemLikeElement.marginLeft) &&
|
|
65
|
+
(indent == 0 || isPx(stack[indent - 1].marginLeft))) {
|
|
66
|
+
let marginLeft = itemLikeElement.marginLeft;
|
|
67
|
+
if (indent > 0) {
|
|
68
|
+
// Convert the padding from absolute to relative.
|
|
69
|
+
marginLeft = toPx(parseFloat(marginLeft) - parseFloat(stack[indent - 1].marginLeft));
|
|
70
|
+
}
|
|
71
|
+
writer.setStyle('padding-left', marginLeft, listElement);
|
|
72
|
+
}
|
|
73
|
+
// Insert the new OL/UL.
|
|
74
|
+
if (stack.length == 0) {
|
|
75
|
+
const parent = itemLikeElement.element.parent;
|
|
76
|
+
const index = parent.getChildIndex(itemLikeElement.element) + 1;
|
|
77
|
+
writer.insertChild(index, listElement, parent);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
const parentListItems = stack[indent - 1].listItemElements;
|
|
81
|
+
writer.appendChild(listElement, parentListItems[parentListItems.length - 1]);
|
|
82
|
+
}
|
|
83
|
+
// Update the list stack for other items to reference.
|
|
84
|
+
stack[indent] = {
|
|
85
|
+
...itemLikeElement,
|
|
86
|
+
listElement,
|
|
87
|
+
listItemElements: []
|
|
88
|
+
};
|
|
89
|
+
// Prepare list counter for start index.
|
|
90
|
+
if (indent == 0 && itemLikeElement.id !== undefined) {
|
|
91
|
+
encounteredLists[originalListId] = listStyle.startIndex || 1;
|
|
92
|
+
}
|
|
60
93
|
}
|
|
61
94
|
}
|
|
95
|
+
// Use LI if it is already it or create a new LI element.
|
|
96
|
+
// https://github.com/ckeditor/ckeditor5/issues/15964
|
|
97
|
+
const listItem = itemLikeElement.element.name == 'li' ? itemLikeElement.element : writer.createElement('li');
|
|
98
|
+
// Append the LI to OL/UL.
|
|
99
|
+
writer.appendChild(listItem, stack[indent].listElement);
|
|
100
|
+
stack[indent].listItemElements.push(listItem);
|
|
101
|
+
// Increment list counter.
|
|
102
|
+
if (indent == 0 && itemLikeElement.id !== undefined) {
|
|
103
|
+
encounteredLists[originalListId]++;
|
|
104
|
+
}
|
|
105
|
+
// Append list block to LI.
|
|
106
|
+
if (itemLikeElement.element != listItem) {
|
|
107
|
+
writer.appendChild(itemLikeElement.element, listItem);
|
|
108
|
+
}
|
|
109
|
+
// Clean list block.
|
|
110
|
+
removeBulletElement(itemLikeElement.element, writer);
|
|
111
|
+
writer.removeStyle('text-indent', itemLikeElement.element); // #12361
|
|
112
|
+
writer.removeStyle('margin-left', itemLikeElement.element);
|
|
62
113
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
114
|
+
else {
|
|
115
|
+
// Other blocks in a list item.
|
|
116
|
+
const stackItem = stack.find(stackItem => stackItem.marginLeft == itemLikeElement.marginLeft);
|
|
117
|
+
// This might be a paragraph that has known margin, but it is not a real list block.
|
|
118
|
+
if (stackItem) {
|
|
119
|
+
const listItems = stackItem.listItemElements;
|
|
120
|
+
// Append block to LI.
|
|
121
|
+
writer.appendChild(itemLikeElement.element, listItems[listItems.length - 1]);
|
|
122
|
+
writer.removeStyle('margin-left', itemLikeElement.element);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
stack.length = 0;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
66
129
|
}
|
|
67
130
|
/**
|
|
68
131
|
* Removes paragraph wrapping content inside a list item.
|
|
@@ -87,27 +150,58 @@ export function unwrapParagraphInListItem(documentFragment, writer) {
|
|
|
87
150
|
*/
|
|
88
151
|
function findAllItemLikeElements(documentFragment, writer) {
|
|
89
152
|
const range = writer.createRangeIn(documentFragment);
|
|
90
|
-
// Matcher for finding list-like elements.
|
|
91
|
-
const itemLikeElementsMatcher = new Matcher({
|
|
92
|
-
name: /^p|h\d+$/,
|
|
93
|
-
styles: {
|
|
94
|
-
'mso-list': /.*/
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
153
|
const itemLikeElements = [];
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
154
|
+
const foundMargins = new Set();
|
|
155
|
+
for (const item of range.getItems()) {
|
|
156
|
+
// https://github.com/ckeditor/ckeditor5/issues/15964
|
|
157
|
+
if (!item.is('element') || !item.name.match(/^(p|h\d+|li|div)$/)) {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
// Try to rely on margin-left style to find paragraphs visually aligned with previously encountered list item.
|
|
161
|
+
let marginLeft = getMarginLeftNormalized(item);
|
|
162
|
+
// Ignore margin-left 0 style if there is no MsoList... class.
|
|
163
|
+
if (marginLeft !== undefined &&
|
|
164
|
+
parseFloat(marginLeft) == 0 &&
|
|
165
|
+
!Array.from(item.getClassNames()).find(className => className.startsWith('MsoList'))) {
|
|
166
|
+
marginLeft = undefined;
|
|
167
|
+
}
|
|
168
|
+
// List item or a following list item block.
|
|
169
|
+
if (item.hasStyle('mso-list') || marginLeft !== undefined && foundMargins.has(marginLeft)) {
|
|
170
|
+
const itemData = getListItemData(item);
|
|
101
171
|
itemLikeElements.push({
|
|
102
|
-
element:
|
|
172
|
+
element: item,
|
|
103
173
|
id: itemData.id,
|
|
104
174
|
order: itemData.order,
|
|
105
|
-
indent: itemData.indent
|
|
175
|
+
indent: itemData.indent,
|
|
176
|
+
marginLeft
|
|
106
177
|
});
|
|
178
|
+
if (marginLeft !== undefined) {
|
|
179
|
+
foundMargins.add(marginLeft);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// Clear found margins as we found block after a list.
|
|
183
|
+
else {
|
|
184
|
+
foundMargins.clear();
|
|
107
185
|
}
|
|
108
186
|
}
|
|
109
187
|
return itemLikeElements;
|
|
110
188
|
}
|
|
189
|
+
/**
|
|
190
|
+
* Whether the given element is possibly a list continuation. Previous element was wrapped into a list
|
|
191
|
+
* or the current element already is inside a list.
|
|
192
|
+
*/
|
|
193
|
+
function isListContinuation(currentItem) {
|
|
194
|
+
const previousSibling = currentItem.element.previousSibling;
|
|
195
|
+
if (!previousSibling) {
|
|
196
|
+
// If it's a li inside ul or ol like in here: https://github.com/ckeditor/ckeditor5/issues/15964.
|
|
197
|
+
return isList(currentItem.element.parent);
|
|
198
|
+
}
|
|
199
|
+
// Even with the same id the list does not have to be continuous (#43).
|
|
200
|
+
return isList(previousSibling);
|
|
201
|
+
}
|
|
202
|
+
function isList(element) {
|
|
203
|
+
return element.is('element', 'ol') || element.is('element', 'ul');
|
|
204
|
+
}
|
|
111
205
|
/**
|
|
112
206
|
* Extracts list item style from the provided CSS.
|
|
113
207
|
*
|
|
@@ -139,6 +233,14 @@ function detectListStyle(listLikeItem, stylesString) {
|
|
|
139
233
|
const listStyleRegexp = new RegExp(`@list l${listLikeItem.id}:level${listLikeItem.indent}\\s*({[^}]*)`, 'gi');
|
|
140
234
|
const listStyleTypeRegex = /mso-level-number-format:([^;]{0,100});/gi;
|
|
141
235
|
const listStartIndexRegex = /mso-level-start-at:\s{0,100}([0-9]{0,10})\s{0,100};/gi;
|
|
236
|
+
const legalStyleListRegex = new RegExp(`@list\\s+l${listLikeItem.id}:level\\d\\s*{[^{]*mso-level-text:"%\\d\\\\.`, 'gi');
|
|
237
|
+
const multiLevelNumberFormatTypeRegex = new RegExp(`@list l${listLikeItem.id}:level\\d\\s*{[^{]*mso-level-number-format:`, 'gi');
|
|
238
|
+
const legalStyleListMatch = legalStyleListRegex.exec(stylesString);
|
|
239
|
+
const multiLevelNumberFormatMatch = multiLevelNumberFormatTypeRegex.exec(stylesString);
|
|
240
|
+
// Multi level lists in Word have mso-level-number-format attribute except legal lists,
|
|
241
|
+
// so we used that. If list has legal list match and doesn't has mso-level-number-format
|
|
242
|
+
// then this is legal-list.
|
|
243
|
+
const islegalStyleList = legalStyleListMatch && !multiLevelNumberFormatMatch;
|
|
142
244
|
const listStyleMatch = listStyleRegexp.exec(stylesString);
|
|
143
245
|
let listStyleType = 'decimal'; // Decimal is default one.
|
|
144
246
|
let type = 'ol'; // <ol> is default list.
|
|
@@ -165,17 +267,25 @@ function detectListStyle(listLikeItem, stylesString) {
|
|
|
165
267
|
startIndex = parseInt(listStartIndexMatch[1]);
|
|
166
268
|
}
|
|
167
269
|
}
|
|
270
|
+
if (islegalStyleList) {
|
|
271
|
+
type = 'ol';
|
|
272
|
+
}
|
|
168
273
|
}
|
|
169
274
|
return {
|
|
170
275
|
type,
|
|
171
276
|
startIndex,
|
|
172
|
-
style: mapListStyleDefinition(listStyleType)
|
|
277
|
+
style: mapListStyleDefinition(listStyleType),
|
|
278
|
+
isLegalStyleList: islegalStyleList
|
|
173
279
|
};
|
|
174
280
|
}
|
|
175
281
|
/**
|
|
176
282
|
* Tries to extract the `list-style-type` value based on the marker element for bulleted list.
|
|
177
283
|
*/
|
|
178
284
|
function findBulletedListStyle(element) {
|
|
285
|
+
// https://github.com/ckeditor/ckeditor5/issues/15964
|
|
286
|
+
if (element.name == 'li' && element.parent.name == 'ul' && element.parent.hasAttribute('type')) {
|
|
287
|
+
return element.parent.getAttribute('type');
|
|
288
|
+
}
|
|
179
289
|
const listMarkerElement = findListMarkerNode(element);
|
|
180
290
|
if (!listMarkerElement) {
|
|
181
291
|
return null;
|
|
@@ -246,18 +356,10 @@ function mapListStyleDefinition(value) {
|
|
|
246
356
|
}
|
|
247
357
|
}
|
|
248
358
|
/**
|
|
249
|
-
* Creates
|
|
250
|
-
*
|
|
251
|
-
* @param listStyle List style object which determines the type of newly created list.
|
|
252
|
-
* Usually a result of `detectListStyle()` function.
|
|
253
|
-
* @param element Element after which list is inserted.
|
|
254
|
-
* @returns Newly created list element.
|
|
359
|
+
* Creates a new list OL/UL element.
|
|
255
360
|
*/
|
|
256
|
-
function
|
|
257
|
-
const parent = element.parent;
|
|
361
|
+
function createNewEmptyList(listStyle, writer, hasMultiLevelListPlugin) {
|
|
258
362
|
const list = writer.createElement(listStyle.type);
|
|
259
|
-
const position = parent.getChildIndex(element) + 1;
|
|
260
|
-
writer.insertChild(position, list, parent);
|
|
261
363
|
// We do not support modifying the marker for a particular list item.
|
|
262
364
|
// Set the value for the `list-style-type` property directly to the list container.
|
|
263
365
|
if (listStyle.style) {
|
|
@@ -266,21 +368,11 @@ function insertNewEmptyList(listStyle, element, writer) {
|
|
|
266
368
|
if (listStyle.startIndex && listStyle.startIndex > 1) {
|
|
267
369
|
writer.setAttribute('start', listStyle.startIndex, list);
|
|
268
370
|
}
|
|
371
|
+
if (listStyle.isLegalStyleList && hasMultiLevelListPlugin) {
|
|
372
|
+
writer.addClass('legal-list', list);
|
|
373
|
+
}
|
|
269
374
|
return list;
|
|
270
375
|
}
|
|
271
|
-
/**
|
|
272
|
-
* Transforms a given element into a semantic list item. As the function operates on a provided
|
|
273
|
-
* {module:engine/src/view/element~Element element} it will modify the view structure to which this element belongs.
|
|
274
|
-
*
|
|
275
|
-
* @param element Element which will be transformed into a list item.
|
|
276
|
-
* @returns New element to which the given one was transformed. It is
|
|
277
|
-
* inserted in place of the old element (the reference to the old element is lost due to renaming).
|
|
278
|
-
*/
|
|
279
|
-
function transformElementIntoListItem(element, writer) {
|
|
280
|
-
removeBulletElement(element, writer);
|
|
281
|
-
writer.removeStyle('text-indent', element); // #12361
|
|
282
|
-
return writer.rename('li', element);
|
|
283
|
-
}
|
|
284
376
|
/**
|
|
285
377
|
* Extracts list item information from Word specific list-like element style:
|
|
286
378
|
*
|
|
@@ -299,19 +391,23 @@ function transformElementIntoListItem(element, writer) {
|
|
|
299
391
|
* @param element Element from which style data is extracted.
|
|
300
392
|
*/
|
|
301
393
|
function getListItemData(element) {
|
|
302
|
-
const data = {};
|
|
303
394
|
const listStyle = element.getStyle('mso-list');
|
|
304
|
-
if (listStyle) {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
395
|
+
if (listStyle === undefined) {
|
|
396
|
+
return {};
|
|
397
|
+
}
|
|
398
|
+
const idMatch = listStyle.match(/(^|\s{1,100})l(\d+)/i);
|
|
399
|
+
const orderMatch = listStyle.match(/\s{0,100}lfo(\d+)/i);
|
|
400
|
+
const indentMatch = listStyle.match(/\s{0,100}level(\d+)/i);
|
|
401
|
+
if (idMatch && orderMatch && indentMatch) {
|
|
402
|
+
return {
|
|
403
|
+
id: idMatch[2],
|
|
404
|
+
order: orderMatch[1],
|
|
405
|
+
indent: parseInt(indentMatch[1])
|
|
406
|
+
};
|
|
313
407
|
}
|
|
314
|
-
return
|
|
408
|
+
return {
|
|
409
|
+
indent: 1 // Handle empty mso-list style as a marked for default list item.
|
|
410
|
+
};
|
|
315
411
|
}
|
|
316
412
|
/**
|
|
317
413
|
* Removes span with a numbering/bullet from a given element.
|
|
@@ -332,64 +428,12 @@ function removeBulletElement(element, writer) {
|
|
|
332
428
|
}
|
|
333
429
|
}
|
|
334
430
|
/**
|
|
335
|
-
*
|
|
336
|
-
* (extracted from `mso-list` style, see #getListItemData) and a previous sibling of the current item.
|
|
337
|
-
*
|
|
338
|
-
* However, it's quite easy to change the `id` attribute for nested lists in Word. It will break the list feature while pasting.
|
|
339
|
-
* Let's check also the `indent` attribute. If the difference between those two elements is equal to 1, we can assume that
|
|
340
|
-
* the `currentItem` is a beginning of the nested list because lists in CKEditor 5 always start with the `indent=0` attribute.
|
|
341
|
-
* See: https://github.com/ckeditor/ckeditor5/issues/7805.
|
|
342
|
-
*/
|
|
343
|
-
function isNewListNeeded(previousItem, currentItem) {
|
|
344
|
-
if (!previousItem) {
|
|
345
|
-
return true;
|
|
346
|
-
}
|
|
347
|
-
if (previousItem.id !== currentItem.id) {
|
|
348
|
-
// See: https://github.com/ckeditor/ckeditor5/issues/7805.
|
|
349
|
-
//
|
|
350
|
-
// * List item 1.
|
|
351
|
-
// - Nested list item 1.
|
|
352
|
-
if (currentItem.indent - previousItem.indent === 1) {
|
|
353
|
-
return false;
|
|
354
|
-
}
|
|
355
|
-
return true;
|
|
356
|
-
}
|
|
357
|
-
const previousSibling = currentItem.element.previousSibling;
|
|
358
|
-
if (!previousSibling) {
|
|
359
|
-
return true;
|
|
360
|
-
}
|
|
361
|
-
// Even with the same id the list does not have to be continuous (#43).
|
|
362
|
-
return !isList(previousSibling);
|
|
363
|
-
}
|
|
364
|
-
function isList(element) {
|
|
365
|
-
return element.is('element', 'ol') || element.is('element', 'ul');
|
|
366
|
-
}
|
|
367
|
-
/**
|
|
368
|
-
* Calculates the indentation difference between two given list items (based on the indent attribute
|
|
369
|
-
* extracted from the `mso-list` style, see #getListItemData).
|
|
431
|
+
* Returns element left margin normalized to 'px' if possible.
|
|
370
432
|
*/
|
|
371
|
-
function
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
* Finds the parent list element (ul/ol) of a given list element with indentation level lower by a given value.
|
|
376
|
-
*
|
|
377
|
-
* @param listElement List element from which to start looking for a parent list.
|
|
378
|
-
* @param indentationDifference Indentation difference between lists.
|
|
379
|
-
* @returns Found list element with indentation level lower by a given value.
|
|
380
|
-
*/
|
|
381
|
-
function findParentListAtLevel(listElement, indentationDifference) {
|
|
382
|
-
const ancestors = listElement.getAncestors({ parentFirst: true });
|
|
383
|
-
let parentList = null;
|
|
384
|
-
let levelChange = 0;
|
|
385
|
-
for (const ancestor of ancestors) {
|
|
386
|
-
if (ancestor.is('element', 'ul') || ancestor.is('element', 'ol')) {
|
|
387
|
-
levelChange++;
|
|
388
|
-
}
|
|
389
|
-
if (levelChange === indentationDifference) {
|
|
390
|
-
parentList = ancestor;
|
|
391
|
-
break;
|
|
392
|
-
}
|
|
433
|
+
function getMarginLeftNormalized(element) {
|
|
434
|
+
const value = element.getStyle('margin-left');
|
|
435
|
+
if (value === undefined || value.endsWith('px')) {
|
|
436
|
+
return value;
|
|
393
437
|
}
|
|
394
|
-
return
|
|
438
|
+
return convertCssLengthToPx(value);
|
|
395
439
|
}
|
|
@@ -28,7 +28,9 @@ export default function removeMSAttributes(documentFragment) {
|
|
|
28
28
|
writer.removeStyle(styleName, item);
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
-
if (item.is('element', 'w:sdt')
|
|
31
|
+
if (item.is('element', 'w:sdt') ||
|
|
32
|
+
item.is('element', 'w:sdtpr') && item.isEmpty ||
|
|
33
|
+
item.is('element', 'o:p') && item.isEmpty) {
|
|
32
34
|
elementsToUnwrap.push(item);
|
|
33
35
|
}
|
|
34
36
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @module paste-from-office/filters/utils
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Normalizes CSS length value to 'px'.
|
|
10
|
+
*
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
export declare function convertCssLengthToPx(value: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Returns true for value with 'px' unit.
|
|
16
|
+
*
|
|
17
|
+
* @internal
|
|
18
|
+
*/
|
|
19
|
+
export declare function isPx(value?: string): value is string;
|
|
20
|
+
/**
|
|
21
|
+
* Returns a rounded 'px' value.
|
|
22
|
+
*
|
|
23
|
+
* @internal
|
|
24
|
+
*/
|
|
25
|
+
export declare function toPx(value: number): string;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @module paste-from-office/filters/utils
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Normalizes CSS length value to 'px'.
|
|
10
|
+
*
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
export function convertCssLengthToPx(value) {
|
|
14
|
+
const numericValue = parseFloat(value);
|
|
15
|
+
if (value.endsWith('pt')) {
|
|
16
|
+
// 1pt = 1in / 72
|
|
17
|
+
return toPx(numericValue * 96 / 72);
|
|
18
|
+
}
|
|
19
|
+
else if (value.endsWith('pc')) {
|
|
20
|
+
// 1pc = 12pt = 1in / 6.
|
|
21
|
+
return toPx(numericValue * 12 * 96 / 72);
|
|
22
|
+
}
|
|
23
|
+
else if (value.endsWith('in')) {
|
|
24
|
+
// 1in = 2.54cm = 96px
|
|
25
|
+
return toPx(numericValue * 96);
|
|
26
|
+
}
|
|
27
|
+
else if (value.endsWith('cm')) {
|
|
28
|
+
// 1cm = 96px / 2.54
|
|
29
|
+
return toPx(numericValue * 96 / 2.54);
|
|
30
|
+
}
|
|
31
|
+
else if (value.endsWith('mm')) {
|
|
32
|
+
// 1mm = 1cm / 10
|
|
33
|
+
return toPx(numericValue / 10 * 96 / 2.54);
|
|
34
|
+
}
|
|
35
|
+
return value;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Returns true for value with 'px' unit.
|
|
39
|
+
*
|
|
40
|
+
* @internal
|
|
41
|
+
*/
|
|
42
|
+
export function isPx(value) {
|
|
43
|
+
return value !== undefined && value.endsWith('px');
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Returns a rounded 'px' value.
|
|
47
|
+
*
|
|
48
|
+
* @internal
|
|
49
|
+
*/
|
|
50
|
+
export function toPx(value) {
|
|
51
|
+
return value.toFixed(2).replace(/\.?0+$/, '') + 'px';
|
|
52
|
+
}
|
package/src/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @module paste-from-office
|
|
7
7
|
*/
|
|
8
8
|
export { default as PasteFromOffice } from './pastefromoffice.js';
|
|
9
|
-
export
|
|
9
|
+
export { Normalizer, type NormalizerData } from './normalizer.js';
|
|
10
10
|
export { default as MSWordNormalizer } from './normalizers/mswordnormalizer.js';
|
|
11
11
|
export { parseHtml } from './filters/parse.js';
|
|
12
12
|
import './augmentation.js';
|
|
@@ -9,12 +9,13 @@ import type { Normalizer, NormalizerData } from '../normalizer.js';
|
|
|
9
9
|
*/
|
|
10
10
|
export default class MSWordNormalizer implements Normalizer {
|
|
11
11
|
readonly document: ViewDocument;
|
|
12
|
+
readonly hasMultiLevelListPlugin: boolean;
|
|
12
13
|
/**
|
|
13
14
|
* Creates a new `MSWordNormalizer` instance.
|
|
14
15
|
*
|
|
15
16
|
* @param document View document.
|
|
16
17
|
*/
|
|
17
|
-
constructor(document: ViewDocument);
|
|
18
|
+
constructor(document: ViewDocument, hasMultiLevelListPlugin?: boolean);
|
|
18
19
|
/**
|
|
19
20
|
* @inheritDoc
|
|
20
21
|
*/
|
|
@@ -19,8 +19,9 @@ export default class MSWordNormalizer {
|
|
|
19
19
|
*
|
|
20
20
|
* @param document View document.
|
|
21
21
|
*/
|
|
22
|
-
constructor(document) {
|
|
22
|
+
constructor(document, hasMultiLevelListPlugin = false) {
|
|
23
23
|
this.document = document;
|
|
24
|
+
this.hasMultiLevelListPlugin = hasMultiLevelListPlugin;
|
|
24
25
|
}
|
|
25
26
|
/**
|
|
26
27
|
* @inheritDoc
|
|
@@ -33,7 +34,7 @@ export default class MSWordNormalizer {
|
|
|
33
34
|
*/
|
|
34
35
|
execute(data) {
|
|
35
36
|
const { body: documentFragment, stylesString } = data._parsedData;
|
|
36
|
-
transformListItemLikeElementsIntoLists(documentFragment, stylesString);
|
|
37
|
+
transformListItemLikeElementsIntoLists(documentFragment, stylesString, this.hasMultiLevelListPlugin);
|
|
37
38
|
replaceImagesSourceWithBase64(documentFragment, data.dataTransfer.getData('text/rtf'));
|
|
38
39
|
removeMSAttributes(documentFragment);
|
|
39
40
|
data.content = documentFragment;
|
package/src/pastefromoffice.js
CHANGED
|
@@ -45,7 +45,8 @@ export default class PasteFromOffice extends Plugin {
|
|
|
45
45
|
const clipboardPipeline = editor.plugins.get('ClipboardPipeline');
|
|
46
46
|
const viewDocument = editor.editing.view.document;
|
|
47
47
|
const normalizers = [];
|
|
48
|
-
|
|
48
|
+
const hasMultiLevelListPlugin = this.editor.plugins.has('MultiLevelList');
|
|
49
|
+
normalizers.push(new MSWordNormalizer(viewDocument, hasMultiLevelListPlugin));
|
|
49
50
|
normalizers.push(new GoogleDocsNormalizer(viewDocument));
|
|
50
51
|
normalizers.push(new GoogleSheetsNormalizer(viewDocument));
|
|
51
52
|
clipboardPipeline.on('inputTransformation', (evt, data) => {
|
package/dist/content-index.css
DELETED
package/dist/editor-index.css
DELETED
package/dist/index.css
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
7
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
8
|
-
*/
|
|
9
|
-
import type { PasteFromOffice } from './index.js';
|
|
10
|
-
declare module '@ckeditor/ckeditor5-core' {
|
|
11
|
-
interface PluginsMap {
|
|
12
|
-
[PasteFromOffice.pluginName]: PasteFromOffice;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
7
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* @module paste-from-office/filters/br
|
|
11
|
-
*/
|
|
12
|
-
import { type UpcastWriter, type ViewDocumentFragment } from 'ckeditor5/src/engine.js';
|
|
13
|
-
/**
|
|
14
|
-
* Transforms `<br>` elements that are siblings to some block element into a paragraphs.
|
|
15
|
-
*
|
|
16
|
-
* @param documentFragment The view structure to be transformed.
|
|
17
|
-
*/
|
|
18
|
-
export default function transformBlockBrsToParagraphs(documentFragment: ViewDocumentFragment, writer: UpcastWriter): void;
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
7
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* @module paste-from-office/filters/image
|
|
11
|
-
*/
|
|
12
|
-
import { type ViewDocumentFragment } from 'ckeditor5/src/engine.js';
|
|
13
|
-
/**
|
|
14
|
-
* Replaces source attribute of all `<img>` elements representing regular
|
|
15
|
-
* images (not the Word shapes) with inlined base64 image representation extracted from RTF or Blob data.
|
|
16
|
-
*
|
|
17
|
-
* @param documentFragment Document fragment on which transform images.
|
|
18
|
-
* @param rtfData The RTF data from which images representation will be used.
|
|
19
|
-
*/
|
|
20
|
-
export declare function replaceImagesSourceWithBase64(documentFragment: ViewDocumentFragment, rtfData: string): void;
|
|
21
|
-
/**
|
|
22
|
-
* Converts given HEX string to base64 representation.
|
|
23
|
-
*
|
|
24
|
-
* @internal
|
|
25
|
-
* @param hexString The HEX string to be converted.
|
|
26
|
-
* @returns Base64 representation of a given HEX string.
|
|
27
|
-
*/
|
|
28
|
-
export declare function _convertHexToBase64(hexString: string): string;
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
7
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* @module paste-from-office/filters/list
|
|
11
|
-
*/
|
|
12
|
-
import { UpcastWriter, type ViewDocumentFragment } from 'ckeditor5/src/engine.js';
|
|
13
|
-
/**
|
|
14
|
-
* Transforms Word specific list-like elements to the semantic HTML lists.
|
|
15
|
-
*
|
|
16
|
-
* Lists in Word are represented by block elements with special attributes like:
|
|
17
|
-
*
|
|
18
|
-
* ```xml
|
|
19
|
-
* <p class=MsoListParagraphCxSpFirst style='mso-list:l1 level1 lfo1'>...</p> // Paragraph based list.
|
|
20
|
-
* <h1 style='mso-list:l0 level1 lfo1'>...</h1> // Heading 1 based list.
|
|
21
|
-
* ```
|
|
22
|
-
*
|
|
23
|
-
* @param documentFragment The view structure to be transformed.
|
|
24
|
-
* @param stylesString Styles from which list-like elements styling will be extracted.
|
|
25
|
-
*/
|
|
26
|
-
export declare function transformListItemLikeElementsIntoLists(documentFragment: ViewDocumentFragment, stylesString: string): void;
|
|
27
|
-
/**
|
|
28
|
-
* Removes paragraph wrapping content inside a list item.
|
|
29
|
-
*/
|
|
30
|
-
export declare function unwrapParagraphInListItem(documentFragment: ViewDocumentFragment, writer: UpcastWriter): void;
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
7
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* @module paste-from-office/filters/parse
|
|
11
|
-
*/
|
|
12
|
-
import { type StylesProcessor, type ViewDocumentFragment } from 'ckeditor5/src/engine.js';
|
|
13
|
-
/**
|
|
14
|
-
* Parses the provided HTML extracting contents of `<body>` and `<style>` tags.
|
|
15
|
-
*
|
|
16
|
-
* @param htmlString HTML string to be parsed.
|
|
17
|
-
*/
|
|
18
|
-
export declare function parseHtml(htmlString: string, stylesProcessor: StylesProcessor): ParseHtmlResult;
|
|
19
|
-
/**
|
|
20
|
-
* The result of {@link ~parseHtml}.
|
|
21
|
-
*/
|
|
22
|
-
export interface ParseHtmlResult {
|
|
23
|
-
/**
|
|
24
|
-
* Parsed body content as a traversable structure.
|
|
25
|
-
*/
|
|
26
|
-
body: ViewDocumentFragment;
|
|
27
|
-
/**
|
|
28
|
-
* Entire body content as a string.
|
|
29
|
-
*/
|
|
30
|
-
bodyString: string;
|
|
31
|
-
/**
|
|
32
|
-
* Array of native `CSSStyleSheet` objects, each representing separate `style` tag from the source HTML.
|
|
33
|
-
*/
|
|
34
|
-
styles: Array<CSSStyleSheet>;
|
|
35
|
-
/**
|
|
36
|
-
* All `style` tags contents combined in the order of occurrence into one string.
|
|
37
|
-
*/
|
|
38
|
-
stylesString: string;
|
|
39
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
7
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* @module paste-from-office/filters/removeboldwrapper
|
|
11
|
-
*/
|
|
12
|
-
import type { UpcastWriter, ViewDocumentFragment } from 'ckeditor5/src/engine.js';
|
|
13
|
-
/**
|
|
14
|
-
* Removes the `<b>` tag wrapper added by Google Docs to a copied content.
|
|
15
|
-
*
|
|
16
|
-
* @param documentFragment element `data.content` obtained from clipboard
|
|
17
|
-
*/
|
|
18
|
-
export default function removeBoldWrapper(documentFragment: ViewDocumentFragment, writer: UpcastWriter): void;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
7
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* @module paste-from-office/filters/removegooglesheetstag
|
|
11
|
-
*/
|
|
12
|
-
import type { UpcastWriter, ViewDocumentFragment } from 'ckeditor5/src/engine.js';
|
|
13
|
-
/**
|
|
14
|
-
* Removes the `<google-sheets-html-origin>` tag wrapper added by Google Sheets to a copied content.
|
|
15
|
-
*
|
|
16
|
-
* @param documentFragment element `data.content` obtained from clipboard
|
|
17
|
-
*/
|
|
18
|
-
export default function removeGoogleSheetsTag(documentFragment: ViewDocumentFragment, writer: UpcastWriter): void;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
7
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* @module paste-from-office/filters/removeinvalidtablewidth
|
|
11
|
-
*/
|
|
12
|
-
import type { UpcastWriter, ViewDocumentFragment } from 'ckeditor5/src/engine.js';
|
|
13
|
-
/**
|
|
14
|
-
* Removes the `width:0px` style from table pasted from Google Sheets.
|
|
15
|
-
*
|
|
16
|
-
* @param documentFragment element `data.content` obtained from clipboard
|
|
17
|
-
*/
|
|
18
|
-
export default function removeInvalidTableWidth(documentFragment: ViewDocumentFragment, writer: UpcastWriter): void;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
7
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* @module paste-from-office/filters/removemsattributes
|
|
11
|
-
*/
|
|
12
|
-
import { type ViewDocumentFragment } from 'ckeditor5/src/engine.js';
|
|
13
|
-
/**
|
|
14
|
-
* Cleanup MS attributes like styles, attributes and elements.
|
|
15
|
-
*
|
|
16
|
-
* @param documentFragment element `data.content` obtained from clipboard.
|
|
17
|
-
*/
|
|
18
|
-
export default function removeMSAttributes(documentFragment: ViewDocumentFragment): void;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
7
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* @module paste-from-office/filters/removestyleblock
|
|
11
|
-
*/
|
|
12
|
-
import type { UpcastWriter, ViewDocumentFragment } from 'ckeditor5/src/engine.js';
|
|
13
|
-
/**
|
|
14
|
-
* Removes `<style>` block added by Google Sheets to a copied content.
|
|
15
|
-
*
|
|
16
|
-
* @param documentFragment element `data.content` obtained from clipboard
|
|
17
|
-
*/
|
|
18
|
-
export default function removeStyleBlock(documentFragment: ViewDocumentFragment, writer: UpcastWriter): void;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
7
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* @module paste-from-office/filters/removexmlns
|
|
11
|
-
*/
|
|
12
|
-
import type { UpcastWriter, ViewDocumentFragment } from 'ckeditor5/src/engine.js';
|
|
13
|
-
/**
|
|
14
|
-
* Removes the `xmlns` attribute from table pasted from Google Sheets.
|
|
15
|
-
*
|
|
16
|
-
* @param documentFragment element `data.content` obtained from clipboard
|
|
17
|
-
*/
|
|
18
|
-
export default function removeXmlns(documentFragment: ViewDocumentFragment, writer: UpcastWriter): void;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
7
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* @module paste-from-office/filters/space
|
|
11
|
-
*/
|
|
12
|
-
/**
|
|
13
|
-
* Replaces last space preceding elements closing tag with ` `. Such operation prevents spaces from being removed
|
|
14
|
-
* during further DOM/View processing (see especially {@link module:engine/view/domconverter~DomConverter#_processDomInlineNodes}).
|
|
15
|
-
* This method also takes into account Word specific `<o:p></o:p>` empty tags.
|
|
16
|
-
* Additionally multiline sequences of spaces and new lines between tags are removed (see #39 and #40).
|
|
17
|
-
*
|
|
18
|
-
* @param htmlString HTML string in which spacing should be normalized.
|
|
19
|
-
* @returns Input HTML with spaces normalized.
|
|
20
|
-
*/
|
|
21
|
-
export declare function normalizeSpacing(htmlString: string): string;
|
|
22
|
-
/**
|
|
23
|
-
* Normalizes spacing in special Word `spacerun spans` (`<span style='mso-spacerun:yes'>\s+</span>`) by replacing
|
|
24
|
-
* all spaces with ` ` pairs. This prevents spaces from being removed during further DOM/View processing
|
|
25
|
-
* (see especially {@link module:engine/view/domconverter~DomConverter#_processDomInlineNodes}).
|
|
26
|
-
*
|
|
27
|
-
* @param htmlDocument Native `Document` object in which spacing should be normalized.
|
|
28
|
-
*/
|
|
29
|
-
export declare function normalizeSpacerunSpans(htmlDocument: Document): void;
|
package/dist/types/index.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
7
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* @module paste-from-office
|
|
11
|
-
*/
|
|
12
|
-
export { default as PasteFromOffice } from './pastefromoffice.js';
|
|
13
|
-
export type { Normalizer, NormalizerData } from './normalizer.js';
|
|
14
|
-
export { default as MSWordNormalizer } from './normalizers/mswordnormalizer.js';
|
|
15
|
-
export { parseHtml } from './filters/parse.js';
|
|
16
|
-
import './augmentation.js';
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
7
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* @module paste-from-office/normalizer
|
|
11
|
-
*/
|
|
12
|
-
import type { ClipboardInputTransformationData } from 'ckeditor5/src/clipboard.js';
|
|
13
|
-
import type { ParseHtmlResult } from './filters/parse.js';
|
|
14
|
-
/**
|
|
15
|
-
* Interface defining a content transformation pasted from an external editor.
|
|
16
|
-
*
|
|
17
|
-
* Normalizers are registered by the {@link module:paste-from-office/pastefromoffice~PasteFromOffice} plugin and run on
|
|
18
|
-
* {@link module:clipboard/clipboardpipeline~ClipboardPipeline#event:inputTransformation inputTransformation event}.
|
|
19
|
-
* They detect environment-specific quirks and transform it into a form compatible with other CKEditor features.
|
|
20
|
-
*/
|
|
21
|
-
export interface Normalizer {
|
|
22
|
-
/**
|
|
23
|
-
* Must return `true` if the `htmlString` contains content which this normalizer can transform.
|
|
24
|
-
*/
|
|
25
|
-
isActive(htmlString: string): boolean;
|
|
26
|
-
/**
|
|
27
|
-
* Executes the normalization of a given data.
|
|
28
|
-
*/
|
|
29
|
-
execute(data: NormalizerData): void;
|
|
30
|
-
}
|
|
31
|
-
export interface NormalizerData extends ClipboardInputTransformationData {
|
|
32
|
-
_isTransformedWithPasteFromOffice?: boolean;
|
|
33
|
-
_parsedData: ParseHtmlResult;
|
|
34
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
7
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* @module paste-from-office/normalizers/googledocsnormalizer
|
|
11
|
-
*/
|
|
12
|
-
import { type ViewDocument } from 'ckeditor5/src/engine.js';
|
|
13
|
-
import type { Normalizer, NormalizerData } from '../normalizer.js';
|
|
14
|
-
/**
|
|
15
|
-
* Normalizer for the content pasted from Google Docs.
|
|
16
|
-
*/
|
|
17
|
-
export default class GoogleDocsNormalizer implements Normalizer {
|
|
18
|
-
readonly document: ViewDocument;
|
|
19
|
-
/**
|
|
20
|
-
* Creates a new `GoogleDocsNormalizer` instance.
|
|
21
|
-
*
|
|
22
|
-
* @param document View document.
|
|
23
|
-
*/
|
|
24
|
-
constructor(document: ViewDocument);
|
|
25
|
-
/**
|
|
26
|
-
* @inheritDoc
|
|
27
|
-
*/
|
|
28
|
-
isActive(htmlString: string): boolean;
|
|
29
|
-
/**
|
|
30
|
-
* @inheritDoc
|
|
31
|
-
*/
|
|
32
|
-
execute(data: NormalizerData): void;
|
|
33
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
7
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* @module paste-from-office/normalizers/googlesheetsnormalizer
|
|
11
|
-
*/
|
|
12
|
-
import { type ViewDocument } from 'ckeditor5/src/engine.js';
|
|
13
|
-
import type { Normalizer, NormalizerData } from '../normalizer.js';
|
|
14
|
-
/**
|
|
15
|
-
* Normalizer for the content pasted from Google Sheets.
|
|
16
|
-
*/
|
|
17
|
-
export default class GoogleSheetsNormalizer implements Normalizer {
|
|
18
|
-
readonly document: ViewDocument;
|
|
19
|
-
/**
|
|
20
|
-
* Creates a new `GoogleSheetsNormalizer` instance.
|
|
21
|
-
*
|
|
22
|
-
* @param document View document.
|
|
23
|
-
*/
|
|
24
|
-
constructor(document: ViewDocument);
|
|
25
|
-
/**
|
|
26
|
-
* @inheritDoc
|
|
27
|
-
*/
|
|
28
|
-
isActive(htmlString: string): boolean;
|
|
29
|
-
/**
|
|
30
|
-
* @inheritDoc
|
|
31
|
-
*/
|
|
32
|
-
execute(data: NormalizerData): void;
|
|
33
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
7
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
8
|
-
*/
|
|
9
|
-
import type { ViewDocument } from 'ckeditor5/src/engine.js';
|
|
10
|
-
import type { Normalizer, NormalizerData } from '../normalizer.js';
|
|
11
|
-
/**
|
|
12
|
-
* Normalizer for the content pasted from Microsoft Word.
|
|
13
|
-
*/
|
|
14
|
-
export default class MSWordNormalizer implements Normalizer {
|
|
15
|
-
readonly document: ViewDocument;
|
|
16
|
-
/**
|
|
17
|
-
* Creates a new `MSWordNormalizer` instance.
|
|
18
|
-
*
|
|
19
|
-
* @param document View document.
|
|
20
|
-
*/
|
|
21
|
-
constructor(document: ViewDocument);
|
|
22
|
-
/**
|
|
23
|
-
* @inheritDoc
|
|
24
|
-
*/
|
|
25
|
-
isActive(htmlString: string): boolean;
|
|
26
|
-
/**
|
|
27
|
-
* @inheritDoc
|
|
28
|
-
*/
|
|
29
|
-
execute(data: NormalizerData): void;
|
|
30
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
7
|
-
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* @module paste-from-office/pastefromoffice
|
|
11
|
-
*/
|
|
12
|
-
import { Plugin } from 'ckeditor5/src/core.js';
|
|
13
|
-
import { ClipboardPipeline } from 'ckeditor5/src/clipboard.js';
|
|
14
|
-
/**
|
|
15
|
-
* The Paste from Office plugin.
|
|
16
|
-
*
|
|
17
|
-
* This plugin handles content pasted from Office apps and transforms it (if necessary)
|
|
18
|
-
* to a valid structure which can then be understood by the editor features.
|
|
19
|
-
*
|
|
20
|
-
* Transformation is made by a set of predefined {@link module:paste-from-office/normalizer~Normalizer normalizers}.
|
|
21
|
-
* This plugin includes following normalizers:
|
|
22
|
-
* * {@link module:paste-from-office/normalizers/mswordnormalizer~MSWordNormalizer Microsoft Word normalizer}
|
|
23
|
-
* * {@link module:paste-from-office/normalizers/googledocsnormalizer~GoogleDocsNormalizer Google Docs normalizer}
|
|
24
|
-
*
|
|
25
|
-
* For more information about this feature check the {@glink api/paste-from-office package page}.
|
|
26
|
-
*/
|
|
27
|
-
export default class PasteFromOffice extends Plugin {
|
|
28
|
-
/**
|
|
29
|
-
* @inheritDoc
|
|
30
|
-
*/
|
|
31
|
-
static get pluginName(): "PasteFromOffice";
|
|
32
|
-
/**
|
|
33
|
-
* @inheritDoc
|
|
34
|
-
*/
|
|
35
|
-
static get requires(): readonly [typeof ClipboardPipeline];
|
|
36
|
-
/**
|
|
37
|
-
* @inheritDoc
|
|
38
|
-
*/
|
|
39
|
-
init(): void;
|
|
40
|
-
}
|