@ckeditor/ckeditor5-paste-from-office
Advanced tools
Comparing version 17.0.0 to 18.0.0
Changelog | ||
========= | ||
## [18.0.0](https://github.com/ckeditor/ckeditor5-paste-from-office/compare/v17.0.0...v18.0.0) (2020-03-19) | ||
### Features | ||
* Added support for basic list indentation when pasting from Microsoft Word. Closes [ckeditor/ckeditor5#2518](https://github.com/ckeditor/ckeditor5/issues/2518). ([58ae829](https://github.com/ckeditor/ckeditor5-paste-from-office/commit/58ae829)) | ||
Thanks to [gjhenrique](https://github.com/gjhenrique) for the contribution! | ||
## [17.0.0](https://github.com/ckeditor/ckeditor5-paste-from-office/compare/v16.0.0...v17.0.0) (2020-02-19) | ||
@@ -5,0 +14,0 @@ |
{ | ||
"name": "@ckeditor/ckeditor5-paste-from-office", | ||
"version": "17.0.0", | ||
"version": "18.0.0", | ||
"description": "Paste from Office feature for CKEditor 5.", | ||
@@ -13,19 +13,19 @@ "keywords": [ | ||
"dependencies": { | ||
"@ckeditor/ckeditor5-clipboard": "^17.0.0", | ||
"@ckeditor/ckeditor5-core": "^17.0.0", | ||
"@ckeditor/ckeditor5-engine": "^17.0.0" | ||
"@ckeditor/ckeditor5-clipboard": "^18.0.0", | ||
"@ckeditor/ckeditor5-core": "^18.0.0", | ||
"@ckeditor/ckeditor5-engine": "^18.0.0" | ||
}, | ||
"devDependencies": { | ||
"@ckeditor/ckeditor5-basic-styles": "^17.0.0", | ||
"@ckeditor/ckeditor5-cloud-services": "^17.0.0", | ||
"@ckeditor/ckeditor5-easy-image": "^17.0.0", | ||
"@ckeditor/ckeditor5-editor-classic": "^17.0.0", | ||
"@ckeditor/ckeditor5-enter": "^17.0.0", | ||
"@ckeditor/ckeditor5-heading": "^17.0.0", | ||
"@ckeditor/ckeditor5-image": "^17.0.0", | ||
"@ckeditor/ckeditor5-link": "^17.0.0", | ||
"@ckeditor/ckeditor5-list": "^17.0.0", | ||
"@ckeditor/ckeditor5-paragraph": "^17.0.0", | ||
"@ckeditor/ckeditor5-table": "^17.0.0", | ||
"@ckeditor/ckeditor5-utils": "^17.0.0", | ||
"@ckeditor/ckeditor5-basic-styles": "^18.0.0", | ||
"@ckeditor/ckeditor5-cloud-services": "^18.0.0", | ||
"@ckeditor/ckeditor5-easy-image": "^18.0.0", | ||
"@ckeditor/ckeditor5-editor-classic": "^18.0.0", | ||
"@ckeditor/ckeditor5-enter": "^18.0.0", | ||
"@ckeditor/ckeditor5-heading": "^18.0.0", | ||
"@ckeditor/ckeditor5-image": "^18.0.0", | ||
"@ckeditor/ckeditor5-link": "^18.0.0", | ||
"@ckeditor/ckeditor5-list": "^18.0.0", | ||
"@ckeditor/ckeditor5-paragraph": "^18.0.0", | ||
"@ckeditor/ckeditor5-table": "^18.0.0", | ||
"@ckeditor/ckeditor5-utils": "^18.0.0", | ||
"eslint": "^5.5.0", | ||
@@ -32,0 +32,0 @@ "eslint-config-ckeditor5": "^2.0.0", |
@@ -10,3 +10,2 @@ /** | ||
import Element from '@ckeditor/ckeditor5-engine/src/view/element'; | ||
import Matcher from '@ckeditor/ckeditor5-engine/src/view/matcher'; | ||
@@ -23,3 +22,3 @@ import UpcastWriter from '@ckeditor/ckeditor5-engine/src/view/upcastwriter'; | ||
* | ||
* @param {module:engine/view/documentfragment~DocumentFragment} documentFragment The view structure which to transform. | ||
* @param {module:engine/view/documentfragment~DocumentFragment} documentFragment The view structure to be transformed. | ||
* @param {String} stylesString Styles from which list-like elements styling will be extracted. | ||
@@ -32,3 +31,3 @@ */ | ||
const writer = new UpcastWriter(); | ||
const writer = new UpcastWriter( documentFragment.document ); | ||
const itemLikeElements = findAllItemLikeElements( documentFragment, writer ); | ||
@@ -41,8 +40,39 @@ | ||
let currentList = null; | ||
let currentIndentation = 1; | ||
itemLikeElements.forEach( ( itemLikeElement, i ) => { | ||
if ( !currentList || isNewListNeeded( itemLikeElements[ i - 1 ], itemLikeElement ) ) { | ||
const isDifferentList = isNewListNeeded( itemLikeElements[ i - 1 ], itemLikeElement ); | ||
const previousItemLikeElement = isDifferentList ? null : itemLikeElements[ i - 1 ]; | ||
const indentationDifference = getIndentationDifference( previousItemLikeElement, itemLikeElement ); | ||
if ( isDifferentList ) { | ||
currentList = null; | ||
currentIndentation = 1; | ||
} | ||
if ( !currentList || indentationDifference !== 0 ) { | ||
const listStyle = detectListStyle( itemLikeElement, stylesString ); | ||
currentList = insertNewEmptyList( listStyle, itemLikeElement.element, writer ); | ||
if ( !currentList ) { | ||
currentList = insertNewEmptyList( listStyle, itemLikeElement.element, writer ); | ||
} else if ( itemLikeElement.indent > currentIndentation ) { | ||
const lastListItem = currentList.getChild( currentList.childCount - 1 ); | ||
const lastListItemChild = lastListItem.getChild( lastListItem.childCount - 1 ); | ||
currentList = insertNewEmptyList( listStyle, lastListItemChild, writer ); | ||
currentIndentation += 1; | ||
} else if ( itemLikeElement.indent < currentIndentation ) { | ||
const differentIndentation = currentIndentation - itemLikeElement.indent; | ||
currentList = findParentListAtLevel( currentList, differentIndentation ); | ||
currentIndentation = parseInt( itemLikeElement.indent ); | ||
} | ||
if ( itemLikeElement.indent <= currentIndentation ) { | ||
if ( !currentList.is( listStyle.type ) ) { | ||
currentList = writer.rename( listStyle.type, currentList ); | ||
} | ||
} | ||
} | ||
@@ -163,10 +193,12 @@ | ||
// Usually a result of `detectListStyle()` function. | ||
// @param {module:engine/view/element~Element} element Element before which list is inserted. | ||
// @param {module:engine/view/element~Element} element Element after which list is inserted. | ||
// @param {module:engine/view/upcastwriter~UpcastWriter} writer | ||
// @returns {module:engine/view/element~Element} Newly created list element. | ||
function insertNewEmptyList( listStyle, element, writer ) { | ||
const list = new Element( listStyle.type ); | ||
const position = element.parent.getChildIndex( element ); | ||
const parent = element.parent; | ||
const list = writer.createElement( listStyle.type ); | ||
const position = parent.getChildIndex( element ) + 1; | ||
writer.insertChild( position, list, element.parent ); | ||
writer.insertChild( position, list, parent ); | ||
@@ -252,2 +284,6 @@ return list; | ||
function isNewListNeeded( previousItem, currentItem ) { | ||
if ( !previousItem ) { | ||
return true; | ||
} | ||
if ( previousItem.id !== currentItem.id ) { | ||
@@ -270,1 +306,36 @@ return true; | ||
} | ||
// Calculates the indentation difference between two given list items (based on indent attribute | ||
// extracted from `mso-list` style, see #getListItemData). | ||
// | ||
// @param {Object} previousItem | ||
// @param {Object} currentItem | ||
// @returns {Number} | ||
function getIndentationDifference( previousItem, currentItem ) { | ||
return previousItem ? currentItem.indent - previousItem.indent : currentItem.indent - 1; | ||
} | ||
// Finds parent list element (ul/ol) of a given list element with indentation level lower by a given value. | ||
// | ||
// @param {module:engine/view/element~Element} listElement List element from which to start looking for a parent list. | ||
// @param {Number} indentationDifference Indentation difference between lists. | ||
// @returns {module:engine/view/element~Element} Found list element with indentation level lower by a given value. | ||
function findParentListAtLevel( listElement, indentationDifference ) { | ||
const ancestors = listElement.getAncestors( { parentFirst: true } ); | ||
let parentList = null; | ||
let levelChange = 0; | ||
for ( const ancestor of ancestors ) { | ||
if ( ancestor.name === 'ul' || ancestor.name === 'ol' ) { | ||
levelChange++; | ||
} | ||
if ( levelChange === indentationDifference ) { | ||
parentList = ancestor; | ||
break; | ||
} | ||
} | ||
return parentList; | ||
} |
@@ -13,4 +13,6 @@ /** | ||
import DomConverter from '@ckeditor/ckeditor5-engine/src/view/domconverter'; | ||
import ViewDocument from '@ckeditor/ckeditor5-engine/src/view/document'; | ||
import { normalizeSpacing, normalizeSpacerunSpans } from './space'; | ||
import { StylesProcessor } from '@ckeditor/ckeditor5-engine/src/view/stylesmap'; | ||
@@ -64,3 +66,4 @@ /** | ||
function documentToView( htmlDocument ) { | ||
const domConverter = new DomConverter( { blockFillerMode: 'nbsp' } ); | ||
const viewDocument = new ViewDocument( new StylesProcessor() ); | ||
const domConverter = new DomConverter( viewDocument, { blockFillerMode: 'nbsp' } ); | ||
const fragment = htmlDocument.createDocumentFragment(); | ||
@@ -67,0 +70,0 @@ const nodes = htmlDocument.body.childNodes; |
@@ -22,2 +22,10 @@ /** | ||
export default class GoogleDocsNormalizer { | ||
constructor( document ) { | ||
/** | ||
* @readonly | ||
* @type {module:engine/view/document~Document} | ||
*/ | ||
this.document = document; | ||
} | ||
/** | ||
@@ -34,3 +42,3 @@ * @inheritDoc | ||
execute( data ) { | ||
const writer = new UpcastWriter(); | ||
const writer = new UpcastWriter( this.document ); | ||
@@ -37,0 +45,0 @@ removeBoldWrapper( data.content, writer ); |
@@ -54,3 +54,3 @@ /** | ||
normalizers.push( new MSWordNormalizer() ); | ||
normalizers.push( new GoogleDocsNormalizer() ); | ||
normalizers.push( new GoogleDocsNormalizer( editor.editing.view.document ) ); | ||
@@ -57,0 +57,0 @@ editor.plugins.get( 'Clipboard' ).on( |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
43913
775
+ Added@ckeditor/ckeditor5-clipboard@18.0.0(transitive)
+ Added@ckeditor/ckeditor5-core@18.0.0(transitive)
+ Added@ckeditor/ckeditor5-engine@18.0.0(transitive)
+ Added@ckeditor/ckeditor5-utils@18.0.0(transitive)
- Removed@ckeditor/ckeditor5-clipboard@17.0.0(transitive)
- Removed@ckeditor/ckeditor5-core@17.0.0(transitive)
- Removed@ckeditor/ckeditor5-engine@17.0.0(transitive)
- Removed@ckeditor/ckeditor5-utils@17.0.0(transitive)