jsb-rails 1.0.0 → 3.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c32a2dcaa69f191fd655263efe511f12487137ed
4
- data.tar.gz: 735f68a353b576fc0f7947146d151b0408d25d5e
3
+ metadata.gz: 4e794aa1af14dd917b871a9ff559c9ad237f2cb9
4
+ data.tar.gz: 4a14cc27c024b2f438c4c9364b62f9bae69166c6
5
5
  SHA512:
6
- metadata.gz: 852800ca2ce00b98aead0759452c99585ffb5cde7440505e9971aa4dd44b1d6444444853d78ec957efe831c7b72bed9b86bf1b77b5f9dfb2cf0bc64e1c843de5
7
- data.tar.gz: 2603c8ef5335c7fc905ed711981757464331b44ba5ad04e83d4565653ad6269d024793c8988ae8ea2a7f9b6f32db375339b668a115989f6c89411bf0f60e5e57
6
+ metadata.gz: 2f0f1188cd1dc994a07cd6db488f916ee4f85846e260e785987f90afde4588c4d91613d3f620354e797d75f7d1490e0d93e3b23bc7e94e04ef6907f650b46d59
7
+ data.tar.gz: 6d7f8ccc5de6123ec27df13bda8707858bef6934ce0c3c215a4334d772c10c9cceab3f6fa11cd8709227addacce1fb0c6f38ad187ddd6617a3d789047332c994
data/README.md CHANGED
@@ -8,7 +8,7 @@ https://github.com/DracoBlue/jsb
8
8
 
9
9
  ## What version of jsb?
10
10
 
11
- the latest and greatest 2.0.0
11
+ the latest and greatest 3.0.0
12
12
 
13
13
  ## Installation
14
14
 
@@ -1,6 +1,6 @@
1
1
  module Jsb
2
2
  module Rails
3
- VERSION = "1.0.0"
4
- JSB_VERSION = "2.3.0"
3
+ VERSION = "3.0.0"
4
+ JSB_VERSION = "3.0.0"
5
5
  end
6
6
  end
@@ -8,492 +8,405 @@
8
8
  * information, please see the LICENSE file in the root folder.
9
9
  */
10
10
 
