diff --git a/bower.json b/bower.json index eb398b69a..c0e9df018 100644 --- a/bower.json +++ b/bower.json @@ -26,6 +26,8 @@ "font-awesome-bower": "~4.4.0", "js-data": "~2.8.1", "js-data-angular": "~3.1.0", - "ng-file-upload": "~9.1.2" + "ng-file-upload": "~9.1.2", + "ckeditor": "~4.5.4", + "angular-ckeditor": "~1.0.0" } } diff --git a/gulpfile.js b/gulpfile.js index 9a7240997..dc836ba95 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -33,7 +33,7 @@ var output_directory = path.join('openslides', 'static'); // Catches all JavaScript files from all bower components and concats them to // one file js/openslides-libs.js. In production mode the file is uglified. -gulp.task('js-libs', function() { +gulp.task('js-libs', function () { return gulp.src(mainBowerFiles({ filter: /\.js$/ })) @@ -44,7 +44,7 @@ gulp.task('js-libs', function() { // Catches all CSS files from all bower components and concats them to one file // css/openslides-libs.css. In production mode the file is uglified. -gulp.task('css-libs', function() { +gulp.task('css-libs', function () { return gulp.src(mainBowerFiles({ filter: /\.css$/ })) @@ -61,8 +61,14 @@ gulp.task('fonts-libs', function() { .pipe(gulp.dest(path.join(output_directory, 'fonts'))); }); +// Extra task only for CKEditor +gulp.task('ckeditor', function () { + return gulp.src(path.join('bower_components', 'ckeditor', '**')) + .pipe(gulp.dest(path.join(output_directory, 'ckeditor'))); +}); + // Gulp default task. Runs all other tasks before. -gulp.task('default', ['js-libs', 'css-libs', 'fonts-libs'], function() {}); +gulp.task('default', ['js-libs', 'css-libs', 'fonts-libs', 'ckeditor'], function () {}); /** @@ -90,7 +96,7 @@ gulp.task('translations', function () { }); // Checks JavaScript using JSHint -gulp.task( 'jshint', function() { +gulp.task( 'jshint', function () { return gulp.src([ 'gulpfile.js', path.join( 'openslides', '*', 'static', '**', '*.js' ) ]) .pipe(jshint()) .pipe(jshint.reporter('default')); diff --git a/openslides/core/static/js/core/base.js b/openslides/core/static/js/core/base.js index 5c1053d36..fd9d760d1 100644 --- a/openslides/core/static/js/core/base.js +++ b/openslides/core/static/js/core/base.js @@ -227,6 +227,26 @@ angular.module('OpenSlidesApp.core', [ }; } ]) + +/* Options for CKEditor used in various create and edit views. */ +.value('CKEditorOptions', { + allowedContent: 'h1 h2 h3 p pre b i u strike strong em; a[!href]; ol ul{list-style}; li; span{color,background-color}; img;', + removePlugins: 'save, print, preview, pagebreak, templates, showblocks, magicline', + // TODO extraPlugins: 'insertpre', // see http://ckeditor.com/addon/insertpre + toolbar: 'Full', + toolbar_Full: [ + {'name': 'document', 'items': ['Source', '-', 'Save', 'DocProps', 'Preview', 'Print', '-', 'Templates']}, + {'name': 'clipboard', 'items': ['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo']}, + {'name': 'editing', 'items': ['Find', 'Replace', '-', 'SpellChecker', 'Scayt']}, + {'name': 'basicstyles', 'items': ['Bold', 'Italic', 'Underline', 'Strike', '-', 'RemoveFormat']}, + {'name': 'paragraph', 'items': ['NumberedList', 'BulletedList', '-', 'InsertPre']}, + {'name': 'links', 'items': ['Link', 'Unlink']}, + {'name': 'styles', 'items': ['Format', 'TextColor', 'BGColor']}, + {'name': 'tools', 'items': ['Maximize', 'ShowBlocks', '-', 'About']}, + {'name': 'images', 'items': ['Image']} + ] +}) + // Make sure that the DS factories are loaded by making them a dependency .run(['Projector', 'Config', 'Tag', 'Customslide', function(Projector, Config, Tag, Customslide){}]); diff --git a/openslides/core/static/js/core/site.js b/openslides/core/static/js/core/site.js index 30a5f6ebb..5946bd4bd 100644 --- a/openslides/core/static/js/core/site.js +++ b/openslides/core/static/js/core/site.js @@ -14,6 +14,7 @@ angular.module('OpenSlidesApp.core.site', [ 'ngSanitize', // TODO: only use this in functions that need it. 'ui.select', 'xeditable', + 'ckeditor', ]) // Provider to register entries for the main menu. @@ -663,27 +664,42 @@ angular.module('OpenSlidesApp.core.site', [ Customslide.loadRelations(customslide, 'agenda_item'); }) -.controller('CustomslideCreateCtrl', function($scope, $state, Customslide) { - $scope.customslide = {}; - $scope.save = function (customslide) { - Customslide.create(customslide).then( - function(success) { - $state.go('core.customslide.list'); - } - ); - }; -}) +.controller('CustomslideCreateCtrl', [ + '$scope', + '$state', + 'CKEditorOptions', + 'Customslide', + function($scope, $state, CKEditorOptions, Customslide) { + $scope.customslide = {}; + $scope.CKEditorOptions = CKEditorOptions; + $scope.save = function (customslide) { + Customslide.create(customslide).then( + function(success) { + $state.go('core.customslide.list'); + } + ); + }; + } +]) -.controller('CustomslideUpdateCtrl', function($scope, $state, Customslide, customslide) { - $scope.customslide = customslide; - $scope.save = function (customslide) { - Customslide.save(customslide).then( - function(success) { - $state.go('core.customslide.list'); - } - ); - }; -}) +.controller('CustomslideUpdateCtrl', [ + '$scope', + '$state', + 'CKEditorOptions', + 'Customslide', + 'customslide', + function($scope, $state, CKEditorOptions, Customslide, customslide) { + $scope.customslide = customslide; + $scope.CKEditorOptions = CKEditorOptions; + $scope.save = function (customslide) { + Customslide.save(customslide).then( + function(success) { + $state.go('core.customslide.list'); + } + ); + }; + } +]) // Tag Controller .controller('TagListCtrl', function($scope, Tag) { diff --git a/openslides/core/static/templates/core/customslide-form.html b/openslides/core/static/templates/core/customslide-form.html index 13b0050da..26dcfee16 100644 --- a/openslides/core/static/templates/core/customslide-form.html +++ b/openslides/core/static/templates/core/customslide-form.html @@ -14,8 +14,8 @@