diff --git a/.travis.yml b/.travis.yml index a3fda8cee..4d1f4f82f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,6 +14,7 @@ install: script: - "flake8 openslides tests" - "isort --check-only --recursive openslides tests" + - "gulp jshint" - "DJANGO_SETTINGS_MODULE='tests.settings' coverage run ./manage.py test tests.unit" - "coverage report --fail-under=40" diff --git a/gulpfile.js b/gulpfile.js index 61f13018b..45d21c04a 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -84,13 +84,19 @@ gulp.task('tinymce-i18n', function () { 'bower_components/tinymce-i18n/langs/pt_PT.js', ]) .pipe(rename(function (path) { - if (path.basename === 'pt_PT') {path.basename = 'pt'} - if (path.basename === 'fr_FR') {path.basename = 'fr'} + 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'))); }); +// Combines all TinyMCE related tasks. +gulp.task('tinymce', ['tinymce-skins', 'tinymce-i18n'], function () {}); + // Compiles translation files (*.po) to *.json and saves them in the directory // openslides/static/i18n/. gulp.task('translations', function () { @@ -102,7 +108,7 @@ gulp.task('translations', function () { }); // Gulp default task. Runs all other tasks before. -gulp.task('default', ['js-libs', 'css-libs', 'fonts-libs', 'tinymce-skins', 'tinymce-i18n', 'translations'], function () {}); +gulp.task('default', ['js-libs', 'css-libs', 'fonts-libs', 'tinymce', 'translations'], function () {}); /** @@ -123,7 +129,13 @@ gulp.task('pot', function () { // Checks JavaScript using JSHint gulp.task('jshint', function () { - return gulp.src([ 'gulpfile.js', path.join( 'openslides', '*', 'static', '**', '*.js' ) ]) + return gulp.src([ + 'gulpfile.js', + path.join( 'openslides', '*', 'static', '**', '*.js' ), + '!' + path.join( 'openslides', 'users', 'static', 'js', 'users', 'site.js' ), + '!' + path.join( 'openslides', 'motions', 'static', 'js', 'motions', 'base.js' ), + '!' + path.join( 'openslides', 'motions', 'static', 'js', 'motions', 'site.js' ), + ]) .pipe(jshint()) .pipe(jshint.reporter('default')); }); diff --git a/openslides/agenda/static/js/agenda/site.js b/openslides/agenda/static/js/agenda/site.js index 83b722f55..594181d74 100644 --- a/openslides/agenda/static/js/agenda/site.js +++ b/openslides/agenda/static/js/agenda/site.js @@ -279,7 +279,7 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda']) if (action == 'remove') { return ($.inArray(operator.user.id, nextUsers) != -1); } - } + }; // begin speech of selected/next speaker $scope.beginSpeech = function (speakerId) { @@ -304,12 +304,12 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda']) }; // gets speech duration of selected speaker in seconds $scope.getDuration = function (speaker) { - var beginTimestamp = new Date(speaker.begin_time).getTime() - var endTimestamp = new Date(speaker.end_time).getTime() + var beginTimestamp = new Date(speaker.begin_time).getTime(); + var endTimestamp = new Date(speaker.end_time).getTime(); // calculate duration in seconds return Math.floor((endTimestamp - beginTimestamp) / 1000); - } + }; // save reordered list of speakers $scope.treeOptions = { dropped: function (event) { @@ -387,7 +387,7 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda']) // *** CSV import *** // set initial data for csv import - $scope.items = [] + $scope.items = []; $scope.separator = ','; $scope.encoding = 'UTF-8'; $scope.encodingOptions = ['UTF-8', 'ISO-8859-1']; @@ -494,7 +494,7 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda']) element.href = 'data:text/csv;charset=utf-8,' + csvString; element.download = 'agenda-example.csv'; element.target = '_blank'; - } + }; } ]); diff --git a/openslides/assignments/static/js/assignments/base.js b/openslides/assignments/static/js/assignments/base.js index 22a63781e..bd9fa86c0 100644 --- a/openslides/assignments/static/js/assignments/base.js +++ b/openslides/assignments/static/js/assignments/base.js @@ -67,7 +67,7 @@ angular.module('OpenSlidesApp.assignments', []) } } }, - }) + }); } ]) @@ -131,7 +131,7 @@ angular.module('OpenSlidesApp.assignments', []) } } }, - }) + }); } ]) @@ -148,7 +148,7 @@ angular.module('OpenSlidesApp.assignments', []) } } } - }) + }); } ]) diff --git a/openslides/assignments/static/js/assignments/site.js b/openslides/assignments/static/js/assignments/site.js index d7e31e766..baab1a2a7 100644 --- a/openslides/assignments/static/js/assignments/site.js +++ b/openslides/assignments/static/js/assignments/site.js @@ -99,8 +99,9 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments']) return { // ngDialog for assignment form getDialog: function (assignment) { + var resolve; if (assignment) { - var resolve = { + resolve = { assignment: function() { return assignment; }, @@ -116,7 +117,7 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments']) closeByEscape: false, closeByDocument: false, resolve: (resolve) ? resolve : null - } + }; }, // angular-formly fields for assignment form getFormFields: function () { @@ -162,7 +163,7 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments']) hide: !operator.hasPerms('assignments.can_manage') }]; } - } + }; } ]) @@ -195,9 +196,9 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments']) assignment.description, $scope.phases[assignment.phase].display_name, _.map(assignment.assignment_related_users, - function (candidate) {return candidate.user.get_short_name()}).join(" "), + function (candidate) {return candidate.user.get_short_name();}).join(" "), ].join(" "); - } + }; // open new/edit dialog $scope.openDialog = function (assignment) { @@ -338,13 +339,13 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments']) $scope.updatePhase = function (phase_id) { assignment.phase = phase_id; Assignment.save(assignment); - } + }; // create new ballot $scope.createBallot = function () { $http.post('/rest/assignments/assignment/' + assignment.id + '/create_poll/') .success(function(data){ $scope.alert.show = false; - if (assignment.phase == 0) { + if (assignment.phase === 0) { $scope.updatePhase(1); } }) @@ -355,7 +356,7 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments']) // delete ballot $scope.deleteBallot = function (poll) { poll.DSDestroy(); - } + }; // edit poll dialog $scope.editPollDialog = function (poll, ballot) { ngDialog.open({ @@ -396,8 +397,13 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments']) if (reverse) { $http.delete( '/rest/assignments/assignment/' + assignment.id + '/mark_elected/', - {headers: {'Content-Type': 'application/json'}, - data: JSON.stringify({user: user})}) + { + headers: { + 'Content-Type': 'application/json' + }, + data: JSON.stringify({user: user}) + } + ); } else { $http.post('/rest/assignments/assignment/' + assignment.id + '/mark_elected/', {'user': user}) .then(function(success) { @@ -414,7 +420,9 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments']) }; // Just mark some vote value strings for translation. - gettext('Yes'), gettext('No'), gettext('Abstain'); + gettext('Yes'); + gettext('No'); + gettext('Abstain'); } ]) @@ -518,8 +526,9 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments']) // add dynamic form fields assignmentpoll.options.forEach(function(option) { + var defaultValue; if (assignmentpoll.yesnoabstain) { - var defaultValue = { + defaultValue = { 'yes': '', 'no': '', 'abstain': '' @@ -565,7 +574,6 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments']) defaultValue: defaultValue.abstain }); } else { - var defaultValue; if (option.votes.length) { defaultValue = option.votes[0].weight; } diff --git a/openslides/core/static/js/core/base.js b/openslides/core/static/js/core/base.js index 91b1cbe62..5b06c1c80 100644 --- a/openslides/core/static/js/core/base.js +++ b/openslides/core/static/js/core/base.js @@ -99,7 +99,7 @@ angular.module('OpenSlidesApp.core', [ if (language.code == current) language.selected = true; }); - return languages + return languages; }, // get detected browser language code getBrowserLanguage: function () { @@ -125,7 +125,7 @@ angular.module('OpenSlidesApp.core', [ }); return languages; } - } + }; } ]) @@ -157,7 +157,7 @@ angular.module('OpenSlidesApp.core', [ } }); } - } + }; } ]) @@ -425,7 +425,7 @@ angular.module('OpenSlidesApp.core', [ return Array.prototype.filter.call(array, function (item) { return getFilterString(item).toLowerCase().indexOf(string.toLowerCase()) > -1; }); - } + }; } ]) diff --git a/openslides/core/static/js/core/site.js b/openslides/core/static/js/core/site.js index a3d045bc9..b06b2cb0a 100644 --- a/openslides/core/static/js/core/site.js +++ b/openslides/core/static/js/core/site.js @@ -259,7 +259,7 @@ angular.module('OpenSlidesApp.core.site', [ controller: 'CustomslideUpdateCtrl', className: 'ngdialog-theme-default wide-form', resolve: { - customslide: function() {return Customslide.find($stateParams.id) } + customslide: function() {return Customslide.find($stateParams.id);} }, preCloseCallback: function() { $state.go('core.customslide.detail', {customslide: $stateParams.id}); @@ -385,7 +385,7 @@ angular.module('OpenSlidesApp.core.site', [ 'link image charmap table | code preview fullscreen' }; } - } + }; } ]) @@ -424,7 +424,7 @@ angular.module('OpenSlidesApp.core.site', [ $scope.reset = function () { $scope.value = $scope.default_value; $scope.save(field.key, $scope.value); - } + }; } }; } @@ -502,7 +502,7 @@ angular.module('OpenSlidesApp.core.site', [ $scope.search = function(query) { $scope.query = ''; $state.go('search', {q: query}); - } + }; } ]) // Search Controller @@ -523,9 +523,9 @@ angular.module('OpenSlidesApp.core.site', [ data.urlParam = {id: element.id}; $scope.results.push(data); }); - }) + }); }); - } + }; // run search with get parameter from url if ($stateParams.q) { @@ -551,7 +551,7 @@ angular.module('OpenSlidesApp.core.site', [ customslide: function(Customslide) {return Customslide.find(customslide.id);} }; } - resolve.mediafiles = function(Mediafile) {return Mediafile.findAll();} + resolve.mediafiles = function(Mediafile) {return Mediafile.findAll();}; return { template: 'static/templates/core/customslide-form.html', controller: (customslide) ? 'CustomslideUpdateCtrl' : 'CustomslideCreateCtrl', @@ -559,7 +559,7 @@ angular.module('OpenSlidesApp.core.site', [ closeByEscape: false, closeByDocument: false, resolve: (resolve) ? resolve : null - } + }; }, getFormFields: function () { var images = Mediafile.getAllImages(); @@ -605,7 +605,7 @@ angular.module('OpenSlidesApp.core.site', [ }, ]; } - } + }; } ]) @@ -999,7 +999,7 @@ angular.module('OpenSlidesApp.core.site', [ $scope.chatboxIsCollapsed = !$scope.chatboxIsCollapsed; NewChatMessages = []; $scope.unreadMessages = NewChatMessages.length; - } + }; $scope.sendMessage = function () { angular.element('#messageSendButton').addClass('disabled'); angular.element('#messageInput').attr('disabled', ''); @@ -1027,7 +1027,7 @@ angular.module('OpenSlidesApp.core.site', [ $scope.unreadMessages = NewChatMessages.length; } } - }) + }); } ]) diff --git a/openslides/mediafiles/static/js/mediafiles/base.js b/openslides/mediafiles/static/js/mediafiles/base.js index cd0e266cd..af1e7749c 100644 --- a/openslides/mediafiles/static/js/mediafiles/base.js +++ b/openslides/mediafiles/static/js/mediafiles/base.js @@ -13,7 +13,7 @@ angular.module('OpenSlidesApp.mediafiles', []) name: name, useClass: jsDataModel, getAllImages: function () { - var images = [] + var images = []; angular.forEach(this.getAll(), function(file) { if (file.is_image) { images.push({title: file.title, value: file.mediafileUrl}); diff --git a/openslides/mediafiles/static/js/mediafiles/projector.js b/openslides/mediafiles/static/js/mediafiles/projector.js index e40fe83f9..da8ead3f7 100644 --- a/openslides/mediafiles/static/js/mediafiles/projector.js +++ b/openslides/mediafiles/static/js/mediafiles/projector.js @@ -22,7 +22,7 @@ angular.module('OpenSlidesApp.mediafiles.projector', ['OpenSlidesApp.mediafiles' mediafile.then(function(mediafile) { $scope.pdfName = mediafile.title; $scope.pdfUrl = mediafile.mediafileUrl; - }) + }); } ]); diff --git a/openslides/mediafiles/static/js/mediafiles/site.js b/openslides/mediafiles/static/js/mediafiles/site.js index ee2f0b6d9..bbba1cd8b 100644 --- a/openslides/mediafiles/static/js/mediafiles/site.js +++ b/openslides/mediafiles/static/js/mediafiles/site.js @@ -40,7 +40,7 @@ angular.module('OpenSlidesApp.mediafiles.site', ['ngFileUpload', 'OpenSlidesApp. return User.findAll(); }, } - }) + }); } ]) @@ -62,7 +62,7 @@ angular.module('OpenSlidesApp.mediafiles.site', ['ngFileUpload', 'OpenSlidesApp. $scope.reverse = false; function updatePresentedMediafiles() { - var projectorElements = _.map(Projector.get(1).elements, function(element) { return element }); + var projectorElements = _.map(Projector.get(1).elements, function(element) { return element; }); $scope.presentedMediafiles = _.filter(projectorElements, function (element) { return element.name === 'mediafiles/mediafile'; }); @@ -94,7 +94,7 @@ angular.module('OpenSlidesApp.mediafiles.site', ['ngFileUpload', 'OpenSlidesApp. mediafile.mediafile.name, mediafile.uploader.get_short_name() ].join(" "); - } + }; // open new/edit dialog $scope.openDialog = function (mediafile) { @@ -242,7 +242,7 @@ angular.module('OpenSlidesApp.mediafiles.site', ['ngFileUpload', 'OpenSlidesApp. $scope.alert = {type: 'danger', msg: message, show: true}; } ); - } + }; } ]) @@ -286,7 +286,7 @@ angular.module('OpenSlidesApp.mediafiles.site', ['ngFileUpload', 'OpenSlidesApp. $scope.alert = {type: 'danger', msg: message, show: true}; } ); - } + }; } ]) @@ -301,8 +301,9 @@ angular.module('OpenSlidesApp.mediafiles.site', ['ngFileUpload', 'OpenSlidesApp. return { // ngDialog for mediafile form getDialog: function (mediafile) { + var resolve; if (mediafile) { - var resolve = { + resolve = { mediafile: function(Assignment) {return mediafile;} }; } @@ -313,7 +314,7 @@ angular.module('OpenSlidesApp.mediafiles.site', ['ngFileUpload', 'OpenSlidesApp. closeByEscape: false, closeByDocument: false, resolve: (resolve) ? resolve : null - } + }; }, // upload selected file (used by create view only) uploadFile: function (mediafile) {