golf 0.0.1

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