@ckeditor/ckeditor5-paste-from-office 45.2.1-alpha.9 → 46.0.0-alpha.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/dist/index.js +48 -23
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/src/filters/bookmark.d.ts +4 -2
- package/src/filters/bookmark.js +3 -1
- package/src/filters/br.d.ts +3 -2
- package/src/filters/br.js +4 -3
- package/src/filters/image.d.ts +1 -0
- package/src/filters/image.js +3 -2
- package/src/filters/list.d.ts +5 -2
- package/src/filters/list.js +10 -4
- package/src/filters/parse.d.ts +3 -3
- package/src/filters/parse.js +4 -4
- package/src/filters/removeboldwrapper.d.ts +3 -2
- package/src/filters/removeboldwrapper.js +2 -1
- package/src/filters/removegooglesheetstag.d.ts +3 -2
- package/src/filters/removegooglesheetstag.js +2 -1
- package/src/filters/removeinvalidtablewidth.d.ts +3 -2
- package/src/filters/removeinvalidtablewidth.js +2 -1
- package/src/filters/removemsattributes.d.ts +2 -1
- package/src/filters/removemsattributes.js +4 -3
- package/src/filters/removestyleblock.d.ts +3 -2
- package/src/filters/removestyleblock.js +2 -1
- package/src/filters/removexmlns.d.ts +3 -2
- package/src/filters/removexmlns.js +2 -1
- package/src/filters/space.d.ts +4 -2
- package/src/filters/space.js +6 -3
- package/src/filters/table.d.ts +4 -2
- package/src/filters/table.js +3 -1
- package/src/index.d.ts +19 -4
- package/src/index.js +18 -3
- package/src/normalizer.d.ts +5 -5
- package/src/normalizers/googledocsnormalizer.d.ts +5 -3
- package/src/normalizers/googledocsnormalizer.js +7 -5
- package/src/normalizers/googlesheetsnormalizer.d.ts +5 -3
- package/src/normalizers/googlesheetsnormalizer.js +9 -7
- package/src/normalizers/mswordnormalizer.d.ts +4 -4
- package/src/normalizers/mswordnormalizer.js +7 -7
- package/src/pastefromoffice.d.ts +3 -3
- package/src/pastefromoffice.js +9 -9
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
3
|
* For licensing, see LICENSE.md.
|
|
4
|
-
*/(()=>{var e={237:e=>{"use strict";e.exports=CKEditor5.dll},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")}},t={};function n(s){var r=t[s];if(void 0!==r)return r.exports;var i=t[s]={exports:{}};return e[s](i,i.exports,n),i.exports}n.d=(e,t)=>{for(var s in t)n.o(t,s)&&!n.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:t[s]})},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 s={};(()=>{"use strict";n.r(s),n.d(s,{MSWordNormalizer:()=>w,PasteFromOffice:()=>$,parseHtml:()=>P});var e=n(782),t=n(331);var r=n(783);function i(e){const t=parseFloat(e);return e.endsWith("pt")?l(96*t/72):e.endsWith("pc")?l(12*t*96/72):e.endsWith("in")?l(96*t):e.endsWith("cm")?l(96*t/2.54):e.endsWith("mm")?l(t/10*96/2.54):e}function o(e){return void 0!==e&&e.endsWith("px")}function l(e){return Math.round(e)+"px"}function c(e,t,n){if(!e.childCount)return;const s=new r.UpcastWriter(e.document),i=function(e,t){const n=t.createRangeIn(e),s=[],r=new Set;for(const e of n.getItems()){if(!e.is("element")||!e.name.match(/^(p|h\d+|li|div)$/))continue;let t=h(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&&r.has(t)){const n=p(e);s.push({element:e,id:n.id,order:n.order,indent:n.indent,marginLeft:t}),void 0!==t&&r.add(t)}else r.clear()}return s}(e,s);if(!i.length)return;const c={},m=[];for(const e of i)if(void 0!==e.indent){a(e)||(m.length=0);const r=`${e.id}:${e.indent}`,i=Math.min(e.indent-1,m.length);if(i<m.length&&m[i].id!==e.id&&(m.length=i),i<m.length-1)m.length=i+1;else{const a=u(e,t);if(i>m.length-1||m[i].listElement.name!=a.type){0==i&&"ol"==a.type&&void 0!==e.id&&c[r]&&(a.startIndex=c[r]);const t=f(a,s,n);if(o(e.marginLeft)&&(0==i||o(m[i-1].marginLeft))){let n=e.marginLeft;i>0&&(n=l(parseFloat(n)-parseFloat(m[i-1].marginLeft))),s.setStyle("padding-left",n,t)}if(0==m.length){const n=e.element.parent,r=n.getChildIndex(e.element)+1;s.insertChild(r,t,n)}else{const e=m[i-1].listItemElements;s.appendChild(t,e[e.length-1])}m[i]={...e,listElement:t,listItemElements:[]},0==i&&void 0!==e.id&&(c[r]=a.startIndex||1)}}const d="li"==e.element.name?e.element:s.createElement("li");s.appendChild(d,m[i].listElement),m[i].listItemElements.push(d),0==i&&void 0!==e.id&&c[r]++,e.element!=d&&s.appendChild(e.element,d),g(e.element,s),s.removeStyle("text-indent",e.element),s.removeStyle("margin-left",e.element)}else{const t=m.find(t=>t.marginLeft==e.marginLeft);if(t){const n=t.listItemElements;s.appendChild(e.element,n[n.length-1]),s.removeStyle("margin-left",e.element)}else m.length=0}}function a(e){const t=e.element.previousSibling;return m(t||e.element.parent)}function m(e){return e.is("element","ol")||e.is("element","ul")}function u(e,t){const n=new RegExp(`@list l${e.id}:level${e.indent}\\s*({[^}]*)`,"gi"),s=/mso-level-number-format:([^;]{0,100});/gi,r=/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 u="decimal",f="ol",p=null;if(m&&m[1]){const t=s.exec(m[1]);if(t&&t[1]&&(u=t[1].trim(),f="bullet"!==u&&"image"!==u?"ol":"ul"),"bullet"===u){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&&(u=t)}else{const e=r.exec(m[1]);e&&e[1]&&(p=parseInt(e[1]))}a&&(f="ol")}return{type:f,startIndex:p,style:d(u),isLegalStyleList:a}}function d(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 f(e,t,n){const s=t.createElement(e.type);return e.style&&t.setStyle("list-style-type",e.style,s),e.startIndex&&e.startIndex>1&&t.setAttribute("start",e.startIndex,s),e.isLegalStyleList&&n&&t.addClass("legal-list",s),s}function p(e){const t=e.getStyle("mso-list");if(void 0===t)return{};const n=t.match(/(^|\s{1,100})l(\d+)/i),s=t.match(/\s{0,100}lfo(\d+)/i),r=t.match(/\s{0,100}level(\d+)/i);return n&&s&&r?{id:n[2],order:s[1],indent:parseInt(r[1])}:{indent:1}}function g(e,t){const n=new r.Matcher({name:"span",styles:{"mso-list":"Ignore"}}),s=t.createRangeIn(e);for(const e of s)"elementStart"===e.type&&n.match(e.item)&&t.remove(e.item)}function h(e){const t=e.getStyle("margin-left");return void 0===t||t.endsWith("px")?t:i(t)}function y(e,t){if(!e.childCount)return;const n=new r.UpcastWriter(e.document),s=function(e,t){const n=t.createRangeIn(e),s=new r.Matcher({name:/v:(.+)/}),i=[];for(const e of n){if("elementStart"!=e.type)continue;const t=e.item,n=t.previousSibling,r=n&&n.is("element")?n.name:null,o=["Chart"],l=s.match(t),c=t.getAttribute("o:gfxdata"),a="v:shapetype"===r,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 s=n.createRangeIn(t),i=new r.Matcher({name:"img"}),o=[];for(const t of s)if(t.item.is("element")&&i.match(t.item)){const n=t.item,s=n.getAttribute("v:shapes")?n.getAttribute("v:shapes").split(" "):[];s.length&&s.every(t=>e.indexOf(t)>-1)?o.push(n):n.getAttribute("src")||o.push(n)}for(const e of o)n.remove(e)}(s,e,n),function(e,t,n){const s=n.createRangeIn(t),r=[];for(const t of s)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)||r.push(t.item)}for(const e of r){const t={src:o(e)};e.hasAttribute("alt")&&(t.alt=e.getAttribute("alt"));const s=n.createElement("img",t);n.insertChild(e.index+1,s,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")}}(s,e,n),function(e,t){const n=t.createRangeIn(e),s=new r.Matcher({name:/v:(.+)/}),i=[];for(const e of n)"elementStart"==e.type&&s.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),s=new r.Matcher({name:"img"}),i=[];let o=0;for(const e of n)e.item.is("element")&&s.match(e.item)&&(e.item.getAttribute("src").startsWith("file://")&&i.push({element:e.item,imageIndex:o}),o++);return i}(e,n);i.length&&function(e,t,n){for(let s=0;s<e.length;s++){const{element:r,imageIndex:i}=e[s],o=t[i];if(o){const e=`data:${o.type};base64,${b(o.hex)}`;n.setAttribute("src",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"),s=e.match(n),r=[];if(s)for(const e of s){let n=!1;e.includes("\\pngblip")?n="image/png":e.includes("\\jpegblip")&&(n="image/jpeg"),n&&r.push({hex:e.replace(t,"").replace(/[^\da-fA-F]/g,""),type:n})}return r}(t),n)}function b(e){return btoa(e.match(/\w{2}/g).map(e=>String.fromCharCode(parseInt(e,16))).join(""))}const v=/<meta\s*name="?generator"?\s*content="?microsoft\s*word\s*\d+"?\/?>/i,x=/xmlns:o="urn:schemas-microsoft-com/i;class w{document;hasMultiLevelListPlugin;constructor(e,t=!1){this.document=e,this.hasMultiLevelListPlugin=t}isActive(e){return v.test(e)||x.test(e)}execute(e){const t=new r.UpcastWriter(this.document),{body:n,stylesString:s}=e._parsedData;!function(e,t){const n=[];for(const s of t.createRangeIn(e)){const e=s.item;e.is("element","a")&&!e.hasAttribute("href")&&(e.hasAttribute("id")||e.hasAttribute("name"))&&n.push(e)}for(const e of n){const n=e.parent.getChildIndex(e)+1,s=e.getChildren();t.insertChild(n,s,e.parent)}}(n,t),c(n,s,this.hasMultiLevelListPlugin),y(n,e.dataTransfer.getData("text/rtf")),function(e,t){for(const n of t.createRangeIn(e).getItems()){if(!n.is("element","table")&&!n.is("element","td")&&!n.is("element","th"))continue;const e=["left","top","right","bottom"];if(e.every(e=>!n.hasStyle(`border-${e}-style`)))t.setStyle("border-style","none",n);else for(const s of e)n.hasStyle(`border-${s}-style`)||t.setStyle(`border-${s}-style`,"none",n);const s=["width","height",...e.map(e=>`border-${e}-width`),...e.map(e=>`padding-${e}`)];for(const e of s)n.hasStyle(e)&&t.setStyle(e,i(n.getStyle(e)),n)}}(n,t),function(e){const t=[],n=new r.UpcastWriter(e.document);for(const{item:s}of n.createRangeIn(e))if(s.is("element")){for(const e of s.getClassNames())/\bmso/gi.exec(e)&&n.removeClass(e,s);for(const e of s.getStyleNames())/\bmso/gi.exec(e)&&n.removeStyle(e,s);(s.is("element","w:sdt")||s.is("element","w:sdtpr")&&s.isEmpty||s.is("element","o:p")&&s.isEmpty)&&t.push(s)}for(const e of t){const t=e.parent,s=t.getChildIndex(e);n.insertChild(s,e.getChildren(),t),n.remove(e)}}(n),e.content=n}}function C(e,t,n,{blockElements:s,inlineObjectElements:r}){let i=n.createPositionAt(e,"forward"==t?"after":"before");return i=i.getLastMatchingPosition(({item:e})=>e.is("element")&&!s.includes(e.name)&&!r.includes(e.name),{direction:t}),"forward"==t?i.nodeAfter:i.nodeBefore}function S(e,t){return!!e&&e.is("element")&&t.includes(e.name)}const A=/id=("|')docs-internal-guid-[-0-9a-f]+("|')/i;class I{document;constructor(e){this.document=e}isActive(e){return A.test(e)}execute(e){const t=new r.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 s=e.getChildIndex(n);t.remove(n),t.insertChild(s,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 r.ViewDocument(t.document.stylesProcessor),s=new r.DomConverter(n,{renderingMode:"data"}),i=s.blockElements,o=s.inlineObjectElements,l=[];for(const n of t.createRangeIn(e)){const e=n.item;if(e.is("element","br")){const n=C(e,"forward",t,{blockElements:i,inlineObjectElements:o}),s=C(e,"backward",t,{blockElements:i,inlineObjectElements:o}),r=S(n,i);(S(s,i)||r)&&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 L{document;constructor(e){this.document=e}isActive(e){return E.test(e)}execute(e){const t=new r.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 s=e.getChildIndex(n);t.remove(n),t.insertChild(s,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 M(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 P(e,t){const n=new DOMParser,s=function(e){return M(M(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>",s=e.indexOf(t);if(s<0)return e;const r=e.indexOf(n,s+t.length);return e.substring(0,s+t.length)+(r>=0?e.substring(r):"")}(e=(e=e.replace(/<!--\[if gte vml 1]>/g,"")).replace(/<o:SmartTagType(?:\s+[^\s>=]+(?:="[^"]*")?)*\s*\/?>/gi,""))),i=n.parseFromString(s,"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 r.ViewDocument(t),s=new r.DomConverter(n,{renderingMode:"data"}),i=e.createDocumentFragment(),o=e.body.childNodes;for(;o.length>0;)i.appendChild(o[0]);return s.domToView(i,{skipComments:!0})}(i,t),c=function(e){const t=[],n=[],s=Array.from(e.getElementsByTagName("style"));for(const e of s)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 $ extends e.Plugin{static get pluginName(){return"PasteFromOffice"}static get isOfficialPlugin(){return!0}static get requires(){return[t.ClipboardPipeline]}init(){const e=this.editor,t=e.plugins.get("ClipboardPipeline"),n=e.editing.view.document,s=[],r=this.editor.plugins.has("MultiLevelList");s.push(new w(n,r)),s.push(new I(n)),s.push(new L(n)),t.on("inputTransformation",(t,r)=>{if(r._isTransformedWithPasteFromOffice)return;if(e.model.document.selection.getFirstPosition().parent.is("element","codeBlock"))return;const i=r.dataTransfer.getData("text/html"),o=s.find(e=>e.isActive(i));o&&(r._parsedData||(r._parsedData=P(i,n.stylesProcessor)),o.execute(r),r._isTransformedWithPasteFromOffice=!0)},{priority:"high"})}}})(),(window.CKEditor5=window.CKEditor5||{}).pasteFromOffice=s})();
|
|
4
|
+
*/(()=>{var e={237:e=>{"use strict";e.exports=CKEditor5.dll},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")}},t={};function n(s){var i=t[s];if(void 0!==i)return i.exports;var r=t[s]={exports:{}};return e[s](r,r.exports,n),r.exports}n.d=(e,t)=>{for(var s in t)n.o(t,s)&&!n.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:t[s]})},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 s={};(()=>{"use strict";n.r(s),n.d(s,{PasteFromOffice:()=>N,PasteFromOfficeGoogleDocsNormalizer:()=>M,PasteFromOfficeGoogleSheetsNormalizer:()=>j,PasteFromOfficeMSWordNormalizer:()=>A,_convertHexToBase64:()=>x,_convertPasteOfficeCssLengthToPx:()=>o,_isPasteOfficePxValue:()=>l,_normalizePasteOfficeSpaceRunSpans:()=>V,_normalizePasteOfficeSpacing:()=>D,_removePasteGoogleOfficeSheetsTag:()=>T,_removePasteMSOfficeAttributes:()=>w,_removePasteOfficeBoldWrapper:()=>I,_removePasteOfficeInvalidTableWidths:()=>$,_removePasteOfficeStyleBlock:()=>R,_removePasteOfficeXmlnsAttributes:()=>W,_replacePasteOfficeImagesSourceWithBase64:()=>v,_toPasteOfficePxValue:()=>a,_transformPasteOfficeBlockBrsToParagraphs:()=>O,_transformPasteOfficeBookmarks:()=>i,_transformPasteOfficeListItemLikeElementsIntoLists:()=>c,_transformPasteOfficeTables:()=>S,_unwrapPasteOfficeParagraphInListItem:()=>m,parsePasteOfficeHtml:()=>B});var e=n(782),t=n(331);function i(e,t){const n=[];for(const s of t.createRangeIn(e)){const e=s.item;e.is("element","a")&&!e.hasAttribute("href")&&(e.hasAttribute("id")||e.hasAttribute("name"))&&n.push(e)}for(const e of n){const n=e.parent.getChildIndex(e)+1,s=e.getChildren();t.insertChild(n,s,e.parent)}}var r=n(783);function o(e){const t=parseFloat(e);return e.endsWith("pt")?a(96*t/72):e.endsWith("pc")?a(12*t*96/72):e.endsWith("in")?a(96*t):e.endsWith("cm")?a(96*t/2.54):e.endsWith("mm")?a(t/10*96/2.54):e}function l(e){return void 0!==e&&e.endsWith("px")}function a(e){return Math.round(e)+"px"}function c(e,t,n){if(!e.childCount)return;const s=new r.ViewUpcastWriter(e.document),i=function(e,t){const n=t.createRangeIn(e),s=[],i=new Set;for(const e of n.getItems()){if(!e.is("element")||!e.name.match(/^(p|h\d+|li|div)$/))continue;let t=b(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&&i.has(t)){const n=h(e);s.push({element:e,id:n.id,order:n.order,indent:n.indent,marginLeft:t}),void 0!==t&&i.add(t)}else i.clear()}return s}(e,s);if(!i.length)return;const o={},c=[];for(const e of i)if(void 0!==e.indent){f(e)||(c.length=0);const i=`${e.id}:${e.indent}`,r=Math.min(e.indent-1,c.length);if(r<c.length&&c[r].id!==e.id&&(c.length=r),r<c.length-1)c.length=r+1;else{const m=d(e,t);if(r>c.length-1||c[r].listElement.name!=m.type){0==r&&"ol"==m.type&&void 0!==e.id&&o[i]&&(m.startIndex=o[i]);const t=g(m,s,n);if(l(e.marginLeft)&&(0==r||l(c[r-1].marginLeft))){let n=e.marginLeft;r>0&&(n=a(parseFloat(n)-parseFloat(c[r-1].marginLeft))),s.setStyle("padding-left",n,t)}if(0==c.length){const n=e.element.parent,i=n.getChildIndex(e.element)+1;s.insertChild(i,t,n)}else{const e=c[r-1].listItemElements;s.appendChild(t,e[e.length-1])}c[r]={...e,listElement:t,listItemElements:[]},0==r&&void 0!==e.id&&(o[i]=m.startIndex||1)}}const m="li"==e.element.name?e.element:s.createElement("li");s.appendChild(m,c[r].listElement),c[r].listItemElements.push(m),0==r&&void 0!==e.id&&o[i]++,e.element!=m&&s.appendChild(e.element,m),y(e.element,s),s.removeStyle("text-indent",e.element),s.removeStyle("margin-left",e.element)}else{const t=c.find(t=>t.marginLeft==e.marginLeft);if(t){const n=t.listItemElements;s.appendChild(e.element,n[n.length-1]),s.removeStyle("margin-left",e.element)}else c.length=0}}function m(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)}}}function f(e){const t=e.element.previousSibling;if(!t){const t=e.element.parent;return u(t)&&(!t.previousSibling||u(t.previousSibling))}return u(t)}function u(e){return e.is("element","ol")||e.is("element","ul")}function d(e,t){const n=new RegExp(`@list l${e.id}:level${e.indent}\\s*({[^}]*)`,"gi"),s=/mso-level-number-format:([^;]{0,100});/gi,i=/mso-level-start-at:\s{0,100}([0-9]{0,10})\s{0,100};/gi,r=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=r.exec(t),a=o.exec(t),c=l&&!a,m=n.exec(t);let f="decimal",u="ol",d=null;if(m&&m[1]){const t=s.exec(m[1]);if(t&&t[1]&&(f=t[1].trim(),u="bullet"!==f&&"image"!==f?"ol":"ul"),"bullet"===f){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&&(f=t)}else{const e=i.exec(m[1]);e&&e[1]&&(d=parseInt(e[1]))}c&&(u="ol")}return{type:u,startIndex:d,style:p(f),isLegalStyleList:c}}function p(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 g(e,t,n){const s=t.createElement(e.type);return e.style&&t.setStyle("list-style-type",e.style,s),e.startIndex&&e.startIndex>1&&t.setAttribute("start",e.startIndex,s),e.isLegalStyleList&&n&&t.addClass("legal-list",s),s}function h(e){const t=e.getStyle("mso-list");if(void 0===t)return{};const n=t.match(/(^|\s{1,100})l(\d+)/i),s=t.match(/\s{0,100}lfo(\d+)/i),i=t.match(/\s{0,100}level(\d+)/i);return n&&s&&i?{id:n[2],order:s[1],indent:parseInt(i[1])}:{indent:1}}function y(e,t){const n=new r.Matcher({name:"span",styles:{"mso-list":"Ignore"}}),s=t.createRangeIn(e);for(const e of s)"elementStart"===e.type&&n.match(e.item)&&t.remove(e.item)}function b(e){const t=e.getStyle("margin-left");return void 0===t||t.endsWith("px")?t:o(t)}function v(e,t){if(!e.childCount)return;const n=new r.ViewUpcastWriter(e.document),s=function(e,t){const n=t.createRangeIn(e),s=new r.Matcher({name:/v:(.+)/}),i=[];for(const e of n){if("elementStart"!=e.type)continue;const t=e.item,n=t.previousSibling,r=n&&n.is("element")?n.name:null,o=["Chart"],l=s.match(t),a=t.getAttribute("o:gfxdata"),c="v:shapetype"===r,m=a&&o.some(e=>t.getAttribute("id").includes(e));l&&a&&!c&&!m&&i.push(e.item.getAttribute("id"))}return i}(e,n);!function(e,t,n){const s=n.createRangeIn(t),i=new r.Matcher({name:"img"}),o=[];for(const t of s)if(t.item.is("element")&&i.match(t.item)){const n=t.item,s=n.getAttribute("v:shapes")?n.getAttribute("v:shapes").split(" "):[];s.length&&s.every(t=>e.indexOf(t)>-1)?o.push(n):n.getAttribute("src")||o.push(n)}for(const e of o)n.remove(e)}(s,e,n),function(e,t,n){const s=n.createRangeIn(t),i=[];for(const t of s)if("elementStart"==t.type&&t.item.is("element","v:shape")){const n=t.item.getAttribute("id");if(e.includes(n))continue;r(t.item.parent.getChildren(),n)||i.push(t.item)}for(const e of i){const t={src:o(e)};e.hasAttribute("alt")&&(t.alt=e.getAttribute("alt"));const s=n.createElement("img",t);n.insertChild(e.index+1,s,e.parent)}function r(e,t){for(const n of e)if(n.is("element")){if("img"==n.name&&n.getAttribute("v:shapes")==t)return!0;if(r(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")}}(s,e,n),function(e,t){const n=t.createRangeIn(e),s=new r.Matcher({name:/v:(.+)/}),i=[];for(const e of n)"elementStart"==e.type&&s.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),s=new r.Matcher({name:"img"}),i=[];let o=0;for(const e of n)e.item.is("element")&&s.match(e.item)&&(e.item.getAttribute("src").startsWith("file://")&&i.push({element:e.item,imageIndex:o}),o++);return i}(e,n);i.length&&function(e,t,n){for(let s=0;s<e.length;s++){const{element:i,imageIndex:r}=e[s],o=t[r];if(o){const e=`data:${o.type};base64,${x(o.hex)}`;n.setAttribute("src",e,i)}}}(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"),s=e.match(n),i=[];if(s)for(const e of s){let n=!1;e.includes("\\pngblip")?n="image/png":e.includes("\\jpegblip")&&(n="image/jpeg"),n&&i.push({hex:e.replace(t,"").replace(/[^\da-fA-F]/g,""),type:n})}return i}(t),n)}function x(e){return btoa(e.match(/\w{2}/g).map(e=>String.fromCharCode(parseInt(e,16))).join(""))}function w(e){const t=[],n=new r.ViewUpcastWriter(e.document);for(const{item:s}of n.createRangeIn(e))if(s.is("element")){for(const e of s.getClassNames())/\bmso/gi.exec(e)&&n.removeClass(e,s);for(const e of s.getStyleNames())/\bmso/gi.exec(e)&&n.removeStyle(e,s);(s.is("element","w:sdt")||s.is("element","w:sdtpr")&&s.isEmpty||s.is("element","o:p")&&s.isEmpty)&&t.push(s)}for(const e of t){const t=e.parent,s=t.getChildIndex(e);n.insertChild(s,e.getChildren(),t),n.remove(e)}}function S(e,t){for(const n of t.createRangeIn(e).getItems()){if(!n.is("element","table")&&!n.is("element","td")&&!n.is("element","th"))continue;const e=["left","top","right","bottom"];if(e.every(e=>!n.hasStyle(`border-${e}-style`)))t.setStyle("border-style","none",n);else for(const s of e)n.hasStyle(`border-${s}-style`)||t.setStyle(`border-${s}-style`,"none",n);const s=["width","height",...e.map(e=>`border-${e}-width`),...e.map(e=>`padding-${e}`)];for(const e of s)n.hasStyle(e)&&t.setStyle(e,o(n.getStyle(e)),n)}}const C=/<meta\s*name="?generator"?\s*content="?microsoft\s*word\s*\d+"?\/?>/i,P=/xmlns:o="urn:schemas-microsoft-com/i;class A{document;hasMultiLevelListPlugin;constructor(e,t=!1){this.document=e,this.hasMultiLevelListPlugin=t}isActive(e){return C.test(e)||P.test(e)}execute(e){const t=new r.ViewUpcastWriter(this.document),{body:n,stylesString:s}=e._parsedData;i(n,t),c(n,s,this.hasMultiLevelListPlugin),v(n,e.dataTransfer.getData("text/rtf")),S(n,t),w(n),e.content=n}}function I(e,t){for(const n of e.getChildren())if(n.is("element","b")&&"normal"===n.getStyle("font-weight")){const s=e.getChildIndex(n);t.remove(n),t.insertChild(s,n.getChildren(),e)}}function O(e,t){const n=new r.ViewDocument(t.document.stylesProcessor),s=new r.ViewDomConverter(n,{renderingMode:"data"}),i=s.blockElements,o=s.inlineObjectElements,l=[];for(const n of t.createRangeIn(e)){const e=n.item;if(e.is("element","br")){const n=E(e,"forward",t,{blockElements:i,inlineObjectElements:o}),s=E(e,"backward",t,{blockElements:i,inlineObjectElements:o}),r=L(n,i);(L(s,i)||r)&&l.push(e)}}for(const e of l)e.hasClass("Apple-interchange-newline")?t.remove(e):t.replace(e,t.createElement("p"))}function E(e,t,n,{blockElements:s,inlineObjectElements:i}){let r=n.createPositionAt(e,"forward"==t?"after":"before");return r=r.getLastMatchingPosition(({item:e})=>e.is("element")&&!s.includes(e.name)&&!i.includes(e.name),{direction:t}),"forward"==t?r.nodeAfter:r.nodeBefore}function L(e,t){return!!e&&e.is("element")&&t.includes(e.name)}const _=/id=("|')docs-internal-guid-[-0-9a-f]+("|')/i;class M{document;constructor(e){this.document=e}isActive(e){return _.test(e)}execute(e){const t=new r.ViewUpcastWriter(this.document),{body:n}=e._parsedData;I(n,t),m(n,t),O(n,t),e.content=n}}function W(e,t){for(const n of e.getChildren())n.is("element","table")&&n.hasAttribute("xmlns")&&t.removeAttribute("xmlns",n)}function T(e,t){for(const n of e.getChildren())if(n.is("element","google-sheets-html-origin")){const s=e.getChildIndex(n);t.remove(n),t.insertChild(s,n.getChildren(),e)}}function $(e,t){for(const n of e.getChildren())n.is("element","table")&&"0px"===n.getStyle("width")&&t.removeStyle("width",n)}function R(e,t){for(const n of Array.from(e.getChildren()))n.is("element","style")&&t.remove(n)}const F=/<google-sheets-html-origin/i;class j{document;constructor(e){this.document=e}isActive(e){return F.test(e)}execute(e){const t=new r.ViewUpcastWriter(this.document),{body:n}=e._parsedData;T(n,t),W(n,t),$(n,t),R(n,t),e.content=n}}function D(e){return k(k(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 V(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)})}function k(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 B(e,t){const n=new DOMParser,s=D(function(e){const t="</body>",n="</html>",s=e.indexOf(t);if(s<0)return e;const i=e.indexOf(n,s+t.length);return e.substring(0,s+t.length)+(i>=0?e.substring(i):"")}(e=(e=e.replace(/<!--\[if gte vml 1]>/g,"")).replace(/<o:SmartTagType(?:\s+[^\s>=]+(?:="[^"]*")?)*\s*\/?>/gi,""))),i=n.parseFromString(s,"text/html");V(i);const o=i.body.innerHTML,l=function(e,t){const n=new r.ViewDocument(t),s=new r.ViewDomConverter(n,{renderingMode:"data"}),i=e.createDocumentFragment(),o=e.body.childNodes;for(;o.length>0;)i.appendChild(o[0]);return s.domToView(i,{skipComments:!0})}(i,t),a=function(e){const t=[],n=[],s=Array.from(e.getElementsByTagName("style"));for(const e of s)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:a.styles,stylesString:a.stylesString}}class N extends e.Plugin{static get pluginName(){return"PasteFromOffice"}static get isOfficialPlugin(){return!0}static get requires(){return[t.ClipboardPipeline]}init(){const e=this.editor,t=e.plugins.get("ClipboardPipeline"),n=e.editing.view.document,s=[],i=this.editor.plugins.has("MultiLevelList");s.push(new A(n,i)),s.push(new M(n)),s.push(new j(n)),t.on("inputTransformation",(t,i)=>{if(i._isTransformedWithPasteFromOffice)return;if(e.model.document.selection.getFirstPosition().parent.is("element","codeBlock"))return;const r=i.dataTransfer.getData("text/html"),o=s.find(e=>e.isActive(r));o&&(i._parsedData||(i._parsedData=B(r,n.stylesProcessor)),o.execute(i),i._isTransformedWithPasteFromOffice=!0)},{priority:"high"})}}})(),(window.CKEditor5=window.CKEditor5||{}).pasteFromOffice=s})();
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { Plugin } from '@ckeditor/ckeditor5-core/dist/index.js';
|
|
6
6
|
import { ClipboardPipeline } from '@ckeditor/ckeditor5-clipboard/dist/index.js';
|
|
7
|
-
import {
|
|
7
|
+
import { ViewUpcastWriter, Matcher, ViewDocument, ViewDomConverter } from '@ckeditor/ckeditor5-engine/dist/index.js';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
|
|
@@ -13,6 +13,8 @@ import { UpcastWriter, Matcher, ViewDocument, DomConverter } from '@ckeditor/cke
|
|
|
13
13
|
* @module paste-from-office/filters/bookmark
|
|
14
14
|
*/ /**
|
|
15
15
|
* Transforms `<a>` elements which are bookmarks by moving their children after the element.
|
|
16
|
+
*
|
|
17
|
+
* @internal
|
|
16
18
|
*/ function transformBookmarks(documentFragment, writer) {
|
|
17
19
|
const elementsToChange = [];
|
|
18
20
|
for (const value of writer.createRangeIn(documentFragment)){
|
|
@@ -84,11 +86,12 @@ import { UpcastWriter, Matcher, ViewDocument, DomConverter } from '@ckeditor/cke
|
|
|
84
86
|
*
|
|
85
87
|
* @param documentFragment The view structure to be transformed.
|
|
86
88
|
* @param stylesString Styles from which list-like elements styling will be extracted.
|
|
89
|
+
* @internal
|
|
87
90
|
*/ function transformListItemLikeElementsIntoLists(documentFragment, stylesString, hasMultiLevelListPlugin) {
|
|
88
91
|
if (!documentFragment.childCount) {
|
|
89
92
|
return;
|
|
90
93
|
}
|
|
91
|
-
const writer = new
|
|
94
|
+
const writer = new ViewUpcastWriter(documentFragment.document);
|
|
92
95
|
const itemLikeElements = findAllItemLikeElements(documentFragment, writer);
|
|
93
96
|
if (!itemLikeElements.length) {
|
|
94
97
|
return;
|
|
@@ -185,6 +188,8 @@ import { UpcastWriter, Matcher, ViewDocument, DomConverter } from '@ckeditor/cke
|
|
|
185
188
|
}
|
|
186
189
|
/**
|
|
187
190
|
* Removes paragraph wrapping content inside a list item.
|
|
191
|
+
*
|
|
192
|
+
* @internal
|
|
188
193
|
*/ function unwrapParagraphInListItem(documentFragment, writer) {
|
|
189
194
|
for (const value of writer.createRangeIn(documentFragment)){
|
|
190
195
|
const element = value.item;
|
|
@@ -201,7 +206,8 @@ import { UpcastWriter, Matcher, ViewDocument, DomConverter } from '@ckeditor/cke
|
|
|
201
206
|
* Finds all list-like elements in a given document fragment.
|
|
202
207
|
*
|
|
203
208
|
* @param documentFragment Document fragment in which to look for list-like nodes.
|
|
204
|
-
* @returns Array of found list-like items. Each item is an object containing
|
|
209
|
+
* @returns Array of found list-like items. Each item is an object containing
|
|
210
|
+
* @internal
|
|
205
211
|
*/ function findAllItemLikeElements(documentFragment, writer) {
|
|
206
212
|
const range = writer.createRangeIn(documentFragment);
|
|
207
213
|
const itemLikeElements = [];
|
|
@@ -242,8 +248,10 @@ import { UpcastWriter, Matcher, ViewDocument, DomConverter } from '@ckeditor/cke
|
|
|
242
248
|
*/ function isListContinuation(currentItem) {
|
|
243
249
|
const previousSibling = currentItem.element.previousSibling;
|
|
244
250
|
if (!previousSibling) {
|
|
251
|
+
const parent = currentItem.element.parent;
|
|
245
252
|
// If it's a li inside ul or ol like in here: https://github.com/ckeditor/ckeditor5/issues/15964.
|
|
246
|
-
|
|
253
|
+
// If the parent has previous sibling, which is not a list, then it is not a continuation.
|
|
254
|
+
return isList(parent) && (!parent.previousSibling || isList(parent.previousSibling));
|
|
247
255
|
}
|
|
248
256
|
// Even with the same id the list does not have to be continuous (#43).
|
|
249
257
|
return isList(previousSibling);
|
|
@@ -480,11 +488,12 @@ function isList(element) {
|
|
|
480
488
|
*
|
|
481
489
|
* @param documentFragment Document fragment on which transform images.
|
|
482
490
|
* @param rtfData The RTF data from which images representation will be used.
|
|
491
|
+
* @internal
|
|
483
492
|
*/ function replaceImagesSourceWithBase64(documentFragment, rtfData) {
|
|
484
493
|
if (!documentFragment.childCount) {
|
|
485
494
|
return;
|
|
486
495
|
}
|
|
487
|
-
const upcastWriter = new
|
|
496
|
+
const upcastWriter = new ViewUpcastWriter(documentFragment.document);
|
|
488
497
|
const shapesIds = findAllShapesIds(documentFragment, upcastWriter);
|
|
489
498
|
removeAllImgElementsRepresentingShapes(shapesIds, documentFragment, upcastWriter);
|
|
490
499
|
insertMissingImgs(shapesIds, documentFragment, upcastWriter);
|
|
@@ -718,9 +727,10 @@ function isList(element) {
|
|
|
718
727
|
* Cleanup MS attributes like styles, attributes and elements.
|
|
719
728
|
*
|
|
720
729
|
* @param documentFragment element `data.content` obtained from clipboard.
|
|
730
|
+
* @internal
|
|
721
731
|
*/ function removeMSAttributes(documentFragment) {
|
|
722
732
|
const elementsToUnwrap = [];
|
|
723
|
-
const writer = new
|
|
733
|
+
const writer = new ViewUpcastWriter(documentFragment.document);
|
|
724
734
|
for (const { item } of writer.createRangeIn(documentFragment)){
|
|
725
735
|
if (!item.is('element')) {
|
|
726
736
|
continue;
|
|
@@ -750,6 +760,8 @@ function isList(element) {
|
|
|
750
760
|
/**
|
|
751
761
|
* Applies border none for table and cells without a border specified.
|
|
752
762
|
* Normalizes style length units to px.
|
|
763
|
+
*
|
|
764
|
+
* @internal
|
|
753
765
|
*/ function transformTables(documentFragment, writer) {
|
|
754
766
|
for (const item of writer.createRangeIn(documentFragment).getItems()){
|
|
755
767
|
if (!item.is('element', 'table') && !item.is('element', 'td') && !item.is('element', 'th')) {
|
|
@@ -792,11 +804,11 @@ const msWordMatch1 = /<meta\s*name="?generator"?\s*content="?microsoft\s*word\s*
|
|
|
792
804
|
const msWordMatch2 = /xmlns:o="urn:schemas-microsoft-com/i;
|
|
793
805
|
/**
|
|
794
806
|
* Normalizer for the content pasted from Microsoft Word.
|
|
795
|
-
*/ class
|
|
807
|
+
*/ class PasteFromOfficeMSWordNormalizer {
|
|
796
808
|
document;
|
|
797
809
|
hasMultiLevelListPlugin;
|
|
798
810
|
/**
|
|
799
|
-
* Creates a new `
|
|
811
|
+
* Creates a new `PasteFromOfficeMSWordNormalizer` instance.
|
|
800
812
|
*
|
|
801
813
|
* @param document View document.
|
|
802
814
|
*/ constructor(document, hasMultiLevelListPlugin = false){
|
|
@@ -811,7 +823,7 @@ const msWordMatch2 = /xmlns:o="urn:schemas-microsoft-com/i;
|
|
|
811
823
|
/**
|
|
812
824
|
* @inheritDoc
|
|
813
825
|
*/ execute(data) {
|
|
814
|
-
const writer = new
|
|
826
|
+
const writer = new ViewUpcastWriter(this.document);
|
|
815
827
|
const { body: documentFragment, stylesString } = data._parsedData;
|
|
816
828
|
transformBookmarks(documentFragment, writer);
|
|
817
829
|
transformListItemLikeElementsIntoLists(documentFragment, stylesString, this.hasMultiLevelListPlugin);
|
|
@@ -831,6 +843,7 @@ const msWordMatch2 = /xmlns:o="urn:schemas-microsoft-com/i;
|
|
|
831
843
|
* Removes the `<b>` tag wrapper added by Google Docs to a copied content.
|
|
832
844
|
*
|
|
833
845
|
* @param documentFragment element `data.content` obtained from clipboard
|
|
846
|
+
* @internal
|
|
834
847
|
*/ function removeBoldWrapper(documentFragment, writer) {
|
|
835
848
|
for (const child of documentFragment.getChildren()){
|
|
836
849
|
if (child.is('element', 'b') && child.getStyle('font-weight') === 'normal') {
|
|
@@ -845,9 +858,10 @@ const msWordMatch2 = /xmlns:o="urn:schemas-microsoft-com/i;
|
|
|
845
858
|
* Transforms `<br>` elements that are siblings to some block element into a paragraphs.
|
|
846
859
|
*
|
|
847
860
|
* @param documentFragment The view structure to be transformed.
|
|
861
|
+
* @internal
|
|
848
862
|
*/ function transformBlockBrsToParagraphs(documentFragment, writer) {
|
|
849
863
|
const viewDocument = new ViewDocument(writer.document.stylesProcessor);
|
|
850
|
-
const domConverter = new
|
|
864
|
+
const domConverter = new ViewDomConverter(viewDocument, {
|
|
851
865
|
renderingMode: 'data'
|
|
852
866
|
});
|
|
853
867
|
const blockElements = domConverter.blockElements;
|
|
@@ -906,6 +920,8 @@ const msWordMatch2 = /xmlns:o="urn:schemas-microsoft-com/i;
|
|
|
906
920
|
const googleDocsMatch = /id=("|')docs-internal-guid-[-0-9a-f]+("|')/i;
|
|
907
921
|
/**
|
|
908
922
|
* Normalizer for the content pasted from Google Docs.
|
|
923
|
+
*
|
|
924
|
+
* @internal
|
|
909
925
|
*/ class GoogleDocsNormalizer {
|
|
910
926
|
document;
|
|
911
927
|
/**
|
|
@@ -923,7 +939,7 @@ const googleDocsMatch = /id=("|')docs-internal-guid-[-0-9a-f]+("|')/i;
|
|
|
923
939
|
/**
|
|
924
940
|
* @inheritDoc
|
|
925
941
|
*/ execute(data) {
|
|
926
|
-
const writer = new
|
|
942
|
+
const writer = new ViewUpcastWriter(this.document);
|
|
927
943
|
const { body: documentFragment } = data._parsedData;
|
|
928
944
|
removeBoldWrapper(documentFragment, writer);
|
|
929
945
|
unwrapParagraphInListItem(documentFragment, writer);
|
|
@@ -941,6 +957,7 @@ const googleDocsMatch = /id=("|')docs-internal-guid-[-0-9a-f]+("|')/i;
|
|
|
941
957
|
* Removes the `xmlns` attribute from table pasted from Google Sheets.
|
|
942
958
|
*
|
|
943
959
|
* @param documentFragment element `data.content` obtained from clipboard
|
|
960
|
+
* @internal
|
|
944
961
|
*/ function removeXmlns(documentFragment, writer) {
|
|
945
962
|
for (const child of documentFragment.getChildren()){
|
|
946
963
|
if (child.is('element', 'table') && child.hasAttribute('xmlns')) {
|
|
@@ -958,6 +975,7 @@ const googleDocsMatch = /id=("|')docs-internal-guid-[-0-9a-f]+("|')/i;
|
|
|
958
975
|
* Removes the `<google-sheets-html-origin>` tag wrapper added by Google Sheets to a copied content.
|
|
959
976
|
*
|
|
960
977
|
* @param documentFragment element `data.content` obtained from clipboard
|
|
978
|
+
* @internal
|
|
961
979
|
*/ function removeGoogleSheetsTag(documentFragment, writer) {
|
|
962
980
|
for (const child of documentFragment.getChildren()){
|
|
963
981
|
if (child.is('element', 'google-sheets-html-origin')) {
|
|
@@ -977,6 +995,7 @@ const googleDocsMatch = /id=("|')docs-internal-guid-[-0-9a-f]+("|')/i;
|
|
|
977
995
|
* Removes the `width:0px` style from table pasted from Google Sheets.
|
|
978
996
|
*
|
|
979
997
|
* @param documentFragment element `data.content` obtained from clipboard
|
|
998
|
+
* @internal
|
|
980
999
|
*/ function removeInvalidTableWidth(documentFragment, writer) {
|
|
981
1000
|
for (const child of documentFragment.getChildren()){
|
|
982
1001
|
if (child.is('element', 'table') && child.getStyle('width') === '0px') {
|
|
@@ -994,6 +1013,7 @@ const googleDocsMatch = /id=("|')docs-internal-guid-[-0-9a-f]+("|')/i;
|
|
|
994
1013
|
* Removes `<style>` block added by Google Sheets to a copied content.
|
|
995
1014
|
*
|
|
996
1015
|
* @param documentFragment element `data.content` obtained from clipboard
|
|
1016
|
+
* @internal
|
|
997
1017
|
*/ function removeStyleBlock(documentFragment, writer) {
|
|
998
1018
|
for (const child of Array.from(documentFragment.getChildren())){
|
|
999
1019
|
if (child.is('element', 'style')) {
|
|
@@ -1005,6 +1025,8 @@ const googleDocsMatch = /id=("|')docs-internal-guid-[-0-9a-f]+("|')/i;
|
|
|
1005
1025
|
const googleSheetsMatch = /<google-sheets-html-origin/i;
|
|
1006
1026
|
/**
|
|
1007
1027
|
* Normalizer for the content pasted from Google Sheets.
|
|
1028
|
+
*
|
|
1029
|
+
* @internal
|
|
1008
1030
|
*/ class GoogleSheetsNormalizer {
|
|
1009
1031
|
document;
|
|
1010
1032
|
/**
|
|
@@ -1022,7 +1044,7 @@ const googleSheetsMatch = /<google-sheets-html-origin/i;
|
|
|
1022
1044
|
/**
|
|
1023
1045
|
* @inheritDoc
|
|
1024
1046
|
*/ execute(data) {
|
|
1025
|
-
const writer = new
|
|
1047
|
+
const writer = new ViewUpcastWriter(this.document);
|
|
1026
1048
|
const { body: documentFragment } = data._parsedData;
|
|
1027
1049
|
removeGoogleSheetsTag(documentFragment, writer);
|
|
1028
1050
|
removeXmlns(documentFragment, writer);
|
|
@@ -1039,12 +1061,13 @@ const googleSheetsMatch = /<google-sheets-html-origin/i;
|
|
|
1039
1061
|
* @module paste-from-office/filters/space
|
|
1040
1062
|
*/ /**
|
|
1041
1063
|
* Replaces last space preceding elements closing tag with ` `. Such operation prevents spaces from being removed
|
|
1042
|
-
* during further DOM/View processing (see especially {@link module:engine/view/domconverter~
|
|
1064
|
+
* during further DOM/View processing (see especially {@link module:engine/view/domconverter~ViewDomConverter#_processDomInlineNodes}).
|
|
1043
1065
|
* This method also takes into account Word specific `<o:p></o:p>` empty tags.
|
|
1044
1066
|
* Additionally multiline sequences of spaces and new lines between tags are removed (see #39 and #40).
|
|
1045
1067
|
*
|
|
1046
1068
|
* @param htmlString HTML string in which spacing should be normalized.
|
|
1047
1069
|
* @returns Input HTML with spaces normalized.
|
|
1070
|
+
* @internal
|
|
1048
1071
|
*/ function normalizeSpacing(htmlString) {
|
|
1049
1072
|
// Run normalizeSafariSpaceSpans() two times to cover nested spans.
|
|
1050
1073
|
return normalizeSafariSpaceSpans(normalizeSafariSpaceSpans(htmlString))// Remove all \r\n from "spacerun spans" so the last replace line doesn't strip all whitespaces.
|
|
@@ -1055,9 +1078,10 @@ const googleSheetsMatch = /<google-sheets-html-origin/i;
|
|
|
1055
1078
|
/**
|
|
1056
1079
|
* Normalizes spacing in special Word `spacerun spans` (`<span style='mso-spacerun:yes'>\s+</span>`) by replacing
|
|
1057
1080
|
* all spaces with ` ` pairs. This prevents spaces from being removed during further DOM/View processing
|
|
1058
|
-
* (see especially {@link module:engine/view/domconverter~
|
|
1081
|
+
* (see especially {@link module:engine/view/domconverter~ViewDomConverter#_processDomInlineNodes}).
|
|
1059
1082
|
*
|
|
1060
1083
|
* @param htmlDocument Native `Document` object in which spacing should be normalized.
|
|
1084
|
+
* @internal
|
|
1061
1085
|
*/ function normalizeSpacerunSpans(htmlDocument) {
|
|
1062
1086
|
htmlDocument.querySelectorAll('span[style*=spacerun]').forEach((el)=>{
|
|
1063
1087
|
const htmlElement = el;
|
|
@@ -1068,13 +1092,14 @@ const googleSheetsMatch = /<google-sheets-html-origin/i;
|
|
|
1068
1092
|
/**
|
|
1069
1093
|
* Normalizes specific spacing generated by Safari when content pasted from Word (`<span class="Apple-converted-space"> </span>`)
|
|
1070
1094
|
* by replacing all spaces sequences longer than 1 space with ` ` pairs. This prevents spaces from being removed during
|
|
1071
|
-
* further DOM/View processing (see especially {@link module:engine/view/domconverter~
|
|
1095
|
+
* further DOM/View processing (see especially {@link module:engine/view/domconverter~ViewDomConverter#_processDataFromDomText}).
|
|
1072
1096
|
*
|
|
1073
1097
|
* This function is similar to {@link module:clipboard/utils/normalizeclipboarddata normalizeClipboardData util} but uses
|
|
1074
1098
|
* regular spaces / sequence for replacement.
|
|
1075
1099
|
*
|
|
1076
1100
|
* @param htmlString HTML string in which spacing should be normalized
|
|
1077
1101
|
* @returns Input HTML with spaces normalized.
|
|
1102
|
+
* @internal
|
|
1078
1103
|
*/ function normalizeSafariSpaceSpans(htmlString) {
|
|
1079
1104
|
return htmlString.replace(/<span(?: class="Apple-converted-space"|)>(\s+)<\/span>/g, (fullMatch, spaces)=>{
|
|
1080
1105
|
return spaces.length === 1 ? ' ' : Array(spaces.length + 1).join('\u00A0 ').substr(0, spaces.length);
|
|
@@ -1085,7 +1110,7 @@ const googleSheetsMatch = /<google-sheets-html-origin/i;
|
|
|
1085
1110
|
* Parses the provided HTML extracting contents of `<body>` and `<style>` tags.
|
|
1086
1111
|
*
|
|
1087
1112
|
* @param htmlString HTML string to be parsed.
|
|
1088
|
-
*/ function
|
|
1113
|
+
*/ function parsePasteOfficeHtml(htmlString, stylesProcessor) {
|
|
1089
1114
|
const domParser = new DOMParser();
|
|
1090
1115
|
// Remove Word specific "if comments" so content inside is not omitted by the parser.
|
|
1091
1116
|
htmlString = htmlString.replace(/<!--\[if gte vml 1]>/g, '');
|
|
@@ -1110,12 +1135,12 @@ const googleSheetsMatch = /<google-sheets-html-origin/i;
|
|
|
1110
1135
|
};
|
|
1111
1136
|
}
|
|
1112
1137
|
/**
|
|
1113
|
-
* Transforms native `Document` object into {@link module:engine/view/documentfragment~
|
|
1138
|
+
* Transforms native `Document` object into {@link module:engine/view/documentfragment~ViewDocumentFragment}. Comments are skipped.
|
|
1114
1139
|
*
|
|
1115
1140
|
* @param htmlDocument Native `Document` object to be transformed.
|
|
1116
1141
|
*/ function documentToView(htmlDocument, stylesProcessor) {
|
|
1117
1142
|
const viewDocument = new ViewDocument(stylesProcessor);
|
|
1118
|
-
const domConverter = new
|
|
1143
|
+
const domConverter = new ViewDomConverter(viewDocument, {
|
|
1119
1144
|
renderingMode: 'data'
|
|
1120
1145
|
});
|
|
1121
1146
|
const fragment = htmlDocument.createDocumentFragment();
|
|
@@ -1173,9 +1198,9 @@ const googleSheetsMatch = /<google-sheets-html-origin/i;
|
|
|
1173
1198
|
* This plugin handles content pasted from Office apps and transforms it (if necessary)
|
|
1174
1199
|
* to a valid structure which can then be understood by the editor features.
|
|
1175
1200
|
*
|
|
1176
|
-
* Transformation is made by a set of predefined {@link module:paste-from-office/normalizer~
|
|
1201
|
+
* Transformation is made by a set of predefined {@link module:paste-from-office/normalizer~PasteFromOfficeNormalizer normalizers}.
|
|
1177
1202
|
* This plugin includes following normalizers:
|
|
1178
|
-
* * {@link module:paste-from-office/normalizers/mswordnormalizer~
|
|
1203
|
+
* * {@link module:paste-from-office/normalizers/mswordnormalizer~PasteFromOfficeMSWordNormalizer Microsoft Word normalizer}
|
|
1179
1204
|
* * {@link module:paste-from-office/normalizers/googledocsnormalizer~GoogleDocsNormalizer Google Docs normalizer}
|
|
1180
1205
|
*
|
|
1181
1206
|
* For more information about this feature check the {@glink api/paste-from-office package page}.
|
|
@@ -1205,7 +1230,7 @@ const googleSheetsMatch = /<google-sheets-html-origin/i;
|
|
|
1205
1230
|
const viewDocument = editor.editing.view.document;
|
|
1206
1231
|
const normalizers = [];
|
|
1207
1232
|
const hasMultiLevelListPlugin = this.editor.plugins.has('MultiLevelList');
|
|
1208
|
-
normalizers.push(new
|
|
1233
|
+
normalizers.push(new PasteFromOfficeMSWordNormalizer(viewDocument, hasMultiLevelListPlugin));
|
|
1209
1234
|
normalizers.push(new GoogleDocsNormalizer(viewDocument));
|
|
1210
1235
|
normalizers.push(new GoogleSheetsNormalizer(viewDocument));
|
|
1211
1236
|
clipboardPipeline.on('inputTransformation', (evt, data)=>{
|
|
@@ -1220,7 +1245,7 @@ const googleSheetsMatch = /<google-sheets-html-origin/i;
|
|
|
1220
1245
|
const activeNormalizer = normalizers.find((normalizer)=>normalizer.isActive(htmlString));
|
|
1221
1246
|
if (activeNormalizer) {
|
|
1222
1247
|
if (!data._parsedData) {
|
|
1223
|
-
data._parsedData =
|
|
1248
|
+
data._parsedData = parsePasteOfficeHtml(htmlString, viewDocument.stylesProcessor);
|
|
1224
1249
|
}
|
|
1225
1250
|
activeNormalizer.execute(data);
|
|
1226
1251
|
data._isTransformedWithPasteFromOffice = true;
|
|
@@ -1231,5 +1256,5 @@ const googleSheetsMatch = /<google-sheets-html-origin/i;
|
|
|
1231
1256
|
}
|
|
1232
1257
|
}
|
|
1233
1258
|
|
|
1234
|
-
export {
|
|
1259
|
+
export { PasteFromOffice, GoogleDocsNormalizer as PasteFromOfficeGoogleDocsNormalizer, GoogleSheetsNormalizer as PasteFromOfficeGoogleSheetsNormalizer, PasteFromOfficeMSWordNormalizer, _convertHexToBase64, convertCssLengthToPx as _convertPasteOfficeCssLengthToPx, isPx as _isPasteOfficePxValue, normalizeSpacerunSpans as _normalizePasteOfficeSpaceRunSpans, normalizeSpacing as _normalizePasteOfficeSpacing, removeGoogleSheetsTag as _removePasteGoogleOfficeSheetsTag, removeMSAttributes as _removePasteMSOfficeAttributes, removeBoldWrapper as _removePasteOfficeBoldWrapper, removeInvalidTableWidth as _removePasteOfficeInvalidTableWidths, removeStyleBlock as _removePasteOfficeStyleBlock, removeXmlns as _removePasteOfficeXmlnsAttributes, replaceImagesSourceWithBase64 as _replacePasteOfficeImagesSourceWithBase64, toPx as _toPasteOfficePxValue, transformBlockBrsToParagraphs as _transformPasteOfficeBlockBrsToParagraphs, transformBookmarks as _transformPasteOfficeBookmarks, transformListItemLikeElementsIntoLists as _transformPasteOfficeListItemLikeElementsIntoLists, transformTables as _transformPasteOfficeTables, unwrapParagraphInListItem as _unwrapPasteOfficeParagraphInListItem, parsePasteOfficeHtml };
|
|
1235
1260
|
//# sourceMappingURL=index.js.map
|