mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
Revert my Squire node.remove() back to detach(node) and
Cleanup some code
This commit is contained in:
parent
807c3696d4
commit
d747de7649
6 changed files with 131 additions and 183 deletions
19
README.md
19
README.md
|
|
@ -35,6 +35,7 @@ And don't forget to read the [RainLoop documentation](https://www.rainloop.net/d
|
||||||
http://www.gnu.org/licenses/agpl-3.0.html
|
http://www.gnu.org/licenses/agpl-3.0.html
|
||||||
|
|
||||||
Copyright (c) 2020 SnappyMail
|
Copyright (c) 2020 SnappyMail
|
||||||
|
Copyright (c) 2019 RainLoop
|
||||||
|
|
||||||
## Modifications
|
## Modifications
|
||||||
|
|
||||||
|
|
@ -106,22 +107,22 @@ RainLoop 1.14 vs SnappyMail
|
||||||
|
|
||||||
|js/* |RainLoop |Snappy |
|
|js/* |RainLoop |Snappy |
|
||||||
|----------- |--------: |--------: |
|
|----------- |--------: |--------: |
|
||||||
|admin.js |2.130.942 | 669.377 |
|
|admin.js |2.130.942 | 666.175 |
|
||||||
|app.js |4.184.455 |2.418.170 |
|
|app.js |4.184.455 |2.412.164 |
|
||||||
|boot.js | 671.522 | 5.285 |
|
|boot.js | 671.522 | 5.285 |
|
||||||
|libs.js | 647.614 | 240.181 |
|
|libs.js | 647.614 | 238.674 |
|
||||||
|polyfills.js | 325.834 | 0 |
|
|polyfills.js | 325.834 | 0 |
|
||||||
|TOTAL |7.960.367 |3.333.013 |
|
|TOTAL |7.960.367 |3.322.298 |
|
||||||
|
|
||||||
|js/min/* |RainLoop |Snappy |Rain gzip |gzip |brotli |
|
|js/min/* |RainLoop |Snappy |Rain gzip |gzip |brotli |
|
||||||
|--------------- |--------: |--------: |--------: |--------: |--------: |
|
|--------------- |--------: |--------: |--------: |--------: |--------: |
|
||||||
|admin.min.js | 252.147 | 92.040 | 73.657 | 23.656 | 20.584 |
|
|admin.min.js | 252.147 | 91.598 | 73.657 | 23.547 | 20.518 |
|
||||||
|app.min.js | 511.202 | 325.791 |140.462 | 84.060 | 68.147 |
|
|app.min.js | 511.202 | 325.187 |140.462 | 83.936 | 68.135 |
|
||||||
|boot.min.js | 66.007 | 2.918 | 22.567 | 1.500 | 1.275 |
|
|boot.min.js | 66.007 | 2.918 | 22.567 | 1.500 | 1.275 |
|
||||||
|libs.min.js | 572.545 | 135.084 |176.720 | 48.346 | 42.934 |
|
|libs.min.js | 572.545 | 134.223 |176.720 | 48.183 | 42.816 |
|
||||||
|polyfills.min.js | 32.452 | 0 | 11.312 | 0 | 0 |
|
|polyfills.min.js | 32.452 | 0 | 11.312 | 0 | 0 |
|
||||||
|TOTAL |1.434.353 | 555.833 |424.718 |157.562 |132.940 |
|
|TOTAL |1.434.353 | 553.926 |424.718 |157.166 |132.744 |
|
||||||
|TOTAL (no admin) |1.182.206 | 463.793 |351.061 |133.906 |112.356 |
|
|TOTAL (no admin) |1.182.206 | 462.328 |351.061 |133.619 |112.226 |
|
||||||
|
|
||||||
For a user its around 61% smaller and faster than traditional RainLoop.
|
For a user its around 61% smaller and faster than traditional RainLoop.
|
||||||
|
|
||||||
|
|
|
||||||
2
dev/External/SquireUI.js
vendored
2
dev/External/SquireUI.js
vendored
|
|
@ -487,7 +487,7 @@ class SquireUI
|
||||||
}
|
}
|
||||||
|
|
||||||
testPresenceinSelection(format, validation) {
|
testPresenceinSelection(format, validation) {
|
||||||
return validation.test(this.squire.getPath()) | this.squire.hasFormat(format);
|
return validation.test(this.squire.getPath()) || this.squire.hasFormat(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
setMode(mode) {
|
setMode(mode) {
|
||||||
|
|
|
||||||
|
|
@ -358,40 +358,27 @@ class EmailModel {
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
toLine(friendlyView, wrapWithLink, useEncodeHtml) {
|
toLine(friendlyView, wrapWithLink, useEncodeHtml) {
|
||||||
let result = '';
|
let result = '',
|
||||||
|
toLink = (to, txt) => '<a href="mailto:' + to + '" target="_blank" tabindex="-1">' + encodeHtml(txt) + '</a>';
|
||||||
if (this.email) {
|
if (this.email) {
|
||||||
if (friendlyView && this.name) {
|
if (friendlyView && this.name) {
|
||||||
result = wrapWithLink
|
result = wrapWithLink
|
||||||
? '<a href="mailto:' +
|
? toLink(
|
||||||
encodeHtml(this.email) +
|
encodeHtml(this.email) + '?to=' + encodeURIComponent('"' + this.name + '" <' + this.email + '>'),
|
||||||
'?to=' +
|
this.name
|
||||||
encodeURIComponent('"' + this.name + '" <' + this.email + '>') +
|
)
|
||||||
'" target="_blank" tabindex="-1">' +
|
|
||||||
encodeHtml(this.name) +
|
|
||||||
'</a>'
|
|
||||||
: (useEncodeHtml ? encodeHtml(this.name) : this.name);
|
: (useEncodeHtml ? encodeHtml(this.name) : this.name);
|
||||||
// result = wrapWithLink ? '<a href="mailto:' + encodeHtml('"' + this.name + '" <' + this.email + '>') +
|
|
||||||
// '" target="_blank" tabindex="-1">' + encodeHtml(this.name) + '</a>' : (useEncodeHtml ? encodeHtml(this.name) : this.name);
|
|
||||||
} else {
|
} else {
|
||||||
result = this.email;
|
result = this.email;
|
||||||
if (this.name) {
|
if (this.name) {
|
||||||
if (wrapWithLink) {
|
if (wrapWithLink) {
|
||||||
result =
|
result =
|
||||||
encodeHtml('"' + this.name + '" <') +
|
encodeHtml('"' + this.name + '" <')
|
||||||
'<a href="mailto:' +
|
+ toLink(
|
||||||
encodeHtml(this.email) +
|
encodeHtml(this.email) + '?to=' + encodeURIComponent('"' + this.name + '" <' + this.email + '>'),
|
||||||
'?to=' +
|
result
|
||||||
encodeURIComponent('"' + this.name + '" <' + this.email + '>') +
|
)
|
||||||
'" target="_blank" tabindex="-1">' +
|
+ encodeHtml('>');
|
||||||
encodeHtml(result) +
|
|
||||||
'</a>' +
|
|
||||||
encodeHtml('>');
|
|
||||||
// result = encodeHtml('"' + this.name + '" <') + '<a href="mailto:' +
|
|
||||||
// encodeHtml('"' + this.name + '" <' + this.email + '>') +
|
|
||||||
// '" target="_blank" tabindex="-1">' +
|
|
||||||
// encodeHtml(result) +
|
|
||||||
// '</a>' +
|
|
||||||
// encodeHtml('>');
|
|
||||||
} else {
|
} else {
|
||||||
result = '"' + this.name + '" <' + result + '>';
|
result = '"' + this.name + '" <' + result + '>';
|
||||||
if (useEncodeHtml) {
|
if (useEncodeHtml) {
|
||||||
|
|
@ -399,12 +386,7 @@ class EmailModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (wrapWithLink) {
|
} else if (wrapWithLink) {
|
||||||
result =
|
result = toLink(encodeHtml(this.email), this.email);
|
||||||
'<a href="mailto:' +
|
|
||||||
encodeHtml(this.email) +
|
|
||||||
'" target="_blank" tabindex="-1">' +
|
|
||||||
encodeHtml(this.email) +
|
|
||||||
'</a>';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
29
dev/prototype.js
vendored
29
dev/prototype.js
vendored
|
|
@ -8,7 +8,6 @@
|
||||||
|
|
||||||
Date.defineRelativeTimeFormat = config => relativeTime = config;
|
Date.defineRelativeTimeFormat = config => relativeTime = config;
|
||||||
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat
|
|
||||||
let formats = {
|
let formats = {
|
||||||
LT : {hour: 'numeric', minute: 'numeric'},
|
LT : {hour: 'numeric', minute: 'numeric'},
|
||||||
L : {},
|
L : {},
|
||||||
|
|
@ -23,6 +22,7 @@
|
||||||
D: {weekday: 'short'},
|
D: {weekday: 'short'},
|
||||||
j: {day: 'numeric'},
|
j: {day: 'numeric'},
|
||||||
l: {weekday: 'long'},
|
l: {weekday: 'long'},
|
||||||
|
z: {},
|
||||||
// Month
|
// Month
|
||||||
F: {month: 'long'},
|
F: {month: 'long'},
|
||||||
m: {month: '2-digit'},
|
m: {month: '2-digit'},
|
||||||
|
|
@ -31,11 +31,8 @@
|
||||||
Y: {year: 'numeric'},
|
Y: {year: 'numeric'},
|
||||||
y: {year: '2-digit'},
|
y: {year: '2-digit'},
|
||||||
// Time
|
// Time
|
||||||
a: {hour12: true},
|
|
||||||
A: {hour12: true},
|
A: {hour12: true},
|
||||||
g: {hour: 'numeric', hourCycle: 'h12'},
|
|
||||||
G: {hour: 'numeric'},
|
G: {hour: 'numeric'},
|
||||||
h: {hour: '2-digit', hourCycle: 'h12'},
|
|
||||||
H: {hour: '2-digit'},
|
H: {hour: '2-digit'},
|
||||||
i: {minute: '2-digit'},
|
i: {minute: '2-digit'},
|
||||||
s: {second: '2-digit'},
|
s: {second: '2-digit'},
|
||||||
|
|
@ -49,24 +46,24 @@
|
||||||
|
|
||||||
// Format momentjs/PHP date formats to Intl.DateTimeFormat
|
// Format momentjs/PHP date formats to Intl.DateTimeFormat
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat
|
||||||
Date.prototype.format = function (str, UTC) {
|
Date.prototype.format = function (options, UTC) {
|
||||||
if ('Y-m-d\\TH:i:s' == str) {
|
if (typeof options == 'string') {
|
||||||
|
if ('Y-m-d\\TH:i:s' == options) {
|
||||||
return this.getFullYear() + '-' + pad2(1 + this.getMonth()) + '-' + pad2(this.getDate())
|
return this.getFullYear() + '-' + pad2(1 + this.getMonth()) + '-' + pad2(this.getDate())
|
||||||
+ 'T' + pad2(this.getHours()) + ':' + pad2(this.getMinutes()) + ':' + pad2(this.getSeconds());
|
+ 'T' + pad2(this.getHours()) + ':' + pad2(this.getMinutes()) + ':' + pad2(this.getSeconds());
|
||||||
}
|
}
|
||||||
let options = {};
|
if (formats[options]) {
|
||||||
if (formats[str]) {
|
options = formats[options];
|
||||||
options = formats[str];
|
|
||||||
} else {
|
} else {
|
||||||
console.log('Date.format('+str+', '+(UTC?'true':'false')+')');
|
let o, s = options + (UTC?'Z':''), i = s.length;
|
||||||
if (UTC) {
|
console.log('Date.format('+s+')');
|
||||||
str += 'Z';
|
options = {};
|
||||||
}
|
|
||||||
let i = str.length;
|
|
||||||
while (i--) {
|
while (i--) {
|
||||||
phpFormats[str[i]] && Object.entries(phpFormats[str[i]]).forEach(([k,v])=>options[k]=v);
|
o = phpFormats[s[i]] || phpFormats[s[i].toUpperCase()];
|
||||||
|
o && Object.entries(o).forEach(([k,v])=>options[k]=v);
|
||||||
|
}
|
||||||
|
formats[s] = options;
|
||||||
}
|
}
|
||||||
formats[str] = options;
|
|
||||||
}
|
}
|
||||||
return new Intl.DateTimeFormat(doc.documentElement.lang, options).format(this);
|
return new Intl.DateTimeFormat(doc.documentElement.lang, options).format(this);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,6 @@ exports.zip = (srcDir, destDir, fileName) =>
|
||||||
.pipe(require('gulp-zip')(fileName))
|
.pipe(require('gulp-zip')(fileName))
|
||||||
.pipe(gulp.dest(destDir));
|
.pipe(gulp.dest(destDir));
|
||||||
|
|
||||||
exports.getHead = () => (!config.community ? config.head.rainloop : config.head.agpl);
|
exports.getHead = () => config.head.agpl;
|
||||||
|
|
||||||
exports.cleanStatic = () => exports.del(config.paths.static);
|
exports.cleanStatic = () => exports.del(config.paths.static);
|
||||||
|
|
|
||||||
210
vendors/squire/build/squire-raw.js
vendored
210
vendors/squire/build/squire-raw.js
vendored
|
|
@ -14,7 +14,6 @@ const
|
||||||
DOCUMENT_POSITION_PRECEDING = 2, // Node.DOCUMENT_POSITION_PRECEDING
|
DOCUMENT_POSITION_PRECEDING = 2, // Node.DOCUMENT_POSITION_PRECEDING
|
||||||
ELEMENT_NODE = 1, // Node.ELEMENT_NODE,
|
ELEMENT_NODE = 1, // Node.ELEMENT_NODE,
|
||||||
TEXT_NODE = 3, // Node.TEXT_NODE,
|
TEXT_NODE = 3, // Node.TEXT_NODE,
|
||||||
DOCUMENT_NODE = 9, // Node.DOCUMENT_NODE,
|
|
||||||
DOCUMENT_FRAGMENT_NODE = 11, // Node.DOCUMENT_FRAGMENT_NODE,
|
DOCUMENT_FRAGMENT_NODE = 11, // Node.DOCUMENT_FRAGMENT_NODE,
|
||||||
SHOW_ELEMENT = 1, // NodeFilter.SHOW_ELEMENT,
|
SHOW_ELEMENT = 1, // NodeFilter.SHOW_ELEMENT,
|
||||||
SHOW_TEXT = 4, // NodeFilter.SHOW_TEXT,
|
SHOW_TEXT = 4, // NodeFilter.SHOW_TEXT,
|
||||||
|
|
@ -207,6 +206,13 @@ const
|
||||||
node.childNodes.length : node.length || 0;
|
node.childNodes.length : node.length || 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
detach = node => {
|
||||||
|
// node.remove();
|
||||||
|
let parent = node.parentNode;
|
||||||
|
parent && parent.removeChild( node );
|
||||||
|
return node;
|
||||||
|
},
|
||||||
|
|
||||||
empty = node => {
|
empty = node => {
|
||||||
let frag = doc.createDocumentFragment(),
|
let frag = doc.createDocumentFragment(),
|
||||||
childNodes = node.childNodes;
|
childNodes = node.childNodes;
|
||||||
|
|
@ -214,7 +220,7 @@ const
|
||||||
return frag;
|
return frag;
|
||||||
},
|
},
|
||||||
|
|
||||||
createElement = ( doc, tag, props, children ) => {
|
createElement = ( tag, props, children ) => {
|
||||||
let el = doc.createElement( tag ),
|
let el = doc.createElement( tag ),
|
||||||
attr, value;
|
attr, value;
|
||||||
if ( props instanceof Array ) {
|
if ( props instanceof Array ) {
|
||||||
|
|
@ -277,7 +283,7 @@ const
|
||||||
}
|
}
|
||||||
// } else if ( !node.querySelector( 'BR' ) ) {
|
// } else if ( !node.querySelector( 'BR' ) ) {
|
||||||
} else if ( node.matches( ':empty' ) ) {
|
} else if ( node.matches( ':empty' ) ) {
|
||||||
fixer = createElement( doc, 'BR' );
|
fixer = createElement( 'BR' );
|
||||||
while ( ( child = node.lastElementChild ) && !isInline( child ) ) {
|
while ( ( child = node.lastElementChild ) && !isInline( child ) ) {
|
||||||
node = child;
|
node = child;
|
||||||
}
|
}
|
||||||
|
|
@ -310,14 +316,14 @@ const
|
||||||
// && (root.__squire__._config.blockTag !== 'DIV' || (child.matches && !child.matches(phrasingElements)))
|
// && (root.__squire__._config.blockTag !== 'DIV' || (child.matches && !child.matches(phrasingElements)))
|
||||||
) {
|
) {
|
||||||
if ( !wrapper ) {
|
if ( !wrapper ) {
|
||||||
wrapper = createElement( doc, 'div' );
|
wrapper = createElement( 'div' );
|
||||||
}
|
}
|
||||||
wrapper.append( child );
|
wrapper.append( child );
|
||||||
--i;
|
--i;
|
||||||
--l;
|
--l;
|
||||||
} else if ( isBR || wrapper ) {
|
} else if ( isBR || wrapper ) {
|
||||||
if ( !wrapper ) {
|
if ( !wrapper ) {
|
||||||
wrapper = createElement( doc, 'div' );
|
wrapper = createElement( 'div' );
|
||||||
}
|
}
|
||||||
fixCursor( wrapper, root );
|
fixCursor( wrapper, root );
|
||||||
if ( isBR ) {
|
if ( isBR ) {
|
||||||
|
|
@ -341,12 +347,12 @@ const
|
||||||
// && (root.__squire__._config.blockTag !== 'DIV' || (child.matches && !child.matches(phrasingElements)))
|
// && (root.__squire__._config.blockTag !== 'DIV' || (child.matches && !child.matches(phrasingElements)))
|
||||||
) {
|
) {
|
||||||
if ( !wrapper ) {
|
if ( !wrapper ) {
|
||||||
wrapper = createElement( doc, 'div' );
|
wrapper = createElement( 'div' );
|
||||||
}
|
}
|
||||||
wrapper.append( child );
|
wrapper.append( child );
|
||||||
} else if ( isBR || wrapper ) {
|
} else if ( isBR || wrapper ) {
|
||||||
if ( !wrapper ) {
|
if ( !wrapper ) {
|
||||||
wrapper = createElement( doc, 'div' );
|
wrapper = createElement( 'div' );
|
||||||
}
|
}
|
||||||
fixCursor( wrapper, root );
|
fixCursor( wrapper, root );
|
||||||
if ( isBR ) {
|
if ( isBR ) {
|
||||||
|
|
@ -452,7 +458,7 @@ const
|
||||||
fakeRange.endOffset = getLength( prev );
|
fakeRange.endOffset = getLength( prev );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
child.remove();
|
detach( child );
|
||||||
if ( child.nodeType === TEXT_NODE ) {
|
if ( child.nodeType === TEXT_NODE ) {
|
||||||
prev.appendData( child.data );
|
prev.appendData( child.data );
|
||||||
}
|
}
|
||||||
|
|
@ -494,8 +500,7 @@ const
|
||||||
parent.childNodes.length === 1 ) {
|
parent.childNodes.length === 1 ) {
|
||||||
container = parent;
|
container = parent;
|
||||||
}
|
}
|
||||||
// container.remove(); // not a function?
|
detach( container );
|
||||||
container.parentNode && container.parentNode.removeChild( container );
|
|
||||||
|
|
||||||
offset = block.childNodes.length;
|
offset = block.childNodes.length;
|
||||||
|
|
||||||
|
|
@ -527,14 +532,14 @@ const
|
||||||
if ( prev && areAlike( prev, node ) ) {
|
if ( prev && areAlike( prev, node ) ) {
|
||||||
if ( !isContainer( prev ) ) {
|
if ( !isContainer( prev ) ) {
|
||||||
if ( isListItem ) {
|
if ( isListItem ) {
|
||||||
block = createElement( doc, 'DIV' );
|
block = createElement( 'DIV' );
|
||||||
block.append( empty( prev ) );
|
block.append( empty( prev ) );
|
||||||
prev.append( block );
|
prev.append( block );
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
node.remove();
|
detach( node );
|
||||||
needsFix = !isContainer( node );
|
needsFix = !isContainer( node );
|
||||||
prev.append( empty( node ) );
|
prev.append( empty( node ) );
|
||||||
if ( needsFix ) {
|
if ( needsFix ) {
|
||||||
|
|
@ -544,7 +549,7 @@ const
|
||||||
mergeContainers( first, root );
|
mergeContainers( first, root );
|
||||||
}
|
}
|
||||||
} else if ( isListItem ) {
|
} else if ( isListItem ) {
|
||||||
prev = createElement( doc, 'DIV' );
|
prev = createElement( 'DIV' );
|
||||||
node.insertBefore( prev, first );
|
node.insertBefore( prev, first );
|
||||||
fixCursor( prev, root );
|
fixCursor( prev, root );
|
||||||
}
|
}
|
||||||
|
|
@ -679,7 +684,7 @@ const
|
||||||
afterText = NBSP + afterText.slice( 1 ); // nbsp
|
afterText = NBSP + afterText.slice( 1 ); // nbsp
|
||||||
}
|
}
|
||||||
before.appendData( afterText );
|
before.appendData( afterText );
|
||||||
after.remove();
|
detach( after );
|
||||||
}
|
}
|
||||||
|
|
||||||
range.setStart( startContainer, startOffset );
|
range.setStart( startContainer, startOffset );
|
||||||
|
|
@ -810,7 +815,7 @@ const
|
||||||
if ( replaceBlock ) {
|
if ( replaceBlock ) {
|
||||||
range.setEndBefore( block );
|
range.setEndBefore( block );
|
||||||
range.collapse( false );
|
range.collapse( false );
|
||||||
block.remove();
|
detach( block );
|
||||||
}
|
}
|
||||||
moveRangeBoundariesUpTree( range, stopPoint, stopPoint, root );
|
moveRangeBoundariesUpTree( range, stopPoint, stopPoint, root );
|
||||||
// Now split after block up to blockquote (if a parent) or root
|
// Now split after block up to blockquote (if a parent) or root
|
||||||
|
|
@ -952,10 +957,7 @@ const
|
||||||
startContainer = parent;
|
startContainer = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ( true ) {
|
while ( endContainer !== endMax && endContainer !== root ) {
|
||||||
if ( endContainer === endMax || endContainer === root ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if ( maySkipBR &&
|
if ( maySkipBR &&
|
||||||
endContainer.nodeType !== TEXT_NODE &&
|
endContainer.nodeType !== TEXT_NODE &&
|
||||||
endContainer.childNodes[ endOffset ] &&
|
endContainer.childNodes[ endOffset ] &&
|
||||||
|
|
@ -1119,21 +1121,19 @@ TreeWalker.prototype.previousPONode = function () {
|
||||||
nodeType = this.nodeType,
|
nodeType = this.nodeType,
|
||||||
filter = this.filter,
|
filter = this.filter,
|
||||||
node;
|
node;
|
||||||
while ( true ) {
|
while ( current ) {
|
||||||
node = current.lastChild;
|
node = current.lastChild;
|
||||||
while ( !node && current && current !== root) {
|
while ( !node && current && current !== root) {
|
||||||
node = current.previousSibling;
|
node = current.previousSibling;
|
||||||
if ( !node ) { current = current.parentNode; }
|
if ( !node ) { current = current.parentNode; }
|
||||||
}
|
}
|
||||||
if ( !node ) {
|
if ( node && ( typeToBitArray[ node.nodeType ] & nodeType ) && filter( node ) ) {
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if ( ( typeToBitArray[ node.nodeType ] & nodeType ) && filter( node ) ) {
|
|
||||||
this.currentNode = node;
|
this.currentNode = node;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
current = node;
|
current = node;
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
let onKey = function ( event ) {
|
let onKey = function ( event ) {
|
||||||
|
|
@ -1236,7 +1236,7 @@ let afterDelete = ( self, range ) => {
|
||||||
// block.
|
// block.
|
||||||
if ( node === self._root &&
|
if ( node === self._root &&
|
||||||
( node = node.firstChild ) && node.nodeName === 'BR' ) {
|
( node = node.firstChild ) && node.nodeName === 'BR' ) {
|
||||||
node.remove();
|
detach( node );
|
||||||
}
|
}
|
||||||
self._ensureBottomLine();
|
self._ensureBottomLine();
|
||||||
self.setSelection( range );
|
self.setSelection( range );
|
||||||
|
|
@ -1254,7 +1254,7 @@ let detachUneditableNode = ( node, root ) => {
|
||||||
}
|
}
|
||||||
node = parent;
|
node = parent;
|
||||||
}
|
}
|
||||||
node.remove();
|
detach( node );
|
||||||
};
|
};
|
||||||
|
|
||||||
let handleEnter = ( self, shiftKey, range ) => {
|
let handleEnter = ( self, shiftKey, range ) => {
|
||||||
|
|
@ -1299,12 +1299,12 @@ let handleEnter = ( self, shiftKey, range ) => {
|
||||||
split( node, offset && offset - 1, root, root );
|
split( node, offset && offset - 1, root, root );
|
||||||
node = nodeAfterSplit.previousSibling;
|
node = nodeAfterSplit.previousSibling;
|
||||||
if ( !node.textContent ) {
|
if ( !node.textContent ) {
|
||||||
node.remove();
|
detach( node );
|
||||||
}
|
}
|
||||||
node = self.createDefaultBlock();
|
node = self.createDefaultBlock();
|
||||||
nodeAfterSplit.before( node );
|
nodeAfterSplit.before( node );
|
||||||
if ( !nodeAfterSplit.textContent ) {
|
if ( !nodeAfterSplit.textContent ) {
|
||||||
nodeAfterSplit.remove();
|
detach( nodeAfterSplit );
|
||||||
}
|
}
|
||||||
range.setStart( node, 0 );
|
range.setStart( node, 0 );
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1332,7 +1332,7 @@ let handleEnter = ( self, shiftKey, range ) => {
|
||||||
if ( !block || shiftKey || /^T[HD]$/.test( block.nodeName ) ) {
|
if ( !block || shiftKey || /^T[HD]$/.test( block.nodeName ) ) {
|
||||||
// If inside an <a>, move focus out
|
// If inside an <a>, move focus out
|
||||||
moveRangeBoundaryOutOf( range, 'A', root );
|
moveRangeBoundaryOutOf( range, 'A', root );
|
||||||
insertNodeInRange( range, self.createElement( 'BR' ) );
|
insertNodeInRange( range, createElement( 'BR' ) );
|
||||||
range.collapse( false );
|
range.collapse( false );
|
||||||
self.setSelection( range );
|
self.setSelection( range );
|
||||||
self._updatePath( range, true );
|
self._updatePath( range, true );
|
||||||
|
|
@ -1382,7 +1382,7 @@ let handleEnter = ( self, shiftKey, range ) => {
|
||||||
if ( !next || next.nodeName === 'BR' ) {
|
if ( !next || next.nodeName === 'BR' ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
child.remove();
|
detach( child );
|
||||||
child = next;
|
child = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1554,7 +1554,7 @@ let keyHandlers = {
|
||||||
nodeAfterCursor = cursorContainer.childNodes[ cursorOffset ];
|
nodeAfterCursor = cursorContainer.childNodes[ cursorOffset ];
|
||||||
if ( nodeAfterCursor && nodeAfterCursor.nodeName === 'IMG' ) {
|
if ( nodeAfterCursor && nodeAfterCursor.nodeName === 'IMG' ) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
nodeAfterCursor.remove();
|
detach( nodeAfterCursor );
|
||||||
moveRangeBoundariesDownTree( range );
|
moveRangeBoundariesDownTree( range );
|
||||||
afterDelete( self, range );
|
afterDelete( self, range );
|
||||||
return;
|
return;
|
||||||
|
|
@ -1694,40 +1694,40 @@ let fontSizes = {
|
||||||
let styleToSemantic = {
|
let styleToSemantic = {
|
||||||
fontWeight: {
|
fontWeight: {
|
||||||
regexp: /^bold|^700/i,
|
regexp: /^bold|^700/i,
|
||||||
replace: doc => createElement( doc, 'B' )
|
replace: () => createElement( 'B' )
|
||||||
},
|
},
|
||||||
fontStyle: {
|
fontStyle: {
|
||||||
regexp: /^italic/i,
|
regexp: /^italic/i,
|
||||||
replace: doc => createElement( doc, 'I' )
|
replace: () => createElement( 'I' )
|
||||||
},
|
},
|
||||||
fontFamily: {
|
fontFamily: {
|
||||||
regexp: notWS,
|
regexp: notWS,
|
||||||
replace: ( doc, classNames, family ) => createElement( doc, 'SPAN', {
|
replace: ( doc, classNames, family ) => createElement( 'SPAN', {
|
||||||
'class': classNames.fontFamily,
|
'class': classNames.fontFamily,
|
||||||
style: 'font-family:' + family
|
style: 'font-family:' + family
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
fontSize: {
|
fontSize: {
|
||||||
regexp: notWS,
|
regexp: notWS,
|
||||||
replace: ( doc, classNames, size ) => createElement( doc, 'SPAN', {
|
replace: ( doc, classNames, size ) => createElement( 'SPAN', {
|
||||||
'class': classNames.fontSize,
|
'class': classNames.fontSize,
|
||||||
style: 'font-size:' + size
|
style: 'font-size:' + size
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
textDecoration: {
|
textDecoration: {
|
||||||
regexp: /^underline/i,
|
regexp: /^underline/i,
|
||||||
replace: doc => createElement( doc, 'U' )
|
replace: () => createElement( 'U' )
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
textDecoration: {
|
textDecoration: {
|
||||||
regexp: /^line-through/i,
|
regexp: /^line-through/i,
|
||||||
replace: doc => createElement( doc, 'S' )
|
replace: doc => createElement( 'S' )
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
let replaceWithTag = tag => node => {
|
let replaceWithTag = tag => node => {
|
||||||
let el = createElement( doc, tag );
|
let el = createElement( tag );
|
||||||
Array.prototype.forEach.call( node.attributes, attr => el.setAttribute( attr.name, attr.value ) );
|
Array.prototype.forEach.call( node.attributes, attr => el.setAttribute( attr.name, attr.value ) );
|
||||||
node.replaceWith( el );
|
node.replaceWith( el );
|
||||||
el.append( empty( node ) );
|
el.append( empty( node ) );
|
||||||
|
|
@ -1780,7 +1780,7 @@ let stylesRewriters = {
|
||||||
let fontSpan, sizeSpan, colourSpan;
|
let fontSpan, sizeSpan, colourSpan;
|
||||||
let newTreeBottom, newTreeTop;
|
let newTreeBottom, newTreeTop;
|
||||||
if ( face ) {
|
if ( face ) {
|
||||||
fontSpan = createElement( doc, 'SPAN', {
|
fontSpan = createElement( 'SPAN', {
|
||||||
'class': classNames.fontFamily,
|
'class': classNames.fontFamily,
|
||||||
style: 'font-family:' + face
|
style: 'font-family:' + face
|
||||||
});
|
});
|
||||||
|
|
@ -1788,7 +1788,7 @@ let stylesRewriters = {
|
||||||
newTreeBottom = fontSpan;
|
newTreeBottom = fontSpan;
|
||||||
}
|
}
|
||||||
if ( size ) {
|
if ( size ) {
|
||||||
sizeSpan = createElement( doc, 'SPAN', {
|
sizeSpan = createElement( 'SPAN', {
|
||||||
'class': classNames.fontSize,
|
'class': classNames.fontSize,
|
||||||
style: 'font-size:' + fontSizes[ size ] + 'px'
|
style: 'font-size:' + fontSizes[ size ] + 'px'
|
||||||
});
|
});
|
||||||
|
|
@ -1804,7 +1804,7 @@ let stylesRewriters = {
|
||||||
if ( colour.charAt( 0 ) !== '#' ) {
|
if ( colour.charAt( 0 ) !== '#' ) {
|
||||||
colour = '#' + colour;
|
colour = '#' + colour;
|
||||||
}
|
}
|
||||||
colourSpan = createElement( doc, 'SPAN', {
|
colourSpan = createElement( 'SPAN', {
|
||||||
'class': classNames.colour,
|
'class': classNames.colour,
|
||||||
style: 'color:' + colour
|
style: 'color:' + colour
|
||||||
});
|
});
|
||||||
|
|
@ -1817,7 +1817,7 @@ let stylesRewriters = {
|
||||||
newTreeBottom = colourSpan;
|
newTreeBottom = colourSpan;
|
||||||
}
|
}
|
||||||
if ( !newTreeTop ) {
|
if ( !newTreeTop ) {
|
||||||
newTreeTop = newTreeBottom = createElement( doc, 'SPAN' );
|
newTreeTop = newTreeBottom = createElement( 'SPAN' );
|
||||||
}
|
}
|
||||||
node.replaceWith( newTreeTop );
|
node.replaceWith( newTreeTop );
|
||||||
newTreeBottom.append( empty( node ) );
|
newTreeBottom.append( empty( node ) );
|
||||||
|
|
@ -1828,7 +1828,7 @@ let stylesRewriters = {
|
||||||
// CODE:
|
// CODE:
|
||||||
// SAMP:
|
// SAMP:
|
||||||
TT: ( node, parent, config ) => {
|
TT: ( node, parent, config ) => {
|
||||||
let el = createElement( doc, 'SPAN', {
|
let el = createElement( 'SPAN', {
|
||||||
'class': config.classNames.fontFamily,
|
'class': config.classNames.fontFamily,
|
||||||
style: 'font-family:menlo,consolas,"courier new",monospace'
|
style: 'font-family:menlo,consolas,"courier new",monospace'
|
||||||
});
|
});
|
||||||
|
|
@ -2002,7 +2002,7 @@ let cleanupBRs = ( node, root, keepForBlankLine ) => {
|
||||||
// browser. If it breaks a line, wrap the content in div tags
|
// browser. If it breaks a line, wrap the content in div tags
|
||||||
// and replace the brs.
|
// and replace the brs.
|
||||||
if ( !brBreaksLine[l] ) {
|
if ( !brBreaksLine[l] ) {
|
||||||
br.remove();
|
detach( br );
|
||||||
} else if ( !isInline( parent ) ) {
|
} else if ( !isInline( parent ) ) {
|
||||||
fixContainer( parent, root );
|
fixContainer( parent, root );
|
||||||
}
|
}
|
||||||
|
|
@ -2016,7 +2016,7 @@ let setClipboardData =
|
||||||
( event, contents, root, willCutCopy, toPlainText, plainTextOnly ) => {
|
( event, contents, root, willCutCopy, toPlainText, plainTextOnly ) => {
|
||||||
let clipboardData = event.clipboardData;
|
let clipboardData = event.clipboardData;
|
||||||
let body = doc.body;
|
let body = doc.body;
|
||||||
let node = createElement( doc, 'div' );
|
let node = createElement( 'div' );
|
||||||
let html, text;
|
let html, text;
|
||||||
|
|
||||||
node.append( contents );
|
node.append( contents );
|
||||||
|
|
@ -2291,11 +2291,6 @@ function mergeObjects ( base, extras, mayOverride ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function Squire ( root, config ) {
|
function Squire ( root, config ) {
|
||||||
if ( root.nodeType === DOCUMENT_NODE ) {
|
|
||||||
root = root.body;
|
|
||||||
}
|
|
||||||
let mutation;
|
|
||||||
|
|
||||||
this._root = root;
|
this._root = root;
|
||||||
|
|
||||||
this._events = {};
|
this._events = {};
|
||||||
|
|
@ -2308,16 +2303,14 @@ function Squire ( root, config ) {
|
||||||
this._lastAnchorNode = null;
|
this._lastAnchorNode = null;
|
||||||
this._lastFocusNode = null;
|
this._lastFocusNode = null;
|
||||||
this._path = '';
|
this._path = '';
|
||||||
this._willUpdatePath = false;
|
|
||||||
|
|
||||||
|
let _willUpdatePath;
|
||||||
const selectionchange = () => {
|
const selectionchange = () => {
|
||||||
if (root.contains(doc.activeElement)) {
|
if (root.contains(doc.activeElement)) {
|
||||||
let self = this;
|
if ( this._isFocused && !_willUpdatePath ) {
|
||||||
if ( self._isFocused && !self._willUpdatePath ) {
|
_willUpdatePath = setTimeout( () => {
|
||||||
self._willUpdatePath = true;
|
_willUpdatePath = 0;
|
||||||
setTimeout( function () {
|
this._updatePath( this.getSelection() );
|
||||||
self._willUpdatePath = false;
|
|
||||||
self._updatePath( self.getSelection() );
|
|
||||||
}, 0 );
|
}, 0 );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2333,14 +2326,13 @@ function Squire ( root, config ) {
|
||||||
this._ignoreChange = false;
|
this._ignoreChange = false;
|
||||||
this._ignoreAllChanges = false;
|
this._ignoreAllChanges = false;
|
||||||
|
|
||||||
mutation = new MutationObserver( ()=>this._docWasChanged() );
|
this._mutation = new MutationObserver( ()=>this._docWasChanged() );
|
||||||
mutation.observe( root, {
|
this._mutation.observe( root, {
|
||||||
childList: true,
|
childList: true,
|
||||||
attributes: true,
|
attributes: true,
|
||||||
characterData: true,
|
characterData: true,
|
||||||
subtree: true
|
subtree: true
|
||||||
});
|
});
|
||||||
this._mutation = mutation;
|
|
||||||
|
|
||||||
// On blur, restore focus except if the user taps or clicks to focus a
|
// On blur, restore focus except if the user taps or clicks to focus a
|
||||||
// specific point. Can't actually use click event because focus happens
|
// specific point. Can't actually use click event because focus happens
|
||||||
|
|
@ -2430,14 +2422,10 @@ proto.setConfig = function ( config ) {
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
proto.createElement = function ( tag, props, children ) {
|
|
||||||
return createElement( doc, tag, props, children );
|
|
||||||
};
|
|
||||||
|
|
||||||
proto.createDefaultBlock = function ( children ) {
|
proto.createDefaultBlock = function ( children ) {
|
||||||
let config = this._config;
|
let config = this._config;
|
||||||
return fixCursor(
|
return fixCursor(
|
||||||
this.createElement( config.blockTag, config.blockAttributes, children ),
|
createElement( config.blockTag, config.blockAttributes, children ),
|
||||||
this._root
|
this._root
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
@ -2606,8 +2594,7 @@ proto.removeEventListener = function ( type, fn ) {
|
||||||
|
|
||||||
// --- Selection and Path ---
|
// --- Selection and Path ---
|
||||||
|
|
||||||
proto.createRange =
|
proto.createRange = ( range, startOffset, endContainer, endOffset ) => {
|
||||||
function ( range, startOffset, endContainer, endOffset ) {
|
|
||||||
if ( range instanceof win.Range ) {
|
if ( range instanceof win.Range ) {
|
||||||
return range.cloneRange();
|
return range.cloneRange();
|
||||||
}
|
}
|
||||||
|
|
@ -2631,7 +2618,7 @@ proto.getCursorPosition = function ( range ) {
|
||||||
let node, parent;
|
let node, parent;
|
||||||
if ( rect && !rect.top ) {
|
if ( rect && !rect.top ) {
|
||||||
this._ignoreChange = true;
|
this._ignoreChange = true;
|
||||||
node = doc.createElement( 'SPAN' );
|
node = createElement( 'SPAN' );
|
||||||
node.textContent = ZWS;
|
node.textContent = ZWS;
|
||||||
insertNodeInRange( range, node );
|
insertNodeInRange( range, node );
|
||||||
rect = node.getBoundingClientRect();
|
rect = node.getBoundingClientRect();
|
||||||
|
|
@ -2854,12 +2841,12 @@ proto.blur = function () {
|
||||||
let startSelectionId = 'squire-selection-start';
|
let startSelectionId = 'squire-selection-start';
|
||||||
let endSelectionId = 'squire-selection-end';
|
let endSelectionId = 'squire-selection-end';
|
||||||
|
|
||||||
const createBookmarkNodes = self => [
|
const createBookmarkNodes = () => [
|
||||||
self.createElement( 'INPUT', {
|
createElement( 'INPUT', {
|
||||||
id: startSelectionId,
|
id: startSelectionId,
|
||||||
type: 'hidden'
|
type: 'hidden'
|
||||||
}),
|
}),
|
||||||
self.createElement( 'INPUT', {
|
createElement( 'INPUT', {
|
||||||
id: endSelectionId,
|
id: endSelectionId,
|
||||||
type: 'hidden'
|
type: 'hidden'
|
||||||
})
|
})
|
||||||
|
|
@ -2902,8 +2889,8 @@ proto._getRangeAndRemoveBookmark = function ( range ) {
|
||||||
--endOffset;
|
--endOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
start.remove();
|
detach( start );
|
||||||
end.remove();
|
detach( end );
|
||||||
|
|
||||||
if ( !range ) {
|
if ( !range ) {
|
||||||
range = doc.createRange();
|
range = doc.createRange();
|
||||||
|
|
@ -3182,7 +3169,7 @@ proto._addFormat = function ( tag, attributes, range ) {
|
||||||
node, needsFormat, block;
|
node, needsFormat, block;
|
||||||
|
|
||||||
if ( range.collapsed ) {
|
if ( range.collapsed ) {
|
||||||
el = fixCursor( this.createElement( tag, attributes ), root );
|
el = fixCursor( createElement( tag, attributes ), root );
|
||||||
insertNodeInRange( range, el );
|
insertNodeInRange( range, el );
|
||||||
range.setStart( el.firstChild, el.firstChild.length );
|
range.setStart( el.firstChild, el.firstChild.length );
|
||||||
range.collapse( true );
|
range.collapse( true );
|
||||||
|
|
@ -3256,7 +3243,7 @@ proto._addFormat = function ( tag, attributes, range ) {
|
||||||
startContainer = node;
|
startContainer = node;
|
||||||
startOffset = 0;
|
startOffset = 0;
|
||||||
}
|
}
|
||||||
el = this.createElement( tag, attributes );
|
el = createElement( tag, attributes );
|
||||||
node.replaceWith( el );
|
node.replaceWith( el );
|
||||||
el.append( node );
|
el.append( node );
|
||||||
}
|
}
|
||||||
|
|
@ -3312,7 +3299,7 @@ proto._removeFormat = function ( tag, attributes, range, partial ) {
|
||||||
endContainer = range.endContainer,
|
endContainer = range.endContainer,
|
||||||
endOffset = range.endOffset,
|
endOffset = range.endOffset,
|
||||||
toWrap = [],
|
toWrap = [],
|
||||||
examineNode = function ( node, exemplar ) {
|
examineNode = ( node, exemplar ) => {
|
||||||
// If the node is completely contained by the range then
|
// If the node is completely contained by the range then
|
||||||
// we're going to remove all formatting so ignore it.
|
// we're going to remove all formatting so ignore it.
|
||||||
if ( isNodeContainedInRange( range, node, false ) ) {
|
if ( isNodeContainedInRange( range, node, false ) ) {
|
||||||
|
|
@ -3354,20 +3341,16 @@ proto._removeFormat = function ( tag, attributes, range, partial ) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
formatTags = Array.prototype.filter.call(
|
formatTags = Array.prototype.filter.call(
|
||||||
root.getElementsByTagName( tag ), function ( el ) {
|
root.getElementsByTagName( tag ),
|
||||||
return isNodeContainedInRange( range, el ) &&
|
el => isNodeContainedInRange( range, el ) && hasTagAttributes( el, tag, attributes )
|
||||||
hasTagAttributes( el, tag, attributes );
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if ( !partial ) {
|
if ( !partial ) {
|
||||||
formatTags.forEach( function ( node ) {
|
formatTags.forEach( node => examineNode( node, node ) );
|
||||||
examineNode( node, node );
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now wrap unselected nodes in the tag
|
// Now wrap unselected nodes in the tag
|
||||||
toWrap.forEach( function ( item ) {
|
toWrap.forEach( item => {
|
||||||
// [ exemplar, node ] tuple
|
// [ exemplar, node ] tuple
|
||||||
let el = item[0].cloneNode( false ),
|
let el = item[0].cloneNode( false ),
|
||||||
node = item[1];
|
node = item[1];
|
||||||
|
|
@ -3375,9 +3358,7 @@ proto._removeFormat = function ( tag, attributes, range, partial ) {
|
||||||
el.append( node );
|
el.append( node );
|
||||||
});
|
});
|
||||||
// and remove old formatting tags.
|
// and remove old formatting tags.
|
||||||
formatTags.forEach( function ( el ) {
|
formatTags.forEach( el => el.replaceWith( empty( el ) ) );
|
||||||
el.replaceWith( empty( el ) );
|
|
||||||
});
|
|
||||||
|
|
||||||
// Merge adjacent inlines:
|
// Merge adjacent inlines:
|
||||||
this._getRangeAndRemoveBookmark( range );
|
this._getRangeAndRemoveBookmark( range );
|
||||||
|
|
@ -3435,8 +3416,7 @@ let splitBlock = ( self, block, node, offset ) => {
|
||||||
|
|
||||||
// Make sure the new node is the correct type.
|
// Make sure the new node is the correct type.
|
||||||
if ( !hasTagAttributes( nodeAfterSplit, splitTag, splitProperties ) ) {
|
if ( !hasTagAttributes( nodeAfterSplit, splitTag, splitProperties ) ) {
|
||||||
block = createElement( doc,
|
block = createElement( splitTag, splitProperties );
|
||||||
splitTag, splitProperties );
|
|
||||||
if ( nodeAfterSplit.dir ) {
|
if ( nodeAfterSplit.dir ) {
|
||||||
block.dir = nodeAfterSplit.dir;
|
block.dir = nodeAfterSplit.dir;
|
||||||
}
|
}
|
||||||
|
|
@ -3511,13 +3491,13 @@ proto.modifyBlocks = function ( modify, range ) {
|
||||||
};
|
};
|
||||||
|
|
||||||
let increaseBlockQuoteLevel = function ( frag ) {
|
let increaseBlockQuoteLevel = function ( frag ) {
|
||||||
return this.createElement( 'BLOCKQUOTE',
|
return createElement( 'BLOCKQUOTE',
|
||||||
this._config.tagAttributes.blockquote, [
|
this._config.tagAttributes.blockquote, [
|
||||||
frag
|
frag
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
let decreaseBlockQuoteLevel = function ( frag ) {
|
let decreaseBlockQuoteLevel = frag => {
|
||||||
var blockquotes = frag.querySelectorAll( 'blockquote' );
|
var blockquotes = frag.querySelectorAll( 'blockquote' );
|
||||||
Array.prototype.filter.call( blockquotes, el =>
|
Array.prototype.filter.call( blockquotes, el =>
|
||||||
!getClosest( el.parentNode, frag, 'BLOCKQUOTE' )
|
!getClosest( el.parentNode, frag, 'BLOCKQUOTE' )
|
||||||
|
|
@ -3538,7 +3518,7 @@ let makeList = ( self, frag, type ) => {
|
||||||
walker.currentNode = node.lastChild;
|
walker.currentNode = node.lastChild;
|
||||||
}
|
}
|
||||||
if ( node.nodeName !== 'LI' ) {
|
if ( node.nodeName !== 'LI' ) {
|
||||||
newLi = self.createElement( 'LI', listItemAttrs );
|
newLi = createElement( 'LI', listItemAttrs );
|
||||||
if ( node.dir ) {
|
if ( node.dir ) {
|
||||||
newLi.dir = node.dir;
|
newLi.dir = node.dir;
|
||||||
}
|
}
|
||||||
|
|
@ -3546,12 +3526,12 @@ let makeList = ( self, frag, type ) => {
|
||||||
// Have we replaced the previous block with a new <ul>/<ol>?
|
// Have we replaced the previous block with a new <ul>/<ol>?
|
||||||
if ( ( prev = node.previousSibling ) && prev.nodeName === type ) {
|
if ( ( prev = node.previousSibling ) && prev.nodeName === type ) {
|
||||||
prev.append( newLi );
|
prev.append( newLi );
|
||||||
node.remove();
|
detach( node );
|
||||||
}
|
}
|
||||||
// Otherwise, replace this block with the <ul>/<ol>
|
// Otherwise, replace this block with the <ul>/<ol>
|
||||||
else {
|
else {
|
||||||
node.replaceWith(
|
node.replaceWith(
|
||||||
self.createElement( type, listAttrs, [
|
createElement( type, listAttrs, [
|
||||||
newLi
|
newLi
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
|
|
@ -3563,7 +3543,7 @@ let makeList = ( self, frag, type ) => {
|
||||||
tag = node.nodeName;
|
tag = node.nodeName;
|
||||||
if ( tag !== type && ( /^[OU]L$/.test( tag ) ) ) {
|
if ( tag !== type && ( /^[OU]L$/.test( tag ) ) ) {
|
||||||
node.replaceWith(
|
node.replaceWith(
|
||||||
self.createElement( type, listAttrs, [ empty( node ) ] )
|
createElement( type, listAttrs, [ empty( node ) ] )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3659,7 +3639,7 @@ proto.increaseListLevel = function ( range ) {
|
||||||
let listAttrs, next;
|
let listAttrs, next;
|
||||||
if ( newParent.nodeName !== type ) {
|
if ( newParent.nodeName !== type ) {
|
||||||
listAttrs = this._config.tagAttributes[ type.toLowerCase() ];
|
listAttrs = this._config.tagAttributes[ type.toLowerCase() ];
|
||||||
newParent = this.createElement( type, listAttrs );
|
newParent = createElement( type, listAttrs );
|
||||||
startLi.before( newParent );
|
startLi.before( newParent );
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
@ -3735,7 +3715,7 @@ proto.decreaseListLevel = function ( range ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !list.firstChild ) {
|
if ( !list.firstChild ) {
|
||||||
list.remove();
|
detach( list );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( insertBefore ) {
|
if ( insertBefore ) {
|
||||||
|
|
@ -3805,7 +3785,7 @@ proto.setHTML = function ( html ) {
|
||||||
if ( typeof sanitizeToDOMFragment === 'function' ) {
|
if ( typeof sanitizeToDOMFragment === 'function' ) {
|
||||||
frag = sanitizeToDOMFragment( html, false, this );
|
frag = sanitizeToDOMFragment( html, false, this );
|
||||||
} else {
|
} else {
|
||||||
div = this.createElement( 'DIV' );
|
div = createElement( 'DIV' );
|
||||||
div.innerHTML = html;
|
div.innerHTML = html;
|
||||||
frag = doc.createDocumentFragment();
|
frag = doc.createDocumentFragment();
|
||||||
frag.append( empty( div ) );
|
frag.append( empty( div ) );
|
||||||
|
|
@ -3897,7 +3877,7 @@ proto.insertElement = function ( el, range ) {
|
||||||
};
|
};
|
||||||
|
|
||||||
proto.insertImage = function ( src, attributes ) {
|
proto.insertImage = function ( src, attributes ) {
|
||||||
let img = this.createElement( 'IMG', mergeObjects({
|
let img = createElement( 'IMG', mergeObjects({
|
||||||
src: src
|
src: src
|
||||||
}, attributes, true ));
|
}, attributes, true ));
|
||||||
this.insertElement( img );
|
this.insertElement( img );
|
||||||
|
|
@ -3924,7 +3904,7 @@ let addLinks = ( frag, root, self ) => {
|
||||||
child = doc.createTextNode( data.slice( 0, index ) );
|
child = doc.createTextNode( data.slice( 0, index ) );
|
||||||
parent.insertBefore( child, node );
|
parent.insertBefore( child, node );
|
||||||
}
|
}
|
||||||
child = self.createElement( 'A', mergeObjects({
|
child = createElement( 'A', mergeObjects({
|
||||||
href: match[1] ?
|
href: match[1] ?
|
||||||
/^(?:ht|f)tps?:/i.test( match[1] ) ?
|
/^(?:ht|f)tps?:/i.test( match[1] ) ?
|
||||||
match[1] :
|
match[1] :
|
||||||
|
|
@ -3971,7 +3951,7 @@ proto.insertHTML = function ( html, isPaste ) {
|
||||||
html = '<TABLE>' + html + '</TABLE>';
|
html = '<TABLE>' + html + '</TABLE>';
|
||||||
}
|
}
|
||||||
// Parse HTML into DOM tree
|
// Parse HTML into DOM tree
|
||||||
div = this.createElement( 'DIV' );
|
div = createElement( 'DIV' );
|
||||||
div.innerHTML = html;
|
div.innerHTML = html;
|
||||||
frag = doc.createDocumentFragment();
|
frag = doc.createDocumentFragment();
|
||||||
frag.append( empty( div ) );
|
frag.append( empty( div ) );
|
||||||
|
|
@ -4106,7 +4086,7 @@ let command = ( method, arg, arg2 ) => function () {
|
||||||
proto.addStyles = function ( styles ) {
|
proto.addStyles = function ( styles ) {
|
||||||
if ( styles ) {
|
if ( styles ) {
|
||||||
let head = doc.documentElement.firstChild,
|
let head = doc.documentElement.firstChild,
|
||||||
style = this.createElement( 'STYLE', {
|
style = createElement( 'STYLE', {
|
||||||
type: 'text/css'
|
type: 'text/css'
|
||||||
});
|
});
|
||||||
style.append( doc.createTextNode( styles ) );
|
style.append( doc.createTextNode( styles ) );
|
||||||
|
|
@ -4225,26 +4205,14 @@ proto.setHighlightColour = function ( colour ) {
|
||||||
};
|
};
|
||||||
|
|
||||||
proto.setTextAlignment = function ( alignment ) {
|
proto.setTextAlignment = function ( alignment ) {
|
||||||
this.forEachBlock( function ( block ) {
|
this.forEachBlock( block => {
|
||||||
let className = block.className
|
block.style.textAlign = alignment || '';
|
||||||
.split( /\s+/ )
|
|
||||||
.filter( function ( klass ) {
|
|
||||||
return !!klass && !/^align/.test( klass );
|
|
||||||
})
|
|
||||||
.join( ' ' );
|
|
||||||
if ( alignment ) {
|
|
||||||
block.className = className + ' align-' + alignment;
|
|
||||||
block.style.textAlign = alignment;
|
|
||||||
} else {
|
|
||||||
block.className = className;
|
|
||||||
block.style.textAlign = '';
|
|
||||||
}
|
|
||||||
}, true );
|
}, true );
|
||||||
return this.focus();
|
return this.focus();
|
||||||
};
|
};
|
||||||
|
|
||||||
proto.setTextDirection = function ( direction ) {
|
proto.setTextDirection = function ( direction ) {
|
||||||
this.forEachBlock( function ( block ) {
|
this.forEachBlock( block => {
|
||||||
if ( direction ) {
|
if ( direction ) {
|
||||||
block.dir = direction;
|
block.dir = direction;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -4280,7 +4248,7 @@ let addPre = function ( frag ) {
|
||||||
while ( l-- ) {
|
while ( l-- ) {
|
||||||
br = nodes[l];
|
br = nodes[l];
|
||||||
if ( !brBreaksLine[l] ) {
|
if ( !brBreaksLine[l] ) {
|
||||||
br.remove();
|
detach( br );
|
||||||
} else {
|
} else {
|
||||||
br.replaceWith( doc.createTextNode( '\n' ) );
|
br.replaceWith( doc.createTextNode( '\n' ) );
|
||||||
}
|
}
|
||||||
|
|
@ -4289,7 +4257,7 @@ let addPre = function ( frag ) {
|
||||||
nodes = node.querySelectorAll( 'CODE' );
|
nodes = node.querySelectorAll( 'CODE' );
|
||||||
l = nodes.length;
|
l = nodes.length;
|
||||||
while ( l-- ) {
|
while ( l-- ) {
|
||||||
nodes[l].remove();
|
detach( nodes[l] );
|
||||||
}
|
}
|
||||||
if ( output.childNodes.length ) {
|
if ( output.childNodes.length ) {
|
||||||
output.append( doc.createTextNode( '\n' ) );
|
output.append( doc.createTextNode( '\n' ) );
|
||||||
|
|
@ -4302,7 +4270,7 @@ let addPre = function ( frag ) {
|
||||||
node.data = node.data.replace( NBSP, ' ' ); // nbsp -> sp
|
node.data = node.data.replace( NBSP, ' ' ); // nbsp -> sp
|
||||||
}
|
}
|
||||||
output.normalize();
|
output.normalize();
|
||||||
return fixCursor( this.createElement( 'PRE',
|
return fixCursor( createElement( 'PRE',
|
||||||
this._config.tagAttributes.pre, [
|
this._config.tagAttributes.pre, [
|
||||||
output
|
output
|
||||||
]), root );
|
]), root );
|
||||||
|
|
@ -4324,7 +4292,7 @@ let removePre = function ( frag ) {
|
||||||
contents.append(
|
contents.append(
|
||||||
doc.createTextNode( value.slice( 0, index ) )
|
doc.createTextNode( value.slice( 0, index ) )
|
||||||
);
|
);
|
||||||
contents.append( doc.createElement( 'BR' ) );
|
contents.append( createElement( 'BR' ) );
|
||||||
value = value.slice( index + 1 );
|
value = value.slice( index + 1 );
|
||||||
}
|
}
|
||||||
node.before( contents );
|
node.before( contents );
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue