golf 0.4.14 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/Gemfile.lock +3 -1
  2. data/golf.gemspec +1 -0
  3. data/lib/golf/compiler.rb +60 -21
  4. data/lib/golf/filter.rb +10 -0
  5. data/lib/golf/filters/dummy_filter.rb +11 -0
  6. data/lib/golf/version.rb +1 -1
  7. data/lib/golf.rb +2 -1
  8. data/test/reference_app/golfapp/components/HelloWorld/HelloWorld.html +13 -0
  9. data/test/reference_app/golfapp/components/golf/cart/Admin/Admin.html +13 -0
  10. data/test/reference_app/golfapp/components/golf/cart/Cart/Cart.html +16 -0
  11. data/test/reference_app/golfapp/components/golf/cart/Product/Product.html +21 -0
  12. data/test/reference_app/golfapp/components/golf/cart/ProductListing/ProductListing.html +19 -0
  13. data/test/reference_app/golfapp/components/golf/cart/Store/Store.html +18 -0
  14. data/test/reference_app/golfapp/components.js +1 -0
  15. data/test/reference_app/golfapp/controller.js +28 -0
  16. data/test/reference_app/golfapp/img/ Timer & Non-Stick.jpeg +0 -0
  17. data/test/reference_app/golfapp/img/134lines.jpeg +0 -0
  18. data/test/reference_app/golfapp/img/Q33 Sail Plan.jpeg +0 -0
  19. data/test/reference_app/golfapp/img/a/b/qwer +0 -0
  20. data/test/reference_app/golfapp/img/em> - Brushed Stainless Steel.jpeg +0 -0
  21. data/test/reference_app/golfapp/img/em> - White.jpeg +0 -0
  22. data/test/reference_app/golfapp/img/em> Broil CTO7100B.jpeg +0 -0
  23. data/test/reference_app/golfapp/img/em> Broiler - Stainless.jpeg +0 -0
  24. data/test/reference_app/golfapp/img/em> with Countdo.jpeg +0 -0
  25. data/test/reference_app/golfapp/img/em> with Element IQ.jpeg +0 -0
  26. data/test/reference_app/golfapp/img/em> with OneTouch ...jpeg +0 -0
  27. data/test/reference_app/golfapp/img/em> with Pizza.jpeg +0 -0
  28. data/test/reference_app/golfapp/img/em>-1.jpeg +0 -0
  29. data/test/reference_app/golfapp/img/em>-2.jpeg +0 -0
  30. data/test/reference_app/golfapp/img/em>-3.jpeg +0 -0
  31. data/test/reference_app/golfapp/img/em>-Black.jpeg +0 -0
  32. data/test/reference_app/golfapp/img/em>.jpeg +0 -0
  33. data/test/reference_app/golfapp/img/unnamed.jpeg +0 -0
  34. data/test/reference_app/golfapp/plugins/mylib.js +0 -0
  35. data/test/reference_app/golfapp/scripts/00-myscript.js +0 -0
  36. data/test/reference_app/golfapp/scripts/01-jquery.tmpl.js +484 -0
  37. data/test/reference_app/golfapp/styles/main.css +0 -0
  38. data/test/test_compiler.rb +87 -7
  39. metadata +47 -17
  40. data/test/twitter_compiled/Gemfile +0 -6
  41. data/test/twitter_compiled/config.ru +0 -7
  42. data/test/twitter_compiled/golfapp/app_error.html +0 -60
  43. data/test/twitter_compiled/golfapp/components/golf/twitter/Search/Search.html +0 -29
  44. data/test/twitter_compiled/golfapp/components/golf/twitter/Tweet/Tweet.html +0 -16
  45. data/test/twitter_compiled/golfapp/components.js +0 -1
  46. data/test/twitter_compiled/golfapp/controller.js +0 -9
  47. data/test/twitter_compiled/golfapp/index.html +0 -58
  48. data/test/twitter_compiled/golfapp/jquery.address.js +0 -439
  49. data/test/twitter_compiled/golfapp/jquery.golf.js +0 -942
  50. data/test/twitter_compiled/golfapp/jquery.js +0 -4376
  51. data/test/twitter_compiled/golfapp/plugins/twitter.js +0 -14
  52. data/test/twitter_compiled/golfapp/welcome2golf.html +0 -50
  53. /data/test/{twitter_compiled/golfapp/scripts/00-myscript.js → reference_app/golfapp/img/a/asdf} +0 -0
  54. /data/test/{twitter_compiled/golfapp/styles/main.css → reference_app/golfapp/img/a/b/c/zxcv} +0 -0
data/Gemfile.lock CHANGED
@@ -1,7 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- golf (0.4.13)
4
+ golf (0.4.14)
5
+ hpricot
5
6
  json
6
7
  rack
7
8
  thor
@@ -9,6 +10,7 @@ PATH
9
10
  GEM
10
11
  remote: http://rubygems.org/
11
12
  specs:
13
+ hpricot (0.8.4)
12
14
  json (1.5.1)
13
15
  rack (1.2.2)
14
16
  rack-test (0.5.7)
data/golf.gemspec CHANGED
@@ -15,6 +15,7 @@ Gem::Specification.new do |s|
15
15
  s.add_dependency('thor')
16
16
  s.add_dependency('json')
17
17
  s.add_dependency('rack')
18
+ s.add_dependency('hpricot')
18
19
 
19
20
  s.bindir = 'bin'
20
21
  s.executables = ['golf']
data/lib/golf/compiler.rb CHANGED
@@ -4,8 +4,10 @@ module Golf
4
4
 
5
5
  require 'find'
6
6
 
7
- def initialize(golfpath = ".")
8
- @golfpath = "#{golfpath}/golfapp"
7
+ attr_accessor :golfpath
8
+
9
+ def initialize(golfpath = '.')
10
+ self.golfpath = "#{golfpath}/golfapp"
9
11
  puts "golf #{Golf::VERSION}: starting compiler in #{@golfpath}..."
10
12
  puts "golf #{Golf::VERSION}: is valid golfapp?: #{Golf::Compiler.valid?(@golfpath)}"
11
13
  end
