-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
172 lines (141 loc) · 4.78 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
var components = {};
var initialized = false;
function getOptions(el, model, rootModel, view){
var opts = {
el: el,
getOptions: function(newEl){
return getOptions(newEl, model, rootModel, view);
}
};
var data = model ? model.toJSON() : {};
var rootData = rootModel ? rootModel.toJSON() : {};
//include template helpers from marionette views
if(view && typeof view.mixinTemplateHelpers === 'function'){
view.mixinTemplateHelpers(data);
view.mixinTemplateHelpers(rootData);
}
for(var i = 0; i < el.attributes.length; i++) {
var attrib = el.attributes[i];
if(attrib.value.indexOf('$$') === 0)
opts[attrib.name] = getValue(rootData, attrib.value.substr(1,attrib.value.length - 1), el, view);
else if(attrib.value.indexOf('$') === 0)
opts[attrib.name] = getValue(data, attrib.value, el, view);
else opts[attrib.name] = attrib.value;
}
return opts;
}
module.exports = {
components: components,
register: function (name, Component) {
if(name.indexOf('-component') > 0) throw new Error('-component is already appended to the end of the name you pass in.');
name = name + '-component';
if(components[name]) {
console.warn('Skipping `' + name + '` It is already registered.');
}
components[name] = Component;
//console.info('`' + name + '` registered');
},
init: function (Backbone) {
if(Backbone.__componentsInit) {
console.warn('You are trying to initialize backbone-components again.');
return;
}
initialized = true;
console.info('Initializing with Backbone instance:', Backbone);
Backbone.originalViewRef = Backbone.View;
Backbone.View = Backbone.View.extend({
constructor: function () {
// console.debug('Applying custom component logic to View', this);
Backbone.originalViewRef.apply(this, arguments);
this.on('render', function () {
var model = this.model;
var _this = this;
this.$el.find('*').each(function(index, el) {
// skip if already initialized by lower component
if(el.attributes.getNamedItem('__owner-view') && el.attributes.getNamedItem('__owner-view').value) {
return;
}
if(!_this.components) _this.components = {};
var componentClass = components[el.tagName.toLowerCase()] || _this.components[el.tagName.toLowerCase()];
if(componentClass) {
var rootModel = _this.rootModel;
if(!rootModel){
rootModel = model;
}
var rootView = _this.rootView;
if(!rootView){
rootView = _this;
}
var opts = getOptions(el, model, rootModel,_this, opts);
//extend the component with anything on par
var originalComponentClass = componentClass;
componentClass = componentClass.extend(
{rootModel: rootModel,
rootView: rootView,
parentView: _this,
parentModel: model,
initialize: function(opts){
//override intitialize so we can call parse component
if(this.parseComponent){
this.parseComponent(opts.el, opts);
}
//call the original inititalize prototype
if(originalComponentClass.prototype){
return originalComponentClass.prototype.initialize.call(this, opts);
}
}
});
//console.info('Creating component:', el.tagName.toLowerCase(), 'with opts', opts, 'for view:', _this.cid);
var comp = new componentClass(opts);
if(comp.parseOptions){
comp.parseComponent();
}
if(!_this.views){
_this.views = [];
}
_this.views.push(comp);
try {
el.setAttribute('__owner-view', _this.cid);
if(comp.render) comp.render();
} catch(err) {
console.error('Error rendering', el, err, err.stack);
}
if(comp.triggerMethod) comp.triggerMethod('show');
} else {
if(el.tagName.toLowerCase().indexOf('-component') > 0) console.warn('No component registered for', el.tagName.toLowerCase());
}
});
});
this.on('attach', function () {
if(this.views){
for(var i in this.views){
var comp = this.views[i];
if(comp.triggerMethod) comp.triggerMethod('attach');
}
}
});
}
});
}
};
function getValue(data, expr, el, view) {
data._parent = view;
data._model = view.model;
data._collection = view.collection;
var parsedExpr = expr.substring(2, expr.length - 1);
var keys = Object.keys(data).filter(function(key){ return key.indexOf("-") < 0;});
var fnExpr = [
'(function (',
keys.join(','),
'){ return ' + parsedExpr + '; })',
'(' +keys.map(function (p) { return 'data["' + p + '"]'; }).join(',') + ')'
].join('');
var result = undefined;
try {
result = eval(fnExpr);
} catch(err) {
console.error('Error evaluating:', expr, 'for el:', el, 'inside view:', view.cid, view.name);
console.error(err);
}
return result;
}