From 0fa67552247b2d29a6ca438c2605b8db2bbdbab7 Mon Sep 17 00:00:00 2001 From: Bernhard Posselt Date: Wed, 21 May 2014 23:43:28 +0200 Subject: es6 all the things --- js/.jshintrc | 43 + js/Gruntfile.js | 78 +- js/app/App.js | 2 +- js/app/Config.js | 25 +- js/app/Run.js | 44 +- js/bower.json | 3 +- js/build/app.js | 1072 +++++++------ js/controller/AppController.js | 6 +- js/controller/ContentController.js | 7 +- js/gui/keyboardshortcuts.js | 100 +- js/karma.conf.js | 34 +- js/package.json | 8 +- js/service/FeedResource.js | 12 +- js/service/FolderResource.js | 12 +- js/service/ItemResource.js | 45 +- js/service/Loading.js | 4 +- js/service/Publisher.js | 28 +- js/service/Resource.js | 68 +- js/service/Settings.js | 13 +- js/tests/e2e/main.js | 7 +- js/tests/unit/controller/AppControllerSpec.js | 14 +- js/tests/unit/controller/ContentControllerSpec.js | 8 +- js/tests/unit/service/ItemResourceSpec.js | 8 +- js/tests/unit/service/LoadingSpec.js | 6 +- js/tests/unit/service/PublisherSpec.js | 10 +- js/tests/unit/service/ResourceSpec.js | 109 +- js/tests/unit/service/SettingsSpec.js | 6 +- js/tests/unit/stubs/App.js | 15 + js/tests/unit/stubs/OC.js | 16 + js/tests/unit/stubs/app.js | 10 - js/tests/unit/stubs/oc.js | 16 - js/vendor/traceur-runtime/.bower.json | 22 + js/vendor/traceur-runtime/README.md | 35 + js/vendor/traceur-runtime/traceur-runtime.js | 1712 +++++++++++++++++++++ js/vendor/traceur-runtime/traceur-runtime.min.js | 2 + js/vendor/traceur-runtime/traceur-runtime.min.map | 1 + 36 files changed, 2704 insertions(+), 897 deletions(-) create mode 100644 js/.jshintrc create mode 100644 js/tests/unit/stubs/App.js create mode 100644 js/tests/unit/stubs/OC.js delete mode 100644 js/tests/unit/stubs/app.js delete mode 100644 js/tests/unit/stubs/oc.js create mode 100644 js/vendor/traceur-runtime/.bower.json create mode 100644 js/vendor/traceur-runtime/README.md create mode 100644 js/vendor/traceur-runtime/traceur-runtime.js create mode 100644 js/vendor/traceur-runtime/traceur-runtime.min.js create mode 100644 js/vendor/traceur-runtime/traceur-runtime.min.map diff --git a/js/.jshintrc b/js/.jshintrc new file mode 100644 index 000000000..cd85aa807 --- /dev/null +++ b/js/.jshintrc @@ -0,0 +1,43 @@ +{ + "esnext": true, + "bitwise": false, + "camelcase": true, + "curly": true, + "eqeqeq": true, + "forin": false, + "immed": true, + "indent": 4, + "latedef": true, + "newcap": true, + "noarg": true, + "noempty": true, + "nonew": true, + "plusplus": true, + "quotmark": "single", + "undef": false, + "unused": true, + "strict": true, + "maxparams": false, + "maxdepth": 3, + "maxlen": 80, + "browser": true, + "devel": true, + "jquery": true, + "globals": { + "angular": true, + "app": true, + "OC": true, + "csrfToken": true, + "inject": true, + "module": true, + "protractor": true, + "browser": true, + "By": true, + "jasmine": true, + "it": true, + "describe": true, + "beforeEach": true, + "expect": true, + "exports": true + } +} diff --git a/js/Gruntfile.js b/js/Gruntfile.js index 1baf2d7d1..e40900f5a 100644 --- a/js/Gruntfile.js +++ b/js/Gruntfile.js @@ -7,36 +7,6 @@ * @author Bernhard Posselt * @copyright Bernhard Posselt 2012, 2014 */ - -var globals = [ - // libs - '$', - 'jQuery', - 'angular', - // app - 'app', - // ownCloud - 'OC', - 'oc_requesttoken', - // angular - 'inject', - 'module', - - // protractor - 'protractor', - 'browser', - 'By', - // jasmine - 'jasmine', - 'it', - 'describe', - 'beforeEach', - 'expect', - // js - 'console', - 'exports' -]; - module.exports = function (grunt) { 'use strict'; @@ -44,11 +14,12 @@ module.exports = function (grunt) { grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-contrib-connect'); - grunt.loadNpmTasks('grunt-jslint'); + grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-phpunit'); grunt.loadNpmTasks('grunt-wrap'); grunt.loadNpmTasks('grunt-karma'); grunt.loadNpmTasks('grunt-ngmin'); + grunt.loadNpmTasks('grunt-traceur'); grunt.loadNpmTasks('grunt-protractor-runner'); grunt.loadNpmTasks('grunt-protractor-webdriver'); @@ -72,7 +43,6 @@ module.exports = function (grunt) { 'filter/**/*.js', 'service/**/*.js', 'gui/**/*.js', - 'model/**/*.js', 'directive/**/*.js' ], dest: '<%= meta.production %>app.js' @@ -84,37 +54,50 @@ module.exports = function (grunt) { dest: '<%= meta.production %>app.js' } }, + traceur: { + app: { + files: { + '<%= meta.production %>app.js': ['<%= meta.production %>app.js'] + } + }, + options: { + blockBinding: true, + sourceMap: false, + experimental: true, + modules: 'inline' + } + }, wrap: { basic: { src: ['<%= meta.production %>app.js'], dest: '<%= meta.production %>app.js', options: { wrapper: [ - '(function(angular, $, OC, oc_requesttoken, undefined){\n\n\'use strict\';\n\n', - '\n})(angular, jQuery, OC, oc_requesttoken);' + '(function(window, document, angular, $, OC, ' + + 'csrfToken, undefined){\n\n\'use strict\';\n\n', + + '\n})(window, document, angular, jQuery, OC, ' + + 'oc_requesttoken);' ] } } }, - jslint: { - browser: { + jshint: { + app: { src: [ - 'app/**/*.js', + 'app/Config.js', + 'app/Run.js', 'filter/**/*.js', 'service/**/*.js', 'model/**/*.js', 'controller/**/*.js', 'directive/**/*.js', 'tests/**/*.js', - 'gui/**/*.js', - 'Gruntfile.js', - 'karma.conf.js', - 'protractor*conf.js' - ], - directives: { - browser: true, - predef: globals - } + 'gui/**/*.js' + ] + }, + options: { + jshintrc: true } }, watch: { @@ -146,7 +129,6 @@ module.exports = function (grunt) { karma: { unit: { configFile: 'karma.conf.js', - browsers: ['PhantomJS'], autoWatch: true }, continuous: { @@ -199,7 +181,7 @@ module.exports = function (grunt) { }); // make tasks available under simpler commands - grunt.registerTask('default', ['jslint', 'concat', 'ngmin', 'wrap']); + grunt.registerTask('default', ['jshint', 'concat', 'wrap', 'traceur', 'ngmin']); grunt.registerTask('dev', ['watch:concat']); grunt.registerTask('test', ['karma:unit']); grunt.registerTask('phpunit', ['watch:phpunit']); diff --git a/js/app/App.js b/js/app/App.js index 947a68a2e..3dbc907da 100644 --- a/js/app/App.js +++ b/js/app/App.js @@ -7,4 +7,4 @@ * @author Bernhard Posselt * @copyright Bernhard Posselt 2014 */ -var app = angular.module('News', ['ngRoute', 'ngSanitize', 'ngAnimate']); \ No newline at end of file +let app = angular.module('News', ['ngRoute', 'ngSanitize', 'ngAnimate']); \ No newline at end of file diff --git a/js/app/Config.js b/js/app/Config.js index 5581af0e4..bd38f897b 100644 --- a/js/app/Config.js +++ b/js/app/Config.js @@ -9,10 +9,8 @@ */ app.config(function ($routeProvider, $provide, $httpProvider) { 'use strict'; - var getResolve, - feedType; - feedType = { + let feedType = { FEED: 0, FOLDER: 1, STARRED: 2, @@ -21,17 +19,17 @@ app.config(function ($routeProvider, $provide, $httpProvider) { }; // constants - $provide.constant('REFRESH_RATE', 60); // seconds, how often feeds and folders shoudl be refreshed + $provide.constant('REFRESH_RATE', 60); // seconds $provide.constant('ITEM_BATCH_SIZE', 50); // how many items to autopage by $provide.constant('BASE_URL', OC.generateUrl('/apps/news')); $provide.constant('FEED_TYPE', feedType); // make sure that the CSRF header is only sent to the ownCloud domain - $provide.factory('CSRFInterceptor', function ($q, BASE_URL) { + $provide.factory('CSRFInterceptor', ($q, BASE_URL) => { return { - request: function (config) { + request: (config) => { if (config.url.indexOf(BASE_URL) === 0) { - config.headers.requesttoken = oc_requesttoken; + config.headers.requesttoken = csrfToken; } return config || $q.when(config); @@ -41,7 +39,7 @@ app.config(function ($routeProvider, $provide, $httpProvider) { $httpProvider.interceptors.push('CSRFInterceptor'); // routing - getResolve = function (type) { + let getResolve = (type) => { return { // request to items also returns feeds data: [ @@ -50,12 +48,9 @@ app.config(function ($routeProvider, $provide, $httpProvider) { '$q', 'BASE_URL', 'ITEM_BATCH_SIZE', - function ($http, $route, $q, BASE_URL, ITEM_BATCH_SIZE) { + ($http, $route, $q, BASE_URL, ITEM_BATCH_SIZE) => { - var parameters, - deferred; - - parameters = { + let parameters = { type: type, limit: ITEM_BATCH_SIZE }; @@ -64,13 +59,13 @@ app.config(function ($routeProvider, $provide, $httpProvider) { parameters.id = $route.current.params.id; } - deferred = $q.defer(); + let deferred = $q.defer(); $http({ url: BASE_URL + '/items', method: 'GET', params: parameters - }).success(function (data) { + }).success((data) => { deferred.resolve(data); }); diff --git a/js/app/Run.js b/js/app/Run.js index c60150fbe..743f83c9b 100644 --- a/js/app/Run.js +++ b/js/app/Run.js @@ -7,36 +7,34 @@ * @author Bernhard Posselt * @copyright Bernhard Posselt 2014 */ -app.run(function ($rootScope, $location, $http, $q, $interval, Loading, - ItemResource, FeedResource, FolderResource, Settings, - Publisher, BASE_URL, FEED_TYPE, REFRESH_RATE) { +app.run(($rootScope, $location, $http, $q, $interval, Loading, ItemResource, + FeedResource, FolderResource, Settings, Publisher, BASE_URL, FEED_TYPE, + REFRESH_RATE) => { 'use strict'; + console.log($location); + // show Loading screen Loading.setLoading('global', true); // listen to keys in returned queries to automatically distribute the // incoming values to models - Publisher.subscribe(ItemResource).toChannels('items', 'newestItemId', 'starred'); + Publisher.subscribe(ItemResource).toChannels('items', 'newestItemId', + 'starred'); Publisher.subscribe(FolderResource).toChannels('folders'); Publisher.subscribe(FeedResource).toChannels('feeds'); Publisher.subscribe(Settings).toChannels('settings'); // load feeds, settings and last read feed - var settingsDeferred, - activeFeedDeferred, - folderDeferred, - feedDeferred; - - settingsDeferred = $q.defer(); - $http.get(BASE_URL + '/settings').success(function (data) { + let settingsDeferred = $q.defer(); + $http.get(BASE_URL + '/settings').success((data) => { Publisher.publishAll(data); settingsDeferred.resolve(); }); - activeFeedDeferred = $q.defer(); - $http.get(BASE_URL + '/feeds/active').success(function (data) { - var url; + let activeFeedDeferred = $q.defer(); + $http.get(BASE_URL + '/feeds/active').success((data) => { + let url; switch (data.type) { @@ -60,14 +58,14 @@ app.run(function ($rootScope, $location, $http, $q, $interval, Loading, activeFeedDeferred.resolve(); }); - folderDeferred = $q.defer(); - $http.get(BASE_URL + '/folders').success(function (data) { + let folderDeferred = $q.defer(); + $http.get(BASE_URL + '/folders').success((data) => { Publisher.publishAll(data); folderDeferred.resolve(); }); - feedDeferred = $q.defer(); - $http.get(BASE_URL + '/feeds').success(function (data) { + let feedDeferred = $q.defer(); + $http.get(BASE_URL + '/feeds').success((data) => { Publisher.publishAll(data); feedDeferred.resolve(); }); @@ -81,27 +79,27 @@ app.run(function ($rootScope, $location, $http, $q, $interval, Loading, folderDeferred.promise ] ) - .then(function () { + .then(() => { Loading.setLoading('global', false); }); // refresh feeds and folders - $interval(function () { + $interval(() => { $http.get(BASE_URL + '/feeds'); $http.get(BASE_URL + '/folders'); }, REFRESH_RATE * 1000); - $rootScope.$on('$routeChangeStart', function () { + $rootScope.$on('$routeChangeStart', () => { Loading.setLoading('content', true); }); - $rootScope.$on('$routeChangeSuccess', function () { + $rootScope.$on('$routeChangeSuccess', () => { Loading.setLoading('content', false); }); // in case of wrong id etc show all items - $rootScope.$on('$routeChangeError', function () { + $rootScope.$on('$routeChangeError', () => { $location.path('/items'); }); }); \ No newline at end of file diff --git a/js/bower.json b/js/bower.json index 0ed1b0cc4..f48e00076 100644 --- a/js/bower.json +++ b/js/bower.json @@ -30,6 +30,7 @@ "angular-sanitize": "~1.2.16", "jquery": "~2.1.1", "momentjs": "~2.6.0", - "angular-animate": "~1.2.16" + "angular-animate": "~1.2.16", + "traceur-runtime": "~0.0.41" } } diff --git a/js/build/app.js b/js/build/app.js index cad42c8ae..7e68fc320 100644 --- a/js/build/app.js +++ b/js/build/app.js @@ -1,521 +1,569 @@ -(function(angular, $, OC, oc_requesttoken, undefined){ - -'use strict'; - - -var app = angular.module('News', [ - 'ngRoute', - 'ngSanitize', - 'ngAnimate' - ]); -app.config([ - '$routeProvider', - '$provide', - '$httpProvider', - function ($routeProvider, $provide, $httpProvider) { +var $__build_47_app__ = function () { 'use strict'; - var getResolve, feedType; - feedType = { - FEED: 0, - FOLDER: 1, - STARRED: 2, - SUBSCRIPTIONS: 3, - SHARED: 4 - }; - // constants - $provide.constant('REFRESH_RATE', 60); - // seconds, how often feeds and folders shoudl be refreshed - $provide.constant('ITEM_BATCH_SIZE', 50); - // how many items to autopage by - $provide.constant('BASE_URL', OC.generateUrl('/apps/news')); - $provide.constant('FEED_TYPE', feedType); - // make sure that the CSRF header is only sent to the ownCloud domain - $provide.factory('CSRFInterceptor', function ($q, BASE_URL) { - return { - request: function (config) { - if (config.url.indexOf(BASE_URL) === 0) { - config.headers.requesttoken = oc_requesttoken; - } - return config || $q.when(config); - } - }; - }); - $httpProvider.interceptors.push('CSRFInterceptor'); - // routing - getResolve = function (type) { - return { - data: [ - '$http', - '$route', - '$q', - 'BASE_URL', - 'ITEM_BATCH_SIZE', - function ($http, $route, $q, BASE_URL, ITEM_BATCH_SIZE) { - var parameters, deferred; - parameters = { - type: type, - limit: ITEM_BATCH_SIZE + var __moduleName = 'build/app'; + (function (window, document, angular, $, OC, csrfToken, undefined) { + 'use strict'; + var app = angular.module('News', [ + 'ngRoute', + 'ngSanitize', + 'ngAnimate' + ]); + app.config([ + '$routeProvider', + '$provide', + '$httpProvider', + function ($routeProvider, $provide, $httpProvider) { + 'use strict'; + var feedType = { + FEED: 0, + FOLDER: 1, + STARRED: 2, + SUBSCRIPTIONS: 3, + SHARED: 4 + }; + $provide.constant('REFRESH_RATE', 60); + $provide.constant('ITEM_BATCH_SIZE', 50); + $provide.constant('BASE_URL', OC.generateUrl('/apps/news')); + $provide.constant('FEED_TYPE', feedType); + $provide.factory('CSRFInterceptor', function ($q, BASE_URL) { + return { + request: function (config) { + if (config.url.indexOf(BASE_URL) === 0) { + config.headers.requesttoken = csrfToken; + } + return config || $q.when(config); + } }; - if ($route.current.params.id !== undefined) { - parameters.id = $route.current.params.id; + }); + $httpProvider.interceptors.push('CSRFInterceptor'); + var getResolve = function (type) { + return { + data: [ + '$http', + '$route', + '$q', + 'BASE_URL', + 'ITEM_BATCH_SIZE', + function ($http, $route, $q, BASE_URL, ITEM_BATCH_SIZE) { + var parameters = { + type: type, + limit: ITEM_BATCH_SIZE + }; + if ($route.current.params.id !== undefined) { + parameters.id = $route.current.params.id; + } + var deferred = $q.defer(); + $http({ + url: BASE_URL + '/items', + method: 'GET', + params: parameters + }).success(function (data) { + deferred.resolve(data); + }); + return deferred.promise; + } + ] + }; + }; + $routeProvider.when('/items', { + controller: 'ContentController', + templateUrl: 'content.html', + resolve: getResolve(feedType.SUBSCRIPTIONS) + }).when('/items/starred', { + controller: 'ContentController', + templateUrl: 'content.html', + resolve: getResolve(feedType.STARRED) + }).when('/items/feeds/:id', { + controller: 'ContentController', + templateUrl: 'content.html', + resolve: getResolve(feedType.FEED) + }).when('/items/folders/:id', { + controller: 'ContentController', + templateUrl: 'content.html', + resolve: getResolve(feedType.FOLDER) + }).otherwise({ redirectTo: '/items' }); + } + ]); + app.run([ + '$rootScope', + '$location', + '$http', + '$q', + '$interval', + 'Loading', + 'ItemResource', + 'FeedResource', + 'FolderResource', + 'Settings', + 'Publisher', + 'BASE_URL', + 'FEED_TYPE', + 'REFRESH_RATE', + function ($rootScope, $location, $http, $q, $interval, Loading, ItemResource, FeedResource, FolderResource, Settings, Publisher, BASE_URL, FEED_TYPE, REFRESH_RATE) { + 'use strict'; + console.log($location); + Loading.setLoading('global', true); + Publisher.subscribe(ItemResource).toChannels('items', 'newestItemId', 'starred'); + Publisher.subscribe(FolderResource).toChannels('folders'); + Publisher.subscribe(FeedResource).toChannels('feeds'); + Publisher.subscribe(Settings).toChannels('settings'); + var settingsDeferred = $q.defer(); + $http.get(BASE_URL + '/settings').success(function (data) { + Publisher.publishAll(data); + settingsDeferred.resolve(); + }); + var activeFeedDeferred = $q.defer(); + $http.get(BASE_URL + '/feeds/active').success(function (data) { + var url; + switch (data.type) { + case FEED_TYPE.FEED: + url = '/items/feeds/' + data.id; + break; + case FEED_TYPE.FOLDER: + url = '/items/folders/' + data.id; + break; + case FEED_TYPE.STARRED: + url = '/items/starred'; + break; + default: + url = '/items'; } - deferred = $q.defer(); - $http({ - url: BASE_URL + '/items', - method: 'GET', - params: parameters - }).success(function (data) { - deferred.resolve(data); - }); - return deferred.promise; - } - ] - }; - }; - $routeProvider.when('/items', { - controller: 'ContentController', - templateUrl: 'content.html', - resolve: getResolve(feedType.SUBSCRIPTIONS) - }).when('/items/starred', { - controller: 'ContentController', - templateUrl: 'content.html', - resolve: getResolve(feedType.STARRED) - }).when('/items/feeds/:id', { - controller: 'ContentController', - templateUrl: 'content.html', - resolve: getResolve(feedType.FEED) - }).when('/items/folders/:id', { - controller: 'ContentController', - templateUrl: 'content.html', - resolve: getResolve(feedType.FOLDER) - }).otherwise({ redirectTo: '/items' }); - } -]); -app.run([ - '$rootScope', - '$location', - '$http', - '$q', - '$interval', - 'Loading', - 'ItemResource', - 'FeedResource', - 'FolderResource', - 'Settings', - 'Publisher', - 'BASE_URL', - 'FEED_TYPE', - 'REFRESH_RATE', - function ($rootScope, $location, $http, $q, $interval, Loading, ItemResource, FeedResource, FolderResource, Settings, Publisher, BASE_URL, FEED_TYPE, REFRESH_RATE) { - 'use strict'; - // show Loading screen - Loading.setLoading('global', true); - // listen to keys in returned queries to automatically distribute the - // incoming values to models - Publisher.subscribe(ItemResource).toChannels('items', 'newestItemId', 'starred'); - Publisher.subscribe(FolderResource).toChannels('folders'); - Publisher.subscribe(FeedResource).toChannels('feeds'); - Publisher.subscribe(Settings).toChannels('settings'); - // load feeds, settings and last read feed - var settingsDeferred, activeFeedDeferred, folderDeferred, feedDeferred; - settingsDeferred = $q.defer(); - $http.get(BASE_URL + '/settings').success(function (data) { - Publisher.publishAll(data); - settingsDeferred.resolve(); - }); - activeFeedDeferred = $q.defer(); - $http.get(BASE_URL + '/feeds/active').success(function (data) { - var url; - switch (data.type) { - case FEED_TYPE.FEED: - url = '/items/feeds/' + data.id; - break; - case FEED_TYPE.FOLDER: - url = '/items/folders/' + data.id; - break; - case FEED_TYPE.STARRED: - url = '/items/starred'; - break; - default: - url = '/items'; - } - $location.path(url); - activeFeedDeferred.resolve(); - }); - folderDeferred = $q.defer(); - $http.get(BASE_URL + '/folders').success(function (data) { - Publisher.publishAll(data); - folderDeferred.resolve(); - }); - feedDeferred = $q.defer(); - $http.get(BASE_URL + '/feeds').success(function (data) { - Publisher.publishAll(data); - feedDeferred.resolve(); - }); - // disable loading if all initial requests finished - $q.all([ - settingsDeferred.promise, - activeFeedDeferred.promise, - feedDeferred.promise, - folderDeferred.promise - ]).then(function () { - Loading.setLoading('global', false); - }); - // refresh feeds and folders - $interval(function () { - $http.get(BASE_URL + '/feeds'); - $http.get(BASE_URL + '/folders'); - }, REFRESH_RATE * 1000); - $rootScope.$on('$routeChangeStart', function () { - Loading.setLoading('content', true); - }); - $rootScope.$on('$routeChangeSuccess', function () { - Loading.setLoading('content', false); - }); - // in case of wrong id etc show all items - $rootScope.$on('$routeChangeError', function () { - $location.path('/items'); - }); - } -]); -app.controller('AppController', [ - 'Loading', - 'FeedResource', - 'FolderResource', - function (Loading, FeedResource, FolderResource) { - 'use strict'; - this.loading = Loading; - this.isFirstRun = function () { - return FeedResource.size() === 0 && FolderResource.size() === 0; - }; - } -]); -app.controller('ContentController', [ - 'Publisher', - 'FeedResource', - 'ItemResource', - 'data', - function (Publisher, FeedResource, ItemResource, data) { - 'use strict'; - // distribute data to models based on key - Publisher.publishAll(data); - this.getItems = function () { - return ItemResource.getAll(); - }; - this.getFeeds = function () { - return FeedResource.getAll(); - }; - } -]); -app.controller('NavigationController', function () { - 'use strict'; - console.log('here'); -}); -app.controller('SettingsController', function () { - 'use strict'; - console.log('here'); -}); -app.factory('FeedResource', [ - 'Resource', - '$http', - function (Resource, $http) { - 'use strict'; - var FeedResource = function ($http) { - Resource.call(this, 'url', $http); - }; - FeedResource.prototype = Object.create(Resource.prototype); - return new FeedResource($http); - } -]); -app.factory('FolderResource', [ - 'Resource', - '$http', - function (Resource, $http) { - 'use strict'; - var FolderResource = function ($http) { - Resource.call(this, 'name', $http); - }; - FolderResource.prototype = Object.create(Resource.prototype); - return new FolderResource($http); - } -]); -app.factory('ItemResource', [ - 'Resource', - '$http', - function (Resource, $http) { - 'use strict'; - var ItemResource = function ($http) { - Resource.call(this, 'id', $http); - }; - ItemResource.prototype = Object.create(Resource.prototype); - ItemResource.prototype.receive = function (value, channel) { - switch (channel) { - case 'newestItemId': - this.newestItemId = value; - break; - case 'starred': - this.starredCount = value; - break; - default: - Resource.prototype.receive.call(this, value, channel); - } - }; - ItemResource.prototype.getNewestItemId = function () { - return this.newestItemId; - }; - ItemResource.prototype.getStarredCount = function () { - return this.starredCount; - }; - return new ItemResource($http); - } -]); -app.service('Loading', function () { - 'use strict'; - this.loading = { - global: false, - content: false, - autopaging: false - }; - this.setLoading = function (area, isLoading) { - this.loading[area] = isLoading; - }; - this.isLoading = function (area) { - return this.loading[area]; - }; -}); -app.service('Publisher', function () { - 'use strict'; - var self = this; - this.channels = {}; - this.subscribe = function (object) { - return { - toChannels: function () { - var counter, channel; - for (counter = 0; counter < arguments.length; counter += 1) { - channel = arguments[counter]; - self.channels[channel] = self.channels[channel] || []; - self.channels[channel].push(object); + $location.path(url); + activeFeedDeferred.resolve(); + }); + var folderDeferred = $q.defer(); + $http.get(BASE_URL + '/folders').success(function (data) { + Publisher.publishAll(data); + folderDeferred.resolve(); + }); + var feedDeferred = $q.defer(); + $http.get(BASE_URL + '/feeds').success(function (data) { + Publisher.publishAll(data); + feedDeferred.resolve(); + }); + $q.all([ + settingsDeferred.promise, + activeFeedDeferred.promise, + feedDeferred.promise, + folderDeferred.promise + ]).then(function () { + Loading.setLoading('global', false); + }); + $interval(function () { + $http.get(BASE_URL + '/feeds'); + $http.get(BASE_URL + '/folders'); + }, REFRESH_RATE * 1000); + $rootScope.$on('$routeChangeStart', function () { + Loading.setLoading('content', true); + }); + $rootScope.$on('$routeChangeSuccess', function () { + Loading.setLoading('content', false); + }); + $rootScope.$on('$routeChangeError', function () { + $location.path('/items'); + }); + } + ]); + app.controller('AppController', [ + 'Loading', + 'FeedResource', + 'FolderResource', + function (Loading, FeedResource, FolderResource) { + 'use strict'; + this.loading = Loading; + this.isFirstRun = function () { + return FeedResource.size() === 0 && FolderResource.size() === 0; + }; } - } - }; - }; - this.publishAll = function (data) { - var channel, counter; - for (channel in data) { - if (data.hasOwnProperty(channel) && this.channels[channel] !== undefined) { - for (counter = 0; counter < this.channels[channel].length; counter += 1) { - this.channels[channel][counter].receive(data[channel], channel); + ]); + app.controller('ContentController', [ + 'Publisher', + 'FeedResource', + 'ItemResource', + 'data', + function (Publisher, FeedResource, ItemResource, data) { + 'use strict'; + Publisher.publishAll(data); + this.getItems = function () { + return ItemResource.getAll(); + }; + this.getFeeds = function () { + return FeedResource.getAll(); + }; } - } - } - }; -}); -app.factory('Resource', function () { - 'use strict'; - var Resource = function (id, http) { - this.id = id; - this.values = []; - this.hashMap = {}; - this.http = http; - }; - Resource.prototype = { - receive: function (values) { - var self = this; - values.forEach(function (value) { - self.add(value); + ]); + app.controller('NavigationController', function () { + 'use strict'; + console.log('here'); }); - }, - add: function (value) { - var key, existing; - existing = this.hashMap[value[this.id]]; - if (existing === undefined) { - this.values.push(value); - this.hashMap[value[this.id]] = value; - } else { - // copy values from new to old object if it exists already - for (key in value) { - if (value.hasOwnProperty(key)) { - existing[key] = value[key]; - } + app.controller('SettingsController', function () { + 'use strict'; + console.log('here'); + }); + app.factory('FeedResource', [ + 'Resource', + '$http', + function (Resource, $http) { + 'use strict'; + var FeedResource = function FeedResource($http) { + $traceurRuntime.superCall(this, $FeedResource.prototype, 'constructor', [ + 'url', + $http + ]); + }; + var $FeedResource = FeedResource; + $traceurRuntime.createClass(FeedResource, {}, {}, Resource); + return new FeedResource($http); } - } - }, - size: function () { - return this.values.length; - }, - get: function (id) { - return this.hashMap[id]; - }, - delete: function (id) { - // find index of object that should be deleted - var i, deleteAtIndex; - for (i = 0; i < this.values.length; i += 1) { - if (this.values[i][this.id] === id) { - deleteAtIndex = i; - break; + ]); + app.factory('FolderResource', [ + 'Resource', + '$http', + function (Resource, $http) { + 'use strict'; + var FolderResource = function FolderResource($http) { + $traceurRuntime.superCall(this, $FolderResource.prototype, 'constructor', [ + 'name', + $http + ]); + }; + var $FolderResource = FolderResource; + $traceurRuntime.createClass(FolderResource, {}, {}, Resource); + return new FolderResource($http); } - } - if (deleteAtIndex !== undefined) { - this.values.splice(deleteAtIndex, 1); - } - if (this.hashMap[id] !== undefined) { - delete this.hashMap[id]; - } - }, - clear: function () { - this.hashMap = {}; - // http://stackoverflow.com/questions/1232040/how-to-empty-an-array-in-javascript - // this is the fastes way to empty an array when you want to keep the - // reference around - while (this.values.length > 0) { - this.values.pop(); - } - }, - getAll: function () { - return this.values; - } - }; - return Resource; -}); -app.service('Settings', function () { - 'use strict'; - this.settings = {}; - this.receive = function (data) { - var key; - for (key in data) { - if (data.hasOwnProperty(key)) { - this.settings[key] = data[key]; - } - } - }; - this.get = function (key) { - return this.settings[key]; - }; - this.set = function (key, value) { - this.settings[key] = value; - }; -}); -/** - * Code in here acts only as a click shortcut mechanism. That's why its not - * being put into a directive since it has to be tested with protractor - * anyways and theres no benefit from wiring it into the angular app - */ -(function (window, document, $) { - 'use strict'; - var noInputFocused, noModifierKey, scrollArea, scrollToItem, scrollToNextItem, scrollToPreviousItem, toggleStar, toggleUnread, expandItem, openLink, getActiveItem; - scrollArea = $('#app-content'); - noInputFocused = function (element) { - return !(element.is('input') && element.is('select') && element.is('textarea') && element.is('checkbox')); - }; - noModifierKey = function (event) { - return !(event.shiftKey || event.altKey || event.ctrlKey || event.metaKey); - }; - scrollToItem = function (item, scrollArea) { - scrollArea.scrollTop(item.offset().top - scrollArea.offset().top + scrollArea.scrollTop()); - }; - scrollToNextItem = function (scrollArea) { - var items, counter, item; - items = scrollArea.find('.feed_item'); - for (counter = 0; counter < items.length; counter += 1) { - item = $(items[counter]); - if (item.position().top > 1) { - scrollToItem(scrollArea, item); - return; - } - } - // in case this is the last item it should still scroll below the top - scrollArea.scrollTop(scrollArea.prop('scrollHeight')); - }; - scrollToPreviousItem = function (scrollArea) { - var items, item, counter, previous; - items = scrollArea.find('.feed_item'); - for (counter = 0; counter < items.length; counter += 1) { - item = $(items[counter]); - if (item.position().top >= 0) { - previous = item.prev(); - // if there are no items before the current one - if (previous.length > 0) { - scrollToItem(scrollArea, previous); + ]); + app.factory('ItemResource', [ + 'Resource', + '$http', + function (Resource, $http) { + 'use strict'; + var ItemResource = function ItemResource($http) { + $traceurRuntime.superCall(this, $ItemResource.prototype, 'constructor', [ + 'id', + $http + ]); + }; + var $ItemResource = ItemResource; + $traceurRuntime.createClass(ItemResource, { + receive: function (value, channel) { + switch (channel) { + case 'newestItemId': + this.newestItemId = value; + break; + case 'starred': + this.starredCount = value; + break; + default: + $traceurRuntime.superCall(this, $ItemResource.prototype, 'receive', [ + value, + channel + ]); + } + }, + getNewestItemId: function () { + return this.newestItemId; + }, + getStarredCount: function () { + return this.starredCount; + } + }, {}, Resource); + return new ItemResource($http); } - return; - } - } - // if there was no jump jump to the last element - if (items.length > 0) { - scrollToItem(scrollArea, items.last()); - } - }; - getActiveItem = function (scrollArea) { - var items, item, counter; - items = scrollArea.find('.feed_item'); - for (counter = 0; counter < items.length; counter += 1) { - item = $(items[counter]); - // 130px of the item should be visible - if (item.height() + item.position().top > 30) { - return item; - } - } - }; - toggleUnread = function (scrollArea) { - var item = getActiveItem(scrollArea); - item.find('.keep_unread').trigger('click'); - }; - toggleStar = function (scrollArea) { - var item = getActiveItem(scrollArea); - item.find('.item_utils .star').trigger('click'); - }; - expandItem = function (scrollArea) { - var item = getActiveItem(scrollArea); - item.find('.item_heading a').trigger('click'); - }; - openLink = function (scrollArea) { - var item = getActiveItem(scrollArea).find('.item_title a'); - item.trigger('click'); - // mark read - window.open(item.attr('href'), '_blank'); - }; - $(document).keyup(function (event) { - var keyCode; - keyCode = event.keyCode; - if (noInputFocused($(':focus')) && noModifierKey(event)) { - // j, n, right arrow - if ([ - 74, - 78, - 34 - ].indexOf(keyCode) >= 0) { - event.preventDefault(); - scrollToNextItem(scrollArea); // k, p, left arrow - } else if ([ - 75, - 80, - 37 - ].indexOf(keyCode) >= 0) { - event.preventDefault(); - scrollToPreviousItem(scrollArea); // u - } else if ([85].indexOf(keyCode) >= 0) { - event.preventDefault(); - toggleUnread(scrollArea); // e - } else if ([69].indexOf(keyCode) >= 0) { - event.preventDefault(); - expandItem(scrollArea); // s, i, l - } else if ([ - 73, - 83, - 76 - ].indexOf(keyCode) >= 0) { - event.preventDefault(); - toggleStar(scrollArea); // h - } else if ([72].indexOf(keyCode) >= 0) { - event.preventDefault(); - toggleStar(scrollArea); - scrollToNextItem(scrollArea); // o - } else if ([79].indexOf(keyCode) >= 0) { - event.preventDefault(); - openLink(scrollArea); - } - } - }); -}(window, document, jQuery)); - -})(angular, jQuery, OC, oc_requesttoken); \ No newline at end of file + ]); + app.service('Loading', function () { + 'use strict'; + var $__0 = this; + this.loading = { + global: false, + content: false, + autopaging: false + }; + this.setLoading = function (area, isLoading) { + $traceurRuntime.setProperty($__0.loading, area, isLoading); + }; + this.isLoading = function (area) { + return $__0.loading[$traceurRuntime.toProperty(area)]; + }; + }); + app.service('Publisher', function () { + 'use strict'; + var $__0 = this; + this.channels = {}; + this.subscribe = function (obj) { + return { + toChannels: function () { + for (var channels = [], $__4 = 0; $__4 < arguments.length; $__4++) + $traceurRuntime.setProperty(channels, $__4, arguments[$traceurRuntime.toProperty($__4)]); + for (var $__2 = channels[$traceurRuntime.toProperty(Symbol.iterator)](), $__3; !($__3 = $__2.next()).done;) { + try { + throw undefined; + } catch (channel) { + channel = $__3.value; + { + $traceurRuntime.setProperty($__0.channels, channel, $__0.channels[$traceurRuntime.toProperty(channel)] || []); + $__0.channels[$traceurRuntime.toProperty(channel)].push(obj); + } + } + } + } + }; + }; + this.publishAll = function (data) { + for (var $channel in data) { + try { + throw undefined; + } catch (channel) { + channel = $channel; + if ($__0.channels[$traceurRuntime.toProperty(channel)] !== undefined) { + for (var $__2 = $__0.channels[$traceurRuntime.toProperty(channel)][$traceurRuntime.toProperty(Symbol.iterator)](), $__3; !($__3 = $__2.next()).done;) { + try { + throw undefined; + } catch (listener) { + listener = $__3.value; + { + listener.receive(data[$traceurRuntime.toProperty(channel)], channel); + } + } + } + } + } + } + }; + }); + app.factory('Resource', function () { + 'use strict'; + var Resource = function Resource(id, http) { + this.id = id; + this.values = []; + this.hashMap = {}; + this.http = http; + }; + $traceurRuntime.createClass(Resource, { + receive: function (values) { + var $__0 = this; + values.forEach(function (value) { + $__0.add(value); + }); + }, + add: function (value) { + var existing = this.hashMap[$traceurRuntime.toProperty(value[$traceurRuntime.toProperty(this.id)])]; + if (existing === undefined) { + this.values.push(value); + $traceurRuntime.setProperty(this.hashMap, value[$traceurRuntime.toProperty(this.id)], value); + } else { + for (var $key in value) { + try { + throw undefined; + } catch (key) { + key = $key; + if (value.hasOwnProperty(key)) { + $traceurRuntime.setProperty(existing, key, value[$traceurRuntime.toProperty(key)]); + } + } + } + } + }, + size: function () { + return this.values.length; + }, + get: function (id) { + return this.hashMap[$traceurRuntime.toProperty(id)]; + }, + delete: function (id) { + var deleteAtIndex; + { + try { + throw undefined; + } catch ($i) { + $i = 0; + for (; $i < this.values.length; $i += 1) { + try { + throw undefined; + } catch (i) { + i = $i; + try { + if (this.values[$traceurRuntime.toProperty(i)][$traceurRuntime.toProperty(this.id)] === id) { + deleteAtIndex = i; + break; + } + } finally { + $i = i; + } + } + } + } + } + if (deleteAtIndex !== undefined) { + this.values.splice(deleteAtIndex, 1); + } + if (this.hashMap[$traceurRuntime.toProperty(id)] !== undefined) { + delete this.hashMap[$traceurRuntime.toProperty(id)]; + } + }, + clear: function () { + this.hashMap = {}; + while (this.values.length > 0) { + this.values.pop(); + } + }, + getAll: function () { + return this.values; + } + }, {}); + return Resource; + }); + app.service('Settings', function () { + 'use strict'; + var $__0 = this; + this.settings = {}; + this.receive = function (data) { + for (var $key in data) { + try { + throw undefined; + } catch (key) { + key = $key; + $traceurRuntime.setProperty($__0.settings, key, data[$traceurRuntime.toProperty(key)]); + } + } + }; + this.get = function (key) { + return $__0.settings[$traceurRuntime.toProperty(key)]; + }; + this.set = function (key, value) { + $traceurRuntime.setProperty($__0.settings, key, value); + }; + }); + (function (window, document, $) { + 'use strict'; + var scrollArea = $('#app-content'); + var noInputFocused = function (element) { + return !(element.is('input') && element.is('select') && element.is('textarea') && element.is('checkbox')); + }; + var noModifierKey = function (event) { + return !(event.shiftKey || event.altKey || event.ctrlKey || event.metaKey); + }; + var scrollToItem = function (item, scrollArea) { + scrollArea.scrollTop(item.offset().top - scrollArea.offset().top + scrollArea.scrollTop()); + }; + var scrollToNextItem = function (scrollArea) { + var items = scrollArea.find('.feed_item'); + for (var $__2 = items[$traceurRuntime.toProperty(Symbol.iterator)](), $__3; !($__3 = $__2.next()).done;) { + try { + throw undefined; + } catch (item) { + item = $__3.value; + { + item = $(item); + if (item.position().top > 1) { + scrollToItem(scrollArea, item); + return; + } + } + } + } + scrollArea.scrollTop(scrollArea.prop('scrollHeight')); + }; + var scrollToPreviousItem = function (scrollArea) { + var items = scrollArea.find('.feed_item'); + for (var $__2 = items[$traceurRuntime.toProperty(Symbol.iterator)](), $__3; !($__3 = $__2.next()).done;) { + try { + throw undefined; + } catch (item) { + item = $__3.value; + { + item = $(item); + if (item.position().top >= 0) { + try { + throw undefined; + } catch (previous) { + previous = item.prev(); + if (previous.length > 0) { + scrollToItem(scrollArea, previous); + } + return; + } + } + } + } + } + if (items.length > 0) { + scrollToItem(scrollArea, items.last()); + } + }; + var getActiveItem = function (scrollArea) { + var items = scrollArea.find('.feed_item'); + for (var $__2 = items[$traceurRuntime.toProperty(Symbol.iterator)](), $__3; !($__3 = $__2.next()).done;) { + try { + throw undefined; + } catch (item) { + item = $__3.value; + { + item = $(item); + if (item.height() + item.position().top > 30) { + return item; + } + } + } + } + }; + var toggleUnread = function (scrollArea) { + var item = getActiveItem(scrollArea); + item.find('.keep_unread').trigger('click'); + }; + var toggleStar = function (scrollArea) { + var item = getActiveItem(scrollArea); + item.find('.item_utils .star').trigger('click'); + }; + var expandItem = function (scrollArea) { + var item = getActiveItem(scrollArea); + item.find('.item_heading a').trigger('click'); + }; + var openLink = function (scrollArea) { + var item = getActiveItem(scrollArea).find('.item_title a'); + item.trigger('click'); + window.open(item.attr('href'), '_blank'); + }; + $(document).keyup(function (event) { + var keyCode = event.keyCode; + if (noInputFocused($(':focus')) && noModifierKey(event)) { + if ([ + 74, + 78, + 34 + ].indexOf(keyCode) >= 0) { + event.preventDefault(); + scrollToNextItem(scrollArea); + } else if ([ + 75, + 80, + 37 + ].indexOf(keyCode) >= 0) { + event.preventDefault(); + scrollToPreviousItem(scrollArea); + } else if ([85].indexOf(keyCode) >= 0) { + event.preventDefault(); + toggleUnread(scrollArea); + } else if ([69].indexOf(keyCode) >= 0) { + event.preventDefault(); + expandItem(scrollArea); + } else if ([ + 73, + 83, + 76 + ].indexOf(keyCode) >= 0) { + event.preventDefault(); + toggleStar(scrollArea); + } else if ([72].indexOf(keyCode) >= 0) { + event.preventDefault(); + toggleStar(scrollArea); + scrollToNextItem(scrollArea); + } else if ([79].indexOf(keyCode) >= 0) { + event.preventDefault(); + openLink(scrollArea); + } + } + }); + }(window, document, jQuery)); + }(window, document, angular, jQuery, OC, oc_requesttoken)); + return {}; + }(); \ No newline at end of file diff --git a/js/controller/AppController.js b/js/controller/AppController.js index b833d3fe1..17471e71e 100644 --- a/js/controller/AppController.js +++ b/js/controller/AppController.js @@ -7,12 +7,14 @@ * @author Bernhard Posselt * @copyright Bernhard Posselt 2014 */ -app.controller('AppController', function (Loading, FeedResource, FolderResource) { +app.controller('AppController', +function (Loading, FeedResource, FolderResource) { + 'use strict'; this.loading = Loading; - this.isFirstRun = function () { + this.isFirstRun = () => { return FeedResource.size() === 0 && FolderResource.size() === 0; }; diff --git a/js/controller/ContentController.js b/js/controller/ContentController.js index 8e4632f7e..ae5116dbb 100644 --- a/js/controller/ContentController.js +++ b/js/controller/ContentController.js @@ -7,17 +7,18 @@ * @author Bernhard Posselt * @copyright Bernhard Posselt 2014 */ -app.controller('ContentController', function (Publisher, FeedResource, ItemResource, data) { +app.controller('ContentController', +function (Publisher, FeedResource, ItemResource, data) { 'use strict'; // distribute data to models based on key Publisher.publishAll(data); - this.getItems = function () { + this.getItems = () => { return ItemResource.getAll(); }; - this.getFeeds = function () { + this.getFeeds = () => { return FeedResource.getAll(); }; }); \ No newline at end of file diff --git a/js/gui/keyboardshortcuts.js b/js/gui/keyboardshortcuts.js index ba777dc16..8ba93880e 100644 --- a/js/gui/keyboardshortcuts.js +++ b/js/gui/keyboardshortcuts.js @@ -16,53 +16,37 @@ (function (window, document, $) { 'use strict'; - var noInputFocused, - noModifierKey, - scrollArea, - scrollToItem, - scrollToNextItem, - scrollToPreviousItem, - toggleStar, - toggleUnread, - expandItem, - openLink, - getActiveItem; - - scrollArea = $('#app-content'); - - noInputFocused = function (element) { + let scrollArea = $('#app-content'); + + let noInputFocused = (element) => { return !( - element.is('input') - && element.is('select') - && element.is('textarea') - && element.is('checkbox') + element.is('input') && + element.is('select') && + element.is('textarea') && + element.is('checkbox') ); }; - noModifierKey = function (event) { + let noModifierKey = (event) => { return !( - event.shiftKey - || event.altKey - || event.ctrlKey - || event.metaKey + event.shiftKey || + event.altKey || + event.ctrlKey || + event.metaKey ); }; - scrollToItem = function (item, scrollArea) { + let scrollToItem = (item, scrollArea) => { scrollArea.scrollTop( item.offset().top - scrollArea.offset().top + scrollArea.scrollTop() ); }; - scrollToNextItem = function (scrollArea) { - var items, - counter, - item; - - items = scrollArea.find('.feed_item'); + let scrollToNextItem = (scrollArea) => { + let items = scrollArea.find('.feed_item'); - for (counter = 0; counter < items.length; counter += 1) { - item = $(items[counter]); + for (let item of items) { + item = $(item); if (item.position().top > 1) { scrollToItem(scrollArea, item); @@ -75,19 +59,14 @@ }; - scrollToPreviousItem = function (scrollArea) { - var items, - item, - counter, - previous; - - items = scrollArea.find('.feed_item'); + let scrollToPreviousItem = (scrollArea) => { + let items = scrollArea.find('.feed_item'); - for (counter = 0; counter < items.length; counter += 1) { - item = $(items[counter]); + for (let item of items) { + item = $(item); if (item.position().top >= 0) { - previous = item.prev(); + let previous = item.prev(); // if there are no items before the current one if (previous.length > 0) { @@ -104,15 +83,11 @@ } }; - getActiveItem = function (scrollArea) { - var items, - item, - counter; + let getActiveItem = (scrollArea) => { + let items = scrollArea.find('.feed_item'); - items = scrollArea.find('.feed_item'); - - for (counter = 0; counter < items.length; counter += 1) { - item = $(items[counter]); + for (let item of items) { + item = $(item); // 130px of the item should be visible if ((item.height() + item.position().top) > 30) { @@ -121,32 +96,29 @@ } }; - toggleUnread = function (scrollArea) { - var item = getActiveItem(scrollArea); + let toggleUnread = (scrollArea) => { + let item = getActiveItem(scrollArea); item.find('.keep_unread').trigger('click'); }; - toggleStar = function (scrollArea) { - var item = getActiveItem(scrollArea); + let toggleStar = (scrollArea) => { + let item = getActiveItem(scrollArea); item.find('.item_utils .star').trigger('click'); }; - expandItem = function (scrollArea) { - var item = getActiveItem(scrollArea); + let expandItem = (scrollArea) => { + let item = getActiveItem(scrollArea); item.find('.item_heading a').trigger('click'); }; - openLink = function (scrollArea) { - var item = getActiveItem(scrollArea).find('.item_title a'); + let openLink = (scrollArea) => { + let item = getActiveItem(scrollArea).find('.item_title a'); item.trigger('click'); // mark read window.open(item.attr('href'), '_blank'); }; - $(document).keyup(function (event) { - var keyCode; - - keyCode = event.keyCode; - + $(document).keyup((event) => { + let keyCode = event.keyCode; if (noInputFocused($(':focus')) && noModifierKey(event)) { diff --git a/js/karma.conf.js b/js/karma.conf.js index 5b33469dd..73c083350 100644 --- a/js/karma.conf.js +++ b/js/karma.conf.js @@ -12,8 +12,25 @@ module.exports = function (config) { // frameworks to use // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ['jasmine'], + frameworks: ['jasmine', 'traceur'], + preprocessors: { + 'tests/unit/stubs/*.js': ['traceur'], + 'controller/**/*.js': ['traceur'], + 'filter/**/*.js': ['traceur'], + 'service/**/*.js': ['traceur'], + 'directive/**/*.js': ['traceur'], + 'tests/unit/**/*Spec.js': ['traceur'] + }, + + traceurPreprocessor: { + options: { + blockBinding: true, + experimental: true, + sourceMap: false, + modules: 'inline' + } + }, // list of files / patterns to load in the browser files: [ @@ -25,13 +42,13 @@ module.exports = function (config) { 'vendor/angular-route/angular-route.js', 'vendor/angular-sanitize/angular-sanitize.js', 'vendor/angular-animate/angular-animate.js', - 'tests/unit/stubs/*.js', + 'tests/unit/stubs/App.js', + 'tests/unit/stubs/OC.js', 'controller/**/*.js', 'filter/**/*.js', 'service/**/*.js', - 'model/**/*.js', 'directive/**/*.js', - 'tests/unit/**/*Spec.js' + 'tests/unit/**/*Spec.js', ], @@ -41,13 +58,6 @@ module.exports = function (config) { ], - // preprocess matching files before serving them to the browser - // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor - preprocessors: { - - }, - - // test results reporter to use // possible values: 'dots', 'progress' // available reporters: https://npmjs.org/browse/keyword/karma-reporter @@ -73,7 +83,7 @@ module.exports = function (config) { // start these browsers // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher - browsers: ['PhantomJS'], + browsers: ['Firefox'], // Continuous Integration mode diff --git a/js/package.json b/js/package.json index 6a6cea1ac..f1d7fd509 100644 --- a/js/package.json +++ b/js/package.json @@ -28,17 +28,21 @@ "grunt": "^0.4.5", "grunt-contrib-concat": "^0.4.0", "grunt-contrib-connect": "^0.7.1", + "grunt-contrib-jshint": "^0.10.0", "grunt-contrib-watch": "^0.6.1", - "grunt-jslint": "^1.1.11", "grunt-karma": "^0.8.3", "grunt-ngmin": "0.0.3", "grunt-phpunit": "^0.3.3", "grunt-protractor-runner": "^0.2.4", "grunt-protractor-webdriver": "^0.1.6", + "grunt-traceur": "^0.1.2", "grunt-wrap": "^0.3.0", "karma": "^0.12.16", "karma-coverage": "^0.2.1", + "karma-firefox-launcher": "^0.1.3", "karma-jasmine": "^0.1.5", - "karma-phantomjs-launcher": "^0.1.4" + "karma-phantomjs-launcher": "^0.1.4", + "karma-traceur-preprocessor": "^0.2.2", + "traceur": "0.0.42" } } diff --git a/js/service/FeedResource.js b/js/service/FeedResource.js index 09de0a607..903a58241 100644 --- a/js/service/FeedResource.js +++ b/js/service/FeedResource.js @@ -7,14 +7,14 @@ * @author Bernhard Posselt * @copyright Bernhard Posselt 2014 */ -app.factory('FeedResource', function (Resource, $http) { +app.factory('FeedResource', (Resource, $http) => { 'use strict'; - var FeedResource = function ($http) { - Resource.call(this, 'url', $http); - }; - - FeedResource.prototype = Object.create(Resource.prototype); + class FeedResource extends Resource { + constructor ($http) { + super('url', $http); + } + } return new FeedResource($http); }); \ No newline at end of file diff --git a/js/service/FolderResource.js b/js/service/FolderResource.js index 30026b9a2..b1c0271dd 100644 --- a/js/service/FolderResource.js +++ b/js/service/FolderResource.js @@ -7,14 +7,14 @@ * @author Bernhard Posselt * @copyright Bernhard Posselt 2014 */ -app.factory('FolderResource', function (Resource, $http) { +app.factory('FolderResource', (Resource, $http) => { 'use strict'; - var FolderResource = function ($http) { - Resource.call(this, 'name', $http); - }; - - FolderResource.prototype = Object.create(Resource.prototype); + class FolderResource extends Resource { + constructor ($http) { + super('name', $http); + } + } return new FolderResource($http); }); \ No newline at end of file diff --git a/js/service/ItemResource.js b/js/service/ItemResource.js index 9b13f07c7..8cb47d527 100644 --- a/js/service/ItemResource.js +++ b/js/service/ItemResource.js @@ -7,38 +7,39 @@ * @author Bernhard Posselt * @copyright Bernhard Posselt 2014 */ -app.factory('ItemResource', function (Resource, $http) { +app.factory('ItemResource', (Resource, $http) => { 'use strict'; - var ItemResource = function ($http) { - Resource.call(this, 'id', $http); - }; + class ItemResource extends Resource { - ItemResource.prototype = Object.create(Resource.prototype); + constructor ($http) { + super('id', $http); + } - ItemResource.prototype.receive = function (value, channel) { - switch (channel) { + receive (value, channel) { + switch (channel) { - case 'newestItemId': - this.newestItemId = value; - break; + case 'newestItemId': + this.newestItemId = value; + break; - case 'starred': - this.starredCount = value; - break; - default: - Resource.prototype.receive.call(this, value, channel); + case 'starred': + this.starredCount = value; + break; + default: + super.receive(value, channel); + } } - }; - ItemResource.prototype.getNewestItemId = function () { - return this.newestItemId; - }; + getNewestItemId () { + return this.