diff --git a/CHANGELOG b/CHANGELOG index 9898678af..b03950c21 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -24,6 +24,8 @@ Core: - Added support for multiple projectors. - Added an overlay for the current list of speakers. - Added button to clear the chatbox. +- Switched editor back from TinyMCE to CKEditor which provides a + better copy/paste support from MS Word. Motions: - Added origin field. diff --git a/README.rst b/README.rst index 905139713..6e8eac64c 100644 --- a/README.rst +++ b/README.rst @@ -178,6 +178,7 @@ OpenSlides uses the following projects or parts of them: * `angular-bootstrap `_, License: MIT * `angular-bootstrap-colorpicker `_, License: MIT * `angular-chosen-localytics `_, License: MIT + * `angular-ckeditor `_, License: MIT * `angular-csv-import `_, License: MIT * `angular-formly `_, License: MIT * `angular-formly-templates-bootstrap `_, License: MIT @@ -189,13 +190,13 @@ OpenSlides uses the following projects or parts of them: * `angular-sanitize `_, License: MIT * `angular-scroll-glue `_, License: MIT * `angular-ui-router `_, License: MIT - * `angular-ui-tinymce `_, License: MIT * `angular-ui-tree `_, License: MIT * `angular-xeditable `_, License: MIT * `api-check `_, License: MIT * `bootstrap `_, License: MIT * `bootstrap-ui-datetime-picker `_, License: MIT * `chosen `_, License: MIT + * `ckeditor `_, License: GPL 2+, LGPL 2.1+ or MPL 1.1. * `font-awesome-bower `_, License: MIT * `jquery `_, License: MIT * `jquery.cookie `_, License: MIT @@ -210,8 +211,6 @@ OpenSlides uses the following projects or parts of them: * `open-sans-fontface `_, License: Apache License version 2.0 * `pdfjs-dist `_, License: Apache-2.0 * `roboto-condensed `_, License: Apache 2.0 - * `tinymce `_, License: LGPL-2.1 - * `tinymce-i18n `_, License: LGPL-2.1 License and authors diff --git a/bower.json b/bower.json index 0d69134e1..f0609bf97 100644 --- a/bower.json +++ b/bower.json @@ -8,6 +8,7 @@ "angular-bootstrap": "~2.1.3", "angular-bootstrap-colorpicker": "~3.0.25", "angular-chosen-localytics": "~1.5.0", + "angular-ckeditor": "~1.0.3", "angular-csv-import": "0.0.36", "angular-file-saver": "~1.1.2", "angular-formly": "~8.4.0", @@ -19,11 +20,11 @@ "angular-sanitize": "~1.5.8", "angular-scroll-glue": "~2.0.7", "angular-ui-router": "~0.3.1", - "angular-ui-tinymce": "~0.0.17", "angular-ui-tree": "~2.22.0", "angular-xeditable": "~0.5.0", "bootstrap-css-only": "~3.3.6", "bootstrap-ui-datetime-picker": "~2.4.0", + "ckeditor": "~4.6.1", "docxtemplater": "~2.1.5", "font-awesome-bower": "~4.5.0", "jquery.cookie": "~1.4.1", @@ -35,9 +36,7 @@ "ngstorage": "~0.3.11", "ngBootbox": "~0.1.3", "pdfmake": "bpampuch/pdfmake#214ec161c11fadb8f02c08f2e3bea0576ac4c9fb", - "roboto-fontface": "~0.6.0", - "tinymce": "~4.4.3", - "tinymce-i18n": "OpenSlides/tinymce-i18n#a186ad61e0aa30fdf657e88f405f966d790f0805" + "roboto-fontface": "~0.6.0" }, "overrides": { "pdfmake": { @@ -56,13 +55,6 @@ "fonts/Roboto-Condensed/Roboto-Condensed-Regular.woff", "fonts/Roboto-Condensed/Roboto-Condensed-Light.woff" ] - }, - "tinymce": { - "main": [ - "tinymce.js", - "themes/modern/theme.js", - "plugins/*/plugin.js" - ] } }, "resolutions": { diff --git a/gulpfile.js b/gulpfile.js index a051fc789..45a376831 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -108,37 +108,59 @@ gulp.task('angular-chosen-img', function () { .pipe(gulp.dest(path.join(output_directory, 'css'))); }); -// Catches all skins files for TinyMCE editor. -gulp.task('tinymce-skins', function () { - return gulp.src(path.join('bower_components', 'tinymce', 'skins', '**')) - .pipe(gulp.dest(path.join(output_directory, 'tinymce', 'skins'))); -}); - -// Catches all required i18n files for TinyMCE editor. -gulp.task('tinymce-i18n', function () { +// CKEditor defaults +gulp.task('ckeditor-defaults', function () { return gulp.src([ - 'bower_components/tinymce-i18n/langs/en_GB.js', - 'bower_components/tinymce-i18n/langs/cs.js', - 'bower_components/tinymce-i18n/langs/de.js', - 'bower_components/tinymce-i18n/langs/es.js', - 'bower_components/tinymce-i18n/langs/fr_FR.js', - 'bower_components/tinymce-i18n/langs/pt_PT.js', - ]) - .pipe(rename(function (path) { - if (path.basename === 'en_GB') { - path.basename = 'en'; - } else if (path.basename === 'fr_FR') { - path.basename = 'fr'; - } else if (path.basename === 'pt_PT') { - path.basename = 'pt'; - } - })) - .pipe(gulpif(argv.production, uglify())) - .pipe(gulp.dest(path.join(output_directory, 'tinymce', 'i18n'))); + path.join('bower_components', 'ckeditor', 'styles.js'), + path.join('bower_components', 'ckeditor', 'contents.css'), + ]) + .pipe(gulp.dest(path.join(output_directory, 'ckeditor'))); }); -// Combines all TinyMCE related tasks. -gulp.task('tinymce', ['tinymce-skins', 'tinymce-i18n'], function () {}); +// CKEditor skins +gulp.task('ckeditor-skins', function () { + return gulp.src([ + path.join('bower_components', 'ckeditor', 'skins', 'moono-lisa', '**', '*'), + ],{ base: path.join('bower_components', 'ckeditor', 'skins') }) + .pipe(gulp.dest(path.join(output_directory, 'ckeditor', 'skins'))); +}); + +// CKEditor plugins +gulp.task('ckeditor-plugins', function () { + return gulp.src([ + path.join('bower_components', 'ckeditor', 'plugins', 'clipboard', '**', '*'), + path.join('bower_components', 'ckeditor', 'plugins', 'colorbutton', '**', '*'), + path.join('bower_components', 'ckeditor', 'plugins', 'dialog', '**', '*'), + path.join('bower_components', 'ckeditor', 'plugins', 'find', '**', '*'), + path.join('bower_components', 'ckeditor', 'plugins', 'image', '**', '*'), + path.join('bower_components', 'ckeditor', 'plugins', 'justify', '**', '*'), + path.join('bower_components', 'ckeditor', 'plugins', 'liststyle', '**', '*'), + path.join('bower_components', 'ckeditor', 'plugins', 'magicline', '**', '*'), + path.join('bower_components', 'ckeditor', 'plugins', 'pastefromword', '**', '*'), + path.join('bower_components', 'ckeditor', 'plugins', 'panelbutton', '**', '*'), + path.join('bower_components', 'ckeditor', 'plugins', 'showblocks', '**', '*'), + path.join('bower_components', 'ckeditor', 'plugins', 'sourcedialog', '**', '*'), + path.join('bower_components', 'ckeditor', 'plugins', 'table', '**', '*'), + path.join('bower_components', 'ckeditor', 'plugins', 'tabeltools', '**', '*'), + ],{ base: path.join('bower_components', 'ckeditor', 'plugins') }) + .pipe(gulp.dest(path.join(output_directory, 'ckeditor', 'plugins'))); +}); + +// CKEditor languages +gulp.task('ckeditor-lang', function () { + return gulp.src([ + path.join('bower_components', 'ckeditor', 'lang', 'en.js'), + path.join('bower_components', 'ckeditor', 'lang', 'de.js'), + path.join('bower_components', 'ckeditor', 'lang', 'pt.js'), + path.join('bower_components', 'ckeditor', 'lang', 'es.js'), + path.join('bower_components', 'ckeditor', 'lang', 'fr.js'), + path.join('bower_components', 'ckeditor', 'lang', 'cs.js'), + ]) + .pipe(gulp.dest(path.join(output_directory, 'ckeditor', 'lang'))); +}); + +// Combines all CKEditor related tasks. +gulp.task('ckeditor', ['ckeditor-defaults', 'ckeditor-skins', 'ckeditor-plugins', 'ckeditor-lang'], function () {}); // Compiles translation files (*.po) to *.json and saves them in the directory // openslides/static/i18n/. @@ -151,7 +173,16 @@ gulp.task('translations', function () { }); // Gulp default task. Runs all other tasks before. -gulp.task('default', ['js', 'js-libs', 'templates', 'css-libs', 'fonts-libs', 'tinymce', 'angular-chosen-img', 'translations'], function () {}); +gulp.task('default', [ + 'js', + 'js-libs', + 'templates', + 'css-libs', + 'fonts-libs', + 'ckeditor', + 'angular-chosen-img', + 'translations' + ], function () {}); /** diff --git a/openslides/core/static/js/core/base.js b/openslides/core/static/js/core/base.js index 89bcf616f..f45c22e02 100644 --- a/openslides/core/static/js/core/base.js +++ b/openslides/core/static/js/core/base.js @@ -548,33 +548,113 @@ angular.module('OpenSlidesApp.core', [ } ]) -// Options for TinyMCE editor used in various create and edit views. + +// Configs for CKEditor which has to set while startup of OpenSlides +.config( + function() { + CKEDITOR.disableAutoInline = true; + } +) + +// Options for CKEditor used in various create and edit views. // Required in core/base.js because MotionComment factory which used this // factory has to placed in motions/base.js. .factory('Editor', [ 'gettextCatalog', function (gettextCatalog) { return { - getOptions: function (images, inlineMode) { - if (inlineMode === undefined) { - inlineMode = false; - } + getOptions: function (images) { return { - language_url: '/static/tinymce/i18n/' + gettextCatalog.getCurrentLanguage() + '.js', - theme_url: '/static/js/openslides-libs.js', - skin_url: '/static/tinymce/skins/lightgray/', - inline: inlineMode, - browser_spellcheck: true, - image_advtab: true, - image_list: images, - plugins: [ - 'lists link autolink charmap preview searchreplace code fullscreen', - 'paste textcolor colorpicker image imagetools wordcount' - ], - menubar: '', - toolbar: 'undo redo searchreplace | styleselect | bold italic underline strikethrough ' + - 'forecolor backcolor removeformat | bullist numlist | outdent indent | ' + - 'link image charmap table | code preview fullscreen' + on: { + instanceReady: function() { + // This adds a listener to ckeditor to remove unwanted blank lines on import. + // Clipboard content varies heavily in structure and html code, depending on the "sender". + // Here it is first parsed into a pseudo-DOM (two lines taken from a ckeditor + // paste example on the ckeditor site). + this.on('paste', function(evt) { + if (evt.data.type == 'html') { + var fragment = CKEDITOR.htmlParser.fragment.fromHtml(evt.data.dataValue); + var writer = new CKEDITOR.htmlParser.basicWriter(); + // html content will now be in a dom-like structure inside 'fragment'. + this.filter.applyTo(fragment); + if (fragment.children) { + // If this fragment is DOM-like, it may contain nested properties + // (being html nodes). Traverse the children and check if it is a + // child only containing empty
or

. + // new_content_children will finally contain all nodes that are + // not empty. + var new_content_children = []; + _.forEach(fragment.children, function (child) { + var empty = true; + if (child.children){ + _.forEach(child.children, function(grandchild) { + if (grandchild.name != 'p' && grandchild.name != 'br') { + empty = false; + } else if (grandchild.isEmpty !== true) { + empty = false; + } + }); + if (empty === false) { + new_content_children.push(child); + } + } else { + if (child.name != 'p' && child.name != 'br' && + child.isEmpty !== true){ + new_content_children.push(child); + } + } + }); + fragment.children = new_content_children; + } + fragment.writeHtml(writer); + // Return the re-created fragment without the empty

and
into the + // editor import processing (same as at the begin of the function: by ckeditor) + evt.data.dataValue = writer.getHtml(); + } + }); + } + }, + customConfig: '', + disableNativeSpellChecker: false, + language_list: [ + 'fr:français', + 'es:español', + 'pt:português', + 'en:english', + 'de:deutsch', + 'cs:čeština'], + language: gettextCatalog.getCurrentLanguage(), + allowedContent: + 'h1 h2 h3 b i u strike sup sub strong em;' + + 'blockquote p pre table' + + '(text-align-left,text-align-center,text-align-right,text-align-justify){text-align};' + + 'a[!href];' + + 'img[!src,alt]{width,height,float};' + + 'tr th td caption;' + + 'li; ol[start]{list-style-type};' + + 'ul{list-style};' + + 'span[data-line-number,contenteditable]{color,background-color}(os-line-number,line-number-*);' + + 'br(os-line-break);', + + // there seems to be an error in CKeditor that parses spaces in extraPlugins as part of the plugin name. + extraPlugins: 'colorbutton,find,liststyle,sourcedialog,justify,showblocks', + removePlugins: 'wsc,scayt,a11yhelp,filebrowser,sourcearea', + removeButtons: 'Scayt,Anchor,Styles,HorizontalRule', + toolbarGroups: [ + { name: 'clipboard', groups: [ 'clipboard', 'undo' ] }, + { name: 'editing', groups: [ 'find', 'selection', 'spellchecker', 'editing' ] }, + { name: 'links', groups: [ 'links' ] }, + { name: 'insert', groups: [ 'insert' ] }, + { name: 'tools', groups: [ 'tools' ] }, + { name: 'document', groups: [ 'mode' ] }, + '/', + { name: 'styles', groups: [ 'styles' ] }, + { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] }, + { name: 'colors', groups: [ 'colors' ] }, + { name: 'paragraph', groups: [ 'list', 'indent' ] }, + { name: 'align'}, + { name: 'paragraph', groups: [ 'blocks' ] } + ] }; } }; diff --git a/openslides/core/static/js/core/site.js b/openslides/core/static/js/core/site.js index 307b9d2ff..ff8763ca3 100644 --- a/openslides/core/static/js/core/site.js +++ b/openslides/core/static/js/core/site.js @@ -18,7 +18,7 @@ angular.module('OpenSlidesApp.core.site', [ 'ngMessages', 'ngCsvImport', 'ngStorage', - 'ui.tinymce', + 'ckeditor', 'luegg.directives', 'xeditable', ]) diff --git a/openslides/core/static/templates/core/editor.html b/openslides/core/static/templates/core/editor.html index b634bd64e..13fd511d8 100644 --- a/openslides/core/static/templates/core/editor.html +++ b/openslides/core/static/templates/core/editor.html @@ -1,2 +1,2 @@ - - + + \ No newline at end of file diff --git a/openslides/core/static/templates/index.html b/openslides/core/static/templates/index.html index 6688a741d..14bcab87c 100644 --- a/openslides/core/static/templates/index.html +++ b/openslides/core/static/templates/index.html @@ -10,6 +10,10 @@ + + diff --git a/openslides/motions/static/js/motions/base.js b/openslides/motions/static/js/motions/base.js index 4677e9df5..84e79e5bf 100644 --- a/openslides/motions/static/js/motions/base.js +++ b/openslides/motions/static/js/motions/base.js @@ -546,7 +546,7 @@ angular.module('OpenSlidesApp.motions', [ label: field.name, }, data: { - tinymceOption: Editor.getOptions() + ckeditorOptions: Editor.getOptions() }, hide: !operator.hasPerms("motions.can_see_and_manage_comments") }; diff --git a/openslides/motions/static/js/motions/linenumbering.js b/openslides/motions/static/js/motions/linenumbering.js index 2b7d91c03..3b32a72fd 100644 --- a/openslides/motions/static/js/motions/linenumbering.js +++ b/openslides/motions/static/js/motions/linenumbering.js @@ -82,7 +82,7 @@ angular.module('OpenSlidesApp.motions.lineNumbering', []) node.setAttribute('class', 'os-line-number line-number-' + lineNumber); node.setAttribute('data-line-number', lineNumber + ''); node.setAttribute('contenteditable', 'false'); - node.innerHTML = ' '; // Prevent tinymce from stripping out empty span's + node.innerHTML = ' '; // Prevent ckeditor from stripping out empty span's return node; }; @@ -302,6 +302,15 @@ angular.module('OpenSlidesApp.motions.lineNumbering', []) for (i = 0; i < oldChildren.length; i++) { if (oldChildren[i].nodeType == TEXT_NODE) { + if (!oldChildren[i].nodeValue.match(/\S/)) { + // White space nodes between block elements should be ignored + var prevIsBlock = (i > 0 && !this._isInlineElement(oldChildren[i - 1])); + var nextIsBlock = (i < oldChildren.length - 1 && !this._isInlineElement(oldChildren[i + 1])); + if ((prevIsBlock && nextIsBlock) || (i === 0 && nextIsBlock) || (i === oldChildren.length - 1 && prevIsBlock)) { + node.appendChild(oldChildren[i]); + continue; + } + } var ret = this._textNodeToLines(oldChildren[i], length, highlight); for (var j = 0; j < ret.length; j++) { node.appendChild(ret[j]); diff --git a/openslides/motions/static/js/motions/motion-services.js b/openslides/motions/static/js/motions/motion-services.js index ce96638c1..7b6059b63 100644 --- a/openslides/motions/static/js/motions/motion-services.js +++ b/openslides/motions/static/js/motions/motion-services.js @@ -61,13 +61,12 @@ angular.module('OpenSlidesApp.motions.motionservices', ['OpenSlidesApp.motions', 'Motion', 'Config', '$timeout', - function (Editor, Motion, Config, $timeout) { + 'gettextCatalog', + function (Editor, Motion, Config, $timeout, gettextCatalog) { var obj = { active: false, changed: false, trivialChange: false, - editor: null, - lineBrokenText: null, originalHtml: null }; @@ -76,62 +75,77 @@ angular.module('OpenSlidesApp.motions.motionservices', ['OpenSlidesApp.motions', obj.init = function (_scope, _motion) { $scope = _scope; motion = _motion; - obj.lineBrokenText = motion.getTextWithLineBreaks($scope.version); - obj.originalHtml = obj.lineBrokenText; - }; - - - obj.tinymceOptions = Editor.getOptions(null, true); - obj.tinymceOptions.readonly = 1; - obj.tinymceOptions.setup = function (editor) { - obj.editor = editor; - editor.on('init', function () { - obj.lineBrokenText = motion.getTextWithLineBreaks($scope.version); - obj.editor.setContent(obj.lineBrokenText); - obj.originalHtml = obj.editor.getContent(); - obj.changed = false; - }); - editor.on('change', function () { - obj.changed = (editor.getContent() != obj.originalHtml); - }); - editor.on('undo', function () { - obj.changed = (editor.getContent() != obj.originalHtml); - }); + obj.ckeditorOptions = Editor.getOptions(); + obj.ckeditorOptions.readOnly = true; + obj.isEditable = false; + obj.changed = false; }; obj.setVersion = function (_motion, versionId) { motion = _motion; // If this is not updated, - obj.lineBrokenText = motion.getTextWithLineBreaks(versionId); + obj.originalHtml = motion.getTextWithLineBreaks(versionId); obj.changed = false; - obj.active = false; + obj.editor.setReadOnly(true); if (obj.editor) { - obj.editor.setContent(obj.lineBrokenText); - obj.editor.setMode('readonly'); - obj.originalHtml = obj.editor.getContent(); - } else { - obj.originalHtml = obj.lineBrokenText; + obj.editor.setData(obj.originalHtml); } }; obj.enable = function () { - obj.editor.setMode('design'); - obj.active = true; - obj.changed = false; - - obj.lineBrokenText = motion.getTextWithLineBreaks($scope.version); - obj.editor.setContent(obj.lineBrokenText); - obj.originalHtml = obj.editor.getContent(); - $timeout(function () { - obj.editor.focus(); - }, 100); + if (motion.isAllowed('update')) { + obj.active = true; + obj.isEditable = true; + obj.ckeditorOptions.language = gettextCatalog.getCurrentLanguage(); + obj.editor = CKEDITOR.inline('view-original-inline-editor', obj.ckeditorOptions); + obj.editor.on('change', function () { + $timeout(function() { + if (obj.editor.getData() != obj.originalHtml) { + obj.changed = true; + } else { + obj.changed = false; + } + }); + }); + obj.revert(); + } else { + obj.disable(); + } }; obj.disable = function () { - obj.editor.setMode('readonly'); - obj.active = false; - obj.changed = false; - obj.lineBrokenText = obj.originalHtml; - obj.editor.setContent(obj.originalHtml); + if (obj.editor) { + obj.editor.setReadOnly(true); + obj.editor.setData(obj.originalHtml, { + callback: function() { + obj.editor.destroy(); + } + }); + } + $timeout(function() { + obj.active = false; + obj.changed = false; + obj.isEditable = false; + }); + }; + + // sets editor content to the initial motion state + obj.revert = function() { + if (obj.editor) { + obj.originalHtml = motion.getTextWithLineBreaks($scope.version); + obj.editor.setData( + motion.getTextWithLineBreaks($scope.version), { + callback: function() { + obj.originalHtml = obj.editor.getData(); + obj.editor.setReadOnly(false); + $timeout(function() { + obj.changed = false; + }); + $timeout(function () { + obj.editor.focus(); + }, 100); + } + }); + } }; obj.save = function () { @@ -139,7 +153,7 @@ angular.module('OpenSlidesApp.motions.motionservices', ['OpenSlidesApp.motions', throw 'No permission to update motion'; } - motion.setTextStrippingLineBreaks(obj.editor.getContent()); + motion.setTextStrippingLineBreaks(obj.editor.getData()); motion.disable_versioning = (obj.trivialChange && Config.get('motions_allow_disable_versioning').value); Motion.inject(motion); @@ -147,11 +161,13 @@ angular.module('OpenSlidesApp.motions.motionservices', ['OpenSlidesApp.motions', Motion.save(motion, {method: 'PATCH'}).then( function (success) { $scope.showVersion(motion.getVersion(-1)); + obj.revert(); }, function (error) { // save error: revert all changes by restore // (refresh) original motion object from server Motion.refresh(motion); + obj.revert(); var message = ''; for (var e in error.data) { message += e + ': ' + error.data[e] + ' '; diff --git a/openslides/motions/static/js/motions/site.js b/openslides/motions/static/js/motions/site.js index 5b9f0b612..18908441e 100644 --- a/openslides/motions/static/js/motions/site.js +++ b/openslides/motions/static/js/motions/site.js @@ -397,7 +397,7 @@ angular.module('OpenSlidesApp.motions.site', [ required: false }, data: { - tinymceOption: Editor.getOptions() + ckeditorOptions: Editor.getOptions() } } ]; @@ -492,7 +492,7 @@ angular.module('OpenSlidesApp.motions.site', [ required: true }, data: { - tinymceOption: Editor.getOptions(images) + ckeditorOptions: Editor.getOptions(images) } }, { @@ -502,7 +502,7 @@ angular.module('OpenSlidesApp.motions.site', [ label: gettextCatalog.getString('Reason'), }, data: { - tinymceOption: Editor.getOptions(images) + ckeditorOptions: Editor.getOptions(images) } }, { diff --git a/openslides/motions/static/templates/motions/motion-detail/view-original.html b/openslides/motions/static/templates/motions/motion-detail/view-original.html index 7c33cba43..790a8fc84 100644 --- a/openslides/motions/static/templates/motions/motion-detail/view-original.html +++ b/openslides/motions/static/templates/motions/motion-detail/view-original.html @@ -1,30 +1,23 @@ - -

-
-
+ +
+
-
-
The text has been changed.
+
- - -
-
-
-
    diff --git a/openslides/topics/static/js/topics/site.js b/openslides/topics/static/js/topics/site.js index d17e32d72..ba4621364 100644 --- a/openslides/topics/static/js/topics/site.js +++ b/openslides/topics/static/js/topics/site.js @@ -118,7 +118,7 @@ angular.module('OpenSlidesApp.topics.site', ['OpenSlidesApp.topics']) label: gettextCatalog.getString('Text') }, data: { - tinymceOption: Editor.getOptions(images) + ckeditorOptions: Editor.getOptions(images) } }]; // attachments diff --git a/openslides/users/static/js/users/site.js b/openslides/users/static/js/users/site.js index 6868f9217..dd10e3ea8 100644 --- a/openslides/users/static/js/users/site.js +++ b/openslides/users/static/js/users/site.js @@ -446,7 +446,7 @@ angular.module('OpenSlidesApp.users.site', [ label: gettextCatalog.getString('About me'), }, data: { - tinymceOption: Editor.getOptions(images) + ckeditorOptions: Editor.getOptions(images) }, hideExpression: '!model.more' } @@ -801,7 +801,7 @@ angular.module('OpenSlidesApp.users.site', [ 'user', function($scope, $state, Editor, User, user) { $scope.user = user; // autoupdate is not activated - $scope.tinymceOption = Editor.getOptions(); + $scope.ckeditorOptions = Editor.getOptions(); $scope.save = function (user) { User.save(user).then( function(success) { diff --git a/openslides/users/static/templates/users/user-detail-profile.html b/openslides/users/static/templates/users/user-detail-profile.html index 159e93fca..0df2341b5 100644 --- a/openslides/users/static/templates/users/user-detail-profile.html +++ b/openslides/users/static/templates/users/user-detail-profile.html @@ -37,7 +37,7 @@
-