Skip to content

Commit f95a9d6

Browse files
committed
upgrade to flight version 1.1.2
1 parent 0a75970 commit f95a9d6

File tree

10 files changed

+423
-356
lines changed

10 files changed

+423
-356
lines changed

components/flight/lib/advice.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,14 @@
44
// http://opensource.org/licenses/MIT
55
// ==========================================
66

7-
"use strict";
8-
97
define(
108

119
[
12-
'./utils',
1310
'./compose'
1411
],
1512

16-
function (util, compose) {
13+
function(compose) {
14+
'use strict';
1715

1816
var advice = {
1917

@@ -25,15 +23,15 @@ define(
2523
for (; i < l; i++) args[i + 1] = arguments[i];
2624

2725
return wrapped.apply(this, args);
28-
}
26+
};
2927
},
3028

3129
before: function(base, before) {
3230
var beforeFn = (typeof before == 'function') ? before : before.obj[before.fnName];
3331
return function composedBefore() {
3432
beforeFn.apply(this, arguments);
3533
return base.apply(this, arguments);
36-
}
34+
};
3735
},
3836

3937
after: function(base, after) {
@@ -42,7 +40,7 @@ define(
4240
var res = (base.unbound || base).apply(this, arguments);
4341
afterFn.apply(this, arguments);
4442
return res;
45-
}
43+
};
4644
},
4745

4846
// a mixin that allows other mixins to augment existing functions by adding additional
@@ -53,10 +51,12 @@ define(
5351

5452
compose.unlockProperty(this, method, function() {
5553
if (typeof this[method] == 'function') {
56-
return this[method] = advice[m](this[method], fn);
54+
this[method] = advice[m](this[method], fn);
5755
} else {
58-
return this[method] = fn;
56+
this[method] = fn;
5957
}
58+
59+
return this[method];
6060
});
6161

6262
};