11
- jsb = {
12
- prefix: 'jsb_',
13
- prefix_regexp: /jsb_([^\s]+)/,
14
-
15
- handlers: {},
16
- listeners: [],
17
- last_event_values: {},
18
- sticky_event_values: {},
19
-
20
- /**
21
- * Set the prefix for the jsb toolkit.
22
- *
23
- * @param {String} prefix
24
- */
25
- setPrefix: function(prefix) {
26
- this.prefix = prefix + '_';
27
- this.prefix_regexp = new RegExp(this.prefix + '([^\s]+)');
28
- },
29
-
30
- /**
31
- * Register a new handler with the given constructor function
32
- *
33
- * @param {String} key
34
- * @param {Function} handler_function
35
- */
36
- registerHandler: function(key, handler_function) {
37
- this.handlers[key] = handler_function;
38
- },
39
-
40
- /**
41
- * Apply all behaviours on a given dom_element and it's children.
42
- *
43
- * @param {HTMLElement} dom_element
44
- */
45
- applyBehaviour: function(parent_dom_element) {
46
- var dom_elements = this.getJsbElementsInDomElement(parent_dom_element);
47
- var dom_elements_length = dom_elements.length;
48
- var dom_element = null;
49
- var key = null;
50
- var key_match = null;
51
-
52
- for (var i = 0; i < dom_elements_length; i++) {
53
- dom_element = dom_elements[i];
54
- this.removeClassFromElement(dom_element, this.prefix);
55
-
56
- do {
57
- key_match = dom_element.className.match(this.prefix_regexp);
58
- if (key_match) {
59
- key = key_match[1];
60
- this.callHandler(key, dom_element);
61
- this.removeClassFromElement(dom_element, this.prefix + key);
62
- }
63
- } while(key_match);
64
-
65
- }
11
+ (function (root, factory) {
12
+ if (typeof define === 'function' && define.amd) {
13
+ define('jsb', factory);
14
+ } else if (typeof module === 'object' && module.exports) {
15
+ module.exports = factory();
16
+ } else {
17
+ root.jsb = factory();
18
+ }
19
+ }(this, function () {
66
20
 
67
- this.fireEvent('Jsb::BEHAVIOURS_APPLIED');
68
- },
21
+ var jsb = {
22
+ prefix: 'jsb_',
23
+ prefix_regexp: /jsb_([^\s]+)/,
69
24
 
70
- /**
71
- * Fires an event with the given name and values.
72
- * @param {String} name
73
- * @param {Object} [values={}]
74
- */
75
- fireEvent: function(name, values, sticky) {
76
- values = values || {};
77
- sticky = sticky || false;
25
+ handlers: {},
26
+ listeners: [],
27
+ last_event_values: {},
28
+ sticky_event_values: {},
78
29
 
79
- /*
80
- * Remember the last values for calls to `jsb.whenFired`
30
+ /**
31
+ * Set the prefix for the jsb toolkit.
32
+ *
33
+ * @param {String} prefix
81
34
  */
82
- if (sticky) {
83
- this.sticky_event_values[name] = this.sticky_event_values[name] || [];
84
- this.sticky_event_values[name].push(values);
85
- } else {
86
- this.last_event_values[name] = values;
87
- }
88
-
89
- var listeners = this.listeners;
90
- var listeners_length = listeners.length;
91
- for (var i = 0; i < listeners_length; i++) {
92
- this.rawFireEventToListener(listeners[i], name, values);
93
- }
94
-
95
- if (name === 'Jsb::REMOVED_INSTANCE')
96
- {
97
- this.removeBoundListenersForInstance(values);
98
- }
99
- },
100
-
101
- fireStickyEvent: function(name, values) {
102
- this.fireEvent(name, values, true);
103
- },
104
-
105
- /**
106
- * Adds an event listener for a given name or regular expression.
107
- *
108
- * @param {String|RegExp} name_or_regexp
109
- * @param {Object|Function} [filter_or_cb=null]
110
- * @param {Function} cb
111
- */
112
- on: function(name_or_regexp, filter_or_cb, cb) {
113
- var filter = filter_or_cb || null;
114
-
115
- if (!cb) {
116
- filter = null;
117
- cb = filter_or_cb;
118
- }
35
+ setPrefix: function(prefix) {
36
+ this.prefix = prefix + '_';
37
+ this.prefix_regexp = new RegExp(this.prefix + '([^\s]+)');
38
+ },
39
+
40
+ /**
41
+ * Register a new handler with the given constructor function
42
+ *
43
+ * @param {String} key
44
+ * @param {Function} handler_function
45
+ */
46
+ registerHandler: function(key, handler_function) {
47
+ this.handlers[key] = handler_function;
48
+ },
49
+
50
+ /**
51
+ * Apply all behaviours on a given dom_element and it's children.
52
+ *
53
+ * @param {HTMLElement} dom_element
54
+ */
55
+ applyBehaviour: function(parent_dom_element) {
56
+ var dom_elements = this.getJsbElementsInDomElement(parent_dom_element);
57
+ var dom_elements_length = dom_elements.length;
58
+ var dom_element = null;
59
+ var key = null;
60
+ var key_match = null;
61
+
62
+ for (var i = 0; i < dom_elements_length; i++) {
63
+ dom_element = dom_elements[i];
64
+ this.removeClassFromElement(dom_element, this.prefix);
65
+
66
+ do {
67
+ key_match = dom_element.className.match(this.prefix_regexp);
68
+ if (key_match) {
69
+ key = key_match[1];
70
+ this.callHandler(key, dom_element);
71
+ this.removeClassFromElement(dom_element, this.prefix + key);
72
+ }
73
+ } while(key_match);
119
74
 
120
- this.listeners.push([cb, name_or_regexp, filter]);
75
+ }
121
76
 
122
- var that = this;
123
- var off_handler = function() {
124
- that.off(name_or_regexp, cb);
125
- };
77
+ this.fireEvent('Jsb::BEHAVIOURS_APPLIED');
78
+ },
126
79
 
127
- /*
128
- * Call this method with your jsb instance, to allow automatic removal of the handler on
129
- * disposal of the jsb instance.
80
+ /**
81
+ * Fires an event with the given name and values.
82
+ * @param {String} name
83
+ * @param {Object} [values={}]
130
84
  */
131
- off_handler.dontLeak = function(element) {
132
- for (var i = 0; i < that.listeners.length; i++) {
133
- var listener = that.listeners[i];
134
- if (listener[0] === cb && listener[1] === name_or_regexp && listener[2] === filter) {
135
- listener[3] = element;
136
- return ;
137
- }
85
+ fireEvent: function(name, values, sticky) {
86
+ values = values || {};
87
+ sticky = sticky || false;
88
+
89
+ /*
90
+ * Remember the last values for calls to `jsb.whenFired`
91
+ */
92
+ if (sticky) {
93
+ this.sticky_event_values[name] = this.sticky_event_values[name] || [];
94
+ this.sticky_event_values[name].push(values);
95
+ } else {
96
+ this.last_event_values[name] = values;
138
97
  }
139
- };
140
-
141
- return off_handler;
142
- },
143
-
144
- /**
145
- * Please call jsb.fireEvent('Jsb::REMOVED_INSTANCE', this) within your object
146
- * to free all handlers which are bound to the element (by using the dontLeak-method).
147
- *
148
- * @private
149
- *
150
- * @param instance Jsb Instance
151
- */
152
- removeBoundListenersForInstance: function(instance) {
153
- var new_listeners = [];
154
- var listeners = this.listeners;
155
- var listeners_length = listeners.length;
156
- for (var i = 0; i < listeners_length; i++) {
157
- if (listeners[i][3] !== instance) {
158
- new_listeners.push(listeners[i]);
98
+
99
+ var listeners = this.listeners;
100
+ var listeners_length = listeners.length;
101
+ for (var i = 0; i < listeners_length; i++) {
102
+ this.rawFireEventToListener(listeners[i], name, values);
159
103
  }
160
- }
161
104
 
162
- this.listeners = new_listeners;
163
- },
164
-
165
- /**
166
- * Removes an event listener for a given name or regular expression and handler function.
167
- *
168
- * The handler function needs to be the exact same Function object that was previously registered as an event handler.
169
- *
170
- * @param {String|RegExp} name_or_regexp
171
- * @param {Function} cb
172
- */
173
- off: function(name_or_regexp, cb) {
174
- var listeners = this.listeners;
175
- this.listeners = [];
176
- var listeners_length = listeners.length;
177
- for (var i = 0; i < listeners_length; i++) {
178
- if (!(listeners[i][0] === cb && listeners[i][1].toString() === name_or_regexp.toString())) {
179
- this.listeners.push(listeners[i]);
105
+ if (name === 'Jsb::REMOVED_INSTANCE') {
106
+ this.removeBoundListenersForInstance(values);
180
107
  }
181
- }
182
- },
183
-
184
- /**
185
- * Register to an event as soon as it's fired for the first time
186
- * even if that happend earlier!
187
- *
188
- * @param {String|RegExp} name_or_regexp
189
- * @param {Object|Function} [filter_or_cb=null]
190
- * @param {Function} cb
191
- */
192
- whenFired: function(name_or_regexp, filter_or_cb, cb)
193
- {
194
- var that = this;
195
- var filter = filter_or_cb;
196
-
197
- if (!cb) {
198
- filter = null;
199
- cb = filter_or_cb;
200
- }
108
+ },
109
+
110
+ fireStickyEvent: function(name, values) {
111
+ this.fireEvent(name, values, true);
112
+ },
113
+
114
+ /**
115
+ * Adds an event listener for a given name or regular expression.
116
+ *
117
+ * @param {String|RegExp} name_or_regexp
118
+ * @param {Object|Function} [filter_or_cb=null]
119
+ * @param {Function} cb
120
+ */
121
+ on: function(name_or_regexp, filter_or_cb, cb) {
122
+ var filter = filter_or_cb || null;
201
123
 
202
- var off_handler = this.on(name_or_regexp, filter, cb);
203
-
204
- var is_regexp = (name_or_regexp instanceof RegExp);
205
- if (is_regexp) {
206
- for (var key in this.last_event_values) {
207
- if (this.last_event_values.hasOwnProperty(key) && key.match(name_or_regexp)) {
208
- (function(key)
209
- {
210
- var last_value = that.last_event_values[key];
211
- setTimeout(function()
212
- {
213
- that.rawFireEventToListener([cb, name_or_regexp, filter], key, last_value);
214
- }, 0);
215
- })(key);
216
- }
124
+ if (!cb) {
125
+ filter = null;
126
+ cb = filter_or_cb;
217
127
  }
218
- for (var key in this.sticky_event_values) {
219
- if (this.sticky_event_values.hasOwnProperty(key) && key.match(name_or_regexp)) {
220
- (function(key)
221
- {
222
- var last_values = that.sticky_event_values[key];
223
- var last_values_length = last_values.length;
224
- for (var i = 0; i < last_values_length; i++) {
225
- (function(last_value) {
226
- setTimeout(function()
227
- {
228
- that.rawFireEventToListener([cb, name_or_regexp, filter], key, last_value);
229
- }, 0);
230
- })(last_values[i]);
231
- }
232
- })(key);
128
+
129
+ this.listeners.push([cb, name_or_regexp, filter]);
130
+
131
+ var that = this;
132
+ var off_handler = function() {
133
+ that.off(name_or_regexp, cb);
134
+ };
135
+
136
+ /*
137
+ * Call this method with your jsb instance, to allow automatic removal of the handler on
138
+ * disposal of the jsb instance.
139
+ */
140
+ off_handler.dontLeak = function(element) {
141
+ for (var i = 0; i < that.listeners.length; i++) {
142
+ var listener = that.listeners[i];
143
+ if (listener[0] === cb && listener[1] === name_or_regexp && listener[2] === filter) {
144
+ listener[3] = element;
145
+ return ;
146
+ }
233
147
  }
234
- }
235
- } else {
236
- if (typeof this.last_event_values[name_or_regexp] !== 'undefined') {
237
- var last_value = that.last_event_values[name_or_regexp];
238
- setTimeout(function()
239
- {
240
- that.rawFireEventToListener([cb, name_or_regexp, filter], name_or_regexp, last_value);
241
- }, 0);
242
- }
243
- if (typeof this.sticky_event_values[name_or_regexp] !== 'undefined') {
244
- var last_values = that.sticky_event_values[name_or_regexp];
245
- var last_values_length = last_values.length;
246
- for (var i = 0; i < last_values_length; i++) {
247
- (function(last_value) {
248
- setTimeout(function()
249
- {
250
- that.rawFireEventToListener([cb, name_or_regexp, filter], name_or_regexp, last_value);
251
- }, 0);
252
- })(last_values[i]);
148
+ };
149
+
150
+ return off_handler;
151
+ },
152
+
153
+ /**
154
+ * Please call jsb.fireEvent('Jsb::REMOVED_INSTANCE', this) within your object
155
+ * to free all handlers which are bound to the element (by using the dontLeak-method).
156
+ *
157
+ * @private
158
+ *
159
+ * @param instance Jsb Instance
160
+ */
161
+ removeBoundListenersForInstance: function(instance) {
162
+ var new_listeners = [];
163
+ var listeners = this.listeners;
164
+ var listeners_length = listeners.length;
165
+ for (var i = 0; i < listeners_length; i++) {
166
+ if (listeners[i][3] !== instance) {
167
+ new_listeners.push(listeners[i]);
253
168
  }
254
169
  }
255
- }
256
170
 
257
- return off_handler;
258
- },
259
-
260
- /**
261
- * @private
262
- */
263
- rawFireEventToListener: function(listener, name, values) {
264
- var is_regexp_match = (listener[1] instanceof RegExp && name.match(listener[1]));
265
-
266
- if (is_regexp_match || listener[1] === name) {
267
- var filter = listener[2];
268
- var is_match = true;
269
- if (filter) {
270
- for (var filter_key in filter) {
271
- if (filter.hasOwnProperty(filter_key)) {
272
- is_match = is_match && (typeof values[filter_key] !== 'undefined' && filter[filter_key] === values[filter_key]);
273
- }
171
+ this.listeners = new_listeners;
172
+ },
173
+
174
+ /**
175
+ * Removes an event listener for a given name or regular expression and handler function.
176
+ *
177
+ * The handler function needs to be the exact same Function object that was previously registered as an event handler.
178
+ *
179
+ * @param {String|RegExp} name_or_regexp
180
+ * @param {Function} cb
181
+ */
182
+ off: function(name_or_regexp, cb) {
183
+ var listeners = this.listeners;
184
+ this.listeners = [];
185
+ var listeners_length = listeners.length;
186
+ for (var i = 0; i < listeners_length; i++) {
187
+ if (!(listeners[i][0] === cb && listeners[i][1].toString() === name_or_regexp.toString())) {
188
+ this.listeners.push(listeners[i]);
274
189
  }
275
190
  }
191
+ },
192
+
193
+ /**
194
+ * Register to an event as soon as it's fired for the first time
195
+ * even if that happend earlier!
196
+ *
197
+ * @param {String|RegExp} name_or_regexp
198
+ * @param {Object|Function} [filter_or_cb=null]
199
+ * @param {Function} cb
200
+ */
201
+ whenFired: function(name_or_regexp, filter_or_cb, cb) {
202
+ var that = this;
203
+ var filter = filter_or_cb;
276
204
 
277
- if (is_match) {
278
- listener[0](values, name);
205
+ if (!cb) {
206
+ filter = null;
207
+ cb = filter_or_cb;
279
208
  }
280
- }
281
- },
282
-
283
- /**
284
- * Call a specific handler on a given dom element
285
- * @private
286
- * @param {String} key
287
- * @param {HTMLElement} dom_element
288
- */
289
- callHandler: function(key, dom_element) {
290
- if (typeof this.handlers[key] === 'undefined') {
291
- if (typeof require === "undefined") {
292
- throw new Error('The handler ' + key + ' is not defined!');
209
+
210
+ var off_handler = this.on(name_or_regexp, filter, cb);
211
+
212
+ var is_regexp = (name_or_regexp instanceof RegExp);
213
+ if (is_regexp) {
214
+ for (var key in this.last_event_values) {
215
+ if (this.last_event_values.hasOwnProperty(key) && key.match(name_or_regexp)) {
216
+ (function(key) {
217
+ var last_value = that.last_event_values[key];
218
+ setTimeout(function() {
219
+ that.rawFireEventToListener([cb, name_or_regexp, filter], key, last_value);
220
+ }, 0);
221
+ })(key);
222
+ }
223
+ }
224
+ for (var key in this.sticky_event_values) {
225
+ if (this.sticky_event_values.hasOwnProperty(key) && key.match(name_or_regexp)) {
226
+ (function(key) {
227
+ var last_values = that.sticky_event_values[key];
228
+ var last_values_length = last_values.length;
229
+ for (var i = 0; i < last_values_length; i++) {
230
+ (function(last_value) {
231
+ setTimeout(function() {
232
+ that.rawFireEventToListener([cb, name_or_regexp, filter], key, last_value);
233
+ }, 0);
234
+ })(last_values[i]);
235
+ }
236
+ })(key);
237
+ }
238
+ }
293
239
  } else {
294
- require([key], function(require_result) {
295
- if (typeof jsb.handlers[key] === 'undefined') {
296
- if (typeof require_result === "undefined")
297
- {
298
- throw new Error('The handler ' + key + ' is not defined (even with requirejs)!');
299
- }
300
- else
301
- {
302
- jsb.registerHandler(key, require_result);
303
- }
240
+ if (typeof this.last_event_values[name_or_regexp] !== 'undefined') {
241
+ var last_value = that.last_event_values[name_or_regexp];
242
+ setTimeout(function() {
243
+ that.rawFireEventToListener([cb, name_or_regexp, filter], name_or_regexp, last_value);
244
+ }, 0);
245
+ }
246
+ if (typeof this.sticky_event_values[name_or_regexp] !== 'undefined') {
247
+ var last_values = that.sticky_event_values[name_or_regexp];
248
+ var last_values_length = last_values.length;
249
+ for (var i = 0; i < last_values_length; i++) {
250
+ (function(last_value) {
251
+ setTimeout(function() {
252
+ that.rawFireEventToListener([cb, name_or_regexp, filter], name_or_regexp, last_value);
253
+ }, 0);
254
+ })(last_values[i]);
304
255
  }
305
- jsb.callHandler(key, dom_element);
306
- });
307
- return ;
256
+ }
308
257
  }
309
- }
310
258
 
311
- var value_string = null;
312
- var dashed_key_name = key.toString().replace(/\//g, "-");
259
+ return off_handler;
260
+ },
313
261
 
314
- if (dom_element.getAttribute('data-jsb-' + dashed_key_name)) {
315
- /*
316
- * Nice, we have a class specific data-jsb attribute -> let's use that one!
317
- */
318
- value_string = dom_element.getAttribute('data-jsb-' + dashed_key_name);
319
- } else if (dom_element.getAttribute('data-jsb')) {
320
- /*
321
- * Nice, we have a data-jsb attribute -> let's use that one!
322
- */
323
- value_string = dom_element.getAttribute('data-jsb');
324
- }
325
-
326
- if (value_string !== null) {
327
- new this.handlers[key](dom_element, this.parseValueString(value_string));
328
- } else {
329
- new this.handlers[key](dom_element);
330
- }
331
- },
332
-
333
- /**
334
- * Parse a json or a query string into an object hash
335
- * @private
336
- * @param {String} value_string
337
- * @return {Object}
338
- */
339
- parseValueString: function(value_string) {
340
- if (value_string.substr(0, 1) == '{') {
341
- return JSON.parse(value_string);
342
- } else {
343
- var value = {};
344
- var parts = value_string.split("&");
345
- var parts_length = parts.length;
346
- for (var i = 0; i < parts_length; i++) {
347
- var query_string_entry = parts[i].split("=");
348
- var value_key = decodeURIComponent(query_string_entry[0]);
349
- var value_content = decodeURIComponent(query_string_entry.slice(1).join("="));
350
- value[value_key] = value_content;
351
- }
352
- return value;
353
- }
354
- },
355
-
356
- /**
357
- * @private
358
- * @param {HTMLElement} dom_element
359
- * @param {String} class_name
360
- * @return {void}
361
- */
362
- removeClassFromElement: function(dom_element, class_name) {
363
- var element_class_name = dom_element.className;
364
- element_class_name = element_class_name.replace(new RegExp('(^|[\\s]+)' + class_name + '($|[\\s]+)'), '$1$2');
365
- dom_element.className = element_class_name;
366
- },
367
-
368
- /**
369
- * Return all elements within the dom_element, which match the
370
- * jsb prefix.
371
- *
372
- * @private
373
- * @param {HTMLElement} dom_element
374
- * @returns {HTMLElement[]}
375
- */
376
- getJsbElementsInDomElement: function(dom_element) {
377
- var dom_elements = [];
378
- /*
379
- * We need to use concat, because otherwise the returned array would
380
- * change as soon as we remove the element's className.
262
+ /**
263
+ * @private
381
264
  */
382
- var raw_dom_elements = null;
383
- if (dom_element.getElementsByClassName) {
384
- raw_dom_elements = dom_element.getElementsByClassName(this.prefix);
385
- } else {
386
- raw_dom_elements = dom_element.querySelectorAll('.' + this.prefix);
387
- }
388
- var raw_dom_elements_length = raw_dom_elements.length;
389
- for (var r = 0; r < raw_dom_elements_length; r++) {
390
- dom_elements.push(raw_dom_elements[r]);
391
- }
392
-
393
- return dom_elements;
394
- }
395
- };
396
-
397
- if (typeof jQuery !== 'undefined') {
398
- /*
399
- * If we have jQuery available, we can use the jQuery methods instead
400
- * of the native ones (thus having compatibility for IE < 8, FF < 3 and so on)
401
- */
402
- jsb.removeClassFromElement = function(dom_element, class_name) {
403
- jQuery(dom_element).removeClass(class_name);
404
- };
405
-
406
- jsb.getJsbElementsInDomElement = function(dom_element) {
407
- return jQuery(dom_element).find('.' + this.prefix);
408
- };
265
+ rawFireEventToListener: function(listener, name, values) {
266
+ var is_regexp_match = (listener[1] instanceof RegExp && name.match(listener[1]));
267
+
268
+ if (is_regexp_match || listener[1] === name) {
269
+ var filter = listener[2];
270
+ var is_match = true;
271
+ if (filter) {
272
+ for (var filter_key in filter) {
273
+ if (filter.hasOwnProperty(filter_key)) {
274
+ is_match = is_match && (typeof values[filter_key] !== 'undefined' && filter[filter_key] === values[filter_key]);
275
+ }
276
+ }
277
+ }
409
278
 
410
- jsb.parseValueString = function(value_string) {
411
- if (value_string.substr(0, 1) == '{') {
412
- return jQuery.parseJSON(value_string);
413
- } else {
414
- var value = {};
415
- var parts = value_string.split("&");
416
- var parts_length = parts.length;
417
- for (var i = 0; i < parts_length; i++) {
418
- var query_string_entry = parts[i].split("=");
419
- var value_key = decodeURIComponent(query_string_entry[0]);
420
- var value_content = decodeURIComponent(query_string_entry.slice(1).join("="));
421
- value[value_key] = value_content;
279
+ if (is_match) {
280
+ listener[0](values, name);
281
+ }
422
282
  }
423
- return value;
424
- }
425
- };
283
+ },
426
284
 
427
- if (typeof window !== "undefined") {
428
- /*
429
- * Fire domready in a jQuery way!
285
+ /**
286
+ * Call a specific handler on a given dom element
287
+ * @private
288
+ * @param {String} key
289
+ * @param {HTMLElement} dom_element
430
290
  */
291
+ callHandler: function(key, dom_element) {
292
+ if (typeof this.handlers[key] === 'undefined') {
293
+ if (typeof require === 'undefined') {
294
+ throw new Error('The handler ' + key + ' is not defined!');
295
+ } else {
296
+ require([key], function(require_result) {
297
+ if (typeof jsb.handlers[key] === 'undefined') {
298
+ if (typeof require_result === 'undefined') {
299
+ throw new Error('The handler ' + key + ' is not defined (even with requirejs)!');
300
+ } else {
301
+ jsb.registerHandler(key, require_result);
302
+ }
303
+ }
304
+ jsb.callHandler(key, dom_element);
305
+ });
306
+ return ;
307
+ }
308
+ }
431
309
 
432
- jQuery(window.document).ready(function () {
433
- jsb.applyBehaviour(window.document);
434
- });
435
- }
436
- } else if (typeof MooTools !== 'undefined') {
437
- /*
438
- * If we have MooTools available, we can use the MooTools methods instead
439
- * of the native ones (thus having compatibility for IE < 8, FF < 3 and so on)
440
- */
441
- jsb.removeClassFromElement = function(dom_element, class_name) {
442
- $(dom_element).removeClass(class_name);
443
- };
310
+ var value_string = null;
311
+ var dashed_key_name = key.toString().replace(/\//g, '-');
312
+
313
+ if (dom_element.getAttribute('data-jsb-' + dashed_key_name)) {
314
+ /*
315
+ * Nice, we have a class specific data-jsb attribute -> let's use that one!
316
+ */
317
+ value_string = dom_element.getAttribute('data-jsb-' + dashed_key_name);
318
+ } else if (dom_element.getAttribute('data-jsb')) {
319
+ /*
320
+ * Nice, we have a data-jsb attribute -> let's use that one!
321
+ */
322
+ value_string = dom_element.getAttribute('data-jsb');
323
+ }
444
324
 
445
- jsb.getJsbElementsInDomElement = function(dom_element) {
446
- return $(dom_element).getElements('.' + this.prefix);
447
- };
325
+ if (value_string !== null) {
326
+ new this.handlers[key](dom_element, this.parseValueString(value_string));
327
+ } else {
328
+ new this.handlers[key](dom_element);
329
+ }
330
+ },
448
331
 
449
- jsb.parseValueString = function(value_string) {
450
- if (value_string.substr(0, 1) == '{') {
451
- return JSON.decode(value_string);
452
- } else {
453
- var value = {};
454
- var parts = value_string.split("&");
455
- var parts_length = parts.length;
456
- for (var i = 0; i < parts_length; i++) {
457
- var query_string_entry = parts[i].split("=");
458
- var value_key = decodeURIComponent(query_string_entry[0]);
459
- var value_content = decodeURIComponent(query_string_entry.slice(1).join("="));
460
- value[value_key] = value_content;
332
+ /**
333
+ * Parse a json or a query string into an object hash
334
+ * @private
335
+ * @param {String} value_string
336
+ * @return {Object}
337
+ */
338
+ parseValueString: function(value_string) {
339
+ if (value_string.substr(0, 1) == '{') {
340
+ return JSON.parse(value_string);
341
+ } else {
342
+ var value = {};
343
+ var parts = value_string.split('&');
344
+ var parts_length = parts.length;
345
+ for (var i = 0; i < parts_length; i++) {
346
+ var query_string_entry = parts[i].split('=');
347
+ var value_key = decodeURIComponent(query_string_entry[0]);
348
+ var value_content = decodeURIComponent(query_string_entry.slice(1).join('='));
349
+ value[value_key] = value_content;
350
+ }
351
+ return value;
461
352
  }
462
- return value;
463
- }
464
- };
353
+ },
465
354
 
466
- if (typeof window !== "undefined") {
467
- /*
468
- * Fire domready in a mootools way!
355
+ /**
356
+ * @private
357
+ * @param {HTMLElement} dom_element
358
+ * @param {String} class_name
359
+ * @return {void}
360
+ */
361
+ removeClassFromElement: function(dom_element, class_name) {
362
+ var element_class_name = dom_element.className;
363
+ element_class_name = element_class_name.replace(new RegExp('(^|[\\s]+)' + class_name + '($|[\\s]+)'), '$1$2');
364
+ dom_element.className = element_class_name;
365
+ },
366
+
367
+ /**
368
+ * Return all elements within the dom_element, which match the
369
+ * jsb prefix.
370
+ *
371
+ * @private
372
+ * @param {HTMLElement} dom_element
373
+ * @returns {HTMLElement[]}
469
374
  */
375
+ getJsbElementsInDomElement: function(dom_element) {
376
+ var dom_elements = [];
377
+ /*
378
+ * We need to use concat, because otherwise the returned array would
379
+ * change as soon as we remove the element's className.
380
+ */
381
+ var raw_dom_elements = null;
382
+ if (dom_element.getElementsByClassName) {
383
+ raw_dom_elements = dom_element.getElementsByClassName(this.prefix);
384
+ } else {
385
+ raw_dom_elements = dom_element.querySelectorAll('.' + this.prefix);
386
+ }
387
+ var raw_dom_elements_length = raw_dom_elements.length;
388
+ for (var r = 0; r < raw_dom_elements_length; r++) {
389
+ dom_elements.push(raw_dom_elements[r]);
390
+ }
470
391
 
471
- $(window).addEvent('domready', function () {
472
- jsb.applyBehaviour(window.document);
473
- });
474
- }
475
- } else {
392
+ return dom_elements;
393
+ }
394
+ };
476
395
 
477
- if (typeof window !== "undefined") {
396
+ if (typeof window !== 'undefined') {
478
397
  /*
479
398
  * Fire domready in a native way!
480
399
  */
481
400
  if (window.addEventListener) {
482
- window.addEventListener("DOMContentLoaded", function() {
401
+ window.addEventListener('DOMContentLoaded', function() {
483
402
  jsb.applyBehaviour(window.document);
484
403
  }, true);
485
404
  } else if(window.attachEvent) {
486
- window.attachEvent("onLoad",function() {
405
+ window.attachEvent('onLoad',function() {
487
406
  jsb.applyBehaviour(window.document);
488
407
  });
489
408
  }
490
409
  }
491
- }
492
-
493
- if (typeof define !== "undefined" && define.amd) {
494
- define('jsb', function() {
495
- return jsb;
496
- });
497
- } else if (typeof module === 'object' && module.exports) {
498
- module.exports = jsb;
499
- }
410
+
411
+ return jsb;
412
+ }));
metadata CHANGED
@@ -1,41 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsb-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - René Kersten
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-09-18 00:00:00.000000000 Z
11
+ date: 2016-05-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.8'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.8'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '10.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '10.0'
41
41
  description: This gem integrates JsBehaviourToolkit with Rails asset pipeline for
@@ -46,8 +46,8 @@ executables: []
46
46
  extensions: []
47
47
  extra_rdoc_files: []
48
48
  files:
49
- - .gitignore
50
- - .travis.yml
49
+ - ".gitignore"
50
+ - ".travis.yml"
51
51
  - CODE_OF_CONDUCT.md
52
52
  - Gemfile
53
53
  - LICENSE.txt
@@ -69,20 +69,19 @@ require_paths:
69
69
  - lib
70
70
  required_ruby_version: !ruby/object:Gem::Requirement
71
71
  requirements:
72
- - - '>='
72
+ - - ">="
73
73
  - !ruby/object:Gem::Version
74
74
  version: '0'
75
75
  required_rubygems_version: !ruby/object:Gem::Requirement
76
76
  requirements:
77
- - - '>='
77
+ - - ">="
78
78
  - !ruby/object:Gem::Version
79
79
  version: '0'
80
80
  requirements: []
81
81
  rubyforge_project:
82
- rubygems_version: 2.4.7
82
+ rubygems_version: 2.4.5.1
83
83
  signing_key:
84
84
  specification_version: 4
85
85
  summary: This gem integrates JsBehaviourToolkit with Rails asset pipeline for ease
86
86
  of use.
87
87
  test_files: []
88
- has_rdoc: