flight-for-rails 1.1.4 → 1.2.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: d88eda3b9ee66fd3f576a3ae5d16432d289405b5
4
- data.tar.gz: d46961d373630ab7ee3b1b2fdcaf3ee598db915f
3
+ metadata.gz: 5f3fefad2bb984a54aa51f73a29b47aba6607c43
4
+ data.tar.gz: 6fface1503e3b8a16c79ddf7b06daec6bf008bbf
5
5
  SHA512:
6
- metadata.gz: 5c4eb45143451494d6510d3231e136218eebadf8a13f3f1f36432cf56385e237d0d81c7f5da46d34bd5d21b461fadabc335f0815b34d91ccc1ba5e194de8008e
7
- data.tar.gz: e5b594a85fc77f9148d98a0028f885f098a925d1480af8ff4a7e4eaf08baf512b30928f2f94387e7a24fa3a0dbe8fcc2124f2fdbf75d36249121d245956c6d2c
6
+ metadata.gz: c6cfe0635fab87024976d4521f1fabeed859b536a513f3769182590d70f57e8fde8331eac1df5ee539de3d9b550f2d2cbd02f23fedc38799e8ceda3aa013337b
7
+ data.tar.gz: 649a0de7a0d81e1ae596c1bfafa6f78eed7a1a9c9d2ae9a4bcab2b8bdf28abd406f51cef0f6113e932aafffbc81a117a4a023c92b3b2d77ddccf198f2bb88014
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013 Sergey Rezvanov
1
+ Copyright (c) 2013-2014 Sergey Rezvanov
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,3 +1,7 @@
1
+ <!---
2
+ This file is automatically generated. Change template/readme.erb if you need.
3
+ -->
4
+
1
5
  FlightForRails
2
6
  ==============
3
7
 
@@ -16,7 +20,7 @@ This gem vendors Flight files and dependecies for Rails assets pipeline.
16
20
  First add the following lines to your application `Gemfile`:
17
21
 
18
22
  ``` ruby
19
- gem 'flight-for-rails', '~> 1.1.3'
23
+ gem 'flight-for-rails', '~> 1.2.0'
20
24
  ```
21
25
 
22
26
  Then run `bundle install` to update your's gems bundle.
data/Rakefile CHANGED
@@ -1,29 +1,40 @@
1
- require File.expand_path('../lib/flight-for-rails/version', __FILE__)
1
+ $:.unshift File.join(File.dirname(__FILE__), 'lib')
2
2
 
3
3
  require 'rubygems'
4
4
  require 'bundler/setup'
5
5
  require 'open-uri'
6
+ require 'erb'
7
+
8
+ require 'flight-for-rails/version'
6
9
 
7
10
  Bundler::GemHelper.install_tasks
8
11
 
9
12
  namespace :flight do
10
13
  desc 'Try to update standalone version of flight.js'
11
14
  task :check_for_updates do
15
+ project_root = Pathname.new(File.expand_path(File.join(File.dirname(__FILE__))))
12
16
  source_file = open('http://flightjs.github.io/release/latest/flight.js')
13
17
 
14
18
  if source_file && (fl = source_file.gets)
15
19
  fl.match /\A\/\*! *Flight *v([0-9]*\.[0-9]*\.[0-9]*)/
16
- if $1 && $1 != FlightForRails::VERSION
20
+ if $1 && (version = $1) != FlightForRails::VERSION
17
21
  source_file.rewind
18
22
 
19
23
  # Updates vendor/assets/javascripts/flight/standalone.js
20
- open(File.expand_path('../vendor/assets/javascripts/flight/standalone.js', __FILE__), 'w') do |file|
24
+ open(project_root.join('vendor', 'assets', 'javascripts', 'flight', 'standalone.js'), 'w') do |file|
21
25
  file.write source_file.read
22
26
  end
23
27
 
24
28
  # Updates lib/flight-for-rails/version.rb
25
- open(File.expand_path('../lib/flight-for-rails/version.rb', __FILE__), 'w') do |file|
26
- file.write "# This file is generated automatically\nmodule FlightForRails; VERSION = '#{$1}'; end"
29
+ erb = ERB.new(open(project_root.join('templates', 'version.erb'), 'r').read)
30
+ open(project_root.join('lib', 'flight-for-rails', 'version.rb'), 'w') do |file|
31
+ file.write erb.result(binding)
32
+ end
33
+
34
+ # Updates installation version in README file
35
+ erb = ERB.new(open(project_root.join('templates', 'readme.erb'), 'r').read)
36
+ open(project_root.join('README.md'), 'w') do |file|
37
+ file.write erb.result(binding)
27
38
  end
28
39
 
29
40
  puts "Hooray! Flight.js has been updated to v#{$1}!"
@@ -1,2 +1,5 @@
1
- # This file is generated automatically
2
- module FlightForRails; VERSION = '1.1.4'; end
1
+ # This file is automatically generated.
2
+ # Change template/version.erb if you need.
3
+ module FlightForRails
4
+ VERSION = '1.2.0'
5
+ end
@@ -0,0 +1,80 @@
1
+ <!---
2
+ This file is automatically generated. Change template/readme.erb if you need.
3
+ -->
4
+
5
+ FlightForRails
6
+ ==============
7
+
8
+ FlightForRails is a plugin for Rails assets pipeline, which integrates your applicaiton with Twitter Flight javascript framework. Flight is a lightweight, component-based javascript framework that maps behavior to DOM nodes. Twitter uses it for their web applications. Why do not you try it? :)
9
+
10
+ For more information see [official Flight page](http://twitter.github.com/flight) and [changelog](https://github.com/flightjs/flight/blob/master/CHANGELOG.md).
11
+
12
+ ## Browser Support
13
+
14
+ Flight has been tested on all major browsers: Chrome, Firefox, Safari, Opera and IE7 and upwards.
15
+
16
+ ## Installation
17
+
18
+ This gem vendors Flight files and dependecies for Rails assets pipeline.
19
+
20
+ First add the following lines to your application `Gemfile`:
21
+
22
+ ``` ruby
23
+ gem 'flight-for-rails', '~> <%= version %>'
24
+ ```
25
+
26
+ Then run `bundle install` to update your's gems bundle.
27
+
28
+ Now you need to edit your manifest file (usualy `app/assets/javascripts/application.js`) and add the following lines:
29
+
30
+ ``` javascript
31
+ //= require jquery
32
+ //= require flight-for-rails
33
+ ```
34
+
35
+ Done!
36
+
37
+ ## Usage
38
+
39
+ 0. Define a component
40
+ 0. Attach a component instance to a DOM node
41
+
42
+ Simple example:
43
+
44
+ ``` coffeescript
45
+ # app/assets/javascript/components/my-component.js.coffee
46
+ $ ->
47
+ MyComponent = flight.component ->
48
+ @after 'initialize', ->
49
+ @on 'click', @triggerMyEvent
50
+
51
+ @triggerMyEvent = ->
52
+ @trigger document, 'myEvent', text: 'My event'
53
+
54
+ MyComponent.attachTo '#my-component'
55
+ ```
56
+
57
+ ``` coffeescript
58
+ # app/assets/javascript/components/my-component-2.js.coffee
59
+ $ ->
60
+ MyComponent2 = flight.component ->
61
+ @after 'initialize', ->
62
+ @on 'myEvent', @handleMyEvent
63
+
64
+ @handleMyEvent = (event, data) ->
65
+ console.log "#{data.text} event is triggered!"
66
+
67
+ MyComponent2.attachTo '#my-component2'
68
+ ```
69
+
70
+ And don't forget add the following line to your manifest file (usualy `app/assets/javascript/application.js`):
71
+
72
+ ```javascript
73
+ //= require_directory ./components
74
+ ```
75
+
76
+ Pretty awesome! Enjoy!
77
+
78
+ ## Copyright
79
+
80
+ See LICENSE file.
@@ -0,0 +1,5 @@
1
+ # This file is automatically generated.
2
+ # Change template/version.erb if you need.
3
+ module FlightForRails
4
+ VERSION = '<%= version %>'
5
+ end
@@ -1,4 +1,4 @@
1
- /*! Flight v1.1.4 | (c) Twitter, Inc. | MIT License */
1
+ /*! Flight v1.2.0 | (c) Twitter, Inc. | MIT License */
2
2
  (function(context) {
3
3
  var factories = {}, loaded = {};
4
4
  var isArray = Array.isArray || function(obj) {
@@ -58,169 +58,6 @@
58
58
  return loaded[id];
59
59
  }
60
60
 
61
- // ==========================================
62
- // Copyright 2013 Twitter, Inc
63
- // Licensed under The MIT License
64
- // http://opensource.org/licenses/MIT
65
- // ==========================================
66
- define('lib/utils', [], function () {
67
- 'use strict';
68
- var arry = [];
69
- var DEFAULT_INTERVAL = 100;
70
- var utils = {
71
- isDomObj: function (obj) {
72
- return !!(obj.nodeType || obj === window);
73
- },
74
- toArray: function (obj, from) {
75
- return arry.slice.call(obj, from);
76
- },
77
- merge: function () {
78
- // unpacking arguments by hand benchmarked faster
79
- var l = arguments.length, i = 0, args = new Array(l + 1);
80
- for (; i < l; i++)
81
- args[i + 1] = arguments[i];
82
- if (l === 0) {
83
- return {};
84
- }
85
- //start with empty object so a copy is created
86
- args[0] = {};
87
- if (args[args.length - 1] === true) {
88
- //jquery extend requires deep copy as first arg
89
- args.pop();
90
- args.unshift(true);
91
- }
92
- return $.extend.apply(undefined, args);
93
- },
94
- push: function (base, extra, protect) {
95
- if (base) {
96
- Object.keys(extra || {}).forEach(function (key) {
97
- if (base[key] && protect) {
98
- throw new Error('utils.push attempted to overwrite "' + key + '" while running in protected mode');
99
- }
100
- if (typeof base[key] == 'object' && typeof extra[key] == 'object') {
101
- // recurse
102
- this.push(base[key], extra[key]);
103
- } else {
104
- // no protect, so extra wins
105
- base[key] = extra[key];
106
- }
107
- }, this);
108
- }
109
- return base;
110
- },
111
- isEnumerable: function (obj, property) {
112
- return Object.keys(obj).indexOf(property) > -1;
113
- },
114
- compose: function () {
115
- var funcs = arguments;
116
- return function () {
117
- var args = arguments;
118
- for (var i = funcs.length - 1; i >= 0; i--) {
119
- args = [funcs[i].apply(this, args)];
120
- }
121
- return args[0];
122
- };
123
- },
124
- uniqueArray: function (array) {
125
- var u = {}, a = [];
126
- for (var i = 0, l = array.length; i < l; ++i) {
127
- if (u.hasOwnProperty(array[i])) {
128
- continue;
129
- }
130
- a.push(array[i]);
131
- u[array[i]] = 1;
132
- }
133
- return a;
134
- },
135
- debounce: function (func, wait, immediate) {
136
- if (typeof wait != 'number') {
137
- wait = DEFAULT_INTERVAL;
138
- }
139
- var timeout, result;
140
- return function () {
141
- var context = this, args = arguments;
142
- var later = function () {
143
- timeout = null;
144
- if (!immediate) {
145
- result = func.apply(context, args);
146
- }
147
- };
148
- var callNow = immediate && !timeout;
149
- clearTimeout(timeout);
150
- timeout = setTimeout(later, wait);
151
- if (callNow) {
152
- result = func.apply(context, args);
153
- }
154
- return result;
155
- };
156
- },
157
- throttle: function (func, wait) {
158
- if (typeof wait != 'number') {
159
- wait = DEFAULT_INTERVAL;
160
- }
161
- var context, args, timeout, throttling, more, result;
162
- var whenDone = this.debounce(function () {
163
- more = throttling = false;
164
- }, wait);
165
- return function () {
166
- context = this;
167
- args = arguments;
168
- var later = function () {
169
- timeout = null;
170
- if (more) {
171
- result = func.apply(context, args);
172
- }
173
- whenDone();
174
- };
175
- if (!timeout) {
176
- timeout = setTimeout(later, wait);
177
- }
178
- if (throttling) {
179
- more = true;
180
- } else {
181
- throttling = true;
182
- result = func.apply(context, args);
183
- }
184
- whenDone();
185
- return result;
186
- };
187
- },
188
- countThen: function (num, base) {
189
- return function () {
190
- if (!--num) {
191
- return base.apply(this, arguments);
192
- }
193
- };
194
- },
195
- delegate: function (rules) {
196
- return function (e, data) {
197
- var target = $(e.target), parent;
198
- Object.keys(rules).forEach(function (selector) {
199
- if (!e.isPropagationStopped() && (parent = target.closest(selector)).length) {
200
- data = data || {};
201
- data.el = parent[0];
202
- return rules[selector].apply(this, [
203
- e,
204
- data
205
- ]);
206
- }
207
- }, this);
208
- };
209
- },
210
- once: function (func) {
211
- var ran, result;
212
- return function () {
213
- if (ran) {
214
- return result;
215
- }
216
- ran = true;
217
- result = func.apply(this, arguments);
218
- return result;
219
- };
220
- }
221
- };
222
- return utils;
223
- });
224
61
  // ==========================================
225
62
  // Copyright 2013 Twitter, Inc
226
63
  // Licensed under The MIT License
@@ -397,70 +234,230 @@ define('lib/debug', [], function () {
397
234
  // Licensed under The MIT License
398
235
  // http://opensource.org/licenses/MIT
399
236
  // ==========================================
400
- define('lib/compose', [
401
- './utils',
402
- './debug'
403
- ], function (utils, debug) {
237
+ define('lib/utils', ['./debug'], function (debug) {
404
238
  'use strict';
405
- //enumerables are shims - getOwnPropertyDescriptor shim doesn't work
406
- var canWriteProtect = debug.enabled && !utils.isEnumerable(Object, 'getOwnPropertyDescriptor');
407
- //whitelist of unlockable property names
408
- var dontLock = ['mixedIn'];
409
- if (canWriteProtect) {
410
- //IE8 getOwnPropertyDescriptor is built-in but throws exeption on non DOM objects
411
- try {
412
- Object.getOwnPropertyDescriptor(Object, 'keys');
413
- } catch (e) {
414
- canWriteProtect = false;
239
+ var arry = [];
240
+ var DEFAULT_INTERVAL = 100;
241
+ function canWriteProtect() {
242
+ var writeProtectSupported = debug.enabled && !utils.isEnumerable(Object, 'getOwnPropertyDescriptor');
243
+ if (writeProtectSupported) {
244
+ //IE8 getOwnPropertyDescriptor is built-in but throws exeption on non DOM objects
245
+ try {
246
+ Object.getOwnPropertyDescriptor(Object, 'keys');
247
+ } catch (e) {
248
+ return false;
249
+ }
415
250
  }
251
+ return writeProtectSupported;
416
252
  }
417
- function setPropertyWritability(obj, isWritable) {
418
- if (!canWriteProtect) {
419
- return;
420
- }
253
+ var utils = {
254
+ isDomObj: function (obj) {
255
+ return !!(obj.nodeType || obj === window);
256
+ },
257
+ toArray: function (obj, from) {
258
+ return arry.slice.call(obj, from);
259
+ },
260
+ merge: function () {
261
+ // unpacking arguments by hand benchmarked faster
262
+ var l = arguments.length, args = new Array(l + 1);
263
+ if (l === 0) {
264
+ return {};
265
+ }
266
+ for (var i = 0; i < l; i++)
267
+ args[i + 1] = arguments[i];
268
+ //start with empty object so a copy is created
269
+ args[0] = {};
270
+ if (args[args.length - 1] === true) {
271
+ //jquery extend requires deep copy as first arg
272
+ args.pop();
273
+ args.unshift(true);
274
+ }
275
+ return $.extend.apply(undefined, args);
276
+ },
277
+ push: function (base, extra, protect) {
278
+ if (base) {
279
+ Object.keys(extra || {}).forEach(function (key) {
280
+ if (base[key] && protect) {
281
+ throw new Error('utils.push attempted to overwrite "' + key + '" while running in protected mode');
282
+ }
283
+ if (typeof base[key] == 'object' && typeof extra[key] == 'object') {
284
+ // recurse
285
+ this.push(base[key], extra[key]);
286
+ } else {
287
+ // no protect, so extra wins
288
+ base[key] = extra[key];
289
+ }
290
+ }, this);
291
+ }
292
+ return base;
293
+ },
294
+ isEnumerable: function (obj, property) {
295
+ return Object.keys(obj).indexOf(property) > -1;
296
+ },
297
+ compose: function () {
298
+ var funcs = arguments;
299
+ return function () {
300
+ var args = arguments;
301
+ for (var i = funcs.length - 1; i >= 0; i--) {
302
+ args = [funcs[i].apply(this, args)];
303
+ }
304
+ return args[0];
305
+ };
306
+ },
307
+ uniqueArray: function (array) {
308
+ var u = {}, a = [];
309
+ for (var i = 0, l = array.length; i < l; ++i) {
310
+ if (u.hasOwnProperty(array[i])) {
311
+ continue;
312
+ }
313
+ a.push(array[i]);
314
+ u[array[i]] = 1;
315
+ }
316
+ return a;
317
+ },
318
+ debounce: function (func, wait, immediate) {
319
+ if (typeof wait != 'number') {
320
+ wait = DEFAULT_INTERVAL;
321
+ }
322
+ var timeout, result;
323
+ return function () {
324
+ var context = this, args = arguments;
325
+ var later = function () {
326
+ timeout = null;
327
+ if (!immediate) {
328
+ result = func.apply(context, args);
329
+ }
330
+ };
331
+ var callNow = immediate && !timeout;
332
+ clearTimeout(timeout);
333
+ timeout = setTimeout(later, wait);
334
+ if (callNow) {
335
+ result = func.apply(context, args);
336
+ }
337
+ return result;
338
+ };
339
+ },
340
+ throttle: function (func, wait) {
341
+ if (typeof wait != 'number') {
342
+ wait = DEFAULT_INTERVAL;
343
+ }
344
+ var context, args, timeout, throttling, more, result;
345
+ var whenDone = this.debounce(function () {
346
+ more = throttling = false;
347
+ }, wait);
348
+ return function () {
349
+ context = this;
350
+ args = arguments;
351
+ var later = function () {
352
+ timeout = null;
353
+ if (more) {
354
+ result = func.apply(context, args);
355
+ }
356
+ whenDone();
357
+ };
358
+ if (!timeout) {
359
+ timeout = setTimeout(later, wait);
360
+ }
361
+ if (throttling) {
362
+ more = true;
363
+ } else {
364
+ throttling = true;
365
+ result = func.apply(context, args);
366
+ }
367
+ whenDone();
368
+ return result;
369
+ };
370
+ },
371
+ countThen: function (num, base) {
372
+ return function () {
373
+ if (!--num) {
374
+ return base.apply(this, arguments);
375
+ }
376
+ };
377
+ },
378
+ delegate: function (rules) {
379
+ return function (e, data) {
380
+ var target = $(e.target), parent;
381
+ Object.keys(rules).forEach(function (selector) {
382
+ if (!e.isPropagationStopped() && (parent = target.closest(selector)).length) {
383
+ data = data || {};
384
+ data.el = parent[0];
385
+ return rules[selector].apply(this, [
386
+ e,
387
+ data
388
+ ]);
389
+ }
390
+ }, this);
391
+ };
392
+ },
393
+ once: function (func) {
394
+ var ran, result;
395
+ return function () {
396
+ if (ran) {
397
+ return result;
398
+ }
399
+ ran = true;
400
+ result = func.apply(this, arguments);
401
+ return result;
402
+ };
403
+ },
404
+ propertyWritability: function (obj, prop, writable) {
405
+ if (canWriteProtect() && obj.hasOwnProperty(prop)) {
406
+ Object.defineProperty(obj, prop, { writable: writable });
407
+ }
408
+ },
409
+ mutateProperty: function (obj, prop, op) {
410
+ var writable;
411
+ if (!canWriteProtect() || !obj.hasOwnProperty(prop)) {
412
+ op.call(obj);
413
+ return;
414
+ }
415
+ writable = Object.getOwnPropertyDescriptor(obj, prop).writable;
416
+ Object.defineProperty(obj, prop, { writable: true });
417
+ op.call(obj);
418
+ Object.defineProperty(obj, prop, { writable: writable });
419
+ }
420
+ };
421
+ return utils;
422
+ });
423
+ // ==========================================
424
+ // Copyright 2013 Twitter, Inc
425
+ // Licensed under The MIT License
426
+ // http://opensource.org/licenses/MIT
427
+ // ==========================================
428
+ define('lib/compose', ['./utils'], function (utils) {
429
+ 'use strict';
430
+ var dontLock = ['mixedIn'];
431
+ function setWritability(obj, writable) {
421
432
  var props = Object.create(null);
422
433
  Object.keys(obj).forEach(function (key) {
423
434
  if (dontLock.indexOf(key) < 0) {
424
- var desc = Object.getOwnPropertyDescriptor(obj, key);
425
- desc.writable = isWritable;
426
- props[key] = desc;
435
+ utils.propertyWritability(obj, key, writable);
427
436
  }
428
437
  });
429
- Object.defineProperties(obj, props);
430
- }
431
- function unlockProperty(obj, prop, op) {
432
- var writable;
433
- if (!canWriteProtect || !obj.hasOwnProperty(prop)) {
434
- op.call(obj);
435
- return;
436
- }
437
- writable = Object.getOwnPropertyDescriptor(obj, prop).writable;
438
- Object.defineProperty(obj, prop, { writable: true });
439
- op.call(obj);
440
- Object.defineProperty(obj, prop, { writable: writable });
441
438
  }
442
439
  function mixin(base, mixins) {
443
440
  base.mixedIn = base.hasOwnProperty('mixedIn') ? base.mixedIn : [];
444
441
  for (var i = 0; i < mixins.length; i++) {
445
442
  if (base.mixedIn.indexOf(mixins[i]) == -1) {
446
- setPropertyWritability(base, false);
443
+ setWritability(base, false);
447
444
  mixins[i].call(base);
448
445
  base.mixedIn.push(mixins[i]);
449
446
  }
450
447
  }
451
- setPropertyWritability(base, true);
448
+ setWritability(base, true);
452
449
  }
453
- return {
454
- mixin: mixin,
455
- unlockProperty: unlockProperty
456
- };
450
+ return { mixin: mixin };
457
451
  });
458
452
  // ==========================================
459
453
  // Copyright 2013 Twitter, Inc
460
454
  // Licensed under The MIT License
461
455
  // http://opensource.org/licenses/MIT
462
456
  // ==========================================
463
- define('lib/advice', ['./compose'], function (compose) {
457
+ define('lib/advice', [
458
+ './compose',
459
+ './utils'
460
+ ], function (compose, utils) {
464
461
  'use strict';
465
462
  var advice = {
466
463
  around: function (base, wrapped) {
@@ -495,7 +492,7 @@ define('lib/advice', ['./compose'], function (compose) {
495
492
  'around'
496
493
  ].forEach(function (m) {
497
494
  this[m] = function (method, fn) {
498
- compose.unlockProperty(this, method, function () {
495
+ utils.mutateProperty(this, method, function () {
499
496
  if (typeof this[method] == 'function') {
500
497
  this[method] = advice[m](this[method], fn);
501
498
  } else {
@@ -722,6 +719,46 @@ define('lib/base', [
722
719
  ].join(' '));
723
720
  }
724
721
  }
722
+ function initAttributes(attrs) {
723
+ var definedKeys = [], incomingKeys;
724
+ this.attr = new this.attrDef();
725
+ if (debug.enabled && window.console) {
726
+ for (var key in this.attrDef.prototype)
727
+ definedKeys.push(key);
728
+ incomingKeys = Object.keys(attrs);
729
+ for (var i = incomingKeys.length - 1; i >= 0; i--) {
730
+ if (definedKeys.indexOf(incomingKeys[i]) == -1) {
731
+ console.warn('Passed unused attributes including "' + incomingKeys[i] + '" to component "' + this.toString() + '".');
732
+ break;
733
+ }
734
+ }
735
+ }
736
+ for (var key in this.attrDef.prototype) {
737
+ if (typeof attrs[key] == 'undefined') {
738
+ if (this.attr[key] == null) {
739
+ throw new Error('Required attribute "' + key + '" not specified in attachTo for component "' + this.toString() + '".');
740
+ }
741
+ } else {
742
+ this.attr[key] = attrs[key];
743
+ }
744
+ }
745
+ }
746
+ function initDeprecatedAttributes(attrs) {
747
+ // merge defaults with supplied options
748
+ // put options in attr.__proto__ to avoid merge overhead
749
+ var attr = Object.create(attrs);
750
+ for (var key in this.defaults) {
751
+ if (!attrs.hasOwnProperty(key)) {
752
+ attr[key] = this.defaults[key];
753
+ }
754
+ }
755
+ this.attr = attr;
756
+ Object.keys(this.defaults || {}).forEach(function (key) {
757
+ if (this.defaults[key] === null && this.attr[key] === null) {
758
+ throw new Error('Required attribute "' + key + '" not specified in attachTo for component "' + this.toString() + '".');
759
+ }
760
+ }, this);
761
+ }
725
762
  function proxyEventTo(targetEvent) {
726
763
  return function (e, data) {
727
764
  $(e.target).trigger(targetEvent, data);
@@ -833,15 +870,27 @@ define('lib/base', [
833
870
  }, this);
834
871
  return rules;
835
872
  };
836
- this.defaultAttrs = function (defaults) {
837
- utils.push(this.defaults, defaults, true) || (this.defaults = defaults);
838
- };
839
873
  this.select = function (attributeKey) {
840
874
  return this.$node.find(this.attr[attributeKey]);
841
875
  };
876
+ // New-style attributes
877
+ this.attributes = function (attrs) {
878
+ var Attributes = function () {
879
+ };
880
+ if (this.attrDef) {
881
+ Attributes.prototype = new this.attrDef();
882
+ }
883
+ for (var name in attrs) {
884
+ Attributes.prototype[name] = attrs[name];
885
+ }
886
+ this.attrDef = Attributes;
887
+ };
888
+ // Deprecated attributes
889
+ this.defaultAttrs = function (defaults) {
890
+ utils.push(this.defaults, defaults, true) || (this.defaults = defaults);
891
+ };
842
892
  this.initialize = function (node, attrs) {
843
- attrs || (attrs = {});
844
- //only assign identity if there isn't one (initialize can be called multiple times)
893
+ attrs = attrs || {};
845
894
  this.identity || (this.identity = componentId++);
846
895
  if (!node) {
847
896
  throw new Error('Component needs a node');
@@ -853,20 +902,11 @@ define('lib/base', [
853
902
  this.node = node;
854
903
  this.$node = $(node);
855
904
  }
856
- // merge defaults with supplied options
857
- // put options in attr.__proto__ to avoid merge overhead
858
- var attr = Object.create(attrs);
859
- for (var key in this.defaults) {
860
- if (!attrs.hasOwnProperty(key)) {
861
- attr[key] = this.defaults[key];
862
- }
905
+ if (this.attrDef) {
906
+ initAttributes.call(this, attrs);
907
+ } else {
908
+ initDeprecatedAttributes.call(this, attrs);
863
909
  }
864
- this.attr = attr;
865
- Object.keys(this.defaults || {}).forEach(function (key) {
866
- if (this.defaults[key] === null && this.attr[key] === null) {
867
- throw new Error('Required attribute "' + key + '" not specified in attachTo for component "' + this.toString() + '".');
868
- }
869
- }, this);
870
910
  return this;
871
911
  };
872
912
  this.teardown = function () {
@@ -1062,6 +1102,8 @@ define('lib/component', [
1062
1102
  //TODO: fix pretty print
1063
1103
  var newPrototype = Object.create(Component.prototype);
1064
1104
  newPrototype.mixedIn = [].concat(Component.prototype.mixedIn);
1105
+ newPrototype.defaults = utils.merge(Component.prototype.defaults);
1106
+ newPrototype.attrDef = Component.prototype.attrDef;
1065
1107
  compose.mixin(newPrototype, arguments);
1066
1108
  newComponent.prototype = newPrototype;
1067
1109
  newComponent.prototype.constructor = newComponent;
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flight-for-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.4
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sergey Rezvanov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-19 00:00:00.000000000 Z
11
+ date: 2014-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -53,6 +53,8 @@ files:
53
53
  - lib/flight-for-rails.rb
54
54
  - lib/flight-for-rails/engine.rb
55
55
  - lib/flight-for-rails/version.rb
56
+ - templates/readme.erb
57
+ - templates/version.erb
56
58
  - vendor/assets/javascripts/es5-shim/es5-sham.js
57
59
  - vendor/assets/javascripts/es5-shim/es5-shim.js
58
60
  - vendor/assets/javascripts/flight-for-rails.js