flight-for-rails 1.1.4 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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