This repository has been archived by the owner on Jun 26, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 18
/
pastefromword.js
99 lines (83 loc) · 3.24 KB
/
pastefromword.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/**
* @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md.
*/
/**
* @module pastefromword/pastefromword
*/
import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
import DocumentFragment from '@ckeditor/ckeditor5-engine/src/view/documentfragment';
import { extractBody, bodyToView, extractStyles } from './filters/common';
import { paragraphsToLists } from './filters/list';
/**
* This plugin handles content pasted from Word and transforms it (if necessary)
* to format suitable for editor {@link module:engine/model/model~Model}.
*
* @extends module:core/plugin~Plugin
*/
export default class PasteFromWord extends Plugin {
/**
* @inheritDoc
*/
static get pluginName() {
return 'PasteFromWord';
}
/**
* @inheritDoc
*/
init() {
const editor = this.editor;
const document = editor.editing.view.document;
this.listenTo( document, 'clipboardInput', ( evt, data ) => {
const html = data.dataTransfer.getData( 'text/html' );
if ( isWordInput( html ) ) {
evt.stop();
const normalizedInput = this._normalizeWordInput( html, editor );
editor.plugins.get( 'Clipboard' ).fire( 'inputTransformation', { content: normalizedInput } );
}
} );
}
/**
* Normalizes input pasted from Word to format suitable for editor {@link module:engine/model/model~Model}.
*
* @private
* @param {module:core/editor/editor~Editor} editor Editor instance.
* @param {String} input Word input.
* @returns {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment} view Normalized input.
*/
_normalizeWordInput( input, editor ) {
const editorDocument = editor.editing.view.getDomRoot();
const ownerDocument = editorDocument ? editorDocument.ownerDocument : null;
const transofrmedInput = transformInput( input, ownerDocument,
extractBody,
bodyToView,
extractStyles,
paragraphsToLists );
return transofrmedInput.view || new DocumentFragment();
}
}
// Checks if given HTML string is a result of pasting content from Word.
//
// @param {String} html HTML string to test.
// @returns {Boolean} True if given HTML string is a Word HTML.
//
function isWordInput( html ) {
return !!( html && html.match( /<meta\s*name="?generator"?\s*content="?microsoft\s*word\s*\d+"?\/?>/gi ) );
}
// Transforms given HTML string by provided filter functions.
//
// @param {String} html HTML string to transform.
// @param {Document} domDocument Editor owner document.
// @param {Array.<Function>} filters Functions which are used filter/transform given HTML. Filters are executed
// in an order they where provided to this function.
// @returns {Object} data Object containing transformed parts of an input HTML string in a different formats. The number
// and type of formats depends on a provided filters as each filter function can create separate format or change existing one.
// @returns {String} data.html Input HTML string.
// @returns {*} data.* Any type of data created by filter functions. It directly depends on provided filter functions.
function transformInput( html, domDocument, ...filters ) {
let transformedData = { html };
for ( const filter of filters ) {
transformedData = filter( transformedData, domDocument );
}
return transformedData;
}