Unreviewed, rolling out r216677.
[WebKit-https.git] / PerformanceTests / Speedometer / resources / todomvc / dependency-examples / flight / bower_components / flight / lib / component.js
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     './advice',
11     './utils',
12     './compose',
13     './base',
14     './registry',
15     './logger',
16     './debug'
17   ],
18
19   function(advice, utils, compose, withBase, registry, withLogging, debug) {
20     'use strict';
21
22     var functionNameRegEx = /function (.*?)\s?\(/;
23
24     // teardown for all instances of this constructor
25     function teardownAll() {
26       var componentInfo = registry.findComponentInfo(this);
27
28       componentInfo && Object.keys(componentInfo.instances).forEach(function(k) {
29         var info = componentInfo.instances[k];
30         info.instance.teardown();
31       });
32     }
33
34     function checkSerializable(type, data) {
35       try {
36         window.postMessage(data, '*');
37       } catch(e) {
38         console.log('unserializable data for event',type,':',data);
39         throw new Error(
40           ['The event', type, 'on component', this.toString(), 'was triggered with non-serializable data'].join(' ')
41         );
42       }
43     }
44
45     function attachTo(selector/*, options args */) {
46       // unpacking arguments by hand benchmarked faster
47       var l = arguments.length;
48       var args = new Array(l - 1);
49       for (var i = 1; i < l; i++) args[i - 1] = arguments[i];
50
51       if (!selector) {
52         throw new Error('Component needs to be attachTo\'d a jQuery object, native node or selector string');
53       }
54
55       var options = utils.merge.apply(utils, args);
56       var componentInfo = registry.findComponentInfo(this);
57
58       $(selector).each(function(i, node) {
59         if (componentInfo && componentInfo.isAttachedTo(node)) {
60           // already attached
61           return;
62         }
63
64         (new this).initialize(node, options);
65       }.bind(this));
66     }
67
68     // define the constructor for a custom component type
69     // takes an unlimited number of mixin functions as arguments
70     // typical api call with 3 mixins: define(timeline, withTweetCapability, withScrollCapability);
71     function define(/*mixins*/) {
72       // unpacking arguments by hand benchmarked faster
73       var l = arguments.length;
74       // add three for common mixins
75       var mixins = new Array(l + 3);
76       for (var i = 0; i < l; i++) mixins[i] = arguments[i];
77
78       var Component = function() {};
79
80       Component.toString = Component.prototype.toString = function() {
81         var prettyPrintMixins = mixins.map(function(mixin) {
82           if (mixin.name == null) {
83             // function name property not supported by this browser, use regex
84             var m = mixin.toString().match(functionNameRegEx);
85             return (m && m[1]) ? m[1] : '';
86           } else {
87             return (mixin.name != 'withBase') ? mixin.name : '';
88           }
89         }).filter(Boolean).join(', ');
90         return prettyPrintMixins;
91       };
92
93       if (debug.enabled) {
94         Component.describe = Component.prototype.describe = Component.toString();
95       }
96
97       // 'options' is optional hash to be merged with 'defaults' in the component definition
98       Component.attachTo = attachTo;
99       Component.teardownAll = teardownAll;
100
101       // prepend common mixins to supplied list, then mixin all flavors
102       if (debug.enabled) {
103         mixins.unshift(withLogging);
104       }
105       mixins.unshift(withBase, advice.withAdvice, registry.withRegistration);
106       compose.mixin(Component.prototype, mixins);
107
108       return Component;
109     }
110
111     define.teardownAll = function() {
112       registry.components.slice().forEach(function(c) {
113         c.component.teardownAll();
114       });
115       registry.reset();
116     };
117
118     return define;
119   }
120 );