@ckeditor/ckeditor5-paste-from-office 39.0.2 → 40.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/paste-from-office.js.map +1 -0
- package/package.json +2 -2
- package/src/augmentation.d.ts +10 -10
- package/src/augmentation.js +5 -5
- package/src/filters/br.d.ts +14 -14
- package/src/filters/br.js +65 -65
- package/src/filters/image.d.ts +24 -24
- package/src/filters/image.js +241 -241
- package/src/filters/list.d.ts +26 -26
- package/src/filters/list.js +395 -395
- package/src/filters/parse.d.ts +35 -35
- package/src/filters/parse.js +93 -93
- package/src/filters/removeboldwrapper.d.ts +14 -14
- package/src/filters/removeboldwrapper.js +18 -18
- package/src/filters/removegooglesheetstag.d.ts +14 -14
- package/src/filters/removegooglesheetstag.js +18 -18
- package/src/filters/removeinvalidtablewidth.d.ts +14 -14
- package/src/filters/removeinvalidtablewidth.js +16 -16
- package/src/filters/removestyleblock.d.ts +14 -14
- package/src/filters/removestyleblock.js +16 -16
- package/src/filters/removexmlns.d.ts +14 -14
- package/src/filters/removexmlns.js +16 -16
- package/src/filters/space.d.ts +25 -25
- package/src/filters/space.js +60 -60
- package/src/index.d.ts +12 -12
- package/src/index.js +11 -11
- package/src/normalizer.d.ts +30 -30
- package/src/normalizer.js +5 -5
- package/src/normalizers/googledocsnormalizer.d.ts +29 -29
- package/src/normalizers/googledocsnormalizer.js +42 -42
- package/src/normalizers/googlesheetsnormalizer.d.ts +29 -29
- package/src/normalizers/googlesheetsnormalizer.js +44 -44
- package/src/normalizers/mswordnormalizer.d.ts +26 -26
- package/src/normalizers/mswordnormalizer.js +39 -39
- package/src/pastefromoffice.d.ts +36 -36
- package/src/pastefromoffice.js +70 -70
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paste-from-office.js","mappings":";;;;;;;;;;;;;;;;;;;AAAA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEkE;;AAElE;AACA;AACA;AACA,WAAW,sDAAsD;AACjE,WAAW,8CAA8C;AACzD;AACe;AACf,0BAA0B,8DAAY;AACtC,0BAA0B,8DAAY,kBAAkB,wBAAwB;;AAEhF;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA,kEAAkE,sCAAsC;AACxG,uEAAuE,sCAAsC;;AAE7G;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;;AAEA;AACA,wDAAwD,sCAAsC;AAC9F;;AAEA;AACA;AACA;AACA;AACA;AACA,kDAAkD,OAAO;AACzD;AACA;AACA;AACA,MAAM,YAAY;;AAElB;AACA;;AAEA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;AC5EA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAE6D;;AAE7D;AACA;AACA;AACA;AACA,WAAW,sDAAsD;AACjE,WAAW,QAAQ;AACnB;AACO;AACP;AACA;AACA;;AAEA,0BAA0B,8DAAY;AACtC;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa,QAAQ;AACrB;AACO;AACP,mCAAmC,EAAE;AACrC;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA,WAAW,sDAAsD;AACjE;AACA,WAAW,8CAA8C;AACzD,aAAa,gBAAgB;AAC7B;AACA;;AAEA,kCAAkC,yDAAO;AACzC;AACA,GAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,WAAW,gBAAgB;AAC3B,WAAW,sDAAsD;AACjE,WAAW,8CAA8C;AACzD;AACA;;AAEA,kCAAkC,yDAAO;AACzC;AACA,GAAG;;AAEH;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,sDAAsD;AACjE,WAAW,8CAA8C;AACzD;AACA;;AAEA,kCAAkC,yDAAO;AACzC;AACA,GAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,sDAAsD;AACjE,WAAW,8CAA8C;AACzD,aAAa,QAAQ;AACrB,aAAa,4CAA4C;AACzD,aAAa,4CAA4C;AACzD;AACA;;AAEA,kCAAkC,yDAAO;AACzC;AACA,GAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa,gBAAgB;AAC7B;AACA,QAAQ,QAAQ;AAChB,QAAQ,QAAQ;AAChB;AACA;AACA;AACA;;AAEA,8BAA8B,+CAA+C,iCAAiC;AAC9G,8FAA8F;AAC9F;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,WAAW,4CAA4C;AACvD,WAAW,gBAAgB;AAC3B;AACA,WAAW,8CAA8C;AACzD;AACA;AACA;AACA,mBAAmB,0BAA0B;AAC7C,2BAA2B,6BAA6B,UAAU,kDAAkD;AACpH;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;AC7NA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6D;;AAE7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,sDAAsD;AACjE,WAAW,QAAQ;AACnB;AACO;AACP;AACA;AACA;;AAEA,oBAAoB,8DAAY;AAChC;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA,WAAW,sDAAsD;AACjE,WAAW,8CAA8C;AACzD;AACO;AACP;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,sDAAsD;AACjE;AACA,WAAW,8CAA8C;AACzD,aAAa,gBAAgB;AAC7B;AACA,OAAO,wCAAwC;AAC/C,OAAO,QAAQ;AACf,OAAO,QAAQ;AACf,OAAO,QAAQ;AACf;AACA;;AAEA;AACA,qCAAqC,yDAAO;AAC5C;AACA;AACA;AACA;AACA,GAAG;;AAEH;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA,WAAW,QAAQ;AACnB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,aAAa;AAC1B;AACA;AACA;AACA,gDAAgD,iBAAiB,SAAS,qBAAqB,MAAM,GAAG;AACxG,yDAAyD,EAAE,MAAM,EAAE;AACnE,oDAAoD,MAAM,OAAO,KAAK,IAAI,OAAO;;AAEjF;;AAEA,gCAAgC;AAChC,kBAAkB;AAClB;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,oCAAoC;AAC/C,aAAa;AACb;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,WAAW,oCAAoC;AAC/C,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,WAAW,aAAa;AACxB,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB;AACA,WAAW,oCAAoC;AAC/C,WAAW,8CAA8C;AACzD,aAAa,oCAAoC;;AAEjD;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,IAAI,gDAAgD;AACpD;AACA,WAAW,oCAAoC;AAC/C,WAAW,8CAA8C;AACzD,aAAa,oCAAoC;AACjD;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,oCAAoC;AAC/C,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA;AACA;;AAEA;AACA,0CAA0C,MAAM;AAChD,0CAA0C,MAAM;AAChD,2CAA2C,MAAM;;AAEjD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,WAAW,oCAAoC;AAC/C,WAAW,8CAA8C;AACzD;AACA;AACA,2BAA2B,yDAAO;AAClC;AACA;AACA;AACA;AACA,GAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA,WAAW,oCAAoC;AAC/C,WAAW,QAAQ;AACnB,aAAa,oCAAoC;AACjD;AACA,+CAA+C,oBAAoB;;AAEnE;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;AC5cA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEkE;;AAEC;;AAEnE;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,8CAA8C;AACzD,aAAa,QAAQ;AACrB,aAAa,sDAAsD;AACnE;AACA,aAAa,QAAQ;AACrB,aAAa,uBAAuB;AACpC;AACA,aAAa,QAAQ;AACrB;AACO;AACP;;AAEA;AACA;;AAEA,wBAAwB,wDAAgB;;AAExC;AACA;;AAEA,CAAC,8DAAsB;;AAEvB;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,6CAA6C,2DAA2D;AACxG;AACA,WAAW,UAAU;AACrB,WAAW,8CAA8C;AACzD,aAAa;AACb;AACA,0BAA0B,8DAAY;AACtC,0BAA0B,8DAAY,kBAAkB,wBAAwB;AAChF;AACA;;AAEA;AACA;AACA;;AAEA,4CAA4C,qBAAqB;AACjE;;AAEA;AACA;AACA,WAAW,UAAU;AACrB,aAAa,QAAQ;AACrB,aAAa,uBAAuB;AACpC;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa,QAAQ;AACrB;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;AC1HA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,sDAAsD;AACjE,WAAW,8CAA8C;AACzD;AACe;AACf;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ACxBA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,kEAAkE;AAClE,uDAAuD,2EAA2E;AAClI;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa,QAAQ;AACrB;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yFAAyF;AACzF,yBAAyB;AACzB;AACA;AACA;;AAEA;AACA;AACA,2BAA2B;AAC3B,oBAAoB,2EAA2E;AAC/F;AACA,WAAW,UAAU;AACrB;AACO;AACP;AACA;;AAEA;AACA,GAAG;AACH;;AAEA;AACA,sEAAsE;AACtE,gDAAgD,2EAA2E;AAC3H;AACA,gCAAgC,iFAAiF;AACjH,2BAA2B;AAC3B;AACA,WAAW,QAAQ;AACnB,aAAa,QAAQ;AACrB;AACA;AACA;AACA,GAAG;AACH;;;;;;;;;;;;;;;;;;;;AC5DA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEoD;;AAES;AACH;AACE;;AAE5D;;AAEA;AACA;AACA;AACA;AACA;AACe;AACf;AACA;AACA;AACA,YAAY,sCAAsC;AAClD;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB,8DAAY;AACjC,UAAU,yBAAyB;;AAEnC,EAAE,sEAAiB;AACnB,EAAE,wEAAyB;AAC3B,EAAE,uDAA6B;;AAE/B;AACA;AACA;;;;;;;;;;;;;;;;;;ACxDA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEyE;AACR;;AAEjE;AACA;;AAEA;AACA;AACA;AACA;AACA;AACe;AACf;AACA;AACA;AACA,YAAY,sCAAsC;AAClD;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAU,uCAAuC;;AAEjD,EAAE,qFAAsC;AACxC,EAAE,6EAA6B;;AAE/B;AACA;AACA;;;;;;;;;;;;;;;;;;;;;ACpDA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;AACgB;;AAEU;AACR;;AAElB;;AAE5C;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,iEAAiE;AACnH;AACA,QAAQ;AACR,QAAQ;AACR;AACA,sDAAsD,0CAA0C;AAChG;AACA;AACA;AACe,8BAA8B,sDAAM;AACnD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,sEAAiB;AAC5B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,wBAAwB,qEAAgB;AACxC,wBAAwB,yEAAoB;;AAE5C;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,wBAAwB,yDAAS;;AAEjC;;AAEA;AACA;AACA,IAAI;AACJ,KAAK;AACL;AACA;AACA;;;;;;;;;;;ACrFA;;;;;;;;;;ACAA;;;;;;;;;;ACAA;;;;;;;;;;;ACAA;;;;;;UCAA;UACA;;UAEA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;;UAEA;UACA;;UAEA;UACA;UACA;;;;;WCtBA;WACA;WACA;WACA;WACA,yCAAyC,wCAAwC;WACjF;WACA;WACA;;;;;WCPA;;;;;WCAA;WACA;WACA;WACA,uDAAuD,iBAAiB;WACxE;WACA,gDAAgD,aAAa;WAC7D;;;;;;;;;;;;;;;;ACNA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE+D","sources":["webpack://CKEditor5.pasteFromOffice/./src/filters/br.js","webpack://CKEditor5.pasteFromOffice/./src/filters/image.js","webpack://CKEditor5.pasteFromOffice/./src/filters/list.js","webpack://CKEditor5.pasteFromOffice/./src/filters/parse.js","webpack://CKEditor5.pasteFromOffice/./src/filters/removeboldwrapper.js","webpack://CKEditor5.pasteFromOffice/./src/filters/space.js","webpack://CKEditor5.pasteFromOffice/./src/normalizers/googledocsnormalizer.js","webpack://CKEditor5.pasteFromOffice/./src/normalizers/mswordnormalizer.js","webpack://CKEditor5.pasteFromOffice/./src/pastefromoffice.js","webpack://CKEditor5.pasteFromOffice/delegated \"./src/clipboard.js\" from dll-reference CKEditor5.dll","webpack://CKEditor5.pasteFromOffice/delegated \"./src/core.js\" from dll-reference CKEditor5.dll","webpack://CKEditor5.pasteFromOffice/delegated \"./src/engine.js\" from dll-reference CKEditor5.dll","webpack://CKEditor5.pasteFromOffice/external var \"CKEditor5.dll\"","webpack://CKEditor5.pasteFromOffice/webpack/bootstrap","webpack://CKEditor5.pasteFromOffice/webpack/runtime/define property getters","webpack://CKEditor5.pasteFromOffice/webpack/runtime/hasOwnProperty shorthand","webpack://CKEditor5.pasteFromOffice/webpack/runtime/make namespace object","webpack://CKEditor5.pasteFromOffice/./src/index.js"],"sourcesContent":["/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paste-from-office/filters/br\n */\n\nimport { DomConverter, ViewDocument } from 'ckeditor5/src/engine';\n\n/**\n * Transforms `<br>` elements that are siblings to some block element into a paragraphs.\n *\n * @param {module:engine/view/documentfragment~DocumentFragment} documentFragment The view structure to be transformed.\n * @param {module:engine/view/upcastwriter~UpcastWriter} writer\n */\nexport default function transformBlockBrsToParagraphs( documentFragment, writer ) {\n\tconst viewDocument = new ViewDocument( writer.document.stylesProcessor );\n\tconst domConverter = new DomConverter( viewDocument, { renderingMode: 'data' } );\n\n\tconst blockElements = domConverter.blockElements;\n\tconst inlineObjectElements = domConverter.inlineObjectElements;\n\n\tconst elementsToReplace = [];\n\n\tfor ( const value of writer.createRangeIn( documentFragment ) ) {\n\t\tconst element = value.item;\n\n\t\tif ( element.is( 'element', 'br' ) ) {\n\t\t\tconst nextSibling = findSibling( element, 'forward', writer, { blockElements, inlineObjectElements } );\n\t\t\tconst previousSibling = findSibling( element, 'backward', writer, { blockElements, inlineObjectElements } );\n\n\t\t\tconst nextSiblingIsBlock = isBlockViewElement( nextSibling, blockElements );\n\t\t\tconst previousSiblingIsBlock = isBlockViewElement( previousSibling, blockElements );\n\n\t\t\t// If the <br> is surrounded by blocks then convert it to a paragraph:\n\t\t\t// * <p>foo</p>[<br>]<p>bar</p> -> <p>foo</p>[<p></p>]<p>bar</p>\n\t\t\t// * <p>foo</p>[<br>] -> <p>foo</p>[<p></p>]\n\t\t\t// * [<br>]<p>foo</p> -> [<p></p>]<p>foo</p>\n\t\t\tif ( previousSiblingIsBlock || nextSiblingIsBlock ) {\n\t\t\t\telementsToReplace.push( element );\n\t\t\t}\n\t\t}\n\t}\n\n\tfor ( const element of elementsToReplace ) {\n\t\tif ( element.hasClass( 'Apple-interchange-newline' ) ) {\n\t\t\twriter.remove( element );\n\t\t} else {\n\t\t\twriter.replace( element, writer.createElement( 'p' ) );\n\t\t}\n\t}\n}\n\n// Returns sibling node, threats inline elements as transparent (but should stop on an inline objects).\nfunction findSibling( viewElement, direction, writer, { blockElements, inlineObjectElements } ) {\n\tlet position = writer.createPositionAt( viewElement, direction == 'forward' ? 'after' : 'before' );\n\n\t// Find first position that is just before a first:\n\t// * text node,\n\t// * block element,\n\t// * inline object element.\n\t// It's ignoring any inline (non-object) elements like span, strong, etc.\n\tposition = position.getLastMatchingPosition( ( { item } ) => (\n\t\titem.is( 'element' ) &&\n\t\t!blockElements.includes( item.name ) &&\n\t\t!inlineObjectElements.includes( item.name )\n\t), { direction } );\n\n\treturn direction == 'forward' ? position.nodeAfter : position.nodeBefore;\n}\n\n// Returns true for view elements that are listed as block view elements.\nfunction isBlockViewElement( node, blockElements ) {\n\treturn !!node && node.is( 'element' ) && blockElements.includes( node.name );\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paste-from-office/filters/image\n */\n\n/* globals btoa */\n\nimport { Matcher, UpcastWriter } from 'ckeditor5/src/engine';\n\n/**\n * Replaces source attribute of all `<img>` elements representing regular\n * images (not the Word shapes) with inlined base64 image representation extracted from RTF or Blob data.\n *\n * @param {module:engine/view/documentfragment~DocumentFragment} documentFragment Document fragment on which transform images.\n * @param {String} rtfData The RTF data from which images representation will be used.\n */\nexport function replaceImagesSourceWithBase64( documentFragment, rtfData ) {\n\tif ( !documentFragment.childCount ) {\n\t\treturn;\n\t}\n\n\tconst upcastWriter = new UpcastWriter();\n\tconst shapesIds = findAllShapesIds( documentFragment, upcastWriter );\n\n\tremoveAllImgElementsRepresentingShapes( shapesIds, documentFragment, upcastWriter );\n\tremoveAllShapeElements( documentFragment, upcastWriter );\n\n\tconst images = findAllImageElementsWithLocalSource( documentFragment, upcastWriter );\n\n\tif ( images.length ) {\n\t\treplaceImagesFileSourceWithInlineRepresentation( images, extractImageDataFromRtf( rtfData ), upcastWriter );\n\t}\n}\n\n/**\n * Converts given HEX string to base64 representation.\n *\n * @protected\n * @param {String} hexString The HEX string to be converted.\n * @returns {String} Base64 representation of a given HEX string.\n */\nexport function _convertHexToBase64( hexString ) {\n\treturn btoa( hexString.match( /\\w{2}/g ).map( char => {\n\t\treturn String.fromCharCode( parseInt( char, 16 ) );\n\t} ).join( '' ) );\n}\n\n// Finds all shapes (`<v:*>...</v:*>`) ids. Shapes can represent images (canvas)\n// or Word shapes (which does not have RTF or Blob representation).\n//\n// @param {module:engine/view/documentfragment~DocumentFragment} documentFragment Document fragment\n// from which to extract shape ids.\n// @param {module:engine/view/upcastwriter~UpcastWriter} writer\n// @returns {Array.<String>} Array of shape ids.\nfunction findAllShapesIds( documentFragment, writer ) {\n\tconst range = writer.createRangeIn( documentFragment );\n\n\tconst shapeElementsMatcher = new Matcher( {\n\t\tname: /v:(.+)/\n\t} );\n\n\tconst shapesIds = [];\n\n\tfor ( const value of range ) {\n\t\tif ( value.type != 'elementStart' ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst el = value.item;\n\t\tconst prevSiblingName = el.previousSibling && el.previousSibling.name || null;\n\n\t\t// If shape element have 'o:gfxdata' attribute and is not directly before `<v:shapetype>` element it means it represent Word shape.\n\t\tif ( shapeElementsMatcher.match( el ) && el.getAttribute( 'o:gfxdata' ) && prevSiblingName !== 'v:shapetype' ) {\n\t\t\tshapesIds.push( value.item.getAttribute( 'id' ) );\n\t\t}\n\t}\n\n\treturn shapesIds;\n}\n\n// Removes all `<img>` elements which represents Word shapes and not regular images.\n//\n// @param {Array.<String>} shapesIds Shape ids which will be checked against `<img>` elements.\n// @param {module:engine/view/documentfragment~DocumentFragment} documentFragment Document fragment from which to remove `<img>` elements.\n// @param {module:engine/view/upcastwriter~UpcastWriter} writer\nfunction removeAllImgElementsRepresentingShapes( shapesIds, documentFragment, writer ) {\n\tconst range = writer.createRangeIn( documentFragment );\n\n\tconst imageElementsMatcher = new Matcher( {\n\t\tname: 'img'\n\t} );\n\n\tconst imgs = [];\n\n\tfor ( const value of range ) {\n\t\tif ( imageElementsMatcher.match( value.item ) ) {\n\t\t\tconst el = value.item;\n\t\t\tconst shapes = el.getAttribute( 'v:shapes' ) ? el.getAttribute( 'v:shapes' ).split( ' ' ) : [];\n\n\t\t\tif ( shapes.length && shapes.every( shape => shapesIds.indexOf( shape ) > -1 ) ) {\n\t\t\t\timgs.push( el );\n\t\t\t// Shapes may also have empty source while content is paste in some browsers (Safari).\n\t\t\t} else if ( !el.getAttribute( 'src' ) ) {\n\t\t\t\timgs.push( el );\n\t\t\t}\n\t\t}\n\t}\n\n\tfor ( const img of imgs ) {\n\t\twriter.remove( img );\n\t}\n}\n\n// Removes all shape elements (`<v:*>...</v:*>`) so they do not pollute the output structure.\n//\n// @param {module:engine/view/documentfragment~DocumentFragment} documentFragment Document fragment from which to remove shape elements.\n// @param {module:engine/view/upcastwriter~UpcastWriter} writer\nfunction removeAllShapeElements( documentFragment, writer ) {\n\tconst range = writer.createRangeIn( documentFragment );\n\n\tconst shapeElementsMatcher = new Matcher( {\n\t\tname: /v:(.+)/\n\t} );\n\n\tconst shapes = [];\n\n\tfor ( const value of range ) {\n\t\tif ( value.type == 'elementStart' && shapeElementsMatcher.match( value.item ) ) {\n\t\t\tshapes.push( value.item );\n\t\t}\n\t}\n\n\tfor ( const shape of shapes ) {\n\t\twriter.remove( shape );\n\t}\n}\n\n// Finds all `<img>` elements in a given document fragment which have source pointing to local `file://` resource.\n//\n// @param {module:engine/view/documentfragment~DocumentFragment} documentFragment Document fragment in which to look for `<img>` elements.\n// @param {module:engine/view/upcastwriter~UpcastWriter} writer\n// @returns {Object} result All found images grouped by source type.\n// @returns {Array.<module:engine/view/element~Element>} result.file Array of found `<img>` elements with `file://` source.\n// @returns {Array.<module:engine/view/element~Element>} result.blob Array of found `<img>` elements with `blob:` source.\nfunction findAllImageElementsWithLocalSource( documentFragment, writer ) {\n\tconst range = writer.createRangeIn( documentFragment );\n\n\tconst imageElementsMatcher = new Matcher( {\n\t\tname: 'img'\n\t} );\n\n\tconst imgs = [];\n\n\tfor ( const value of range ) {\n\t\tif ( imageElementsMatcher.match( value.item ) ) {\n\t\t\tif ( value.item.getAttribute( 'src' ).startsWith( 'file://' ) ) {\n\t\t\t\timgs.push( value.item );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn imgs;\n}\n\n// Extracts all images HEX representations from a given RTF data.\n//\n// @param {String} rtfData The RTF data from which to extract images HEX representation.\n// @returns {Array.<Object>} Array of found HEX representations. Each array item is an object containing:\n//\n// \t\t* {String} hex Image representation in HEX format.\n// \t\t* {string} type Type of image, `image/png` or `image/jpeg`.\nfunction extractImageDataFromRtf( rtfData ) {\n\tif ( !rtfData ) {\n\t\treturn [];\n\t}\n\n\tconst regexPictureHeader = /{\\\\pict[\\s\\S]+?\\\\bliptag-?\\d+(\\\\blipupi-?\\d+)?({\\\\\\*\\\\blipuid\\s?[\\da-fA-F]+)?[\\s}]*?/;\n\tconst regexPicture = new RegExp( '(?:(' + regexPictureHeader.source + '))([\\\\da-fA-F\\\\s]+)\\\\}', 'g' );\n\tconst images = rtfData.match( regexPicture );\n\tconst result = [];\n\n\tif ( images ) {\n\t\tfor ( const image of images ) {\n\t\t\tlet imageType = false;\n\n\t\t\tif ( image.includes( '\\\\pngblip' ) ) {\n\t\t\t\timageType = 'image/png';\n\t\t\t} else if ( image.includes( '\\\\jpegblip' ) ) {\n\t\t\t\timageType = 'image/jpeg';\n\t\t\t}\n\n\t\t\tif ( imageType ) {\n\t\t\t\tresult.push( {\n\t\t\t\t\thex: image.replace( regexPictureHeader, '' ).replace( /[^\\da-fA-F]/g, '' ),\n\t\t\t\t\ttype: imageType\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result;\n}\n\n// Replaces `src` attribute value of all given images with the corresponding base64 image representation.\n//\n// @param {Array.<module:engine/view/element~Element>} imageElements Array of image elements which will have its source replaced.\n// @param {Array.<Object>} imagesHexSources Array of images hex sources (usually the result of `extractImageDataFromRtf()` function).\n// The array should be the same length as `imageElements` parameter.\n// @param {module:engine/view/upcastwriter~UpcastWriter} writer\nfunction replaceImagesFileSourceWithInlineRepresentation( imageElements, imagesHexSources, writer ) {\n\t// Assume there is an equal amount of image elements and images HEX sources so they can be matched accordingly based on existing order.\n\tif ( imageElements.length === imagesHexSources.length ) {\n\t\tfor ( let i = 0; i < imageElements.length; i++ ) {\n\t\t\tconst newSrc = `data:${ imagesHexSources[ i ].type };base64,${ _convertHexToBase64( imagesHexSources[ i ].hex ) }`;\n\t\t\twriter.setAttribute( 'src', newSrc, imageElements[ i ] );\n\t\t}\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paste-from-office/filters/list\n */\n\nimport { Matcher, UpcastWriter } from 'ckeditor5/src/engine';\n\n/**\n * Transforms Word specific list-like elements to the semantic HTML lists.\n *\n * Lists in Word are represented by block elements with special attributes like:\n *\n *\t\t<p class=MsoListParagraphCxSpFirst style='mso-list:l1 level1 lfo1'>...</p> // Paragraph based list.\n *\t\t<h1 style='mso-list:l0 level1 lfo1'>...</h1> // Heading 1 based list.\n *\n * @param {module:engine/view/documentfragment~DocumentFragment} documentFragment The view structure to be transformed.\n * @param {String} stylesString Styles from which list-like elements styling will be extracted.\n */\nexport function transformListItemLikeElementsIntoLists( documentFragment, stylesString ) {\n\tif ( !documentFragment.childCount ) {\n\t\treturn;\n\t}\n\n\tconst writer = new UpcastWriter( documentFragment.document );\n\tconst itemLikeElements = findAllItemLikeElements( documentFragment, writer );\n\n\tif ( !itemLikeElements.length ) {\n\t\treturn;\n\t}\n\n\tlet currentList = null;\n\tlet currentIndentation = 1;\n\n\titemLikeElements.forEach( ( itemLikeElement, i ) => {\n\t\tconst isDifferentList = isNewListNeeded( itemLikeElements[ i - 1 ], itemLikeElement );\n\t\tconst previousItemLikeElement = isDifferentList ? null : itemLikeElements[ i - 1 ];\n\t\tconst indentationDifference = getIndentationDifference( previousItemLikeElement, itemLikeElement );\n\n\t\tif ( isDifferentList ) {\n\t\t\tcurrentList = null;\n\t\t\tcurrentIndentation = 1;\n\t\t}\n\n\t\tif ( !currentList || indentationDifference !== 0 ) {\n\t\t\tconst listStyle = detectListStyle( itemLikeElement, stylesString );\n\n\t\t\tif ( !currentList ) {\n\t\t\t\tcurrentList = insertNewEmptyList( listStyle, itemLikeElement.element, writer );\n\t\t\t} else if ( itemLikeElement.indent > currentIndentation ) {\n\t\t\t\tconst lastListItem = currentList.getChild( currentList.childCount - 1 );\n\t\t\t\tconst lastListItemChild = lastListItem.getChild( lastListItem.childCount - 1 );\n\n\t\t\t\tcurrentList = insertNewEmptyList( listStyle, lastListItemChild, writer );\n\t\t\t\tcurrentIndentation += 1;\n\t\t\t} else if ( itemLikeElement.indent < currentIndentation ) {\n\t\t\t\tconst differentIndentation = currentIndentation - itemLikeElement.indent;\n\n\t\t\t\tcurrentList = findParentListAtLevel( currentList, differentIndentation );\n\t\t\t\tcurrentIndentation = parseInt( itemLikeElement.indent );\n\t\t\t}\n\n\t\t\tif ( itemLikeElement.indent <= currentIndentation ) {\n\t\t\t\tif ( !currentList.is( 'element', listStyle.type ) ) {\n\t\t\t\t\tcurrentList = writer.rename( listStyle.type, currentList );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst listItem = transformElementIntoListItem( itemLikeElement.element, writer );\n\n\t\twriter.appendChild( listItem, currentList );\n\t} );\n}\n\n/**\n * Removes paragraph wrapping content inside a list item.\n *\n * @param {module:engine/view/documentfragment~DocumentFragment} documentFragment\n * @param {module:engine/view/upcastwriter~UpcastWriter} writer\n */\nexport function unwrapParagraphInListItem( documentFragment, writer ) {\n\tfor ( const value of writer.createRangeIn( documentFragment ) ) {\n\t\tconst element = value.item;\n\n\t\tif ( element.is( 'element', 'li' ) ) {\n\t\t\t// Google Docs allows for single paragraph inside LI.\n\t\t\tconst firstChild = element.getChild( 0 );\n\n\t\t\tif ( firstChild && firstChild.is( 'element', 'p' ) ) {\n\t\t\t\twriter.unwrapElement( firstChild );\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Finds all list-like elements in a given document fragment.\n//\n// @param {module:engine/view/documentfragment~DocumentFragment} documentFragment Document fragment\n// in which to look for list-like nodes.\n// @param {module:engine/view/upcastwriter~UpcastWriter} writer\n// @returns {Array.<Object>} Array of found list-like items. Each item is an object containing:\n//\n//\t\t* {module:engine/src/view/element~Element} element List-like element.\n//\t\t* {Number} id List item id parsed from `mso-list` style (see `getListItemData()` function).\n//\t\t* {Number} order List item creation order parsed from `mso-list` style (see `getListItemData()` function).\n//\t\t* {Number} indent List item indentation level parsed from `mso-list` style (see `getListItemData()` function).\nfunction findAllItemLikeElements( documentFragment, writer ) {\n\tconst range = writer.createRangeIn( documentFragment );\n\n\t// Matcher for finding list-like elements.\n\tconst itemLikeElementsMatcher = new Matcher( {\n\t\tname: /^p|h\\d+$/,\n\t\tstyles: {\n\t\t\t'mso-list': /.*/\n\t\t}\n\t} );\n\n\tconst itemLikeElements = [];\n\n\tfor ( const value of range ) {\n\t\tif ( value.type === 'elementStart' && itemLikeElementsMatcher.match( value.item ) ) {\n\t\t\tconst itemData = getListItemData( value.item );\n\n\t\t\titemLikeElements.push( {\n\t\t\t\telement: value.item,\n\t\t\t\tid: itemData.id,\n\t\t\t\torder: itemData.order,\n\t\t\t\tindent: itemData.indent\n\t\t\t} );\n\t\t}\n\t}\n\n\treturn itemLikeElements;\n}\n\n// Extracts list item style from the provided CSS.\n//\n// List item style is extracted from the CSS stylesheet. Each list with its specific style attribute\n// value (`mso-list:l1 level1 lfo1`) has its dedicated properties in a CSS stylesheet defined with a selector like:\n//\n// \t\t@list l1:level1 { ... }\n//\n// It contains `mso-level-number-format` property which defines list numbering/bullet style. If this property\n// is not defined it means default `decimal` numbering.\n//\n// Here CSS string representation is used as `mso-level-number-format` property is an invalid CSS property\n// and will be removed during CSS parsing.\n//\n// @param {Object} listLikeItem List-like item for which list style will be searched for. Usually\n// a result of `findAllItemLikeElements()` function.\n// @param {String} stylesString CSS stylesheet.\n// @returns {Object} result\n// @returns {String} result.type List type, could be `ul` or `ol`.\n// @returns {Number} result.startIndex List start index, valid only for ordered lists.\n// @returns {String|null} result.style List style, for example: `decimal`, `lower-roman`, etc. It is extracted\n// directly from Word stylesheet and adjusted to represent proper values for the CSS `list-style-type` property.\n// If it cannot be adjusted, the `null` value is returned.\nfunction detectListStyle( listLikeItem, stylesString ) {\n\tconst listStyleRegexp = new RegExp( `@list l${ listLikeItem.id }:level${ listLikeItem.indent }\\\\s*({[^}]*)`, 'gi' );\n\tconst listStyleTypeRegex = /mso-level-number-format:([^;]{0,100});/gi;\n\tconst listStartIndexRegex = /mso-level-start-at:\\s{0,100}([0-9]{0,10})\\s{0,100};/gi;\n\n\tconst listStyleMatch = listStyleRegexp.exec( stylesString );\n\n\tlet listStyleType = 'decimal'; // Decimal is default one.\n\tlet type = 'ol'; // <ol> is default list.\n\tlet startIndex = null;\n\n\tif ( listStyleMatch && listStyleMatch[ 1 ] ) {\n\t\tconst listStyleTypeMatch = listStyleTypeRegex.exec( listStyleMatch[ 1 ] );\n\n\t\tif ( listStyleTypeMatch && listStyleTypeMatch[ 1 ] ) {\n\t\t\tlistStyleType = listStyleTypeMatch[ 1 ].trim();\n\t\t\ttype = listStyleType !== 'bullet' && listStyleType !== 'image' ? 'ol' : 'ul';\n\t\t}\n\n\t\t// Styles for the numbered lists are always defined in the Word CSS stylesheet.\n\t\t// Unordered lists MAY contain a value for the Word CSS definition `mso-level-text` but sometimes\n\t\t// this tag is missing. And because of that, we cannot depend on that. We need to predict the list style value\n\t\t// based on the list style marker element.\n\t\tif ( listStyleType === 'bullet' ) {\n\t\t\tconst bulletedStyle = findBulletedListStyle( listLikeItem.element );\n\n\t\t\tif ( bulletedStyle ) {\n\t\t\t\tlistStyleType = bulletedStyle;\n\t\t\t}\n\t\t} else {\n\t\t\tconst listStartIndexMatch = listStartIndexRegex.exec( listStyleMatch[ 1 ] );\n\n\t\t\tif ( listStartIndexMatch && listStartIndexMatch[ 1 ] ) {\n\t\t\t\tstartIndex = parseInt( listStartIndexMatch[ 1 ] );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\ttype,\n\t\tstartIndex,\n\t\tstyle: mapListStyleDefinition( listStyleType )\n\t};\n}\n\n// Tries to extract the `list-style-type` value based on the marker element for bulleted list.\n//\n// @param {module:engine/view/element~Element} element\n// @returns {String|null}\nfunction findBulletedListStyle( element ) {\n\tconst listMarkerElement = findListMarkerNode( element );\n\n\tif ( !listMarkerElement ) {\n\t\treturn null;\n\t}\n\n\tconst listMarker = listMarkerElement._data;\n\n\tif ( listMarker === 'o' ) {\n\t\treturn 'circle';\n\t} else if ( listMarker === '·' ) {\n\t\treturn 'disc';\n\t}\n\t// Word returns '§' instead of '■' for the square list style.\n\telse if ( listMarker === '§' ) {\n\t\treturn 'square';\n\t}\n\n\treturn null;\n}\n\n// Tries to find a text node that represents the marker element (list-style-type).\n//\n// @param {module:engine/view/element~Element} element\n// @returns {module:engine/view/text~Text|null}\nfunction findListMarkerNode( element ) {\n\t// If the first child is a text node, it is the data for the element.\n\t// The list-style marker is not present here.\n\tif ( element.getChild( 0 ).is( '$text' ) ) {\n\t\treturn null;\n\t}\n\n\tfor ( const childNode of element.getChildren() ) {\n\t\t// The list-style marker will be inside the `<span>` element. Let's ignore all non-span elements.\n\t\t// It may happen that the `<a>` element is added as the first child. Most probably, it's an anchor element.\n\t\tif ( !childNode.is( 'element', 'span' ) ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst textNodeOrElement = childNode.getChild( 0 );\n\n\t\t// If already found the marker element, use it.\n\t\tif ( textNodeOrElement.is( '$text' ) ) {\n\t\t\treturn textNodeOrElement;\n\t\t}\n\n\t\treturn textNodeOrElement.getChild( 0 );\n\t}\n}\n\n// Parses the `list-style-type` value extracted directly from the Word CSS stylesheet and returns proper CSS definition.\n//\n// @param {String|null} value\n// @returns {String|null}\nfunction mapListStyleDefinition( value ) {\n\tif ( value.startsWith( 'arabic-leading-zero' ) ) {\n\t\treturn 'decimal-leading-zero';\n\t}\n\n\tswitch ( value ) {\n\t\tcase 'alpha-upper':\n\t\t\treturn 'upper-alpha';\n\t\tcase 'alpha-lower':\n\t\t\treturn 'lower-alpha';\n\t\tcase 'roman-upper':\n\t\t\treturn 'upper-roman';\n\t\tcase 'roman-lower':\n\t\t\treturn 'lower-roman';\n\t\tcase 'circle':\n\t\tcase 'disc':\n\t\tcase 'square':\n\t\t\treturn value;\n\t\tdefault:\n\t\t\treturn null;\n\t}\n}\n\n// Creates an empty list of a given type and inserts it after a specified element.\n//\n// @param {Object} listStyle List style object which determines the type of newly created list.\n// Usually a result of `detectListStyle()` function.\n// @param {module:engine/view/element~Element} element Element after which list is inserted.\n// @param {module:engine/view/upcastwriter~UpcastWriter} writer\n// @returns {module:engine/view/element~Element} Newly created list element.\n\nfunction insertNewEmptyList( listStyle, element, writer ) {\n\tconst parent = element.parent;\n\tconst list = writer.createElement( listStyle.type );\n\tconst position = parent.getChildIndex( element ) + 1;\n\n\twriter.insertChild( position, list, parent );\n\n\t// We do not support modifying the marker for a particular list item.\n\t// Set the value for the `list-style-type` property directly to the list container.\n\tif ( listStyle.style ) {\n\t\twriter.setStyle( 'list-style-type', listStyle.style, list );\n\t}\n\n\tif ( listStyle.startIndex && listStyle.startIndex > 1 ) {\n\t\twriter.setAttribute( 'start', listStyle.startIndex, list );\n\t}\n\n\treturn list;\n}\n\n// Transforms a given element into a semantic list item. As the function operates on a provided\n// {module:engine/src/view/element~Element element} it will modify the view structure to which this element belongs.\n//\n// @param {module:engine/view/element~Element} element Element which will be transformed into a list item.\n// @param {module:engine/view/upcastwriter~UpcastWriter} writer\n// @returns {module:engine/view/element~Element} New element to which the given one was transformed. It is\n// inserted in place of the old element (the reference to the old element is lost due to renaming).\nfunction transformElementIntoListItem( element, writer ) {\n\tremoveBulletElement( element, writer );\n\n\treturn writer.rename( 'li', element );\n}\n\n// Extracts list item information from Word specific list-like element style:\n//\n//\t\t`style=\"mso-list:l1 level1 lfo1\"`\n//\n// where:\n//\n//\t\t* `l1` is a list id (however it does not mean this is a continuous list - see #43),\n//\t\t* `level1` is a list item indentation level,\n//\t\t* `lfo1` is a list insertion order in a document.\n//\n// @param {module:engine/view/element~Element} element Element from which style data is extracted.\n// @returns {Object} result\n// @returns {Number} result.id Parent list id.\n// @returns {Number} result.order List item creation order.\n// @returns {Number} result.indent List item indentation level.\nfunction getListItemData( element ) {\n\tconst data = {};\n\tconst listStyle = element.getStyle( 'mso-list' );\n\n\tif ( listStyle ) {\n\t\tconst idMatch = listStyle.match( /(^|\\s{1,100})l(\\d+)/i );\n\t\tconst orderMatch = listStyle.match( /\\s{0,100}lfo(\\d+)/i );\n\t\tconst indentMatch = listStyle.match( /\\s{0,100}level(\\d+)/i );\n\n\t\tif ( idMatch && orderMatch && indentMatch ) {\n\t\t\tdata.id = idMatch[ 2 ];\n\t\t\tdata.order = orderMatch[ 1 ];\n\t\t\tdata.indent = indentMatch[ 1 ];\n\t\t}\n\t}\n\n\treturn data;\n}\n\n// Removes span with a numbering/bullet from a given element.\n//\n// @param {module:engine/view/element~Element} element\n// @param {module:engine/view/upcastwriter~UpcastWriter} writer\nfunction removeBulletElement( element, writer ) {\n\t// Matcher for finding `span` elements holding lists numbering/bullets.\n\tconst bulletMatcher = new Matcher( {\n\t\tname: 'span',\n\t\tstyles: {\n\t\t\t'mso-list': 'Ignore'\n\t\t}\n\t} );\n\n\tconst range = writer.createRangeIn( element );\n\n\tfor ( const value of range ) {\n\t\tif ( value.type === 'elementStart' && bulletMatcher.match( value.item ) ) {\n\t\t\twriter.remove( value.item );\n\t\t}\n\t}\n}\n\n// Whether the previous and current items belong to the same list. It is determined based on `item.id`\n// (extracted from `mso-list` style, see #getListItemData) and a previous sibling of the current item.\n//\n// However, it's quite easy to change the `id` attribute for nested lists in Word. It will break the list feature while pasting.\n// Let's check also the `indent` attribute. If the difference between those two elements is equal to 1, we can assume that\n// the `currentItem` is a beginning of the nested list because lists in CKEditor 5 always start with the `indent=0` attribute.\n// See: https://github.com/ckeditor/ckeditor5/issues/7805.\n//\n// @param {Object} previousItem\n// @param {Object} currentItem\n// @returns {Boolean}\nfunction isNewListNeeded( previousItem, currentItem ) {\n\tif ( !previousItem ) {\n\t\treturn true;\n\t}\n\n\tif ( previousItem.id !== currentItem.id ) {\n\t\t// See: https://github.com/ckeditor/ckeditor5/issues/7805.\n\t\t//\n\t\t// * List item 1.\n\t\t// - Nested list item 1.\n\t\tif ( currentItem.indent - previousItem.indent === 1 ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tconst previousSibling = currentItem.element.previousSibling;\n\n\tif ( !previousSibling ) {\n\t\treturn true;\n\t}\n\n\t// Even with the same id the list does not have to be continuous (#43).\n\treturn !isList( previousSibling );\n}\n\nfunction isList( element ) {\n\treturn element.is( 'element', 'ol' ) || element.is( 'element', 'ul' );\n}\n\n// Calculates the indentation difference between two given list items (based on the indent attribute\n// extracted from the `mso-list` style, see #getListItemData).\n//\n// @param {Object} previousItem\n// @param {Object} currentItem\n// @returns {Number}\nfunction getIndentationDifference( previousItem, currentItem ) {\n\treturn previousItem ? currentItem.indent - previousItem.indent : currentItem.indent - 1;\n}\n\n// Finds the parent list element (ul/ol) of a given list element with indentation level lower by a given value.\n//\n// @param {module:engine/view/element~Element} listElement List element from which to start looking for a parent list.\n// @param {Number} indentationDifference Indentation difference between lists.\n// @returns {module:engine/view/element~Element} Found list element with indentation level lower by a given value.\nfunction findParentListAtLevel( listElement, indentationDifference ) {\n\tconst ancestors = listElement.getAncestors( { parentFirst: true } );\n\n\tlet parentList = null;\n\tlet levelChange = 0;\n\n\tfor ( const ancestor of ancestors ) {\n\t\tif ( ancestor.name === 'ul' || ancestor.name === 'ol' ) {\n\t\t\tlevelChange++;\n\t\t}\n\n\t\tif ( levelChange === indentationDifference ) {\n\t\t\tparentList = ancestor;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn parentList;\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paste-from-office/filters/parse\n */\n\n/* globals DOMParser */\n\nimport { DomConverter, ViewDocument } from 'ckeditor5/src/engine';\n\nimport { normalizeSpacing, normalizeSpacerunSpans } from './space';\n\n/**\n * Parses provided HTML extracting contents of `<body>` and `<style>` tags.\n *\n * @param {String} htmlString HTML string to be parsed.\n * @param {module:engine/view/stylesmap~StylesProcessor} stylesProcessor\n * @returns {Object} result\n * @returns {module:engine/view/documentfragment~DocumentFragment} result.body Parsed body\n * content as a traversable structure.\n * @returns {String} result.bodyString Entire body content as a string.\n * @returns {Array.<CSSStyleSheet>} result.styles Array of native `CSSStyleSheet` objects, each representing\n * separate `style` tag from the source HTML.\n * @returns {String} result.stylesString All `style` tags contents combined in the order of occurrence into one string.\n */\nexport function parseHtml( htmlString, stylesProcessor ) {\n\tconst domParser = new DOMParser();\n\n\t// Remove Word specific \"if comments\" so content inside is not omitted by the parser.\n\thtmlString = htmlString.replace( /<!--\\[if gte vml 1]>/g, '' );\n\n\tconst normalizedHtml = normalizeSpacing( cleanContentAfterBody( htmlString ) );\n\n\t// Parse htmlString as native Document object.\n\tconst htmlDocument = domParser.parseFromString( normalizedHtml, 'text/html' );\n\n\tnormalizeSpacerunSpans( htmlDocument );\n\n\t// Get `innerHTML` first as transforming to View modifies the source document.\n\tconst bodyString = htmlDocument.body.innerHTML;\n\n\t// Transform document.body to View.\n\tconst bodyView = documentToView( htmlDocument, stylesProcessor );\n\n\t// Extract stylesheets.\n\tconst stylesObject = extractStyles( htmlDocument );\n\n\treturn {\n\t\tbody: bodyView,\n\t\tbodyString,\n\t\tstyles: stylesObject.styles,\n\t\tstylesString: stylesObject.stylesString\n\t};\n}\n\n// Transforms native `Document` object into {@link module:engine/view/documentfragment~DocumentFragment}. Comments are skipped.\n//\n// @param {Document} htmlDocument Native `Document` object to be transformed.\n// @param {module:engine/view/stylesmap~StylesProcessor} stylesProcessor\n// @returns {module:engine/view/documentfragment~DocumentFragment}\nfunction documentToView( htmlDocument, stylesProcessor ) {\n\tconst viewDocument = new ViewDocument( stylesProcessor );\n\tconst domConverter = new DomConverter( viewDocument, { renderingMode: 'data' } );\n\tconst fragment = htmlDocument.createDocumentFragment();\n\tconst nodes = htmlDocument.body.childNodes;\n\n\twhile ( nodes.length > 0 ) {\n\t\tfragment.appendChild( nodes[ 0 ] );\n\t}\n\n\treturn domConverter.domToView( fragment, { skipComments: true } );\n}\n\n// Extracts both `CSSStyleSheet` and string representation from all `style` elements available in a provided `htmlDocument`.\n//\n// @param {Document} htmlDocument Native `Document` object from which styles will be extracted.\n// @returns {Object} result\n// @returns {Array.<CSSStyleSheet>} result.styles Array of native `CSSStyleSheet` object, each representing\n// separate `style` tag from the source object.\n// @returns {String} result.stylesString All `style` tags contents combined in the order of occurrence as one string.\nfunction extractStyles( htmlDocument ) {\n\tconst styles = [];\n\tconst stylesString = [];\n\tconst styleTags = Array.from( htmlDocument.getElementsByTagName( 'style' ) );\n\n\tfor ( const style of styleTags ) {\n\t\tif ( style.sheet && style.sheet.cssRules && style.sheet.cssRules.length ) {\n\t\t\tstyles.push( style.sheet );\n\t\t\tstylesString.push( style.innerHTML );\n\t\t}\n\t}\n\n\treturn {\n\t\tstyles,\n\t\tstylesString: stylesString.join( ' ' )\n\t};\n}\n\n// Removes leftover content from between closing </body> and closing </html> tag:\n//\n// \t\t<html><body><p>Foo Bar</p></body><span>Fo</span></html> -> <html><body><p>Foo Bar</p></body></html>\n//\n// This function is used as specific browsers (Edge) add some random content after `body` tag when pasting from Word.\n// @param {String} htmlString The HTML string to be cleaned.\n// @returns {String} The HTML string with leftover content removed.\nfunction cleanContentAfterBody( htmlString ) {\n\tconst bodyCloseTag = '</body>';\n\tconst htmlCloseTag = '</html>';\n\n\tconst bodyCloseIndex = htmlString.indexOf( bodyCloseTag );\n\n\tif ( bodyCloseIndex < 0 ) {\n\t\treturn htmlString;\n\t}\n\n\tconst htmlCloseIndex = htmlString.indexOf( htmlCloseTag, bodyCloseIndex + bodyCloseTag.length );\n\n\treturn htmlString.substring( 0, bodyCloseIndex + bodyCloseTag.length ) +\n\t\t( htmlCloseIndex >= 0 ? htmlString.substring( htmlCloseIndex ) : '' );\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paste-from-office/filters/removeboldwrapper\n */\n\n/**\n * Removes `<b>` tag wrapper added by Google Docs to a copied content.\n *\n * @param {module:engine/view/documentfragment~DocumentFragment} documentFragment element `data.content` obtained from clipboard\n * @param {module:engine/view/upcastwriter~UpcastWriter} writer\n */\nexport default function removeBoldWrapper( documentFragment, writer ) {\n\tfor ( const child of documentFragment.getChildren() ) {\n\t\tif ( child.is( 'element', 'b' ) && child.getStyle( 'font-weight' ) === 'normal' ) {\n\t\t\tconst childIndex = documentFragment.getChildIndex( child );\n\n\t\t\twriter.remove( child );\n\t\t\twriter.insertChild( childIndex, child.getChildren(), documentFragment );\n\t\t}\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paste-from-office/filters/space\n */\n\n/**\n * Replaces last space preceding elements closing tag with ` `. Such operation prevents spaces from being removed\n * during further DOM/View processing (see especially {@link module:engine/view/domconverter~DomConverter#_processDataFromDomText}).\n * This method also takes into account Word specific `<o:p></o:p>` empty tags.\n * Additionally multiline sequences of spaces and new lines between tags are removed (see #39 and #40).\n *\n * @param {String} htmlString HTML string in which spacing should be normalized.\n * @returns {String} Input HTML with spaces normalized.\n */\nexport function normalizeSpacing( htmlString ) {\n\t// Run normalizeSafariSpaceSpans() two times to cover nested spans.\n\treturn normalizeSafariSpaceSpans( normalizeSafariSpaceSpans( htmlString ) )\n\t\t// Remove all \\r\\n from \"spacerun spans\" so the last replace line doesn't strip all whitespaces.\n\t\t.replace( /(<span\\s+style=['\"]mso-spacerun:yes['\"]>[^\\S\\r\\n]*?)[\\r\\n]+([^\\S\\r\\n]*<\\/span>)/g, '$1$2' )\n\t\t.replace( /<span\\s+style=['\"]mso-spacerun:yes['\"]><\\/span>/g, '' )\n\t\t.replace( / <\\//g, '\\u00A0</' )\n\t\t.replace( / <o:p><\\/o:p>/g, '\\u00A0<o:p></o:p>' )\n\t\t// Remove <o:p> block filler from empty paragraph. Safari uses \\u00A0 instead of .\n\t\t.replace( /<o:p>( |\\u00A0)<\\/o:p>/g, '' )\n\t\t// Remove all whitespaces when they contain any \\r or \\n.\n\t\t.replace( />([^\\S\\r\\n]*[\\r\\n]\\s*)</g, '><' );\n}\n\n/**\n * Normalizes spacing in special Word `spacerun spans` (`<span style='mso-spacerun:yes'>\\s+</span>`) by replacing\n * all spaces with ` ` pairs. This prevents spaces from being removed during further DOM/View processing\n * (see especially {@link module:engine/view/domconverter~DomConverter#_processDataFromDomText}).\n *\n * @param {Document} htmlDocument Native `Document` object in which spacing should be normalized.\n */\nexport function normalizeSpacerunSpans( htmlDocument ) {\n\thtmlDocument.querySelectorAll( 'span[style*=spacerun]' ).forEach( el => {\n\t\tconst innerTextLength = el.innerText.length || 0;\n\n\t\tel.innerText = Array( innerTextLength + 1 ).join( '\\u00A0 ' ).substr( 0, innerTextLength );\n\t} );\n}\n\n// Normalizes specific spacing generated by Safari when content pasted from Word (`<span class=\"Apple-converted-space\"> </span>`)\n// by replacing all spaces sequences longer than 1 space with ` ` pairs. This prevents spaces from being removed during\n// further DOM/View processing (see especially {@link module:engine/view/domconverter~DomConverter#_processDataFromDomText}).\n//\n// This function is similar to {@link module:clipboard/utils/normalizeclipboarddata normalizeClipboardData util} but uses\n// regular spaces / sequence for replacement.\n//\n// @param {String} htmlString HTML string in which spacing should be normalized\n// @returns {String} Input HTML with spaces normalized.\nfunction normalizeSafariSpaceSpans( htmlString ) {\n\treturn htmlString.replace( /<span(?: class=\"Apple-converted-space\"|)>(\\s+)<\\/span>/g, ( fullMatch, spaces ) => {\n\t\treturn spaces.length === 1 ? ' ' : Array( spaces.length + 1 ).join( '\\u00A0 ' ).substr( 0, spaces.length );\n\t} );\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paste-from-office/normalizers/googledocsnormalizer\n */\n\nimport { UpcastWriter } from 'ckeditor5/src/engine';\n\nimport removeBoldWrapper from '../filters/removeboldwrapper';\nimport transformBlockBrsToParagraphs from '../filters/br';\nimport { unwrapParagraphInListItem } from '../filters/list';\n\nconst googleDocsMatch = /id=(\"|')docs-internal-guid-[-0-9a-f]+(\"|')/i;\n\n/**\n * Normalizer for the content pasted from Google Docs.\n *\n * @implements module:paste-from-office/normalizer~Normalizer\n */\nexport default class GoogleDocsNormalizer {\n\t/**\n\t * Creates a new `GoogleDocsNormalizer` instance.\n\t *\n\t * @param {module:engine/view/document~Document} document View document.\n\t */\n\tconstructor( document ) {\n\t\t/**\n\t\t * @readonly\n\t\t * @type {module:engine/view/document~Document}\n\t\t */\n\t\tthis.document = document;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tisActive( htmlString ) {\n\t\treturn googleDocsMatch.test( htmlString );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\texecute( data ) {\n\t\tconst writer = new UpcastWriter( this.document );\n\t\tconst { body: documentFragment } = data._parsedData;\n\n\t\tremoveBoldWrapper( documentFragment, writer );\n\t\tunwrapParagraphInListItem( documentFragment, writer );\n\t\ttransformBlockBrsToParagraphs( documentFragment, writer );\n\n\t\tdata.content = documentFragment;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paste-from-office/normalizers/mswordnormalizer\n */\n\nimport { transformListItemLikeElementsIntoLists } from '../filters/list';\nimport { replaceImagesSourceWithBase64 } from '../filters/image';\n\nconst msWordMatch1 = /<meta\\s*name=\"?generator\"?\\s*content=\"?microsoft\\s*word\\s*\\d+\"?\\/?>/i;\nconst msWordMatch2 = /xmlns:o=\"urn:schemas-microsoft-com/i;\n\n/**\n * Normalizer for the content pasted from Microsoft Word.\n *\n * @implements module:paste-from-office/normalizer~Normalizer\n */\nexport default class MSWordNormalizer {\n\t/**\n\t * Creates a new `MSWordNormalizer` instance.\n\t *\n\t * @param {module:engine/view/document~Document} document View document.\n\t */\n\tconstructor( document ) {\n\t\t/**\n\t\t * @readonly\n\t\t * @type {module:engine/view/document~Document}\n\t\t */\n\t\tthis.document = document;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tisActive( htmlString ) {\n\t\treturn msWordMatch1.test( htmlString ) || msWordMatch2.test( htmlString );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\texecute( data ) {\n\t\tconst { body: documentFragment, stylesString } = data._parsedData;\n\n\t\ttransformListItemLikeElementsIntoLists( documentFragment, stylesString );\n\t\treplaceImagesSourceWithBase64( documentFragment, data.dataTransfer.getData( 'text/rtf' ) );\n\n\t\tdata.content = documentFragment;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paste-from-office/pastefromoffice\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport { ClipboardPipeline } from 'ckeditor5/src/clipboard';\n\nimport GoogleDocsNormalizer from './normalizers/googledocsnormalizer';\nimport MSWordNormalizer from './normalizers/mswordnormalizer';\n\nimport { parseHtml } from './filters/parse';\n\n/**\n * The Paste from Office plugin.\n *\n * This plugin handles content pasted from Office apps and transforms it (if necessary)\n * to a valid structure which can then be understood by the editor features.\n *\n * Transformation is made by a set of predefined {@link module:paste-from-office/normalizer~Normalizer normalizers}.\n * This plugin includes following normalizers:\n * * {@link module:paste-from-office/normalizers/mswordnormalizer~MSWordNormalizer Microsoft Word normalizer}\n * * {@link module:paste-from-office/normalizers/googledocsnormalizer~GoogleDocsNormalizer Google Docs normalizer}\n *\n * For more information about this feature check the {@glink api/paste-from-office package page}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class PasteFromOffice extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'PasteFromOffice';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ClipboardPipeline ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst viewDocument = editor.editing.view.document;\n\t\tconst normalizers = [];\n\n\t\tnormalizers.push( new MSWordNormalizer( viewDocument ) );\n\t\tnormalizers.push( new GoogleDocsNormalizer( viewDocument ) );\n\n\t\teditor.plugins.get( 'ClipboardPipeline' ).on(\n\t\t\t'inputTransformation',\n\t\t\t( evt, data ) => {\n\t\t\t\tif ( data._isTransformedWithPasteFromOffice ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst codeBlock = editor.model.document.selection.getFirstPosition().parent;\n\n\t\t\t\tif ( codeBlock.is( 'element', 'codeBlock' ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst htmlString = data.dataTransfer.getData( 'text/html' );\n\t\t\t\tconst activeNormalizer = normalizers.find( normalizer => normalizer.isActive( htmlString ) );\n\n\t\t\t\tif ( activeNormalizer ) {\n\t\t\t\t\tdata._parsedData = parseHtml( htmlString, viewDocument.stylesProcessor );\n\n\t\t\t\t\tactiveNormalizer.execute( data );\n\n\t\t\t\t\tdata._isTransformedWithPasteFromOffice = true;\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ priority: 'high' }\n\t\t);\n\t}\n}\n","module.exports = (__webpack_require__(/*! dll-reference CKEditor5.dll */ \"dll-reference CKEditor5.dll\"))(\"./src/clipboard.js\");","module.exports = (__webpack_require__(/*! dll-reference CKEditor5.dll */ \"dll-reference CKEditor5.dll\"))(\"./src/core.js\");","module.exports = (__webpack_require__(/*! dll-reference CKEditor5.dll */ \"dll-reference CKEditor5.dll\"))(\"./src/engine.js\");","module.exports = CKEditor5.dll;","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paste-from-office\n */\n\nexport { default as PasteFromOffice } from './pastefromoffice';\n"],"names":[],"sourceRoot":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ckeditor/ckeditor5-paste-from-office",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "40.0.0",
|
|
4
4
|
"description": "Paste from Office feature for CKEditor 5.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ckeditor",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
],
|
|
13
13
|
"main": "src/index.js",
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"ckeditor5": "
|
|
15
|
+
"ckeditor5": "40.0.0"
|
|
16
16
|
},
|
|
17
17
|
"author": "CKSource (http://cksource.com/)",
|
|
18
18
|
"license": "GPL-2.0-or-later",
|
package/src/augmentation.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2023, 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
|
-
import type { PasteFromOffice } from './index';
|
|
6
|
-
declare module '@ckeditor/ckeditor5-core' {
|
|
7
|
-
interface PluginsMap {
|
|
8
|
-
[PasteFromOffice.pluginName]: PasteFromOffice;
|
|
9
|
-
}
|
|
10
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2023, 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
|
+
import type { PasteFromOffice } from './index';
|
|
6
|
+
declare module '@ckeditor/ckeditor5-core' {
|
|
7
|
+
interface PluginsMap {
|
|
8
|
+
[PasteFromOffice.pluginName]: PasteFromOffice;
|
|
9
|
+
}
|
|
10
|
+
}
|
package/src/augmentation.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2023, 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
|
-
export {};
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2023, 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
|
+
export {};
|
package/src/filters/br.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2023, 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/br
|
|
7
|
-
*/
|
|
8
|
-
import { type UpcastWriter, type ViewDocumentFragment } from 'ckeditor5/src/engine';
|
|
9
|
-
/**
|
|
10
|
-
* Transforms `<br>` elements that are siblings to some block element into a paragraphs.
|
|
11
|
-
*
|
|
12
|
-
* @param documentFragment The view structure to be transformed.
|
|
13
|
-
*/
|
|
14
|
-
export default function transformBlockBrsToParagraphs(documentFragment: ViewDocumentFragment, writer: UpcastWriter): void;
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2023, 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/br
|
|
7
|
+
*/
|
|
8
|
+
import { type UpcastWriter, type ViewDocumentFragment } from 'ckeditor5/src/engine';
|
|
9
|
+
/**
|
|
10
|
+
* Transforms `<br>` elements that are siblings to some block element into a paragraphs.
|
|
11
|
+
*
|
|
12
|
+
* @param documentFragment The view structure to be transformed.
|
|
13
|
+
*/
|
|
14
|
+
export default function transformBlockBrsToParagraphs(documentFragment: ViewDocumentFragment, writer: UpcastWriter): void;
|
package/src/filters/br.js
CHANGED
|
@@ -1,65 +1,65 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2023, 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/br
|
|
7
|
-
*/
|
|
8
|
-
import { DomConverter, ViewDocument } from 'ckeditor5/src/engine';
|
|
9
|
-
/**
|
|
10
|
-
* Transforms `<br>` elements that are siblings to some block element into a paragraphs.
|
|
11
|
-
*
|
|
12
|
-
* @param documentFragment The view structure to be transformed.
|
|
13
|
-
*/
|
|
14
|
-
export default function transformBlockBrsToParagraphs(documentFragment, writer) {
|
|
15
|
-
const viewDocument = new ViewDocument(writer.document.stylesProcessor);
|
|
16
|
-
const domConverter = new DomConverter(viewDocument, { renderingMode: 'data' });
|
|
17
|
-
const blockElements = domConverter.blockElements;
|
|
18
|
-
const inlineObjectElements = domConverter.inlineObjectElements;
|
|
19
|
-
const elementsToReplace = [];
|
|
20
|
-
for (const value of writer.createRangeIn(documentFragment)) {
|
|
21
|
-
const element = value.item;
|
|
22
|
-
if (element.is('element', 'br')) {
|
|
23
|
-
const nextSibling = findSibling(element, 'forward', writer, { blockElements, inlineObjectElements });
|
|
24
|
-
const previousSibling = findSibling(element, 'backward', writer, { blockElements, inlineObjectElements });
|
|
25
|
-
const nextSiblingIsBlock = isBlockViewElement(nextSibling, blockElements);
|
|
26
|
-
const previousSiblingIsBlock = isBlockViewElement(previousSibling, blockElements);
|
|
27
|
-
// If the <br> is surrounded by blocks then convert it to a paragraph:
|
|
28
|
-
// * <p>foo</p>[<br>]<p>bar</p> -> <p>foo</p>[<p></p>]<p>bar</p>
|
|
29
|
-
// * <p>foo</p>[<br>] -> <p>foo</p>[<p></p>]
|
|
30
|
-
// * [<br>]<p>foo</p> -> [<p></p>]<p>foo</p>
|
|
31
|
-
if (previousSiblingIsBlock || nextSiblingIsBlock) {
|
|
32
|
-
elementsToReplace.push(element);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
for (const element of elementsToReplace) {
|
|
37
|
-
if (element.hasClass('Apple-interchange-newline')) {
|
|
38
|
-
writer.remove(element);
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
writer.replace(element, writer.createElement('p'));
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Returns sibling node, threats inline elements as transparent (but should stop on an inline objects).
|
|
47
|
-
*/
|
|
48
|
-
function findSibling(viewElement, direction, writer, { blockElements, inlineObjectElements }) {
|
|
49
|
-
let position = writer.createPositionAt(viewElement, direction == 'forward' ? 'after' : 'before');
|
|
50
|
-
// Find first position that is just before a first:
|
|
51
|
-
// * text node,
|
|
52
|
-
// * block element,
|
|
53
|
-
// * inline object element.
|
|
54
|
-
// It's ignoring any inline (non-object) elements like span, strong, etc.
|
|
55
|
-
position = position.getLastMatchingPosition(({ item }) => (item.is('element') &&
|
|
56
|
-
!blockElements.includes(item.name) &&
|
|
57
|
-
!inlineObjectElements.includes(item.name)), { direction });
|
|
58
|
-
return direction == 'forward' ? position.nodeAfter : position.nodeBefore;
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Returns true for view elements that are listed as block view elements.
|
|
62
|
-
*/
|
|
63
|
-
function isBlockViewElement(node, blockElements) {
|
|
64
|
-
return !!node && node.is('element') && blockElements.includes(node.name);
|
|
65
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2023, 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/br
|
|
7
|
+
*/
|
|
8
|
+
import { DomConverter, ViewDocument } from 'ckeditor5/src/engine';
|
|
9
|
+
/**
|
|
10
|
+
* Transforms `<br>` elements that are siblings to some block element into a paragraphs.
|
|
11
|
+
*
|
|
12
|
+
* @param documentFragment The view structure to be transformed.
|
|
13
|
+
*/
|
|
14
|
+
export default function transformBlockBrsToParagraphs(documentFragment, writer) {
|
|
15
|
+
const viewDocument = new ViewDocument(writer.document.stylesProcessor);
|
|
16
|
+
const domConverter = new DomConverter(viewDocument, { renderingMode: 'data' });
|
|
17
|
+
const blockElements = domConverter.blockElements;
|
|
18
|
+
const inlineObjectElements = domConverter.inlineObjectElements;
|
|
19
|
+
const elementsToReplace = [];
|
|
20
|
+
for (const value of writer.createRangeIn(documentFragment)) {
|
|
21
|
+
const element = value.item;
|
|
22
|
+
if (element.is('element', 'br')) {
|
|
23
|
+
const nextSibling = findSibling(element, 'forward', writer, { blockElements, inlineObjectElements });
|
|
24
|
+
const previousSibling = findSibling(element, 'backward', writer, { blockElements, inlineObjectElements });
|
|
25
|
+
const nextSiblingIsBlock = isBlockViewElement(nextSibling, blockElements);
|
|
26
|
+
const previousSiblingIsBlock = isBlockViewElement(previousSibling, blockElements);
|
|
27
|
+
// If the <br> is surrounded by blocks then convert it to a paragraph:
|
|
28
|
+
// * <p>foo</p>[<br>]<p>bar</p> -> <p>foo</p>[<p></p>]<p>bar</p>
|
|
29
|
+
// * <p>foo</p>[<br>] -> <p>foo</p>[<p></p>]
|
|
30
|
+
// * [<br>]<p>foo</p> -> [<p></p>]<p>foo</p>
|
|
31
|
+
if (previousSiblingIsBlock || nextSiblingIsBlock) {
|
|
32
|
+
elementsToReplace.push(element);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
for (const element of elementsToReplace) {
|
|
37
|
+
if (element.hasClass('Apple-interchange-newline')) {
|
|
38
|
+
writer.remove(element);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
writer.replace(element, writer.createElement('p'));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Returns sibling node, threats inline elements as transparent (but should stop on an inline objects).
|
|
47
|
+
*/
|
|
48
|
+
function findSibling(viewElement, direction, writer, { blockElements, inlineObjectElements }) {
|
|
49
|
+
let position = writer.createPositionAt(viewElement, direction == 'forward' ? 'after' : 'before');
|
|
50
|
+
// Find first position that is just before a first:
|
|
51
|
+
// * text node,
|
|
52
|
+
// * block element,
|
|
53
|
+
// * inline object element.
|
|
54
|
+
// It's ignoring any inline (non-object) elements like span, strong, etc.
|
|
55
|
+
position = position.getLastMatchingPosition(({ item }) => (item.is('element') &&
|
|
56
|
+
!blockElements.includes(item.name) &&
|
|
57
|
+
!inlineObjectElements.includes(item.name)), { direction });
|
|
58
|
+
return direction == 'forward' ? position.nodeAfter : position.nodeBefore;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Returns true for view elements that are listed as block view elements.
|
|
62
|
+
*/
|
|
63
|
+
function isBlockViewElement(node, blockElements) {
|
|
64
|
+
return !!node && node.is('element') && blockElements.includes(node.name);
|
|
65
|
+
}
|
package/src/filters/image.d.ts
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright (c) 2003-2023, 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/image
|
|
7
|
-
*/
|
|
8
|
-
import { type ViewDocumentFragment } from 'ckeditor5/src/engine';
|
|
9
|
-
/**
|
|
10
|
-
* Replaces source attribute of all `<img>` elements representing regular
|
|
11
|
-
* images (not the Word shapes) with inlined base64 image representation extracted from RTF or Blob data.
|
|
12
|
-
*
|
|
13
|
-
* @param documentFragment Document fragment on which transform images.
|
|
14
|
-
* @param rtfData The RTF data from which images representation will be used.
|
|
15
|
-
*/
|
|
16
|
-
export declare function replaceImagesSourceWithBase64(documentFragment: ViewDocumentFragment, rtfData: string): void;
|
|
17
|
-
/**
|
|
18
|
-
* Converts given HEX string to base64 representation.
|
|
19
|
-
*
|
|
20
|
-
* @internal
|
|
21
|
-
* @param hexString The HEX string to be converted.
|
|
22
|
-
* @returns Base64 representation of a given HEX string.
|
|
23
|
-
*/
|
|
24
|
-
export declare function _convertHexToBase64(hexString: string): string;
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2023, 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/image
|
|
7
|
+
*/
|
|
8
|
+
import { type ViewDocumentFragment } from 'ckeditor5/src/engine';
|
|
9
|
+
/**
|
|
10
|
+
* Replaces source attribute of all `<img>` elements representing regular
|
|
11
|
+
* images (not the Word shapes) with inlined base64 image representation extracted from RTF or Blob data.
|
|
12
|
+
*
|
|
13
|
+
* @param documentFragment Document fragment on which transform images.
|
|
14
|
+
* @param rtfData The RTF data from which images representation will be used.
|
|
15
|
+
*/
|
|
16
|
+
export declare function replaceImagesSourceWithBase64(documentFragment: ViewDocumentFragment, rtfData: string): void;
|
|
17
|
+
/**
|
|
18
|
+
* Converts given HEX string to base64 representation.
|
|
19
|
+
*
|
|
20
|
+
* @internal
|
|
21
|
+
* @param hexString The HEX string to be converted.
|
|
22
|
+
* @returns Base64 representation of a given HEX string.
|
|
23
|
+
*/
|
|
24
|
+
export declare function _convertHexToBase64(hexString: string): string;
|