modularity-rails 0.28.0 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -16
- data/lib/modularity-rails/version.rb +1 -1
- metadata +3 -7
- data/app/assets/javascripts/modularity/data/ajax_loader.coffee +0 -77
- data/app/assets/javascripts/modularity/data/cache.coffee +0 -65
- data/app/assets/javascripts/modularity/data/indexed_cache.coffee +0 -32
- data/app/assets/javascripts/modularity/data/persistence_manager.coffee +0 -238
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 65f2ce39342e4c93961f900aabf4c03b62feec63
|
4
|
+
data.tar.gz: 23b288aaa60b08f814f664ede4605487cb69fe51
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7c6c1e2a371e3003c401780f624d3792890ccd92521a8de5741380496596c60dfd248f0ca07148b4ee68caa4d1cd00b8aea03822cdb74a72f1bebe77fc1541db
|
7
|
+
data.tar.gz: 42576e03b20368447a62be4e6df4f475e79b7336ac346f642d59f39efde7bad459b4ba49323272a98462b2190932d34e14231b59b7f84bbe12aeac3aec249a99
|
data/README.md
CHANGED
@@ -148,10 +148,10 @@ and must be explicitly required in your Rails files using the `require` commands
|
|
148
148
|
|
149
149
|
## Mixins
|
150
150
|
|
151
|
-
###
|
151
|
+
### Clickable
|
152
152
|
Including this mixins adds a 'clickable' aspect to your module, i.e. turns it into a button. Clicking anywhere inside the container makes it fire the 'clicked' event.
|
153
153
|
|
154
|
-
###
|
154
|
+
### Closable
|
155
155
|
Including this mixin makes a module closable. The mixin searches for an embedded DOM element with the class 'CloseButton'. When it is clicked, the following things happen:
|
156
156
|
|
157
157
|
* The _closable_closing_ hook of the closable class is called.
|
@@ -162,20 +162,6 @@ Including this mixin makes a module closable. The mixin searches for an embedded
|
|
162
162
|
* The _closable_closed_ hook of the closable class is called.
|
163
163
|
|
164
164
|
|
165
|
-
## Tools
|
166
|
-
|
167
|
-
### Loader
|
168
|
-
A generic cached loader for parallel and repeated GET requests.
|
169
|
-
Prevents duplicate requests, caches the responses.
|
170
|
-
|
171
|
-
The first request triggers the ajax request. Subsequent requests while the resquest is running are accumulated without causing new requests.
|
172
|
-
Once the response arrives, all currently requesting clients are answered. Subsequent requests are answered immediately using the cached data.
|
173
|
-
|
174
|
-
```coffeescript
|
175
|
-
Module.loader.get '/test.json', (data) ->
|
176
|
-
# Use data here.
|
177
|
-
```
|
178
|
-
|
179
165
|
# Development
|
180
166
|
|
181
167
|
## Contributing
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: modularity-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.29.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Goslar
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-11-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -115,10 +115,6 @@ executables: []
|
|
115
115
|
extensions: []
|
116
116
|
extra_rdoc_files: []
|
117
117
|
files:
|
118
|
-
- app/assets/javascripts/modularity/data/ajax_loader.coffee
|
119
|
-
- app/assets/javascripts/modularity/data/cache.coffee
|
120
|
-
- app/assets/javascripts/modularity/data/indexed_cache.coffee
|
121
|
-
- app/assets/javascripts/modularity/data/persistence_manager.coffee
|
122
118
|
- app/assets/javascripts/modularity/mixins/clickable.coffee
|
123
119
|
- app/assets/javascripts/modularity/mixins/closable.coffee
|
124
120
|
- app/assets/javascripts/modularity/modularity.coffee
|
@@ -152,7 +148,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
152
148
|
version: '0'
|
153
149
|
requirements: []
|
154
150
|
rubyforge_project:
|
155
|
-
rubygems_version: 2.0.
|
151
|
+
rubygems_version: 2.0.14
|
156
152
|
signing_key:
|
157
153
|
specification_version: 4
|
158
154
|
summary: A lightweight, object- and component-oriented CoffeeScript framework for
|
@@ -1,77 +0,0 @@
|
|
1
|
-
#= require modularity/data/cache
|
2
|
-
|
3
|
-
|
4
|
-
# A generic ajax loader for parallel GET requests.
|
5
|
-
# Prevents duplicate requests, caches the responses
|
6
|
-
# to answer subsequent requests immediately
|
7
|
-
# without additional server requests.
|
8
|
-
#
|
9
|
-
# Warning: Caches the responses, so once a request is cached,
|
10
|
-
# any new content on the same URL will not be visible!
|
11
|
-
class modularity.AjaxLoader
|
12
|
-
|
13
|
-
constructor: (params = {}) ->
|
14
|
-
|
15
|
-
# Caches the callbacks.
|
16
|
-
@cb_cache = new modularity.Cache()
|
17
|
-
|
18
|
-
# Whether to perform caching of data.
|
19
|
-
# Default: no.
|
20
|
-
@caching = !!params.caching
|
21
|
-
|
22
|
-
# Caches the data loaded.
|
23
|
-
@data_cache = new modularity.Cache()
|
24
|
-
|
25
|
-
# The number of currently running loading operations.
|
26
|
-
@loader_count = 0
|
27
|
-
|
28
|
-
|
29
|
-
# The different events that this class can fire.
|
30
|
-
@events =
|
31
|
-
AJAX_LOADING: 'AJAX_LOADING'
|
32
|
-
AJAX_LOADED: 'AJAX_LOADED'
|
33
|
-
|
34
|
-
|
35
|
-
# Loads the data from the given URL asynchronously.
|
36
|
-
get: (url, callback) ->
|
37
|
-
|
38
|
-
# Return immediately if we have cached data.
|
39
|
-
if @caching
|
40
|
-
cached_data = @data_cache.get url
|
41
|
-
return callback(cached_data) if cached_data?
|
42
|
-
|
43
|
-
# Here, we have no cached data. Check
|
44
|
-
|
45
|
-
# If a GET call to this URL is already in progress -->
|
46
|
-
# add the given callback to the list of waiting callbacks.
|
47
|
-
request_in_progress = @cb_cache.get url
|
48
|
-
return request_in_progress.push(callback) if request_in_progress?
|
49
|
-
|
50
|
-
# Here, no request is currently in progress --> start a new one.
|
51
|
-
|
52
|
-
# Add callback to callback list.
|
53
|
-
@cb_cache.add url, [callback]
|
54
|
-
|
55
|
-
# Fire 'loading' event if this is the start of a loading operation.
|
56
|
-
@loader_count++
|
57
|
-
if @loader_count == 1
|
58
|
-
modularity.fire_global_event modularity.AjaxLoader.events.AJAX_LOADING
|
59
|
-
|
60
|
-
# Perform the request.
|
61
|
-
jQuery.get url, (data) =>
|
62
|
-
|
63
|
-
# Add result to cache.
|
64
|
-
if @caching
|
65
|
-
@data_cache.add url, data
|
66
|
-
|
67
|
-
# Call callbacks.
|
68
|
-
cb(data) for cb in @cb_cache.get url
|
69
|
-
|
70
|
-
# Remove request from callback list.
|
71
|
-
@cb_cache.remove url
|
72
|
-
|
73
|
-
# Fire 'loaded' event.
|
74
|
-
@loader_count--
|
75
|
-
if @loader_count == 0
|
76
|
-
modularity.fire_global_event modularity.AjaxLoader.events.AJAX_LOADED
|
77
|
-
|
@@ -1,65 +0,0 @@
|
|
1
|
-
#= require modularity/tools/object_tools
|
2
|
-
|
3
|
-
# A generic cache.
|
4
|
-
# Stores key-value pairs.
|
5
|
-
class modularity.Cache
|
6
|
-
|
7
|
-
constructor: ->
|
8
|
-
|
9
|
-
# Container for the cached objects.
|
10
|
-
@cache = {}
|
11
|
-
|
12
|
-
|
13
|
-
# Adds the given entry to the cache.
|
14
|
-
# Overwrites existing entries.
|
15
|
-
add: (key, value) ->
|
16
|
-
@cache[key] = value
|
17
|
-
|
18
|
-
|
19
|
-
# Returns the entry with the given key from the cache, or NULL if no entry exists.
|
20
|
-
get: (key) ->
|
21
|
-
@cache[key]
|
22
|
-
|
23
|
-
|
24
|
-
# Looks up several entries at once.
|
25
|
-
# Returns a hash of found entries, and a list of missing entries.
|
26
|
-
get_many: (keys) ->
|
27
|
-
result = { found: {}, missing: [] }
|
28
|
-
for key in keys
|
29
|
-
do (key) =>
|
30
|
-
value = @cache[key]
|
31
|
-
if value
|
32
|
-
result.found[key] = value
|
33
|
-
else
|
34
|
-
result.missing.push key
|
35
|
-
result
|
36
|
-
getMany: Cache::get_many
|
37
|
-
|
38
|
-
|
39
|
-
# Returns the number of cached objects.
|
40
|
-
length: () ->
|
41
|
-
modularity.object_length @cache
|
42
|
-
|
43
|
-
|
44
|
-
# Removes the entry with the given key.
|
45
|
-
remove: (key) =>
|
46
|
-
delete @cache[key]
|
47
|
-
|
48
|
-
|
49
|
-
# Removes all entries with the given keys.
|
50
|
-
remove_many: (keys) ->
|
51
|
-
@remove(key) for key in keys
|
52
|
-
|
53
|
-
|
54
|
-
# Replaces the cache with the given data.
|
55
|
-
# When 'key' is given, treats 'data' as an array of objects, and indexes each element by the given key.
|
56
|
-
# When 'key' is not given, treats 'data' as an already indexed hash object.
|
57
|
-
replace_all: (data, key) ->
|
58
|
-
if key
|
59
|
-
# Key given --> index the data array.
|
60
|
-
@add(entry[key], entry) for entry in data
|
61
|
-
else
|
62
|
-
# Key not given --> use data as the new cache.
|
63
|
-
@cache = data
|
64
|
-
replaceAll: Cache::replace_all
|
65
|
-
|
@@ -1,32 +0,0 @@
|
|
1
|
-
#= require modularity/data/cache
|
2
|
-
|
3
|
-
# Provides fast and convenient retrieval of hash objects
|
4
|
-
# by indexing them on a given key column.
|
5
|
-
class modularity.IndexedCache
|
6
|
-
|
7
|
-
constructor: (@key = 'id') ->
|
8
|
-
@cache = new modularity.Cache
|
9
|
-
|
10
|
-
|
11
|
-
add: (entry) ->
|
12
|
-
@cache.add entry[@key], entry
|
13
|
-
|
14
|
-
|
15
|
-
add_all: (entries) ->
|
16
|
-
@add(entry) for entry in entries
|
17
|
-
|
18
|
-
|
19
|
-
remove: (entry_id) ->
|
20
|
-
@cache.remove entry_id
|
21
|
-
|
22
|
-
|
23
|
-
remove_many: (entry_ids) ->
|
24
|
-
@cache.remove_many entry_ids
|
25
|
-
|
26
|
-
|
27
|
-
get: (key) ->
|
28
|
-
@cache.get key
|
29
|
-
|
30
|
-
|
31
|
-
length: => @cache.length()
|
32
|
-
|
@@ -1,238 +0,0 @@
|
|
1
|
-
#= require modularity/data/ajax_loader
|
2
|
-
#= require modularity/data/indexed_cache
|
3
|
-
#= require modularity/tools/object_tools
|
4
|
-
|
5
|
-
# Provides persistence services for data models.
|
6
|
-
#
|
7
|
-
# This class operates against a standard RESTful data API, whole path is given in params.url.
|
8
|
-
# In addition to the standard RESTful routes, the data API is expected to support these methods for performance reasons:
|
9
|
-
# * DELETE /entries: Delete a whole batch of entries at once. The ids of the entries to delete are given as a JSON hash in the body of the request.
|
10
|
-
# *
|
11
|
-
class modularity.PersistenceManager
|
12
|
-
|
13
|
-
constructor: (params) ->
|
14
|
-
|
15
|
-
# Copy of the data as it is on the server.
|
16
|
-
@server_data = new modularity.IndexedCache
|
17
|
-
|
18
|
-
# Copy of the data as it is on the client.
|
19
|
-
@client_data = new modularity.IndexedCache
|
20
|
-
|
21
|
-
# The base url on the server. Expected to be a fully RESTful API.
|
22
|
-
@base_url = params.url
|
23
|
-
|
24
|
-
# Name of the 'id' column for models.
|
25
|
-
@key = params.key or 'id'
|
26
|
-
|
27
|
-
# Name of the model class (e.g. "user").
|
28
|
-
@model_name = params.model_name
|
29
|
-
|
30
|
-
# For handling parallel requests to the server.
|
31
|
-
@loader = new modularity.AjaxLoader { cache: no }
|
32
|
-
|
33
|
-
|
34
|
-
# Adds the given data objects to the server cache.
|
35
|
-
add_all: (data) ->
|
36
|
-
@server_data.add_all data
|
37
|
-
|
38
|
-
|
39
|
-
# Returns an array containing only the changed objects.
|
40
|
-
# Each object contains only the changed columns + key column.
|
41
|
-
changed_objects_columns: (objects) ->
|
42
|
-
modularity.tap [], (result) =>
|
43
|
-
for object in objects
|
44
|
-
diff = modularity.object_diff @server_data.get(object[@key]), object
|
45
|
-
continue if modularity.object_length(diff) == 0
|
46
|
-
diff[@key] = object[@key]
|
47
|
-
result.push(diff)
|
48
|
-
|
49
|
-
|
50
|
-
# Returns the URL to access the collection of objects.
|
51
|
-
collection_url: ->
|
52
|
-
"#{@base_url}.json"
|
53
|
-
|
54
|
-
|
55
|
-
# Creates the given object on the server.
|
56
|
-
create: (obj, success_callback, error_callback) ->
|
57
|
-
data = {}
|
58
|
-
data[@model_name] = obj
|
59
|
-
|
60
|
-
jQuery.ajax
|
61
|
-
url: @collection_url()
|
62
|
-
type: 'POST'
|
63
|
-
data: data
|
64
|
-
success: (server_response) =>
|
65
|
-
server_obj = server_response[@model_name]
|
66
|
-
@server_data.add server_obj
|
67
|
-
success_callback server_obj
|
68
|
-
error: (xhr) =>
|
69
|
-
error_callback(xhr.responseText) if error_callback
|
70
|
-
|
71
|
-
|
72
|
-
# Deletes the given object from the server.
|
73
|
-
delete: (obj, success_callback, error_callback) ->
|
74
|
-
@client_data.remove obj
|
75
|
-
@server_data.remove obj
|
76
|
-
jQuery.ajax
|
77
|
-
url: @entry_url(obj)
|
78
|
-
type: 'DELETE'
|
79
|
-
success: ->
|
80
|
-
success_callback() if success_callback?
|
81
|
-
error: (xhr) ->
|
82
|
-
error_callback(xhr.responseText) if error_callback
|
83
|
-
|
84
|
-
|
85
|
-
# Deletes the given objects from the server.
|
86
|
-
delete_many: (object_ids, success_callback, error_callback) ->
|
87
|
-
@client_data.remove_many object_ids
|
88
|
-
@server_data.remove_many object_ids
|
89
|
-
jQuery.ajax
|
90
|
-
url: @base_url
|
91
|
-
type: 'DELETE'
|
92
|
-
data: {ids: object_ids}
|
93
|
-
success: ->
|
94
|
-
success_callback() if success_callback?
|
95
|
-
error: (xhr) ->
|
96
|
-
error_callback(xhr.responseText) if error_callback
|
97
|
-
|
98
|
-
|
99
|
-
# Returns the url to access a single entry.
|
100
|
-
entry_url: (entry) ->
|
101
|
-
"#{@base_url}/#{entry[@key]}.json"
|
102
|
-
|
103
|
-
|
104
|
-
# Returns the url to access the collection of entries.
|
105
|
-
entries_url: ->
|
106
|
-
"#{@base_url}.json"
|
107
|
-
|
108
|
-
|
109
|
-
# Returns the cached data object, or undefined.
|
110
|
-
get_cached: (key) ->
|
111
|
-
|
112
|
-
# Try to use client_data cache.
|
113
|
-
client_obj = @client_data.get key
|
114
|
-
return client_obj if client_obj
|
115
|
-
|
116
|
-
# No data in client cache --> try to use server cache.
|
117
|
-
server_obj = @server_data.get key
|
118
|
-
if server_obj
|
119
|
-
client_obj = modularity.clone_hash server_obj
|
120
|
-
@client_data.add client_obj
|
121
|
-
return client_obj
|
122
|
-
|
123
|
-
# Object not found in client or server cache.
|
124
|
-
return undefined
|
125
|
-
|
126
|
-
|
127
|
-
# Returns the entry with the given key.
|
128
|
-
load: (key, success_callback) ->
|
129
|
-
|
130
|
-
# Try to load from cache.
|
131
|
-
return success_callback(entry) if entry = @get_cached key
|
132
|
-
|
133
|
-
# No data on client at all --> load data from server.
|
134
|
-
@loader.get "#{@base_url}/#{key}", (server_entry) =>
|
135
|
-
@server_data.add server_entry
|
136
|
-
client_entry = modularity.clone_hash server_entry
|
137
|
-
@client_data.add client_entry
|
138
|
-
success_callback client_entry
|
139
|
-
|
140
|
-
|
141
|
-
# Loads all objects from the server.
|
142
|
-
# Provides the given params as parameters to the GET request.
|
143
|
-
load_all: (params, success_callback, error_callback) ->
|
144
|
-
jQuery.ajax
|
145
|
-
url: @collection_url()
|
146
|
-
cache: no
|
147
|
-
data: params
|
148
|
-
success: (data) =>
|
149
|
-
@server_data.add_all data
|
150
|
-
success_callback() if success_callback
|
151
|
-
error: (xhr) ->
|
152
|
-
error_callback(xhr.responseText) if error_callback
|
153
|
-
|
154
|
-
|
155
|
-
# Loads all entries with the given ids.
|
156
|
-
load_many: (ids, success_callback) ->
|
157
|
-
missing_ids = []
|
158
|
-
entries = []
|
159
|
-
$.each ids, (pos, id) =>
|
160
|
-
entry = @get_cached id
|
161
|
-
if entry
|
162
|
-
entries.push entry
|
163
|
-
else
|
164
|
-
missing_ids.push id
|
165
|
-
|
166
|
-
if missing_ids.length == 0
|
167
|
-
return success_callback(entries)
|
168
|
-
|
169
|
-
alert "uncached entries found: #{missing_ids}"
|
170
|
-
|
171
|
-
|
172
|
-
# Saves the given object.
|
173
|
-
# Does the right thing (create or update) dependent on
|
174
|
-
# whether the object already has a key parameter.
|
175
|
-
save: (obj, success_callback, error_callback) ->
|
176
|
-
if obj[@key]?
|
177
|
-
@update obj, success_callback, error_callback
|
178
|
-
else
|
179
|
-
@create obj, success_callback, error_callback
|
180
|
-
|
181
|
-
|
182
|
-
# Updates the given object.
|
183
|
-
#
|
184
|
-
# The given object must exist on the server already,
|
185
|
-
# and have a proper value in the key attribute.
|
186
|
-
update: (obj, success_callback, error_callback) ->
|
187
|
-
|
188
|
-
# Handle updating several objects.
|
189
|
-
return @update_many(obj, success_callback, error_callback) if $.type(obj) == 'array'
|
190
|
-
|
191
|
-
# Create a new hash, containing only the changed attributes between obj and it's replica in @server_data.
|
192
|
-
diff_obj = modularity.object_diff @server_data.get(obj[@key]), obj
|
193
|
-
if modularity.object_length(diff_obj) == 0
|
194
|
-
success_callback obj if success_callback
|
195
|
-
return
|
196
|
-
|
197
|
-
# Send to server
|
198
|
-
data = {}
|
199
|
-
data[@model_name] = diff_obj
|
200
|
-
jQuery.ajax
|
201
|
-
url: @entry_url(obj)
|
202
|
-
type: 'PUT'
|
203
|
-
data: data
|
204
|
-
success: (server_response) =>
|
205
|
-
server_obj = server_response[@model_name]
|
206
|
-
@server_data.add server_obj
|
207
|
-
client_obj = modularity.clone_hash server_obj
|
208
|
-
@client_data.add client_obj
|
209
|
-
success_callback client_obj if success_callback
|
210
|
-
error: (xhr) ->
|
211
|
-
error_callback(xhr.responseText) if error_callback
|
212
|
-
|
213
|
-
|
214
|
-
# Bulk-updates the given objects.
|
215
|
-
# All the existing objects must exist on the server already,
|
216
|
-
# and have a value in the key attribute.
|
217
|
-
update_many: (objects, success_callback, error_callback) ->
|
218
|
-
|
219
|
-
# Find all objects that have been changed on the client.
|
220
|
-
diff_objects = @changed_objects_columns objects
|
221
|
-
|
222
|
-
# Send to server
|
223
|
-
data = {}
|
224
|
-
data["#{@model_name}s"] = diff_objects
|
225
|
-
jQuery.ajax
|
226
|
-
url: @entries_url()
|
227
|
-
type: 'PUT'
|
228
|
-
data: data
|
229
|
-
success: (server_response) =>
|
230
|
-
server_objects = server_response["#{@model_name}s"]
|
231
|
-
client_objects = (for server_object in server_objects
|
232
|
-
@server_data.add server_object
|
233
|
-
client_object = modularity.clone_hash server_object
|
234
|
-
@client_data.add client_object
|
235
|
-
client_object)
|
236
|
-
success_callback(client_objects) if success_callback
|
237
|
-
error: (xhr) ->
|
238
|
-
error_callback(xhr.responseText) if error_callback
|