From 68f5a01dc692e9bf6c0a60e584d1600adcae3a62 Mon Sep 17 00:00:00 2001 From: Bernhard Posselt Date: Tue, 8 Apr 2014 22:19:19 +0200 Subject: port javascript from appframework --- js/app/app.coffee | 6 +- js/app/directives/clickfocus.coffee | 44 + js/app/directives/clickslidetoggle.coffee | 82 + js/app/directives/draggable.coffee | 32 + js/app/directives/forwardclick.coffee | 35 + js/app/directives/readfile.coffee | 44 + js/app/directives/tooltip.coffee | 27 + js/app/services/loading.coffee | 50 + js/app/services/model.coffee | 128 ++ js/app/services/notification.coffee | 26 + js/app/services/notimplementederror.coffee | 35 + js/app/services/publisher.coffee | 64 + js/app/services/queries/biggerthan.coffee | 46 + js/app/services/queries/biggerthanequal.coffee | 45 + js/app/services/queries/contains.coffee | 54 + js/app/services/queries/doesnotcontain.coffee | 54 + js/app/services/queries/equal.coffee | 54 + js/app/services/queries/lessthan.coffee | 45 + js/app/services/queries/lessthanequal.coffee | 45 + js/app/services/queries/maximum.coffee | 46 + js/app/services/queries/minimum.coffee | 46 + js/app/services/queries/query.coffee | 49 + js/app/services/queries/unequal.coffee | 54 + js/app/services/request.coffee | 150 ++ js/app/services/router.coffee | 26 + js/app/services/utils.coffee | 26 + js/config/karma.js | 1 + js/public/app.js | 1735 +++++++++++++++++++- js/tests/directives/clickfocusSpec.coffee | 73 + js/tests/directives/clickslidetoggleSpec.coffee | 128 ++ js/tests/directives/draggableSpec.coffee | 43 + js/tests/directives/forwardclickSpec.coffee | 71 + js/tests/directives/tooltipSpec.coffee | 49 + js/tests/services/loadingSpec.coffee | 54 + js/tests/services/modelSpec.coffee | 219 +++ js/tests/services/notificationSpec.coffee | 33 + js/tests/services/notimplementederrorSpec.coffee | 35 + js/tests/services/ocSpec.coffee | 32 + js/tests/services/publisherSpec.coffee | 69 + js/tests/services/queries/biggerthanSpec.coffee | 80 + .../services/queries/biggerthanequalSpec.coffee | 80 + js/tests/services/queries/containsSpec.coffee | 86 + .../services/queries/doesnotcontainSpec.coffee | 89 + js/tests/services/queries/equalSpec.coffee | 83 + js/tests/services/queries/lessthanSpec.coffee | 80 + js/tests/services/queries/lessthanequalSpec.coffee | 80 + js/tests/services/queries/maximumSpec.coffee | 63 + js/tests/services/queries/minimumSpec.coffee | 64 + js/tests/services/queries/querySpec.coffee | 68 + js/tests/services/queries/unequalSpec.coffee | 88 + js/tests/services/requestSpec.coffee | 273 +++ js/tests/services/routerSpec.coffee | 33 + js/tests/stubs/modules.js | 2 +- 53 files changed, 4956 insertions(+), 68 deletions(-) create mode 100644 js/app/directives/clickfocus.coffee create mode 100644 js/app/directives/clickslidetoggle.coffee create mode 100644 js/app/directives/draggable.coffee create mode 100644 js/app/directives/forwardclick.coffee create mode 100644 js/app/directives/readfile.coffee create mode 100644 js/app/directives/tooltip.coffee create mode 100644 js/app/services/loading.coffee create mode 100644 js/app/services/model.coffee create mode 100644 js/app/services/notification.coffee create mode 100644 js/app/services/notimplementederror.coffee create mode 100644 js/app/services/publisher.coffee create mode 100644 js/app/services/queries/biggerthan.coffee create mode 100644 js/app/services/queries/biggerthanequal.coffee create mode 100644 js/app/services/queries/contains.coffee create mode 100644 js/app/services/queries/doesnotcontain.coffee create mode 100644 js/app/services/queries/equal.coffee create mode 100644 js/app/services/queries/lessthan.coffee create mode 100644 js/app/services/queries/lessthanequal.coffee create mode 100644 js/app/services/queries/maximum.coffee create mode 100644 js/app/services/queries/minimum.coffee create mode 100644 js/app/services/queries/query.coffee create mode 100644 js/app/services/queries/unequal.coffee create mode 100644 js/app/services/request.coffee create mode 100644 js/app/services/router.coffee create mode 100644 js/app/services/utils.coffee create mode 100644 js/tests/directives/clickfocusSpec.coffee create mode 100644 js/tests/directives/clickslidetoggleSpec.coffee create mode 100644 js/tests/directives/draggableSpec.coffee create mode 100644 js/tests/directives/forwardclickSpec.coffee create mode 100644 js/tests/directives/tooltipSpec.coffee create mode 100644 js/tests/services/loadingSpec.coffee create mode 100644 js/tests/services/modelSpec.coffee create mode 100644 js/tests/services/notificationSpec.coffee create mode 100644 js/tests/services/notimplementederrorSpec.coffee create mode 100644 js/tests/services/ocSpec.coffee create mode 100644 js/tests/services/publisherSpec.coffee create mode 100644 js/tests/services/queries/biggerthanSpec.coffee create mode 100644 js/tests/services/queries/biggerthanequalSpec.coffee create mode 100644 js/tests/services/queries/containsSpec.coffee create mode 100644 js/tests/services/queries/doesnotcontainSpec.coffee create mode 100644 js/tests/services/queries/equalSpec.coffee create mode 100644 js/tests/services/queries/lessthanSpec.coffee create mode 100644 js/tests/services/queries/lessthanequalSpec.coffee create mode 100644 js/tests/services/queries/maximumSpec.coffee create mode 100644 js/tests/services/queries/minimumSpec.coffee create mode 100644 js/tests/services/queries/querySpec.coffee create mode 100644 js/tests/services/queries/unequalSpec.coffee create mode 100644 js/tests/services/requestSpec.coffee create mode 100644 js/tests/services/routerSpec.coffee (limited to 'js') diff --git a/js/app/app.coffee b/js/app/app.coffee index 03a25c6c4..0c5763bd2 100644 --- a/js/app/app.coffee +++ b/js/app/app.coffee @@ -22,7 +22,8 @@ License along with this library. If not, see . # app main -angular.module('News', ['OC', 'ui']).config ($provide) -> +angular.module('News', ['ui']).config ['$provide', '$httpProvider', +($provide, $httpProvider) -> $provide.value 'Config', config = markReadTimeout: 500 scrollTimeout: 500 @@ -33,6 +34,9 @@ angular.module('News', ['OC', 'ui']).config ($provide) -> # before it starts autopaging autoPageFactor: 30 + # Always send the CSRF token by default + $httpProvider.defaults.headers.common['requesttoken'] = oc_requesttoken +] angular.module('News').run ['Persistence', 'Config', (Persistence, Config) -> diff --git a/js/app/directives/clickfocus.coffee b/js/app/directives/clickfocus.coffee new file mode 100644 index 000000000..4a5323418 --- /dev/null +++ b/js/app/directives/clickfocus.coffee @@ -0,0 +1,44 @@ +### + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . + +### + +# Used to focus an element when you click on the element that this directive is +# bound to +# The selector attribute needs to defined, this element will be focused +# If the timeout attribute is defined, it will focus the element after +# after the passed miliseconds +# Examlpe:
+angular.module('News').directive 'ocClickFocus', ['$timeout', ($timeout) -> + + return (scope, elm, attr) -> + options = scope.$eval(attr.ocClickFocus) + + if angular.isDefined(options) and angular.isDefined(options.selector) + elm.click -> + if angular.isDefined(options.timeout) + $timeout -> + $(options.selector).focus() + , options.timeout + else + $(options.selector).focus() + + +] \ No newline at end of file diff --git a/js/app/directives/clickslidetoggle.coffee b/js/app/directives/clickslidetoggle.coffee new file mode 100644 index 000000000..e31c5e955 --- /dev/null +++ b/js/app/directives/clickslidetoggle.coffee @@ -0,0 +1,82 @@ +### + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . + +### + + + +# Used to slide up an area and can be customized by passing an expression. +# If selector is defined, a different area is slid up on click +# If hideOnFocusLost is defined, the slid up area will hide when the focus is +# If cssClass is defined this class will be applied to the element +# lost +angular.module('News').directive 'ocClickSlideToggle', +['$rootScope', ($rootScope) -> + + return (scope, elm, attr) -> + options = scope.$eval(attr.ocClickSlideToggle) + + # get selected slide area + if angular.isDefined(options) and angular.isDefined(options.selector) + slideArea = $(options.selector) + else + slideArea = elm + + # get css class for element + if angular.isDefined(options) and angular.isDefined(options.cssClass) + cssClass = options.cssClass + else + cssClass = false + + elm.click -> + if slideArea.is(':visible') and not slideArea.is(':animated') + slideArea.slideUp() + if cssClass != false + elm.removeClass('opened') + else + slideArea.slideDown() + if cssClass != false + elm.addClass('opened') + + # if focus lost is set use broadcast to be sure that the currently + # active element doesnt get slid up + if angular.isDefined(options) and + angular.isDefined(options.hideOnFocusLost) and + options.hideOnFocusLost + $(document.body).click -> + $rootScope.$broadcast 'ocLostFocus' + + $rootScope.$on 'ocLostFocus', (scope, params) -> + if params != slideArea + if slideArea.is(':visible') and not slideArea.is(':animated') + slideArea.slideUp() + + if cssClass != false + elm.removeClass('opened') + + slideArea.click (e) -> + $rootScope.$broadcast 'ocLostFocus', slideArea + e.stopPropagation() + + elm.click (e) -> + $rootScope.$broadcast 'ocLostFocus', slideArea + e.stopPropagation() + +] \ No newline at end of file diff --git a/js/app/directives/draggable.coffee b/js/app/directives/draggable.coffee new file mode 100644 index 000000000..22fa041bf --- /dev/null +++ b/js/app/directives/draggable.coffee @@ -0,0 +1,32 @@ +### + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . + +### + +# Wrapper for jquery ui draggable +angular.module('News').directive 'ocDraggable', -> + + return (scope, elm, attr) -> + options = scope.$eval(attr.ocDraggable) + + if angular.isDefined(options) + elm.draggable(options) + else + elm.draggable() diff --git a/js/app/directives/forwardclick.coffee b/js/app/directives/forwardclick.coffee new file mode 100644 index 000000000..d4fdac10a --- /dev/null +++ b/js/app/directives/forwardclick.coffee @@ -0,0 +1,35 @@ +### + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . + +### + + +# Used to forward clicks to another element via jquery selector +# The expression which can be passed looks like this {selector:'#opml-upload'} +# The element where to which the click was fowarded must not be a child element +# otherwise this will end in endless recursion +angular.module('News').directive 'ocForwardClick', -> + + return (scope, elm, attr) -> + options = scope.$eval(attr.ocForwardClick) + + if angular.isDefined(options) and angular.isDefined(options.selector) + $(elm).click -> + $(options.selector).trigger('click') diff --git a/js/app/directives/readfile.coffee b/js/app/directives/readfile.coffee new file mode 100644 index 000000000..fc5cc0c80 --- /dev/null +++ b/js/app/directives/readfile.coffee @@ -0,0 +1,44 @@ +### + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . + +### + +### +This directive can be bound on an input element with type file +When a file is input, the content will be passed to the given function as +$fileContent parameter +### +angular.module('News').directive 'ocReadFile', +['$rootScope', ($rootScope) -> + + return (scope, elm, attr) -> + elm.change -> + + file = elm[0].files[0] + reader = new FileReader() + + reader.onload = (e) -> + elm[0].value = null + scope.$fileContent = e.target.result + scope.$apply attr.ocReadFile + + reader.readAsText(file) + +] \ No newline at end of file diff --git a/js/app/directives/tooltip.coffee b/js/app/directives/tooltip.coffee new file mode 100644 index 000000000..8241436e5 --- /dev/null +++ b/js/app/directives/tooltip.coffee @@ -0,0 +1,27 @@ +### + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . + +### + +# binds twitter tooltips to the element +angular.module('News').directive 'ocTooltip', -> + + return (scope, elm, attr) -> + elm.tooltip() diff --git a/js/app/services/loading.coffee b/js/app/services/loading.coffee new file mode 100644 index 000000000..c68cc9f40 --- /dev/null +++ b/js/app/services/loading.coffee @@ -0,0 +1,50 @@ +### + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . + +### + + +# Simple class which can be used to show loading events when ajax events are +# fired +angular.module('News').factory '_Loading', -> + + class Loading + + constructor: -> + @_count = 0 + + + increase: -> + @_count += 1 + + + decrease: -> + @_count -= 1 + + + getCount: -> + return @_count + + + isLoading: -> + return @_count > 0 + + + return Loading \ No newline at end of file diff --git a/js/app/services/model.coffee b/js/app/services/model.coffee new file mode 100644 index 000000000..238e5bcf0 --- /dev/null +++ b/js/app/services/model.coffee @@ -0,0 +1,128 @@ +### + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . + +### + + +# Model which offers basic crud for storing your data +angular.module('News').factory '_Model', -> + + class Model + + constructor: -> + @_data = [] + @_dataMap = {} + @_filterCache = {} + + + handle: (data) -> + ### + Redirects to add method + ### + for item in data + @add(item) + + + add: (data, clearCache=true) -> + ### + Adds a new entry or updates an entry if the id exists already + ### + if clearCache + @_invalidateCache() + if angular.isDefined(@_dataMap[data.id]) + @update(data, clearCache) + else + @_data.push(data) + @_dataMap[data.id] = data + + + update: (data, clearCache=true) -> + ### + Update an entry by searching for its id + ### + if clearCache + @_invalidateCache() + entry = @getById(data.id) + for key, value of data + if key == 'id' + continue + else + entry[key] = value + + + getById: (id) -> + ### + Return an entry by its id + ### + return @_dataMap[id] + + + getAll: -> + ### + Returns all stored entries + ### + return @_data + + + removeById: (id, clearCache=true) -> + ### + Remove an entry by id + ### + for entry, counter in @_data + if entry.id == id + @_data.splice(counter, 1) + data = @_dataMap[id] + delete @_dataMap[id] + if clearCache + @_invalidateCache() + return data + + + clear: -> + ### + Removes all cached elements + ### + @_data.length = 0 + @_dataMap = {} + @_invalidateCache() + + + _invalidateCache: -> + @_filterCache = {} + + + get: (query) -> + ### + Calls, caches and returns filtered results + ### + hash = query.hashCode() + if not angular.isDefined(@_filterCache[hash]) + @_filterCache[hash] = query.exec(@_data) + return @_filterCache[hash] + + + size: -> + ### + Return the number of all stored entries + ### + return @_data.length + + + return Model \ No newline at end of file diff --git a/js/app/services/notification.coffee b/js/app/services/notification.coffee new file mode 100644 index 000000000..fefc9e306 --- /dev/null +++ b/js/app/services/notification.coffee @@ -0,0 +1,26 @@ +### + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . + +### + + +# Inject notification into angular to make testing easier +angular.module('News').factory 'Notification', -> + return OC.Notification \ No newline at end of file diff --git a/js/app/services/notimplementederror.coffee b/js/app/services/notimplementederror.coffee new file mode 100644 index 000000000..1c1b480ea --- /dev/null +++ b/js/app/services/notimplementederror.coffee @@ -0,0 +1,35 @@ +### + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . + +### + + +# Model which offers basic crud for storing your data +angular.module('News').factory '_NotImplementedError', -> + + class NotImplementedError + + constructor: (@_msg) -> + + getMessage: -> + return @_msg + + + return NotImplementedError \ No newline at end of file diff --git a/js/app/services/publisher.coffee b/js/app/services/publisher.coffee new file mode 100644 index 000000000..acf2ee2c0 --- /dev/null +++ b/js/app/services/publisher.coffee @@ -0,0 +1,64 @@ +### + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . + +### + + +# Used for properly distributing received model data from the server +angular.module('News').factory '_Publisher', -> + + + class Publisher + + constructor: -> + @_subscriptions = {} + + + # Use this to subscribe to a certain hashkey in the returned json data + # dictionary. + # If you send JSON from the server, you'll receive something like this + # + # { + # data: { + # modelName: { + # create: [{id: 1, name: 'john'}, {id: 2, name: 'ron'}], + # update: [], + # delete: [] + # } + # } + # } + # + # To get the array ['one', 'two'] passed to your object, just subscribe + # to the key: + # Publisher.subscribeObjectTo('modelName', myModelInstance) + # + subscribeObjectTo: (object, name) -> + @_subscriptions[name] or= [] + @_subscriptions[name].push(object) + + + # This will publish data from the server to all registered subscribers + # The parameter 'name' is the name under which subscribers have registered + publishDataTo: (data, name) -> + for subscriber in @_subscriptions[name] || [] + subscriber.handle(data) + + + return Publisher \ No newline at end of file diff --git a/js/app/services/queries/biggerthan.coffee b/js/app/services/queries/biggerthan.coffee new file mode 100644 index 000000000..a8ab7aea4 --- /dev/null +++ b/js/app/services/queries/biggerthan.coffee @@ -0,0 +1,46 @@ +### + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . + +### + + +# A query for returning a list with elements bigger than equal to the provided +# one +angular.module('News').factory '_BiggerThanQuery', ['_Query', +(_Query) -> + + class BiggerThanQuery extends _Query + + constructor: (@_field, @_value) -> + name = 'biggerthan' + super(name, [@_field, @_value]) + + + exec: (data) -> + filtered = [] + for entry in data + if entry[@_field] > @_value + filtered.push(entry) + + return filtered + + + return BiggerThanQuery +] diff --git a/js/app/services/queries/biggerthanequal.coffee b/js/app/services/queries/biggerthanequal.coffee new file mode 100644 index 000000000..0733ced20 --- /dev/null +++ b/js/app/services/queries/biggerthanequal.coffee @@ -0,0 +1,45 @@ +### + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . + +### + + +# A query for returning a list with elements equal to the provided one +angular.module('News').factory '_BiggerThanEqualQuery', ['_Query', +(_Query) -> + + class BiggerThanEqualQuery extends _Query + + constructor: (@_field, @_value) -> + name = 'biggerthanequal' + super(name, [@_field, @_value]) + + + exec: (data) -> + filtered = [] + for entry in data + if entry[@_field] >= @_value + filtered.push(entry) + + return filtered + + + return BiggerThanEqualQuery +] diff --git a/js/app/services/queries/contains.coffee b/js/app/services/queries/contains.coffee new file mode 100644 index 000000000..f1ade5e59 --- /dev/null +++ b/js/app/services/queries/contains.coffee @@ -0,0 +1,54 @@ +### + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . + +### + + +# A query for returning a list with elements that contain the search term +angular.module('News').factory '_ContainsQuery', ['_Query', +(_Query) -> + + class ContainsQuery extends _Query + + constructor: (@_field, @_value, @_caseInsensitive=false) -> + name = 'contains' + super(name, [@_field, @_value, @_caseInsensitive]) + + + exec: (data) -> + filtered = [] + + if @_caseInsensitive + @_value = @_value.toLowerCase() + + for entry in data + if @_caseInsensitive + field = entry[@_field].toLowerCase() + else + field = entry[@_field] + + if field.indexOf(@_value) != -1 + filtered.push(entry) + + return filtered + + + return ContainsQuery +] diff --git a/js/app/services/queries/doesnotcontain.coffee b/js/app/services/queries/doesnotcontain.coffee new file mode 100644 index 000000000..a99d18a04 --- /dev/null +++ b/js/app/services/queries/doesnotcontain.coffee @@ -0,0 +1,54 @@ +### + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . + +### + + +# A query for returning a list with elements that does not contain the search +# term +angular.module('News').factory '_DoesNotContainQuery', ['_Query', +(_Query) -> + + class DoesNotContainQuery extends _Query + + constructor: (@_field, @_value, @_caseInsensitive=false) -> + name = 'doesnotcontain' + super(name, [@_field, @_value, @_caseInsensitive]) + + + exec: (data) -> + filtered = [] + if @_caseInsensitive + @_value = @_value.toLowerCase() + + for entry in data + if @_caseInsensitive + field = entry[@_field].toLowerCase() + else + field = entry[@_field] + + if field.indexOf(@_value) == -1 + filtered.push(entry) + + return filtered + + + return DoesNotContainQuery +] diff --git a/js/app/services/queries/equal.coffee b/js/app/services/queries/equal.coffee new file mode 100644 index 000000000..06f9f0abb --- /dev/null +++ b/js/app/services/queries/equal.coffee @@ -0,0 +1,54 @@ +### + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . + +### + + +# A query for returning a list with elements equal to the provided one +angular.module('News').factory '_EqualQuery', ['_Query', +(_Query) -> + + class EqualQuery extends _Query + + constructor: (@_field, @_value, @_caseInsensitive=false) -> + name = 'equal' + super(name, [@_field, @_value, @_caseInsensitive]) + + + exec: (data) -> + equal = [] + + if @_caseInsensitive + @_value = @_value.toLowerCase() + + for entry in data + if @_caseInsensitive + field = entry[@_field].toLowerCase() + else + field = entry[@_field] + + if field == @_value + equal.push(entry) + + return equal + + + return EqualQuery +] diff --git a/js/app/services/queries/lessthan.coffee b/js/app/services/queries/lessthan.coffee new file mode 100644 index 000000000..94898b371 --- /dev/null +++ b/js/app/services/queries/lessthan.coffee @@ -0,0 +1,45 @@ +### + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . + +### + + +# A query for returning a list with elements less than to the provided one +angular.module('News').factory '_LessThanQuery', ['_Query', +(_Query) -> + + class LessThanQuery extends _Query + + constructor: (@_field, @_value) -> + name = 'lessthan' + super(name, [@_field, @_value]) + + + exec: (data) -> + filtered = [] + for entry in data + if entry[@_field] < @_value + filtered.push(entry) + + return filtered + + + return LessThanQuery +] diff --git a/js/app/services/queries/lessthanequal.coffee b/js/app/services/queries/lessthanequal.coffee new file mode 100644 index 000000000..ab27032a2 --- /dev/null +++ b/js/app/services/queries/lessthanequal.coffee @@ -0,0 +1,45 @@ +### + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . + +### + + +# A query for returning a list with elements less than equal to the provided one +angular.module('News').factory '_LessThanEqualQuery', ['_Query', +(_Query) -> + + class LessThanEqualQuery extends _Query + + constructor: (@_field, @_value) -> + name = 'lessthanequal' + super(name, [@_field, @_value]) + + + exec: (data) -> + filtered = [] + for entry in data + if entry[@_field] <= @_value + filtered.push(entry) + + return filtered + + + return LessThanEqualQuery +] diff --git a/js/app/services/queries/maximum.coffee b/js/app/services/queries/maximum.coffee new file mode 100644 index 000000000..09f595cd8 --- /dev/null +++ b/js/app/services/queries/maximum.coffee @@ -0,0 +1,46 @@ +### + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . + +### + + +# A query for returning the maximum of an array based on the object +angular.module('News').factory '_MaximumQuery', ['_Query', +(_Query) -> + + class MaximumQuery extends _Query + + constructor: (@_field) -> + name = 'maximum' + super(name, [@_field]) + + + exec: (data) -> + maximum = undefined + for entry in data + if angular.isUndefined(maximum) or + entry[@_field] > maximum[@_field] + maximum = entry + + return maximum + + + return MaximumQuery +] diff --git a/js/app/services/queries/minimum.coffee b/js/app/services/queries/minimum.coffee new file mode 100644 index 000000000..db77a9bf9 --- /dev/null +++ b/js/app/services/queries/minimum.coffee @@ -0,0 +1,46 @@ +### + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . + +### + + +# A query for returning the minium of an array based on the object +angular.module('News').factory '_MinimumQuery', ['_Query', +(_Query) -> + + class MinimumQuery extends _Query + + constructor: (@_field) -> + name = 'minimum' + super(name, [@_field]) + + + exec: (data) -> + minimum = undefined + for entry in data + if angular.isUndefined(minimum) or + entry[@_field] < minimum[@_field] + minimum = entry + + return minimum + + + return MinimumQuery +] diff --git a/js/app/services/queries/query.coffee b/js/app/services/queries/query.coffee new file mode 100644 index 000000000..ba4e1c21e --- /dev/null +++ b/js/app/services/queries/query.coffee @@ -0,0 +1,49 @@ +### + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . + +### + + +# Parentclass to inherit from for defining own model query +angular.module('News').factory '_Query', ['_NotImplementedError', +(_NotImplementedError) -> + + class Query + + constructor: (@_name, @_args=[]) -> + + + exec: (data) -> + throw new _NotImplementedError('Not implemented') + + + hashCode: (filter) -> + hash = @_name + for arg in @_args + if angular.isString(arg) + arg = arg.replace(/_/gi, '__') + hash += '_' + arg + + return hash + + + return Query + +] \ No newline at end of file diff --git a/js/app/services/queries/unequal.coffee b/js/app/services/queries/unequal.coffee new file mode 100644 index 000000000..d76847bfd --- /dev/null +++ b/js/app/services/queries/unequal.coffee @@ -0,0 +1,54 @@ +### + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . + +### + + +# A query for returning a list with all elements unequal to the provided one +angular.module('News').factory '_UnequalQuery', ['_Query', +(_Query) -> + + class UnequalQuery extends _Query + + constructor: (@_field, @_value, @_caseInsensitive=false) -> + name = 'unequal' + super(name, [@_field, @_value, @_caseInsensitive]) + + + exec: (data) -> + equal = [] + + if @_caseInsensitive + @_value = @_value.toLowerCase() + + for entry in data + if @_caseInsensitive + field = entry[@_field].toLowerCase() + else + field = entry[@_field] + + if field != @_value + equal.push(entry) + + return equal + + + return UnequalQuery +] diff --git a/js/app/services/request.coffee b/js/app/services/request.coffee new file mode 100644 index 000000000..e0e24bb44 --- /dev/null +++ b/js/app/services/request.coffee @@ -0,0 +1,150 @@ +### + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . + +### + + +# Inherit from this baseclass to define your own routes +angular.module('News').factory '_Request', -> + + class Request + + constructor: (@_$http, @_publisher, @_router) -> + @_initialized = false + @_shelvedRequests = [] + + @_router.registerLoadedCallback => + @_initialized = true + @_executeShelvedRequests() + @_shelvedRequests = [] + + + request: (route, data={}) -> + ### + Wrapper to do a normal request to the server. This needs to + be done to hook the publisher into the requests and to handle + requests, that come in before routes have been loaded + + route: the routename data can contain the following + data.routeParams: object with parameters for the route + data.data: ajax data objec which is passed to PHP + data.onSuccess: callback for successful requests + data.onFailure: callback for failed requests + data.config: a config which should be passed to $http + ### + defaultData = + routeParams: {} + data: {} + onSuccess: -> + onFailure: -> + config: {} + + angular.extend(defaultData, data) + + # if routes are not ready yet, save the request + if not @_initialized + @_shelveRequest(route, defaultData) + return + + url = @_router.generate(route, defaultData.routeParams) + + defaultConfig = + url: url + data: defaultData.data + + + # overwrite default values from passed in config + angular.extend(defaultConfig, defaultData.config) + + # use params array instead of data when using get + if defaultConfig.method == 'GET' + defaultConfig.params = defaultConfig.data + + @_$http(defaultConfig) + .success (data, status, headers, config) => + + # publish data to models + for name, value of data + @_publisher.publishDataTo(value, name) + + defaultData.onSuccess(data, status, headers, config) + + + .error (data, status, headers, config) -> + defaultData.onFailure(data, status, headers, config) + + + post: (route, data={}) -> + ### + Request shortcut which sets the method to POST + ### + data.config or= {} + data.config.method = 'POST' + @request(route, data) + + + get: (route, data={}) -> + ### + Request shortcut which sets the method to GET + ### + data.config or= {} + data.config.method = 'GET' + @request(route, data) + + put: (route, data={}) -> + ### + Request shortcut which sets the method to GET + ### + data.config or= {} + data.config.method = 'PUT' + @request(route, data) + + + delete: (route, data={}) -> + ### + Request shortcut which sets the method to GET + ### + data.config or= {} + data.config.method = 'DELETE' + @request(route, data) + + + _shelveRequest: (route, data) -> + ### + Saves requests for later if the routes have not been loaded + ### + request = + route: route + data: data + + @_shelvedRequests.push(request) + + + _executeShelvedRequests: -> + ### + Run all saved requests that were done before routes were fully + loaded + ### + for r in @_shelvedRequests + @request(r.route, r.data) + + + + return Request diff --git a/js/app/services/router.coffee b/js/app/services/router.coffee new file mode 100644 index 000000000..49c87c112 --- /dev/null +++ b/js/app/services/router.coffee @@ -0,0 +1,26 @@ +### + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . + +### + + +# Inject router into angular to make testing easier +angular.module('News').factory 'Router', -> + return OC.Router \ No newline at end of file diff --git a/js/app/services/utils.coffee b/js/app/services/utils.coffee new file mode 100644 index 000000000..8171a0d87 --- /dev/null +++ b/js/app/services/utils.coffee @@ -0,0 +1,26 @@ +### + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . + +### + + +# Inject router into angular to make testing easier +angular.module('News').factory 'Utils', -> + return OC \ No newline at end of file diff --git a/js/config/karma.js b/js/config/karma.js index ac9b29192..497c426d7 100644 --- a/js/config/karma.js +++ b/js/config/karma.js @@ -32,6 +32,7 @@ module.exports = function(config) { files: [ 'vendor/jquery/dist/jquery.js', 'vendor/jquery-ui/ui/jquery-ui.js', + 'vendor/bootstrap/tooltip.js', 'vendor/angular/angular.js', 'vendor/angular-mocks/angular-mocks.js', 'vendor/angular-ui/build/angular-ui.js', diff --git a/js/public/app.js b/js/public/app.js index 396626e47..1c45a5394 100644 --- a/js/public/app.js +++ b/js/public/app.js @@ -34,17 +34,20 @@ License along with this library. If not, see . (function() { - angular.module('News', ['OC', 'ui']).config(function($provide) { - var config; - return $provide.value('Config', config = { - markReadTimeout: 500, - scrollTimeout: 500, - feedUpdateInterval: 1000 * 60 * 3, - itemBatchSize: 40, - undoTimeout: 1000 * 10, - autoPageFactor: 30 - }); - }); + angular.module('News', ['ui']).config([ + '$provide', '$httpProvider', function($provide, $httpProvider) { + var config; + $provide.value('Config', config = { + markReadTimeout: 500, + scrollTimeout: 500, + feedUpdateInterval: 1000 * 60 * 3, + itemBatchSize: 40, + undoTimeout: 1000 * 10, + autoPageFactor: 30 + }); + return $httpProvider.defaults.headers.common['requesttoken'] = oc_requesttoken; + } + ]); angular.module('News').run([ 'Persistence', 'Config', function(Persistence, Config) { @@ -191,6 +194,171 @@ License along with this library. If not, see . */ +(function() { + angular.module('News').directive('ocClickFocus', [ + '$timeout', function($timeout) { + return function(scope, elm, attr) { + var options; + options = scope.$eval(attr.ocClickFocus); + if (angular.isDefined(options) && angular.isDefined(options.selector)) { + return elm.click(function() { + if (angular.isDefined(options.timeout)) { + return $timeout(function() { + return $(options.selector).focus(); + }, options.timeout); + } else { + return $(options.selector).focus(); + } + }); + } + }; + } + ]); + +}).call(this); + +// Generated by CoffeeScript 1.6.3 +/* + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . +*/ + + +(function() { + angular.module('News').directive('ocClickSlideToggle', [ + '$rootScope', function($rootScope) { + return function(scope, elm, attr) { + var cssClass, options, slideArea; + options = scope.$eval(attr.ocClickSlideToggle); + if (angular.isDefined(options) && angular.isDefined(options.selector)) { + slideArea = $(options.selector); + } else { + slideArea = elm; + } + if (angular.isDefined(options) && angular.isDefined(options.cssClass)) { + cssClass = options.cssClass; + } else { + cssClass = false; + } + elm.click(function() { + if (slideArea.is(':visible') && !slideArea.is(':animated')) { + slideArea.slideUp(); + if (cssClass !== false) { + return elm.removeClass('opened'); + } + } else { + slideArea.slideDown(); + if (cssClass !== false) { + return elm.addClass('opened'); + } + } + }); + if (angular.isDefined(options) && angular.isDefined(options.hideOnFocusLost) && options.hideOnFocusLost) { + $(document.body).click(function() { + return $rootScope.$broadcast('ocLostFocus'); + }); + $rootScope.$on('ocLostFocus', function(scope, params) { + if (params !== slideArea) { + if (slideArea.is(':visible') && !slideArea.is(':animated')) { + slideArea.slideUp(); + if (cssClass !== false) { + return elm.removeClass('opened'); + } + } + } + }); + slideArea.click(function(e) { + $rootScope.$broadcast('ocLostFocus', slideArea); + return e.stopPropagation(); + }); + return elm.click(function(e) { + $rootScope.$broadcast('ocLostFocus', slideArea); + return e.stopPropagation(); + }); + } + }; + } + ]); + +}).call(this); + +// Generated by CoffeeScript 1.6.3 +/* + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . +*/ + + +(function() { + angular.module('News').directive('ocDraggable', function() { + return function(scope, elm, attr) { + var options; + options = scope.$eval(attr.ocDraggable); + if (angular.isDefined(options)) { + return elm.draggable(options); + } else { + return elm.draggable(); + } + }; + }); + +}).call(this); + +// Generated by CoffeeScript 1.6.3 +/* + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . +*/ + + (function() { angular.module('News').directive('droppable', [ '$rootScope', function($rootScope) { @@ -242,6 +410,44 @@ License along with this library. If not, see . */ +(function() { + angular.module('News').directive('ocForwardClick', function() { + return function(scope, elm, attr) { + var options; + options = scope.$eval(attr.ocForwardClick); + if (angular.isDefined(options) && angular.isDefined(options.selector)) { + return $(elm).click(function() { + return $(options.selector).trigger('click'); + }); + } + }; + }); + +}).call(this); + +// Generated by CoffeeScript 1.6.3 +/* + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . +*/ + + (function() { angular.module('News').directive('itemShortcuts', [ '$window', function($window) { @@ -568,6 +774,89 @@ License along with this library. If not, see . */ +/* +This directive can be bound on an input element with type file +When a file is input, the content will be passed to the given function as +$fileContent parameter +*/ + + +(function() { + angular.module('News').directive('ocReadFile', [ + '$rootScope', function($rootScope) { + return function(scope, elm, attr) { + return elm.change(function() { + var file, reader; + file = elm[0].files[0]; + reader = new FileReader(); + reader.onload = function(e) { + elm[0].value = null; + scope.$fileContent = e.target.result; + return scope.$apply(attr.ocReadFile); + }; + return reader.readAsText(file); + }); + }; + } + ]); + +}).call(this); + +// Generated by CoffeeScript 1.6.3 +/* + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . +*/ + + +(function() { + angular.module('News').directive('ocTooltip', function() { + return function(scope, elm, attr) { + return elm.tooltip(); + }; + }); + +}).call(this); + +// Generated by CoffeeScript 1.6.3 +/* + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . +*/ + + (function() { angular.module('News').directive('newsTranslate', function() { var directive; @@ -2112,43 +2401,272 @@ License along with this library. If not, see . (function() { - var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + angular.module('News').factory('_Loading', function() { + var Loading; + Loading = (function() { + function Loading() { + this._count = 0; + } - angular.module('News').factory('FeedModel', [ - '_Model', '_EqualQuery', 'Utils', function(_Model, _EqualQuery, Utils) { - var FeedModel; - FeedModel = (function(_super) { - __extends(FeedModel, _super); + Loading.prototype.increase = function() { + return this._count += 1; + }; - function FeedModel(_utils) { - this._utils = _utils; - this._url = {}; - FeedModel.__super__.constructor.call(this); - } + Loading.prototype.decrease = function() { + return this._count -= 1; + }; - FeedModel.prototype.clear = function() { - this._url = {}; - return FeedModel.__super__.clear.call(this); - }; + Loading.prototype.getCount = function() { + return this._count; + }; - FeedModel.prototype.add = function(data, clearCache) { - var item, updateById, updateByUrl; - if (clearCache == null) { - clearCache = true; - } - if (data.faviconLink === null) { - data.faviconLink = 'url(' + this._utils.imagePath('news', 'rss.svg') + ')'; - } else if (angular.isDefined(data.faviconLink) && data.faviconLink.indexOf('url(') !== 0) { - data.faviconLink = 'url(' + data.faviconLink + ')'; - } - /* - We want to add a feed on the client side before - we have an id from the server. Once the server returns - an id, we have to update the existing item without id - */ + Loading.prototype.isLoading = function() { + return this._count > 0; + }; - item = this._url[data.url]; + return Loading; + + })(); + return Loading; + }); + +}).call(this); + +// Generated by CoffeeScript 1.6.3 +/* + +ownCloud - News + +@author Bernhard Posselt +@copyright 2012 Bernhard Posselt dev@bernhard-posselt.com + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +License as published by the Free Software Foundation; either +version 3 of the License, or any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU AFFERO GENERAL PUBLIC LICENSE for more details. + +You should have received a copy of the GNU Affero General Public +License along with this library. If not, see . +*/ + + +(function() { + angular.module('News').factory('_Model', function() { + var Model; + Model = (function() { + function Model() { + this._data = []; + this._dataMap = {}; + this._filterCache = {}; + } + + Model.prototype.handle = function(data) { + /* + Redirects to add method + */ + + var item, _i, _len, _results; + _results = []; + for (_i = 0, _len = data.length; _i < _len; _i++) { + item = data[_i]; + _results.push(this.add(item)); + } + return _results; + }; + + Model.prototype.add = function(data, clearCache) { + if (clearCache == null) { + clearCache = true; + } + /* + Adds a new entry or updates an entry if the id exists already + */ + + if (clearCache) { + this._invalidateCache(); + } + if (angular.isDefined(this._dataMap[data.id])) { + return this.update(data, clearCache); + } else { + this._data.push(data); + return this._dataMap[data.id] = data; + } + }; + + Model.prototype.update = function(data, clearCache) { + var entry, key, value, _results; + if (clearCache == null) { + clearCache = true; + } + /* + Update an entry by searching for its id + */ + + if (clearCache) { + this._invalidateCache(); + } + entry =