diff --git a/README.md b/README.md index cd14dee3a..831e34b7a 100644 --- a/README.md +++ b/README.md @@ -116,23 +116,23 @@ RainLoop 1.15 vs SnappyMail |js/* |RainLoop |Snappy | |--------------- |--------: |--------: | -|admin.js |2.158.025 | 101.796 | -|app.js |4.215.733 | 501.679 | +|admin.js |2.158.025 | 100.608 | +|app.js |4.215.733 | 495.934 | |boot.js | 672.433 | 4.726 | |libs.js | 647.679 | 227.974 | |polyfills.js | 325.908 | 0 | |serviceworker.js | 0 | 285 | -|TOTAL |8.019.778 | 836.460 | +|TOTAL |8.019.778 | 829.355 | |js/min/* |RainLoop |Snappy |RL gzip |SM gzip |RL brotli |SM brotli | |--------------- |--------: |--------: |------: |------: |--------: |--------: | -|admin.min.js | 255.514 | 51.172 | 73.899 | 15.082 | 60.674 | 13.491 | -|app.min.js | 516.000 | 243.404 |140.430 | 71.302 |110.657 | 60.167 | -|boot.min.js | 66.456 | 2.525 | 22.553 | 1.391 | 20.043 | 1.201 | +|admin.min.js | 255.514 | 50.607 | 73.899 | 14.944 | 60.674 | 13.364 | +|app.min.js | 516.000 | 240.553 |140.430 | 70.291 |110.657 | 59.309 | +|boot.min.js | 66.456 | 2.442 | 22.553 | 1.371 | 20.043 | 1.178 | |libs.min.js | 574.626 | 115.877 |177.280 | 42.809 |151.855 | 38.099 | |polyfills.min.js | 32.608 | 0 | 11.315 | 0 | 10.072 | 0 | -|TOTAL |1.445.204 | 412.978 |425.477 |130.584 |353.301 |112.958 | -|TOTAL (no admin) |1.189.690 | 361.806 |351.061 |115.502 |292.627 | 99.467 | +|TOTAL |1.445.204 | 409.479 |425.477 |129.415 |353.301 |111.950 | +|TOTAL (no admin) |1.189.690 | 358.872 |351.061 |114.471 |292.627 | 98.586 | For a user its around 66% smaller and faster than traditional RainLoop. @@ -166,12 +166,12 @@ For a user its around 66% smaller and faster than traditional RainLoop. |css/* |RainLoop |Snappy |RL gzip |SM gzip |SM brotli | |------------ |-------: |-------: |------: |------: |--------: | -|app.css | 340.334 | 107.316 | 46,959 | 18.818 | 16.150 | -|app.min.css | 274.791 | 88.449 | 39.618 | 16.838 | 14.830 | +|app.css | 340.334 | 107.279 | 46,959 | 18.816 | 16.160 | +|app.min.css | 274.791 | 88.402 | 39.618 | 16.831 | 14.827 | |boot.css | | 2.066 | | 913 | 742 | |boot.min.css | | 1.696 | | 818 | 664 | -|admin.css | | 48.053 | | 9.494 | 8.310 | -|admin.min.css | | 38.740 | | 8.441 | 7.501 | +|admin.css | | 46.393 | | 9.237 | 8.073 | +|admin.min.css | | 37.306 | | 8.191 | 7.282 | ### Squire vs CKEditor @@ -189,8 +189,7 @@ Still TODO: CKEditor including the 7 asset requests (css,language,plugins,icons) is 633.46 KB / 180.47 KB (gzip). -To use the old CKEditor, you must enable it in /data/\_data\_/\_default\_/configs/application.ini -in the [labs] section add/edit: `use_ck_html_editor = On` +To use the old CKEditor, you must install the plugin. ### PHP73 branch diff --git a/dev/App/Abstract.js b/dev/App/Abstract.js index 51fdf8ad3..99ddc4a5d 100644 --- a/dev/App/Abstract.js +++ b/dev/App/Abstract.js @@ -1,7 +1,6 @@ import ko from 'ko'; import { - doc, elementById, Settings } from 'Common/Globals'; @@ -26,27 +25,6 @@ export class AbstractApp { this.Remote = Remote; } - remote() { - return this.Remote || null; - } - - /** - * @param {string} link - * @returns {boolean} - */ - download(link) { - if (ThemeStore.isMobile()) { - open(link, '_self'); - focus(); - } else { - const oLink = doc.createElement('a'); - oLink.href = link; - doc.body.appendChild(oLink).click(); - oLink.remove(); - } - return true; - } - logoutReload(close = false) { const url = logoutLink(); @@ -74,7 +52,7 @@ export class AbstractApp { i18nToNodes(componentInfo.element); - if (undefined !== params.inline && ko.unwrap(params.inline)) { + if (params.inline && ko.unwrap(params.inline)) { params.element.style.display = 'inline-block'; } } @@ -87,12 +65,8 @@ export class AbstractApp { register('Input', InputComponent); register('Select', SelectComponent); register('TextArea', TextAreaComponent); + register('Checkbox', CheckboxMaterialDesignComponent, 'CheckboxMaterialDesignComponent'); register('CheckboxSimple', CheckboxComponent, 'CheckboxComponent'); - if (!Settings.app('materialDesign')) { - register('Checkbox', CheckboxComponent); - } else { - register('Checkbox', CheckboxMaterialDesignComponent, 'CheckboxMaterialDesignComponent'); - } initOnStartOrLangChange(); diff --git a/dev/App/Admin.js b/dev/App/Admin.js index 1c4790d65..b7073b9e7 100644 --- a/dev/App/Admin.js +++ b/dev/App/Admin.js @@ -16,10 +16,6 @@ class AdminApp extends AbstractApp { this.weakPassword = ko.observable(false); } - bootend() { - progressJs.end(); - } - bootstart() { super.bootstart(); @@ -35,7 +31,7 @@ class AdminApp extends AbstractApp { startScreens([LoginAdminScreen]); } - this.bootend(); + progressJs.end(); } } diff --git a/dev/App/User.js b/dev/App/User.js index a7f49e11e..becf923ff 100644 --- a/dev/App/User.js +++ b/dev/App/User.js @@ -867,6 +867,23 @@ class AppUser extends AbstractApp { } } + /** + * @param {string} link + * @returns {boolean} + */ + download(link) { + if (ThemeStore.isMobile()) { + open(link, '_self'); + focus(); + } else { + const oLink = createElement('a'); + oLink.href = link; + doc.body.appendChild(oLink).click(); + oLink.remove(); + } + return true; + } + logout() { Remote.logout(() => this.logoutReload((SettingsGet('ParentEmail')||{length:0}).length)); } diff --git a/dev/Common/File.js b/dev/Common/File.js index 7469b8308..70622c862 100644 --- a/dev/Common/File.js +++ b/dev/Common/File.js @@ -11,96 +11,96 @@ const sizes = ['B', 'KiB', 'MiB', 'GiB', 'TiB'], exts = { - 'eml': 'message/rfc822', - 'mime': 'message/rfc822', - 'rtx': 'text/richtext', - 'vcard': 'text/vcard', - 'vcf': 'text/vcard', - 'htm': 'text/html', - 'html': 'text/html', - 'csv': 'text/csv', - 'ics': 'text/calendar', - 'ifb': 'text/calendar', - 'xml': 'text/xml', - 'json': app+'json', - 'p10': app+'pkcs10', - 'p7c': app+'pkcs7-mime', - 'p7m': app+'pkcs7-mime', - 'p7s': app+'pkcs7-signature', - 'torrent': app+'x-bittorrent', + eml: 'message/rfc822', + mime: 'message/rfc822', + rtx: 'text/richtext', + vcard: 'text/vcard', + vcf: 'text/vcard', + htm: 'text/html', + html: 'text/html', + csv: 'text/csv', + ics: 'text/calendar', + ifb: 'text/calendar', + xml: 'text/xml', + json: app+'json', + p10: app+'pkcs10', + p7c: app+'pkcs7-mime', + p7m: app+'pkcs7-mime', + p7s: app+'pkcs7-signature', + torrent: app+'x-bittorrent', // scripts - 'js': app+'javascript', - 'pl': 'text/perl', - 'css': 'text/css', - 'asp': 'text/asp', - 'php': app+'x-httpd-php', - 'phtml': app+'x-httpd-php', + js: app+'javascript', + pl: 'text/perl', + css: 'text/css', + asp: 'text/asp', + php: app+'x-httpd-php', + phtml: app+'x-httpd-php', // images - 'jpg': 'image/jpeg', - 'ico': 'image/x-icon', - 'tif': 'image/tiff', - 'svg': 'image/svg+xml', - 'svgz': 'image/svg+xml', + jpg: 'image/jpeg', + ico: 'image/x-icon', + tif: 'image/tiff', + svg: 'image/svg+xml', + svgz: 'image/svg+xml', // archives - 'zip': app+'zip', + zip: app+'zip', '7z': app+'x-7z-compressed', - 'rar': app+'x-rar-compressed', - 'cab': app+'vnd.ms-cab-compressed', - 'gz': app+'x-gzip', - 'tgz': app+'x-gzip', - 'bz': app+'x-bzip', - 'bz2': app+'x-bzip2', - 'deb': app+'x-debian-package', + rar: app+'x-rar-compressed', + cab: app+'vnd.ms-cab-compressed', + gz: app+'x-gzip', + tgz: app+'x-gzip', + bz: app+'x-bzip', + bz2: app+'x-bzip2', + deb: app+'x-debian-package', // audio - 'mp3': 'audio/mpeg', - 'wav': 'audio/x-wav', - 'mp4a': 'audio/mp4', - 'weba': 'audio/webm', - 'm3u': 'audio/x-mpegurl', + mp3: 'audio/mpeg', + wav: 'audio/x-wav', + mp4a: 'audio/mp4', + weba: 'audio/webm', + m3u: 'audio/x-mpegurl', // video - 'qt': 'video/quicktime', - 'mov': 'video/quicktime', - 'wmv': 'video/windows-media', - 'avi': 'video/x-msvideo', + qt: 'video/quicktime', + mov: 'video/quicktime', + wmv: 'video/windows-media', + avi: 'video/x-msvideo', '3gp': 'video/3gpp', '3g2': 'video/3gpp2', - 'mp4v': 'video/mp4', - 'mpg4': 'video/mp4', - 'ogv': 'video/ogg', - 'm4v': 'video/x-m4v', - 'asf': 'video/x-ms-asf', - 'asx': 'video/x-ms-asf', - 'wm': 'video/x-ms-wm', - 'wmx': 'video/x-ms-wmx', - 'wvx': 'video/x-ms-wvx', - 'movie': 'video/x-sgi-movie', + mp4v: 'video/mp4', + mpg4: 'video/mp4', + ogv: 'video/ogg', + m4v: 'video/x-m4v', + asf: 'video/x-ms-asf', + asx: 'video/x-ms-asf', + wm: 'video/x-ms-wm', + wmx: 'video/x-ms-wmx', + wvx: 'video/x-ms-wvx', + movie: 'video/x-sgi-movie', // adobe - 'pdf': app+'pdf', - 'psd': 'image/vnd.adobe.photoshop', - 'ai': app+'postscript', - 'eps': app+'postscript', - 'ps': app+'postscript', + pdf: app+'pdf', + psd: 'image/vnd.adobe.photoshop', + ai: app+'postscript', + eps: app+'postscript', + ps: app+'postscript', // ms office - 'doc': app+'msword', - 'rtf': app+'rtf', - 'xls': app+'vnd.ms-excel', - 'ppt': app+'vnd.ms-powerpoint', - 'docx': msOffice+'wordprocessingml.document', - 'xlsx': msOffice+'spreadsheetml.sheet', - 'dotx': msOffice+'wordprocessingml.template', - 'pptx': msOffice+'presentationml.presentation', + doc: app+'msword', + rtf: app+'rtf', + xls: app+'vnd.ms-excel', + ppt: app+'vnd.ms-powerpoint', + docx: msOffice+'wordprocessingml.document', + xlsx: msOffice+'spreadsheetml.sheet', + dotx: msOffice+'wordprocessingml.template', + pptx: msOffice+'presentationml.presentation', // open office - 'odt': openDoc+'text', - 'ods': openDoc+'spreadsheet', - 'odp': openDoc+'presentation' + odt: openDoc+'text', + ods: openDoc+'spreadsheet', + odp: openDoc+'presentation' }; export const FileType = { diff --git a/dev/Common/Html.js b/dev/Common/Html.js index 227f2e181..a1b82528a 100644 --- a/dev/Common/Html.js +++ b/dev/Common/Html.js @@ -1,5 +1,3 @@ -import { createCKEditor } from 'External/CKEditor.js'; - const htmlre = /[&<>"']/g, htmlmap = { @@ -180,11 +178,11 @@ class HtmlEditor { this.onReady && this.onReady(); }; - if (window.CKEDITOR) { - this.editor = createCKEditor(this.element); - this.editor.on('instanceReady', onReady); - } else { - this.editor = new SquireUI(this.element, this.editor); + if (rl.createWYSIWYG) { + this.editor = rl.createWYSIWYG(this.element, onReady); + } + if (!this.editor) { + this.editor = new SquireUI(this.element); setTimeout(onReady,1); } diff --git a/dev/Common/Plugins.js b/dev/Common/Plugins.js index d1a92528c..01a8bcd68 100644 --- a/dev/Common/Plugins.js +++ b/dev/Common/Plugins.js @@ -36,7 +36,7 @@ export function runHook(name, args = []) { * @param {?number=} timeout */ rl.pluginRemoteRequest = (callback, action, parameters, timeout) => { - rl.app && rl.app.remote().defaultRequest(callback, 'Plugin' + action, parameters, timeout); + rl.app && rl.app.Remote.defaultRequest(callback, 'Plugin' + action, parameters, timeout); }; /** diff --git a/dev/Common/Translator.js b/dev/Common/Translator.js index 63bcdd4d6..552d16d15 100644 --- a/dev/Common/Translator.js +++ b/dev/Common/Translator.js @@ -1,7 +1,7 @@ import ko from 'ko'; import { Notification, UploadErrorCode } from 'Common/Enums'; import { langLink } from 'Common/Links'; -import { doc } from 'Common/Globals'; +import { doc, createElement } from 'Common/Globals'; let I18N_DATA = window.rainloopI18N || {}; @@ -14,19 +14,12 @@ export const trigger = ko.observable(false); * @returns {string} */ export function i18n(key, valueList, defaulValue) { - let valueName = '', - result = I18N_DATA[key]; + let result = I18N_DATA[key] || defaulValue || key; - if (undefined === result) { - result = undefined === defaulValue ? key : defaulValue; - } - - if (null != valueList) { - for (valueName in valueList) { - if (Object.prototype.hasOwnProperty.call(valueList, valueName)) { - result = result.replace('%' + valueName + '%', valueList[valueName]); - } - } + if (valueList) { + Object.entries(valueList).forEach(([key, value]) => { + result = result.replace('%' + key + '%', value); + }); } return result; @@ -129,7 +122,7 @@ export function getUploadErrorDescByCode(code) { */ export function reload(admin, language) { return new Promise((resolve, reject) => { - const script = doc.createElement('script'); + const script = createElement('script'); script.onload = () => { // reload the data if (window.rainloopI18N) { diff --git a/dev/Common/Utils.js b/dev/Common/Utils.js index cc5351d47..89b55658a 100644 --- a/dev/Common/Utils.js +++ b/dev/Common/Utils.js @@ -1,5 +1,5 @@ import { SaveSettingsStep } from 'Common/Enums'; -import { doc, elementById } from 'Common/Globals'; +import { doc, createElement, elementById } from 'Common/Globals'; export const isArray = Array.isArray, @@ -119,7 +119,7 @@ export function changeTheme(value, themeTrigger = ()=>{}) { .then(data => { if (data && isArray(data) && 2 === data.length) { if (themeLink && !themeStyle) { - themeStyle = doc.createElement('style'); + themeStyle = createElement('style'); themeStyle.id = 'app-theme-style'; themeLink.after(themeStyle); themeLink.remove(); diff --git a/dev/Common/UtilsUser.js b/dev/Common/UtilsUser.js index 48493219a..93fed0663 100644 --- a/dev/Common/UtilsUser.js +++ b/dev/Common/UtilsUser.js @@ -2,7 +2,7 @@ import { ComposeType, FolderType } from 'Common/EnumsUser'; import { EmailModel } from 'Model/Email'; import { encodeHtml } from 'Common/Html'; import { isArray } from 'Common/Utils'; -import { doc } from 'Common/Globals'; +import { createElement } from 'Common/Globals'; /** * @param {(string|number)} value @@ -79,7 +79,7 @@ export function htmlToPlain(html) { }; const - tpl = doc.createElement('template'), + tpl = createElement('template'), convertPre = (...args) => args && 1 < args.length ? args[1] diff --git a/dev/External/CKEditor.js b/dev/External/CKEditor.js deleted file mode 100644 index 0bbf4b5b4..000000000 --- a/dev/External/CKEditor.js +++ /dev/null @@ -1,79 +0,0 @@ -export function createCKEditor(element) -{ - const language = (rl.settings.get('Language') || 'en').toLowerCase(), - - htmlEditorLangsMap = { - 'ar_sa': 'ar-sa', - 'pt_br': 'pt-br', - 'zh_cn': 'zh-cn', - }; - - const editor = CKEDITOR.appendTo(element, { - title: false, - stylesSet: false, -// customConfig: '', -// contentsCss: '', - toolbarGroups: [ - { name: 'spec' }, - { name: 'styles' }, - { name: 'basicstyles', groups: ['basicstyles', 'cleanup', 'bidi'] }, - { name: 'colors' }, - { name: 'paragraph', groups: ['list', 'indent', 'blocks', 'align'] }, - { name: 'links' }, - { name: 'insert' }, - { name: 'document', groups: ['mode', 'document', 'doctools'] }, - { name: 'others' } - ], - - removePlugins: 'liststyle' + (rl.settings.app('allowHtmlEditorBitiButtons') ? '' : ',bidi'), - removeButtons: 'Format,Undo,Redo,Cut,Copy,Paste,Anchor,Strike,Subscript,Superscript,Image,SelectAll' - + (rl.settings.app('allowHtmlEditorSourceButton') ? '' : ',Source'), - removeDialogTabs: 'link:advanced;link:target;image:advanced;images:advanced', - - extraPlugins: 'plain,signature', - - allowedContent: true, - extraAllowedContent: true, - - fillEmptyBlocks: false, -// ignoreEmptyParagraph: true, - disableNativeSpellChecker: false, - - colorButton_enableAutomatic: false, -// colorButton_enableMore: true, - - font_defaultLabel: 'Arial', - fontSize_defaultLabel: '13', - fontSize_sizes: '10/10px;12/12px;13/13px;14/14px;16/16px;18/18px;20/20px;24/24px;28/28px;36/36px;48/48px', - - enterMode: CKEDITOR.ENTER_BR, - shiftEnterMode: CKEDITOR.ENTER_P, - language: htmlEditorLangsMap[language] || language.substr(0,2) - }); - - editor.on('key', event => !(event && event.data && 'Tab' == event.data.key)); - - editor.on('drop', event => { - const dt = event.data.dataTransfer, - id = dt.id, - file = dt.getFilesCount() ? dt.getFile(0) : 0; - if (file && id && file.type && file.type.match(/^image/i)) { - const imageId = `[img=${id}]`, - reader = new FileReader(); - - reader.onloadend = () => { - if (reader.result && 'wysiwyg' === editor.mode) { - try { - editor.setData(editor.getData().replace(imageId, ``)); - } catch (e) {} // eslint-disable-line no-empty - } - }; - - reader.readAsDataURL(file); - - dt.setData('text/html', imageId); - } - }); - - return editor; -} diff --git a/dev/External/ko.js b/dev/External/ko.js index 92bd36173..b776995b1 100644 --- a/dev/External/ko.js +++ b/dev/External/ko.js @@ -1,4 +1,4 @@ -import { i18n, i18nToNodes, trigger } from 'Common/Translator'; +import { i18nToNodes } from 'Common/Translator'; import { doc, createElement } from 'Common/Globals'; import { SaveSettingsStep } from 'Common/Enums'; import { isNonEmptyArray, isFunction } from 'Common/Utils'; @@ -6,16 +6,6 @@ import { isNonEmptyArray, isFunction } from 'Common/Utils'; const koValue = value => !ko.isObservable(value) && isFunction(value) ? value() : ko.unwrap(value); -ko.bindingHandlers.tooltip = { - init: (element, fValueAccessor) => { - const sValue = koValue(fValueAccessor()); - element.title = i18n(sValue); - trigger.subscribe(() => element.title = i18n(sValue)); - }, - update: (element, fValueAccessor) => - element.title = i18n(koValue(fValueAccessor())) -}; - ko.bindingHandlers.tooltipErrorTip = { init: element => { doc.addEventListener('click', () => element.removeAttribute('data-rainloopErrorTip')); diff --git a/dev/Model/Message.js b/dev/Model/Message.js index 8a8d4e92a..9c0264258 100644 --- a/dev/Model/Message.js +++ b/dev/Model/Message.js @@ -272,22 +272,22 @@ export class MessageModel extends AbstractModel { lineAsCss() { let classes = []; Object.entries({ - 'deleted': this.deleted(), + deleted: this.deleted(), 'deleted-mark': this.isDeleted(), - 'selected': this.selected(), - 'checked': this.checked(), - 'flagged': this.isFlagged(), - 'unseen': this.isUnseen(), - 'answered': this.isAnswered(), - 'forwarded': this.isForwarded(), - 'focused': this.focused(), - 'important': this.isImportant(), - 'withAttachments': this.hasAttachments(), - 'new': this.newForAnimation(), - 'emptySubject': !this.subject(), - // 'hasChildrenMessage': 1 < this.threadsLen(), - 'hasUnseenSubMessage': this.hasUnseenSubMessage(), - 'hasFlaggedSubMessage': this.hasFlaggedSubMessage() + selected: this.selected(), + checked: this.checked(), + flagged: this.isFlagged(), + unseen: this.isUnseen(), + answered: this.isAnswered(), + forwarded: this.isForwarded(), + focused: this.focused(), + important: this.isImportant(), + withAttachments: this.hasAttachments(), + new: this.newForAnimation(), + emptySubject: !this.subject(), + // hasChildrenMessage: 1 < this.threadsLen(), + hasUnseenSubMessage: this.hasUnseenSubMessage(), + hasFlaggedSubMessage: this.hasFlaggedSubMessage() }).forEach(([key, value]) => value && classes.push(key)); return classes.join(' '); } diff --git a/dev/Remote/AbstractFetch.js b/dev/Remote/AbstractFetch.js index 5379c18f7..57afb5257 100644 --- a/dev/Remote/AbstractFetch.js +++ b/dev/Remote/AbstractFetch.js @@ -173,7 +173,7 @@ export class AbstractFetchRemote */ jsVersion(fCallback, sVersion) { this.defaultRequest(fCallback, 'Version', { - 'Version': sVersion + Version: sVersion }); } diff --git a/dev/Settings/Admin/Branding.js b/dev/Settings/Admin/Branding.js index 8c9152c59..a957c8604 100644 --- a/dev/Settings/Admin/Branding.js +++ b/dev/Settings/Admin/Branding.js @@ -13,19 +13,19 @@ export class BrandingAdminSettings { this.title.subscribe(value => Remote.saveAdminConfig(settingsSaveHelperSimpleFunction(this.title.trigger, this), { - 'Title': value.trim() + Title: value.trim() }) ); this.loadingDesc.subscribe(value => Remote.saveAdminConfig(settingsSaveHelperSimpleFunction(this.loadingDesc.trigger, this), { - 'LoadingDescription': value.trim() + LoadingDescription: value.trim() }) ); this.faviconUrl.subscribe(value => Remote.saveAdminConfig(settingsSaveHelperSimpleFunction(this.faviconUrl.trigger, this), { - 'FaviconUrl': value.trim() + FaviconUrl: value.trim() }) ); } diff --git a/dev/Settings/Admin/Contacts.js b/dev/Settings/Admin/Contacts.js index 046dea9f4..7e0fe8a83 100644 --- a/dev/Settings/Admin/Contacts.js +++ b/dev/Settings/Admin/Contacts.js @@ -74,12 +74,12 @@ export class ContactsAdminSettings { addSubscribablesTo(this, { enableContacts: value => Remote.saveAdminConfig(null, { - 'ContactsEnable': value ? 1 : 0 + ContactsEnable: value ? 1 : 0 }), contactsSync: value => Remote.saveAdminConfig(null, { - 'ContactsSync': value ? 1 : 0 + ContactsSync: value ? 1 : 0 }), contactsType: value => { @@ -87,23 +87,23 @@ export class ContactsAdminSettings { this.testContactsError(false); this.testContactsErrorMessage(''); Remote.saveAdminConfig(settingsSaveHelperSimpleFunction(this.contactsTypeTrigger, this), { - 'ContactsPdoType': value.trim() + ContactsPdoType: value.trim() }) }, pdoDsn: value => Remote.saveAdminConfig(settingsSaveHelperSimpleFunction(this.pdoDsnTrigger, this), { - 'ContactsPdoDsn': value.trim() + ContactsPdoDsn: value.trim() }), pdoUser: value => Remote.saveAdminConfig(settingsSaveHelperSimpleFunction(this.pdoUserTrigger, this), { - 'ContactsPdoUser': value.trim() + ContactsPdoUser: value.trim() }), pdoPassword: value => Remote.saveAdminConfig(settingsSaveHelperSimpleFunction(this.pdoPasswordTrigger, this), { - 'ContactsPdoPassword': value.trim() + ContactsPdoPassword: value.trim() }) }) @@ -121,10 +121,10 @@ export class ContactsAdminSettings { this.testing(true); Remote.testContacts(this.onTestContactsResponse, { - 'ContactsPdoType': this.contactsType(), - 'ContactsPdoDsn': this.pdoDsn(), - 'ContactsPdoUser': this.pdoUser(), - 'ContactsPdoPassword': this.pdoPassword() + ContactsPdoType: this.contactsType(), + ContactsPdoDsn: this.pdoDsn(), + ContactsPdoUser: this.pdoUser(), + ContactsPdoPassword: this.pdoPassword() }); } diff --git a/dev/Settings/Admin/General.js b/dev/Settings/Admin/General.js index a7df51e76..22066fbce 100644 --- a/dev/Settings/Admin/General.js +++ b/dev/Settings/Admin/General.js @@ -93,12 +93,12 @@ export class GeneralAdminSettings { addSubscribablesTo(this, { mainAttachmentLimit: value => Remote.saveAdminConfig(settingsSaveHelperSimpleFunction(this.attachmentLimitTrigger, this), { - 'AttachmentLimit': pInt(value) + AttachmentLimit: pInt(value) }), language: value => Remote.saveAdminConfig(settingsSaveHelperSimpleFunction(this.languageTrigger, this), { - 'Language': value.trim() + Language: value.trim() }), languageAdmin: value => { @@ -106,14 +106,14 @@ export class GeneralAdminSettings { translatorReload(true, value) .then(fReloadLanguageHelper(SaveSettingsStep.TrueResult), fReloadLanguageHelper(SaveSettingsStep.FalseResult)) .then(() => Remote.saveAdminConfig(null, { - 'LanguageAdmin': value.trim() + LanguageAdmin: value.trim() })); }, theme: value => { changeTheme(value, this.themeTrigger); Remote.saveAdminConfig(settingsSaveHelperSimpleFunction(this.themeTrigger, this), { - 'Theme': value.trim() + Theme: value.trim() }); }, diff --git a/dev/Settings/Admin/Login.js b/dev/Settings/Admin/Login.js index 3cfab448f..2e0be8ba8 100644 --- a/dev/Settings/Admin/Login.js +++ b/dev/Settings/Admin/Login.js @@ -19,27 +19,27 @@ export class LoginAdminSettings { addSubscribablesTo(this, { determineUserLanguage: value => Remote.saveAdminConfig(null, { - 'DetermineUserLanguage': value ? 1 : 0 + DetermineUserLanguage: value ? 1 : 0 }), determineUserDomain: value => Remote.saveAdminConfig(null, { - 'DetermineUserDomain': value ? 1 : 0 + DetermineUserDomain: value ? 1 : 0 }), allowLanguagesOnLogin: value => Remote.saveAdminConfig(null, { - 'AllowLanguagesOnLogin': value ? 1 : 0 + AllowLanguagesOnLogin: value ? 1 : 0 }), hideSubmitButton: value => Remote.saveAdminConfig(null, { - 'hideSubmitButton': value ? 1 : 0 + hideSubmitButton: value ? 1 : 0 }), defaultDomain: value => Remote.saveAdminConfig(settingsSaveHelperSimpleFunction(this.defaultDomain.trigger, this), { - 'LoginDefaultDomain': value.trim() + LoginDefaultDomain: value.trim() }) }); } diff --git a/dev/Settings/Admin/Plugins.js b/dev/Settings/Admin/Plugins.js index aca7842ee..4cd2eb49c 100644 --- a/dev/Settings/Admin/Plugins.js +++ b/dev/Settings/Admin/Plugins.js @@ -24,7 +24,7 @@ export class PluginsAdminSettings { this.enabledPlugins.subscribe(value => Remote.saveAdminConfig(null, { - 'EnabledPlugins': value ? 1 : 0 + EnabledPlugins: value ? 1 : 0 }) ); } diff --git a/dev/Settings/Admin/Security.js b/dev/Settings/Admin/Security.js index 300e0ebd3..c8c4b3eb3 100644 --- a/dev/Settings/Admin/Security.js +++ b/dev/Settings/Admin/Security.js @@ -57,36 +57,36 @@ export class SecurityAdminSettings { capaOpenPGP: value => Remote.saveAdminConfig(null, { - 'CapaOpenPGP': value ? 1 : 0 + CapaOpenPGP: value ? 1 : 0 }), capaTwoFactorAuth: value => { value || this.capaTwoFactorAuthForce(false); Remote.saveAdminConfig(null, { - 'CapaTwoFactorAuth': value ? 1 : 0 + CapaTwoFactorAuth: value ? 1 : 0 }); }, capaTwoFactorAuthForce: value => Remote.saveAdminConfig(null, { - 'CapaTwoFactorAuthForce': value ? 1 : 0 + CapaTwoFactorAuthForce: value ? 1 : 0 }), useLocalProxyForExternalImages: value => Remote.saveAdminConfig(null, { - 'UseLocalProxyForExternalImages': value ? 1 : 0 + UseLocalProxyForExternalImages: value ? 1 : 0 }), verifySslCertificate: value => { value => value || this.allowSelfSigned(true); Remote.saveAdminConfig(null, { - 'VerifySslCertificate': value ? 1 : 0 + VerifySslCertificate: value ? 1 : 0 }); }, allowSelfSigned: value => Remote.saveAdminConfig(null, { - 'AllowSelfSigned': value ? 1 : 0 + AllowSelfSigned: value ? 1 : 0 }) }); diff --git a/dev/Settings/User/Contacts.js b/dev/Settings/User/Contacts.js index d7347ce02..2769b6320 100644 --- a/dev/Settings/User/Contacts.js +++ b/dev/Settings/User/Contacts.js @@ -27,7 +27,7 @@ export class ContactsUserSettings { this.contactsAutosave.subscribe(value => Remote.saveSettings(null, { - 'ContactsAutosave': value ? 1 : 0 + ContactsAutosave: value ? 1 : 0 }) ); diff --git a/dev/Settings/User/General.js b/dev/Settings/User/General.js index 08d1fc466..ed49b0af6 100644 --- a/dev/Settings/User/General.js +++ b/dev/Settings/User/General.js @@ -68,19 +68,19 @@ export class GeneralUserSettings { this.editorDefaultTypes = ko.computed(() => { translatorTrigger(); return [ - { 'id': EditorDefaultType.Html, 'name': i18n('SETTINGS_GENERAL/LABEL_EDITOR_HTML') }, - { 'id': EditorDefaultType.Plain, 'name': i18n('SETTINGS_GENERAL/LABEL_EDITOR_PLAIN') }, - { 'id': EditorDefaultType.HtmlForced, 'name': i18n('SETTINGS_GENERAL/LABEL_EDITOR_HTML_FORCED') }, - { 'id': EditorDefaultType.PlainForced, 'name': i18n('SETTINGS_GENERAL/LABEL_EDITOR_PLAIN_FORCED') } + { id: EditorDefaultType.Html, name: i18n('SETTINGS_GENERAL/LABEL_EDITOR_HTML') }, + { id: EditorDefaultType.Plain, name: i18n('SETTINGS_GENERAL/LABEL_EDITOR_PLAIN') }, + { id: EditorDefaultType.HtmlForced, name: i18n('SETTINGS_GENERAL/LABEL_EDITOR_HTML_FORCED') }, + { id: EditorDefaultType.PlainForced, name: i18n('SETTINGS_GENERAL/LABEL_EDITOR_PLAIN_FORCED') } ]; }); this.layoutTypes = ko.computed(() => { translatorTrigger(); return [ - { 'id': Layout.NoPreview, 'name': i18n('SETTINGS_GENERAL/LABEL_LAYOUT_NO_SPLIT') }, - { 'id': Layout.SidePreview, 'name': i18n('SETTINGS_GENERAL/LABEL_LAYOUT_VERTICAL_SPLIT') }, - { 'id': Layout.BottomPreview, 'name': i18n('SETTINGS_GENERAL/LABEL_LAYOUT_HORIZONTAL_SPLIT') } + { id: Layout.NoPreview, name: i18n('SETTINGS_GENERAL/LABEL_LAYOUT_NO_SPLIT') }, + { id: Layout.SidePreview, name: i18n('SETTINGS_GENERAL/LABEL_LAYOUT_VERTICAL_SPLIT') }, + { id: Layout.BottomPreview, name: i18n('SETTINGS_GENERAL/LABEL_LAYOUT_HORIZONTAL_SPLIT') } ]; }); @@ -142,7 +142,7 @@ export class GeneralUserSettings { } testSystemNotification() { - NotificationUserStore.displayDesktopNotification('SnappyMail', 'Test notification', { }); + NotificationUserStore.displayDesktopNotification('SnappyMail', 'Test notification'); } selectLanguage() { diff --git a/dev/Settings/User/Security.js b/dev/Settings/User/Security.js index 1d51a3beb..55ed0e458 100644 --- a/dev/Settings/User/Security.js +++ b/dev/Settings/User/Security.js @@ -25,14 +25,14 @@ export class SecurityUserSettings { this.autoLogoutOptions = ko.computed(() => { translatorTrigger(); return [ - { 'id': 0, 'name': i18nLogout('NEVER_OPTION_NAME') }, - { 'id': 5, 'name': i18nLogout('MINUTES_OPTION_NAME', { 'MINUTES': 5 }) }, - { 'id': 10, 'name': i18nLogout('MINUTES_OPTION_NAME', { 'MINUTES': 10 }) }, - { 'id': 30, 'name': i18nLogout('MINUTES_OPTION_NAME', { 'MINUTES': 30 }) }, - { 'id': 60, 'name': i18nLogout('MINUTES_OPTION_NAME', { 'MINUTES': 60 }) }, - { 'id': 60 * 2, 'name': i18nLogout('HOURS_OPTION_NAME', { 'HOURS': 2 }) }, - { 'id': 60 * 5, 'name': i18nLogout('HOURS_OPTION_NAME', { 'HOURS': 5 }) }, - { 'id': 60 * 10, 'name': i18nLogout('HOURS_OPTION_NAME', { 'HOURS': 10 }) } + { id: 0, name: i18nLogout('NEVER_OPTION_NAME') }, + { id: 5, name: i18nLogout('MINUTES_OPTION_NAME', { MINUTES: 5 }) }, + { id: 10, name: i18nLogout('MINUTES_OPTION_NAME', { MINUTES: 10 }) }, + { id: 30, name: i18nLogout('MINUTES_OPTION_NAME', { MINUTES: 30 }) }, + { id: 60, name: i18nLogout('MINUTES_OPTION_NAME', { MINUTES: 60 }) }, + { id: 60 * 2, name: i18nLogout('HOURS_OPTION_NAME', { HOURS: 2 }) }, + { id: 60 * 5, name: i18nLogout('HOURS_OPTION_NAME', { HOURS: 5 }) }, + { id: 60 * 10, name: i18nLogout('HOURS_OPTION_NAME', { HOURS: 10 }) } ]; }); diff --git a/dev/Settings/User/Themes.js b/dev/Settings/User/Themes.js index 44f1a44d1..bc5d9ee69 100644 --- a/dev/Settings/User/Themes.js +++ b/dev/Settings/User/Themes.js @@ -35,7 +35,7 @@ export class ThemesUserSettings { changeTheme(value, this.themeTrigger); Remote.saveSettings(null, { - 'Theme': value + Theme: value }); }); diff --git a/dev/Stores/User/Message.js b/dev/Stores/User/Message.js index 24e2be80a..33fda90f1 100644 --- a/dev/Stores/User/Message.js +++ b/dev/Stores/User/Message.js @@ -2,7 +2,7 @@ import ko from 'ko'; import { Scope, Notification } from 'Common/Enums'; import { MessageSetAction } from 'Common/EnumsUser'; -import { doc, elementById } from 'Common/Globals'; +import { doc, createElement, elementById } from 'Common/Globals'; import { isNonEmptyArray, pInt, pString, addObservablesTo, addSubscribablesTo } from 'Common/Utils'; import { plainToHtml } from 'Common/UtilsUser'; @@ -247,16 +247,16 @@ export const MessageUserStore = new class { NotificationUserStore.displayDesktopNotification( AccountUserStore.email(), i18n('MESSAGE_LIST/NEW_MESSAGE_NOTIFICATION', { - 'COUNT': len + COUNT: len }), - { 'Url': mailBox(newMessages[0].Folder, 1) } + { Url: mailBox(newMessages[0].Folder, 1) } ); } else { newMessages.forEach(item => { NotificationUserStore.displayDesktopNotification( EmailCollectionModel.reviveFromJson(item.From).toString(), item.Subject, - { 'Folder': item.Folder, 'Uid': item.Uid } + { Folder: item.Folder, Uid: item.Uid } ); }); } @@ -504,7 +504,7 @@ export const MessageUserStore = new class { /-----BEGIN PGP SIGNED MESSAGE-----/.test(plain) && /-----BEGIN PGP SIGNATURE-----/.test(plain); } - const pre = doc.createElement('pre'); + const pre = createElement('pre'); if (pgpSigned && message.isPgpSigned()) { pre.className = 'b-plain-openpgp signed'; pre.textContent = plain; diff --git a/dev/Stores/User/Pgp.js b/dev/Stores/User/Pgp.js index 281e3931d..952295536 100644 --- a/dev/Stores/User/Pgp.js +++ b/dev/Stores/User/Pgp.js @@ -2,7 +2,7 @@ import ko from 'ko'; import { i18n } from 'Common/Translator'; import { isArray, isNonEmptyArray, pString } from 'Common/Utils'; -import { doc } from 'Common/Globals'; +import { createElement } from 'Common/Globals'; import { AccountUserStore } from 'Stores/User/Account'; @@ -49,7 +49,7 @@ function domControlEncryptedClickHelper(store, dom, armoredMessage, recipients) this, true, i18n('PGP_NOTIFICATIONS/GOOD_SIGNATURE', { - 'USER': validPublicKey.user + ' (' + validPublicKey.id + ')' + USER: validPublicKey.user + ' (' + validPublicKey.id + ')' }), decryptedMessage.getText() ); @@ -105,7 +105,7 @@ function domControlSignedClickHelper(store, dom, armoredMessage) { this, true, i18n('PGP_NOTIFICATIONS/GOOD_SIGNATURE', { - 'USER': validKey.user + ' (' + validKey.id + ')' + USER: validKey.user + ' (' + validKey.id + ')' }), message.getText() ); @@ -361,7 +361,7 @@ export const PgpUserStore = new class { verControl.addEventHandler('click', domControlSignedClickHelper(this, dom, domText)); } - dom.before(verControl, doc.createElement('div')); + dom.before(verControl, createElement('div')); } } } diff --git a/dev/Styles/@Main.less b/dev/Styles/@Main.less index 9620cc81c..38ec808e0 100644 --- a/dev/Styles/@Main.less +++ b/dev/Styles/@Main.less @@ -67,6 +67,3 @@ @import "Animations.less"; @import "_End.less"; -/* -@import "_CkeFix.less"; -*/ diff --git a/dev/Styles/_CkeFix.less b/dev/Styles/_CkeFix.less deleted file mode 100644 index 3a1349013..000000000 --- a/dev/Styles/_CkeFix.less +++ /dev/null @@ -1,213 +0,0 @@ -/*.cke_button__sourcedialog_label { - display: none !important; -}*/ - -.cke_chrome { - border: 1px solid #ccc !important; -} - -.cke_toolgroup { - padding-right: 0 !important; - background: #FBFBFB !important; -} - -.cke_toolgroup, .cke_combo_button { - border: 1px solid #A6A6A6 !important; -} - -.cke_top { - padding: 2px; - box-shadow: none !important; - border-bottom: 1px solid #b6b6b6 !important; - background: #F0F0F0 !important; -} - -.cke_combo_on a.cke_combo_button, -.cke_combo_off a.cke_combo_button:hover, -.cke_combo_off a.cke_combo_button:focus, -.cke_combo_off a.cke_combo_button:active { - padding: 1px !important; - margin-left: 0 !important; -} - -.cke_toolgroup a.cke_button:last-child:after, -.cke_toolgroup a.cke_button.cke_button_disabled:hover:last-child:after { - border: none !important; - height: 0 !important; - width: 0 !important; - margin: 0 !important; - padding: 0 !important; -} - -.cke_button_on { - background: #ddd !important; -} - -.cke_combo { - margin-top: 1px !important; -} - -.cke_combo__fontsize { - margin-left: 3px !important; - .cke_combo_text { - width: 40px !important; - } -} - -.cke_combo_text { - line-height: 24px !important; - padding-left: 8px !important; -} - -.cke_combo_button { - background: #FBFBFB !important; -} - -.cke_source { - font-family: var(--fontMono) !important; - padding: 10px !important; - padding-right: 0 !important; - box-shadow: none !important; -} - -.cke_plain { - - background-color: #fff; - outline: none; - overflow: auto; - z-index: 1; - margin: 0; - border: 0; - - padding: 10px; - padding-right: 0; - white-space: pre-wrap; - font-family: var(--fontMono), monospace; - font-size: 13px; - line-height: 16px; - color: #333; - resize: none; - - border-radius: 0; - box-shadow: none; - box-sizing: border-box; -} - -.cke_plain:focus, .cke_source:focus { - border: 0; -} - -.b-compose .cke_chrome { - border-right: 0; - border-left: 0; - border-bottom: 0; - box-shadow: none; -} - -.cke_wysiwyg_div { - - padding: 10px !important; - font-family: var(--fontSans); - font-size: 13px; - line-height: 16px; - color: #333; - - ul { - padding-left: 40px; - li { - list-style-type: disc !important; - } - } - - ol { - padding-left: 40px; - li { - list-style-type: decimal !important; - } - } - - pre, code { - margin: 0; - padding: 0; - background: #fff; - border: none; - border-radius: 0; - font-family: var(--fontMono); - display: block; - word-break: normal; - word-wrap: break-word; - background-color: #f9f9f9; - } - - code { - display: inline; - padding: 2px 5px; - } - - pre { - padding: 5px 10px; - border-radius: 5px; - background-color: #f9f9f9; - } - - pre > code { - padding: 0; - } - - blockquote { - border: 0; - border-left: solid 2px #444; - margin: 5px 0 5px 5px; - padding-left: 5px; - } - - blockquote p { - margin: 0 0 10px; - font-size: 14px; - line-height: 20px; - } - - img { - vertical-align: bottom; - } - - a { - color: blue; - text-decoration: underline; - - &:visited { - color: #609; - } - &:active { - color: red; - } - } -} - -.cke_dialog { - - a:hover { - text-decoration: none; - } - - .cke_dialog_ui_labeled_content { - margin-top: 5px; - margin-bottom: 5px; - } - - .cke_dialog_ui_input_select, .cke_dialog_ui_input_text, .cke_dialog_ui_input_textarea { - - box-shadow: none; - border-radius: 2px; - - &:focus { - outline: 0; - border: 1px solid #999; - } - } - - .cke_dialog_ui_input_select, .cke_dialog_ui_input_text { - height: 25px; - line-height: 25px; - } -} diff --git a/dev/View/Popup/Compose.js b/dev/View/Popup/Compose.js index 36522afe6..3a0fb21ea 100644 --- a/dev/View/Popup/Compose.js +++ b/dev/View/Popup/Compose.js @@ -226,7 +226,7 @@ class ComposePopupView extends AbstractViewPopup { sendButtonSuccess: () => !this.sendError() && !this.sendSuccessButSaveError(), savedTimeText: () => - this.savedTime() ? i18n('COMPOSE/SAVED_TIME', { 'TIME': this.savedTime().format('LT') }) : '', + this.savedTime() ? i18n('COMPOSE/SAVED_TIME', { TIME: this.savedTime().format('LT') }) : '', emptyToErrorTooltip: () => (this.emptyToError() ? i18n('COMPOSE/EMPTY_TO_ERROR_DESC') : ''), @@ -254,9 +254,9 @@ class ComposePopupView extends AbstractViewPopup { identitiesOptions: () => IdentityUserStore.map(item => ({ - 'item': item, - 'optValue': item.id(), - 'optText': item.formattedName() + item: item, + optValue: item.id(), + optText: item.formattedName() })), currentIdentityView: () => { @@ -931,8 +931,8 @@ class ComposePopupView extends AbstractViewPopup { case ComposeType.ReplyAll: sFrom = message.fromToLine(false, true); sReplyTitle = i18n('COMPOSE/REPLY_MESSAGE_TITLE', { - 'DATETIME': sDate, - 'EMAIL': sFrom + DATETIME: sDate, + EMAIL: sFrom }); sText = sText.replace(/]+>/g, '').replace(/]+><\/a>/g, '').trim(); diff --git a/dev/View/Popup/ComposeOpenPgp.js b/dev/View/Popup/ComposeOpenPgp.js index 63f520c59..749bdfefc 100644 --- a/dev/View/Popup/ComposeOpenPgp.js +++ b/dev/View/Popup/ComposeOpenPgp.js @@ -49,9 +49,9 @@ class ComposeOpenPgpPopupView extends AbstractViewPopup { return null; } return oKey.users.map(user => ({ - 'id': oKey.guid, - 'name': '(' + oKey.id.substr(KEY_NAME_SUBSTR).toUpperCase() + ') ' + user, - 'key': oKey + id: oKey.guid, + name: '(' + oKey.id.substr(KEY_NAME_SUBSTR).toUpperCase() + ') ' + user, + key: oKey })); }); @@ -64,9 +64,9 @@ class ComposeOpenPgpPopupView extends AbstractViewPopup { return null; } return oKey.users.map(user => ({ - 'id': oKey.guid, - 'name': '(' + oKey.id.substr(KEY_NAME_SUBSTR).toUpperCase() + ') ' + user, - 'key': oKey + id: oKey.guid, + name: '(' + oKey.id.substr(KEY_NAME_SUBSTR).toUpperCase() + ') ' + user, + key: oKey })); }); return opts.flat().filter(v => v); @@ -114,7 +114,7 @@ class ComposeOpenPgpPopupView extends AbstractViewPopup { } else if (!this.signKey().key) { this.notification( i18nPGP('NO_PRIVATE_KEY_FOUND_FOR', { - 'EMAIL': this.signKey().email + EMAIL: this.signKey().email }) ); @@ -150,7 +150,7 @@ class ComposeOpenPgpPopupView extends AbstractViewPopup { } else if (oKey && oKey.email) { this.notification( i18nPGP('NO_PUBLIC_KEYS_FOUND_FOR', { - 'EMAIL': oKey.email + EMAIL: oKey.email }) ); @@ -196,7 +196,7 @@ class ComposeOpenPgpPopupView extends AbstractViewPopup { this.notification( i18nPGP('PGP_ERROR', { - 'ERROR': '' + e + ERROR: '' + e }) ); } @@ -211,13 +211,13 @@ class ComposeOpenPgpPopupView extends AbstractViewPopup { .catch((e) => { this.notification( i18nPGP('PGP_ERROR', { - 'ERROR': '' + e + ERROR: '' + e }) ); }); } catch (e) { this.notification( - i18nPGP('PGP_ERROR', {'ERROR': '' + e}) + i18nPGP('PGP_ERROR', {ERROR: '' + e}) ); } } @@ -237,11 +237,11 @@ class ComposeOpenPgpPopupView extends AbstractViewPopup { if (option) { this.signKey({ - 'empty': !option.key, - 'selected': ko.observable(!!option.key), - 'users': option.key.users, - 'hash': option.key.id.substr(KEY_NAME_SUBSTR).toUpperCase(), - 'key': option.key + empty: !option.key, + selected: ko.observable(!!option.key), + users: option.key.users, + hash: option.key.id.substr(KEY_NAME_SUBSTR).toUpperCase(), + key: option.key }); } } @@ -252,12 +252,12 @@ class ComposeOpenPgpPopupView extends AbstractViewPopup { if (option) { this.encryptKeys.push({ - 'empty': !option.key, - 'selected': ko.observable(!!option.key), - 'removable': ko.observable(!this.sign() || !this.signKey() || this.signKey().key.id !== option.key.id), - 'users': option.key.users, - 'hash': option.key.id.substr(KEY_NAME_SUBSTR).toUpperCase(), - 'key': option.key + empty: !option.key, + selected: ko.observable(!!option.key), + removable: ko.observable(!this.sign() || !this.signKey() || this.signKey().key.id !== option.key.id), + users: option.key.users, + hash: option.key.id.substr(KEY_NAME_SUBSTR).toUpperCase(), + key: option.key }); } } @@ -343,9 +343,9 @@ class ComposeOpenPgpPopupView extends AbstractViewPopup { const keys = PgpUserStore.findAllPrivateKeysByEmailNotNative(emailLine); if (keys && keys[0]) { this.signKey({ - 'users': keys[0].users || [emailLine], - 'hash': keys[0].id.substr(KEY_NAME_SUBSTR).toUpperCase(), - 'key': keys[0] + users: keys[0].users || [emailLine], + hash: keys[0].id.substr(KEY_NAME_SUBSTR).toUpperCase(), + key: keys[0] }); } } @@ -360,14 +360,14 @@ class ComposeOpenPgpPopupView extends AbstractViewPopup { const keys = PgpUserStore.findAllPublicKeysByEmailNotNative(recEmail); return keys ? keys.map(publicKey => ({ - 'empty': !publicKey, - 'selected': ko.observable(!!publicKey), - 'removable': ko.observable( + empty: !publicKey, + selected: ko.observable(!!publicKey), + removable: ko.observable( !this.sign() || !this.signKey() || this.signKey().key.id !== publicKey.id ), - 'users': publicKey ? publicKey.users || [recEmail] : [recEmail], - 'hash': publicKey ? publicKey.id.substr(KEY_NAME_SUBSTR).toUpperCase() : '', - 'key': publicKey + users: publicKey ? publicKey.users || [recEmail] : [recEmail], + hash: publicKey ? publicKey.id.substr(KEY_NAME_SUBSTR).toUpperCase() : '', + key: publicKey })) : []; }).flat().validUnique(encryptKey => encryptKey.hash) diff --git a/dev/View/Popup/Domain.js b/dev/View/Popup/Domain.js index 4a02715c6..1d36cdaaf 100644 --- a/dev/View/Popup/Domain.js +++ b/dev/View/Popup/Domain.js @@ -63,13 +63,13 @@ class DomainPopupView extends AbstractViewPopup { let result = ''; if (this.edit()) { - result = i18n('POPUPS_DOMAIN/TITLE_EDIT_DOMAIN', { 'NAME': name }); + result = i18n('POPUPS_DOMAIN/TITLE_EDIT_DOMAIN', { NAME: name }); if (aliasName) { result += ' ← ' + aliasName; } } else { result = name - ? i18n('POPUPS_DOMAIN/TITLE_ADD_DOMAIN_WITH_NAME', { 'NAME': name }) + ? i18n('POPUPS_DOMAIN/TITLE_ADD_DOMAIN_WITH_NAME', { NAME: name }) : i18n('POPUPS_DOMAIN/TITLE_ADD_DOMAIN'); } @@ -78,7 +78,7 @@ class DomainPopupView extends AbstractViewPopup { domainDesc: () => { const name = this.name(); - return !this.edit() && name ? i18n('POPUPS_DOMAIN/NEW_DOMAIN_DESC', { 'NAME': '*@' + name }) : ''; + return !this.edit() && name ? i18n('POPUPS_DOMAIN/NEW_DOMAIN_DESC', { NAME: '*@' + name }) : ''; }, domainIsComputed: () => { diff --git a/dev/View/Popup/Filter.js b/dev/View/Popup/Filter.js index d22d0d470..88da060d0 100644 --- a/dev/View/Popup/Filter.js +++ b/dev/View/Popup/Filter.js @@ -66,22 +66,22 @@ class FilterPopupView extends AbstractViewPopup { let i18nFilter = key => i18n('POPUPS_FILTER/SELECT_' + key); this.fieldOptions([ - { 'id': FilterConditionField.From, 'name': i18n('GLOBAL/FROM') }, - { 'id': FilterConditionField.Recipient, 'name': i18nFilter('FIELD_RECIPIENTS') }, - { 'id': FilterConditionField.Subject, 'name': i18n('GLOBAL/SUBJECT') }, - { 'id': FilterConditionField.Size, 'name': i18nFilter('FIELD_SIZE') }, - { 'id': FilterConditionField.Header, 'name': i18nFilter('FIELD_HEADER') } + { id: FilterConditionField.From, name: i18n('GLOBAL/FROM') }, + { id: FilterConditionField.Recipient, name: i18nFilter('FIELD_RECIPIENTS') }, + { id: FilterConditionField.Subject, name: i18n('GLOBAL/SUBJECT') }, + { id: FilterConditionField.Size, name: i18nFilter('FIELD_SIZE') }, + { id: FilterConditionField.Header, name: i18nFilter('FIELD_HEADER') } ]); this.typeOptions([ - { 'id': FilterConditionType.Contains, 'name': i18nFilter('TYPE_CONTAINS') }, - { 'id': FilterConditionType.NotContains, 'name': i18nFilter('TYPE_NOT_CONTAINS') }, - { 'id': FilterConditionType.EqualTo, 'name': i18nFilter('TYPE_EQUAL_TO') }, - { 'id': FilterConditionType.NotEqualTo, 'name': i18nFilter('TYPE_NOT_EQUAL_TO') } + { id: FilterConditionType.Contains, name: i18nFilter('TYPE_CONTAINS') }, + { id: FilterConditionType.NotContains, name: i18nFilter('TYPE_NOT_CONTAINS') }, + { id: FilterConditionType.EqualTo, name: i18nFilter('TYPE_EQUAL_TO') }, + { id: FilterConditionType.NotEqualTo, name: i18nFilter('TYPE_NOT_EQUAL_TO') } ]); - // this.actionTypeOptions.push({'id': FilterAction.None, - // 'name': i18n('GLOBAL/NONE')}); + // this.actionTypeOptions.push({id: FilterAction.None, + // name: i18n('GLOBAL/NONE')}); const modules = SieveUserStore.capa; if (modules) { if (modules.includes('imap4flags')) { @@ -90,45 +90,45 @@ class FilterPopupView extends AbstractViewPopup { if (modules.includes('fileinto')) { this.actionTypeOptions.push({ - 'id': FilterAction.MoveTo, - 'name': i18nFilter('ACTION_MOVE_TO') + id: FilterAction.MoveTo, + name: i18nFilter('ACTION_MOVE_TO') }); this.actionTypeOptions.push({ - 'id': FilterAction.Forward, - 'name': i18nFilter('ACTION_FORWARD_TO') + id: FilterAction.Forward, + name: i18nFilter('ACTION_FORWARD_TO') }); } if (modules.includes('reject')) { - this.actionTypeOptions.push({ 'id': FilterAction.Reject, 'name': i18nFilter('ACTION_REJECT') }); + this.actionTypeOptions.push({ id: FilterAction.Reject, name: i18nFilter('ACTION_REJECT') }); } if (modules.includes('vacation')) { this.actionTypeOptions.push({ - 'id': FilterAction.Vacation, - 'name': i18nFilter('ACTION_VACATION_MESSAGE') + id: FilterAction.Vacation, + name: i18nFilter('ACTION_VACATION_MESSAGE') }); } if (modules.includes('body')) { - this.fieldOptions.push({ 'id': FilterConditionField.Body, 'name': i18nFilter('FIELD_BODY') }); + this.fieldOptions.push({ id: FilterConditionField.Body, name: i18nFilter('FIELD_BODY') }); } if (modules.includes('regex')) { - this.typeOptions.push({ 'id': FilterConditionType.Regex, 'name': 'Regex' }); + this.typeOptions.push({ id: FilterConditionType.Regex, name: 'Regex' }); } } - this.actionTypeOptions.push({ 'id': FilterAction.Discard, 'name': i18nFilter('ACTION_DISCARD') }); + this.actionTypeOptions.push({ id: FilterAction.Discard, name: i18nFilter('ACTION_DISCARD') }); this.typeOptionsSize([ - { 'id': FilterConditionType.Over, 'name': i18nFilter('TYPE_OVER') }, - { 'id': FilterConditionType.Under, 'name': i18nFilter('TYPE_UNDER') } + { id: FilterConditionType.Over, name: i18nFilter('TYPE_OVER') }, + { id: FilterConditionType.Under, name: i18nFilter('TYPE_UNDER') } ]); this.typeOptionsBody([ - { 'id': FilterConditionType.Text, 'name': i18nFilter('TYPE_TEXT') }, - { 'id': FilterConditionType.Raw, 'name': i18nFilter('TYPE_RAW') } + { id: FilterConditionType.Text, name: i18nFilter('TYPE_TEXT') }, + { id: FilterConditionType.Raw, name: i18nFilter('TYPE_RAW') } ]); } diff --git a/dev/View/Popup/FolderClear.js b/dev/View/Popup/FolderClear.js index bcfe7dc7f..ce5ccd57c 100644 --- a/dev/View/Popup/FolderClear.js +++ b/dev/View/Popup/FolderClear.js @@ -29,7 +29,7 @@ class FolderClearPopupView extends AbstractViewPopup { return folder ? folder.localName() : ''; }, - dangerDescHtml: () => i18n('POPUPS_CLEAR_FOLDER/DANGER_DESC_HTML_1', { 'FOLDER': this.folderNameForClear() }) + dangerDescHtml: () => i18n('POPUPS_CLEAR_FOLDER/DANGER_DESC_HTML_1', { FOLDER: this.folderNameForClear() }) }); decorateKoCommands(this, { diff --git a/dev/View/Popup/Plugin.js b/dev/View/Popup/Plugin.js index adae75ffa..242d302bb 100644 --- a/dev/View/Popup/Plugin.js +++ b/dev/View/Popup/Plugin.js @@ -74,13 +74,13 @@ class PluginPopupView extends AbstractViewPopup { if (isNonEmptyArray(config)) { this.configures( config.map(item => ({ - 'value': ko.observable(item[0]), - 'placeholder': ko.observable(item[6]), - 'Name': item[1], - 'Type': item[2], - 'Label': item[3], - 'Default': item[4], - 'Desc': item[5] + value: ko.observable(item[0]), + placeholder: ko.observable(item[6]), + Name: item[1], + Type: item[2], + Label: item[3], + Default: item[4], + Desc: item[5] })) ); } diff --git a/dev/View/User/MailBox/MessageList.js b/dev/View/User/MailBox/MessageList.js index 303cdcc36..b1b48ba62 100644 --- a/dev/View/User/MailBox/MessageList.js +++ b/dev/View/User/MailBox/MessageList.js @@ -114,15 +114,15 @@ export class MessageListMailBoxUserView extends AbstractViewRight { }); // append drag and drop - this.dragOver = ko.observable(false).extend({ 'throttle': 1 }); - this.dragOverEnter = ko.observable(false).extend({ 'throttle': 1 }); + this.dragOver = ko.observable(false).extend({ throttle: 1 }); + this.dragOverEnter = ko.observable(false).extend({ throttle: 1 }); this.sLastSearchValue = ''; this.addComputables({ messageListSearchDesc: () => { const value = MessageUserStore.listEndSearch(); - return value ? i18n('MESSAGE_LIST/SEARCH_RESULT_FOR', { 'SEARCH': value }) : '' + return value ? i18n('MESSAGE_LIST/SEARCH_RESULT_FOR', { SEARCH: value }) : '' }, messageListPaginator: computedPaginatorHelper(MessageUserStore.listPage, @@ -871,9 +871,9 @@ export class MessageListMailBoxUserView extends AbstractViewRight { quotaTooltip() { return i18n('MESSAGE_LIST/QUOTA_SIZE', { - 'SIZE': FileInfo.friendlySize(this.userUsageSize()), - 'PROC': this.userUsageProc(), - 'LIMIT': FileInfo.friendlySize(this.userQuota()) + SIZE: FileInfo.friendlySize(this.userUsageSize()), + PROC: this.userUsageProc(), + LIMIT: FileInfo.friendlySize(this.userQuota()) }); } diff --git a/dev/View/User/MailBox/MessageView.js b/dev/View/User/MailBox/MessageView.js index fb22ec0b5..939e0526b 100644 --- a/dev/View/User/MailBox/MessageView.js +++ b/dev/View/User/MailBox/MessageView.js @@ -732,7 +732,7 @@ class MessageViewMailBoxUserView extends AbstractViewRight { oMessage.folder, oMessage.uid, oMessage.readReceipt(), - i18n('READ_RECEIPT/SUBJECT', { 'SUBJECT': oMessage.subject() }), + i18n('READ_RECEIPT/SUBJECT', { SUBJECT: oMessage.subject() }), i18n('READ_RECEIPT/BODY', { 'READ-RECEIPT': AccountUserStore.email() }) ); diff --git a/dev/boot.js b/dev/boot.js index 324afe854..3f988daf2 100644 --- a/dev/boot.js +++ b/dev/boot.js @@ -153,12 +153,6 @@ win.rl = { .then(() => Promise.all([loadScript(appData.TemplatesLink), loadScript(appData.LangLink)])) .then(() => loadScript(appData.StaticAppJsLink)) .then(() => appData.PluginsLink ? loadScript(appData.PluginsLink) : Promise.resolve()) - .then(() => - // Enable the old CKEditor? - (appData.Auth && appData.StaticEditorJsLink) - ? loadScript(appData.StaticEditorJsLink) - : Promise.resolve() - ) .then(() => win.__APP_BOOT ? win.__APP_BOOT(showError) : showError()) .catch(e => { showError(); diff --git a/index.php b/index.php index 5841f0d27..d9b810f64 100644 --- a/index.php +++ b/index.php @@ -4,7 +4,7 @@ if (!defined('APP_VERSION')) { define('APP_VERSION', '0.0.0'); define('APP_INDEX_ROOT_FILE', __FILE__); - define('APP_INDEX_ROOT_PATH', str_replace('\\', '/', rtrim(dirname(__FILE__), '\\/').'/')); + define('APP_INDEX_ROOT_PATH', strtr(__DIR__, DIRECTORY_SEPARATOR, '/') . '/'); } if (file_exists(APP_INDEX_ROOT_PATH.'snappymail/v/'.APP_VERSION.'/include.php')) diff --git a/package.json b/package.json index 7f513d2a9..3e89b199b 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "title": "SnappyMail", "description": "Simple, modern & fast web-based email client", "private": true, - "version": "2.4.1", + "version": "2.4.2", "homepage": "https://snappymail.eu", "author": { "name": "DJ Maze", diff --git a/plugins/ckeditor/ckeditor.js b/plugins/ckeditor/ckeditor.js new file mode 100644 index 000000000..dd0ad7cc0 --- /dev/null +++ b/plugins/ckeditor/ckeditor.js @@ -0,0 +1,93 @@ +(rl => { + if (rl) { + const path = (rl.settings.app('webVersionPath') || 'snappymail/v/' + rl.settings.app('version') + '/'), + script = document.createElement('script'); + script.src = path + 'static/ckeditor/ckeditor.js'; + document.head.append(script); + + rl.createWYSIWYG = (container, onReady) => { + if (!window.CKEDITOR) { + return null; + } + + const + language = (rl.settings.get('Language') || 'en').toLowerCase(), + htmlEditorLangsMap = { + 'ar_sa': 'ar-sa', + 'pt_br': 'pt-br', + 'zh_cn': 'zh-cn', + }, + editor = CKEDITOR.appendTo(container, { + title: false, + stylesSet: false, +// customConfig: '', +// contentsCss: '', + toolbarGroups: [ + { name: 'spec' }, + { name: 'styles' }, + { name: 'basicstyles', groups: ['basicstyles', 'cleanup', 'bidi'] }, + { name: 'colors' }, + { name: 'paragraph', groups: ['list', 'indent', 'blocks', 'align'] }, + { name: 'links' }, + { name: 'insert' }, + { name: 'document', groups: ['mode', 'document', 'doctools'] }, + { name: 'others' } + ], + + removePlugins: 'liststyle' + (rl.settings.app('allowHtmlEditorBitiButtons') ? '' : ',bidi'), + removeButtons: 'Format,Undo,Redo,Cut,Copy,Paste,Anchor,Strike,Subscript,Superscript,Image,SelectAll' + + (rl.settings.app('allowHtmlEditorSourceButton') ? '' : ',Source'), + removeDialogTabs: 'link:advanced;link:target;image:advanced;images:advanced', + + extraPlugins: 'plain,signature', + + allowedContent: true, + extraAllowedContent: true, + + fillEmptyBlocks: false, +// ignoreEmptyParagraph: true, + disableNativeSpellChecker: false, + + colorButton_enableAutomatic: false, +// colorButton_enableMore: true, + + font_defaultLabel: 'Arial', + fontSize_defaultLabel: '13', + fontSize_sizes: '10/10px;12/12px;13/13px;14/14px;16/16px;18/18px;20/20px;24/24px;28/28px;36/36px;48/48px', + + enterMode: CKEDITOR.ENTER_BR, + shiftEnterMode: CKEDITOR.ENTER_P, + language: htmlEditorLangsMap[language] || language.substr(0,2) + }); + + editor.on('key', event => !(event && event.data && 'Tab' == event.data.key)); + + editor.on('drop', event => { + const dt = event.data.dataTransfer, + id = dt.id, + file = dt.getFilesCount() ? dt.getFile(0) : 0; + if (file && id && file.type && file.type.match(/^image/i)) { + const imageId = `[img=${id}]`, + reader = new FileReader(); + + reader.onloadend = () => { + if (reader.result && 'wysiwyg' === editor.mode) { + try { + editor.setData(editor.getData().replace(imageId, ``)); + } catch (e) {} // eslint-disable-line no-empty + } + }; + + reader.readAsDataURL(file); + + dt.setData('text/html', imageId); + } + }); + + editor.on('instanceReady', onReady); + + return editor; + } + } + +})(window.rl); diff --git a/plugins/ckeditor/index.php b/plugins/ckeditor/index.php new file mode 100644 index 000000000..8659d7efc --- /dev/null +++ b/plugins/ckeditor/index.php @@ -0,0 +1,38 @@ +isDir()) { + \mkdir($path . DIRECTORY_SEPARATOR . $iterator->getSubPathName()); + } else { + \copy($item, $path . DIRECTORY_SEPARATOR . $iterator->getSubPathName()); + } + } + } + + if (\is_file("{$path}/ckeditor.js")) { + $this->addJs('ckeditor.js'); + } + } +} diff --git a/vendors/ckeditor/CHANGES.md b/plugins/ckeditor/src/CHANGES.md similarity index 100% rename from vendors/ckeditor/CHANGES.md rename to plugins/ckeditor/src/CHANGES.md diff --git a/vendors/ckeditor/FIXES.txt b/plugins/ckeditor/src/FIXES.txt similarity index 100% rename from vendors/ckeditor/FIXES.txt rename to plugins/ckeditor/src/FIXES.txt diff --git a/vendors/ckeditor/LICENSE.md b/plugins/ckeditor/src/LICENSE.md similarity index 100% rename from vendors/ckeditor/LICENSE.md rename to plugins/ckeditor/src/LICENSE.md diff --git a/vendors/ckeditor/README.md b/plugins/ckeditor/src/README.md similarity index 100% rename from vendors/ckeditor/README.md rename to plugins/ckeditor/src/README.md diff --git a/vendors/ckeditor/build-config.js b/plugins/ckeditor/src/build-config.js similarity index 99% rename from vendors/ckeditor/build-config.js rename to plugins/ckeditor/src/build-config.js index 0f3178ad1..92f79bfe9 100644 --- a/vendors/ckeditor/build-config.js +++ b/plugins/ckeditor/src/build-config.js @@ -1,4 +1,4 @@ -/** +/** * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or http://ckeditor.com/license */ diff --git a/vendors/ckeditor/ckeditor.js b/plugins/ckeditor/src/ckeditor.js similarity index 99% rename from vendors/ckeditor/ckeditor.js rename to plugins/ckeditor/src/ckeditor.js index b35fe49ee..75d808fcf 100644 --- a/vendors/ckeditor/ckeditor.js +++ b/plugins/ckeditor/src/ckeditor.js @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved. For licensing, see LICENSE.md or http://ckeditor.com/license */ diff --git a/vendors/ckeditor/config.js b/plugins/ckeditor/src/config.js similarity index 99% rename from vendors/ckeditor/config.js rename to plugins/ckeditor/src/config.js index 8ab421401..dcf6d7a62 100644 --- a/vendors/ckeditor/config.js +++ b/plugins/ckeditor/src/config.js @@ -1,4 +1,4 @@ -/** +/** * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or http://ckeditor.com/license */ diff --git a/vendors/ckeditor/contents.css b/plugins/ckeditor/src/contents.css similarity index 100% rename from vendors/ckeditor/contents.css rename to plugins/ckeditor/src/contents.css diff --git a/vendors/ckeditor/lang/af.js b/plugins/ckeditor/src/lang/af.js similarity index 100% rename from vendors/ckeditor/lang/af.js rename to plugins/ckeditor/src/lang/af.js diff --git a/vendors/ckeditor/lang/ar.js b/plugins/ckeditor/src/lang/ar.js similarity index 100% rename from vendors/ckeditor/lang/ar.js rename to plugins/ckeditor/src/lang/ar.js diff --git a/vendors/ckeditor/lang/az.js b/plugins/ckeditor/src/lang/az.js similarity index 100% rename from vendors/ckeditor/lang/az.js rename to plugins/ckeditor/src/lang/az.js diff --git a/vendors/ckeditor/lang/bg.js b/plugins/ckeditor/src/lang/bg.js similarity index 100% rename from vendors/ckeditor/lang/bg.js rename to plugins/ckeditor/src/lang/bg.js diff --git a/vendors/ckeditor/lang/bn.js b/plugins/ckeditor/src/lang/bn.js similarity index 100% rename from vendors/ckeditor/lang/bn.js rename to plugins/ckeditor/src/lang/bn.js diff --git a/vendors/ckeditor/lang/bs.js b/plugins/ckeditor/src/lang/bs.js similarity index 100% rename from vendors/ckeditor/lang/bs.js rename to plugins/ckeditor/src/lang/bs.js diff --git a/vendors/ckeditor/lang/ca.js b/plugins/ckeditor/src/lang/ca.js similarity index 100% rename from vendors/ckeditor/lang/ca.js rename to plugins/ckeditor/src/lang/ca.js diff --git a/vendors/ckeditor/lang/cs.js b/plugins/ckeditor/src/lang/cs.js similarity index 100% rename from vendors/ckeditor/lang/cs.js rename to plugins/ckeditor/src/lang/cs.js diff --git a/vendors/ckeditor/lang/cy.js b/plugins/ckeditor/src/lang/cy.js similarity index 100% rename from vendors/ckeditor/lang/cy.js rename to plugins/ckeditor/src/lang/cy.js diff --git a/vendors/ckeditor/lang/da.js b/plugins/ckeditor/src/lang/da.js similarity index 100% rename from vendors/ckeditor/lang/da.js rename to plugins/ckeditor/src/lang/da.js diff --git a/vendors/ckeditor/lang/de-ch.js b/plugins/ckeditor/src/lang/de-ch.js similarity index 100% rename from vendors/ckeditor/lang/de-ch.js rename to plugins/ckeditor/src/lang/de-ch.js diff --git a/vendors/ckeditor/lang/de.js b/plugins/ckeditor/src/lang/de.js similarity index 100% rename from vendors/ckeditor/lang/de.js rename to plugins/ckeditor/src/lang/de.js diff --git a/vendors/ckeditor/lang/el.js b/plugins/ckeditor/src/lang/el.js similarity index 100% rename from vendors/ckeditor/lang/el.js rename to plugins/ckeditor/src/lang/el.js diff --git a/vendors/ckeditor/lang/en-au.js b/plugins/ckeditor/src/lang/en-au.js similarity index 100% rename from vendors/ckeditor/lang/en-au.js rename to plugins/ckeditor/src/lang/en-au.js diff --git a/vendors/ckeditor/lang/en-ca.js b/plugins/ckeditor/src/lang/en-ca.js similarity index 100% rename from vendors/ckeditor/lang/en-ca.js rename to plugins/ckeditor/src/lang/en-ca.js diff --git a/vendors/ckeditor/lang/en-gb.js b/plugins/ckeditor/src/lang/en-gb.js similarity index 100% rename from vendors/ckeditor/lang/en-gb.js rename to plugins/ckeditor/src/lang/en-gb.js diff --git a/vendors/ckeditor/lang/en.js b/plugins/ckeditor/src/lang/en.js similarity index 100% rename from vendors/ckeditor/lang/en.js rename to plugins/ckeditor/src/lang/en.js diff --git a/vendors/ckeditor/lang/eo.js b/plugins/ckeditor/src/lang/eo.js similarity index 100% rename from vendors/ckeditor/lang/eo.js rename to plugins/ckeditor/src/lang/eo.js diff --git a/vendors/ckeditor/lang/es.js b/plugins/ckeditor/src/lang/es.js similarity index 100% rename from vendors/ckeditor/lang/es.js rename to plugins/ckeditor/src/lang/es.js diff --git a/vendors/ckeditor/lang/et.js b/plugins/ckeditor/src/lang/et.js similarity index 100% rename from vendors/ckeditor/lang/et.js rename to plugins/ckeditor/src/lang/et.js diff --git a/vendors/ckeditor/lang/eu.js b/plugins/ckeditor/src/lang/eu.js similarity index 100% rename from vendors/ckeditor/lang/eu.js rename to plugins/ckeditor/src/lang/eu.js diff --git a/vendors/ckeditor/lang/fa.js b/plugins/ckeditor/src/lang/fa.js similarity index 100% rename from vendors/ckeditor/lang/fa.js rename to plugins/ckeditor/src/lang/fa.js diff --git a/vendors/ckeditor/lang/fi.js b/plugins/ckeditor/src/lang/fi.js similarity index 100% rename from vendors/ckeditor/lang/fi.js rename to plugins/ckeditor/src/lang/fi.js diff --git a/vendors/ckeditor/lang/fo.js b/plugins/ckeditor/src/lang/fo.js similarity index 100% rename from vendors/ckeditor/lang/fo.js rename to plugins/ckeditor/src/lang/fo.js diff --git a/vendors/ckeditor/lang/fr-ca.js b/plugins/ckeditor/src/lang/fr-ca.js similarity index 100% rename from vendors/ckeditor/lang/fr-ca.js rename to plugins/ckeditor/src/lang/fr-ca.js diff --git a/vendors/ckeditor/lang/fr.js b/plugins/ckeditor/src/lang/fr.js similarity index 100% rename from vendors/ckeditor/lang/fr.js rename to plugins/ckeditor/src/lang/fr.js diff --git a/vendors/ckeditor/lang/gl.js b/plugins/ckeditor/src/lang/gl.js similarity index 100% rename from vendors/ckeditor/lang/gl.js rename to plugins/ckeditor/src/lang/gl.js diff --git a/vendors/ckeditor/lang/gu.js b/plugins/ckeditor/src/lang/gu.js similarity index 100% rename from vendors/ckeditor/lang/gu.js rename to plugins/ckeditor/src/lang/gu.js diff --git a/vendors/ckeditor/lang/he.js b/plugins/ckeditor/src/lang/he.js similarity index 100% rename from vendors/ckeditor/lang/he.js rename to plugins/ckeditor/src/lang/he.js diff --git a/vendors/ckeditor/lang/hi.js b/plugins/ckeditor/src/lang/hi.js similarity index 100% rename from vendors/ckeditor/lang/hi.js rename to plugins/ckeditor/src/lang/hi.js diff --git a/vendors/ckeditor/lang/hr.js b/plugins/ckeditor/src/lang/hr.js similarity index 100% rename from vendors/ckeditor/lang/hr.js rename to plugins/ckeditor/src/lang/hr.js diff --git a/vendors/ckeditor/lang/hu.js b/plugins/ckeditor/src/lang/hu.js similarity index 100% rename from vendors/ckeditor/lang/hu.js rename to plugins/ckeditor/src/lang/hu.js diff --git a/vendors/ckeditor/lang/id.js b/plugins/ckeditor/src/lang/id.js similarity index 100% rename from vendors/ckeditor/lang/id.js rename to plugins/ckeditor/src/lang/id.js diff --git a/vendors/ckeditor/lang/is.js b/plugins/ckeditor/src/lang/is.js similarity index 100% rename from vendors/ckeditor/lang/is.js rename to plugins/ckeditor/src/lang/is.js diff --git a/vendors/ckeditor/lang/it.js b/plugins/ckeditor/src/lang/it.js similarity index 100% rename from vendors/ckeditor/lang/it.js rename to plugins/ckeditor/src/lang/it.js diff --git a/vendors/ckeditor/lang/ja.js b/plugins/ckeditor/src/lang/ja.js similarity index 100% rename from vendors/ckeditor/lang/ja.js rename to plugins/ckeditor/src/lang/ja.js diff --git a/vendors/ckeditor/lang/ka.js b/plugins/ckeditor/src/lang/ka.js similarity index 100% rename from vendors/ckeditor/lang/ka.js rename to plugins/ckeditor/src/lang/ka.js diff --git a/vendors/ckeditor/lang/km.js b/plugins/ckeditor/src/lang/km.js similarity index 100% rename from vendors/ckeditor/lang/km.js rename to plugins/ckeditor/src/lang/km.js diff --git a/vendors/ckeditor/lang/ko.js b/plugins/ckeditor/src/lang/ko.js similarity index 100% rename from vendors/ckeditor/lang/ko.js rename to plugins/ckeditor/src/lang/ko.js diff --git a/vendors/ckeditor/lang/ku.js b/plugins/ckeditor/src/lang/ku.js similarity index 100% rename from vendors/ckeditor/lang/ku.js rename to plugins/ckeditor/src/lang/ku.js diff --git a/vendors/ckeditor/lang/lt.js b/plugins/ckeditor/src/lang/lt.js similarity index 100% rename from vendors/ckeditor/lang/lt.js rename to plugins/ckeditor/src/lang/lt.js diff --git a/vendors/ckeditor/lang/lv.js b/plugins/ckeditor/src/lang/lv.js similarity index 100% rename from vendors/ckeditor/lang/lv.js rename to plugins/ckeditor/src/lang/lv.js diff --git a/vendors/ckeditor/lang/mk.js b/plugins/ckeditor/src/lang/mk.js similarity index 100% rename from vendors/ckeditor/lang/mk.js rename to plugins/ckeditor/src/lang/mk.js diff --git a/vendors/ckeditor/lang/mn.js b/plugins/ckeditor/src/lang/mn.js similarity index 100% rename from vendors/ckeditor/lang/mn.js rename to plugins/ckeditor/src/lang/mn.js diff --git a/vendors/ckeditor/lang/ms.js b/plugins/ckeditor/src/lang/ms.js similarity index 100% rename from vendors/ckeditor/lang/ms.js rename to plugins/ckeditor/src/lang/ms.js diff --git a/vendors/ckeditor/lang/nb.js b/plugins/ckeditor/src/lang/nb.js similarity index 100% rename from vendors/ckeditor/lang/nb.js rename to plugins/ckeditor/src/lang/nb.js diff --git a/vendors/ckeditor/lang/nl.js b/plugins/ckeditor/src/lang/nl.js similarity index 100% rename from vendors/ckeditor/lang/nl.js rename to plugins/ckeditor/src/lang/nl.js diff --git a/vendors/ckeditor/lang/no.js b/plugins/ckeditor/src/lang/no.js similarity index 100% rename from vendors/ckeditor/lang/no.js rename to plugins/ckeditor/src/lang/no.js diff --git a/vendors/ckeditor/lang/oc.js b/plugins/ckeditor/src/lang/oc.js similarity index 100% rename from vendors/ckeditor/lang/oc.js rename to plugins/ckeditor/src/lang/oc.js diff --git a/vendors/ckeditor/lang/pl.js b/plugins/ckeditor/src/lang/pl.js similarity index 100% rename from vendors/ckeditor/lang/pl.js rename to plugins/ckeditor/src/lang/pl.js diff --git a/vendors/ckeditor/lang/pt-br.js b/plugins/ckeditor/src/lang/pt-br.js similarity index 100% rename from vendors/ckeditor/lang/pt-br.js rename to plugins/ckeditor/src/lang/pt-br.js diff --git a/vendors/ckeditor/lang/pt.js b/plugins/ckeditor/src/lang/pt.js similarity index 100% rename from vendors/ckeditor/lang/pt.js rename to plugins/ckeditor/src/lang/pt.js diff --git a/vendors/ckeditor/lang/ro.js b/plugins/ckeditor/src/lang/ro.js similarity index 100% rename from vendors/ckeditor/lang/ro.js rename to plugins/ckeditor/src/lang/ro.js diff --git a/vendors/ckeditor/lang/ru.js b/plugins/ckeditor/src/lang/ru.js similarity index 100% rename from vendors/ckeditor/lang/ru.js rename to plugins/ckeditor/src/lang/ru.js diff --git a/vendors/ckeditor/lang/si.js b/plugins/ckeditor/src/lang/si.js similarity index 100% rename from vendors/ckeditor/lang/si.js rename to plugins/ckeditor/src/lang/si.js diff --git a/vendors/ckeditor/lang/sk.js b/plugins/ckeditor/src/lang/sk.js similarity index 100% rename from vendors/ckeditor/lang/sk.js rename to plugins/ckeditor/src/lang/sk.js diff --git a/vendors/ckeditor/lang/sl.js b/plugins/ckeditor/src/lang/sl.js similarity index 100% rename from vendors/ckeditor/lang/sl.js rename to plugins/ckeditor/src/lang/sl.js diff --git a/vendors/ckeditor/lang/sq.js b/plugins/ckeditor/src/lang/sq.js similarity index 100% rename from vendors/ckeditor/lang/sq.js rename to plugins/ckeditor/src/lang/sq.js diff --git a/vendors/ckeditor/lang/sr-latn.js b/plugins/ckeditor/src/lang/sr-latn.js similarity index 100% rename from vendors/ckeditor/lang/sr-latn.js rename to plugins/ckeditor/src/lang/sr-latn.js diff --git a/vendors/ckeditor/lang/sr.js b/plugins/ckeditor/src/lang/sr.js similarity index 100% rename from vendors/ckeditor/lang/sr.js rename to plugins/ckeditor/src/lang/sr.js diff --git a/vendors/ckeditor/lang/sv.js b/plugins/ckeditor/src/lang/sv.js similarity index 100% rename from vendors/ckeditor/lang/sv.js rename to plugins/ckeditor/src/lang/sv.js diff --git a/vendors/ckeditor/lang/th.js b/plugins/ckeditor/src/lang/th.js similarity index 100% rename from vendors/ckeditor/lang/th.js rename to plugins/ckeditor/src/lang/th.js diff --git a/vendors/ckeditor/lang/tr.js b/plugins/ckeditor/src/lang/tr.js similarity index 100% rename from vendors/ckeditor/lang/tr.js rename to plugins/ckeditor/src/lang/tr.js diff --git a/vendors/ckeditor/lang/tt.js b/plugins/ckeditor/src/lang/tt.js similarity index 100% rename from vendors/ckeditor/lang/tt.js rename to plugins/ckeditor/src/lang/tt.js diff --git a/vendors/ckeditor/lang/ug.js b/plugins/ckeditor/src/lang/ug.js similarity index 100% rename from vendors/ckeditor/lang/ug.js rename to plugins/ckeditor/src/lang/ug.js diff --git a/vendors/ckeditor/lang/uk.js b/plugins/ckeditor/src/lang/uk.js similarity index 100% rename from vendors/ckeditor/lang/uk.js rename to plugins/ckeditor/src/lang/uk.js diff --git a/vendors/ckeditor/lang/vi.js b/plugins/ckeditor/src/lang/vi.js similarity index 100% rename from vendors/ckeditor/lang/vi.js rename to plugins/ckeditor/src/lang/vi.js diff --git a/vendors/ckeditor/lang/zh-cn.js b/plugins/ckeditor/src/lang/zh-cn.js similarity index 100% rename from vendors/ckeditor/lang/zh-cn.js rename to plugins/ckeditor/src/lang/zh-cn.js diff --git a/vendors/ckeditor/lang/zh.js b/plugins/ckeditor/src/lang/zh.js similarity index 100% rename from vendors/ckeditor/lang/zh.js rename to plugins/ckeditor/src/lang/zh.js diff --git a/vendors/ckeditor/plugins/about/dialogs/about.js b/plugins/ckeditor/src/plugins/about/dialogs/about.js similarity index 100% rename from vendors/ckeditor/plugins/about/dialogs/about.js rename to plugins/ckeditor/src/plugins/about/dialogs/about.js diff --git a/vendors/ckeditor/plugins/about/dialogs/hidpi/logo_ckeditor.png b/plugins/ckeditor/src/plugins/about/dialogs/hidpi/logo_ckeditor.png similarity index 100% rename from vendors/ckeditor/plugins/about/dialogs/hidpi/logo_ckeditor.png rename to plugins/ckeditor/src/plugins/about/dialogs/hidpi/logo_ckeditor.png diff --git a/vendors/ckeditor/plugins/about/dialogs/logo_ckeditor.png b/plugins/ckeditor/src/plugins/about/dialogs/logo_ckeditor.png similarity index 100% rename from vendors/ckeditor/plugins/about/dialogs/logo_ckeditor.png rename to plugins/ckeditor/src/plugins/about/dialogs/logo_ckeditor.png diff --git a/vendors/ckeditor/plugins/base64image/LICENSE.md b/plugins/ckeditor/src/plugins/base64image/LICENSE.md similarity index 100% rename from vendors/ckeditor/plugins/base64image/LICENSE.md rename to plugins/ckeditor/src/plugins/base64image/LICENSE.md diff --git a/vendors/ckeditor/plugins/base64image/README.md b/plugins/ckeditor/src/plugins/base64image/README.md similarity index 100% rename from vendors/ckeditor/plugins/base64image/README.md rename to plugins/ckeditor/src/plugins/base64image/README.md diff --git a/vendors/ckeditor/plugins/base64image/dialogs/base64image.js b/plugins/ckeditor/src/plugins/base64image/dialogs/base64image.js similarity index 100% rename from vendors/ckeditor/plugins/base64image/dialogs/base64image.js rename to plugins/ckeditor/src/plugins/base64image/dialogs/base64image.js diff --git a/vendors/ckeditor/plugins/clipboard/dialogs/paste.js b/plugins/ckeditor/src/plugins/clipboard/dialogs/paste.js similarity index 100% rename from vendors/ckeditor/plugins/clipboard/dialogs/paste.js rename to plugins/ckeditor/src/plugins/clipboard/dialogs/paste.js diff --git a/vendors/ckeditor/plugins/colordialog/dialogs/colordialog.css b/plugins/ckeditor/src/plugins/colordialog/dialogs/colordialog.css similarity index 100% rename from vendors/ckeditor/plugins/colordialog/dialogs/colordialog.css rename to plugins/ckeditor/src/plugins/colordialog/dialogs/colordialog.css diff --git a/vendors/ckeditor/plugins/colordialog/dialogs/colordialog.js b/plugins/ckeditor/src/plugins/colordialog/dialogs/colordialog.js similarity index 100% rename from vendors/ckeditor/plugins/colordialog/dialogs/colordialog.js rename to plugins/ckeditor/src/plugins/colordialog/dialogs/colordialog.js diff --git a/vendors/ckeditor/plugins/dialog/dialogDefinition.js b/plugins/ckeditor/src/plugins/dialog/dialogDefinition.js similarity index 100% rename from vendors/ckeditor/plugins/dialog/dialogDefinition.js rename to plugins/ckeditor/src/plugins/dialog/dialogDefinition.js diff --git a/vendors/ckeditor/plugins/icons.png b/plugins/ckeditor/src/plugins/icons.png similarity index 100% rename from vendors/ckeditor/plugins/icons.png rename to plugins/ckeditor/src/plugins/icons.png diff --git a/vendors/ckeditor/plugins/icons_hidpi.png b/plugins/ckeditor/src/plugins/icons_hidpi.png similarity index 100% rename from vendors/ckeditor/plugins/icons_hidpi.png rename to plugins/ckeditor/src/plugins/icons_hidpi.png diff --git a/vendors/ckeditor/plugins/image/dialogs/image.js b/plugins/ckeditor/src/plugins/image/dialogs/image.js similarity index 100% rename from vendors/ckeditor/plugins/image/dialogs/image.js rename to plugins/ckeditor/src/plugins/image/dialogs/image.js diff --git a/vendors/ckeditor/plugins/image/images/noimage.png b/plugins/ckeditor/src/plugins/image/images/noimage.png similarity index 100% rename from vendors/ckeditor/plugins/image/images/noimage.png rename to plugins/ckeditor/src/plugins/image/images/noimage.png diff --git a/vendors/ckeditor/plugins/image2/dialogs/image2.js b/plugins/ckeditor/src/plugins/image2/dialogs/image2.js similarity index 100% rename from vendors/ckeditor/plugins/image2/dialogs/image2.js rename to plugins/ckeditor/src/plugins/image2/dialogs/image2.js diff --git a/vendors/ckeditor/plugins/link/dialogs/anchor.js b/plugins/ckeditor/src/plugins/link/dialogs/anchor.js similarity index 100% rename from vendors/ckeditor/plugins/link/dialogs/anchor.js rename to plugins/ckeditor/src/plugins/link/dialogs/anchor.js diff --git a/vendors/ckeditor/plugins/link/dialogs/link.js b/plugins/ckeditor/src/plugins/link/dialogs/link.js similarity index 100% rename from vendors/ckeditor/plugins/link/dialogs/link.js rename to plugins/ckeditor/src/plugins/link/dialogs/link.js diff --git a/vendors/ckeditor/plugins/link/images/anchor.png b/plugins/ckeditor/src/plugins/link/images/anchor.png similarity index 100% rename from vendors/ckeditor/plugins/link/images/anchor.png rename to plugins/ckeditor/src/plugins/link/images/anchor.png diff --git a/vendors/ckeditor/plugins/link/images/hidpi/anchor.png b/plugins/ckeditor/src/plugins/link/images/hidpi/anchor.png similarity index 100% rename from vendors/ckeditor/plugins/link/images/hidpi/anchor.png rename to plugins/ckeditor/src/plugins/link/images/hidpi/anchor.png diff --git a/vendors/ckeditor-plugins/plain/icons/hidpi/plain-rtl.png b/plugins/ckeditor/src/plugins/plain/icons/hidpi/plain-rtl.png similarity index 100% rename from vendors/ckeditor-plugins/plain/icons/hidpi/plain-rtl.png rename to plugins/ckeditor/src/plugins/plain/icons/hidpi/plain-rtl.png diff --git a/vendors/ckeditor-plugins/plain/icons/hidpi/plain.png b/plugins/ckeditor/src/plugins/plain/icons/hidpi/plain.png similarity index 100% rename from vendors/ckeditor-plugins/plain/icons/hidpi/plain.png rename to plugins/ckeditor/src/plugins/plain/icons/hidpi/plain.png diff --git a/vendors/ckeditor-plugins/plain/icons/plain-rtl.png b/plugins/ckeditor/src/plugins/plain/icons/plain-rtl.png similarity index 100% rename from vendors/ckeditor-plugins/plain/icons/plain-rtl.png rename to plugins/ckeditor/src/plugins/plain/icons/plain-rtl.png diff --git a/vendors/ckeditor-plugins/plain/icons/plain.png b/plugins/ckeditor/src/plugins/plain/icons/plain.png similarity index 100% rename from vendors/ckeditor-plugins/plain/icons/plain.png rename to plugins/ckeditor/src/plugins/plain/icons/plain.png diff --git a/plugins/ckeditor/src/plugins/plain/plain/icons/hidpi/plain-rtl.png b/plugins/ckeditor/src/plugins/plain/plain/icons/hidpi/plain-rtl.png new file mode 100644 index 000000000..adf4af3c9 Binary files /dev/null and b/plugins/ckeditor/src/plugins/plain/plain/icons/hidpi/plain-rtl.png differ diff --git a/plugins/ckeditor/src/plugins/plain/plain/icons/hidpi/plain.png b/plugins/ckeditor/src/plugins/plain/plain/icons/hidpi/plain.png new file mode 100644 index 000000000..b4d0a15a4 Binary files /dev/null and b/plugins/ckeditor/src/plugins/plain/plain/icons/hidpi/plain.png differ diff --git a/plugins/ckeditor/src/plugins/plain/plain/icons/plain-rtl.png b/plugins/ckeditor/src/plugins/plain/plain/icons/plain-rtl.png new file mode 100644 index 000000000..27d1ba881 Binary files /dev/null and b/plugins/ckeditor/src/plugins/plain/plain/icons/plain-rtl.png differ diff --git a/plugins/ckeditor/src/plugins/plain/plain/icons/plain.png b/plugins/ckeditor/src/plugins/plain/plain/icons/plain.png new file mode 100644 index 000000000..e44db3798 Binary files /dev/null and b/plugins/ckeditor/src/plugins/plain/plain/icons/plain.png differ diff --git a/vendors/ckeditor-plugins/plain/plugin.js b/plugins/ckeditor/src/plugins/plain/plain/plugin.js similarity index 100% rename from vendors/ckeditor-plugins/plain/plugin.js rename to plugins/ckeditor/src/plugins/plain/plain/plugin.js diff --git a/plugins/ckeditor/src/plugins/plain/plugin.js b/plugins/ckeditor/src/plugins/plain/plugin.js new file mode 100644 index 000000000..a88e9702e --- /dev/null +++ b/plugins/ckeditor/src/plugins/plain/plugin.js @@ -0,0 +1,170 @@ + +(function() { + + var + selectRange = function (el, start, end) { + if (!el) { + return; + } + if (end === undefined) { + end = start; + } + if('selectionStart' in el) { + el.selectionStart = start; + el.selectionEnd = end; + } else if(el.setSelectionRange) { + el.setSelectionRange(start, end); + } else if(el.createTextRange) { + var range = el.createTextRange(); + range.collapse(true); + range.moveEnd('character', end); + range.moveStart('character', start); + range.select(); + } + }, + toTop = function (el) { + selectRange(el, 0); + if (el) { + el.scrollTop = 0; + } + } + ; + + CKEDITOR.plugins.add('plain', { + lang: '', + icons: 'plain', + hidpi: true, + init: function(editor) + { + if (editor.elementMode === CKEDITOR.ELEMENT_MODE_INLINE) { + return; + } + + editor.__textUtils = { + plainToHtml: data => rl.Utils.plainToHtml(data, true), + htmlToPlain: data => rl.Utils.htmlToPlain(data, true) + }; + + var plain = CKEDITOR.plugins.plain; + editor.addMode('plain', function(callback) { + + var + contentsSpace = editor.ui.space('contents'), + textarea = contentsSpace.getDocument().createElement('textarea') + ; + + textarea.setStyles( + CKEDITOR.tools.extend({ + width: CKEDITOR.env.ie7Compat ? '99%' : '100%', + height: '100%', + resize: 'none', + outline: 'none', + 'text-align': 'left' + }, + CKEDITOR.tools.cssVendorPrefix('tab-size', 4))) + ; + + textarea.setAttribute('dir', 'ltr'); + textarea.addClass('cke_plain'); + + CKEDITOR.plugins.clipboard.preventDefaultDropOnElement(textarea); + + contentsSpace.append(textarea); + + var editable = editor.editable(new plainEditable(editor, textarea)); + + editable.setData(editor.getData(1)); + editor.__plain = editable; + editor.__textarea = textarea.$; + + if (CKEDITOR.env.ie) { + editable.attachListener(editor, 'resize', onResize, editable); + editable.attachListener(CKEDITOR.document.getWindow(), 'resize', onResize, editable); + CKEDITOR.tools.setTimeout(onResize, 0, editable); + } + + editor.fire('ariaWidget', this); + callback(); + }); + + editor.addCommand('plain', plain.commands.plain); + + if (editor.ui.addButton) { + editor.ui.addButton('plain', { + label: window.rl && window.rl.i18n ? window.rl.i18n('EDITOR/TEXT_SWITCHER_PLAINT_TEXT') : 'Plain', + command: 'plain', + toolbar: 'spec,10' + }); + } + + editor.on('mode', function() { + editor.getCommand('plain').setState(editor.mode === 'plain' ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF); + editor.editable().addClass('cke_enable_context_menu'); + + editor.focus(); + + if (editor.mode === 'plain') { + toTop(editor.__textarea); + } + }); + + function onResize() { + this.hide(); + this.setStyle('height', this.getParent().$.clientHeight + 'px'); + this.setStyle('width', this.getParent().$.clientWidth + 'px'); + this.show(); + } + } + }); + + var plainEditable = CKEDITOR.tools.createClass({ + base: CKEDITOR.editable, + proto: { + setData: function(data) { + this.setValue(this.editor.__textUtils.htmlToPlain(data)); + this.editor.fire('dataReady'); + }, + setRawData: function(data) { + this.setValue(data); + this.editor.fire('dataReady'); + }, + getData: function() { + return this.editor.__textUtils.plainToHtml(this.getValue()); + }, + getRawData: function() { + return this.getValue(); + }, + insertHtml: function() {}, + insertElement: function() {}, + insertText: function() {}, + setReadOnly: function( isReadOnly ) { + this[(isReadOnly ? 'set' : 'remove') + 'Attribute' ]('readOnly', 'readonly'); + }, + detach: function() { + plainEditable.baseProto.detach.call( this ); + this.clearCustomData(); + this.remove(); + } + } + }); + + CKEDITOR.plugins.plain = { + commands: { + plain: { + modes: { + wysiwyg: 1, plain: 1 + }, + editorFocus: true, + readOnly: false, + exec: function(editor) { + if (editor.mode === 'wysiwyg') { + editor.fire('saveSnapshot'); + } + editor.getCommand('plain').setState(CKEDITOR.TRISTATE_DISABLED); + editor.setMode(editor.mode === 'plain' ? 'wysiwyg' : 'plain'); + }, + canUndo: false + } + } + }; +}()); diff --git a/vendors/ckeditor/plugins/quicktable/CHANGELOG.md b/plugins/ckeditor/src/plugins/quicktable/CHANGELOG.md similarity index 100% rename from vendors/ckeditor/plugins/quicktable/CHANGELOG.md rename to plugins/ckeditor/src/plugins/quicktable/CHANGELOG.md diff --git a/vendors/ckeditor/plugins/quicktable/Gruntfile.js b/plugins/ckeditor/src/plugins/quicktable/Gruntfile.js similarity index 100% rename from vendors/ckeditor/plugins/quicktable/Gruntfile.js rename to plugins/ckeditor/src/plugins/quicktable/Gruntfile.js diff --git a/vendors/ckeditor/plugins/quicktable/LICENSE b/plugins/ckeditor/src/plugins/quicktable/LICENSE similarity index 100% rename from vendors/ckeditor/plugins/quicktable/LICENSE rename to plugins/ckeditor/src/plugins/quicktable/LICENSE diff --git a/vendors/ckeditor/plugins/quicktable/README.md b/plugins/ckeditor/src/plugins/quicktable/README.md similarity index 100% rename from vendors/ckeditor/plugins/quicktable/README.md rename to plugins/ckeditor/src/plugins/quicktable/README.md diff --git a/vendors/ckeditor/plugins/quicktable/package.json b/plugins/ckeditor/src/plugins/quicktable/package.json similarity index 100% rename from vendors/ckeditor/plugins/quicktable/package.json rename to plugins/ckeditor/src/plugins/quicktable/package.json diff --git a/vendors/ckeditor/plugins/quicktable/template.jst b/plugins/ckeditor/src/plugins/quicktable/template.jst similarity index 100% rename from vendors/ckeditor/plugins/quicktable/template.jst rename to plugins/ckeditor/src/plugins/quicktable/template.jst diff --git a/vendors/ckeditor-plugins/signature/plugin.js b/plugins/ckeditor/src/plugins/signature/plugin.js similarity index 100% rename from vendors/ckeditor-plugins/signature/plugin.js rename to plugins/ckeditor/src/plugins/signature/plugin.js diff --git a/plugins/ckeditor/src/plugins/signature/signature/plugin.js b/plugins/ckeditor/src/plugins/signature/signature/plugin.js new file mode 100644 index 000000000..8a7fd37e1 --- /dev/null +++ b/plugins/ckeditor/src/plugins/signature/signature/plugin.js @@ -0,0 +1,141 @@ + +(function(CKEDITOR) { + + 'use strict'; + + var rl_signature_replacer = function(editor, text, signature, isHtml, insertBefore) { + + var + skipInsert = false, + isEmptyText = false, + newLine = (isHtml ? '' : "\n"), + clearHtmlLine = function(html) { + return editor.__textUtils.htmlToPlain(html).trim(); + }; + + isEmptyText = !text.trim(); + if (!isEmptyText && isHtml) + { + isEmptyText = !clearHtmlLine(text); + } + + if (editor.__previos_signature && !isEmptyText) + { + if (isHtml && !editor.__previos_signature_is_html) + { + editor.__previos_signature = editor.__textUtils.plainToHtml(editor.__previos_signature); + editor.__previos_signature_is_html = true; + } + else if (!isHtml && editor.__previos_signature_is_html) + { + editor.__previos_signature = editor.__textUtils.htmlToPlain(editor.__previos_signature); + editor.__previos_signature_is_html = false; + } + + skipInsert = false; + if (isHtml) + { + var clearSig = clearHtmlLine(editor.__previos_signature); + text = text.replace(/([\s\S]*)<\/signature>/igm, function(all){ + var c = clearSig === clearHtmlLine(all); + if (!c) { + skipInsert = true; + } + return c ? '' : all; + }); + } + else + { + var textLen = text.length; + text = text + .replace('' + editor.__previos_signature, '') + .replace('' + editor.__previos_signature, ''); + + if (textLen === text.length) + { + skipInsert = true; + } + } + } + + if (!skipInsert) + { + signature = newLine + newLine + (isHtml ? '' : '') + signature + (isHtml ? '' : ''); + + text = insertBefore ? signature + text : text + signature; + + if (10 < signature.length) + { + editor.__previos_signature = signature; + editor.__previos_signature_is_html = isHtml; + } + } + + return text; + }; + + CKEDITOR.plugins.add('signature', { + init: function(editor) { + editor.addCommand('insertSignature', { + modes: {wysiwyg: 1, plain: 1}, + exec: function(editor, cfg) { + + if (cfg && cfg.clearCache) + { + editor.__previos_signature = undefined; + editor.__previos_signature_is_html = undefined; + return true; + } + + var + bIsHtml = false, + bInsertBefore = false, + sSignature = '', + sResultSignature = ''; + + if (cfg) + { + bIsHtml = undefined === cfg.isHtml ? false : !!cfg.isHtml; + bInsertBefore = undefined === cfg.insertBefore ? false : !!cfg.insertBefore; + sSignature = undefined === cfg.signature ? '' : cfg.signature; + } + + sResultSignature = sSignature; + + try + { + if ('plain' === editor.mode && editor.__plain && editor.__textUtils) + { + if (editor.__textUtils && editor.__textUtils.htmlToPlain) + { + if (bIsHtml) + { + sResultSignature = editor.__textUtils.htmlToPlain(sResultSignature); + } + } + + editor.__plain.setRawData( + rl_signature_replacer(editor, editor.__plain.getRawData(), sResultSignature, false, bInsertBefore)); + + } + else + { + if (editor.__textUtils && editor.__textUtils.plainToHtml) + { + if (!bIsHtml) + { + sResultSignature = editor.__textUtils.plainToHtml(sResultSignature); + } + } + + editor.setData( + rl_signature_replacer(editor, editor.getData(), sResultSignature, true, bInsertBefore)); + } + } + catch (e) {} + } + }); + } + }); + +}(CKEDITOR)); diff --git a/vendors/ckeditor/plugins/table/dialogs/table.js b/plugins/ckeditor/src/plugins/table/dialogs/table.js similarity index 100% rename from vendors/ckeditor/plugins/table/dialogs/table.js rename to plugins/ckeditor/src/plugins/table/dialogs/table.js diff --git a/vendors/ckeditor/plugins/widget/images/handle.png b/plugins/ckeditor/src/plugins/widget/images/handle.png similarity index 100% rename from vendors/ckeditor/plugins/widget/images/handle.png rename to plugins/ckeditor/src/plugins/widget/images/handle.png diff --git a/vendors/ckeditor/skins/moono-lisa/dialog.css b/plugins/ckeditor/src/skins/moono-lisa/dialog.css similarity index 100% rename from vendors/ckeditor/skins/moono-lisa/dialog.css rename to plugins/ckeditor/src/skins/moono-lisa/dialog.css diff --git a/vendors/ckeditor/skins/moono-lisa/dialog_ie.css b/plugins/ckeditor/src/skins/moono-lisa/dialog_ie.css similarity index 100% rename from vendors/ckeditor/skins/moono-lisa/dialog_ie.css rename to plugins/ckeditor/src/skins/moono-lisa/dialog_ie.css diff --git a/vendors/ckeditor/skins/moono-lisa/dialog_ie8.css b/plugins/ckeditor/src/skins/moono-lisa/dialog_ie8.css similarity index 100% rename from vendors/ckeditor/skins/moono-lisa/dialog_ie8.css rename to plugins/ckeditor/src/skins/moono-lisa/dialog_ie8.css diff --git a/vendors/ckeditor/skins/moono-lisa/dialog_iequirks.css b/plugins/ckeditor/src/skins/moono-lisa/dialog_iequirks.css similarity index 100% rename from vendors/ckeditor/skins/moono-lisa/dialog_iequirks.css rename to plugins/ckeditor/src/skins/moono-lisa/dialog_iequirks.css diff --git a/vendors/ckeditor/skins/moono-lisa/editor.css b/plugins/ckeditor/src/skins/moono-lisa/editor.css similarity index 100% rename from vendors/ckeditor/skins/moono-lisa/editor.css rename to plugins/ckeditor/src/skins/moono-lisa/editor.css diff --git a/vendors/ckeditor/skins/moono-lisa/editor_gecko.css b/plugins/ckeditor/src/skins/moono-lisa/editor_gecko.css similarity index 100% rename from vendors/ckeditor/skins/moono-lisa/editor_gecko.css rename to plugins/ckeditor/src/skins/moono-lisa/editor_gecko.css diff --git a/vendors/ckeditor/skins/moono-lisa/editor_ie.css b/plugins/ckeditor/src/skins/moono-lisa/editor_ie.css similarity index 100% rename from vendors/ckeditor/skins/moono-lisa/editor_ie.css rename to plugins/ckeditor/src/skins/moono-lisa/editor_ie.css diff --git a/vendors/ckeditor/skins/moono-lisa/editor_ie8.css b/plugins/ckeditor/src/skins/moono-lisa/editor_ie8.css similarity index 100% rename from vendors/ckeditor/skins/moono-lisa/editor_ie8.css rename to plugins/ckeditor/src/skins/moono-lisa/editor_ie8.css diff --git a/vendors/ckeditor/skins/moono-lisa/editor_iequirks.css b/plugins/ckeditor/src/skins/moono-lisa/editor_iequirks.css similarity index 100% rename from vendors/ckeditor/skins/moono-lisa/editor_iequirks.css rename to plugins/ckeditor/src/skins/moono-lisa/editor_iequirks.css diff --git a/vendors/ckeditor/skins/moono-lisa/icons.png b/plugins/ckeditor/src/skins/moono-lisa/icons.png similarity index 100% rename from vendors/ckeditor/skins/moono-lisa/icons.png rename to plugins/ckeditor/src/skins/moono-lisa/icons.png diff --git a/vendors/ckeditor/skins/moono-lisa/icons_hidpi.png b/plugins/ckeditor/src/skins/moono-lisa/icons_hidpi.png similarity index 100% rename from vendors/ckeditor/skins/moono-lisa/icons_hidpi.png rename to plugins/ckeditor/src/skins/moono-lisa/icons_hidpi.png diff --git a/vendors/ckeditor/skins/moono-lisa/images/arrow.png b/plugins/ckeditor/src/skins/moono-lisa/images/arrow.png similarity index 100% rename from vendors/ckeditor/skins/moono-lisa/images/arrow.png rename to plugins/ckeditor/src/skins/moono-lisa/images/arrow.png diff --git a/vendors/ckeditor/skins/moono-lisa/images/close.png b/plugins/ckeditor/src/skins/moono-lisa/images/close.png similarity index 100% rename from vendors/ckeditor/skins/moono-lisa/images/close.png rename to plugins/ckeditor/src/skins/moono-lisa/images/close.png diff --git a/vendors/ckeditor/skins/moono-lisa/images/hidpi/close.png b/plugins/ckeditor/src/skins/moono-lisa/images/hidpi/close.png similarity index 100% rename from vendors/ckeditor/skins/moono-lisa/images/hidpi/close.png rename to plugins/ckeditor/src/skins/moono-lisa/images/hidpi/close.png diff --git a/vendors/ckeditor/skins/moono-lisa/images/hidpi/lock-open.png b/plugins/ckeditor/src/skins/moono-lisa/images/hidpi/lock-open.png similarity index 100% rename from vendors/ckeditor/skins/moono-lisa/images/hidpi/lock-open.png rename to plugins/ckeditor/src/skins/moono-lisa/images/hidpi/lock-open.png diff --git a/vendors/ckeditor/skins/moono-lisa/images/hidpi/lock.png b/plugins/ckeditor/src/skins/moono-lisa/images/hidpi/lock.png similarity index 100% rename from vendors/ckeditor/skins/moono-lisa/images/hidpi/lock.png rename to plugins/ckeditor/src/skins/moono-lisa/images/hidpi/lock.png diff --git a/vendors/ckeditor/skins/moono-lisa/images/hidpi/refresh.png b/plugins/ckeditor/src/skins/moono-lisa/images/hidpi/refresh.png similarity index 100% rename from vendors/ckeditor/skins/moono-lisa/images/hidpi/refresh.png rename to plugins/ckeditor/src/skins/moono-lisa/images/hidpi/refresh.png diff --git a/vendors/ckeditor/skins/moono-lisa/images/lock-open.png b/plugins/ckeditor/src/skins/moono-lisa/images/lock-open.png similarity index 100% rename from vendors/ckeditor/skins/moono-lisa/images/lock-open.png rename to plugins/ckeditor/src/skins/moono-lisa/images/lock-open.png diff --git a/vendors/ckeditor/skins/moono-lisa/images/lock.png b/plugins/ckeditor/src/skins/moono-lisa/images/lock.png similarity index 100% rename from vendors/ckeditor/skins/moono-lisa/images/lock.png rename to plugins/ckeditor/src/skins/moono-lisa/images/lock.png diff --git a/vendors/ckeditor/skins/moono-lisa/images/refresh.png b/plugins/ckeditor/src/skins/moono-lisa/images/refresh.png similarity index 100% rename from vendors/ckeditor/skins/moono-lisa/images/refresh.png rename to plugins/ckeditor/src/skins/moono-lisa/images/refresh.png diff --git a/vendors/ckeditor/skins/moono-lisa/images/spinner.gif b/plugins/ckeditor/src/skins/moono-lisa/images/spinner.gif similarity index 100% rename from vendors/ckeditor/skins/moono-lisa/images/spinner.gif rename to plugins/ckeditor/src/skins/moono-lisa/images/spinner.gif diff --git a/vendors/ckeditor/skins/moono-lisa/readme.md b/plugins/ckeditor/src/skins/moono-lisa/readme.md similarity index 100% rename from vendors/ckeditor/skins/moono-lisa/readme.md rename to plugins/ckeditor/src/skins/moono-lisa/readme.md diff --git a/vendors/ckeditor/styles.js b/plugins/ckeditor/src/styles.js similarity index 99% rename from vendors/ckeditor/styles.js rename to plugins/ckeditor/src/styles.js index b76fa3fa7..e1cd4d4f0 100644 --- a/vendors/ckeditor/styles.js +++ b/plugins/ckeditor/src/styles.js @@ -1,4 +1,4 @@ -/** +/** * Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or http://ckeditor.com/license */ diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Log/Drivers/Syslog.php b/snappymail/v/0.0.0/app/libraries/MailSo/Log/Drivers/Syslog.php index 88361c2e2..842c66ac5 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Log/Drivers/Syslog.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Log/Drivers/Syslog.php @@ -24,31 +24,18 @@ class Syslog extends \MailSo\Log\Driver { parent::__construct(); - if (\function_exists('openlog') && \function_exists('closelog') && \defined('LOG_ODELAY') && \defined('LOG_USER')) - { + if (\is_callable('openlog')) { $this->iLogLevel = \defined('LOG_INFO') ? LOG_INFO : 6; } - else - { - $this->iLogLevel = null; - } } protected function writeImplementation($mDesc) : bool { - if (null === $this->iLogLevel) - { - return false; + $result = false; + if ($this->iLogLevel && \openlog('snappymail', LOG_ODELAY, LOG_USER)) { + $result = \syslog($this->iLogLevel, \is_array($mDesc) ? \implode(PHP_EOL, $mDesc) : $mDesc); + \closelog(); } - - if (\is_array($mDesc)) - { - $mDesc = \implode($this->sNewLine, $mDesc); - } - - \openlog('snappymail', LOG_ODELAY, LOG_USER); - $result = \syslog($this->iLogLevel, $mDesc); - \closelog(); return $result; } diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions.php index 5afcafd47..9da2246c4 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions.php @@ -773,8 +773,8 @@ class Actions $sLogFileFullPath = \APP_PRIVATE_DATA . 'logs/' . $this->compileLogFileName($sLogFileName); $sLogFileDir = \dirname($sLogFileFullPath); - if (!is_dir($sLogFileDir)) { - mkdir($sLogFileDir, 0755, true); + if (!\is_dir($sLogFileDir)) { + \mkdir($sLogFileDir, 0755, true); } $oDriver = new \MailSo\Log\Drivers\File($sLogFileFullPath); @@ -1009,7 +1009,6 @@ class Actions 'useImapThread' => (bool)$oConfig->Get('labs', 'use_imap_thread', false), 'useImapSubscribe' => (bool)$oConfig->Get('labs', 'use_imap_list_subscribe', true), 'allowAppendMessage' => (bool)$oConfig->Get('labs', 'allow_message_append', false), - 'materialDesign' => (bool)$oConfig->Get('labs', 'use_material_design', true), 'folderSpecLimit' => (int)$oConfig->Get('labs', 'folders_spec_limit', 50), 'faviconStatus' => (bool)$oConfig->Get('labs', 'favicon_status', true), 'listPermanentFiltered' => '' !== \trim(Api::Config()->Get('labs', 'imap_message_list_permanent_filter', '')), @@ -1311,12 +1310,8 @@ class Actions $aResult['StaticAppJsLink'] = $this->StaticPath('js/' . ($bAppJsDebug ? '' : 'min/') . ($bAdmin ? 'admin' : 'app') . ($bAppJsDebug ? '' : '.min') . '.js'); - if ($this->Config()->Get('labs', 'use_ck_html_editor', false)) { - $aResult['StaticEditorJsLink'] = $this->StaticPath('ckeditor/ckeditor.js'); - } - - $aResult['EditorDefaultType'] = \in_array($aResult['EditorDefaultType'], array('Plain', 'Html', 'HtmlForced', 'PlainForced')) ? - $aResult['EditorDefaultType'] : 'Plain'; + $aResult['EditorDefaultType'] = \in_array($aResult['EditorDefaultType'], array('Plain', 'Html', 'HtmlForced', 'PlainForced')) + ? $aResult['EditorDefaultType'] : 'Plain'; // IDN $aResult['Email'] = \MailSo\Base\Utils::IdnToUtf8($aResult['Email']); diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Common/PdoAbstract.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Common/PdoAbstract.php index 1ee11818a..08bb2fb36 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Common/PdoAbstract.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Common/PdoAbstract.php @@ -368,9 +368,11 @@ abstract class PdoAbstract { case 'mysql': $aQ[] = 'CREATE TABLE IF NOT EXISTS rainloop_system ( +id bigint UNSIGNED NOT NULL AUTO_INCREMENT, sys_name varchar(50) NOT NULL, value_int int UNSIGNED NOT NULL DEFAULT 0, value_str varchar(128) NOT NULL DEFAULT \'\', +PRIMARY KEY(id), INDEX sys_name_rainloop_system_index (sys_name) ) /*!40000 ENGINE=INNODB *//*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;'; $aQ[] = 'CREATE TABLE IF NOT EXISTS rainloop_users ( diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Config/Application.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Config/Application.php index 2abbdfba5..b1e32a6e5 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Config/Application.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Config/Application.php @@ -329,7 +329,6 @@ Enables caching in the system'), 'use_imap_thread' => array(true), 'use_imap_move' => array(false), 'use_imap_expunge_all_on_delete' => array(false), - 'use_ck_html_editor' => array(false), 'imap_forwarded_flag' => array('$Forwarded'), 'imap_read_receipt_flag' => array('$ReadReceipt'), 'imap_body_text_limit' => array(555000), diff --git a/snappymail/v/0.0.0/app/templates/Views/Admin/AdminLogin.html b/snappymail/v/0.0.0/app/templates/Views/Admin/AdminLogin.html index 301d427fc..7b3a51ab1 100644 --- a/snappymail/v/0.0.0/app/templates/Views/Admin/AdminLogin.html +++ b/snappymail/v/0.0.0/app/templates/Views/Admin/AdminLogin.html @@ -23,7 +23,7 @@ autocomplete="current-password" autocorrect="off" autocapitalize="off" spellcheck="false" data-i18n="[placeholder]LOGIN/LABEL_PASSWORD" data-bind="textInput: password, disable: submitRequest" /> - + 🔑 ❯ diff --git a/snappymail/v/0.0.0/app/templates/Views/User/Login.html b/snappymail/v/0.0.0/app/templates/Views/User/Login.html index b2707d124..1c6ba6e93 100644 --- a/snappymail/v/0.0.0/app/templates/Views/User/Login.html +++ b/snappymail/v/0.0.0/app/templates/Views/User/Login.html @@ -1,7 +1,6 @@ - + @@ -15,8 +14,7 @@ - + + data-bind="command: submitCommand" data-i18n="[title]LOGIN/BUTTON_SIGN_IN"> 🔑 ❯ - + 🔑 - + + @@ -70,7 +67,7 @@ + data-bind="visible: allowLanguagesOnLogin, click: selectLanguage" data-i18n="[title]POPUPS_LANGUAGES/TITLE_LANGUAGES"> 🌍 diff --git a/snappymail/v/0.0.0/app/templates/Views/User/MailFolderList.html b/snappymail/v/0.0.0/app/templates/Views/User/MailFolderList.html index 8de19ff06..081c655f4 100644 --- a/snappymail/v/0.0.0/app/templates/Views/User/MailFolderList.html +++ b/snappymail/v/0.0.0/app/templates/Views/User/MailFolderList.html @@ -1,10 +1,10 @@ - + - 📇 + 📇 @@ -24,7 +24,7 @@ - + ⚙ diff --git a/snappymail/v/0.0.0/app/templates/Views/User/MailMessageList.html b/snappymail/v/0.0.0/app/templates/Views/User/MailMessageList.html index 9c08419c0..b00eab42d 100644 --- a/snappymail/v/0.0.0/app/templates/Views/User/MailMessageList.html +++ b/snappymail/v/0.0.0/app/templates/Views/User/MailMessageList.html @@ -5,15 +5,15 @@ ❮ ❯ - + - + - + 📁 @@ -27,7 +27,7 @@ - + 📁 @@ -35,19 +35,19 @@ + data-bind="visible: isArchiveVisible, command: archiveCommand" data-i18n="[title]GLOBAL/TO_ARCHIVE"> - ⚠ + ⚠ + data-bind="visible: isUnSpamVisible, command: notSpamCommand" data-i18n="[title]GLOBAL/NOT_SPAM"> 🗑 + data-bind="command: deleteCommand" data-i18n="[title]GLOBAL/DELETE">🗑 - ☰ + ☰ diff --git a/snappymail/v/0.0.0/app/templates/Views/User/MailMessageView.html b/snappymail/v/0.0.0/app/templates/Views/User/MailMessageView.html index 62b0f23e4..7567056f4 100644 --- a/snappymail/v/0.0.0/app/templates/Views/User/MailMessageView.html +++ b/snappymail/v/0.0.0/app/templates/Views/User/MailMessageView.html @@ -2,21 +2,21 @@ - + ✖ - + 🖉 - + - ⚠ - + ⚠ + - 🗑 + 🗑 ❮ @@ -46,11 +46,11 @@ ← + data-bind="visible: 'reply' === lastReplyAction() && allowComposer, command: replyCommand" data-i18n="[title]MESSAGE/BUTTON_REPLY">← ↞ + data-bind="visible: 'replyall' === lastReplyAction() && allowComposer, command: replyAllCommand" data-i18n="[title]MESSAGE/BUTTON_REPLY_ALL">↞ → + data-bind="visible: 'forward' === lastReplyAction() && allowComposer, command: forwardCommand" data-i18n="[title]MESSAGE/BUTTON_FORWARD">→ ▾ @@ -157,7 +157,7 @@ - + 🖉 diff --git a/snappymail/v/0.0.0/app/templates/Views/User/PopupsCompose.html b/snappymail/v/0.0.0/app/templates/Views/User/PopupsCompose.html index 4f1a513a6..1dfc0e149 100644 --- a/snappymail/v/0.0.0/app/templates/Views/User/PopupsCompose.html +++ b/snappymail/v/0.0.0/app/templates/Views/User/PopupsCompose.html @@ -9,8 +9,8 @@ - × - + × + 🗑 @@ -76,7 +76,7 @@ - 📇 + 📇 @@ -163,7 +163,7 @@ + data-bind="visible: addAttachmentEnabled(), initDom: composeUploaderButton" data-i18n="[title]COMPOSE/ATTACH_FILES"> + diff --git a/snappymail/v/0.0.0/app/templates/Views/User/PopupsContacts.html b/snappymail/v/0.0.0/app/templates/Views/User/PopupsContacts.html index a7451f68f..86e2033df 100644 --- a/snappymail/v/0.0.0/app/templates/Views/User/PopupsContacts.html +++ b/snappymail/v/0.0.0/app/templates/Views/User/PopupsContacts.html @@ -171,7 +171,7 @@ - @ + @ @@ -185,7 +185,7 @@ - 📞 + 📞 @@ -198,7 +198,7 @@ - 🌍 + 🌍 @@ -212,7 +212,7 @@ diff --git a/snappymail/v/0.0.0/app/templates/Views/User/PopupsSieveScript.html b/snappymail/v/0.0.0/app/templates/Views/User/PopupsSieveScript.html index c8268f755..131e8d4fe 100644 --- a/snappymail/v/0.0.0/app/templates/Views/User/PopupsSieveScript.html +++ b/snappymail/v/0.0.0/app/templates/Views/User/PopupsSieveScript.html @@ -87,8 +87,7 @@