www_app 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +36 -0
  3. data/Gemfile +3 -0
  4. data/LICENSE +21 -0
  5. data/README.md +84 -0
  6. data/TODO.md +13 -0
  7. data/VERSION +1 -0
  8. data/bin/www_app +46 -0
  9. data/doc/Design.md +123 -0
  10. data/doc/Why_this_arch.rb +104 -0
  11. data/lib/public/jquery-2.1.1.js +4 -0
  12. data/lib/public/jquery.serialize-object.min.js +8 -0
  13. data/lib/public/underscore-1.7.0.js +6 -0
  14. data/lib/public/underscore-min.map +1 -0
  15. data/lib/public/underscore.string-2.3.0.js +1 -0
  16. data/lib/public/www_app.js +824 -0
  17. data/lib/www_app/Clean.rb +169 -0
  18. data/lib/www_app/dsl.rb +86 -0
  19. data/lib/www_app/source.rb +53 -0
  20. data/lib/www_app.rb +1024 -0
  21. data/specs/as_ruby/0000-new.rb +23 -0
  22. data/specs/as_ruby/0010-attrs.rb +29 -0
  23. data/specs/as_ruby/0011-class.rb +39 -0
  24. data/specs/as_ruby/0011-href.rb +37 -0
  25. data/specs/as_ruby/0011-id.rb +39 -0
  26. data/specs/as_ruby/0020-tag.rb +21 -0
  27. data/specs/as_ruby/0020-tag_content.rb +43 -0
  28. data/specs/as_ruby/0021-body.rb +16 -0
  29. data/specs/as_ruby/0021-form.rb +22 -0
  30. data/specs/as_ruby/0021-link.rb +26 -0
  31. data/specs/as_ruby/0021-script.rb +44 -0
  32. data/specs/as_ruby/0030-mustache.rb +113 -0
  33. data/specs/as_ruby/0040-css.rb +174 -0
  34. data/specs/as_ruby/0050-on.rb +64 -0
  35. data/specs/client-side/index.html +90 -0
  36. data/specs/client-side/index.js +777 -0
  37. data/specs/lib/config.ru +96 -0
  38. data/specs/lib/helpers.rb +230 -0
  39. data/specs/lib/qunit/qunit-1.15.0.css +237 -0
  40. data/specs/lib/qunit/qunit-1.15.0.js +2495 -0
  41. data/specs/lib/sample.rb +23 -0
  42. data/specs/sampe.2.rb +14 -0
  43. data/specs/sample.3.rb +17 -0
  44. data/specs/sample.rb +44 -0
  45. data/www_app.gemspec +38 -0
  46. metadata +271 -0