@@ -63,23 +65,25 @@ module Golf
63
65
  results = {}
64
66
  mypath = dir.split('').last == "/" ? dir : dir+"/"
65
67
  myroot = @golfpath.split('').last == "/" ? @golfpath : @golfpath+"/"
66
- Find.find(mypath) do |path|
67
- e = path.slice(mypath.length, path.length-mypath.length)
68
- r = path.slice(myroot.length, path.length-myroot.length)
69
- f = URI.escape(e)
70
- g = File.basename(e)
71
- h = File.dirname(r) == "." ? [] : File.dirname(r).split("/")
72
- if FileTest.directory?(path)
73
- next
74
- else
75
- r2 = results
76
- h.each { |i|
77
- if ! r2[i]
78
- r2[i] = {}
79
- end
80
- r2 = r2[i]
81
- }
82
- r2[g] = f
68
+ if File.exists?(mypath)
69
+ Find.find(mypath) do |path|
70
+ e = path.slice(mypath.length, path.length-mypath.length)
71
+ r = path.slice(myroot.length, path.length-myroot.length)
72
+ f = URI.escape(e)
73
+ g = File.basename(e)
74
+ h = File.dirname(r) == "." ? [] : File.dirname(r).split("/")
75
+ if FileTest.directory?(path)
76
+ next
77
+ else
78
+ r2 = results
79
+ h.each { |i|
80
+ if ! r2[i]
81
+ r2[i] = {}
82
+ end
83
+ r2 = r2[i]
84
+ }
85
+ r2[g] = f
86
+ end
83
87
  end
84
88
  end
85
89
  results
@@ -109,13 +113,48 @@ module Golf
109
113
  else
110
114
  name = path.split('/').last.gsub(".#{type}",'')
111
115
  end
112
- data = File.read(path)
116
+ data = filtered_read(path)
113
117
  results = results.merge({ name => { "name" => name, "#{type}" => data }})
114
118
  end
115
119
  end
116
120
  JSON.dump(results)
117
121
  end
118
-
122
+
123
+ def filtered_read(path)
124
+ data = File.read(path)
125
+ if path.split('.').last == 'html'
126
+ data = filter_by_block(data)
127
+ end
128
+ data = filter_by_extension(data)
129
+ data
130
+ end
131
+
132
+ def filter_by_block(data)
133
+ doc = Hpricot(data)
134
+ if doc
135
+ unfiltered_elements = doc.search('//*[@filter]')
136
+ if unfiltered_elements.count == 0
137
+ data
138
+ else
139
+ unfiltered_elements.each do |element|
140
+ filter = element.attributes["filter"]
141
+ filter_name = filter.capitalize.to_sym
142
+ if Golf::Filter.constants.include?(filter_name)
143
+ element.raw_string = Golf::Filter.const_get(filter_name).transform(element.to_s)
144
+ element.remove_attribute("filter")
145
+ end
146
+ end
147
+ return doc.to_s
148
+ end
149
+ else
150
+ data
151
+ end
152
+ end
153
+
154
+ def filter_by_extension(data)
155
+ data
156
+ end
157
+
119
158
  def package_name(path)
120
159
  if path.include?('golfapp/components')
121
160
  path.match(/golfapp\/components\/(.*)/)
@@ -0,0 +1,10 @@
1
+ module Golf
2
+ module Filter
3
+ end
4
+ end
5
+
6
+ Dir["#{File.expand_path('../../../lib/golf/filters', __FILE__)}/*.rb"].each do |path|
7
+ puts "golf #{Golf::VERSION}: loading filter #{path}"
8
+ require path
9
+ end
10
+
@@ -0,0 +1,11 @@
1
+ module Golf
2
+ module Filter
3
+ class Dummy
4
+ def self.transform(data)
5
+ data
6
+ end
7
+ end
8
+ end
9
+ end
10
+
11
+
data/lib/golf/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Golf
2
- VERSION = "0.4.14"
2
+ VERSION = "0.5.0"
3
3
  end
data/lib/golf.rb CHANGED
@@ -1,7 +1,8 @@
1
1
  require "json"
2
+ require "hpricot"
2
3
  require "golf/compiler"
3
4
  require "golf/rack"
4
5
  require "golf/cli"
5
6
  require "golf/version"
6
-
7
+ require "golf/filter"
7
8
 
