feat(core): Update to ckeditor 5. Fixes #5920.

This commit is contained in:
smizrahi committed 2024-02-27 14:29:59 +01:00
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);
}
}
}