@@ -0,0 +1,824 @@
1
+
2
+ "use strict";
3
+
4
+
5
+ var WWW_App = null;
6
+
7
+
8
+ (function () {
9
+
10
+ var VALID_TOUCH_ACTIONS = ['mousedown', 'mouseup', 'focus', 'blur', 'click'];
11
+ var all_scopes = [];
12
+ var id_counter = -1;
13
+ var INVALID_FORM_ACTION_CHARS = /[^a-z0-9\/\.\_]+/g;
14
+ var MAIN = null;
15
+ var WHITE_SPACE = /\s+/;
16
+
17
+
18
+ // ================================================================
19
+ // Helper Functions
20
+ // ================================================================
21
+
22
+ // From:
23
+ // http://stackoverflow.com/questions/1026069/capitalize-the-first-letter-of-string-in-javascript
24
+ var capitalize = function (s) {
25
+ return s.charAt(0).toUpperCase() + s.substring(1);
26
+ };
27
+
28
+
29
+ var classes = function (raw) {
30
+ return _.str.trim($(raw).attr('class')).split(WHITE_SPACE);
31
+ }; // function
32
+
33
+
34
+ var tag_name = function (raw) {
35
+ return ($(raw).prop('tagName') || '').toLowerCase();
36
+ }; // function
37
+
38
+
39
+ var inspect = function (val) {
40
+ var name = func_name(val.constructor || 'Unknown');
41
+ return name + ': ' + val;
42
+ };
43
+
44
+ var form_status = function (form, data, key) {
45
+ var dom = form.find('div.status_msg:first');
46
+ if (dom.length === 0) {
47
+ form.find('div.buttons:first').before('<div class="status_msg"></div>');
48
+ return form_status(form, data, key);
49
+ }
50
+
51
+ dom.addClass(key);
52
+ dom.html(data.clean_html[key]);
53
+ return dom;
54
+ }; // function
55
+
56
+ var form_reset_class = function (form, css_class) {
57
+ form.removeClass('submitted');
58
+ form.removeClass('loading');
59
+ form.removeClass('error');
60
+ form.removeClass('errors');
61
+
62
+ if (css_class === 'errors')
63
+ css_class = 'error';
64
+
65
+ if (css_class) {
66
+ form.addClass(css_class);
67
+ }
68
+ return form;
69
+ }; // function
70
+
71
+
72
+ var id = function (str_or_o) {
73
+ var target = $(str_or_o);
74
+ if (!target.attr('id')) {
75
+ id_counter = id_counter + 1;
76
+ target.attr('id', target.prop('tagName').toLowerCase() + '_client_default_id_' + id_counter);
77
+ }
78
+
79
+ return '#' + target.attr('id');
80
+ }; // function
81
+
82
+
83
+ var is_numeric = function (val) {
84
+ return _.isNumber(val) && !_.isNaN(val);
85
+ };
86
+
87
+
88
+ var log = function () {
89
+ if (!window.console) { return; }
90
+ return console.log.apply(console, arguments);
91
+ };
92
+
93
+
94
+ var func_name = function (raw) {
95
+ var s = null;
96
+ var name = null;
97
+
98
+ if (_.isString(raw)) {
99
+ s = raw;
100
+ } else {
101
+ s = ('' + raw);
102
+ }
103
+
104
+ name = _.last( _.first(s.split('(')).split('function ') );
105
+ return name;
106
+ };
107
+
108
+ var each = function (arr, func) {
109
+ var l = arr.length;
110
+ var i = 0;
111
+ var each_o = {
112
+
113
+ next: function () {
114
+ if (each_o.is_last()) {
115
+ throw new Error('No more items: i: ' + i + ' total: ' + l);
116
+ }
117
+ return arr[i + 1];
118
+ }, // === next
119
+
120
+ prev : function () {
121
+ if (each_o.is_first()) {
122
+ throw new Error('No previous items: i: ' + i + ' total: ' + l);
123
+ }
124
+ return arr[i - 1];
125
+ },
126
+
127
+ next_or_null: function () {
128
+ if (each_o.is_last()) { return null; }
129
+ return arr[i + 1];
130
+ },
131
+
132
+ prev_or_null : function () {
133
+ if (each_o.is_first()) { return null; }
134
+ return arr[i - 1];
135
+ },
136
+
137
+ is_first: function () {
138
+ return i < 1;
139
+ },
140
+
141
+ is_last: function () {
142
+ return i >= (l - 1);
143
+ },
144
+
145
+ grab_next: function () {
146
+ if (each_o.is_last()) {
147
+ throw new Error('Can\'t grab next because already at last position.');
148
+ }
149
+ i = i + 1;
150
+ return arr[i];
151
+ }
152
+
153
+ }; // === each_o
154
+
155
+ while ( i < l ) {
156
+ each_o.i = i;
157
+ func(arr[i], each_o);
158
+ i = i + 1;
159
+ } // while
160
+
161
+ }; // === each
162
+
163
+
164
+ var to_number_name = function (num) {
165
+ var name = null;
166
+ switch (num) {
167
+ case 0:
168
+ name = 'first';
169
+ break;
170
+
171
+ case 1:
172
+ name = 'second';
173
+ break;
174
+
175
+ case 2:
176
+ name = 'third';
177
+ break;
178
+
179
+ case 3:
180
+ name = 'fourth';
181
+ break;
182
+
183
+ case 4:
184
+ name = 'fifth';
185
+ break;
186
+
187
+ case 5:
188
+ name = 'sixth';
189
+ break;
190
+
191
+ default:
192
+ throw new Error("Unknown value: " + num);
193
+ } // === switch num
194
+ return name;
195
+ }; // function
196
+
197
+
198
+ var last_types = function (stack, types, stack_name) {
199
+ var o = {};
200
+
201
+ if (types.length === 0) {
202
+ throw new Error("No arguments.");
203
+ }
204
+
205
+ if (types.length === 1 && types[0] === 'all') {
206
+ return stack;
207
+ }
208
+
209
+ var vals = _.last(stack, types.length);
210
+
211
+ if (vals.length !== types.length) {
212
+ throw new Error('Not enough values in ' + stack_name + '.');
213
+ }
214
+
215
+ _.each(types, function (t, i) {
216
+ var val = vals[i];
217
+ var ignore_type = t === 'any' || t === 'last';
218
+
219
+ if (!ignore_type) {
220
+ if (_.isString(t)) {
221
+ throw new Error('Unknown position or type: ' + t);
222
+ }
223
+
224
+ if (val.constructor !== t) {
225
+ throw new Error('Value in ' + stack_name + " is not a " + func_name(t) + ': ' + inspect(val));
226
+ }
227
+ }
228
+
229
+ o[to_number_name(i)] = val;
230
+ });
231
+
232
+ if (types.length === 1) {
233
+ return o.first;
234
+ }
235
+
236
+ return o;
237
+ }; // last_types
238
+
239
+ // ================================================================
240
+ // === End Helper Functions =======================================
241
+ // ================================================================
242
+
243
+
244
+ // ================================================================
245
+ // Scope
246
+ // ================================================================
247
+ var Scope = function (parent) {
248
+
249
+ var o = {};
250
+ var vars = {};
251
+ var stack = [];
252
+ var events = [];
253
+ var scope_log_stack = [];
254
+ var top = o;
255
+
256
+ if (parent) {
257
+ o.parent = parent;
258
+ while(top.parent) {
259
+ top = top.parent;
260
+ }
261
+ }
262
+
263
+ all_scopes.push(o);
264
+
265
+ var scope_log = function () {
266
+ return _.each(_.toArray(arguments), function (val) {
267
+ top.log.push(val);
268
+ });
269
+ }; // function
270
+
271
+ var on = function (name, raw_target) {
272
+
273
+ if (name === 'defaults') { // =================================
274
+
275
+ // ========= Setup default actions for "button" tags: =======
276
+ _.each( $('button'), function (raw_b) {
277
+ on('click', raw_b);
278
+ }); // === _.each
279
+
280
+ // ========= Setup default actions for "a" tags: ============
281
+ _.each( $('a[href]'), function (raw_a) {
282
+ var a = $(raw_a);
283
+ var href = a.attr('href');
284
+ if (href.indexOf('#') !== 0)
285
+ return false;
286
+
287
+ var anchor = $('a[name="' + href.replace('#', '') + '"]');
288
+ if (anchor.length > 0)
289
+ return false;
290
+
291
+ on('click', a);
292
+ });
293
+
294
+ return o;
295
+ } // if 'defaults' ============================================
296
+
297
+ if (!_.contains(VALID_TOUCH_ACTIONS, name)) {
298
+ throw new Error('Unknown event name: ' + name);
299
+ }
300
+
301
+ var target = $(raw_target);
302
+ target.off(name);
303
+ target.on(name, function (e) {
304
+
305
+ e.preventDefault();
306
+ e.stopPropagation();
307
+ e.stopImmediatePropagation();
308
+
309
+ run_does(name, e.target, {event: e});
310
+
311
+ var tag = tag_name(target);
312
+ var is_click = name === 'click';
313
+ var is_a = tag === 'a';
314
+ var is_button = tag === 'button';
315
+ var is_submit = target.hasClass('submit') && target.parents('form:first').length > 0;
316
+ var is_hash = is_a && target.attr('href').indexOf('#') === 0;
317
+ var form_parents = target.parents('form');
318
+ var is_touch = _.contains(VALID_TOUCH_ACTIONS, name);
319
+
320
+ if (is_click && is_button && !is_submit ) {
321
+ _.each(classes(target), function (css) {
322
+ run_does(css, target, {event: e});
323
+ });
324
+ return false;
325
+ }
326
+
327
+ if (is_click && is_a && !is_submit && is_hash) {
328
+ var action = target.attr('href').replace('#', '');
329
+ var no_anchors = $('a[name="' + action + '"]').length === 0;
330
+ if (no_anchors)
331
+ run_does(action, target, {event: e});
332
+ return false;
333
+ }
334
+
335
+ if (is_submit) {
336
+ submit_form(e.target, {event: e});
337
+ return false;
338
+ }
339
+
340
+ if (is_touch) {
341
+ _.each(classes(target), function (css) {
342
+ run_does(css, target, {event: e});
343
+ });
344
+ }
345
+
346
+ return false;
347
+ }); // target.on
348
+
349
+ }; // === on
350
+
351
+ var click_button = function (name, raw_target, options) {
352
+ var target = $(raw_target);
353
+ var do_click = !target.hasClass('submit');
354
+
355
+ if (!do_click)
356
+ return false;
357
+
358
+ }; // function
359
+
360
+ var submit_form = function (raw_target, options) {
361
+ var e = options.event;
362
+ var target = $(raw_target);
363
+ var form = target.parents('form:first');
364
+ var tag = tag_name(target);
365
+
366
+ var form_type = _.detect('GET POST PUT DELETE'.split(/\s+/), function (val) {
367
+ return target.hasClass(val.toLowerCase());
368
+ }) || 'POST';
369
+
370
+ var form_data = form.serializeObject();
371
+ if (form_type !== 'GET' && form_type !== 'POST') {
372
+ form_data._method = form_type;
373
+ form_type = 'POST';
374
+ }
375
+
376
+ var is_success = false;
377
+ var url = form.attr('action');
378
+ var settings = {
379
+ type : form_type,
380
+ dataType : "json",
381
+ data : form_data,
382
+ success : function (data,status_str, jxhr) {
383
+ is_success = true;
384
+ if (data.clean_html.error_msg) {
385
+ form_status(form, data, 'error_msg');
386
+ form_reset_class(form, 'error');
387
+ run_does('error', target, {event: e, vars: {data: data.data}});
388
+ } else {
389
+ form_status(form, data, 'success_msg');
390
+ form_reset_class(form, 'success');
391
+ run_does('success', target, {event: e, vars: {data: data.data}});
392
+ }
393
+ },
394
+ error : function (data) {
395
+ form_status(form, {clean_html: {error_msg: 'An unknown network error has occurred.'}}, 'error_msg');
396
+ form_reset_class(form, 'error');
397
+ },
398
+ complete : function (a,b,c) {
399
+ form.removeClass('loading');
400
+ form.addClass('complete');
401
+ if (!is_success) {
402
+ form_reset_class(form, 'error');
403
+ form_status(form, 'An unknown error has occurred.');
404
+ }
405
+ }
406
+ };
407
+
408
+ var invalid = url.match(INVALID_FORM_ACTION_CHARS);
409
+ if (invalid) {
410
+ throw new Error('Invalid chars in form action url: ' + invalid.join('') );
411
+ }
412
+
413
+ form_reset_class(form, 'loading');
414
+ $.ajax(url, settings);
415
+
416
+ }; // submit_form_if_needed
417
+
418
+ var run_does = function (event_name, raw_target, options) {
419
+
420
+ var target = $(raw_target);
421
+
422
+ _.each(events, function (meta) {
423
+ var first = meta.path_tokens[0];
424
+
425
+ if (first !== event_name)
426
+ return false;
427
+
428
+ var second = meta.path_tokens[1];
429
+ var third = meta.path_tokens[2];
430
+ var relative = (third || second) ? relative_id(target, (third || second)) : null;
431
+
432
+ var is_touch = _.contains(VALID_TOUCH_ACTIONS, event_name);
433
+ var is_target = second && $(second).is(target);
434
+ var is_css = target.hasClass(event_name);
435
+ var is_href = tag_name(target) === 'a' && target.attr('href') === ('#' + event_name);
436
+ var push_target = null;
437
+
438
+ // === "/click/button.something/relative"
439
+ if (is_touch && is_target && third && relative)
440
+ push_target = relative;
441
+
442
+ else { // === "/click/button.something"
443
+ if (is_touch && is_target && !third)
444
+ push_target = id(target);
445
+
446
+ else { // === "/red/relative"
447
+ if ((is_css || is_href) && !third && relative)
448
+ push_target = relative;
449
+
450
+ else { // "/red"
451
+ if (is_css && !second && !third)
452
+ push_target = id(target);
453
+
454
+ else { // /success/#form_1
455
+ if (!third && first === event_name && relative)
456
+ push_target = relative;
457
+ }
458
+ }
459
+ }
460
+ }
461
+
462
+ if (push_target)
463
+ return child(options.vars).push(push_target).run(meta.code);
464
+
465
+ return false;
466
+ });
467
+ }; // function
468
+
469
+
470
+ // ==============================================================
471
+ // ============== stack functions ===============================
472
+ // ==============================================================
473
+
474
+ var right = function () {
475
+ return last_types(stack, _.toArray(arguments), 'stack');
476
+ };
477
+
478
+
479
+ var push = function () {
480
+ var args = _.toArray(arguments);
481
+ _.each(args, function (v) {
482
+ stack.push(v);
483
+ });
484
+ return o;
485
+ }; // push ========================================
486
+
487
+
488
+ var concat = function (arr) {
489
+ push.apply(null, arr);
490
+ return arr;
491
+ }; // concat ================================
492
+
493
+
494
+ var relative_id = function (target, selector) {
495
+ if (!selector)
496
+ throw new Error('Invalid selector: ' + selector);
497
+
498
+ var relative = $(target).find(selector)[0] || $(target).parents(selector)[0] || ($(target).is($(selector)) && target);
499
+ if (relative) {
500
+ return id(relative);
501
+ }
502
+ return null;
503
+ };
504
+
505
+ // ==============================================================
506
+ // ================ run functions ===============================
507
+ // ==============================================================
508
+
509
+ var run = function (code_array) {
510
+ each(code_array, function (item, l) {
511
+
512
+ if (_.isArray(item)) {
513
+ throw new Error("Syntax error: args w/o function name.");
514
+
515
+ } else if (_.isString(item), _.isArray(l.next_or_null())) {
516
+ run_func(item, l.grab_next());
517
+
518
+ } else {
519
+ stack.push(item);
520
+ } // === if
521
+
522
+ }); // === .each
523
+
524
+ return o;
525
+ }; // run ========================================
526
+
527
+ var run_func = function (name, raw_args) {
528
+
529
+ var compiled_args = null;
530
+ var first = null;
531
+ var second = null;
532
+ var left_args = null;
533
+ var target = null;
534
+
535
+ var run_args = function () {
536
+ if (!compiled_args) {
537
+ compiled_args = child().run(raw_args).right('all');
538
+ }
539
+
540
+ return compiled_args;
541
+ }; // run_args
542
+
543
+ var left = function () {
544
+ return last_types(run_args(), _.toArray(arguments), 'args');
545
+ };
546
+
547
+ var replace_left = function (arr) {
548
+ compiled_args = arr;
549
+ return compiled_args;
550
+ };
551
+
552
+ switch (name) {
553
+
554
+ case 'get':
555
+ return push(get(left(String)));
556
+
557
+ case 'focus on ancestor':
558
+ set('the focus', the_focus().parents(left(String)));
559
+ return get('the focus');
560
+
561
+ case 'submit':
562
+ var form = the_focus();
563
+ var action = form.attr('action');
564
+ if (/[^a-zA-Z0-9\_\-\/]+/.test(action)) {
565
+ throw new Error("Invalid chars in #" + form.attr('id') + " action: " + action);
566
+ }
567
+ return null;
568
+
569
+ case 'array':
570
+ push(run_args());
571
+ return right('last');
572
+
573
+ case 'remove class':
574
+ the_focus().removeClass(left(String));
575
+ return left('last');
576
+
577
+ case 'add class':
578
+ the_focus().addClass(left(String));
579
+ return left('last');
580
+
581
+ case 'add to stack':
582
+ concat( run_args() );
583
+ return run_args();
584
+
585
+ case "and":
586
+ first = right(Boolean);
587
+ second = null;
588
+ left_args = null;
589
+
590
+ if (first === true) {
591
+ second = left(Boolean);
592
+
593
+ if (first === true && second === true) {
594
+ push(true);
595
+ return true;
596
+ }
597
+ }
598
+
599
+ push(false);
600
+ return false;
601
+
602
+ case "or":
603
+ first = right(Boolean);
604
+ second = null;
605
+ left_args = null;
606
+
607
+ if (first === true) {
608
+ push(true);
609
+ return true;
610
+ }
611
+
612
+ second = left(Boolean);
613
+
614
+ if (second === true) {
615
+ push(true);
616
+ return true;
617
+ }
618
+
619
+ push(false);
620
+ return false;
621
+
622
+ case "if true":
623
+ first = right(Boolean);
624
+
625
+ if (first) {
626
+ run_args();
627
+ }
628
+
629
+ return null;
630
+
631
+ case "if false":
632
+ first = right(Boolean);
633
+
634
+ if (!first) {
635
+ run_args();
636
+ }
637
+
638
+ return null;
639
+
640
+ case 'log':
641
+ scope_log.apply(null, run_args());
642
+ return run_args();
643
+
644
+ case "on click":
645
+ var focus_selector = get('the focus');
646
+ var scope = child();
647
+ scope.set('the focus', focus_selector);
648
+
649
+ $(focus_selector).click(function () {
650
+ scope.run(raw_args);
651
+ });
652
+
653
+ return null;
654
+
655
+ case "on":
656
+ throw new Error('Not ready yet: on');
657
+
658
+ case 'bigger or equal':
659
+ return run_func('compare numbers', ['>=', left(Number)]);
660
+
661
+ case 'bigger':
662
+ return run_func('compare numbers', ['>', left(Number)]);
663
+
664
+ case 'less':
665
+ return run_func('compare numbers', ['<', left(Number)]);
666
+
667
+ case 'less or equal':
668
+ return run_func('compare numbers', ['<=', left(Number)]);
669
+
670
+ case 'equal':
671
+ first = right('any');
672
+ second = left('any');
673
+ push(first === second);
674
+ return right('last');
675
+
676
+ case 'compare numbers':
677
+ first = right(Number);
678
+
679
+ var args = left(String, Number);
680
+ var compare = args.first;
681
+ second = args.second;
682
+
683
+ var result = null;
684
+
685
+ switch (compare) {
686
+
687
+ case '===':
688
+ result = first === second;
689
+ break;
690
+
691
+ case '<=':
692
+ result = first <= second;
693
+ break;
694
+
695
+ case '<':
696
+ result = first < second;
697
+ break;
698
+
699
+ case '>=':
700
+ result = first >= second;
701
+ break;
702
+
703
+ case '>':
704
+ result = first > second;
705
+ break;
706
+
707
+ default:
708
+ throw new Error("Unknown value : " + compare);
709
+ } // === switch
710
+
711
+ push(result);
712
+ return result;
713
+
714
+ case 'allows':
715
+ var event_name = left(String);
716
+ target = $(right(String));
717
+
718
+ on(event_name, target);
719
+ return event_name;
720
+
721
+ case 'does':
722
+ var path = right(String);
723
+
724
+ var meta = {};
725
+ meta.path_tokens = _.map(path.split('/'), function (v) {
726
+ return _.str.trim(v);
727
+ });
728
+
729
+ if (meta.path_tokens[0] === '') {
730
+ meta.path_tokens.shift();
731
+ }
732
+
733
+ if (meta.path_tokens.length < 1 || meta.path_tokens.length > 3) {
734
+ throw new Error('Unknown path: ' + path);
735
+ }
736
+
737
+ events.push({
738
+ code : raw_args,
739
+ path : path,
740
+ path_tokens : meta.path_tokens
741
+ });
742
+
743
+ return path;
744
+
745
+ case 'remove':
746
+ $(right(String)).find(left(String)).remove();
747
+ return null;
748
+
749
+
750
+ default:
751
+ throw new Error("Function not found: " + name);
752
+ } // === switch name
753
+
754
+ }; // run_func ===================================
755
+
756
+
757
+ // ==============================================================
758
+ // ============= miscel. functions ==============================
759
+ // ==============================================================
760
+
761
+ var child = function (vars) {
762
+ var s = new Scope(o);
763
+ if (vars) {
764
+ _.each(vars, function (val, key) {
765
+ s.set(key, val);
766
+ });
767
+ }
768
+ return( s );
769
+ };
770
+
771
+ var the_focus = function () {
772
+ return $(right(String));
773
+ };
774
+
775
+ var set = function (name, val) {
776
+ vars[name] = val;
777
+ return val;
778
+ }; // function
779
+
780
+ var get = function (name) {
781
+ if (!vars.hasOwnProperty(name) && !parent) {
782
+ throw new Error('No var found with name: ' + name);
783
+ }
784
+
785
+ return (vars.hasOwnProperty(name)) ?
786
+ vars[name] :
787
+ parent.get(name);
788
+ }; // val =========================================
789
+
790
+
791
+ o.run = run;
792
+
793
+ // ====================================================
794
+ // The following functions
795
+ // are meant to be used by WWW_App.run.
796
+ // Don't use them.
797
+ // ====================================================
798
+ o.right = right;
799
+ o.get = get;
800
+ o.set = set;
801
+ o.push = push;
802
+ o.on = on;
803
+ o.log = scope_log_stack;
804
+ // ====================================================
805
+
806
+ return o;
807
+
808
+ // ================================================================
809
+ }; // ===== Scope =================================================
810
+ // ================================================================
811
+
812
+ WWW_App = {
813
+ run : function (code_array) {
814
+ WWW_App.MAIN = (new Scope()).on('defaults').run(code_array);
815
+ return WWW_App.MAIN;
816
+ }
817
+ };
818
+
819
+ WWW_App.run([]);
820
+
821
+ })(); // === WWW_App scope
822
+
823
+
824
+