@innovastudio/contentbuilder 1.4.124 → 1.4.126
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.
|
@@ -1439,7 +1439,7 @@ class Util {
|
|
|
1439
1439
|
const selection = this.builder.win.getSelection();
|
|
1440
1440
|
const container = this.builder.dom.getElm();
|
|
1441
1441
|
if (!container) return;
|
|
1442
|
-
const sameSelection = container && container.innerText === selection.toString();
|
|
1442
|
+
const sameSelection = container && container.innerText === selection.toString().trim();
|
|
1443
1443
|
if (sameSelection || selection.toString().trim() === '') {
|
|
1444
1444
|
this.builder.selectionElm = container;
|
|
1445
1445
|
|
|
@@ -3395,7 +3395,7 @@ class Dom {
|
|
|
3395
3395
|
if (callback) callback(false);
|
|
3396
3396
|
return;
|
|
3397
3397
|
}
|
|
3398
|
-
const sameSelection = container && container.innerText === selection.toString();
|
|
3398
|
+
const sameSelection = container && container.innerText === selection.toString().trim();
|
|
3399
3399
|
let newElement;
|
|
3400
3400
|
if (sameSelection || selection.toString().trim() === '') {
|
|
3401
3401
|
newElement = this.updateSelection(action, value, container);
|
|
@@ -3519,7 +3519,7 @@ class Dom {
|
|
|
3519
3519
|
const selection = this.builder.win.getSelection();
|
|
3520
3520
|
let container = this.getElm();
|
|
3521
3521
|
if (!container) return;
|
|
3522
|
-
const sameSelection = container && container.innerText === selection.toString();
|
|
3522
|
+
const sameSelection = container && container.innerText === selection.toString().trim();
|
|
3523
3523
|
if (currentElement) {
|
|
3524
3524
|
if (mode === 'block') if (this.getStyle(container, 'display') === 'inline') {
|
|
3525
3525
|
container = this.getParentBlock(container);
|
|
@@ -3592,7 +3592,7 @@ class Dom {
|
|
|
3592
3592
|
}
|
|
3593
3593
|
}
|
|
3594
3594
|
let blocks = [];
|
|
3595
|
-
const blockElms = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'pre'];
|
|
3595
|
+
const blockElms = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'pre', 'td', 'th'];
|
|
3596
3596
|
elements.forEach(item => {
|
|
3597
3597
|
const tagName = item.tagName.toLowerCase();
|
|
3598
3598
|
if (blockElms.includes(tagName)) {
|
|
@@ -3600,6 +3600,21 @@ class Dom {
|
|
|
3600
3600
|
blocks.push(item);
|
|
3601
3601
|
}
|
|
3602
3602
|
});
|
|
3603
|
+
|
|
3604
|
+
/*
|
|
3605
|
+
If a block is double clicked to select the block, the selection goes to the next block as well.
|
|
3606
|
+
This seems a default behavior (tested with simple contentEditable div). So the blocks contains 2 blocks.
|
|
3607
|
+
To fix this, perform an extra test here:
|
|
3608
|
+
*/
|
|
3609
|
+
if (blocks.length === 2) {
|
|
3610
|
+
// console.log(blocks[0].innerText.trim());
|
|
3611
|
+
// console.log(selection.toString().trim());
|
|
3612
|
+
if (blocks[0].innerText.trim() === selection.toString().trim()) {
|
|
3613
|
+
blocks.pop();
|
|
3614
|
+
// console.log('remove last')
|
|
3615
|
+
}
|
|
3616
|
+
}
|
|
3617
|
+
|
|
3603
3618
|
if (multiSelectBlocks) {
|
|
3604
3619
|
return blocks;
|
|
3605
3620
|
} else {
|
|
@@ -3733,7 +3748,7 @@ class Dom {
|
|
|
3733
3748
|
const selection = this.builder.win.getSelection();
|
|
3734
3749
|
const container = this.getElm();
|
|
3735
3750
|
if (!container) return;
|
|
3736
|
-
const sameSelection = container && container.innerText === selection.toString();
|
|
3751
|
+
const sameSelection = container && container.innerText === selection.toString().trim();
|
|
3737
3752
|
if (sameSelection || selection.toString().trim() === '') {
|
|
3738
3753
|
this.updateSelectionToggle(action, value, config, container);
|
|
3739
3754
|
} else {
|
|
@@ -4155,7 +4170,7 @@ class Dom {
|
|
|
4155
4170
|
const anchorNode = selection.anchorNode;
|
|
4156
4171
|
if (!anchorNode) return;
|
|
4157
4172
|
const container = anchorNode.nodeType !== Node.TEXT_NODE && anchorNode.nodeType !== Node.COMMENT_NODE ? anchorNode : anchorNode.parentElement;
|
|
4158
|
-
const sameSelection = container && container.innerText === selection.toString();
|
|
4173
|
+
const sameSelection = container && container.innerText === selection.toString().trim();
|
|
4159
4174
|
if (sameSelection || selection.toString().trim() === '') {
|
|
4160
4175
|
this.cleanElement(container);
|
|
4161
4176
|
} else {
|
|
@@ -66285,7 +66300,7 @@ class Rte {
|
|
|
66285
66300
|
} else if (num === '+' || num === '-') {
|
|
66286
66301
|
for (let i = 0; i < Object.keys(classes).length; i++) {
|
|
66287
66302
|
let className = Object.values(classes)[i];
|
|
66288
|
-
if (
|
|
66303
|
+
if (container.closest('.' + className) && !container.classList.contains('is-builder')) {
|
|
66289
66304
|
if (num === '+') {
|
|
66290
66305
|
if (i + 1 === Object.keys(classes).length) return;
|
|
66291
66306
|
newClassName = Object.values(classes)[i + 1];
|
|
@@ -76867,8 +76882,10 @@ class ContentBuilder {
|
|
|
76867
76882
|
// ON PASTE
|
|
76868
76883
|
// col.addEventListener('paste', this.handleCellPaste.bind(this));
|
|
76869
76884
|
col.addEventListener('paste', e => {
|
|
76870
|
-
|
|
76871
|
-
|
|
76885
|
+
e.preventDefault();
|
|
76886
|
+
const clipboardDataText = (e.clipboardData || window.clipboardData).getData('text');
|
|
76887
|
+
const clipboardDataHtml = (e.clipboardData || window.clipboardData).getData('text/html');
|
|
76888
|
+
this.handleCellPaste(clipboardDataText, clipboardDataHtml);
|
|
76872
76889
|
});
|
|
76873
76890
|
col.setAttribute('data-click', true);
|
|
76874
76891
|
}
|
|
@@ -79046,6 +79063,7 @@ class ContentBuilder {
|
|
|
79046
79063
|
// CMD-B
|
|
79047
79064
|
|
|
79048
79065
|
if (this.opts.useCssClasses) {
|
|
79066
|
+
this.uo.saveForUndo();
|
|
79049
79067
|
this.dom.execCommandToggle('fontWeight', '', this.opts.cssClasses);
|
|
79050
79068
|
this.opts.onChange();
|
|
79051
79069
|
e.preventDefault();
|
|
@@ -79056,6 +79074,7 @@ class ContentBuilder {
|
|
|
79056
79074
|
// CMD-I
|
|
79057
79075
|
|
|
79058
79076
|
if (this.opts.useCssClasses) {
|
|
79077
|
+
this.uo.saveForUndo();
|
|
79059
79078
|
this.dom.execCommandToggle('fontStyle', '', this.opts.cssClasses);
|
|
79060
79079
|
this.opts.onChange();
|
|
79061
79080
|
e.preventDefault();
|
|
@@ -79066,6 +79085,7 @@ class ContentBuilder {
|
|
|
79066
79085
|
// CMD-U
|
|
79067
79086
|
|
|
79068
79087
|
if (this.opts.useCssClasses) {
|
|
79088
|
+
this.uo.saveForUndo();
|
|
79069
79089
|
this.dom.execCommandToggle('textUnderline', '', this.opts.cssClasses);
|
|
79070
79090
|
this.opts.onChange();
|
|
79071
79091
|
e.preventDefault();
|
|
@@ -79076,6 +79096,7 @@ class ContentBuilder {
|
|
|
79076
79096
|
// CMD-S
|
|
79077
79097
|
|
|
79078
79098
|
if (this.opts.useCssClasses) {
|
|
79099
|
+
this.uo.saveForUndo();
|
|
79079
79100
|
this.dom.execCommandToggle('textLinethrough', '', this.opts.cssClasses);
|
|
79080
79101
|
this.opts.onChange();
|
|
79081
79102
|
e.preventDefault();
|
|
@@ -79083,6 +79104,8 @@ class ContentBuilder {
|
|
|
79083
79104
|
}
|
|
79084
79105
|
}
|
|
79085
79106
|
if (isCmd && e.which === 221) {
|
|
79107
|
+
this.uo.saveForUndo();
|
|
79108
|
+
|
|
79086
79109
|
// CMD-]
|
|
79087
79110
|
e.preventDefault();
|
|
79088
79111
|
document.execCommand('indent', false, null);
|
|
@@ -79091,6 +79114,8 @@ class ContentBuilder {
|
|
|
79091
79114
|
markSpan();
|
|
79092
79115
|
}
|
|
79093
79116
|
if (isCmd && e.which === 219) {
|
|
79117
|
+
this.uo.saveForUndo();
|
|
79118
|
+
|
|
79094
79119
|
// CMD-]
|
|
79095
79120
|
e.preventDefault();
|
|
79096
79121
|
document.execCommand('outdent', false, null);
|
|
@@ -79322,307 +79347,326 @@ class ContentBuilder {
|
|
|
79322
79347
|
this.opts.onChange();
|
|
79323
79348
|
}, 2000);
|
|
79324
79349
|
}
|
|
79325
|
-
handleCellPaste(clipboardData) {
|
|
79350
|
+
handleCellPaste(clipboardData, clipboardDataHtml) {
|
|
79326
79351
|
this.uo.saveForUndo();
|
|
79327
79352
|
const util = this.util;
|
|
79328
79353
|
util.saveSelection(); //required. Without this, CTRL-A (select element) & CTRL-V won't replace the element, but will paste at the end of the element.
|
|
79329
79354
|
|
|
79330
|
-
|
|
79331
|
-
|
|
79332
|
-
|
|
79333
|
-
|
|
79334
|
-
|
|
79335
|
-
|
|
79336
|
-
|
|
79337
|
-
|
|
79338
|
-
|
|
79339
|
-
|
|
79340
|
-
|
|
79341
|
-
|
|
79342
|
-
|
|
79343
|
-
|
|
79344
|
-
|
|
79345
|
-
|
|
79346
|
-
|
|
79347
|
-
|
|
79348
|
-
|
|
79349
|
-
|
|
79350
|
-
|
|
79351
|
-
|
|
79352
|
-
|
|
79353
|
-
contentword = this.doc.querySelector('#idContentWord');
|
|
79354
|
-
contentword.focus();
|
|
79355
|
-
setTimeout(() => {
|
|
79356
|
-
try {
|
|
79357
|
-
var sPastedText = '';
|
|
79358
|
-
let contentword = this.doc.querySelector('#idContentWord');
|
|
79359
|
-
|
|
79360
|
-
//Check video embed
|
|
79361
|
-
var bPasteObject = false;
|
|
79362
|
-
var src = contentword.innerText;
|
|
79363
|
-
if (!this.opts.disableAutoEmbedVideo) {
|
|
79364
|
-
//var youRegex = /^http[s]?:\/\/(((www.youtube.com\/watch\?(feature=player_detailpage&)?)v=)|(youtu.be\/))([^#\&\?]*)/;
|
|
79365
|
-
var youRegex = /^http[s]?:\/\/(((www.youtube.com\/watch\?(feature=player_detailpage&)?)v=)|(youtu.be\/))([^#&?]*)/;
|
|
79366
|
-
var vimeoRegex = /^.*(vimeo\.com\/)((channels\/[A-z]+\/)|(groups\/[A-z]+\/videos\/)|(video\/))?([0-9]+)\/?/;
|
|
79367
|
-
var youRegexMatches = youRegex.exec(src);
|
|
79368
|
-
var vimeoRegexMatches = vimeoRegex.exec(src);
|
|
79369
|
-
if (youRegexMatches !== null || vimeoRegexMatches !== null) {
|
|
79370
|
-
if (youRegexMatches !== null && youRegexMatches.length >= 7) {
|
|
79371
|
-
var youMatch = youRegexMatches[6];
|
|
79372
|
-
src = 'https://www.youtube.com/embed/' + youMatch + '?rel=0';
|
|
79373
|
-
}
|
|
79374
|
-
if (vimeoRegexMatches !== null && vimeoRegexMatches.length >= 7) {
|
|
79375
|
-
var vimeoMatch = vimeoRegexMatches[6];
|
|
79376
|
-
src = 'https://player.vimeo.com/video/' + vimeoMatch;
|
|
79377
|
-
}
|
|
79378
|
-
sPastedText = '<div class="embed-responsive embed-responsive-16by9"><iframe tabindex="0" width="560" height="315" src="' + src + '" frameborder="0" allowfullscreen=""></iframe></div>';
|
|
79379
|
-
bPasteObject = true;
|
|
79355
|
+
// Create a temporary div to hold the pasted HTML
|
|
79356
|
+
let contentword = document.createElement('div');
|
|
79357
|
+
contentword.innerHTML = clipboardDataHtml;
|
|
79358
|
+
try {
|
|
79359
|
+
var sPastedText = '';
|
|
79360
|
+
|
|
79361
|
+
//Check video embed
|
|
79362
|
+
var bPasteObject = false;
|
|
79363
|
+
var src = contentword.innerText;
|
|
79364
|
+
if (!this.opts.disableAutoEmbedVideo) {
|
|
79365
|
+
//var youRegex = /^http[s]?:\/\/(((www.youtube.com\/watch\?(feature=player_detailpage&)?)v=)|(youtu.be\/))([^#\&\?]*)/;
|
|
79366
|
+
var youRegex = /^http[s]?:\/\/(((www.youtube.com\/watch\?(feature=player_detailpage&)?)v=)|(youtu.be\/))([^#&?]*)/;
|
|
79367
|
+
var vimeoRegex = /^.*(vimeo\.com\/)((channels\/[A-z]+\/)|(groups\/[A-z]+\/videos\/)|(video\/))?([0-9]+)\/?/;
|
|
79368
|
+
var youRegexMatches = youRegex.exec(src);
|
|
79369
|
+
var vimeoRegexMatches = vimeoRegex.exec(src);
|
|
79370
|
+
if (youRegexMatches !== null || vimeoRegexMatches !== null) {
|
|
79371
|
+
if (youRegexMatches !== null && youRegexMatches.length >= 7) {
|
|
79372
|
+
var youMatch = youRegexMatches[6];
|
|
79373
|
+
src = 'https://www.youtube.com/embed/' + youMatch + '?rel=0';
|
|
79374
|
+
}
|
|
79375
|
+
if (vimeoRegexMatches !== null && vimeoRegexMatches.length >= 7) {
|
|
79376
|
+
var vimeoMatch = vimeoRegexMatches[6];
|
|
79377
|
+
src = 'https://player.vimeo.com/video/' + vimeoMatch;
|
|
79380
79378
|
}
|
|
79379
|
+
sPastedText = '<div class="embed-responsive embed-responsive-16by9"><iframe tabindex="0" width="560" height="315" src="' + src + '" frameborder="0" allowfullscreen=""></iframe></div>';
|
|
79380
|
+
bPasteObject = true;
|
|
79381
79381
|
}
|
|
79382
|
-
|
|
79383
|
-
|
|
79384
|
-
|
|
79385
|
-
|
|
79386
|
-
|
|
79387
|
-
|
|
79388
|
-
|
|
79389
|
-
|
|
79390
|
-
|
|
79391
|
-
|
|
79392
|
-
|
|
79393
|
-
|
|
79394
|
-
|
|
79395
|
-
|
|
79396
|
-
|
|
79397
|
-
|
|
79398
|
-
|
|
79399
|
-
|
|
79400
|
-
|
|
79382
|
+
}
|
|
79383
|
+
if (!bPasteObject) {
|
|
79384
|
+
if (this.opts.paste === 'text') {
|
|
79385
|
+
/*
|
|
79386
|
+
let elms = contentword.querySelectorAll('p,h1,h2,h3,h4,h5,h6');
|
|
79387
|
+
Array.prototype.forEach.call(elms, (elm) => {
|
|
79388
|
+
elm.innerHTML = elm.innerHTML + ' '; //add space ( )
|
|
79389
|
+
});
|
|
79390
|
+
// sPastedText = contentword.innerText;
|
|
79391
|
+
sPastedText = contentword.innerHTML;
|
|
79392
|
+
sPastedText = sPastedText.replace(/(<([^>]+)>)/ig,'<br>');
|
|
79393
|
+
sPastedText = sPastedText.replace(/(<br\s*\/?>){3,}/gi, '<br>');
|
|
79394
|
+
if(sPastedText.indexOf('<br>')===0) {
|
|
79395
|
+
sPastedText = sPastedText.substring(4);
|
|
79396
|
+
}
|
|
79397
|
+
if(sPastedText.substring(sPastedText.length-4)==='<br>'){
|
|
79398
|
+
sPastedText = sPastedText.substring(0, sPastedText.length-4);
|
|
79399
|
+
}
|
|
79400
|
+
sPastedText = sPastedText.trim();
|
|
79401
|
+
*/
|
|
79401
79402
|
|
|
79402
|
-
|
|
79403
|
-
|
|
79403
|
+
sPastedText = clipboardData;
|
|
79404
|
+
// sPastedText = sPastedText.replace(/(?:\r\n|\r|\n)/g, '<br>');
|
|
79405
|
+
} else {
|
|
79406
|
+
sPastedText = contentword.innerHTML;
|
|
79407
|
+
if (this.opts.paste === 'html') {
|
|
79408
|
+
//with styles
|
|
79409
|
+
sPastedText = util.cleanHTML(sPastedText, false);
|
|
79404
79410
|
} else {
|
|
79405
|
-
|
|
79406
|
-
|
|
79407
|
-
//with styles
|
|
79408
|
-
sPastedText = util.cleanHTML(sPastedText, false);
|
|
79409
|
-
} else {
|
|
79410
|
-
//html-without-styles (default)
|
|
79411
|
-
sPastedText = util.cleanHTML(sPastedText, true);
|
|
79412
|
-
}
|
|
79413
|
-
contentword.innerHTML = sPastedText;
|
|
79414
|
-
|
|
79415
|
-
/*
|
|
79416
|
-
// remove attributes
|
|
79417
|
-
if(this.opts.paste === 'html'){//with styles
|
|
79418
|
-
let elms = contentword.querySelectorAll('*');
|
|
79419
|
-
Array.prototype.forEach.call(elms, (elm) => {
|
|
79420
|
-
for(let n = 0;n<elm.attributes.length;n++) {
|
|
79421
|
-
if(elm.attributes[n].name!=='style') elm.removeAttribute(elm.attributes[n].name);
|
|
79422
|
-
}
|
|
79423
|
-
});
|
|
79424
|
-
} else { //html-without-styles (default)
|
|
79425
|
-
|
|
79426
|
-
const removeAttributes = (element) => {
|
|
79427
|
-
while (element.attributes.length > 0) {
|
|
79428
|
-
element.removeAttribute(element.attributes[0].name);
|
|
79429
|
-
}
|
|
79430
|
-
};
|
|
79431
|
-
let elms = contentword.querySelectorAll('*');
|
|
79432
|
-
Array.prototype.forEach.call(elms, (elm) => {
|
|
79433
|
-
removeAttributes(elm);
|
|
79434
|
-
});
|
|
79435
|
-
}
|
|
79436
|
-
*/
|
|
79437
|
-
|
|
79438
|
-
/*
|
|
79439
|
-
Additional Cleanup:
|
|
79440
|
-
- Remove p inside li
|
|
79441
|
-
- Remove li with white-space: pre
|
|
79442
|
-
*/
|
|
79443
|
-
let elms = contentword.querySelectorAll('li');
|
|
79444
|
-
Array.prototype.forEach.call(elms, elm => {
|
|
79445
|
-
elm.style.whiteSpace = '';
|
|
79446
|
-
const childNodes = elm.childNodes;
|
|
79447
|
-
let i = childNodes.length;
|
|
79448
|
-
while (i--) {
|
|
79449
|
-
if (childNodes[i].tagName === 'P') {
|
|
79450
|
-
childNodes[i].outerHTML = childNodes[i].innerHTML;
|
|
79451
|
-
}
|
|
79452
|
-
}
|
|
79453
|
-
});
|
|
79454
|
-
|
|
79455
|
-
// NOTE: paste <h1><p> jadi nempel
|
|
79456
|
-
|
|
79457
|
-
// // Source: https://gist.github.com/sbrin/6801034
|
|
79458
|
-
// jQuery('p', $editor).each(function(){
|
|
79459
|
-
// var str = jQuery(this).attr('style');
|
|
79460
|
-
// var matches = /mso-list:\w+ \w+([0-9]+)/.exec(str);
|
|
79461
|
-
// if (matches) {
|
|
79462
|
-
// jQuery(this).data('_listLevel', parseInt(matches[1], 10));
|
|
79463
|
-
// }
|
|
79464
|
-
// });
|
|
79465
|
-
// var last_level=0;
|
|
79466
|
-
// var pnt = null;
|
|
79467
|
-
// jQuery('p', $editor).each(function(){
|
|
79468
|
-
// var cur_level = jQuery(this).data('_listLevel');
|
|
79469
|
-
// if(cur_level !== undefined){
|
|
79470
|
-
// var txt = jQuery(this).text();
|
|
79471
|
-
// var list_tag = '<ul></ul>';
|
|
79472
|
-
// if (/^\s*\w+\./.test(txt)) {
|
|
79473
|
-
// var matches = /([0-9])\./.exec(txt);
|
|
79474
|
-
// if (matches) {
|
|
79475
|
-
// var start = parseInt(matches[1], 10);
|
|
79476
|
-
// list_tag = start>1 ? '<ol start="' + start + '"></ol>' : '<ol></ol>';
|
|
79477
|
-
// }else{
|
|
79478
|
-
// list_tag = '<ol></ol>';
|
|
79479
|
-
// }
|
|
79480
|
-
// }
|
|
79481
|
-
|
|
79482
|
-
// if(cur_level>last_level){
|
|
79483
|
-
// if(last_level===0){
|
|
79484
|
-
// jQuery(this).before(list_tag);
|
|
79485
|
-
// pnt = jQuery(this).prev();
|
|
79486
|
-
// }else{
|
|
79487
|
-
// pnt = jQuery(list_tag).appendTo(pnt);
|
|
79488
|
-
// }
|
|
79489
|
-
// }
|
|
79490
|
-
// if(cur_level<last_level){
|
|
79491
|
-
// for(var i=0; i<last_level-cur_level; i++){
|
|
79492
|
-
// pnt = pnt.parent();
|
|
79493
|
-
// }
|
|
79494
|
-
// }
|
|
79495
|
-
// jQuery('span:first', this).remove();
|
|
79496
|
-
// pnt.append('<li>' + jQuery(this).html() + '</li>');
|
|
79497
|
-
// jQuery(this).remove();
|
|
79498
|
-
// last_level = cur_level;
|
|
79499
|
-
// }else{
|
|
79500
|
-
// last_level = 0;
|
|
79501
|
-
// }
|
|
79502
|
-
// });
|
|
79503
|
-
// //jQuery('[style]', $editor).removeAttr('style'); //done (see cleanHTML)
|
|
79504
|
-
// jQuery('[align]', $editor).removeAttr('align');
|
|
79505
|
-
// //jQuery('span', $editor).replaceWith(function() {return jQuery(this).contents();}); //done (see cleanHTML)
|
|
79506
|
-
// jQuery('span:empty', $editor).remove();
|
|
79507
|
-
// //jQuery("[class^='Mso']", $editor).removeAttr('class'); //done (see cleanHTML)
|
|
79508
|
-
// jQuery('p:empty', $editor).remove();
|
|
79509
|
-
|
|
79510
|
-
sPastedText = contentword.innerHTML;
|
|
79411
|
+
//html-without-styles (default)
|
|
79412
|
+
sPastedText = util.cleanHTML(sPastedText, true);
|
|
79511
79413
|
}
|
|
79512
|
-
|
|
79513
|
-
|
|
79514
|
-
if (contentword) contentword.parentNode.removeChild(contentword);
|
|
79515
|
-
util.restoreSelection();
|
|
79516
|
-
var oSel = this.win.getSelection();
|
|
79517
|
-
var range = oSel.getRangeAt(0);
|
|
79518
|
-
range.extractContents();
|
|
79519
|
-
range.collapse(true);
|
|
79520
|
-
var docFrag = range.createContextualFragment(sPastedText);
|
|
79521
|
-
var lastNode = docFrag.lastChild;
|
|
79522
|
-
range.insertNode(docFrag);
|
|
79523
|
-
if (this.activeCol) {
|
|
79414
|
+
contentword.innerHTML = sPastedText;
|
|
79415
|
+
|
|
79524
79416
|
/*
|
|
79525
|
-
|
|
79526
|
-
|
|
79417
|
+
// remove attributes
|
|
79418
|
+
if(this.opts.paste === 'html'){//with styles
|
|
79419
|
+
let elms = contentword.querySelectorAll('*');
|
|
79420
|
+
Array.prototype.forEach.call(elms, (elm) => {
|
|
79421
|
+
for(let n = 0;n<elm.attributes.length;n++) {
|
|
79422
|
+
if(elm.attributes[n].name!=='style') elm.removeAttribute(elm.attributes[n].name);
|
|
79423
|
+
}
|
|
79424
|
+
});
|
|
79425
|
+
} else { //html-without-styles (default)
|
|
79426
|
+
|
|
79427
|
+
const removeAttributes = (element) => {
|
|
79428
|
+
while (element.attributes.length > 0) {
|
|
79429
|
+
element.removeAttribute(element.attributes[0].name);
|
|
79430
|
+
}
|
|
79431
|
+
};
|
|
79432
|
+
let elms = contentword.querySelectorAll('*');
|
|
79433
|
+
Array.prototype.forEach.call(elms, (elm) => {
|
|
79434
|
+
removeAttributes(elm);
|
|
79435
|
+
});
|
|
79436
|
+
}
|
|
79527
79437
|
*/
|
|
79528
|
-
// this.activeCol.find('h1:empty,h2:empty,h3:empty,h4:empty,h5:empty,h6:empty,p:empty').remove();
|
|
79529
|
-
// this.activeCol.querySelectorAll('*:empty').forEach((x)=>{x.remove();}); // Makes <img> removed
|
|
79530
|
-
this.activeCol.querySelectorAll('h1:empty,h2:empty,h3:empty,h4:empty,h5:empty,h6:empty,p:empty').forEach(x => {
|
|
79531
|
-
x.remove();
|
|
79532
|
-
});
|
|
79533
79438
|
|
|
79534
79439
|
/*
|
|
79535
79440
|
Additional Cleanup:
|
|
79536
|
-
|
|
79537
|
-
|
|
79538
|
-
...Sometimes h1, h2, p can be pasted here..
|
|
79539
|
-
</p>
|
|
79441
|
+
- Remove p inside li
|
|
79442
|
+
- Remove li with white-space: pre
|
|
79540
79443
|
*/
|
|
79541
|
-
let
|
|
79542
|
-
|
|
79543
|
-
|
|
79544
|
-
|
|
79545
|
-
|
|
79546
|
-
|
|
79547
|
-
|
|
79548
|
-
|
|
79549
|
-
|
|
79550
|
-
|
|
79551
|
-
|
|
79552
|
-
span.appendChild(node);
|
|
79553
|
-
});
|
|
79554
|
-
if (elmActive.firstElementChild && elmActive.childNodes.length === 1) {
|
|
79555
|
-
if (elmActive.firstElementChild.tagName === 'SPAN') {
|
|
79556
|
-
// Paste HTML with styles
|
|
79444
|
+
let elms = contentword.querySelectorAll('li');
|
|
79445
|
+
Array.prototype.forEach.call(elms, elm => {
|
|
79446
|
+
elm.style.whiteSpace = '';
|
|
79447
|
+
const childNodes = elm.childNodes;
|
|
79448
|
+
let i = childNodes.length;
|
|
79449
|
+
while (i--) {
|
|
79450
|
+
if (childNodes[i].tagName === 'P') {
|
|
79451
|
+
childNodes[i].outerHTML = childNodes[i].innerHTML;
|
|
79452
|
+
}
|
|
79453
|
+
}
|
|
79454
|
+
});
|
|
79557
79455
|
|
|
79558
|
-
|
|
79456
|
+
// NOTE: paste <h1><p> jadi nempel
|
|
79559
79457
|
|
|
79560
|
-
|
|
79561
|
-
|
|
79562
|
-
|
|
79563
|
-
|
|
79458
|
+
// // Source: https://gist.github.com/sbrin/6801034
|
|
79459
|
+
// jQuery('p', $editor).each(function(){
|
|
79460
|
+
// var str = jQuery(this).attr('style');
|
|
79461
|
+
// var matches = /mso-list:\w+ \w+([0-9]+)/.exec(str);
|
|
79462
|
+
// if (matches) {
|
|
79463
|
+
// jQuery(this).data('_listLevel', parseInt(matches[1], 10));
|
|
79464
|
+
// }
|
|
79465
|
+
// });
|
|
79466
|
+
// var last_level=0;
|
|
79467
|
+
// var pnt = null;
|
|
79468
|
+
// jQuery('p', $editor).each(function(){
|
|
79469
|
+
// var cur_level = jQuery(this).data('_listLevel');
|
|
79470
|
+
// if(cur_level !== undefined){
|
|
79471
|
+
// var txt = jQuery(this).text();
|
|
79472
|
+
// var list_tag = '<ul></ul>';
|
|
79473
|
+
// if (/^\s*\w+\./.test(txt)) {
|
|
79474
|
+
// var matches = /([0-9])\./.exec(txt);
|
|
79475
|
+
// if (matches) {
|
|
79476
|
+
// var start = parseInt(matches[1], 10);
|
|
79477
|
+
// list_tag = start>1 ? '<ol start="' + start + '"></ol>' : '<ol></ol>';
|
|
79478
|
+
// }else{
|
|
79479
|
+
// list_tag = '<ol></ol>';
|
|
79480
|
+
// }
|
|
79481
|
+
// }
|
|
79482
|
+
|
|
79483
|
+
// if(cur_level>last_level){
|
|
79484
|
+
// if(last_level===0){
|
|
79485
|
+
// jQuery(this).before(list_tag);
|
|
79486
|
+
// pnt = jQuery(this).prev();
|
|
79487
|
+
// }else{
|
|
79488
|
+
// pnt = jQuery(list_tag).appendTo(pnt);
|
|
79489
|
+
// }
|
|
79490
|
+
// }
|
|
79491
|
+
// if(cur_level<last_level){
|
|
79492
|
+
// for(var i=0; i<last_level-cur_level; i++){
|
|
79493
|
+
// pnt = pnt.parent();
|
|
79494
|
+
// }
|
|
79495
|
+
// }
|
|
79496
|
+
// jQuery('span:first', this).remove();
|
|
79497
|
+
// pnt.append('<li>' + jQuery(this).html() + '</li>');
|
|
79498
|
+
// jQuery(this).remove();
|
|
79499
|
+
// last_level = cur_level;
|
|
79500
|
+
// }else{
|
|
79501
|
+
// last_level = 0;
|
|
79502
|
+
// }
|
|
79503
|
+
// });
|
|
79504
|
+
// //jQuery('[style]', $editor).removeAttr('style'); //done (see cleanHTML)
|
|
79505
|
+
// jQuery('[align]', $editor).removeAttr('align');
|
|
79506
|
+
// //jQuery('span', $editor).replaceWith(function() {return jQuery(this).contents();}); //done (see cleanHTML)
|
|
79507
|
+
// jQuery('span:empty', $editor).remove();
|
|
79508
|
+
// //jQuery("[class^='Mso']", $editor).removeAttr('class'); //done (see cleanHTML)
|
|
79509
|
+
// jQuery('p:empty', $editor).remove();
|
|
79564
79510
|
|
|
79565
|
-
|
|
79566
|
-
|
|
79567
|
-
|
|
79568
|
-
|
|
79511
|
+
sPastedText = contentword.innerHTML;
|
|
79512
|
+
}
|
|
79513
|
+
}
|
|
79514
|
+
contentword = this.doc.querySelector('#idContentWord');
|
|
79515
|
+
if (contentword) contentword.parentNode.removeChild(contentword);
|
|
79516
|
+
util.restoreSelection();
|
|
79569
79517
|
|
|
79570
|
-
|
|
79571
|
-
|
|
79518
|
+
/*
|
|
79519
|
+
var oSel = this.win.getSelection();
|
|
79520
|
+
var range = oSel.getRangeAt(0);
|
|
79521
|
+
range.extractContents();
|
|
79522
|
+
range.collapse(true);
|
|
79523
|
+
var docFrag = range.createContextualFragment(sPastedText);
|
|
79524
|
+
var lastNode = docFrag.lastChild;
|
|
79525
|
+
range.insertNode(docFrag);
|
|
79526
|
+
*/
|
|
79572
79527
|
|
|
79573
|
-
|
|
79574
|
-
|
|
79575
|
-
|
|
79576
|
-
|
|
79577
|
-
|
|
79528
|
+
/*
|
|
79529
|
+
When selection is made by double clicking text (to select the entire block),
|
|
79530
|
+
the actual selection goes to the next block as well (default behavior, tested using a simple contentEditable div).
|
|
79531
|
+
To fix this, re-select the contents inside.
|
|
79532
|
+
*/
|
|
79533
|
+
|
|
79534
|
+
const blocks = this.dom.getSelectedBlocks();
|
|
79535
|
+
const selection = this.win.getSelection();
|
|
79536
|
+
|
|
79537
|
+
/*
|
|
79538
|
+
Check same selection for the block first (this is more accurate than the sameSelection checking below).
|
|
79539
|
+
In case of double click (to select the entire block), for example, on this element:
|
|
79540
|
+
<h2 class="font-light size-54"><span class="size-24">Heading</span> 2 here</h2>
|
|
79541
|
+
The sameSelection checking below is failed, since the container = this.getElm() will return not the entire h2, but only
|
|
79542
|
+
<span class="size-24">Heading</span>
|
|
79543
|
+
So, blocks checking below is made to fix it.
|
|
79544
|
+
*/
|
|
79545
|
+
let blockSelection = false;
|
|
79546
|
+
if (blocks.length === 1) {
|
|
79547
|
+
if (blocks[0].innerText.trim() === selection.toString().trim()) {
|
|
79548
|
+
let range = document.createRange();
|
|
79549
|
+
range.selectNodeContents(blocks[0]);
|
|
79550
|
+
selection.removeAllRanges();
|
|
79551
|
+
selection.addRange(range);
|
|
79552
|
+
blockSelection = true;
|
|
79553
|
+
}
|
|
79554
|
+
}
|
|
79555
|
+
if (!blockSelection) {
|
|
79556
|
+
const container = this.dom.getElm();
|
|
79557
|
+
const sameSelection = container && container.innerText === selection.toString().trim();
|
|
79558
|
+
if (sameSelection || selection.toString().trim() === '') {
|
|
79559
|
+
let range = document.createRange();
|
|
79560
|
+
range.selectNodeContents(container);
|
|
79561
|
+
selection.removeAllRanges();
|
|
79562
|
+
selection.addRange(range);
|
|
79563
|
+
}
|
|
79564
|
+
}
|
|
79565
|
+
document.execCommand('insertHTML', false, sPastedText);
|
|
79566
|
+
if (this.activeCol) {
|
|
79567
|
+
/*
|
|
79568
|
+
Additional Cleanup:
|
|
79569
|
+
- Remove empty elements (empty p, etc)
|
|
79570
|
+
*/
|
|
79571
|
+
// this.activeCol.find('h1:empty,h2:empty,h3:empty,h4:empty,h5:empty,h6:empty,p:empty').remove();
|
|
79572
|
+
// this.activeCol.querySelectorAll('*:empty').forEach((x)=>{x.remove();}); // Makes <img> removed
|
|
79573
|
+
this.activeCol.querySelectorAll('h1:empty,h2:empty,h3:empty,h4:empty,h5:empty,h6:empty,p:empty').forEach(x => {
|
|
79574
|
+
x.remove();
|
|
79575
|
+
});
|
|
79578
79576
|
|
|
79579
|
-
|
|
79580
|
-
|
|
79577
|
+
/*
|
|
79578
|
+
Additional Cleanup:
|
|
79579
|
+
Fix HTML structure. The problem:
|
|
79580
|
+
<p class="elm-active">
|
|
79581
|
+
...Sometimes h1, h2, p can be pasted here..
|
|
79582
|
+
</p>
|
|
79583
|
+
*/
|
|
79584
|
+
let elmActive = this.activeCol.querySelector('p.elm-active,h1.elm-active,h2.elm-active,h3.elm-active,h4.elm-active,h5.elm-active,h6.elm-active');
|
|
79585
|
+
if (elmActive) {
|
|
79586
|
+
let elms = elmActive.querySelectorAll('p,h1,h2,h3,h4,h5,h6');
|
|
79587
|
+
if (elms.length > 0) {
|
|
79588
|
+
let elmClosestElement = elmActive.nextElementSibling;
|
|
79589
|
+
|
|
79590
|
+
//Fix text that doesn't have paragraph
|
|
79591
|
+
let textNodes = Array.from(elmActive.childNodes).filter(node => node.nodeType === 3 && node.textContent.trim().length > 1);
|
|
79592
|
+
textNodes.forEach(node => {
|
|
79593
|
+
const span = document.createElement('p');
|
|
79594
|
+
node.after(span);
|
|
79595
|
+
span.appendChild(node);
|
|
79596
|
+
});
|
|
79597
|
+
if (elmActive.firstElementChild && elmActive.childNodes.length === 1) {
|
|
79598
|
+
if (elmActive.firstElementChild.tagName === 'SPAN') {
|
|
79599
|
+
// Paste HTML with styles
|
|
79581
79600
|
|
|
79582
|
-
|
|
79583
|
-
// this.activeCol.querySelectorAll('*:empty').forEach((x)=>{x.remove();}); // Makes <img> removed
|
|
79584
|
-
this.activeCol.find('h1:empty,h2:empty,h3:empty,h4:empty,h5:empty,h6:empty,p:empty').remove();
|
|
79601
|
+
elmActive.outerHTML = elmActive.firstElementChild.innerHTML; //fix
|
|
79585
79602
|
|
|
79586
|
-
|
|
79587
|
-
|
|
79588
|
-
|
|
79589
|
-
|
|
79603
|
+
// Re-clean empty elements
|
|
79604
|
+
this.activeCol.querySelectorAll('*:empty').forEach(x => {
|
|
79605
|
+
x.remove();
|
|
79606
|
+
});
|
|
79590
79607
|
|
|
79591
|
-
|
|
79592
|
-
|
|
79608
|
+
//place cursor
|
|
79609
|
+
if (elmClosestElement) this.dom.moveCursorToElement(elmClosestElement.previousElementSibling);else this.dom.moveCursorToElement(this.activeCol);
|
|
79610
|
+
let builderActive = this.doc.querySelector('.builder-active');
|
|
79611
|
+
if (builderActive) this.applyBehaviorOn(builderActive);
|
|
79593
79612
|
|
|
79594
|
-
|
|
79595
|
-
|
|
79596
|
-
|
|
79613
|
+
//Trigger Change event
|
|
79614
|
+
this.opts.onChange();
|
|
79615
|
+
|
|
79616
|
+
//Trigger Render event
|
|
79617
|
+
this.opts.onRender();
|
|
79618
|
+
return;
|
|
79619
|
+
}
|
|
79597
79620
|
}
|
|
79621
|
+
|
|
79622
|
+
// Paste HTML without styles
|
|
79623
|
+
elmActive.outerHTML = elmActive.innerHTML; //fix
|
|
79624
|
+
|
|
79625
|
+
// Re-clean empty elements
|
|
79626
|
+
// this.activeCol.querySelectorAll('*:empty').forEach((x)=>{x.remove();}); // Makes <img> removed
|
|
79627
|
+
this.activeCol.find('h1:empty,h2:empty,h3:empty,h4:empty,h5:empty,h6:empty,p:empty').remove();
|
|
79628
|
+
|
|
79629
|
+
//place cursor
|
|
79630
|
+
if (elmClosestElement) this.dom.moveCursorToElement(elmClosestElement.previousElementSibling);else this.dom.moveCursorToElement(this.activeCol);
|
|
79631
|
+
let builderActive = this.doc.querySelector('.builder-active');
|
|
79632
|
+
if (builderActive) this.applyBehaviorOn(builderActive);
|
|
79633
|
+
|
|
79634
|
+
//Trigger Change event
|
|
79635
|
+
this.opts.onChange();
|
|
79636
|
+
|
|
79637
|
+
//Trigger Render event
|
|
79638
|
+
this.opts.onRender();
|
|
79639
|
+
return;
|
|
79598
79640
|
}
|
|
79599
79641
|
}
|
|
79600
|
-
|
|
79601
|
-
|
|
79602
|
-
|
|
79603
|
-
|
|
79604
|
-
|
|
79605
|
-
|
|
79606
|
-
|
|
79607
|
-
|
|
79608
|
-
|
|
79642
|
+
}
|
|
79643
|
+
|
|
79644
|
+
/*
|
|
79645
|
+
range.setStartAfter(lastNode);
|
|
79646
|
+
range.setEndAfter(lastNode);
|
|
79647
|
+
range.collapse(false);
|
|
79648
|
+
var comCon = range.commonAncestorContainer;
|
|
79649
|
+
if (comCon && comCon.parentNode) {
|
|
79650
|
+
try { comCon.parentNode.normalize(); } catch (e) {
|
|
79651
|
+
// Do Nothing
|
|
79609
79652
|
}
|
|
79610
|
-
|
|
79611
|
-
|
|
79612
|
-
|
|
79613
|
-
|
|
79614
|
-
if (builderActive) this.applyBehaviorOn(builderActive);
|
|
79653
|
+
}
|
|
79654
|
+
oSel.removeAllRanges();
|
|
79655
|
+
oSel.addRange(range);
|
|
79656
|
+
*/
|
|
79615
79657
|
|
|
79616
|
-
|
|
79617
|
-
|
|
79658
|
+
let builderActive = this.doc.querySelector('.builder-active');
|
|
79659
|
+
if (builderActive) this.applyBehaviorOn(builderActive);
|
|
79618
79660
|
|
|
79619
|
-
|
|
79620
|
-
|
|
79621
|
-
|
|
79622
|
-
|
|
79623
|
-
|
|
79624
|
-
|
|
79625
|
-
|
|
79661
|
+
//Trigger Change event
|
|
79662
|
+
this.opts.onChange();
|
|
79663
|
+
|
|
79664
|
+
//Trigger Render event
|
|
79665
|
+
this.opts.onRender();
|
|
79666
|
+
} catch (e) {
|
|
79667
|
+
|
|
79668
|
+
// Do Nothing
|
|
79669
|
+
}
|
|
79626
79670
|
}
|
|
79627
79671
|
cellSelected() {
|
|
79628
79672
|
const util = this.util;
|