mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-10-21 10:38:12 +00:00
feat(core): Update to ckeditor 5. Fixes #5920.
This commit is contained in:
1 parent
b8a6d576e1
commit
e92fb8f52d
198 files changed
+754
-5677
No files matched your search
@@ -16,41 +16,7 @@
|
||||
*/
|
||||
function sgCkeditorConfigProvider() {
|
||||
// Default plugins that have successfully passed through Angular's $sanitize service
|
||||
var defaultConfiguration = {
|
||||
toolbarGroups: [
|
||||
{ name: 'basicstyles', groups: [ 'basicstyles', 'colors', 'list', 'indent', 'blocks', 'align', 'links', 'insert', 'spellchecker', 'styles', 'mode', 'emoji' ] }
|
||||
],
|
||||
|
||||
// The default plugins included in the basic setup define some buttons that
|
||||
// are not needed in a basic editor. They are removed here.
|
||||
removeButtons: 'Strike,Subscript,Superscript,BGColor,Anchor,Format,Image',
|
||||
|
||||
// Allow the toolbar to be collapsed (useful for small screens)
|
||||
toolbarCanCollapse: true,
|
||||
|
||||
// Disable check version
|
||||
// NOTE : This is not definitive and ckeditor will be updated
|
||||
versionCheck: false,
|
||||
|
||||
// Dialog windows are also simplified.
|
||||
removeDialogTabs: 'link:advanced',
|
||||
|
||||
enterMode: CKEDITOR.ENTER_BR,
|
||||
tabSpaces: 4,
|
||||
// fullPage: true, include header and body
|
||||
allowedContent: true, // don't filter tags
|
||||
entities: false,
|
||||
|
||||
// Configure autogrow
|
||||
// https://ckeditor.com/docs/ckeditor4/latest/guide/dev_autogrow.html
|
||||
autoGrow_onStartup: true,
|
||||
autoGrow_minHeight: 300,
|
||||
autoGrow_bottomSpace: 0,
|
||||
language: 'en',
|
||||
|
||||
// The Upload Image plugin requires a remote URL to be defined even though we won't use it
|
||||
imageUploadUrl: '/SOGo/'
|
||||
};
|
||||
|
||||
|
||||
var events = [
|
||||
'activeEnterModeChange',
|
||||
@@ -129,7 +95,7 @@
|
||||
'widgetDefinition'
|
||||
];
|
||||
|
||||
var config = angular.copy(defaultConfiguration);
|
||||
var config = {};//angular.copy(defaultConfiguration);
|
||||
|
||||
this.$get = function () {
|
||||
return {
|
||||
@@ -233,6 +199,10 @@
|
||||
controller: sgCkeditorController
|
||||
};
|
||||
|
||||
var emojis = [
|
||||
{ title: 'Grinning Face', character: '😀' }, { title: 'Grinning Face with Big Eyes', character: '😃' }, { title: 'Grinning Face with Smiling Eyes', character: '😄' }, { title: 'Beaming Face with Smiling Eyes', character: '😁' }, { title: 'Grinning Squinting Face', character: '😆' }, { title: 'Grinning Face with Sweat', character: '😅' }, { title: 'Rolling on the Floor Laughing', character: '🤣' }, { title: 'Face with Tears of Joy', character: '😂' }, { title: 'Slightly Smiling Face', character: '🙂' }, { title: 'Upside-Down Face', character: '🙃' }, { title: 'Winking Face', character: '😉' }, { title: 'Smiling Face with Smiling Eyes', character: '😊' }, { title: 'Smiling Face with Halo', character: '😇' }, { title: 'Smiling Face with Hearts', character: '🥰' }, { title: 'Smiling Face with Heart-Eyes', character: '😍' }, { title: 'Star-Struck', character: '🤩' }, { title: 'Face Blowing a Kiss', character: '😘' }, { title: 'Kissing Face', character: '😗' }, { title: 'Smiling Face', character: '☺️' }, { title: 'Kissing Face with Closed Eyes', character: '😚' }, { title: 'Kissing Face with Smiling Eyes', character: '😙' }, { title: 'Smiling Face with Tear', character: '🥲' }, { title: 'Face Savoring Food', character: '😋' }, { title: 'Face with Tongue', character: '😛' }, { title: 'Winking Face with Tongue', character: '😜' }, { title: 'Zany Face', character: '🤪' }, { title: 'Squinting Face with Tongue', character: '😝' }, { title: 'Money-Mouth Face', character: '🤑' }, { title: 'Hugging Face', character: '🤗' }, { title: 'Face with Hand Over Mouth', character: '🤭' }, { title: 'Shushing Face', character: '🤫' }, { title: 'Thinking Face', character: '🤔' }, { title: 'Zipper-Mouth Face', character: '🤐' }, { title: 'Face with Raised Eyebrow', character: '🤨' }, { title: 'Neutral Face', character: '😐' }, { title: 'Expressionless Face', character: '😑' }, { title: 'Face Without Mouth', character: '😶' }, { title: 'Smirking Face', character: '😏' }, { title: 'Unamused Face', character: '😒' }, { title: 'Face with Rolling Eyes', character: '🙄' }, { title: 'Grimacing Face', character: '😬' }, { title: 'Lying Face', character: '🤥' }, { title: 'Relieved Face', character: '😌' }, { title: 'Pensive Face', character: '😔' }, { title: 'Sleepy Face', character: '😪' }, { title: 'Drooling Face', character: '🤤' }, { title: 'Sleeping Face', character: '😴' }, { title: 'Face with Medical Mask', character: '😷' }, { title: 'Face with Thermometer', character: '🤒' }, { title: 'Face with Head-Bandage', character: '🤕' }, { title: 'Nauseated Face', character: '🤢' }, { title: 'Face Vomiting', character: '🤮' }, { title: 'Sneezing Face', character: '🤧' }, { title: 'Hot Face', character: '🥵' }, { title: 'Cold Face', character: '🥶' }, { title: 'Woozy Face', character: '🥴' }, { title: 'Dizzy Face', character: '😵' }, { title: 'Exploding Head', character: '🤯' }, { title: 'Cowboy Hat Face', character: '🤠' }, { title: 'Partying Face', character: '🥳' }, { title: 'Disguised Face', character: '🥸' }, { title: 'Smiling Face with Sunglasses', character: '😎' }, { title: 'Nerd Face', character: '🤓' }, { title: 'Face with Monocle', character: '🧐' }, { title: 'Confused Face', character: '😕' }, { title: 'Worried Face', character: '😟' }, { title: 'Slightly Frowning Face', character: '🙁' }, { title: 'Frowning Face', character: '☹️' }, { title: 'Face with Open Mouth', character: '😮' }, { title: 'Hushed Face', character: '😯' }, { title: 'Astonished Face', character: '😲' }, { title: 'Flushed Face', character: '😳' }, { title: 'Pleading Face', character: '🥺' }, { title: 'Frowning Face with Open Mouth', character: '😦' }, { title: 'Anguished Face', character: '😧' }, { title: 'Fearful Face', character: '😨' }, { title: 'Anxious Face with Sweat', character: '😰' }, { title: 'Sad but Relieved Face', character: '😥' }, { title: 'Crying Face', character: '😢' }, { title: 'Loudly Crying Face', character: '😭' }, { title: 'Face Screaming in Fear', character: '😱' }, { title: 'Confounded Face', character: '😖' }, { title: 'Persevering Face', character: '😣' }, { title: 'Disappointed Face', character: '😞' }, { title: 'Downcast Face with Sweat', character: '😓' }, { title: 'Weary Face', character: '😩' }, { title: 'Tired Face', character: '😫' }, { title: 'Yawning Face', character: '🥱' }, { title: 'Face with Steam From Nose', character: '😤' }, { title: 'Pouting Face', character: '😡' }, { title: 'Angry Face', character: '😠' }, { title: 'Face with Symbols on Mouth', character: '🤬' }, { title: 'Smiling Face with Horns', character: '😈' }, { title: 'Angry Face with Horns', character: '👿' }, { title: 'Skull', character: '💀' }, { title: 'Skull and Crossbones', character: '☠️' }, { title: 'Pile of Poo', character: '💩' }, { title: 'Clown FaLine truncated
|
||||
];
|
||||
|
||||
sgCkeditorController.$inject = ['$element', '$scope', '$parse', '$timeout', 'sgCkeditorConfig'];
|
||||
function sgCkeditorController ($element, $scope, $parse, $timeout, sgCkeditorConfig) {
|
||||
var vm = this;
|
||||
@@ -245,11 +215,12 @@
|
||||
|
||||
this.$onInit = function () {
|
||||
vm.ngModelCtrl.$render = function () {
|
||||
if (editor) {
|
||||
editor.setData(vm.ngModelCtrl.$viewValue, {
|
||||
content = vm.ngModelCtrl.$viewValue;
|
||||
if (vm.editor) {
|
||||
vm.editor.setData(vm.ngModelCtrl.$viewValue, {
|
||||
noSnapshot: true,
|
||||
callback: function () {
|
||||
editor.fire('updateSnapshot')
|
||||
vm.editor.fire('updateSnapshot')
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -260,7 +231,7 @@
|
||||
if (config.language) {
|
||||
// Pickup the first matching language supported by SCAYT
|
||||
// See http://docs.ckeditor.com/#!/guide/dev_howtos_scayt
|
||||
config.scayt_sLang = _.find(['en_US', 'en_GB', 'pt_BR', 'da_DK', 'nl_NL', 'en_CA', 'fi_FI', 'fr_FR', 'fr_CA', 'de_DE', 'el_GR', 'it_IT', 'nb_NO', 'pt_PT', 'es_ES', 'sv_SE'], function(sLang) {
|
||||
config.scayt_sLang = _.find(['en_US', 'en_GB', 'pt_BR', 'da_DK', 'nl_NL', 'en_CA', 'fi_FI', 'fr_FR', 'fr_CA', 'de_DE', 'el_GR', 'it_IT', 'nb_NO', 'pt_PT', 'es_ES', 'sv_SE'], function (sLang) {
|
||||
return sLang.lastIndexOf(config.language, 0) == 0;
|
||||
}) || 'en_US';
|
||||
|
||||
@@ -268,48 +239,82 @@
|
||||
// See https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/126
|
||||
config.scayt_disableOptionsStorage = 'lang';
|
||||
}
|
||||
|
||||
if (vm.ckMargin) {
|
||||
// Set the margin of the iframe editable content
|
||||
CKEDITOR.addCss('.cke_editable { margin-top: ' + vm.ckMargin +
|
||||
'; margin-left: ' + vm.ckMargin +
|
||||
'; margin-right: ' + vm.ckMargin + '; }');
|
||||
if (!config.toolbar) {
|
||||
config.toolbar = {
|
||||
"items": [
|
||||
"bold", "italic", "underline", "|",
|
||||
"fontColor", "fontFamily", "fontSize", "|",
|
||||
"numberedList", "bulletedList", "|",
|
||||
"outdent", "indent", "|",
|
||||
"blockQuote", "|",
|
||||
"alignment", "|",
|
||||
"link", "|",
|
||||
"insertTable", "specialCharacters", "imageUpload", "|",
|
||||
"undo", "redo", "sourceEditing"
|
||||
],
|
||||
"shouldNotGroupWhenFull": true
|
||||
}
|
||||
}
|
||||
config.image = {
|
||||
resizeUnit: "px",
|
||||
insert: {
|
||||
type: "inline"
|
||||
}
|
||||
};
|
||||
vm.config = config;
|
||||
};
|
||||
|
||||
this.$postLink = function () {
|
||||
editorElement = $element[0].children[0];
|
||||
editor = CKEDITOR.replace(editorElement, config);
|
||||
var editorElement = $element[0].children[0];;
|
||||
ClassicEditor
|
||||
.create(editorElement, vm.config)
|
||||
.then(editor => {
|
||||
vm.editor = editor;
|
||||
|
||||
editor.on('instanceReady', onInstanceReady);
|
||||
editor.on('pasteState', onEditorChange);
|
||||
editor.on('change', onEditorChange);
|
||||
editor.on('paste', onEditorPaste);
|
||||
editor.on('fileUploadRequest', onEditorFileUploadRequest);
|
||||
// Add Emoticons
|
||||
editor.plugins.get('SpecialCharacters').addItems('Emoji', emojis, { label: 'Emoticons' });
|
||||
|
||||
if (content) {
|
||||
modelChanged = true
|
||||
editor.setData(content, {
|
||||
noSnapshot: true,
|
||||
callback: function () {
|
||||
editor.fire('updateSnapshot')
|
||||
// if (vm.ckMargin) {
|
||||
// // Set the margin of the iframe editable content
|
||||
// vm.editor.editing.view.domRoots.get("main").style.marginTop = vm.ckMargin;
|
||||
// vm.editor.editing.view.domRoots.get("main").style.marginLeft = vm.ckMargin;
|
||||
// vm.editor.editing.view.domRoots.get("main").style.marginRight = vm.ckMargin;
|
||||
// }
|
||||
|
||||
vm.editor.model.document.on('pasteState', onEditorChange);
|
||||
vm.editor.model.document.on('change:data', onEditorChange);
|
||||
vm.editor.model.document.on('paste', onEditorPaste);
|
||||
|
||||
onInstanceReady();
|
||||
|
||||
if (content) {
|
||||
modelChanged = true
|
||||
vm.editor.setData(content, {
|
||||
noSnapshot: true,
|
||||
callback: function () {
|
||||
vm.editor.fire('updateSnapshot')
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
this.$onChanges = function (changes) {
|
||||
if (
|
||||
changes.ngModel &&
|
||||
changes.ngModel.currentValue !== changes.ngModel.previousValue
|
||||
changes.ngModel.currentValue !== changes.ngModel.previousValue
|
||||
) {
|
||||
content = changes.ngModel.currentValue;
|
||||
if (editor && !editorChanged) {
|
||||
if (vm.editor && !editorChanged) {
|
||||
if (content) {
|
||||
editor.setData(content, {
|
||||
vm.editor.setData(content, {
|
||||
noSnapshot: true,
|
||||
callback: function () {
|
||||
editor.fire('updateSnapshot')
|
||||
vm.editor.fire('updateSnapshot')
|
||||
}
|
||||
});
|
||||
modelChanged = true;
|
||||
@@ -324,46 +329,16 @@
|
||||
|
||||
this.$onDestroy = function () {
|
||||
var noUpdate = true;
|
||||
editorElement.classList.add('ng-cloak');
|
||||
editor.destroy(noUpdate);
|
||||
}
|
||||
|
||||
function onInstanceReady (event) {
|
||||
// Register binded callbacks for all available events
|
||||
_.forEach(_.filter(sgCkeditorConfig.events, function (eventName) {
|
||||
return eventName != 'instanceReady';
|
||||
}), function (eventName) {
|
||||
var callbackName = 'on' + eventName[0].toUpperCase() + eventName.slice(1);
|
||||
if (vm[callbackName]) {
|
||||
editor.on(eventName, function (event) {
|
||||
vm[callbackName]({
|
||||
'$event': event,
|
||||
'$editor': editor
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (vm.onInstanceReady) {
|
||||
vm.onInstanceReady({
|
||||
'$event': event,
|
||||
'$editor': editor
|
||||
});
|
||||
}
|
||||
|
||||
editorElement.classList.remove('ng-cloak');
|
||||
vm.ngModelCtrl.$render();
|
||||
if (vm.editor)
|
||||
vm.editor.destroy(noUpdate);
|
||||
}
|
||||
|
||||
function onEditorChange () {
|
||||
var html = editor.getData();
|
||||
var body = editor.document ? editor.document.getBody() : null;
|
||||
var text;
|
||||
var html = vm.editor.getData();
|
||||
|
||||
if (_.isEmpty(body))
|
||||
return;
|
||||
else
|
||||
text = body.getText();
|
||||
var dom = document.createElement("DIV");
|
||||
dom.innerHTML = html;
|
||||
var text = (dom.textContent || dom.innerText);
|
||||
|
||||
if (text === '\n') {
|
||||
text = '';
|
||||
@@ -375,7 +350,7 @@
|
||||
validate(vm.checkTextLength ? text : html);
|
||||
if (vm.onContentChanged) {
|
||||
vm.onContentChanged({
|
||||
'editor': editor,
|
||||
'editor': vm.editor,
|
||||
'html': html,
|
||||
'text': text
|
||||
});
|
||||
@@ -393,17 +368,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
function onEditorFileUploadRequest (event) {
|
||||
// Intercept the request when an image is pasted, keep an inline base64 version only.
|
||||
var data, img;
|
||||
data = event.data.fileLoader.data;
|
||||
img = editor.document.createElement('img');
|
||||
img.setAttribute('src', data);
|
||||
editor.insertElement(img);
|
||||
event.cancel();
|
||||
function onInstanceReady(event) {
|
||||
if (vm.onInstanceReady) {
|
||||
vm.onInstanceReady({
|
||||
'$event': event,
|
||||
'$editor': vm.editor
|
||||
});
|
||||
}
|
||||
|
||||
vm.ngModelCtrl.$render();
|
||||
}
|
||||
|
||||
function validate (body) {
|
||||
function validate(body) {
|
||||
if (vm.maxLength) {
|
||||
vm.ngModelCtrl.$setValidity('maxlength', body.length > vm.maxLength + 1);
|
||||
}
|
||||
@@ -413,6 +389,7 @@
|
||||
if (vm.required) {
|
||||
vm.ngModelCtrl.$setValidity('required', body.length > 0);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user