components/flight/lib/base.js

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
// ==========================================
2+
// Copyright 2013 Twitter, Inc
3+
// Licensed under The MIT License
4+
// http://opensource.org/licenses/MIT
5+
// ==========================================
6+
7+
define(
8+
9+
[
10+
'./utils',
11+
'./registry',
12+
'./debug'
13+
],
14+
15+
function(utils, registry, debug) {
16+
'use strict';
17+
18+
// common mixin allocates basic functionality - used by all component prototypes
19+
// callback context is bound to component
20+
var componentId = 0;
21+
22+
function teardownInstance(instanceInfo){
23+
instanceInfo.events.slice().forEach(function(event) {
24+
var args = [event.type];
25+
26+
event.element && args.unshift(event.element);
27+
(typeof event.callback == 'function') && args.push(event.callback);
28+
29+
this.off.apply(this, args);
30+
}, instanceInfo.instance);
31+
}
32+
33+
function checkSerializable(type, data) {
34+
try {
35+
window.postMessage(data, '*');
36+
} catch(e) {
37+
console.log('unserializable data for event',type,':',data);
38+
throw new Error(
39+
['The event', type, 'on component', this.toString(), 'was triggered with non-serializable data'].join(' ')
40+
);
41+
}
42+
}
43+
44+
function withBase() {
45+
46+
// delegate trigger, bind and unbind to an element
47+
// if $element not supplied, use component's node
48+
// other arguments are passed on
49+
// event can be either a string specifying the type
50+
// of the event, or a hash specifying both the type
51+
// and a default function to be called.
52+
this.trigger = function() {
53+
var $element, type, data, event, defaultFn;
54+
var lastIndex = arguments.length - 1, lastArg = arguments[lastIndex];
55+
56+
if (typeof lastArg != 'string' && !(lastArg && lastArg.defaultBehavior)) {
57+
lastIndex--;
58+
data = lastArg;
59+
}
60+
61+
if (lastIndex == 1) {
62+
$element = $(arguments[0]);
63+
event = arguments[1];
64+
} else {
65+
$element = this.$node;
66+
event = arguments[0];
67+
}
68+
69+
if (event.defaultBehavior) {
70+
defaultFn = event.defaultBehavior;
71+
event = $.Event(event.type);
72+
}
73+
74+
type = event.type || event;
75+
76+
if (debug.enabled && window.postMessage) {
77+
checkSerializable.call(this, type, data);
78+
}
79+
80+
if (typeof this.attr.eventData === 'object') {
81+
data = $.extend(true, {}, this.attr.eventData, data);
82+
}
83+
84+
$element.trigger((event || type), data);
85+
86+
if (defaultFn && !event.isDefaultPrevented()) {
87+
(this[defaultFn] || defaultFn).call(this);
88+
}
89+
90+
return $element;
91+
};
92+
93+
this.on = function() {
94+
var $element, type, callback, originalCb;
95+
var lastIndex = arguments.length - 1, origin = arguments[lastIndex];
96+
97+
if (typeof origin == 'object') {
98+
//delegate callback
99+
originalCb = utils.delegate(
100+
this.resolveDelegateRules(origin)
101+
);
102+
} else {
103+
originalCb = origin;
104+
}
105+
106+
if (lastIndex == 2) {
107+
$element = $(arguments[0]);
108+
type = arguments[1];
109+
} else {
110+
$element = this.$node;
111+
type = arguments[0];
112+
}
113+
114+
if (typeof originalCb != 'function' && typeof originalCb != 'object') {
115+
throw new Error('Unable to bind to "' + type + '" because the given callback is not a function or an object');
116+
}
117+
118+
callback = originalCb.bind(this);
119+
callback.target = originalCb;
120+
callback.context = this;
121+
122+
$element.on(type, callback);
123+
124+
// store every bound version of the callback
125+
originalCb.bound || (originalCb.bound = []);
126+
originalCb.bound.push(callback);
127+
128+
return callback;
129+
};
130+
131+
this.off = function() {
132+
var $element, type, callback;
133+
var lastIndex = arguments.length - 1;
134+
135+
if (typeof arguments[lastIndex] == 'function') {
136+
callback = arguments[lastIndex];
137+
lastIndex -= 1;
138+
}
139+
140+
if (lastIndex == 1) {
141+
$element = $(arguments[0]);
142+
type = arguments[1];
143+
} else {
144+
$element = this.$node;
145+
type = arguments[0];
146+
}
147+
148+
if (callback) {
149+
//set callback to version bound against this instance
150+
callback.bound && callback.bound.some(function(fn, i, arr) {
151+
if (fn.context && (this.identity == fn.context.identity)) {
152+
arr.splice(i, 1);
153+
callback = fn;
154+
return true;
155+
}
156+
}, this);
157+
}
158+
159+
return $element.off(type, callback);
160+
};
161+
162+
this.resolveDelegateRules = function(ruleInfo) {
163+
var rules = {};
164+
165+
Object.keys(ruleInfo).forEach(function(r) {
166+
if (!(r in this.attr)) {
167+
throw new Error('Component "' + this.toString() + '" wants to listen on "' + r + '" but no such attribute was defined.');
168+
}
169+
rules[this.attr[r]] = ruleInfo[r];
170+
}, this);
171+
172+
return rules;
173+
};
174+
175+
this.defaultAttrs = function(defaults) {
176+
utils.push(this.defaults, defaults, true) || (this.defaults = defaults);
177+
};
178+
179+
this.select = function(attributeKey) {
180+
return this.$node.find(this.attr[attributeKey]);
181+
};
182+
183+
this.initialize = function(node, attrs) {
184+
attrs || (attrs = {});
185+
//only assign identity if there isn't one (initialize can be called multiple times)
186+
this.identity || (this.identity = componentId++);
187+
188+
if (!node) {
189+
throw new Error('Component needs a node');
190+
}
191+
192+
if (node.jquery) {
193+
this.node = node[0];
194+
this.$node = node;
195+
} else {
196+
this.node = node;
197+
this.$node = $(node);
198+
}
199+
200+
// merge defaults with supplied options
201+
// put options in attr.__proto__ to avoid merge overhead
202+
var attr = Object.create(attrs);
203+
for (var key in this.defaults) {
204+
if (!attrs.hasOwnProperty(key)) {
205+
attr[key] = this.defaults[key];
206+
}
207+
}
208+
209+
this.attr = attr;
210+
211+
Object.keys(this.defaults || {}).forEach(function(key) {
212+
if (this.defaults[key] === null && this.attr[key] === null) {
213+
throw new Error('Required attribute "' + key + '" not specified in attachTo for component "' + this.toString() + '".');
214+
}
215+
}, this);
216+
217+
return this;
218+
};
219+
220+
this.teardown = function() {
221+
teardownInstance(registry.findInstanceInfo(this));
222+
};
223+
}
224+
225+
return withBase;
226+
}
227+
);

0 commit comments

Comments
 (0)