diff --git a/README.md b/README.md index 79c186978..1becc7432 100644 --- a/README.md +++ b/README.md @@ -88,23 +88,23 @@ Things might work in Edge 18, Firefox 50-62 and Chrome 54-68 due to one polyfill |js/* |1.14.0 |native | |----------- |--------: |--------: | -|admin.js |2.130.942 | 990.560 | -|app.js |4.184.455 |2.607.924 | +|admin.js |2.130.942 |1.000.931 | +|app.js |4.184.455 |2.618.339 | |boot.js | 671.522 | 5.834 | |libs.js | 647.614 | 312.343 | |polyfills.js | 325.834 | 0 | -|TOTAL |7.960.367 |3.916.661 | +|TOTAL |7.960.367 |3.937.447 | |js/min/* |1.14.0 |native |gzip 1.14 |gzip |brotli | |--------------- |--------: |--------: |--------: |--------: |--------: | -|admin.min.js | 252.147 | 135.441 | 73.657 | 40.158 | 34.434 | -|app.min.js | 511.202 | 355.966 |140.462 | 94.405 | 75.847 | +|admin.min.js | 252.147 | 136.658 | 73.657 | 40.569 | 34.783 | +|app.min.js | 511.202 | 357.183 |140.462 | 94.834 | 76.231 | |boot.min.js | 66.007 | 3.166 | 22.567 | 1.571 | 1.345 | |libs.min.js | 572.545 | 295.754 |176.720 | 91.521 | 80.871 | |polyfills.min.js | 32.452 | 0 | 11.312 | 0 | 0 | -|TOTAL |1.434.353 | 790.327 |424.718 |227.655 |192.497 | +|TOTAL |1.434.353 | 792.761 |424.718 |228.495 |193.230 | -644.026 bytes (197.063 gzip) is not much, but it feels faster. +641.592 bytes (196.223 gzip) is not much, but it feels faster. ### CSS changes @@ -142,7 +142,6 @@ Still TODO: * upload image inline * support for tables (really needed?!?) -* alternative for vendors/ckeditor-plugins/signature/plugin.js | | normal | min | gzip | min gzip | |-------- |-------: |-------: |------: |--------: | diff --git a/dev/External/SquireUI.js b/dev/External/SquireUI.js index a5a90e1a2..caee89e4a 100644 --- a/dev/External/SquireUI.js +++ b/dev/External/SquireUI.js @@ -6,7 +6,7 @@ const doc = document, allowedElements = 'A,B,BLOCKQUOTE,BR,DIV,FONT,H1,H2,H3,H4,H5,H6,HR,IMG,LABEL,LI,OL,P,SPAN,STRONG,TABLE,TD,TH,TR,U,UL', allowedAttributes = 'abbr,align,background,bgcolor,border,cellpadding,cellspacing,class,color,colspan,dir,face,frame,height,href,hspace,id,lang,rowspan,rules,scope,size,src,style,target,type,usemap,valign,vspace,width'.split(','), -i18n = (str, def) => window.rl && window.rl.i18n ? window.rl.i18n(str) : def, +i18n = (str, def) => rl.i18n(str) || def, SquireDefaultConfig = { /* @@ -40,7 +40,7 @@ SquireDefaultConfig = { tpl = doc.createElement('div'); tpl.innerHTML = html; if (isPaste) { - tpl.querySelectorAll(':not('+allowedElements+')').forEach(el => el.remove()); + tpl.querySelectorAll(':not('+allowedElements+',signature)').forEach(el => el.remove()); tpl.querySelectorAll(allowedElements).forEach(el => { if (el.hasAttributes()) { Array.from(el.attributes).forEach(attr => { @@ -55,6 +55,68 @@ SquireDefaultConfig = { frag.append(...tpl.childNodes); return frag; } +}, + +rl_signature_replacer = (editor, text, signature, isHtml, insertBefore) => { + let + prevSignature = editor.__previous_signature, + skipInsert = false, + isEmptyText = false, + newLine = (isHtml ? '
' : "\n"), + clearHtmlLine = html => rl.Utils.htmlToPlain(html).trim(); + + isEmptyText = !text.trim(); + if (!isEmptyText && isHtml) { + isEmptyText = !clearHtmlLine(text); + } + + if (prevSignature && !isEmptyText) { + if (isHtml && !prevSignature.isHtml) { + prevSignature = { + body: rl.Utils.plainToHtml(prevSignature.body), + isHtml: true + }; + } else if (!isHtml && prevSignature.isHtml) { + prevSignature = { + body: rl.Utils.htmlToPlain(prevSignature.body), + isHtml: true + }; + } + + if (isHtml) { + var clearSig = clearHtmlLine(prevSignature.body); + text = text.replace(/([\s\S]*)<\/signature>/igm, all => { + var c = clearSig === clearHtmlLine(all); + if (!c) { + skipInsert = true; + } + return c ? '' : all; + }); + } else { + var textLen = text.length; + text = text + .replace('' + prevSignature.body, '') + .replace('' + prevSignature.body, ''); + skipInsert = textLen === text.length; + } + } + + if (!skipInsert) { + signature = newLine + newLine + (isHtml ? '' : '') + signature + (isHtml ? '' : ''); + + text = insertBefore ? signature + text : text + signature; + + if (10 < signature.length) { + prevSignature = { + body: signature, + isHtml: isHtml + }; + } + } + + editor.__previous_signature = prevSignature; + + return text; }; class SquireUI @@ -101,12 +163,12 @@ class SquireUI textColor: { input: 'color', cmd: s => squire.setTextColour(s.value), - hint: 'text' + hint: 'Text color' }, backgroundColor: { input: 'color', cmd: s => squire.setHighlightColour(s.value), - hint: i18n('EDITOR/TEXT_BACKGROUND_COLOR', 'Background') + hint: 'Background color' }, }, /* @@ -118,61 +180,72 @@ class SquireUI bold: { html: '𝐁', cmd: () => this.doAction('bold','B'), - key: 'B' + key: 'B', + hint: 'Bold' }, italic: { html: '𝐼', cmd: () => this.doAction('italic','I'), - key: 'I' + key: 'I', + hint: 'Italic' }, underline: { html: 'U', cmd: () => this.doAction('underline','U'), - key: 'U' + key: 'U', + hint: 'Underline' }, strike: { html: 'S', cmd: () => this.doAction('strikethrough','S'), - key: 'Shift + 7' + key: 'Shift + 7', + hint: 'Strikethrough' }, sub: { html: 'Sx', cmd: () => this.doAction('subscript','SUB'), - key: 'Shift + 5' + key: 'Shift + 5', + hint: 'Subscript' }, sup: { html: 'Sx', cmd: () => this.doAction('superscript','SUP'), - key: 'Shift + 6' + key: 'Shift + 6', + hint: 'Superscript' } }, block: { ol: { html: '#', cmd: () => this.doList('OL'), - key: 'Shift + 8' + key: 'Shift + 8', + hint: 'Ordered list' }, ul: { html: '⋮', cmd: () => this.doList('UL'), - key: 'Shift + 9' + key: 'Shift + 9', + hint: 'Unordered list' }, quote: { html: '"', cmd: () => { let parent = this.getParentNodeName('UL,OL'); (parent && 'BLOCKQUOTE' == parent) ? squire.decreaseQuoteLevel() : squire.increaseQuoteLevel(); - } + }, + hint: 'Blockquote' }, indentDecrease: { html: '⇤', cmd: () => squire.changeIndentationLevel('decrease'), - key: ']' + key: ']', + hint: 'Decrease indent' }, indentIncrease: { html: '⇥', cmd: () => squire.changeIndentationLevel('increase'), - key: '[' + key: '[', + hint: 'Increase indent' } }, targets: { @@ -185,7 +258,8 @@ class SquireUI let url = prompt("Link","https://"); url != null && url.length && squire.makeLink(url); } - } + }, + hint: 'Link' }, image: { html: '🖼️', @@ -196,7 +270,8 @@ class SquireUI let src = prompt("Image","https://"); src != null && src.length && squire.insertImage(src); } - } + }, + hint: 'Image' }, /* imageUpload: { @@ -213,12 +288,14 @@ class SquireUI undo: { html: '↶', cmd: () => squire.undo(), - key: 'Z' + key: 'Z', + hint: 'Undo' }, redo: { html: '↷', cmd: () => squire.redo(), - key: 'Y' + key: 'Y', + hint: 'Redo' } } }, @@ -230,7 +307,7 @@ class SquireUI plain.className = 'squire-plain cke_plain cke_editable'; wysiwyg.className = 'squire-wysiwyg cke_wysiwyg_div cke_editable'; - this.mode = 'plain'; // 'wysiwyg' + this.mode = ''; // 'plain' | 'wysiwyg' this.__plain = { getRawData: () => this.plain.value, setRawData: plain => this.plain.value = plain @@ -326,7 +403,6 @@ squire-raw.js:4089: this.fireEvent( 'willPaste', event ); this.plugins = { plain: true }; - // .plugins.plain && this.editor.__plain this.focusManager = { hasFocus: () => squire._isFocused, blur: () => squire.blur() @@ -384,12 +460,29 @@ squire-raw.js:4089: this.fireEvent( 'willPaste', event ); execCommand(cmd, cfg) { if ('insertSignature' == cmd) { + cfg = Object.assign({ + clearCache: false, + isHtml: false, + insertBefore: false, + signature: '' + }, cfg); + if (cfg.clearCache) { - // remove it; - } else { - cfg.isHtml; // bool - cfg.insertBefore; // bool - cfg.signature; // string + this.__previous_signature = null; + } else try { + if ('plain' === this.mode) { + if (cfg.isHtml) { + cfg.signature = rl.Utils.htmlToPlain(cfg.signature); + } + this.plain.value = rl_signature_replacer(this, this.plain.value, cfg.signature, false, cfg.insertBefore); + } else { + if (!cfg.isHtml) { + cfg.signature = rl.Utils.plainToHtml(cfg.signature); + } + this.squire.setHTML(rl_signature_replacer(this, this.squire.getHTML(), cfg.signature, true, cfg.insertBefore)); + } + } catch (e) { + console.error(e); } } } diff --git a/dev/Styles/SquireUI.less b/dev/Styles/SquireUI.less index ffccbc1b6..47614cfe7 100644 --- a/dev/Styles/SquireUI.less +++ b/dev/Styles/SquireUI.less @@ -52,5 +52,5 @@ display: block; } .squire-mode-plain .squire-toolgroup:not(#squire-toolgroup-mode) { - opacity: 0.5; + display: none; }