stormfront-rails 0.2.3 → 0.10.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/stormfront/rails/version.rb +1 -1
- data/vendor/assets/javascripts/src/stormfront.js +1198 -520
- metadata +2 -2
@@ -1,5 +1,5 @@
|
|
1
1
|
var stormfront = { };
|
2
|
-
var Stormfront = {
|
2
|
+
var Stormfront = { };
|
3
3
|
|
4
4
|
Stormfront.VERSION = '1.0.0';
|
5
5
|
|
@@ -8,36 +8,49 @@ Stormfront.Class = function(options) {
|
|
8
8
|
this.initialize.apply(this, arguments);
|
9
9
|
};
|
10
10
|
|
11
|
-
Stormfront.Class.extend = function(protoProps
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
child
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
11
|
+
Stormfront.Class.extend = function(protoProps) {
|
12
|
+
function copyConstructor(base){
|
13
|
+
return function(){ return base.apply(this, arguments); };
|
14
|
+
}
|
15
|
+
function copyBaseProperties(child, parent){
|
16
|
+
_.extend(child, parent);
|
17
|
+
}
|
18
|
+
function carryPrototypeChain(child, parent){
|
19
|
+
var Surrogate = function(){ this.constructor = child; };
|
20
|
+
Surrogate.prototype = parent.prototype;
|
21
|
+
child.prototype = new Surrogate;
|
22
|
+
}
|
23
|
+
function copyNewProperties(protoProps){
|
24
|
+
_.extend(child.prototype, protoProps);
|
25
|
+
}
|
26
|
+
function enableAccessToBaseClass(){
|
27
|
+
child.__super__ = parent.prototype;
|
28
|
+
}
|
28
29
|
|
30
|
+
var parent = this;
|
31
|
+
var child = copyConstructor(parent);
|
32
|
+
copyBaseProperties(child, parent);
|
33
|
+
carryPrototypeChain(child, parent);
|
34
|
+
copyNewProperties(protoProps);
|
35
|
+
enableAccessToBaseClass(child, parent);
|
29
36
|
return child;
|
30
37
|
};
|
31
38
|
|
32
|
-
|
33
39
|
stormfront.arguments = function(args){
|
34
40
|
return new Stormfront.Arguments(args);
|
35
41
|
};
|
36
42
|
|
37
43
|
Stormfront.Arguments = Stormfront.Class.extend({
|
38
44
|
initialize: function(array){
|
45
|
+
function copy(array) {
|
46
|
+
var copy = new Array(array.length);
|
47
|
+
for(var i = 0; i < array.length; ++i) {
|
48
|
+
copy[i] = array[i];
|
49
|
+
}
|
50
|
+
return copy;
|
51
|
+
}
|
39
52
|
if (array)
|
40
|
-
this.array =
|
53
|
+
this.array = copy(array);
|
41
54
|
else
|
42
55
|
this.array = [];
|
43
56
|
},
|
@@ -57,11 +70,14 @@ Stormfront.Arguments = Stormfront.Class.extend({
|
|
57
70
|
return this.array;
|
58
71
|
}
|
59
72
|
});
|
60
|
-
|
61
73
|
stormfront.hash = function(hash){
|
62
74
|
return new Stormfront.Hash(hash);
|
63
75
|
};
|
64
76
|
|
77
|
+
Stormfront.Unchanged = {
|
78
|
+
unchanged: 'true'
|
79
|
+
};
|
80
|
+
|
65
81
|
Stormfront.Hash = Stormfront.Class.extend({
|
66
82
|
initialize: function(hash){
|
67
83
|
this.hash = hash;
|
@@ -79,9 +95,68 @@ Stormfront.Hash = Stormfront.Class.extend({
|
|
79
95
|
},
|
80
96
|
subtract: function(values){
|
81
97
|
return _.omit(this.hash, _.keys(values));
|
98
|
+
},
|
99
|
+
diff: function(newProperties){
|
100
|
+
function getProperties(oldProperties, newProperties){
|
101
|
+
var candidates = _.keys(newProperties).concat(_.keys(oldProperties));
|
102
|
+
var position = candidates.length;
|
103
|
+
var keys = [];
|
104
|
+
|
105
|
+
while (position--) {
|
106
|
+
var candidate = candidates[position];
|
107
|
+
if (keys.indexOf(candidate) === -1)
|
108
|
+
keys.unshift(candidate);
|
109
|
+
}
|
110
|
+
return keys;
|
111
|
+
}
|
112
|
+
function evaluateArray(previous, current) {
|
113
|
+
if (current.length !== previous.length)
|
114
|
+
return current;
|
115
|
+
|
116
|
+
var difference = _.any(previous, function(value, index){
|
117
|
+
return evaluateObject(value, current[index]);
|
118
|
+
});
|
119
|
+
return difference ? current : Stormfront.Unchanged;
|
120
|
+
}
|
121
|
+
|
122
|
+
function evaluateValue(previous, current){
|
123
|
+
if (_.isArray(current))
|
124
|
+
return evaluateArray(previous, current);
|
125
|
+
else if (_.isObject(current))
|
126
|
+
return evaluateObject(previous, current);
|
127
|
+
else if (previous !== current)
|
128
|
+
return current;
|
129
|
+
return Stormfront.Unchanged;
|
130
|
+
}
|
131
|
+
|
132
|
+
function evaluateObject(oldProperties, newProperties) {
|
133
|
+
var changes = { };
|
134
|
+
function addEntry(property, value) {
|
135
|
+
if (value)
|
136
|
+
changes[property] = value;
|
137
|
+
}
|
138
|
+
|
139
|
+
var properties = getProperties(oldProperties, newProperties);
|
140
|
+
_.each(properties, function(property){
|
141
|
+
var previous = oldProperties[property];
|
142
|
+
var current = newProperties[property];
|
143
|
+
if (previous && current)
|
144
|
+
addEntry(property, evaluateValue(previous, current));
|
145
|
+
else if (previous)
|
146
|
+
addEntry(property, previous);
|
147
|
+
else
|
148
|
+
addEntry(property, current);
|
149
|
+
});
|
150
|
+
return _.isEmpty(changes) ? Stormfront.Unchanged : changes;
|
151
|
+
}
|
152
|
+
if (!this.hash)
|
153
|
+
return newProperties;
|
154
|
+
if (!newProperties)
|
155
|
+
return this.hash;
|
156
|
+
|
157
|
+
return evaluateObject(this.hash, newProperties);
|
82
158
|
}
|
83
159
|
});
|
84
|
-
|
85
160
|
stormfront.number = function(number){
|
86
161
|
return new Stormfront.Number(number);
|
87
162
|
};
|
@@ -97,7 +172,6 @@ Stormfront.Number = Stormfront.Class.extend({
|
|
97
172
|
return this.number < value ? -1 : this.number > value ? 1 : 0;
|
98
173
|
}
|
99
174
|
});
|
100
|
-
|
101
175
|
Stormfront.Response = Stormfront.Class.extend({
|
102
176
|
initialize: function(xhr){
|
103
177
|
this.xhr = xhr;
|
@@ -129,7 +203,6 @@ Stormfront.Response = Stormfront.Class.extend({
|
|
129
203
|
}
|
130
204
|
}
|
131
205
|
});
|
132
|
-
|
133
206
|
stormfront.string = function(text){
|
134
207
|
return new Stormfront.String(text);
|
135
208
|
};
|
@@ -138,23 +211,6 @@ Stormfront.String = Stormfront.Class.extend({
|
|
138
211
|
initialize: function(text){
|
139
212
|
this.text = text;
|
140
213
|
},
|
141
|
-
title: function(){
|
142
|
-
var sentence = _.str.capitalize(_.str.camelize(this.text)).split(/(?=[A-Z\d])/);
|
143
|
-
var displaySentence = "";
|
144
|
-
function processCharacter(character, i){
|
145
|
-
function whenPreviousWordIsNotAnAcronym() {
|
146
|
-
return i > 0 && sentence[i - 1].length > 1;
|
147
|
-
}
|
148
|
-
function whenPreviousWordISAnAcronymAndCurrentWordIsNotAnAcronym() {
|
149
|
-
return i > 0 && sentence[i - 1].length == 1 && sentence[i].length > 1;
|
150
|
-
}
|
151
|
-
if (whenPreviousWordIsNotAnAcronym() || whenPreviousWordISAnAcronymAndCurrentWordIsNotAnAcronym())
|
152
|
-
displaySentence += " ";
|
153
|
-
displaySentence += character;
|
154
|
-
}
|
155
|
-
_.each(sentence, processCharacter);
|
156
|
-
return displaySentence;
|
157
|
-
},
|
158
214
|
decimal: function(places, placeholder){
|
159
215
|
placeholder = placeholder || '';
|
160
216
|
places = places || 3;
|
@@ -164,17 +220,22 @@ Stormfront.String = Stormfront.Class.extend({
|
|
164
220
|
scientific: function(){
|
165
221
|
return this.text === null || $.trim(this.text) === '' ? '' : parseFloat(this.text).toExponential(3);
|
166
222
|
},
|
167
|
-
decimal_format: function(){
|
168
|
-
return this.decimal(this.text);
|
169
|
-
},
|
170
|
-
scientific_notation: function(){
|
171
|
-
return this.scientific(this.text);
|
172
|
-
},
|
173
223
|
firstWord: function(){
|
174
224
|
return this.text ? this.text.split(' ')[0] : '';
|
225
|
+
},
|
226
|
+
title: function(){
|
227
|
+
return this.camelCase(' ', ' ');
|
228
|
+
},
|
229
|
+
camelCase: function(delimiter, alimiter){
|
230
|
+
delimiter = delimiter || ' ';
|
231
|
+
alimiter = alimiter || '';
|
232
|
+
function capitalize(word){
|
233
|
+
return word.charAt(0).toUpperCase() + word.substr(1).toLowerCase();
|
234
|
+
}
|
235
|
+
var words = this.text.split(delimiter);
|
236
|
+
return _.map(words, capitalize).join(alimiter)
|
175
237
|
}
|
176
238
|
});
|
177
|
-
|
178
239
|
stormfront.time = function(datetime){
|
179
240
|
return new Stormfront.Time(datetime);
|
180
241
|
};
|
@@ -205,201 +266,456 @@ Stormfront.Time = Stormfront.Class.extend({
|
|
205
266
|
|
206
267
|
|
207
268
|
|
269
|
+
stormfront.type = function(name){
|
270
|
+
return (new Stormfront.Type(name)).get();
|
271
|
+
};
|
272
|
+
Stormfront.Type = Stormfront.Class.extend({
|
273
|
+
initialize: function (name) {
|
274
|
+
this.name = name;
|
275
|
+
},
|
276
|
+
get: function () {
|
277
|
+
var name = this.name.split('.');
|
278
|
+
return stormfront.hash(window).findNestedValue(name);
|
279
|
+
}
|
280
|
+
});
|
208
281
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
this.wrap('remove', 'removed', Stormfront.Errors.CLOSING);
|
219
|
-
},
|
220
|
-
|
221
|
-
create: function(childClass, options, context){
|
222
|
-
return new window[childClass](options.call(context));
|
223
|
-
},
|
224
|
-
find: function(identity){
|
225
|
-
return this.children[identity];
|
226
|
-
},
|
227
|
-
add: function(child){
|
228
|
-
var identity = child.getIdentity();
|
229
|
-
this.remove(this.find(identity));
|
230
|
-
this.children[identity] = child;
|
231
|
-
return child;
|
232
|
-
},
|
233
|
-
remove: function(child){
|
234
|
-
if (child)
|
235
|
-
this.children = _.omit(this.children, child.getIdentity());
|
236
|
-
return child;
|
237
|
-
},
|
238
|
-
render: function(child){
|
239
|
-
return child.render();
|
240
|
-
},
|
241
|
-
attach: function(child, location, method){
|
242
|
-
if (location.size() === 0)
|
243
|
-
throw Stormfront.Errors.NO_LOCATION(child);
|
244
|
-
else if (location.size() > 1)
|
245
|
-
throw Stormfront.Errors.MULTIPLE_LOCATIONS(child);
|
246
|
-
|
247
|
-
location[method](child.$el);
|
248
|
-
return child;
|
249
|
-
},
|
250
|
-
|
251
|
-
wrap: function(field, event, error){
|
252
|
-
var implementation = this[field];
|
253
|
-
this[field] = function(){
|
254
|
-
try {
|
255
|
-
var result = implementation.apply(this, arguments);
|
256
|
-
result && this.trigger(event, result);
|
257
|
-
} catch (e) {
|
258
|
-
this.trigger('error', error(arguments[0].toString()), e);
|
259
|
-
}
|
282
|
+
Stormfront.Patterns = {
|
283
|
+
Dispatcher: function (subject, dispatcher) {
|
284
|
+
if (dispatcher) {
|
285
|
+
subject.dispatch = function (event) {
|
286
|
+
dispatcher.dispatch(event);
|
287
|
+
};
|
288
|
+
subject.getDispatcher = function(){
|
289
|
+
return dispatcher;
|
290
|
+
};
|
260
291
|
}
|
261
292
|
},
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
293
|
+
Events: function (subject) {
|
294
|
+
if (!subject.listenTo)
|
295
|
+
$.extend(subject, Backbone.Events);
|
296
|
+
$.extend(subject, {
|
297
|
+
forward: function (other, type) {
|
298
|
+
function propagate(){
|
299
|
+
subject.trigger.apply(subject, arguments);
|
300
|
+
}
|
301
|
+
subject.listenTo(other, type || 'all', propagate);
|
270
302
|
}
|
271
|
-
|
272
|
-
|
303
|
+
})
|
304
|
+
}
|
305
|
+
};
|
306
|
+
Stormfront.Errors = {
|
307
|
+
FEEDBACK: 'An unexpected error was encountered'
|
308
|
+
};
|
309
|
+
|
310
|
+
Stormfront.Dispatches = {
|
311
|
+
RECEIVED: 'Dispatcher:Action:Received',
|
312
|
+
QUEUED: 'Dispatcher:Action:Queued',
|
313
|
+
READY: 'Dispatcher:Action:Ready',
|
314
|
+
EXECUTING: 'Store:Action:Executing',
|
315
|
+
EXECUTED: 'Store:Action:Executed',
|
316
|
+
MISSING: 'Store:Action:Missing',
|
317
|
+
ERROR: 'Store:Action:Error',
|
318
|
+
CHANGE: 'Store:Changed',
|
319
|
+
UNCHANGED: 'Store:Unchanged',
|
320
|
+
NO_RETURN: 'Store:NoReturnValue'
|
321
|
+
};
|
322
|
+
|
323
|
+
Stormfront.NO_CHANGE = 'Store:Nothing_Changed';
|
324
|
+
Stormfront.Reducer = Stormfront.Class.extend({
|
325
|
+
type: 'NOT:IMPLEMENTED',
|
326
|
+
dependencies: [],
|
327
|
+
initialize: function(dispatcher){
|
328
|
+
Stormfront.Patterns.Dispatcher(this, dispatcher);
|
273
329
|
},
|
330
|
+
execute: function(store, event){
|
331
|
+
throw 'The reducer does not implement a function body'
|
332
|
+
}
|
333
|
+
});
|
334
|
+
Stormfront.Ajax = {
|
335
|
+
START: 'AJAX:START',
|
336
|
+
SUCCESS: 'AJAX:SUCCESS',
|
337
|
+
ERROR: 'AJAX:ERROR',
|
338
|
+
ABORTED: 'AJAX:ABORTED',
|
339
|
+
PENDING: 'AJAX:PENDING',
|
340
|
+
Support: {
|
341
|
+
generateKey: function (event) {
|
342
|
+
return event.type;
|
343
|
+
},
|
344
|
+
createGenericRequest: function (type) {
|
345
|
+
return function (info) {
|
346
|
+
return _.extend(info, {type: type});
|
347
|
+
}
|
348
|
+
},
|
349
|
+
createGenericReducer: function (type) {
|
350
|
+
return Stormfront.Ajax.RequestReducer.extend({
|
351
|
+
type: type,
|
352
|
+
execute: function (store, event) {
|
353
|
+
try {
|
354
|
+
event.callbacks[type].call(event.callbacks.context, store, event);
|
355
|
+
} catch (e) {
|
356
|
+
console.warn('Ajax Handler encountered an error', e);
|
357
|
+
}
|
358
|
+
return this.updateEntry(store, event, type);
|
359
|
+
}
|
360
|
+
});
|
361
|
+
}
|
362
|
+
}
|
363
|
+
};
|
274
364
|
|
275
|
-
|
276
|
-
|
365
|
+
Stormfront.Ajax.RequestReducer = Stormfront.Reducer.extend({
|
366
|
+
getKey: function(event){
|
367
|
+
return Stormfront.Ajax.Support.generateKey(event);
|
368
|
+
},
|
369
|
+
getEntries: function(store){
|
370
|
+
return store.ajax || (store.ajax = { });
|
371
|
+
},
|
372
|
+
getEntry: function(store, event){
|
373
|
+
var key = this.getKey(event);
|
374
|
+
var entries = this.getEntries(store);
|
375
|
+
return entries[key] || (entries[key] = { });
|
376
|
+
},
|
377
|
+
updateEntry: function(store, event, state){
|
378
|
+
var ajax = this.getEntry(store, event);
|
379
|
+
ajax.state = state;
|
380
|
+
ajax.request = event.xhr;
|
381
|
+
ajax.exception = event.exception;
|
382
|
+
return store;
|
383
|
+
},
|
384
|
+
dropEntry: function(store, event){
|
385
|
+
var key = this.getKey(event);
|
386
|
+
var entries = this.getEntries(store);
|
387
|
+
delete entries[key];
|
277
388
|
}
|
278
389
|
});
|
279
390
|
|
280
|
-
Stormfront.
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
return $('#' + selector + '_template');
|
289
|
-
}
|
290
|
-
function compileTemplate(selection){
|
291
|
-
return Handlebars.compile(selection.html());
|
292
|
-
}
|
293
|
-
function expandTemplate(template){
|
294
|
-
return template(view.getViewModel());
|
295
|
-
}
|
296
|
-
return expandTemplate(compileTemplate(getTemplate(view)))
|
297
|
-
}
|
298
|
-
function findError(view){
|
299
|
-
function getTemplate(view){
|
300
|
-
if (!view.className)
|
301
|
-
throw Stormfront.Errors.NO_SELECTOR();
|
302
|
-
var selector = view.getIdentity();
|
303
|
-
return $('#' + selector + '_template');
|
304
|
-
}
|
305
|
-
function compileTemplate(template){
|
306
|
-
if (template.size() === 1)
|
307
|
-
return template;
|
308
|
-
if (template.size() === 0)
|
309
|
-
throw Stormfront.Errors.NO_TEMPLATE(view.getIdentity());
|
391
|
+
Stormfront.Ajax.Request = Stormfront.Ajax.RequestReducer.extend({
|
392
|
+
type: 'NOT:IMPLEMENTED',
|
393
|
+
execute: function(store, event){
|
394
|
+
event.callbacks = { };
|
395
|
+
event.callbacks.context = this;
|
396
|
+
event.callbacks[Stormfront.Ajax.START] = this.onStart;
|
397
|
+
event.callbacks[Stormfront.Ajax.SUCCESS] = this.onSuccess;
|
398
|
+
event.callbacks[Stormfront.Ajax.ERROR] = this.onError;
|
310
399
|
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
return template(vm);
|
316
|
-
}
|
317
|
-
catch(e) {
|
318
|
-
throw Stormfront.Errors.INCOMPATIBLE_TEMPLATE(view.getIdentity());
|
319
|
-
}
|
320
|
-
}
|
321
|
-
function getViewModel(view){
|
322
|
-
try {
|
323
|
-
return view.getViewModel();
|
324
|
-
}
|
325
|
-
catch (e){
|
326
|
-
throw Stormfront.Errors.VIEW_MODEL(view.getIdentity());
|
327
|
-
}
|
328
|
-
}
|
329
|
-
try {
|
330
|
-
return expandTemplate(compileTemplate(getTemplate(view)), getViewModel(view));
|
331
|
-
}
|
332
|
-
catch(e) {
|
333
|
-
return e;
|
334
|
-
}
|
400
|
+
var self = this;
|
401
|
+
function onStart(xhr, settings){
|
402
|
+
_.extend(event, { xhr: xhr });
|
403
|
+
self.dispatch(new Stormfront.Ajax.StartRequest(event));
|
335
404
|
}
|
336
|
-
|
337
|
-
|
405
|
+
function onSuccess(data, status, xhr){
|
406
|
+
_.extend(event, {
|
407
|
+
data: data,
|
408
|
+
status: status,
|
409
|
+
xhr: xhr
|
410
|
+
});
|
411
|
+
self.dispatch(new Stormfront.Ajax.SuccessRequest(event));
|
338
412
|
}
|
339
|
-
|
340
|
-
|
413
|
+
function onError(xhr, status, exception){
|
414
|
+
_.extend(event, {
|
415
|
+
status: status,
|
416
|
+
xhr: xhr,
|
417
|
+
exception: exception
|
418
|
+
});
|
419
|
+
self.dispatch(new Stormfront.Ajax.ErrorRequest(event));
|
341
420
|
}
|
342
|
-
|
421
|
+
var request = this.getParameters(store, event);
|
422
|
+
var settings = _.extend(request, {
|
423
|
+
beforeSend: onStart,
|
424
|
+
error: onError,
|
425
|
+
success: onSuccess
|
426
|
+
});
|
427
|
+
this.updateEntry(store, event, Stormfront.Ajax.PENDING);
|
428
|
+
this.send(settings);
|
429
|
+
return store;
|
430
|
+
},
|
431
|
+
send: function(settings){
|
432
|
+
// TODO: Remaining Concerns AJAX:
|
433
|
+
// TODO: Aborting similar request
|
434
|
+
// TODO: Avoiding equal request
|
435
|
+
$.ajax(settings);
|
436
|
+
},
|
437
|
+
getParameters: function(store, event){
|
438
|
+
return { url: '', method: 'get', data: {} }
|
439
|
+
},
|
440
|
+
onStart: function(store, event) { },
|
441
|
+
onSuccess: function(store, event) { },
|
442
|
+
onError: function(store, event) { }
|
343
443
|
});
|
344
444
|
|
345
|
-
|
346
|
-
|
347
|
-
this.name = 'TemplateError';
|
348
|
-
this.message = error.message;
|
349
|
-
this.stack = error.stack;
|
350
|
-
this.innerException = innerException;
|
351
|
-
}
|
445
|
+
Stormfront.Ajax.StartRequest = Stormfront.Ajax.Support.createGenericRequest(Stormfront.Ajax.START);
|
446
|
+
Stormfront.Ajax.Start = Stormfront.Ajax.Support.createGenericReducer(Stormfront.Ajax.START);
|
352
447
|
|
353
|
-
|
354
|
-
|
448
|
+
Stormfront.Ajax.SuccessRequest = Stormfront.Ajax.Support.createGenericRequest(Stormfront.Ajax.SUCCESS);
|
449
|
+
Stormfront.Ajax.Success = Stormfront.Ajax.Support.createGenericReducer(Stormfront.Ajax.SUCCESS);
|
355
450
|
|
451
|
+
Stormfront.Ajax.ErrorRequest = Stormfront.Ajax.Support.createGenericRequest(Stormfront.Ajax.ERROR);
|
452
|
+
Stormfront.Ajax.Error = Stormfront.Ajax.Support.createGenericReducer(Stormfront.Ajax.ERROR);
|
356
453
|
|
357
|
-
Stormfront.
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
454
|
+
Stormfront.Ajax.Reducers = [
|
455
|
+
Stormfront.Ajax.Start,
|
456
|
+
Stormfront.Ajax.Success,
|
457
|
+
Stormfront.Ajax.Error
|
458
|
+
];
|
459
|
+
Stormfront.Store = Stormfront.Class.extend({
|
460
|
+
initialize: function (options) {
|
362
461
|
$.extend(this, Backbone.Events);
|
462
|
+
|
463
|
+
this._state = new Stormfront.Store.State();
|
464
|
+
this._reducers = new Stormfront.Store.Reducers(options);
|
363
465
|
},
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
466
|
+
executeAction: function (action) {
|
467
|
+
var reducer = this._reducers.find(action);
|
468
|
+
if (reducer)
|
469
|
+
this.executeDispatch(action, reducer);
|
470
|
+
else
|
471
|
+
this.trigger(Stormfront.Dispatches.MISSING, action, reducer);
|
472
|
+
},
|
473
|
+
executeDispatch: function (action, reducer) {
|
474
|
+
try {
|
475
|
+
this.executeExternalCode(action, reducer);
|
476
|
+
} catch (e) {
|
477
|
+
this.trigger(Stormfront.Dispatches.ERROR, action, reducer);
|
478
|
+
}
|
369
479
|
},
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
480
|
+
executeExternalCode: function(action, reducer){
|
481
|
+
var current = this._state.getState();
|
482
|
+
this.trigger(Stormfront.Dispatches.EXECUTING, action, reducer, current);
|
483
|
+
|
484
|
+
var updated = reducer.execute(current, action);
|
485
|
+
this.trigger(Stormfront.Dispatches.EXECUTED, action, reducer, updated);
|
486
|
+
|
487
|
+
if (updated === Stormfront.NO_CHANGE)
|
488
|
+
this.trigger(Stormfront.Dispatches.UNCHANGED, action, reducer);
|
489
|
+
if (this._state.setState(updated))
|
490
|
+
this.trigger(Stormfront.Dispatches.CHANGE, action, reducer, updated, current);
|
491
|
+
else
|
492
|
+
this.trigger(Stormfront.Dispatches.NO_RETURN, action, reducer);
|
374
493
|
}
|
375
|
-
};
|
494
|
+
});
|
376
495
|
|
377
|
-
Stormfront.
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
496
|
+
Stormfront.Store.State = Stormfront.Class.extend({
|
497
|
+
setState: function (state) {
|
498
|
+
return state ? this.updateState(state) : false;
|
499
|
+
},
|
500
|
+
updateState: function (state) {
|
501
|
+
this._state = this.copyState(state);
|
502
|
+
return true;
|
503
|
+
},
|
504
|
+
getState: function () {
|
505
|
+
return this.copyState(this._state);
|
384
506
|
},
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
507
|
+
copyState: function (state) {
|
508
|
+
return $.extend(true, {}, state);
|
509
|
+
}
|
510
|
+
});
|
511
|
+
|
512
|
+
Stormfront.Store.Reducers = Stormfront.Class.extend({
|
513
|
+
reducers: { },
|
514
|
+
initialize: function (options) {
|
515
|
+
function createReducer(type) {
|
516
|
+
var reducer = new type(options.dispatcher);
|
517
|
+
this.reducers[reducer.type] = reducer;
|
518
|
+
_.each(reducer.dependencies, createReducer, this);
|
389
519
|
}
|
390
|
-
|
520
|
+
|
521
|
+
_.each(options.reducers, createReducer, this);
|
522
|
+
_.each(Stormfront.Ajax.Reducers, createReducer, this);
|
523
|
+
_.each(Stormfront.Store.Operations, createReducer, this);
|
391
524
|
},
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
525
|
+
find: function(event){
|
526
|
+
return this.reducers[event.type];
|
527
|
+
}
|
528
|
+
});
|
529
|
+
|
530
|
+
SetStateAction = function(state){
|
531
|
+
return {
|
532
|
+
type: 'Stormfront:Store:State:Set',
|
533
|
+
state: state
|
534
|
+
}
|
535
|
+
};
|
536
|
+
|
537
|
+
SetState = Stormfront.Reducer.extend({
|
538
|
+
type: 'Stormfront:Store:State:Set',
|
539
|
+
execute: function (store, action) {
|
540
|
+
return action.state;
|
541
|
+
}
|
542
|
+
});
|
543
|
+
|
544
|
+
Stormfront.Store.Operations = [SetState];
|
545
|
+
Stormfront.Dispatcher = Stormfront.Class.extend({
|
546
|
+
initialize: function () {
|
547
|
+
$.extend(this, Backbone.Events);
|
548
|
+
var queue = [];
|
549
|
+
var root = this;
|
550
|
+
|
551
|
+
this.dispatch = function (event) {
|
552
|
+
this.trigger(Stormfront.Dispatches.RECEIVED, event);
|
553
|
+
if (_.isEmpty(queue))
|
554
|
+
process(event);
|
396
555
|
else
|
397
|
-
|
556
|
+
enqueue(event);
|
557
|
+
};
|
558
|
+
|
559
|
+
function process(event) {
|
560
|
+
enqueue(event);
|
561
|
+
processQueue();
|
562
|
+
}
|
563
|
+
|
564
|
+
function enqueue(event) {
|
565
|
+
queue.push(event);
|
566
|
+
root.trigger(Stormfront.Dispatches.QUEUED, event);
|
567
|
+
}
|
568
|
+
|
569
|
+
|
570
|
+
function processQueue() {
|
571
|
+
if (_.isEmpty(queue))
|
572
|
+
return;
|
573
|
+
processNext();
|
574
|
+
processQueue();
|
575
|
+
}
|
576
|
+
|
577
|
+
function processNext() {
|
578
|
+
root.trigger(Stormfront.Dispatches.READY, queue[0]);
|
579
|
+
queue.shift();
|
580
|
+
}
|
581
|
+
}
|
582
|
+
});
|
583
|
+
Stormfront.Container = Stormfront.Class.extend({
|
584
|
+
page: null,
|
585
|
+
initial: null,
|
586
|
+
reducers: [],
|
587
|
+
initialize: function(location) {
|
588
|
+
Stormfront.Patterns.Events(this);
|
589
|
+
var dispatcher = new Stormfront.Dispatcher();
|
590
|
+
var page = new this.page(dispatcher);
|
591
|
+
var store = new Stormfront.Store({
|
592
|
+
reducers: this.reducers,
|
593
|
+
dispatcher: dispatcher
|
594
|
+
});
|
595
|
+
|
596
|
+
function executeAction(action){
|
597
|
+
store.executeAction(action);
|
598
|
+
}
|
599
|
+
function updateView(action, reducer, newProperties, oldProperties){
|
600
|
+
page.updateProperties(newProperties, oldProperties, action, reducer);
|
398
601
|
}
|
399
|
-
|
602
|
+
this.listenTo(dispatcher, Stormfront.Dispatches.READY, executeAction);
|
603
|
+
this.listenTo(store, Stormfront.Dispatches.CHANGE, updateView);
|
604
|
+
|
605
|
+
Stormfront.Patterns.Dispatcher(this, dispatcher);
|
606
|
+
Stormfront.Patterns.Events(this);
|
607
|
+
|
608
|
+
this.forward(dispatcher);
|
609
|
+
this.forward(store);
|
610
|
+
|
611
|
+
dispatcher.dispatch(SetStateAction(this.initial));
|
612
|
+
|
613
|
+
location.html(page.render().$el);
|
614
|
+
|
615
|
+
page.transition('attached');
|
400
616
|
}
|
617
|
+
});
|
618
|
+
|
619
|
+
var homefront = { };
|
620
|
+
var Homefront = {
|
621
|
+
Patterns: {}
|
401
622
|
};
|
402
623
|
|
624
|
+
Homefront.Template = Stormfront.Class.extend({
|
625
|
+
initialize: function (selector) {
|
626
|
+
this.selector = selector;
|
627
|
+
},
|
628
|
+
render: function (vm) {
|
629
|
+
function getTemplate(selector) {
|
630
|
+
return $('#' + selector + '_template');
|
631
|
+
}
|
632
|
+
function compileTemplate(selection) {
|
633
|
+
return Handlebars.compile(selection.html());
|
634
|
+
}
|
635
|
+
function expandTemplate(template, vm) {
|
636
|
+
return template(vm);
|
637
|
+
}
|
638
|
+
|
639
|
+
var template = getTemplate(this.selector);
|
640
|
+
var compiled = compileTemplate(template);
|
641
|
+
return expandTemplate(compiled, vm)
|
642
|
+
}
|
643
|
+
});
|
644
|
+
|
645
|
+
Homefront.Entity = Stormfront.Class.extend({
|
646
|
+
defaults: null,
|
647
|
+
initialize: function (properties) {
|
648
|
+
this.properties = _.extend(this, this.defaults, properties);
|
649
|
+
},
|
650
|
+
state: function(){
|
651
|
+
return this.getEntity().state;
|
652
|
+
},
|
653
|
+
getEntity: function(){
|
654
|
+
return this.properties;
|
655
|
+
},
|
656
|
+
isBusy: function(){
|
657
|
+
var state = this.state();
|
658
|
+
return state === Stormfront.Ajax.START ||
|
659
|
+
state === Stormfront.Ajax.PENDING;
|
660
|
+
}
|
661
|
+
});
|
662
|
+
Homefront.Collection = Homefront.Entity.extend({
|
663
|
+
entity: null,
|
664
|
+
state: '',
|
665
|
+
initialize: function (items, state) {
|
666
|
+
state = state || this.state;
|
667
|
+
var entity = this.entity;
|
668
|
+
this.properties = {
|
669
|
+
state: state,
|
670
|
+
data: _.map(items, function (option) {
|
671
|
+
return new entity(option);
|
672
|
+
})
|
673
|
+
};
|
674
|
+
this.state = state;
|
675
|
+
},
|
676
|
+
list: function () {
|
677
|
+
return this.getEntity().data;
|
678
|
+
},
|
679
|
+
isEmpty: function () {
|
680
|
+
return this.list().length === 0;
|
681
|
+
},
|
682
|
+
find: function (parameters) {
|
683
|
+
return _.findWhere(this.list(), parameters);
|
684
|
+
},
|
685
|
+
groupBy: function (field) {
|
686
|
+
return _.groupBy(this.list(), field);
|
687
|
+
},
|
688
|
+
pluck: function (field) {
|
689
|
+
return _.pluck(this.list(), field);
|
690
|
+
},
|
691
|
+
first: function () {
|
692
|
+
return this.list()[0];
|
693
|
+
},
|
694
|
+
onlyOne: function () {
|
695
|
+
return this.list().length === 1;
|
696
|
+
}
|
697
|
+
});
|
698
|
+
Homefront.Request = Stormfront.Ajax.Request.extend({
|
699
|
+
getEntity: function (store, action) {
|
700
|
+
return {};
|
701
|
+
},
|
702
|
+
onStart: function (store, action) {
|
703
|
+
this.getEntity(store, action).state = Stormfront.Ajax.START;
|
704
|
+
return store;
|
705
|
+
},
|
706
|
+
onSuccess: function (store, action) {
|
707
|
+
var entity = this.getEntity(store, action);
|
708
|
+
entity.state = Stormfront.Ajax.SUCCESS;
|
709
|
+
entity.data = action.data;
|
710
|
+
return store;
|
711
|
+
},
|
712
|
+
onError: function (store, action) {
|
713
|
+
var entity = this.getEntity(store);
|
714
|
+
entity.state = Stormfront.Ajax.ERROR;
|
715
|
+
entity.error = action.error;
|
716
|
+
return store;
|
717
|
+
}
|
718
|
+
});
|
403
719
|
|
404
720
|
Keys = {
|
405
721
|
Enter: 13,
|
@@ -453,7 +769,6 @@ KeyboardEvents = Stormfront.Class.extend({
|
|
453
769
|
this.off('all');
|
454
770
|
}
|
455
771
|
});
|
456
|
-
|
457
772
|
MouseEvents = Stormfront.Class.extend({
|
458
773
|
initialize: function(options){
|
459
774
|
options = _.extend({delay: 175}, options);
|
@@ -600,123 +915,7 @@ MouseEvents = Stormfront.Class.extend({
|
|
600
915
|
this.$el.global && this.$el.global.off('.me');
|
601
916
|
}
|
602
917
|
});
|
603
|
-
|
604
|
-
|
605
|
-
Stormfront.ViewBase = Backbone.View.extend({
|
606
|
-
initialize: function(){
|
607
|
-
this.errors = [];
|
608
|
-
},
|
609
|
-
render: function(){
|
610
|
-
try {
|
611
|
-
this.$el.html(new Stormfront.Template(this).render());
|
612
|
-
}
|
613
|
-
catch(e) {
|
614
|
-
this.handleException(e);
|
615
|
-
}
|
616
|
-
return this;
|
617
|
-
},
|
618
|
-
getViewModel: function(){
|
619
|
-
return this.model ? this.model.toJSON ? this.model.toJSON() : this.model : {};
|
620
|
-
},
|
621
|
-
handleException: function(exception){
|
622
|
-
if (exception.innerException)
|
623
|
-
console.warn(exception.message, exception.innerException);
|
624
|
-
else
|
625
|
-
console.warn(exception.message);
|
626
|
-
|
627
|
-
this.handleError(exception.message);
|
628
|
-
},
|
629
|
-
handleError: function(message){
|
630
|
-
if (_.contains(this.errors, message))
|
631
|
-
return;
|
632
|
-
this.notifyUser(message);
|
633
|
-
},
|
634
|
-
notifyUser: function(message){
|
635
|
-
this.alert && this.alert.close();
|
636
|
-
|
637
|
-
this.errors.push(message);
|
638
|
-
this.alert = new Stormfront.Alert({
|
639
|
-
model: {
|
640
|
-
summary: Stormfront.Errors.FEEDBACK,
|
641
|
-
details: this.errors.join(', ')
|
642
|
-
}
|
643
|
-
});
|
644
|
-
|
645
|
-
this.listenTo(this.alert, 'closing', this.removeNotification);
|
646
|
-
this.$el.append(this.alert.render().$el);
|
647
|
-
},
|
648
|
-
removeNotification: function(){
|
649
|
-
this.errors = [];
|
650
|
-
this.stopListening(this.alert);
|
651
|
-
},
|
652
|
-
getIdentity: function(){
|
653
|
-
return stormfront.string(this.className).firstWord();
|
654
|
-
},
|
655
|
-
toString: function(){
|
656
|
-
return this.getIdentity();
|
657
|
-
},
|
658
|
-
close: function(){
|
659
|
-
this.remove();
|
660
|
-
}
|
661
|
-
});
|
662
|
-
|
663
|
-
Stormfront.View = Stormfront.ViewBase.extend({
|
664
|
-
initialize: function(options){
|
665
|
-
Stormfront.ViewBase.prototype.initialize.call(this, options);
|
666
|
-
this.when = this.when || { };
|
667
|
-
this.addPublisher(this);
|
668
|
-
this.addSubscriber(this.when);
|
669
|
-
this.transition.apply(this, stormfront.arguments(arguments).prepend('initializing').get());
|
670
|
-
},
|
671
|
-
render: function(){
|
672
|
-
Stormfront.ViewBase.prototype.render.call(this);
|
673
|
-
this.transition.apply(this, stormfront.arguments(arguments).prepend('rendering').get());
|
674
|
-
return this;
|
675
|
-
},
|
676
|
-
addPublisher: function(publisher, identity){
|
677
|
-
function notify(event){
|
678
|
-
var args = stormfront.arguments(arguments).skip(1).get();
|
679
|
-
function executeHandler(subscriber){
|
680
|
-
var handler = stormfront.hash(subscriber).findNestedValue(event.split(':'));
|
681
|
-
if (_.isFunction(handler))
|
682
|
-
handler.apply(this, args);
|
683
|
-
}
|
684
|
-
_.each(this._subscribers, executeHandler, this);
|
685
|
-
}
|
686
|
-
function prepend(identity){
|
687
|
-
return function(event){
|
688
|
-
var newEvent = identity + ':' + event;
|
689
|
-
var args = stormfront.arguments(arguments).skip(1).prepend(newEvent).get();
|
690
|
-
notify.apply(this, args);
|
691
|
-
}
|
692
|
-
}
|
693
|
-
if (publisher === this)
|
694
|
-
this.listenTo(publisher, 'transition', notify);
|
695
|
-
else if (this.model && publisher === this.model)
|
696
|
-
this.listenTo(publisher, 'all', prepend('model'));
|
697
|
-
else if (this.collection && publisher === this.collection)
|
698
|
-
this.listenTo(publisher, 'all', prepend('collection'));
|
699
|
-
else if (publisher.className)
|
700
|
-
this.listenTo(publisher, 'transition', prepend(publisher.getIdentity()));
|
701
|
-
else
|
702
|
-
this.listenTo(publisher, 'all', prepend(identity));
|
703
|
-
},
|
704
|
-
addSubscriber: function(whenBlock){
|
705
|
-
this._subscribers = this._subscribers || [];
|
706
|
-
if (whenBlock)
|
707
|
-
this._subscribers.push(whenBlock);
|
708
|
-
},
|
709
|
-
transition: function(){
|
710
|
-
var args = stormfront.arguments(arguments).prepend('transition').get();
|
711
|
-
this.trigger.apply(this, args);
|
712
|
-
},
|
713
|
-
close: function(){
|
714
|
-
this.transition.apply(this, stormfront.arguments(arguments).prepend('closing').get());
|
715
|
-
Stormfront.ViewBase.prototype.close.call(this);
|
716
|
-
}
|
717
|
-
});
|
718
|
-
|
719
|
-
Stormfront.Errors = {
|
918
|
+
Homefront.Errors = {
|
720
919
|
FEEDBACK: 'An unexpected error was encountered',
|
721
920
|
/** @return {string} */
|
722
921
|
NO_SELECTOR: function() { return 'A template selector was not provided for your view' },
|
@@ -725,7 +924,7 @@ Stormfront.Errors = {
|
|
725
924
|
/** @return {string} */
|
726
925
|
INCOMPATIBLE_TEMPLATE: function(name) { return name +'\'s template and view model for your view are not compatible'; },
|
727
926
|
/** @return {string} */
|
728
|
-
VIEW_MODEL: function(name) { return name + '\'s
|
927
|
+
VIEW_MODEL: function(name) { return name + '\'s context generated an error'; },
|
729
928
|
/** @return {string} */
|
730
929
|
NO_LOCATION: function(name) { return name + ' has no locations available to render'; },
|
731
930
|
/** @return {string} */
|
@@ -742,181 +941,167 @@ Stormfront.Errors = {
|
|
742
941
|
ADDING: function(name) { return name + ' failed to add'; }
|
743
942
|
};
|
744
943
|
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
this
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
self.close();
|
758
|
-
});
|
759
|
-
}
|
760
|
-
}
|
761
|
-
});
|
762
|
-
|
763
|
-
Stormfront.Container = Stormfront.View.extend({
|
764
|
-
reducers: [],
|
765
|
-
store: null,
|
766
|
-
root: null,
|
767
|
-
when: {
|
768
|
-
initializing: function(){
|
769
|
-
this._reducers = _.map(this.reducers, this.createReducer, this);
|
770
|
-
},
|
771
|
-
rendering: function(){
|
772
|
-
this.store = new this.store();
|
773
|
-
this.root = new this.root({model: this.store});
|
774
|
-
this.listenToDispatches(this.root);
|
775
|
-
this.$el.append(this.root.render().$el);
|
944
|
+
Homefront.ViewBase = Backbone.View.extend({
|
945
|
+
location: null,
|
946
|
+
template: null,
|
947
|
+
render: function () {
|
948
|
+
try {
|
949
|
+
var context = this.getContext();
|
950
|
+
if (this.template)
|
951
|
+
this.$el.html(new Homefront.Template(this.template).render(context));
|
952
|
+
} catch (e) {
|
953
|
+
this.$el.html('An error was encountered');
|
954
|
+
console.error('Failed to render view');
|
955
|
+
console.error(e);
|
776
956
|
}
|
957
|
+
return this;
|
777
958
|
},
|
778
|
-
|
779
|
-
|
780
|
-
this.listenToDispatches(useCase);
|
781
|
-
return this.addReducer(useCase);
|
782
|
-
},
|
783
|
-
addReducer: function(useCase){
|
784
|
-
this._reducers[useCase.type] = useCase;
|
785
|
-
return useCase;
|
786
|
-
},
|
787
|
-
executeUseCase: function(event){
|
788
|
-
this._reducers[event.type].execute(this.store, event);
|
959
|
+
getContext: function(){
|
960
|
+
return this.properties ? this.properties : { };
|
789
961
|
},
|
790
|
-
|
791
|
-
this.
|
962
|
+
close: function () {
|
963
|
+
this.remove();
|
792
964
|
}
|
793
965
|
});
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
966
|
+
Homefront.View = Homefront.ViewBase.extend({
|
967
|
+
when: {},
|
968
|
+
initialize: function (dispatcher) {
|
969
|
+
_.each(this.when, this.addSubscriber, this);
|
970
|
+
this.addPublisher(this);
|
971
|
+
this.transition('before:initializing');
|
972
|
+
Stormfront.Patterns.Dispatcher(this, dispatcher);
|
973
|
+
this.transition('initializing');
|
974
|
+
},
|
975
|
+
render: function () {
|
976
|
+
this.transition('before:rendering');
|
977
|
+
Homefront.ViewBase.prototype.render.call(this);
|
978
|
+
this.transition('rendering');
|
979
|
+
return this;
|
980
|
+
},
|
981
|
+
renderAgain: function(){
|
982
|
+
this.render();
|
983
|
+
this.transition('attached');
|
984
|
+
},
|
985
|
+
addPublisher: function (publisher, identity) {
|
986
|
+
function notify(event) {
|
987
|
+
var args = stormfront.arguments(arguments).skip(1).get();
|
988
|
+
function executeHandler(subscriber) {
|
989
|
+
var handler = stormfront.hash(subscriber).findNestedValue(event.split(':'));
|
990
|
+
try {
|
991
|
+
if (_.isFunction(handler))
|
992
|
+
handler.apply(this, args);
|
993
|
+
} catch (e) {
|
994
|
+
console.error('Error encountered within the When block: ('+event+')');
|
995
|
+
console.error(e);
|
803
996
|
}
|
804
|
-
},
|
805
|
-
invalid: function(model, error){
|
806
|
-
this.handleException({error: error});
|
807
997
|
}
|
998
|
+
|
999
|
+
_.each(this._subscribers, executeHandler, this);
|
808
1000
|
}
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
sync: function(){
|
816
|
-
this.removeOverlay();
|
817
|
-
},
|
818
|
-
error: function(){
|
819
|
-
this.removeOverlay();
|
1001
|
+
|
1002
|
+
function prepend(identity) {
|
1003
|
+
return function (event) {
|
1004
|
+
var newEvent = identity + ':' + event;
|
1005
|
+
var args = stormfront.arguments(arguments).skip(1).prepend(newEvent).get();
|
1006
|
+
notify.apply(this, args);
|
820
1007
|
}
|
821
1008
|
}
|
1009
|
+
|
1010
|
+
if (publisher === this)
|
1011
|
+
this.listenTo(publisher, 'transition', notify);
|
1012
|
+
else
|
1013
|
+
this.listenTo(publisher, 'transition', prepend(identity));
|
822
1014
|
},
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
}
|
828
|
-
}
|
1015
|
+
addSubscriber: function (whenBlock) {
|
1016
|
+
this._subscribers = this._subscribers || [];
|
1017
|
+
if (whenBlock && !_.isEmpty(whenBlock))
|
1018
|
+
this._subscribers.push(whenBlock);
|
829
1019
|
},
|
830
|
-
|
831
|
-
this.
|
832
|
-
this.addSubscriber(this.exceptions);
|
833
|
-
this.addSubscriber(this.change);
|
834
|
-
this.addPublisher(this.model);
|
835
|
-
Stormfront.View.prototype.initialize.apply(this, arguments);
|
1020
|
+
transition: function () {
|
1021
|
+
this.trigger.apply(this, stormfront.arguments(arguments).prepend('transition').get());
|
836
1022
|
},
|
837
|
-
|
838
|
-
this.
|
839
|
-
this.
|
1023
|
+
updateProperties: function (properties) {
|
1024
|
+
var previous = this.properties;
|
1025
|
+
this.properties = this.selectProperties(properties);
|
1026
|
+
this.transition('updating', this.properties, previous);
|
840
1027
|
},
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
1028
|
+
selectProperties: function (properties) {
|
1029
|
+
return properties;
|
1030
|
+
},
|
1031
|
+
close: function () {
|
1032
|
+
this.transition('before:closing');
|
1033
|
+
this.transition('closing');
|
1034
|
+
Homefront.ViewBase.prototype.close.call(this);
|
846
1035
|
}
|
847
1036
|
});
|
848
1037
|
|
849
|
-
|
850
|
-
base
|
851
|
-
|
852
|
-
this._children = new Stormfront.Chaperone();
|
853
|
-
this.addPublisher(this._children, 'child');
|
854
|
-
},
|
855
|
-
rendering: function(){
|
856
|
-
_.each(this.children, this.composeChild, this);
|
857
|
-
},
|
858
|
-
closing: function(){
|
859
|
-
this._children.close();
|
860
|
-
},
|
861
|
-
child: {
|
862
|
-
created: function(child){
|
863
|
-
this._children.add(child);
|
864
|
-
},
|
865
|
-
added: function(child){
|
866
|
-
this.addPublisher(child);
|
867
|
-
this._children.render(child);
|
868
|
-
},
|
869
|
-
rendered: function(child){
|
870
|
-
var location = this.$('.' + child.getIdentity());
|
871
|
-
this._children.attach(child, location, 'replaceWith');
|
872
|
-
},
|
873
|
-
attached: function(child){
|
874
|
-
child.transition('rendered', child);
|
875
|
-
},
|
876
|
-
removed: function(child){
|
877
|
-
child.close();
|
878
|
-
this.stopListening(child);
|
879
|
-
},
|
880
|
-
error: function(error, innerException){
|
881
|
-
this.handleException(
|
882
|
-
new LayoutError(error, innerException)
|
883
|
-
);
|
884
|
-
}
|
885
|
-
}
|
886
|
-
},
|
887
|
-
initialize: function(){
|
888
|
-
this.addSubscriber(this.base);
|
889
|
-
Stormfront.View.prototype.initialize.apply(this, arguments);
|
890
|
-
},
|
891
|
-
composeChild: function(childOptions, childClass){
|
892
|
-
this._children.create(childClass, childOptions, this);
|
893
|
-
},
|
894
|
-
findChild: function(identity){
|
895
|
-
return this._children.find(identity);
|
1038
|
+
Homefront.View.extend = function(protoProps){
|
1039
|
+
function copyConstructor(base){
|
1040
|
+
return function(){ return base.apply(this, arguments); };
|
896
1041
|
}
|
897
|
-
|
1042
|
+
function copyBaseProperties(child, parent){
|
1043
|
+
_.extend(child, parent);
|
1044
|
+
}
|
1045
|
+
function carryPrototypeChain(child, parent){
|
1046
|
+
var Surrogate = function(){ this.constructor = child; };
|
1047
|
+
Surrogate.prototype = parent.prototype;
|
1048
|
+
child.prototype = new Surrogate;
|
1049
|
+
}
|
1050
|
+
function copyNewProperties(child, protoProps){
|
1051
|
+
var newWhen = protoProps['when'];
|
1052
|
+
var oldWhen = child.prototype['when'];
|
898
1053
|
|
899
|
-
|
900
|
-
var error = Error(message);
|
901
|
-
this.name = 'LayoutError';
|
902
|
-
this.message = error.message;
|
903
|
-
this.stack = error.stack;
|
904
|
-
this.innerException = innerException;
|
905
|
-
}
|
1054
|
+
_.extend(child.prototype, protoProps);
|
906
1055
|
|
907
|
-
|
908
|
-
|
1056
|
+
var when = [];
|
1057
|
+
oldWhen && when.push(oldWhen);
|
1058
|
+
newWhen && when.push(newWhen);
|
1059
|
+
child.prototype['when'] = _.flatten(when);
|
1060
|
+
}
|
1061
|
+
function enableAccessToBaseClass(){
|
1062
|
+
child.__super__ = parent.prototype;
|
1063
|
+
}
|
1064
|
+
|
1065
|
+
var parent = this;
|
1066
|
+
var child = copyConstructor(parent);
|
1067
|
+
copyBaseProperties(child, parent);
|
1068
|
+
carryPrototypeChain(child, parent);
|
1069
|
+
copyNewProperties(child, protoProps);
|
1070
|
+
enableAccessToBaseClass(child, parent);
|
1071
|
+
return child;
|
1072
|
+
};
|
909
1073
|
|
910
|
-
|
1074
|
+
Homefront.Alert = Homefront.View.extend({
|
1075
|
+
className: 'alert',
|
1076
|
+
events: {
|
1077
|
+
'click .close': 'dismiss'
|
1078
|
+
},
|
1079
|
+
render: function(){
|
1080
|
+
var errors = this.properties.errors || [];
|
1081
|
+
var content = $('<div>');
|
1082
|
+
var summary = $('<p>').addClass('summary').text(Stormfront.Errors.FEEDBACK);
|
1083
|
+
var details = $('<p>').addClass('errors').text(errors.join(', '));
|
1084
|
+
var close = $('<div>').addClass('close').attr('title', 'click to close');
|
1085
|
+
content.append(summary).append(details).append(close);
|
1086
|
+
this.$el.html(content);
|
1087
|
+
this.transitionAs('rendering', arguments);
|
1088
|
+
return this;
|
1089
|
+
},
|
1090
|
+
dismiss: function(){
|
1091
|
+
this.trigger('dismissed');
|
1092
|
+
this.close();
|
1093
|
+
}
|
1094
|
+
});
|
1095
|
+
Homefront.Overlay = Stormfront.Class.extend({
|
911
1096
|
initialize: function(options){
|
912
1097
|
var selector = options.selector;
|
913
1098
|
|
914
1099
|
if (!selector)
|
915
|
-
this.overlay = new
|
1100
|
+
this.overlay = new Homefront.FullScreenOverlay({model: options});
|
916
1101
|
else if (options.saveRequest)
|
917
|
-
this.overlay = new
|
1102
|
+
this.overlay = new Homefront.InlineOverlay();
|
918
1103
|
else
|
919
|
-
this.overlay = new
|
1104
|
+
this.overlay = new Homefront.AnonymousOverlay();
|
920
1105
|
|
921
1106
|
selector = selector ? selector : document.body;
|
922
1107
|
this.location = selector.size ? selector : $(selector);
|
@@ -936,7 +1121,7 @@ Stormfront.Overlay = Stormfront.Class.extend({
|
|
936
1121
|
}
|
937
1122
|
});
|
938
1123
|
|
939
|
-
|
1124
|
+
Homefront.OverlayBase = Homefront.View.extend({
|
940
1125
|
className: 'overlay',
|
941
1126
|
activated: false,
|
942
1127
|
PAUSE_DURATION: 0,
|
@@ -1010,7 +1195,7 @@ Stormfront.OverlayBase = Stormfront.View.extend({
|
|
1010
1195
|
}
|
1011
1196
|
});
|
1012
1197
|
|
1013
|
-
|
1198
|
+
Homefront.FullScreenOverlay = Homefront.OverlayBase.extend({
|
1014
1199
|
MINIMUM_DURATION: 900,
|
1015
1200
|
css: {
|
1016
1201
|
overlay_background: {
|
@@ -1028,7 +1213,7 @@ Stormfront.FullScreenOverlay = Stormfront.OverlayBase.extend({
|
|
1028
1213
|
}
|
1029
1214
|
});
|
1030
1215
|
|
1031
|
-
|
1216
|
+
Homefront.AnonymousOverlay = Homefront.OverlayBase.extend({
|
1032
1217
|
PAUSE_DURATION: 200,
|
1033
1218
|
MINIMUM_DURATION: 450,
|
1034
1219
|
css: {
|
@@ -1047,7 +1232,7 @@ Stormfront.AnonymousOverlay = Stormfront.OverlayBase.extend({
|
|
1047
1232
|
}
|
1048
1233
|
});
|
1049
1234
|
|
1050
|
-
|
1235
|
+
Homefront.InlineOverlay = Homefront.OverlayBase.extend({
|
1051
1236
|
className: 'input_overlay',
|
1052
1237
|
MINIMUM_DURATION: 1500,
|
1053
1238
|
MAXIMUM_WIDTH: 1200,
|
@@ -1085,53 +1270,546 @@ Stormfront.InlineOverlay = Stormfront.OverlayBase.extend({
|
|
1085
1270
|
}
|
1086
1271
|
}
|
1087
1272
|
});
|
1273
|
+
Homefront.Guidance = {
|
1274
|
+
Generic: function (type, text) {
|
1275
|
+
return Homefront.Text.extend({
|
1276
|
+
tagName: type,
|
1277
|
+
className: 'guidance',
|
1278
|
+
text: text,
|
1279
|
+
selectProperties: function () {
|
1280
|
+
return {value: this.text}
|
1281
|
+
}
|
1282
|
+
});
|
1283
|
+
},
|
1284
|
+
Paragraph: function (text) {
|
1285
|
+
return Homefront.Guidance.Generic('p', text);
|
1286
|
+
},
|
1287
|
+
Table: function (text) {
|
1288
|
+
text = '<td colspan="99">' + text + '</td>';
|
1289
|
+
return Homefront.Guidance.Generic('tr', text);
|
1290
|
+
},
|
1291
|
+
List: function (text) {
|
1292
|
+
return Homefront.Guidance.Generic('li', text);
|
1293
|
+
}
|
1294
|
+
};
|
1088
1295
|
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1296
|
+
Homefront.Chaperone = Homefront.View.extend({
|
1297
|
+
method: 'append',
|
1298
|
+
when: {
|
1299
|
+
initializing: function () {
|
1300
|
+
this._children = [];
|
1301
|
+
},
|
1302
|
+
updating: function (properties) {
|
1303
|
+
this.updateChildren(this._children, properties);
|
1304
|
+
},
|
1305
|
+
attached: function(){
|
1306
|
+
var previous = this._children;
|
1307
|
+
this._children = [];
|
1308
|
+
this.createChildren();
|
1309
|
+
this.renderChildren(this._children);
|
1310
|
+
this.attachChildren(this._children);
|
1311
|
+
this.closeChildren(previous);
|
1312
|
+
},
|
1313
|
+
closing: function () {
|
1314
|
+
this.closeChildren(this._children);
|
1315
|
+
this._children = [];
|
1316
|
+
},
|
1317
|
+
chaperone: {
|
1318
|
+
create: function (type, properties) {
|
1319
|
+
type = _.isString(type) ? stormfront.type(type) : type;
|
1320
|
+
properties = _.isObject(properties) ? properties : this.properties;
|
1321
|
+
if (type) {
|
1322
|
+
var child = new type(this.getDispatcher());
|
1323
|
+
this.transition('chaperone:add', child, properties);
|
1324
|
+
} else {
|
1325
|
+
console.error('Child type does not exist: ', type);
|
1326
|
+
}
|
1327
|
+
},
|
1328
|
+
add: function (child, properties) {
|
1329
|
+
this._children.push(child);
|
1330
|
+
child.transition && this.addPublisher(child, 'child');
|
1331
|
+
child.updateProperties(properties);
|
1332
|
+
},
|
1333
|
+
attach: function (child, location, method) {
|
1334
|
+
child.transition('attaching', child);
|
1335
|
+
location[method](child.$el);
|
1336
|
+
child.transition('attached', child);
|
1337
|
+
}
|
1338
|
+
},
|
1339
|
+
child: {
|
1340
|
+
closing: function (child) {
|
1341
|
+
this._children.splice(this._children.indexOf(child), 1);
|
1342
|
+
this.stopListening(child);
|
1343
|
+
}
|
1344
|
+
}
|
1345
|
+
},
|
1346
|
+
createChild: function (type, properties) {
|
1347
|
+
this.transition('chaperone:create', type, properties);
|
1348
|
+
},
|
1349
|
+
attachChild: function (child, location, method) {
|
1350
|
+
this.transition('chaperone:attach', child, location, method || this.method);
|
1351
|
+
},
|
1352
|
+
createChildren: function () {
|
1353
|
+
|
1354
|
+
},
|
1355
|
+
renderChildren: function (children) {
|
1356
|
+
_.invoke(children, 'render');
|
1357
|
+
},
|
1358
|
+
attachChildren: function (children) {
|
1359
|
+
function attachChild(child) {
|
1360
|
+
if (child.location)
|
1361
|
+
this.attachChild(child, this.$('.' + child.location));
|
1362
|
+
else
|
1363
|
+
this.attachChild(child, this.$el, 'append');
|
1364
|
+
}
|
1365
|
+
_.each(children, attachChild, this);
|
1366
|
+
},
|
1367
|
+
updateChildren: function (children, properties) {
|
1368
|
+
_.invoke(children, 'updateProperties', properties);
|
1369
|
+
},
|
1370
|
+
closeChildren: function (children) {
|
1371
|
+
function stop(child) {
|
1372
|
+
this.stopListening(child);
|
1373
|
+
}
|
1374
|
+
//TODO: This bit is odd...
|
1375
|
+
_.each(children, stop, this);
|
1376
|
+
_.invoke(children, 'close');
|
1377
|
+
},
|
1378
|
+
at: function (index) {
|
1379
|
+
return this._children[index];
|
1380
|
+
}
|
1381
|
+
});
|
1382
|
+
Homefront.Layout = Homefront.Chaperone.extend({
|
1383
|
+
method: 'replaceWith',
|
1384
|
+
createChildren: function () {
|
1385
|
+
_.each(this.children, this.createChild, this);
|
1386
|
+
}
|
1387
|
+
});
|
1388
|
+
Homefront.Switch = Homefront.Chaperone.extend({
|
1389
|
+
when: {
|
1390
|
+
updating: function () {
|
1391
|
+
if (this._state !== undefined && this.stateChanged())
|
1392
|
+
this.renderAgain();
|
1393
|
+
}
|
1394
|
+
},
|
1395
|
+
getCases: function () {
|
1396
|
+
var feedback = '"getState" and "getCases" are not implemented';
|
1397
|
+
var guidance = Homefront.Guidance.Paragraph(feedback);
|
1398
|
+
return {
|
1399
|
+
not_implemented: guidance
|
1400
|
+
};
|
1401
|
+
},
|
1402
|
+
getState: function () {
|
1403
|
+
return 'not_implemented'
|
1404
|
+
},
|
1405
|
+
stateChanged: function(){
|
1406
|
+
return this._state !== this.getState(this.properties);
|
1407
|
+
},
|
1408
|
+
updateState: function () {
|
1409
|
+
var oldState = this._state;
|
1410
|
+
var newState = this.getState(this.properties);
|
1411
|
+
this._state = newState;
|
1412
|
+
|
1413
|
+
if (oldState !== newState) {
|
1414
|
+
oldState && this.transition('exiting:' + oldState, oldState);
|
1415
|
+
this.transition('entering:' + newState, newState);
|
1416
|
+
} else {
|
1417
|
+
oldState && this.transition('staying:' + oldState, oldState);
|
1418
|
+
}
|
1419
|
+
return newState;
|
1420
|
+
},
|
1421
|
+
createChildren: function () {
|
1422
|
+
var cases = this.getCases();
|
1423
|
+
var state = this.updateState();
|
1424
|
+
var candidate = cases[state];
|
1425
|
+
candidate && this.createChild(candidate);
|
1426
|
+
},
|
1427
|
+
attachChildren: function (children) {
|
1428
|
+
if (children.length === 1) {
|
1429
|
+
var candidate = children[0];
|
1430
|
+
candidate.$el.addClass(this.className);
|
1431
|
+
candidate.$el.addClass(this._state);
|
1432
|
+
this.attachChild(candidate, this.$el, 'replaceWith');
|
1433
|
+
this.setElement(candidate.el);
|
1434
|
+
}
|
1435
|
+
}
|
1436
|
+
});
|
1437
|
+
|
1438
|
+
Homefront.Expandable = Homefront.Switch.extend({
|
1439
|
+
summary: null,
|
1440
|
+
details: null,
|
1441
|
+
expanded: false,
|
1442
|
+
getCases: function () {
|
1443
|
+
return {
|
1444
|
+
summary: this.summary,
|
1445
|
+
details: this.details
|
1446
|
+
};
|
1447
|
+
},
|
1448
|
+
getState: function () {
|
1449
|
+
return this.expanded ? 'details' : 'summary';
|
1450
|
+
},
|
1451
|
+
expand: function () {
|
1452
|
+
this.expanded = true;
|
1453
|
+
this.renderAgain();
|
1454
|
+
},
|
1455
|
+
collapse: function () {
|
1456
|
+
this.expanded = false;
|
1457
|
+
this.renderAgain();
|
1458
|
+
}
|
1459
|
+
});
|
1460
|
+
Homefront.Enumerator = Homefront.Chaperone.extend({
|
1461
|
+
item: null,
|
1462
|
+
when: {
|
1463
|
+
chaperone: {
|
1464
|
+
add: function(child){
|
1465
|
+
child.location = this.item.location;
|
1466
|
+
}
|
1467
|
+
}
|
1468
|
+
},
|
1469
|
+
createChildren: function () {
|
1470
|
+
var items = this.selectItems(this.properties);
|
1471
|
+
function createChild(item) {
|
1472
|
+
this.createChild(this.item.view, item);
|
1473
|
+
}
|
1474
|
+
_.each(items, createChild, this);
|
1475
|
+
},
|
1476
|
+
updateChildren: function(children, properties){
|
1477
|
+
var items = this.selectItems(properties);
|
1478
|
+
function updateChild(child, index) {
|
1479
|
+
var item = items[index];
|
1480
|
+
child.updateProperties(item);
|
1481
|
+
}
|
1482
|
+
_.each(children, updateChild);
|
1093
1483
|
},
|
1094
|
-
|
1095
|
-
|
1484
|
+
composeChild: function(item){
|
1485
|
+
return this.createChild(this.item, item);
|
1486
|
+
},
|
1487
|
+
selectItems: function (properties) {
|
1488
|
+
return properties;
|
1489
|
+
},
|
1490
|
+
at: function (index) {
|
1491
|
+
return this._children[index];
|
1492
|
+
}
|
1493
|
+
});
|
1494
|
+
Homefront.List = Homefront.Switch.extend({
|
1495
|
+
item: null,
|
1496
|
+
when: {
|
1497
|
+
initializing: function () {
|
1498
|
+
this.enumerator = Homefront.Enumerator.extend({
|
1499
|
+
tagName: this.tagName,
|
1500
|
+
template: this.template,
|
1501
|
+
className: this.className + ' stormfront.enumerator',
|
1502
|
+
item: this.item,
|
1503
|
+
getContext: this.getContext,
|
1504
|
+
selectItems: this.selectItems
|
1505
|
+
});
|
1506
|
+
}
|
1507
|
+
},
|
1508
|
+
getCases: function () {
|
1509
|
+
return {
|
1510
|
+
empty: this.empty,
|
1511
|
+
populated: this.enumerator
|
1512
|
+
}
|
1513
|
+
},
|
1514
|
+
getState: function (properties) {
|
1515
|
+
var items = this.selectItems(properties);
|
1516
|
+
return items && items.length > 0 ? 'populated' : 'empty';
|
1517
|
+
},
|
1518
|
+
selectItems: function (properties) {
|
1519
|
+
return properties.list ? properties.list() : properties;
|
1520
|
+
}
|
1521
|
+
});
|
1522
|
+
//TODO: This should have a better name I suppose
|
1523
|
+
Homefront.ActiveList = Homefront.List.extend({
|
1524
|
+
getCases: function () {
|
1525
|
+
//lazy shortcut
|
1526
|
+
this.populated = this.enumerator;
|
1527
|
+
return this;
|
1528
|
+
},
|
1529
|
+
getState: function (properties) {
|
1530
|
+
var state = properties.state;
|
1531
|
+
if (state === Stormfront.Ajax.SUCCESS)
|
1532
|
+
//TODO: Fetching inventory can return an error in the data
|
1533
|
+
return this.selectItems(properties).length === 0 ? 'empty' : properties.data.error ? 'error' : 'populated';
|
1534
|
+
else if (state === Stormfront.Ajax.START)
|
1535
|
+
return 'requesting';
|
1536
|
+
else if (state === Stormfront.Ajax.ERROR)
|
1537
|
+
return 'error';
|
1538
|
+
return state;
|
1539
|
+
},
|
1540
|
+
selectItems: function(properties) {
|
1541
|
+
return properties.data
|
1096
1542
|
}
|
1097
1543
|
});
|
1098
1544
|
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1545
|
+
//TODO: Got two of them now?
|
1546
|
+
Homefront.Series = Homefront.List.extend({
|
1547
|
+
getState: function (properties) {
|
1548
|
+
var state = properties.state();
|
1549
|
+
if (state === Stormfront.Ajax.SUCCESS) {
|
1550
|
+
var items = this.selectItems(properties);
|
1551
|
+
return items && items.length > 0 ? 'populated' : 'empty';
|
1552
|
+
}
|
1553
|
+
return state;
|
1554
|
+
},
|
1555
|
+
selectItems: function (properties) {
|
1556
|
+
return properties.list();
|
1104
1557
|
}
|
1105
|
-
|
1106
|
-
|
1107
|
-
|
1558
|
+
});
|
1559
|
+
Homefront.Patterns.Selectable = function(method, action){
|
1560
|
+
var events = {};
|
1561
|
+
events[method] = 'select';
|
1562
|
+
return {
|
1563
|
+
events: events,
|
1564
|
+
action: action,
|
1565
|
+
select: function(){
|
1566
|
+
var action = stormfront.type(this.action);
|
1567
|
+
this.dispatch(new action(this.properties));
|
1568
|
+
}
|
1569
|
+
};
|
1570
|
+
};
|
1571
|
+
|
1572
|
+
Homefront.SelectableList = Homefront.Enumerator.extend({
|
1573
|
+
className: 'options',
|
1574
|
+
item: null,
|
1575
|
+
select: null,
|
1576
|
+
method: 'click',
|
1577
|
+
when: {
|
1578
|
+
initializing: function(){
|
1579
|
+
var item = stormfront.type(this.item);
|
1580
|
+
this.item = {
|
1581
|
+
view: item.extend(Homefront.Patterns.Selectable(this.method, this.select))
|
1582
|
+
};
|
1583
|
+
}
|
1584
|
+
},
|
1585
|
+
selectItems: function (properties) {
|
1586
|
+
return properties.list();
|
1108
1587
|
}
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1112
|
-
|
1113
|
-
|
1114
|
-
|
1588
|
+
});
|
1589
|
+
|
1590
|
+
Homefront.SelectableDisplay = Homefront.Switch.extend({
|
1591
|
+
className: 'selected',
|
1592
|
+
select: null,
|
1593
|
+
guidance: '',
|
1594
|
+
display: null,
|
1595
|
+
getCases: function() {
|
1596
|
+
return {
|
1597
|
+
none: Homefront.Guidance.Paragraph(this.guidance),
|
1598
|
+
selected: this.display
|
1599
|
+
};
|
1600
|
+
},
|
1601
|
+
when: {
|
1602
|
+
entering: {
|
1603
|
+
none: function(){
|
1604
|
+
var entity = this.properties;
|
1605
|
+
if (entity.onlyOne()) {
|
1606
|
+
var action = stormfront.type(this.select);
|
1607
|
+
this.dispatch(new action(entity.first()));
|
1608
|
+
}
|
1609
|
+
}
|
1610
|
+
},
|
1611
|
+
updating: function(){
|
1612
|
+
this.render();
|
1613
|
+
}
|
1614
|
+
},
|
1615
|
+
getState: function(properties){
|
1616
|
+
return properties.selected() ? 'selected' : 'none';
|
1115
1617
|
}
|
1116
|
-
|
1117
|
-
|
1118
|
-
|
1119
|
-
|
1618
|
+
});
|
1619
|
+
|
1620
|
+
//TODO: Could be a list or a series.
|
1621
|
+
Homefront.Selection = Homefront.Switch.extend({
|
1622
|
+
className: 'selection',
|
1623
|
+
item: null,
|
1624
|
+
select: null,
|
1625
|
+
method: 'click',
|
1626
|
+
display: null,
|
1627
|
+
none: '',
|
1628
|
+
initial: '',
|
1629
|
+
empty: '',
|
1630
|
+
list: null,
|
1631
|
+
adapter: null,
|
1632
|
+
when: {
|
1633
|
+
initializing: function(){
|
1634
|
+
this.selectList = Homefront.SelectableList.extend({
|
1635
|
+
item: this.item,
|
1636
|
+
select: this.select,
|
1637
|
+
method: this.method || 'click'
|
1638
|
+
});
|
1639
|
+
this.selectDisplay = Homefront.SelectableDisplay.extend({
|
1640
|
+
select: this.select,
|
1641
|
+
display: this.display,
|
1642
|
+
guidance: this.none
|
1643
|
+
});
|
1120
1644
|
}
|
1121
|
-
|
1122
|
-
|
1123
|
-
|
1645
|
+
},
|
1646
|
+
getCases: function(){
|
1647
|
+
return {
|
1648
|
+
initial: Homefront.Guidance.Paragraph(this.initial),
|
1649
|
+
empty: Homefront.Guidance.Paragraph(this.empty),
|
1650
|
+
populated: Homefront.Layout.extend({
|
1651
|
+
children: [this.selectList, this.selectDisplay]
|
1652
|
+
})
|
1124
1653
|
}
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
1654
|
+
},
|
1655
|
+
getState: function (properties) {
|
1656
|
+
var state = properties.state();
|
1657
|
+
if (state === Stormfront.Ajax.SUCCESS)
|
1658
|
+
return properties.isEmpty() ? 'empty' : 'populated';
|
1659
|
+
return state;
|
1660
|
+
},
|
1661
|
+
selectProperties: function(properties){
|
1662
|
+
var adapter = stormfront.type(this.adapter);
|
1663
|
+
return new adapter(properties);
|
1664
|
+
}
|
1665
|
+
});
|
1666
|
+
Homefront.Search = Homefront.Layout.extend({
|
1667
|
+
className: 'search',
|
1668
|
+
adapter: null,
|
1669
|
+
when: {
|
1670
|
+
initializing: function () {
|
1671
|
+
var results = Homefront.Selection.extend({
|
1672
|
+
select: this.select,
|
1673
|
+
display: this.details,
|
1674
|
+
none: this.none,
|
1675
|
+
empty: this.empty,
|
1676
|
+
initial: this.initial,
|
1677
|
+
item: this.item,
|
1678
|
+
method: this.method || 'click'
|
1679
|
+
});
|
1680
|
+
this.children = [this.search, results]
|
1681
|
+
}
|
1682
|
+
},
|
1683
|
+
selectProperties: function (properties) {
|
1684
|
+
var adapter = stormfront.type(this.adapter);
|
1685
|
+
return new adapter(properties);
|
1686
|
+
}
|
1687
|
+
});
|
1688
|
+
|
1689
|
+
Homefront.Text = Homefront.View.extend({
|
1690
|
+
when: {
|
1691
|
+
updating: function(){
|
1692
|
+
this.updateValue();
|
1693
|
+
},
|
1694
|
+
rendering: function(){
|
1695
|
+
this.updateValue();
|
1696
|
+
}
|
1697
|
+
},
|
1698
|
+
updateValue: function(){
|
1699
|
+
this.$el.text(this.getValue(this.properties));
|
1700
|
+
},
|
1701
|
+
getValue: function(properties){
|
1702
|
+
return this.value || properties.value;
|
1703
|
+
}
|
1704
|
+
});
|
1705
|
+
|
1706
|
+
Homefront.Label = Homefront.Text.extend({
|
1707
|
+
tagName: 'label',
|
1708
|
+
when: {
|
1709
|
+
rendering: function() {
|
1710
|
+
this.$el.attr('for', this.properties.for);
|
1711
|
+
}
|
1712
|
+
}
|
1713
|
+
});
|
1714
|
+
|
1715
|
+
Homefront.Paragraph = Homefront.Text.extend({
|
1716
|
+
tagName: 'p'
|
1717
|
+
});
|
1718
|
+
|
1719
|
+
Homefront.Input = Homefront.Text.extend({
|
1720
|
+
tagName: 'input',
|
1721
|
+
enable: function(){
|
1722
|
+
this.$el.prop('disabled', false);
|
1723
|
+
},
|
1724
|
+
disable: function(){
|
1725
|
+
this.$el.prop('disabled', true);
|
1726
|
+
},
|
1727
|
+
updateValue: function(){
|
1728
|
+
this.$el.val(this.getValue(this.properties));
|
1729
|
+
},
|
1730
|
+
readValue: function(){
|
1731
|
+
return this.$el.val();
|
1732
|
+
}
|
1733
|
+
});
|
1734
|
+
|
1735
|
+
Homefront.Select = Homefront.Input.extend({
|
1736
|
+
tagName: 'select',
|
1737
|
+
events: {
|
1738
|
+
'change': 'select'
|
1739
|
+
},
|
1740
|
+
when: {
|
1741
|
+
rendering: function(){
|
1742
|
+
this.updateSelect();
|
1743
|
+
},
|
1744
|
+
updating: function(){
|
1745
|
+
this.updateSelect();
|
1746
|
+
}
|
1747
|
+
},
|
1748
|
+
updateSelect: function(){
|
1749
|
+
this.updateOptions();
|
1750
|
+
this.updateValue();
|
1751
|
+
},
|
1752
|
+
updateOptions: function(){
|
1753
|
+
var options = this.getOptions(this.properties);
|
1754
|
+
function createOption(value){
|
1755
|
+
return $('<option>').val(value).text(value);
|
1129
1756
|
}
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1757
|
+
this.$el.append(_.map(options, createOption));
|
1758
|
+
},
|
1759
|
+
getOptions: function(properties){
|
1760
|
+
return properties.options;
|
1761
|
+
},
|
1762
|
+
getValue: function(properties) {
|
1763
|
+
return properties.selected;
|
1764
|
+
},
|
1765
|
+
select: function(){
|
1766
|
+
this.transition('change', this.$el.val());
|
1767
|
+
}
|
1768
|
+
});
|
1133
1769
|
|
1134
|
-
|
1770
|
+
Homefront.TextBox = Homefront.Input.extend({
|
1771
|
+
events: {
|
1772
|
+
'change': 'change',
|
1773
|
+
'blur': 'blur',
|
1774
|
+
'keyup': 'special'
|
1775
|
+
},
|
1776
|
+
when: {
|
1777
|
+
rendering: function(){
|
1778
|
+
this.$el.attr('type', 'text');
|
1779
|
+
}
|
1780
|
+
},
|
1781
|
+
change: function(){
|
1782
|
+
this.transition('change', this.readValue());
|
1783
|
+
},
|
1784
|
+
blur: function(){
|
1785
|
+
this.transition('blur', this.readValue());
|
1786
|
+
},
|
1787
|
+
special: function(event){
|
1788
|
+
if (event.which === Keys.Enter)
|
1789
|
+
this.transition('enter', this.readValue());
|
1790
|
+
}
|
1791
|
+
});
|
1792
|
+
|
1793
|
+
Homefront.Clicker = Homefront.Input.extend({
|
1794
|
+
events: {
|
1795
|
+
'click': 'click'
|
1796
|
+
},
|
1797
|
+
click: function(){
|
1798
|
+
this.transition('click');
|
1799
|
+
}
|
1800
|
+
});
|
1801
|
+
|
1802
|
+
Homefront.Button = Homefront.Clicker.extend({
|
1803
|
+
when: {
|
1804
|
+
rendering: function(){
|
1805
|
+
this.$el.attr('type', 'button');
|
1806
|
+
}
|
1807
|
+
}
|
1808
|
+
});
|
1809
|
+
Homefront.Leaf = Homefront.View.extend({
|
1810
|
+
when: {
|
1811
|
+
initializing: function() {
|
1812
|
+
this.template = stormfront.string(this.className).firstWord() || null;
|
1813
|
+
}
|
1135
1814
|
}
|
1136
|
-
|
1137
|
-
};
|
1815
|
+
});
|