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
/
space.js
62 lines (56 loc) · 3.28 KB
/
space.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
/**
* @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/
/**
* @module paste-from-office/filters/space
*/
/**
* Replaces last space preceding elements closing tag with ` `. Such operation prevents spaces from being removed
* during further DOM/View processing (see especially {@link module:engine/view/domconverter~DomConverter#_processDataFromDomText}).
* This method also takes into account Word specific `<o:p></o:p>` empty tags.
* Additionally multiline sequences of spaces and new lines between tags are removed (see #39 and #40).
*
* @param {String} htmlString HTML string in which spacing should be normalized.
* @returns {String} Input HTML with spaces normalized.
*/
export function normalizeSpacing( htmlString ) {
// Run normalizeSafariSpaceSpans() two times to cover nested spans.
return normalizeSafariSpaceSpans( normalizeSafariSpaceSpans( htmlString ) )
// Remove all \r\n from "spacerun spans" so the last replace line doesn't strip all whitespaces.
.replace( /(<span style=['"]mso-spacerun:yes['"]>[\s]*?)[\r\n]+(\s*<\/span>)/g, '$1$2' )
.replace( /<span style=['"]mso-spacerun:yes['"]><\/span>/g, '' )
.replace( / <\//g, '\u00A0</' )
.replace( / <o:p><\/o:p>/g, '\u00A0<o:p></o:p>' )
// Remove all whitespaces when they contain any \r or \n.
.replace( />(\s*[\r\n]\s*)</g, '><' );
}
/**
* Normalizes spacing in special Word `spacerun spans` (`<span style='mso-spacerun:yes'>\s+</span>`) by replacing
* all spaces with ` ` pairs. This prevents spaces from being removed during further DOM/View processing
* (see especially {@link module:engine/view/domconverter~DomConverter#_processDataFromDomText}).
*
* @param {Document} htmlDocument Native `Document` object in which spacing should be normalized.
*/
export function normalizeSpacerunSpans( htmlDocument ) {
htmlDocument.querySelectorAll( 'span[style*=spacerun]' ).forEach( el => {
// Use `el.childNodes[ 0 ].data.length` instead of `el.innerText.length`. For `el.innerText.length` which
// contains spaces mixed with ` ` Edge browser returns incorrect length.
const innerTextLength = el.childNodes[ 0 ].data.length;
el.innerHTML = Array( innerTextLength + 1 ).join( '\u00A0 ' ).substr( 0, innerTextLength );
} );
}
// Normalizes specific spacing generated by Safari when content pasted from Word (`<span class="Apple-converted-space"> </span>`)
// by replacing all spaces sequences longer than 1 space with ` ` pairs. This prevents spaces from being removed during
// further DOM/View processing (see especially {@link module:engine/view/domconverter~DomConverter#_processDataFromDomText}).
//
// This function is similar to {@link module:clipboard/utils/normalizeclipboarddata normalizeClipboardData util} but uses
// regular spaces / sequence for replacement.
//
// @param {String} htmlString HTML string in which spacing should be normalized
// @returns {String} Input HTML with spaces normalized.
function normalizeSafariSpaceSpans( htmlString ) {
return htmlString.replace( /<span(?: class="Apple-converted-space"|)>(\s+)<\/span>/g, ( fullMatch, spaces ) => {
return spaces.length === 1 ? ' ' : Array( spaces.length + 1 ).join( '\u00A0 ' ).substr( 0, spaces.length );
} );
}