@@ -0,0 +1,13 @@
1
+ <div>
2
+ <style type="text/golf">
3
+ div.container {
4
+ border: 1px solid red;
5
+ }
6
+ </style>
7
+ <script filter="dummy" type="text/golf">
8
+ function() {
9
+ $(".container").append("<h1>Hello, world!</h1>");
10
+ }
11
+ </script>
12
+ <div class="container"></div>
13
+ </div>
@@ -0,0 +1,13 @@
1
+ <div>
2
+ <style type="text/golf">
3
+ div.container {
4
+ border: 1px solid red;
5
+ }
6
+ </style>
7
+ <script type="text/golf">
8
+ function() {
9
+ $(".container").append("<h1>Hello, woasdrld!</h1>");
10
+ }
11
+ </script>
12
+ <div class="container"></div>
13
+ </div>
@@ -0,0 +1,16 @@
1
+ <div>
2
+ <style type="text/golf">
3
+ div.cart {
4
+ border: 1px solid blue;
5
+ }
6
+ </style>
7
+ <script type="text/golf">
8
+ function() {
9
+ this.add_product = function(product) {
10
+ $(".cart ul").append("<li>" + product +"</li>");
11
+ };
12
+ }
13
+ </script>
14
+ <h3>Your Cart</h3>
15
+ <div class="cart"><ul></ul></div>
16
+ </div>
@@ -0,0 +1,21 @@
1
+ <div>
2
+ <style type="text/golf">
3
+ </style>
4
+ <script type="text/golf">
5
+ function(product) {
6
+ $('li span').text(product.name);
7
+ $('li').attr('id', product.id);
8
+
9
+ this.onAppend = function() {
10
+ d("got hereeeeee");
11
+ $('li .add_to_cart').click(function(e){
12
+ d("click!");
13
+ var id = $(e.target).parent().attr('id');
14
+ window.cart.add_product(id);
15
+ return false;
16
+ });
17
+ };
18
+ }
19
+ </script>
20
+ <li><span></span><button class="add_to_cart">Add</button></li>
21
+ </div>
@@ -0,0 +1,19 @@
1
+ <div>
2
+ <style type="text/golf">
3
+ </style>
4
+ <script type="text/golf">
5
+ function() {
6
+ var draw_products = function(data){
7
+ $.each(data, function(index, item){
8
+ $('.product_listing ul')
9
+ .append(new Component.golf.cart.Product(item.product));
10
+ })
11
+ }
12
+ $.getJSON('/products.json', draw_products);
13
+ }
14
+ </script>
15
+ <div class="product_listing">
16
+ <ul>
17
+ </ul>
18
+ </div>
19
+ </div>
@@ -0,0 +1,18 @@
1
+ <div>
2
+ <style type="text/golf">
3
+ div.container {
4
+ border: 1px solid red;
5
+ }
6
+ </style>
7
+ <script type="text/golf">
8
+ function() {
9
+ window.cart = new Component.golf.cart.Cart();
10
+ $(".container").append(new Component.golf.cart.ProductListing());
11
+ $(".container").append(window.cart);
12
+ }
13
+ </script>
14
+ <div class="container">
15
+ <h1>Welcome to the Store</h1>
16
+ <a href="#/blah/">Click here for a nice NOT FOUND message!</a>
17
+ </div>
18
+ </div>
@@ -0,0 +1 @@
1
+ jQuery.golf.components={"golf.cart.Store":{"html":"<div>\n <style type=\"text/golf\">\n div.container {\n border: 1px solid red;\n }\n </style>\n <script type=\"text/golf\">\n function() {\n window.cart = new Component.golf.cart.Cart();\n $(\".container\").append(new Component.golf.cart.ProductListing());\n $(\".container\").append(window.cart);\n }\n </script>\n <div class=\"container\">\n <h1>Welcome to the Store</h1>\n <a href=\"#/blah/\">Click here for a nice NOT FOUND message!</a>\n </div>\n</div>\n","name":"golf.cart.Store"},"golf.cart.ProductListing":{"html":"<div>\n <style type=\"text/golf\">\n </style>\n <script type=\"text/golf\">\n function() {\n var draw_products = function(data){\n $.each(data, function(index, item){\n $('.product_listing ul')\n .append(new Component.golf.cart.Product(item.product));\n })\n }\n $.getJSON('/products.json', draw_products);\n }\n </script>\n <div class=\"product_listing\">\n <ul>\n </ul>\n </div>\n</div>\n","name":"golf.cart.ProductListing"},"HelloWorld":{"html":"<div>\n <style type=\"text/golf\">\n div.container {\n border: 1px solid red;\n }\n </style>\n <script type=\"text/golf\">\n function() {\n $(\".container\").append(\"<h1>Hello, world!</h1>\");\n }\n </script>\n <div class=\"container\"></div>\n</div>\n","name":"HelloWorld"},"golf.cart.Cart":{"html":"<div>\n <style type=\"text/golf\">\n div.cart {\n border: 1px solid blue;\n }\n </style>\n <script type=\"text/golf\">\n function() {\n this.add_product = function(product) {\n $(\".cart ul\").append(\"<li>\" + product +\"</li>\");\n };\n }\n </script>\n <h3>Your Cart</h3>\n <div class=\"cart\"><ul></ul></div>\n</div>\n","name":"golf.cart.Cart"},"golf.cart.Product":{"html":"<div>\n <style type=\"text/golf\">\n </style>\n <script type=\"text/golf\">\n function(product) {\n $('li span').text(product.name);\n $('li').attr('id', product.id);\n\n this.onAppend = function() {\n d(\"got hereeeeee\");\n $('li .add_to_cart').click(function(e){\n d(\"click!\");\n var id = $(e.target).parent().attr('id');\n window.cart.add_product(id);\n return false;\n });\n };\n }\n </script>\n <li><span></span><button class=\"add_to_cart\">Add</button></li>\n</div>\n","name":"golf.cart.Product"},"golf.cart.Admin":{"html":"<div>\n <style type=\"text/golf\">\n div.container {\n border: 1px solid red;\n }\n </style>\n <script type=\"text/golf\">\n function() {\n $(\".container\").append(\"<h1>Hello, woasdrld!</h1>\");\n }\n </script>\n <div class=\"container\"></div>\n</div>\n","name":"golf.cart.Admin"}};;jQuery.golf.res={"plugins":{"mylib.js":"plugins/mylib.js"},"components":{"HelloWorld":{"HelloWorld.html":"components/HelloWorld/HelloWorld.html"},"golf":{"cart":{"ProductListing":{"ProductListing.html":"components/golf/cart/ProductListing/ProductListing.html"},"Cart":{"Cart.html":"components/golf/cart/Cart/Cart.html"},"Store":{"Store.html":"components/golf/cart/Store/Store.html"},"Product":{"Product.html":"components/golf/cart/Product/Product.html"},"Admin":{"Admin.html":"components/golf/cart/Admin/Admin.html"}}}},"img":{"em> with OneTouch ...jpeg":"img/em%3E%20with%20OneTouch%20...jpeg","a":{"b":{"qwer":"img/a/b/qwer","c":{"zxcv":"img/a/b/c/zxcv"}},"asdf":"img/a/asdf"},"unnamed.jpeg":"img/unnamed.jpeg","em>.jpeg":"img/em%3E.jpeg","em> Broil CTO7100B.jpeg":"img/em%3E%20Broil%20CTO7100B.jpeg","em>-3.jpeg":"img/em%3E-3.jpeg","em>-2.jpeg":"img/em%3E-2.jpeg","em> with Countdo.jpeg":"img/em%3E%20with%20Countdo.jpeg","Q33 Sail Plan.jpeg":"img/Q33%20Sail%20Plan.jpeg","em> with Element IQ.jpeg":"img/em%3E%20with%20Element%20IQ.jpeg"," Timer & Non-Stick.jpeg":"img/%20Timer%20&%20Non-Stick.jpeg","em>-Black.jpeg":"img/em%3E-Black.jpeg","em> with Pizza.jpeg":"img/em%3E%20with%20Pizza.jpeg","em> Broiler - Stainless.jpeg":"img/em%3E%20Broiler%20-%20Stainless.jpeg","em> - Brushed Stainless Steel.jpeg":"img/em%3E%20-%20Brushed%20Stainless%20Steel.jpeg","134lines.jpeg":"img/134lines.jpeg","em>-1.jpeg":"img/em%3E-1.jpeg","em> - White.jpeg":"img/em%3E%20-%20White.jpeg"},"styles":{"main.css":"styles/main.css"},"controller.js":"controller.js","scripts":{"00-myscript.js":"scripts/00-myscript.js","01-jquery.tmpl.js":"scripts/01-jquery.tmpl.js"}};;jQuery.golf.plugins={"mylib":{"name":"mylib","js":""}};;jQuery.golf.scripts={"00-myscript":{"name":"00-myscript","js":""},"01-jquery.tmpl":{"name":"01-jquery.tmpl","js":"/*!\n * jQuery Templates Plugin 1.0.0pre\n * http://github.com/jquery/jquery-tmpl\n * Requires jQuery 1.4.2\n *\n * Copyright Software Freedom Conservancy, Inc.\n * Dual licensed under the MIT or GPL Version 2 licenses.\n * http://jquery.org/license\n */\n(function( jQuery, undefined ){\n\tvar oldManip = jQuery.fn.domManip, tmplItmAtt = \"_tmplitem\", htmlExpr = /^[^<]*(<[\\w\\W]+>)[^>]*$|\\{\\{\\! /,\n\t\tnewTmplItems = {}, wrappedItems = {}, appendToTmplItems, topTmplItem = { key: 0, data: {} }, itemKey = 0, cloneIndex = 0, stack = [];\n\n\tfunction newTmplItem( options, parentItem, fn, data ) {\n\t\t// Returns a template item data structure for a new rendered instance of a template (a 'template item').\n\t\t// The content field is a hierarchical array of strings and nested items (to be\n\t\t// removed and replaced by nodes field of dom elements, once inserted in DOM).\n\t\tvar newItem = {\n\t\t\tdata: data || (data === 0 || data === false) ? data : (parentItem ? parentItem.data : {}),\n\t\t\t_wrap: parentItem ? parentItem._wrap : null,\n\t\t\ttmpl: null,\n\t\t\tparent: parentItem || null,\n\t\t\tnodes: [],\n\t\t\tcalls: tiCalls,\n\t\t\tnest: tiNest,\n\t\t\twrap: tiWrap,\n\t\t\thtml: tiHtml,\n\t\t\tupdate: tiUpdate\n\t\t};\n\t\tif ( options ) {\n\t\t\tjQuery.extend( newItem, options, { nodes: [], parent: parentItem });\n\t\t}\n\t\tif ( fn ) {\n\t\t\t// Build the hierarchical content to be used during insertion into DOM\n\t\t\tnewItem.tmpl = fn;\n\t\t\tnewItem._ctnt = newItem._ctnt || newItem.tmpl( jQuery, newItem );\n\t\t\tnewItem.key = ++itemKey;\n\t\t\t// Keep track of new template item, until it is stored as jQuery Data on DOM element\n\t\t\t(stack.length ? wrappedItems : newTmplItems)[itemKey] = newItem;\n\t\t}\n\t\treturn newItem;\n\t}\n\n\t// Override appendTo etc., in order to provide support for targeting multiple elements. (This code would disappear if integrated in jquery core).\n\tjQuery.each({\n\t\tappendTo: \"append\",\n\t\tprependTo: \"prepend\",\n\t\tinsertBefore: \"before\",\n\t\tinsertAfter: \"after\",\n\t\treplaceAll: \"replaceWith\"\n\t}, function( name, original ) {\n\t\tjQuery.fn[ name ] = function( selector ) {\n\t\t\tvar ret = [], insert = jQuery( selector ), elems, i, l, tmplItems,\n\t\t\t\tparent = this.length === 1 && this[0].parentNode;\n\n\t\t\tappendToTmplItems = newTmplItems || {};\n\t\t\tif ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {\n\t\t\t\tinsert[ original ]( this[0] );\n\t\t\t\tret = this;\n\t\t\t} else {\n\t\t\t\tfor ( i = 0, l = insert.length; i < l; i++ ) {\n\t\t\t\t\tcloneIndex = i;\n\t\t\t\t\telems = (i > 0 ? this.clone(true) : this).get();\n\t\t\t\t\tjQuery( insert[i] )[ original ]( elems );\n\t\t\t\t\tret = ret.concat( elems );\n\t\t\t\t}\n\t\t\t\tcloneIndex = 0;\n\t\t\t\tret = this.pushStack( ret, name, insert.selector );\n\t\t\t}\n\t\t\ttmplItems = appendToTmplItems;\n\t\t\tappendToTmplItems = null;\n\t\t\tjQuery.tmpl.complete( tmplItems );\n\t\t\treturn ret;\n\t\t};\n\t});\n\n\tjQuery.fn.extend({\n\t\t// Use first wrapped element as template markup.\n\t\t// Return wrapped set of template items, obtained by rendering template against data.\n\t\ttmpl: function( data, options, parentItem ) {\n\t\t\treturn jQuery.tmpl( this[0], data, options, parentItem );\n\t\t},\n\n\t\t// Find which rendered template item the first wrapped DOM element belongs to\n\t\ttmplItem: function() {\n\t\t\treturn jQuery.tmplItem( this[0] );\n\t\t},\n\n\t\t// Consider the first wrapped element as a template declaration, and get the compiled template or store it as a named template.\n\t\ttemplate: function( name ) {\n\t\t\treturn jQuery.template( name, this[0] );\n\t\t},\n\n\t\tdomManip: function( args, table, callback, options ) {\n\t\t\tif ( args[0] && jQuery.isArray( args[0] )) {\n\t\t\t\tvar dmArgs = jQuery.makeArray( arguments ), elems = args[0], elemsLength = elems.length, i = 0, tmplItem;\n\t\t\t\twhile ( i < elemsLength && !(tmplItem = jQuery.data( elems[i++], \"tmplItem\" ))) {}\n\t\t\t\tif ( tmplItem && cloneIndex ) {\n\t\t\t\t\tdmArgs[2] = function( fragClone ) {\n\t\t\t\t\t\t// Handler called by oldManip when rendered template has been inserted into DOM.\n\t\t\t\t\t\tjQuery.tmpl.afterManip( this, fragClone, callback );\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\toldManip.apply( this, dmArgs );\n\t\t\t} else {\n\t\t\t\toldManip.apply( this, arguments );\n\t\t\t}\n\t\t\tcloneIndex = 0;\n\t\t\tif ( !appendToTmplItems ) {\n\t\t\t\tjQuery.tmpl.complete( newTmplItems );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t});\n\n\tjQuery.extend({\n\t\t// Return wrapped set of template items, obtained by rendering template against data.\n\t\ttmpl: function( tmpl, data, options, parentItem ) {\n\t\t\tvar ret, topLevel = !parentItem;\n\t\t\tif ( topLevel ) {\n\t\t\t\t// This is a top-level tmpl call (not from a nested template using {{tmpl}})\n\t\t\t\tparentItem = topTmplItem;\n\t\t\t\ttmpl = jQuery.template[tmpl] || jQuery.template( null, tmpl );\n\t\t\t\twrappedItems = {}; // Any wrapped items will be rebuilt, since this is top level\n\t\t\t} else if ( !tmpl ) {\n\t\t\t\t// The template item is already associated with DOM - this is a refresh.\n\t\t\t\t// Re-evaluate rendered template for the parentItem\n\t\t\t\ttmpl = parentItem.tmpl;\n\t\t\t\tnewTmplItems[parentItem.key] = parentItem;\n\t\t\t\tparentItem.nodes = [];\n\t\t\t\tif ( parentItem.wrapped ) {\n\t\t\t\t\tupdateWrapped( parentItem, parentItem.wrapped );\n\t\t\t\t}\n\t\t\t\t// Rebuild, without creating a new template item\n\t\t\t\treturn jQuery( build( parentItem, null, parentItem.tmpl( jQuery, parentItem ) ));\n\t\t\t}\n\t\t\tif ( !tmpl ) {\n\t\t\t\treturn []; // Could throw...\n\t\t\t}\n\t\t\tif ( typeof data === \"function\" ) {\n\t\t\t\tdata = data.call( parentItem || {} );\n\t\t\t}\n\t\t\tif ( options && options.wrapped ) {\n\t\t\t\tupdateWrapped( options, options.wrapped );\n\t\t\t}\n\t\t\tret = jQuery.isArray( data ) ?\n\t\t\t\tjQuery.map( data, function( dataItem ) {\n\t\t\t\t\treturn dataItem ? newTmplItem( options, parentItem, tmpl, dataItem ) : null;\n\t\t\t\t}) :\n\t\t\t\t[ newTmplItem( options, parentItem, tmpl, data ) ];\n\t\t\treturn topLevel ? jQuery( build( parentItem, null, ret ) ) : ret;\n\t\t},\n\n\t\t// Return rendered template item for an element.\n\t\ttmplItem: function( elem ) {\n\t\t\tvar tmplItem;\n\t\t\tif ( elem instanceof jQuery ) {\n\t\t\t\telem = elem[0];\n\t\t\t}\n\t\t\twhile ( elem && elem.nodeType === 1 && !(tmplItem = jQuery.data( elem, \"tmplItem\" )) && (elem = elem.parentNode) ) {}\n\t\t\treturn tmplItem || topTmplItem;\n\t\t},\n\n\t\t// Set:\n\t\t// Use $.template( name, tmpl ) to cache a named template,\n\t\t// where tmpl is a template string, a script element or a jQuery instance wrapping a script element, etc.\n\t\t// Use $( \"selector\" ).template( name ) to provide access by name to a script block template declaration.\n\n\t\t// Get:\n\t\t// Use $.template( name ) to access a cached template.\n\t\t// Also $( selectorToScriptBlock ).template(), or $.template( null, templateString )\n\t\t// will return the compiled template, without adding a name reference.\n\t\t// If templateString includes at least one HTML tag, $.template( templateString ) is equivalent\n\t\t// to $.template( null, templateString )\n\t\ttemplate: function( name, tmpl ) {\n\t\t\tif (tmpl) {\n\t\t\t\t// Compile template and associate with name\n\t\t\t\tif ( typeof tmpl === \"string\" ) {\n\t\t\t\t\t// This is an HTML string being passed directly in.\n\t\t\t\t\ttmpl = buildTmplFn( tmpl )\n\t\t\t\t} else if ( tmpl instanceof jQuery ) {\n\t\t\t\t\ttmpl = tmpl[0] || {};\n\t\t\t\t}\n\t\t\t\tif ( tmpl.nodeType ) {\n\t\t\t\t\t// If this is a template block, use cached copy, or generate tmpl function and cache.\n\t\t\t\t\ttmpl = jQuery.data( tmpl, \"tmpl\" ) || jQuery.data( tmpl, \"tmpl\", buildTmplFn( tmpl.innerHTML ));\n\t\t\t\t\t// Issue: In IE, if the container element is not a script block, the innerHTML will remove quotes from attribute values whenever the value does not include white space.\n\t\t\t\t\t// This means that foo=\"${x}\" will not work if the value of x includes white space: foo=\"${x}\" -> foo=value of x.\n\t\t\t\t\t// To correct this, include space in tag: foo=\"${ x }\" -> foo=\"value of x\"\n\t\t\t\t}\n\t\t\t\treturn typeof name === \"string\" ? (jQuery.template[name] = tmpl) : tmpl;\n\t\t\t}\n\t\t\t// Return named compiled template\n\t\t\treturn name ? (typeof name !== \"string\" ? jQuery.template( null, name ):\n\t\t\t\t(jQuery.template[name] ||\n\t\t\t\t\t// If not in map, and not containing at least on HTML tag, treat as a selector.\n\t\t\t\t\t// (If integrated with core, use quickExpr.exec)\n\t\t\t\t\tjQuery.template( null, htmlExpr.test( name ) ? name : jQuery( name )))) : null;\n\t\t},\n\n\t\tencode: function( text ) {\n\t\t\t// Do HTML encoding replacing < > & and ' and \" by corresponding entities.\n\t\t\treturn (\"\" + text).split(\"<\").join(\"&lt;\").split(\">\").join(\"&gt;\").split('\"').join(\"&#34;\").split(\"'\").join(\"&#39;\");\n\t\t}\n\t});\n\n\tjQuery.extend( jQuery.tmpl, {\n\t\ttag: {\n\t\t\t\"tmpl\": {\n\t\t\t\t_default: { $2: \"null\" },\n\t\t\t\topen: \"if($notnull_1){__=__.concat($item.nest($1,$2));}\"\n\t\t\t\t// tmpl target parameter can be of type function, so use $1, not $1a (so not auto detection of functions)\n\t\t\t\t// This means that {{tmpl foo}} treats foo as a template (which IS a function).\n\t\t\t\t// Explicit parens can be used if foo is a function that returns a template: {{tmpl foo()}}.\n\t\t\t},\n\t\t\t\"wrap\": {\n\t\t\t\t_default: { $2: \"null\" },\n\t\t\t\topen: \"$item.calls(__,$1,$2);__=[];\",\n\t\t\t\tclose: \"call=$item.calls();__=call._.concat($item.wrap(call,__));\"\n\t\t\t},\n\t\t\t\"each\": {\n\t\t\t\t_default: { $2: \"$index, $value\" },\n\t\t\t\topen: \"if($notnull_1){$.each($1a,function($2){with(this){\",\n\t\t\t\tclose: \"}});}\"\n\t\t\t},\n\t\t\t\"if\": {\n\t\t\t\topen: \"if(($notnull_1) && $1a){\",\n\t\t\t\tclose: \"}\"\n\t\t\t},\n\t\t\t\"else\": {\n\t\t\t\t_default: { $1: \"true\" },\n\t\t\t\topen: \"}else if(($notnull_1) && $1a){\"\n\t\t\t},\n\t\t\t\"html\": {\n\t\t\t\t// Unecoded expression evaluation.\n\t\t\t\topen: \"if($notnull_1){__.push($1a);}\"\n\t\t\t},\n\t\t\t\"=\": {\n\t\t\t\t// Encoded expression evaluation. Abbreviated form is ${}.\n\t\t\t\t_default: { $1: \"$data\" },\n\t\t\t\topen: \"if($notnull_1){__.push($.encode($1a));}\"\n\t\t\t},\n\t\t\t\"!\": {\n\t\t\t\t// Comment tag. Skipped by parser\n\t\t\t\topen: \"\"\n\t\t\t}\n\t\t},\n\n\t\t// This stub can be overridden, e.g. in jquery.tmplPlus for providing rendered events\n\t\tcomplete: function( items ) {\n\t\t\tnewTmplItems = {};\n\t\t},\n\n\t\t// Call this from code which overrides domManip, or equivalent\n\t\t// Manage cloning/storing template items etc.\n\t\tafterManip: function afterManip( elem, fragClone, callback ) {\n\t\t\t// Provides cloned fragment ready for fixup prior to and after insertion into DOM\n\t\t\tvar content = fragClone.nodeType === 11 ?\n\t\t\t\tjQuery.makeArray(fragClone.childNodes) :\n\t\t\t\tfragClone.nodeType === 1 ? [fragClone] : [];\n\n\t\t\t// Return fragment to original caller (e.g. append) for DOM insertion\n\t\t\tcallback.call( elem, fragClone );\n\n\t\t\t// Fragment has been inserted:- Add inserted nodes to tmplItem data structure. Replace inserted element annotations by jQuery.data.\n\t\t\tstoreTmplItems( content );\n\t\t\tcloneIndex++;\n\t\t}\n\t});\n\n\t//========================== Private helper functions, used by code above ==========================\n\n\tfunction build( tmplItem, nested, content ) {\n\t\t// Convert hierarchical content into flat string array\n\t\t// and finally return array of fragments ready for DOM insertion\n\t\tvar frag, ret = content ? jQuery.map( content, function( item ) {\n\t\t\treturn (typeof item === \"string\") ?\n\t\t\t\t// Insert template item annotations, to be converted to jQuery.data( \"tmplItem\" ) when elems are inserted into DOM.\n\t\t\t\t(tmplItem.key ? item.replace( /(<\\w+)(?=[\\s>])(?![^>]*_tmplitem)([^>]*)/g, \"$1 \" + tmplItmAtt + \"=\\\"\" + tmplItem.key + \"\\\" $2\" ) : item) :\n\t\t\t\t// This is a child template item. Build nested template.\n\t\t\t\tbuild( item, tmplItem, item._ctnt );\n\t\t}) :\n\t\t// If content is not defined, insert tmplItem directly. Not a template item. May be a string, or a string array, e.g. from {{html $item.html()}}.\n\t\ttmplItem;\n\t\tif ( nested ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\t// top-level template\n\t\tret = ret.join(\"\");\n\n\t\t// Support templates which have initial or final text nodes, or consist only of text\n\t\t// Also support HTML entities within the HTML markup.\n\t\tret.replace( /^\\s*([^<\\s][^<]*)?(<[\\w\\W]+>)([^>]*[^>\\s])?\\s*$/, function( all, before, middle, after) {\n\t\t\tfrag = jQuery( middle ).get();\n\n\t\t\tstoreTmplItems( frag );\n\t\t\tif ( before ) {\n\t\t\t\tfrag = unencode( before ).concat(frag);\n\t\t\t}\n\t\t\tif ( after ) {\n\t\t\t\tfrag = frag.concat(unencode( after ));\n\t\t\t}\n\t\t});\n\t\treturn frag ? frag : unencode( ret );\n\t}\n\n\tfunction unencode( text ) {\n\t\t// Use createElement, since createTextNode will not render HTML entities correctly\n\t\tvar el = document.createElement( \"div\" );\n\t\tel.innerHTML = text;\n\t\treturn jQuery.makeArray(el.childNodes);\n\t}\n\n\t// Generate a reusable function that will serve to render a template against data\n\tfunction buildTmplFn( markup ) {\n\t\treturn new Function(\"jQuery\",\"$item\",\n\t\t\t// Use the variable __ to hold a string array while building the compiled template. (See https://github.com/jquery/jquery-tmpl/issues#issue/10).\n\t\t\t\"var $=jQuery,call,__=[],$data=$item.data;\" +\n\n\t\t\t// Introduce the data as local variables using with(){}\n\t\t\t\"with($data){__.push('\" +\n\n\t\t\t// Convert the template into pure JavaScript\n\t\t\tjQuery.trim(markup)\n\t\t\t\t.replace( /([\\\\'])/g, \"\\\\$1\" )\n\t\t\t\t.replace( /[\\r\\t\\n]/g, \" \" )\n\t\t\t\t.replace( /\\$\\{([^\\}]*)\\}/g, \"{{= $1}}\" )\n\t\t\t\t.replace( /\\{\\{(\\/?)(\\w+|.)(?:\\(((?:[^\\}]|\\}(?!\\}))*?)?\\))?(?:\\s+(.*?)?)?(\\(((?:[^\\}]|\\}(?!\\}))*?)\\))?\\s*\\}\\}/g,\n\t\t\t\tfunction( all, slash, type, fnargs, target, parens, args ) {\n\t\t\t\t\tvar tag = jQuery.tmpl.tag[ type ], def, expr, exprAutoFnDetect;\n\t\t\t\t\tif ( !tag ) {\n\t\t\t\t\t\tthrow \"Unknown template tag: \" + type;\n\t\t\t\t\t}\n\t\t\t\t\tdef = tag._default || [];\n\t\t\t\t\tif ( parens && !/\\w$/.test(target)) {\n\t\t\t\t\t\ttarget += parens;\n\t\t\t\t\t\tparens = \"\";\n\t\t\t\t\t}\n\t\t\t\t\tif ( target ) {\n\t\t\t\t\t\ttarget = unescape( target );\n\t\t\t\t\t\targs = args ? (\",\" + unescape( args ) + \")\") : (parens ? \")\" : \"\");\n\t\t\t\t\t\t// Support for target being things like a.toLowerCase();\n\t\t\t\t\t\t// In that case don't call with template item as 'this' pointer. Just evaluate...\n\t\t\t\t\t\texpr = parens ? (target.indexOf(\".\") > -1 ? target + unescape( parens ) : (\"(\" + target + \").call($item\" + args)) : target;\n\t\t\t\t\t\texprAutoFnDetect = parens ? expr : \"(typeof(\" + target + \")==='function'?(\" + target + \").call($item):(\" + target + \"))\";\n\t\t\t\t\t} else {\n\t\t\t\t\t\texprAutoFnDetect = expr = def.$1 || \"null\";\n\t\t\t\t\t}\n\t\t\t\t\tfnargs = unescape( fnargs );\n\t\t\t\t\treturn \"');\" +\n\t\t\t\t\t\ttag[ slash ? \"close\" : \"open\" ]\n\t\t\t\t\t\t\t.split( \"$notnull_1\" ).join( target ? \"typeof(\" + target + \")!=='undefined' && (\" + target + \")!=null\" : \"true\" )\n\t\t\t\t\t\t\t.split( \"$1a\" ).join( exprAutoFnDetect )\n\t\t\t\t\t\t\t.split( \"$1\" ).join( expr )\n\t\t\t\t\t\t\t.split( \"$2\" ).join( fnargs || def.$2 || \"\" ) +\n\t\t\t\t\t\t\"__.push('\";\n\t\t\t\t}) +\n\t\t\t\"');}return __;\"\n\t\t);\n\t}\n\tfunction updateWrapped( options, wrapped ) {\n\t\t// Build the wrapped content.\n\t\toptions._wrap = build( options, true,\n\t\t\t// Suport imperative scenario in which options.wrapped can be set to a selector or an HTML string.\n\t\t\tjQuery.isArray( wrapped ) ? wrapped : [htmlExpr.test( wrapped ) ? wrapped : jQuery( wrapped ).html()]\n\t\t).join(\"\");\n\t}\n\n\tfunction unescape( args ) {\n\t\treturn args ? args.replace( /\\\\'/g, \"'\").replace(/\\\\\\\\/g, \"\\\\\" ) : null;\n\t}\n\tfunction outerHtml( elem ) {\n\t\tvar div = document.createElement(\"div\");\n\t\tdiv.appendChild( elem.cloneNode(true) );\n\t\treturn div.innerHTML;\n\t}\n\n\t// Store template items in jQuery.data(), ensuring a unique tmplItem data data structure for each rendered template instance.\n\tfunction storeTmplItems( content ) {\n\t\tvar keySuffix = \"_\" + cloneIndex, elem, elems, newClonedItems = {}, i, l, m;\n\t\tfor ( i = 0, l = content.length; i < l; i++ ) {\n\t\t\tif ( (elem = content[i]).nodeType !== 1 ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\telems = elem.getElementsByTagName(\"*\");\n\t\t\tfor ( m = elems.length - 1; m >= 0; m-- ) {\n\t\t\t\tprocessItemKey( elems[m] );\n\t\t\t}\n\t\t\tprocessItemKey( elem );\n\t\t}\n\t\tfunction processItemKey( el ) {\n\t\t\tvar pntKey, pntNode = el, pntItem, tmplItem, key;\n\t\t\t// Ensure that each rendered template inserted into the DOM has its own template item,\n\t\t\tif ( (key = el.getAttribute( tmplItmAtt ))) {\n\t\t\t\twhile ( pntNode.parentNode && (pntNode = pntNode.parentNode).nodeType === 1 && !(pntKey = pntNode.getAttribute( tmplItmAtt ))) { }\n\t\t\t\tif ( pntKey !== key ) {\n\t\t\t\t\t// The next ancestor with a _tmplitem expando is on a different key than this one.\n\t\t\t\t\t// So this is a top-level element within this template item\n\t\t\t\t\t// Set pntNode to the key of the parentNode, or to 0 if pntNode.parentNode is null, or pntNode is a fragment.\n\t\t\t\t\tpntNode = pntNode.parentNode ? (pntNode.nodeType === 11 ? 0 : (pntNode.getAttribute( tmplItmAtt ) || 0)) : 0;\n\t\t\t\t\tif ( !(tmplItem = newTmplItems[key]) ) {\n\t\t\t\t\t\t// The item is for wrapped content, and was copied from the temporary parent wrappedItem.\n\t\t\t\t\t\ttmplItem = wrappedItems[key];\n\t\t\t\t\t\ttmplItem = newTmplItem( tmplItem, newTmplItems[pntNode]||wrappedItems[pntNode] );\n\t\t\t\t\t\ttmplItem.key = ++itemKey;\n\t\t\t\t\t\tnewTmplItems[itemKey] = tmplItem;\n\t\t\t\t\t}\n\t\t\t\t\tif ( cloneIndex ) {\n\t\t\t\t\t\tcloneTmplItem( key );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tel.removeAttribute( tmplItmAtt );\n\t\t\t} else if ( cloneIndex && (tmplItem = jQuery.data( el, \"tmplItem\" )) ) {\n\t\t\t\t// This was a rendered element, cloned during append or appendTo etc.\n\t\t\t\t// TmplItem stored in jQuery data has already been cloned in cloneCopyEvent. We must replace it with a fresh cloned tmplItem.\n\t\t\t\tcloneTmplItem( tmplItem.key );\n\t\t\t\tnewTmplItems[tmplItem.key] = tmplItem;\n\t\t\t\tpntNode = jQuery.data( el.parentNode, \"tmplItem\" );\n\t\t\t\tpntNode = pntNode ? pntNode.key : 0;\n\t\t\t}\n\t\t\tif ( tmplItem ) {\n\t\t\t\tpntItem = tmplItem;\n\t\t\t\t// Find the template item of the parent element.\n\t\t\t\t// (Using !=, not !==, since pntItem.key is number, and pntNode may be a string)\n\t\t\t\twhile ( pntItem && pntItem.key != pntNode ) {\n\t\t\t\t\t// Add this element as a top-level node for this rendered template item, as well as for any\n\t\t\t\t\t// ancestor items between this item and the item of its parent element\n\t\t\t\t\tpntItem.nodes.push( el );\n\t\t\t\t\tpntItem = pntItem.parent;\n\t\t\t\t}\n\t\t\t\t// Delete content built during rendering - reduce API surface area and memory use, and avoid exposing of stale data after rendering...\n\t\t\t\tdelete tmplItem._ctnt;\n\t\t\t\tdelete tmplItem._wrap;\n\t\t\t\t// Store template item as jQuery data on the element\n\t\t\t\tjQuery.data( el, \"tmplItem\", tmplItem );\n\t\t\t}\n\t\t\tfunction cloneTmplItem( key ) {\n\t\t\t\tkey = key + keySuffix;\n\t\t\t\ttmplItem = newClonedItems[key] =\n\t\t\t\t\t(newClonedItems[key] || newTmplItem( tmplItem, newTmplItems[tmplItem.parent.key + keySuffix] || tmplItem.parent ));\n\t\t\t}\n\t\t}\n\t}\n\n\t//---- Helper functions for template item ----\n\n\tfunction tiCalls( content, tmpl, data, options ) {\n\t\tif ( !content ) {\n\t\t\treturn stack.pop();\n\t\t}\n\t\tstack.push({ _: content, tmpl: tmpl, item:this, data: data, options: options });\n\t}\n\n\tfunction tiNest( tmpl, data, options ) {\n\t\t// nested template, using {{tmpl}} tag\n\t\treturn jQuery.tmpl( jQuery.template( tmpl ), data, options, this );\n\t}\n\n\tfunction tiWrap( call, wrapped ) {\n\t\t// nested template, using {{wrap}} tag\n\t\tvar options = call.options || {};\n\t\toptions.wrapped = wrapped;\n\t\t// Apply the template, which may incorporate wrapped content,\n\t\treturn jQuery.tmpl( jQuery.template( call.tmpl ), call.data, options, call.item );\n\t}\n\n\tfunction tiHtml( filter, textOnly ) {\n\t\tvar wrapped = this._wrap;\n\t\treturn jQuery.map(\n\t\t\tjQuery( jQuery.isArray( wrapped ) ? wrapped.join(\"\") : wrapped ).filter( filter || \"*\" ),\n\t\t\tfunction(e) {\n\t\t\t\treturn textOnly ?\n\t\t\t\t\te.innerText || e.textContent :\n\t\t\t\t\te.outerHTML || outerHtml(e);\n\t\t\t});\n\t}\n\n\tfunction tiUpdate() {\n\t\tvar coll = this.nodes;\n\t\tjQuery.tmpl( null, null, null, this).insertBefore( coll[0] );\n\t\tjQuery( coll ).remove();\n\t}\n})( jQuery );\n"}};;jQuery.golf.styles={"main":{"name":"main","css":""}};;jQuery.golf.setupComponents();
@@ -0,0 +1,28 @@
1
+ $.golf.defaultRoute = "/store/";
2
+ $.golf.devmode = true;
3
+
4
+ var store;
5
+
6
+ $.golf.controller = [
7
+
8
+ { route: "/admin/",
9
+ action: function(container, params) {
10
+ container.append(new Component.golf.cart.Admin());
11
+ }
12
+ },
13
+
14
+ { route: "/store/",
15
+ action: function(container, params) {
16
+ if (!store)
17
+ store = new Component.golf.cart.Store();
18
+ container.append(store);
19
+ }
20
+ },
21
+
22
+ { route: ".*",
23
+ action: function(container, params) {
24
+ container.append("<h3>Not found :(</h3>");
25
+ }
26
+ }
27
+
28
+ ];
File without changes
File without changes
File without changes