golf 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,942 @@
1
+ (function($) {
2
+
3
+ function toJson(obj) {
4
+ switch (typeof obj) {
5
+ case 'object':
6
+ if (obj) {
7
+ var list = [];
8
+ if (obj instanceof Array) {
9
+ for (var i=0;i < obj.length;i++) {
10
+ list.push(toJson(obj[i]));
11
+ }
12
+ return '[' + list.join(',') + ']';
13
+ } else {
14
+ for (var prop in obj) {
15
+ list.push('"' + prop + '":' + toJson(obj[prop]));
16
+ }
17
+ return '{' + list.join(',') + '}';
18
+ }
19
+ } else {
20
+ return 'null';
21
+ }
22
+ case 'string':
23
+ return '"' + obj.replace(/(["'])/g, '\\$1') + '"';
24
+ case 'number':
25
+ case 'boolean':
26
+ return new String(obj);
27
+ }
28
+ }
29
+
30
+ function Component() {
31
+ this._dom = null;
32
+ this._$ = null;
33
+ this.hide = function() {
34
+ this._dom.hide(Array.prototype.slice.call(arguments));
35
+ };
36
+ this.show = function() {
37
+ this._dom.show(Array.prototype.slice.call(arguments));
38
+ };
39
+ }
40
+
41
+ function Debug(prefix) {
42
+ return function(text) {
43
+ text = prefix+": "+text;
44
+ if (window.devmode && window.console && window.console.log)
45
+ console.log(text);
46
+ else if (window.serverside)
47
+ alert(text);
48
+ };
49
+ }
50
+
51
+ function $local(selector, root) {
52
+ return $(root)
53
+ .find("*")
54
+ .andSelf()
55
+ .filter(selector)
56
+ .not($(".component *", root).get())
57
+ .not($("* .component", root).get());
58
+ }
59
+
60
+ function checkForReservedClass(elems, shutup) {
61
+ if (! $.golf.reservedClassChecking || window.forcebot)
62
+ return [];
63
+ var RESERVED_CLASSES = [ "component", "golfbody", "golfproxylink" ];
64
+ var badclass = (
65
+ (typeof elems == "string")
66
+ ? $.map(RESERVED_CLASSES, function(c) {
67
+ return (c == elems) ? elems : null;
68
+ })
69
+ : $.map(RESERVED_CLASSES, function(c) {
70
+ return elems.hasClass(c) ? c : null;
71
+ })
72
+ );
73
+
74
+ if (badclass.length && !shutup)
75
+ d("WARN: using, adding, or removing reserved class names: "
76
+ + badclass.join(","));
77
+ return badclass;
78
+ }
79
+
80
+ function doCall(obj, jQuery, $, argv, js, d) {
81
+ d = !!d ? d : window.d;
82
+ if (js.length > 10) {
83
+ var f;
84
+ eval("f = "+js);
85
+ f.apply(obj, argv);
86
+ }
87
+ }
88
+
89
+ /* parseUri is based on work (c) 2007 Steven Levithan <stevenlevithan.com> */
90
+
91
+ function parseUri(str) {
92
+ var o = {
93
+ strictMode: true,
94
+ key: ["source","protocol","authority","userInfo","user","password",
95
+ "host","port","relative","path","directory","file","query","anchor"],
96
+ q: {
97
+ name: "queryKey",
98
+ parser: /(?:^|&)([^&=]*)=?([^&]*)/g
99
+ },
100
+ parser: {
101
+ strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
102
+ loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
103
+ }
104
+ };
105
+ var m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
106
+ uri = {},
107
+ i = 14;
108
+
109
+ while (i--) uri[o.key[i]] = m[i] || "";
110
+
111
+ uri[o.q.name] = {};
112
+ uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
113
+ if ($1) uri[o.q.name][$1] = $2;
114
+ });
115
+
116
+ return uri;
117
+ }
118
+
119
+ /* jss is based on: JSS - 0.4 by Andy Kent */
120
+
121
+ var jss = {
122
+
123
+ mark: function(elem) {
124
+ var cpdom;
125
+
126
+ try {
127
+ cpdom = $(elem).parents(".component").eq(0);
128
+
129
+ if (cpdom.size() == 0 || cpdom.data("_golf_constructing"))
130
+ return;
131
+ }
132
+ catch (x) {
133
+ d("WARN: can't do mark: "+x);
134
+ return;
135
+ }
136
+
137
+ cpdom.data("_golf_jss_dirty", true);
138
+ if ($.golf.jssTimeout >= 0)
139
+ setTimeout(function() { jss.doit(elem) }, 10);
140
+ else jss.doit(elem);
141
+ },
142
+
143
+ doit: function(elem, force) {
144
+ var cpdom, cpname, data, parsed;
145
+
146
+ if ((serverside && !force) || window.forcebot)
147
+ return;
148
+
149
+ try {
150
+ cpdom = $(elem).parents(".component").eq(0);
151
+
152
+ if (cpdom.size() == 0 || cpdom.data("_golf_constructing")
153
+ || !cpdom.data("_golf_jss_dirty"))
154
+ return;
155
+
156
+ cpdom.removeData("_golf_jss_dirty");
157
+
158
+ cpname = cpdom.attr("class").split(" ")[1].replace(/-/g, ".");
159
+ data = $.golf.components[cpname].css;
160
+ parsed = this.parse(data);
161
+ }
162
+ catch (x) {
163
+ d("WARN: can't do jss: "+x);
164
+ return;
165
+ }
166
+
167
+ $local("*", cpdom).each(
168
+ function() {
169
+ var jself = $(this);
170
+ for (var i in jself.data("_golf_jss_log"))
171
+ jself._golf_css(i, "");
172
+ jself.data("_golf_jss_log", {});
173
+ jself.data("_golf_jss_spc", {});
174
+ jself._golf_css(jself.data("_golf_css_log"));
175
+ }
176
+ );
177
+
178
+ $.each(parsed, function() {
179
+ var selectors = this.selector;
180
+ var attrs = this.attributes;
181
+
182
+ $.each(
183
+ selectors.split(/ *, */),
184
+ function(k, selector) {
185
+ var parser = /([a-z][a-z0-9]*|\*)|(#[_a-z][-_a-z0-9]*)|(\.[_a-z][-_a-z0-9]*|\[[^\]]+\])|(:[-a-z]+)|( *[>+~] *| +)/gi;
186
+ var pseudo = /^:(first-(line|letter)|before|after)$/;
187
+ var base=32,TAG=1,ID=2,ATTR=3,PSEUDO=4,COMBI=5,weight=0,m;
188
+
189
+ parser.lastIndex = 0;
190
+
191
+ while (m = parser.exec(selector)) {
192
+ if (m[ID]) {
193
+ weight += 32*32;
194
+ } else if (m[ATTR]) {
195
+ weight += 32;
196
+ } else if (m[PSEUDO]) {
197
+ weight += (m[PSEUDO].match(pseudo) ? 1 : 10);
198
+ } else if (m[TAG]) {
199
+ weight += 1;
200
+ }
201
+ }
202
+
203
+ $local(selector, cpdom).each(
204
+ function() {
205
+ var jself=$(this), log, i;
206
+
207
+ if (!jself.data("_golf_jss_log"))
208
+ jself.data("_golf_jss_log", {});
209
+ if (!jself.data("_golf_jss_spc"))
210
+ jself.data("_golf_jss_spc", {});
211
+
212
+ log = jself.data("_golf_jss_spc");
213
+ for (i in attrs) {
214
+ if (log[i] > weight)
215
+ delete attrs[i];
216
+ else
217
+ log[i] = weight;
218
+ }
219
+
220
+ $.extend(jself.data("_golf_jss_spc"), log);
221
+ $.extend(jself.data("_golf_jss_log"), attrs);
222
+
223
+ jself._golf_css(attrs);
224
+
225
+ log = jself.data("_golf_css_log");
226
+ for (i in log)
227
+ jself._golf_css(jself.data("_golf_css_log"));
228
+ }
229
+ );
230
+ }
231
+ );
232
+ });
233
+ },
234
+
235
+ // ---
236
+ // Ultra lightweight CSS parser, only works with 100% valid css
237
+ // files, no support for hacks etc.
238
+ // ---
239
+
240
+ sanitize: function(content) {
241
+ if(!content) return '';
242
+ var c = content.replace(/[\n\r]/gi,''); // remove newlines
243
+ c = c.replace(/\/\*.+?\*\//gi,''); // remove comments
244
+ return c;
245
+ },
246
+
247
+ parse: function(content) {
248
+ var c = this.sanitize(content);
249
+ var tree = []; // this is the css tree that is built up
250
+ c = c.match(/.+?\{.+?\}/gi); // seperate out selectors
251
+ if(!c) return [];
252
+ for(var i=0;i<c.length;i++) // loop through selectors & parse attributes
253
+ if(c[i])
254
+ tree.push( {
255
+ selector: this.parseSelectorName(c[i]),
256
+ attributes: this.parseAttributes(c[i])
257
+ } );
258
+ return tree;
259
+ },
260
+
261
+ parseSelectorName: function(content) { // extract the selector
262
+ return $.trim(content.match(/^.+?\{/)[0].replace('{',''));
263
+ },
264
+
265
+ parseAttributes: function(content) {
266
+ var attributes = {};
267
+ c = content.match(/\{.+?\}/)[0].replace(/[\{\}]/g,'').split(';').slice(0,-1);
268
+ for(var i=0;i<c.length; i++){
269
+ if(c[i]){
270
+ c[i] = c[i].split(':');
271
+ attributes[$.trim(c[i][0])] = $.trim(c[i][1]);
272
+ };
273
+ };
274
+ return attributes;
275
+ }
276
+
277
+ };
278
+
279
+ function makePkg(pkg, obj) {
280
+ if (!obj)
281
+ obj = Component;
282
+
283
+ if (!pkg || !pkg.length)
284
+ return obj;
285
+
286
+ var r = /^([^.]+)((\.)([^.]+.*))?$/;
287
+ var m = pkg.match(r);
288
+
289
+ if (!m)
290
+ throw "bad package: '"+pkg+"'";
291
+
292
+ if (!obj[m[1]])
293
+ obj[m[1]] = {};
294
+
295
+ return makePkg(m[4], obj[m[1]]);
296
+ }
297
+
298
+ function onLoad() {
299
+ if (serverside)
300
+ $("noscript").remove();
301
+
302
+ if (urlHash && !location.hash)
303
+ window.location.replace(servletUrl + "#" + urlHash);
304
+
305
+ $.address.change(function(evnt) {
306
+ onHistoryChange(evnt.value);
307
+ });
308
+ }
309
+
310
+ var onHistoryChange = (function() {
311
+ var lastHash = "";
312
+ return function(hash, b) {
313
+
314
+ d("history change => '"+hash+"'");
315
+ if (hash && hash == "/")
316
+ return $.golf.location(String($.golf.defaultRoute));
317
+
318
+ if (hash && hash.charAt(0) != "/")
319
+ return $.golf.location("/"+hash);
320
+
321
+ if (hash && hash != lastHash) {
322
+ lastHash = hash;
323
+ hash = hash.replace(/^\/+/, "/");
324
+ $.golf.location.hash = String(hash+"/").replace(/\/+$/, "/");
325
+ window.location.hash = "#"+$.golf.location.hash;
326
+ $.golf.route(hash, b);
327
+ }
328
+ };
329
+ })();
330
+
331
+ function prepare(p) {
332
+ $("*", p).add([ p ]).each(function() {
333
+ // FIXME: verify whether 'this' is jQuery obj or DOM elem?
334
+ var jself = $(this);
335
+ var eself = jself.get()[0];
336
+
337
+ if (jself.data("_golf_prepared"))
338
+ return;
339
+
340
+ jself.data("_golf_prepared", true);
341
+
342
+ // makes hrefs in links work in both client and proxy modes
343
+ if (eself.tagName === "A")
344
+ jself.href(eself.href);
345
+ });
346
+ return p;
347
+ }
348
+
349
+ function componentConstructor(name) {
350
+ var result = function() {
351
+ var argv = Array.prototype.slice.call(arguments);
352
+ var obj = this;
353
+ var cmp = $.golf.components[name];
354
+
355
+ d("Instantiating component '"+$.golf.components[name].name+"'");
356
+
357
+ // $fake: the component-localized jQuery
358
+
359
+ var $fake = function( selector, context ) {
360
+ var isHtml = /^[^<]*(<(.|\s)+>)[^>]*$/;
361
+
362
+ // if it's a function then immediately execute it (DOM loading
363
+ // is guaranteed to be complete by the time this runs)
364
+ if ($.isFunction(selector)) {
365
+ selector();
366
+ return;
367
+ }
368
+
369
+ // if it's not a css selector then passthru to jQ
370
+ if (typeof selector != "string" || selector.match(isHtml))
371
+ return new $(selector);
372
+
373
+ // it's a css selector
374
+ if (context != null)
375
+ return $(context)
376
+ .find(selector)
377
+ .not($(".component *", obj._dom).get())
378
+ .not($("* .component", obj._dom).get());
379
+ else
380
+ return $(obj._dom)
381
+ .find("*")
382
+ .andSelf()
383
+ .filter(selector)
384
+ .not($(".component *", obj._dom).get())
385
+ .not($("* .component", obj._dom).get());
386
+ };
387
+
388
+ $.extend($fake, $);
389
+ $fake.prototype = $fake.fn;
390
+
391
+ $fake.component = cmp;
392
+
393
+ $fake.require = $.golf.require($fake);
394
+
395
+ if (cmp) {
396
+ obj._dom = cmp.dom.clone();
397
+ obj._dom.data("_golf_constructing", true);
398
+ obj.require = $fake.require;
399
+ checkForReservedClass(obj._dom.children().find("*"));
400
+ doCall(obj, $fake, $fake, argv, cmp.js, Debug(name));
401
+ obj._dom.removeData("_golf_constructing");
402
+ jss.mark(obj._dom.children().eq(0));
403
+ jss.doit(obj._dom.children().eq(0));
404
+ } else {
405
+ throw "can't find component: "+name;
406
+ }
407
+ };
408
+ result.prototype = new Component();
409
+ return result;
410
+ }
411
+
412
+ // globals
413
+
414
+ window.d = Debug("GOLF");
415
+ window.Debug = Debug;
416
+ window.Component = Component;
417
+
418
+ // serverside mods to jQuery
419
+
420
+ if (serverside) {
421
+
422
+ if (!window.forcebot) {
423
+ $.fx.off = true;
424
+
425
+ $.fn.fadeIn = $.fn.slideDown = function(speed, callback) {
426
+ return $.fn.show.call(this, 0, callback);
427
+ };
428
+
429
+ $.fn.fadeOut = $.fn.slideUp = function(speed, callback) {
430
+ return $.fn.hide.call(this, 0, callback);
431
+ };
432
+
433
+ // this is problematic because the js css manipulations are not carried
434
+ // over in proxy mode; needs to be in a style tag maybe
435
+ //(function(fadeTo) {
436
+ // jQuery.fn.fadeTo = function(speed, opacity, callback) {
437
+ // return fadeTo.call(this, 0, opacity, callback);
438
+ // };
439
+ //})(jQuery.fn.fadeTo);
440
+
441
+ $.fn.slideToggle = function(speed, callback) {
442
+ return $.fn.toggle.call(this, 0, callback);
443
+ };
444
+
445
+ $.fn.show = (function(show) {
446
+ return function(speed, callback) {
447
+ return show.call(this, 0, callback);
448
+ };
449
+ })($.fn.show);
450
+
451
+ $.fn.hide = (function(hide) {
452
+ return function(speed, callback) {
453
+ return hide.call(this, 0, callback);
454
+ };
455
+ })($.fn.hide);
456
+
457
+ $.fn.bind = (function(bind) {
458
+ var lastId = 0;
459
+ return function(name, fn) {
460
+ var jself = $(this);
461
+ var _href = jself.attr("href");
462
+ var _golfid = jself.attr("golfid");
463
+ if (name == "click") {
464
+ if (!_golfid) {
465
+ ++lastId;
466
+ jself.attr("golfid", lastId);
467
+ }
468
+ if (_href) {
469
+ jself.data("_golf_oldfn", fn);
470
+
471
+ if (_href && _href.charAt(0) != "#")
472
+ jself.data("_golf_oldhref",
473
+ "/"+_href.replace(/^(http:\/\/)?([^\/]\/?)*\/\//g, ""));
474
+ else if (jself.attr("href"))
475
+ jself.data("_golf_oldhref", _href.replace(/^#/, ""));
476
+
477
+ jself.attr({
478
+ rel: "nofollow",
479
+ href: "?target="+lastId+"&event=onclick"
480
+ });
481
+ fn = function() {
482
+ var argv = Array.prototype.slice.call(arguments);
483
+ if ($(this).data("_golf_oldfn").apply(jss, argv) !== false) {
484
+ $(this).attr("href", servletUrl+$(this).data("_golf_oldhref"));
485
+ $.golf.location($(this).data("_golf_oldhref"));
486
+ }
487
+ };
488
+ } else {
489
+ var a = "<a rel='nofollow' href='?target="+lastId+
490
+ "&amp;event=onclick'></a>";
491
+ jself.wrap(a);
492
+ jself._golf_addClass("golfproxylink");
493
+ }
494
+ } else if (name == "submit") {
495
+ if (!_golfid) {
496
+ ++lastId;
497
+ jself.attr("golfid", lastId);
498
+ jself.append(
499
+ "<input type='hidden' name='event' value='onsubmit'/>");
500
+ jself.append(
501
+ "<input type='hidden' name='target' value='"+lastId+"'/>");
502
+ if (!$.golf.events[lastId])
503
+ $.golf.events[lastId] = [];
504
+ }
505
+ $.golf.events[jself.attr("golfid")].push(fn);
506
+ }
507
+ return bind.call(jself, name, fn);
508
+ };
509
+ })($.fn.bind);
510
+
511
+ $.fn.trigger = (function(trigger) {
512
+ return function(type, data) {
513
+ var jself = $(this);
514
+ // FIXME: this is here because hunit stops firing js submit events
515
+ if (type == "submit") {
516
+ var tmp = $.golf.events[jself.attr("golfid")];
517
+ return $.each(tmp, function(){
518
+ this.call(jself, type, data);
519
+ });
520
+ } else {
521
+ return trigger.call($(this), type, data);
522
+ }
523
+ };
524
+ })($.fn.trigger);
525
+ }
526
+
527
+ $.fn.val = (function(val) {
528
+ return function(newVal) {
529
+ if (arguments.length == 0)
530
+ return $.trim(val.call($(this)));
531
+ else
532
+ return val.call($(this), newVal);
533
+ };
534
+ })($.fn.val);
535
+
536
+ $.ajax = (function(ajax) {
537
+ return function(options) {
538
+ options.async = false;
539
+ return ajax(options);
540
+ };
541
+ })($.ajax);
542
+
543
+ } else {
544
+
545
+ $.fn.bind = (function(bind) {
546
+ var lastId = 0;
547
+ return function(name, fn) {
548
+ var jself = $(this);
549
+ if (name == "submit") {
550
+ var oldfn = fn;
551
+ fn = function() {
552
+ var argv = Array.prototype.slice.call(arguments);
553
+ try {
554
+ oldfn.apply(this, argv);
555
+ } catch(e) {
556
+ $.golf.errorPage("Oops!", "<code>"+e.toString()+"</code>");
557
+ }
558
+ return false;
559
+ };
560
+ }
561
+ return bind.call(jself, name, fn);
562
+ };
563
+ })($.fn.bind);
564
+
565
+ }
566
+
567
+ // install overrides on jQ DOM manipulation methods to accomodate components
568
+
569
+ (function() {
570
+
571
+ $.each(
572
+ [
573
+ "append",
574
+ "prepend",
575
+ "after",
576
+ "before",
577
+ "replaceWith"
578
+ ],
579
+ function(k,v) {
580
+ $.fn["_golf_"+v] = $.fn[v];
581
+ $.fn[v] = function(a) {
582
+ var e = $(a instanceof Component ? a._dom : a);
583
+ if (! (a instanceof Component))
584
+ checkForReservedClass(e);
585
+
586
+ prepare(e);
587
+ var ret = $.fn["_golf_"+v].call($(this), e);
588
+ $(e.parent()).each(function() {
589
+ $(this).removeData("_golf_prepared");
590
+ });
591
+ jss.mark(this);
592
+ if (a instanceof Component && a.onAppend)
593
+ a.onAppend();
594
+ return $(this);
595
+ };
596
+ }
597
+ );
598
+
599
+ $.fn._golf_remove = $.fn.remove;
600
+ $.fn.remove = function() {
601
+ $("*", this).add([this]).each(function() {
602
+ if ($(this).attr("golfid"))
603
+ $.golf.events[$(this).attr("golfid")] = [];
604
+ });
605
+ return $.fn._golf_remove.call(this);
606
+ };
607
+
608
+ $.each(
609
+ [
610
+ "addClass",
611
+ "removeClass",
612
+ "toggleClass"
613
+ ],
614
+ function(k,v) {
615
+ $.fn["_golf_"+v] = $.fn[v];
616
+ $.fn[v] = function() {
617
+ // FIXME need to cover the case of $(thing).removeClass() with no
618
+ // parameters and when `thing` _has_ a reserved class already
619
+ var putback = {};
620
+ var self = this;
621
+ if (arguments.length) {
622
+ checkForReservedClass(arguments[0]);
623
+ } else if (v == "removeClass") {
624
+ $.map(checkForReservedClass(this, true), function(c) {
625
+ putback[c] = $.map(self, function(e) {
626
+ return $(e).hasClass(c) ? e : null;
627
+ });
628
+ });
629
+ }
630
+ var ret = $.fn["_golf_"+v].apply(this, arguments);
631
+ for (var i in putback)
632
+ for (var j in putback[i])
633
+ $(putback[i][j])._golf_addClass(i);
634
+ jss.mark(this);
635
+ return ret;
636
+ };
637
+ }
638
+ );
639
+
640
+ $.fn._golf_css = $.fn.css;
641
+ $.fn.css = function() {
642
+ var log = this.data("_golf_css_log") || {};
643
+
644
+ if (arguments.length > 0) {
645
+ if (typeof arguments[0] == "string") {
646
+ if (arguments.length == 1)
647
+ return this._golf_css(arguments[0]);
648
+ else
649
+ log[arguments[0]] = arguments[1];
650
+ } else {
651
+ $.extend(log, arguments[0]);
652
+ }
653
+
654
+ for (var i in log)
655
+ if (log[i] == "")
656
+ delete log[i];
657
+
658
+ this.data("_golf_css_log", log);
659
+ var ret = this._golf_css(arguments[0], arguments[1]);
660
+ jss.mark(this);
661
+ return ret;
662
+ }
663
+ return this;
664
+ };
665
+
666
+ $.fn.href = (function() {
667
+ var uri2;
668
+ return function(uri) {
669
+ var uri1 = parseUri(uri);
670
+ var curHash = window.location.hash.replace(/^#/, "");
671
+ var anchor;
672
+
673
+ if (!uri2)
674
+ uri2 = parseUri(servletUrl);
675
+
676
+ if (uri1.protocol == uri2.protocol
677
+ && uri1.authority == uri2.authority
678
+ && uri1.directory.substr(0, uri2.directory.length)
679
+ == uri2.directory) {
680
+ if (uri1.queryKey.path) {
681
+ if (cloudfrontDomain.length)
682
+ uri = cloudfrontDomain[0]+uri.queryKey.path;
683
+ } else if (uri1.anchor) {
684
+ if (!uri1.anchor.match(/^\//)) {
685
+ anchor = (curHash ? curHash : "/") + uri1.anchor;
686
+ uri = "#"+anchor;
687
+ } else {
688
+ anchor = uri1.anchor;
689
+ }
690
+ if (serverside)
691
+ this.attr("href", servletUrl + anchor);
692
+ }
693
+ }
694
+ };
695
+ })();
696
+ })();
697
+
698
+ // main jQ golf object
699
+
700
+ $.golf = {
701
+
702
+ jssTimeout: 10,
703
+
704
+ controller: [],
705
+
706
+ defaultRoute: "/home/",
707
+
708
+ reservedClassChecking: true,
709
+
710
+ loaded: false,
711
+
712
+ events: [],
713
+
714
+ singleton: {},
715
+
716
+ toJson: toJson,
717
+
718
+ jss: function() {
719
+ var argv = Array.prototype.slice.call(arguments);
720
+ jss.doit.apply(jss, argv);
721
+ },
722
+
723
+ location: function(hash) {
724
+ if (!!hash)
725
+ $.address.value(hash);
726
+ else
727
+ return $.golf.location.hash;
728
+ },
729
+
730
+ htmlEncode: function(text) {
731
+ return text.replace(/&/g, "&amp;")
732
+ .replace(/</g, "&lt;")
733
+ .replace(/>/g, "&gt;")
734
+ .replace(/"/g, "&quot;");
735
+ },
736
+
737
+ addComponent: function(data, name) {
738
+ var orig = data;
739
+ var js =
740
+ data
741
+ .replace(/^(.|\n)*<script +type *= *("text\/golf"|'text\/golf')>/, "")
742
+ .replace(/<\/script>(.|\n)*$/, "");
743
+ var css =
744
+ data
745
+ .replace(/^(.|\n)*<style +type *= *("text\/golf"|'text\/golf')>/, "")
746
+ .replace(/<\/style>(.|\n)*$/, "");
747
+ var html = $("<div/>")._golf_append(
748
+ $(data)._golf_addClass("component")
749
+ ._golf_addClass(name.replace(".", "-"))
750
+ );
751
+ html.find("style,script").remove();
752
+ var cmp = {
753
+ "orig" : orig,
754
+ "name" : name,
755
+ "html" : html.html(),
756
+ "dom" : $(html.html()),
757
+ "css" : css,
758
+ "js" : js
759
+ };
760
+ var m, pkg;
761
+
762
+ $.golf.components[name] = cmp;
763
+
764
+ if (!(m = name.match(/^(.*)\.([^.]+)$/)))
765
+ m = [ "", "", name ];
766
+
767
+ pkg = makePkg(m[1]);
768
+ pkg[m[2]] = componentConstructor(name);
769
+ },
770
+
771
+ setupComponents: function() {
772
+ var cmp, name, i, m, scripts=[];
773
+
774
+ d("Setting up components now.");
775
+
776
+ d("Loading scripts/ directory...");
777
+ for (name in $.golf.scripts)
778
+ scripts.push(name);
779
+
780
+ // sort scripts by name
781
+ scripts = scripts.sort();
782
+
783
+ for (i=0, m=scripts.length; i<m; i++) {
784
+ d("Evaling '"+scripts[i]+"'...");
785
+ $.globalEval($.golf.scripts[scripts[i]].js);
786
+ }
787
+
788
+ d("Loading components/ directory...");
789
+ for (name in $.golf.components)
790
+ $.golf.addComponent($.golf.components[name].html, name);
791
+
792
+ if (!window.forcebot) {
793
+ d("Loading styles/ directory...");
794
+ $("head style").remove();
795
+ for (name in $.golf.styles)
796
+ $("head").append(
797
+ "<style type='text/css'>"+$.golf.styles[name].css+"</style>");
798
+ } else {
799
+ $("head style").remove();
800
+ }
801
+
802
+ d("Done loading directories.");
803
+ },
804
+
805
+ route: function(hash, b) {
806
+ var theHash, theRoute, theAction, i, x, pat, match;
807
+ if (!hash)
808
+ hash = String($.golf.defaultRoute+"/").replace(/\/+$/, "/");
809
+
810
+ theHash = hash;
811
+ theRoute = null;
812
+ theAction = null;
813
+
814
+ if (!b) b = $("body > div.golfbody").eq(0);
815
+ b.empty();
816
+
817
+ try {
818
+ if ($.golf.controller.length > 0) {
819
+ for (i=0; i<$.golf.controller.length && theAction===null; i++) {
820
+ theRoute = "^"+$.golf.controller[i].route+"$";
821
+ match = $.isFunction(theRoute) ? theRoute(theHash)
822
+ : theHash.match(new RegExp(theRoute));
823
+ if (match)
824
+ (theAction = $.golf.controller[i].action)(b, match);
825
+ }
826
+ if (theAction === null)
827
+ $.golf.errorPage("Not Found", "<span>There is no route "
828
+ +"matching <code>"+theHash+"</code>.</span>");
829
+ } else {
830
+ $.golf.errorPage("Hi there!", "<span>Your Golf web application "
831
+ +"server is up and running.</span>");
832
+ }
833
+ } catch (e) {
834
+ $(document).trigger({
835
+ type: "route_error",
836
+ message: e.toString()
837
+ });
838
+ $.golf.errorPage("Oops!", "<code>"+e.toString()+"</code>");
839
+ }
840
+ },
841
+
842
+ errorPage: function(type, desc) {
843
+ $.get("?path=app_error.html", function(data) {
844
+ $(".golfbody").empty().append(data);
845
+ $(".golfbody .type").text(type);
846
+ $(".golfbody .description").append(desc);
847
+ });
848
+ },
849
+
850
+ require: function($fake) {
851
+
852
+ return function(name, cache) {
853
+ var js, exports, target;
854
+
855
+ try {
856
+ if (!$.golf.plugins[name])
857
+ throw "not found";
858
+
859
+ js = $.golf.plugins[name].js;
860
+ exports = {};
861
+ target = this;
862
+
863
+ if (!$.golf.singleton[name])
864
+ $.golf.singleton[name] = {};
865
+
866
+ if (cache && cache[name]) {
867
+ d("require: loading '"+name+"' recursively from cache");
868
+ return cache[name];
869
+ }
870
+
871
+ if (!cache) {
872
+ cache = {};
873
+
874
+ $fake.require = (function(orig) {
875
+ return function(name) {
876
+ return orig(name, cache);
877
+ };
878
+ })($fake.require);
879
+ }
880
+
881
+ cache[name] = exports;
882
+
883
+ (function(jQuery,$,js,singleton) {
884
+ if (!singleton._init) {
885
+ d("require: loading '"+name+"'");
886
+ eval("exports._init = function($,jQuery,exports,singleton) { "+
887
+ js+"; "+
888
+ "return exports; "+
889
+ "}");
890
+ $.extend(true, singleton, exports);
891
+ delete exports._init;
892
+ } else {
893
+ d("require: loading '"+name+"' from cache");
894
+ }
895
+ singleton._init($,$,exports,singleton);
896
+ }).call(target,$fake,$fake,js,$.golf.singleton[name]);
897
+ } catch (x) {
898
+ throw "require: "+name+".js: "+x;
899
+ }
900
+
901
+ return exports;
902
+ };
903
+ }
904
+
905
+ };
906
+
907
+ // Static jQuery methods
908
+
909
+ $.Import = function(name) {
910
+ var ret="", obj, basename, dirname, i;
911
+
912
+ basename = name.replace(/^.*\./, "");
913
+ dirname = name.replace(/\.[^.]*$/, "");
914
+
915
+ if (basename == "*") {
916
+ obj = eval(dirname);
917
+ for (i in obj)
918
+ ret += "var "+i+" = "+dirname+"['"+i+"'];";
919
+ } else {
920
+ ret = "var "+basename+" = "+name+";";
921
+ }
922
+
923
+ return ret;
924
+ };
925
+
926
+ $.require = $.golf.require($);
927
+
928
+ $.golf.location.params = function(i) {
929
+ var p = String($.golf.location.hash).replace(/(^\/|\/$)/g,"").split("/");
930
+ if (i == null)
931
+ return p;
932
+ else
933
+ return p[(p.length + i) % p.length];
934
+ };
935
+
936
+ // jQuery onload handler
937
+
938
+ $(function() {
939
+ onLoad();
940
+ });
941
+
942
+ })(jQuery);