Bugfix: CKEditor failed to load

This commit is contained in:
djmaze 2020-09-23 11:20:00 +02:00
parent 3599c4c745
commit 65032e3b89
5 changed files with 205 additions and 248 deletions

View file

@ -1,79 +1,4 @@
/**
* @type {Object}
*/
const CKEditorDefaultConfig = {
'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',
'removeButtons': 'Format,Undo,Redo,Cut,Copy,Paste,Anchor,Strike,Subscript,Superscript,Image,SelectAll,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'
},
/**
* @type {Object}
*/
htmlEditorLangsMap = {
'ar_sa': 'ar-sa',
'bg_bg': 'bg',
'cs_CZ': 'cs',
'de_de': 'de',
'el_gr': 'el',
'es_es': 'es',
'et_ee': 'et',
'fr_fr': 'fr',
'hu_hu': 'hu',
'is_is': 'is',
'it_it': 'it',
'ja_jp': 'ja',
'ko_kr': 'ko',
'lt_lt': 'lt',
'lv_lv': 'lv',
'fa_ir': 'fa',
'nb_no': 'nb',
'nl_nl': 'nl',
'pl_pl': 'pl',
'pt_br': 'pt-br',
'pt_pt': 'pt',
'ro_ro': 'ro',
'ru_ru': 'ru',
'sk_sk': 'sk',
'sl_si': 'sl',
'sv_se': 'sv',
'tr_tr': 'tr',
'uk_ua': 'uk',
'zh_cn': 'zh-cn',
'zh_tw': 'zh'
};
import { createCKEditor } from 'External/CKEditor.js';
class HtmlEditor {
editor;
@ -218,14 +143,6 @@ class HtmlEditor {
}
}
replaceHtml(find, replaceHtml) {
if (this.editor && this.__inited && 'wysiwyg' === this.editor.mode) {
try {
this.editor.setData(this.editor.getData().replace(find, replaceHtml));
} catch (e) {} // eslint-disable-line no-empty
}
}
setPlain(plain, focus) {
if (this.editor && this.__inited) {
this.clearCachedSignature();
@ -258,82 +175,23 @@ class HtmlEditor {
this.resize();
this.onReady && this.onReady();
},
initFunc = () => {
if (window.CKEDITOR) {
const config = CKEditorDefaultConfig,
language = rl.settings.get('Language'),
allowSource = !!rl.settings.app('allowHtmlEditorSourceButton'),
biti = !!rl.settings.app('allowHtmlEditorBitiButtons');
if ((allowSource || !biti) && !config.toolbarGroups.__cfgInited) {
config.toolbarGroups.__cfgInited = true;
if (allowSource) {
config.removeButtons = config.removeButtons.replace(',Source', '');
}
if (!biti) {
config.removePlugins += (config.removePlugins ? ',' : '') + 'bidi';
}
}
config.enterMode = CKEDITOR.ENTER_BR;
config.shiftEnterMode = CKEDITOR.ENTER_P;
config.language = htmlEditorLangsMap[(language || 'en').toLowerCase()] || 'en';
if (CKEDITOR.env) {
CKEDITOR.env.isCompatible = true;
}
this.editor = CKEDITOR.appendTo(this.element, config);
this.editor.on('key', event => !(event && event.data && 'Tab' == event.data.key));
if (window.FileReader) {
this.editor.on('drop', (event) => {
if (0 < event.data.dataTransfer.getFilesCount()) {
const file = event.data.dataTransfer.getFile(0);
if (file && event.data.dataTransfer.id && file.type && file.type.match(/^image/i)) {
const id = event.data.dataTransfer.id,
imageId = `[img=${id}]`,
reader = new FileReader();
reader.onloadend = () => {
if (reader.result) {
this.replaceHtml(imageId, `<img src="${reader.result}" />`);
}
};
reader.readAsDataURL(file);
event.data.dataTransfer.setData('text/html', imageId);
}
}
});
}
this.editor.on('instanceReady', onReady);
}
else if (window.Squire) {
this.editor = new SquireUI(this.element, this.editor);
setTimeout(onReady,1);
}
if (this.editor) {
this.editor.on('blur', () => this.blurTrigger());
this.editor.on('focus', () => this.blurTimer && clearTimeout(this.blurTimer));
this.editor.on('mode', () => {
this.blurTrigger();
this.onModeChange && this.onModeChange('plain' !== this.editor.mode);
});
}
};
if (window.CKEDITOR || window.Squire) {
initFunc();
if (window.CKEDITOR) {
this.editor = createCKEditor(this.element);
this.editor.on('instanceReady', onReady);
} else {
window.__initEditor = initFunc;
this.editor = new SquireUI(this.element, this.editor);
setTimeout(onReady,1);
}
if (this.editor) {
this.editor.on('blur', () => this.blurTrigger());
this.editor.on('focus', () => this.blurTimer && clearTimeout(this.blurTimer));
this.editor.on('mode', () => {
this.blurTrigger();
this.onModeChange && this.onModeChange('plain' !== this.editor.mode);
});
}
}
}

133
dev/External/CKEditor.js vendored Normal file
View file

@ -0,0 +1,133 @@
const config = {
'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',
'removeButtons': 'Format,Undo,Redo,Cut,Copy,Paste,Anchor,Strike,Subscript,Superscript,Image,SelectAll,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'
},
/**
* @type {Object}
*/
htmlEditorLangsMap = {
'ar_sa': 'ar-sa',
'bg_bg': 'bg',
'cs_CZ': 'cs',
'de_de': 'de',
'el_gr': 'el',
'es_es': 'es',
'et_ee': 'et',
'fr_fr': 'fr',
'hu_hu': 'hu',
'is_is': 'is',
'it_it': 'it',
'ja_jp': 'ja',
'ko_kr': 'ko',
'lt_lt': 'lt',
'lv_lv': 'lv',
'fa_ir': 'fa',
'nb_no': 'nb',
'nl_nl': 'nl',
'pl_pl': 'pl',
'pt_br': 'pt-br',
'pt_pt': 'pt',
'ro_ro': 'ro',
'ru_ru': 'ru',
'sk_sk': 'sk',
'sl_si': 'sl',
'sv_se': 'sv',
'tr_tr': 'tr',
'uk_ua': 'uk',
'zh_cn': 'zh-cn',
'zh_tw': 'zh'
};
export function createCKEditor(element)
{
const language = rl.settings.get('Language'),
allowSource = !!rl.settings.app('allowHtmlEditorSourceButton'),
biti = !!rl.settings.app('allowHtmlEditorBitiButtons');
if ((allowSource || !biti) && !config.toolbarGroups.__cfgInited) {
config.toolbarGroups.__cfgInited = true;
if (allowSource) {
config.removeButtons = config.removeButtons.replace(',Source', '');
}
if (!biti) {
config.removePlugins += (config.removePlugins ? ',' : '') + 'bidi';
}
}
config.enterMode = CKEDITOR.ENTER_BR;
config.shiftEnterMode = CKEDITOR.ENTER_P;
config.language = htmlEditorLangsMap[(language || 'en').toLowerCase()] || 'en';
if (CKEDITOR.env) {
CKEDITOR.env.isCompatible = true;
}
const editor = CKEDITOR.appendTo(element, config);
editor.on('key', event => !(event && event.data && 'Tab' == event.data.key));
if (window.FileReader) {
editor.on('drop', event => {
if (0 < event.data.dataTransfer.getFilesCount()) {
const file = event.data.dataTransfer.getFile(0);
if (file && event.data.dataTransfer.id && file.type && file.type.match(/^image/i)) {
const id = event.data.dataTransfer.id,
imageId = `[img=${id}]`,
reader = new FileReader();
reader.onloadend = () => {
if (reader.result) {
if ('wysiwyg' === editor.mode) {
try {
editor.setData(editor.getData().replace(imageId, `<img src="${reader.result}" />`));
} catch (e) {} // eslint-disable-line no-empty
}
}
};
reader.readAsDataURL(file);
event.data.dataTransfer.setData('text/html', imageId);
}
}
});
}
return editor;
}

View file

@ -60,13 +60,18 @@ const
}
return new Promise((resolve, reject) => {
const script = doc.createElement('script');
script.onload = () => resolve();
script.onload = () => {
p.set(pStep += step);
resolve();
};
script.onerror = () => reject(new Error(src));
script.src = src;
// script.async = true;
doc.head.append(script);
});
},
step = 100 / 7,
p = win.progressJs = {
set: percent => progress.style.width = Math.min(percent, 100) + '%',
end: () => {
@ -84,10 +89,11 @@ if (!navigator || !navigator.cookieEnabled) {
doc.location.href = './?/NoCookie';
}
let container = doc.querySelector('.progressjs'),
let pStep = 0,
container = doc.querySelector('.progressjs'),
progress = doc.querySelector('.progressjs-inner'),
RL_APP_DATA_STORAGE = {};
RL_APP_DATA = {};
win.rl = {
hash: {
@ -95,8 +101,8 @@ win.rl = {
get: () => storage().getItem(STORAGE_KEY) || null,
// setHash
set: () => {
storage().setItem(STORAGE_KEY, RL_APP_DATA_STORAGE && RL_APP_DATA_STORAGE[AUTH_KEY]
? RL_APP_DATA_STORAGE[AUTH_KEY] : '');
storage().setItem(STORAGE_KEY, RL_APP_DATA && RL_APP_DATA[AUTH_KEY]
? RL_APP_DATA[AUTH_KEY] : '');
setTimestamp();
},
// clearHash
@ -114,96 +120,63 @@ win.rl = {
return false;
}
},
data: () => RL_APP_DATA_STORAGE,
data: () => RL_APP_DATA,
adminArea: () => options.admin,
settings: {
get: name => null == RL_APP_DATA_STORAGE[name] ? null : RL_APP_DATA_STORAGE[name],
set: (name, value) => RL_APP_DATA_STORAGE[name] = value,
get: name => null == RL_APP_DATA[name] ? null : RL_APP_DATA[name],
set: (name, value) => RL_APP_DATA[name] = value,
app: name => {
const APP_SETTINGS = RL_APP_DATA_STORAGE.System || {};
const APP_SETTINGS = RL_APP_DATA.System || {};
return null == APP_SETTINGS[name] ? null : APP_SETTINGS[name];
},
capa: name => null != name && Array.isArray(RL_APP_DATA_STORAGE.Capa) && RL_APP_DATA_STORAGE.Capa.includes(name)
capa: name => null != name && Array.isArray(RL_APP_DATA.Capa) && RL_APP_DATA.Capa.includes(name)
},
setWindowTitle: title => {
title = null == title ? '' : '' + title;
if (RL_APP_DATA_STORAGE.Title) {
title += (title ? ' - ' : '') + RL_APP_DATA_STORAGE.Title;
if (RL_APP_DATA.Title) {
title += (title ? ' - ' : '') + RL_APP_DATA.Title;
}
doc.title = null == title ? '' : '' + title;
}
};
},
/**
* @param {mixed} appData
* @returns {void}
*/
win.__initAppData = appData => {
RL_APP_DATA_STORAGE = appData;
initData: appData => {
RL_APP_DATA = appData;
rl.hash.set();
rl.hash.set();
if (appData) {
if (appData.NewThemeLink) {
eId('app-theme-link').href = appData.NewThemeLink;
}
appData.IncludeCss && writeCSS(appData.IncludeCss);
if (appData.IncludeBackground) {
const img = appData.IncludeBackground.replace('{{USER}}', rl.hash.get() || '0');
if (img) {
htmlCL.add('UserBackground');
doc.body.style.backgroundImage = "url("+img+")";
if (appData) {
if (appData.NewThemeLink) {
eId('app-theme-link').href = appData.NewThemeLink;
}
}
}
if (
appData &&
appData.TemplatesLink &&
appData.LangLink &&
appData.StaticLibJsLink &&
appData.StaticAppJsLink
) {
p.set(5);
appData.IncludeCss && writeCSS(appData.IncludeCss);
loadScript(appData.StaticLibJsLink)
.then(() => {
p.set(20);
return Promise.all([loadScript(appData.TemplatesLink), loadScript(appData.LangLink)]);
})
.then(() => {
p.set(30);
return loadScript(appData.StaticAppJsLink);
})
.then(() => {
p.set(50);
return appData.PluginsLink ? loadScript(appData.PluginsLink) : Promise.resolve();
})
.then(() => {
if (win.__APP_BOOT) {
p.set(70);
win.__APP_BOOT(() => showError());
} else {
showError();
if (appData.IncludeBackground) {
const img = appData.IncludeBackground.replace('{{USER}}', rl.hash.get() || '0');
if (img) {
htmlCL.add('UserBackground');
doc.body.style.backgroundImage = "url("+img+")";
}
})
.catch((e) => {
}
loadScript(appData.StaticLibJsLink)
.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();
throw e;
})
.then(() => {
// Enable the old CKEditor
if (appData.Auth && appData.StaticEditorJsLink) {
loadScript(appData.StaticEditorJsLink).then(() => {
win.__initEditor && win.__initEditor();
win.__initEditor = null;
});
}
});
} else {
showError();
} else {
showError();
}
}
};

View file

@ -1007,9 +1007,11 @@ class ServiceActions
$this->oActions->SetSpecAuthToken($sAuthAccountHash);
}
$sResult = $this->compileAppData($this->oActions->AppData($bAdmin,
0 === \strpos($sAdd, 'mobile'), '1' === \substr($sAdd, -1),
$sAuthAccountHash), false);
$sResult = 'rl.initData('
.\json_encode($this->oActions->AppData($bAdmin,
0 === \strpos($sAdd, 'mobile'), '1' === \substr($sAdd, -1),
$sAuthAccountHash))
.');';
$this->Logger()->Write($sResult, \MailSo\Log\Enumerations\Type::INFO, 'APPDATA');
@ -1092,13 +1094,4 @@ class ServiceActions
($bWrapByScriptTag ? '</script>' : '')
;
}
private function compileAppData(array $aAppData, bool $bWrapByScriptTag = true) : string
{
return
($bWrapByScriptTag ? '<script type="text/javascript" data-cfasync="false">' : '').
'if(window.__initAppData){window.__initAppData('.\json_encode($aAppData).');}'.
($bWrapByScriptTag ? '</script>' : '')
;
}
}

View file

@ -1,5 +1,5 @@
(function(CKEDITOR, $) {
(function(CKEDITOR) {
'use strict';
@ -10,10 +10,10 @@
isEmptyText = false,
newLine = (isHtml ? '<br />' : "\n"),
clearHtmlLine = function(html) {
return $.trim(editor.__textUtils.htmlToPlain(html));
return editor.__textUtils.htmlToPlain(html).trim();
};
isEmptyText = !$.trim(text);
isEmptyText = !text.trim();
if (!isEmptyText && isHtml)
{
isEmptyText = !clearHtmlLine(text);
@ -138,4 +138,4 @@
}
});
}(CKEDITOR, $));
}(CKEDITOR));