creationix-milk 0.0.9

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.
Files changed (88) hide show
  1. data/.document +5 -0
  2. data/.gitignore +7 -0
  3. data/LICENSE +27 -0
  4. data/README.rdoc +7 -0
  5. data/Rakefile +62 -0
  6. data/VERSION +1 -0
  7. data/bin/milk +22 -0
  8. data/lib/milk.rb +82 -0
  9. data/lib/milk/application.rb +227 -0
  10. data/lib/milk/component.rb +142 -0
  11. data/lib/milk/field.rb +60 -0
  12. data/lib/milk/fields/component.haml +8 -0
  13. data/lib/milk/fields/component_array.haml +3 -0
  14. data/lib/milk/fields/component_array.rb +4 -0
  15. data/lib/milk/fields/image_chooser.haml +7 -0
  16. data/lib/milk/fields/image_chooser.rb +26 -0
  17. data/lib/milk/fields/login.haml +90 -0
  18. data/lib/milk/fields/markdown_field.haml +1 -0
  19. data/lib/milk/fields/markdown_field.rb +4 -0
  20. data/lib/milk/fields/page_chooser.haml +3 -0
  21. data/lib/milk/fields/page_chooser.rb +17 -0
  22. data/lib/milk/fields/sprite_chooser.haml +6 -0
  23. data/lib/milk/fields/sprite_chooser.rb +19 -0
  24. data/lib/milk/fields/text_field.haml +1 -0
  25. data/lib/milk/fields/text_field.rb +4 -0
  26. data/lib/milk/fields/xhtml.haml +253 -0
  27. data/lib/milk/haxe.rb +139 -0
  28. data/lib/milk/page.rb +139 -0
  29. data/lib/milk/tasks.rb +51 -0
  30. data/milk.gemspec +137 -0
  31. data/site_template/Rakefile +3 -0
  32. data/site_template/config.ru +16 -0
  33. data/site_template/config/config.yaml +31 -0
  34. data/site_template/config/foot.yaml +3 -0
  35. data/site_template/config/head.yaml +18 -0
  36. data/site_template/config/users.yaml +18 -0
  37. data/site_template/design/0-reset.sass +170 -0
  38. data/site_template/design/1-text.sass +65 -0
  39. data/site_template/design/960.sass +305 -0
  40. data/site_template/design/body.haml +1 -0
  41. data/site_template/design/body.rb +4 -0
  42. data/site_template/design/button.haml +2 -0
  43. data/site_template/design/button.rb +16 -0
  44. data/site_template/design/foot.haml +1 -0
  45. data/site_template/design/foot.rb +4 -0
  46. data/site_template/design/foot.sass +3 -0
  47. data/site_template/design/head.haml +3 -0
  48. data/site_template/design/head.rb +4 -0
  49. data/site_template/design/head.sass +27 -0
  50. data/site_template/design/page.haml +2 -0
  51. data/site_template/design/page.sass +7 -0
  52. data/site_template/design/sprites.sass +0 -0
  53. data/site_template/design/xhtml.haml +15 -0
  54. data/site_template/pages/About.yaml +14 -0
  55. data/site_template/pages/Home.yaml +14 -0
  56. data/site_template/pages/News.yaml +14 -0
  57. data/site_template/pages/NotFound.yaml +14 -0
  58. data/site_template/pages/Products.yaml +14 -0
  59. data/site_template/public/cache/About/index.html +42 -0
  60. data/site_template/public/cache/Home/index.html +44 -0
  61. data/site_template/public/cache/News/index.html +42 -0
  62. data/site_template/public/cache/Products/index.html +42 -0
  63. data/site_template/public/favicon.ico +0 -0
  64. data/site_template/public/images/README.txt +2 -0
  65. data/site_template/public/js/jquery-1.3.2.min.js +19 -0
  66. data/site_template/public/js/jquery-ui-1.7.2.custom.min.js +34 -0
  67. data/site_template/public/js/jquery.json-1.3.min.js +37 -0
  68. data/site_template/public/robots.txt +0 -0
  69. data/site_template/public/skin/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  70. data/site_template/public/skin/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  71. data/site_template/public/skin/images/ui-bg_flat_10_000000_40x100.png +0 -0
  72. data/site_template/public/skin/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  73. data/site_template/public/skin/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  74. data/site_template/public/skin/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  75. data/site_template/public/skin/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  76. data/site_template/public/skin/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  77. data/site_template/public/skin/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  78. data/site_template/public/skin/images/ui-icons_222222_256x240.png +0 -0
  79. data/site_template/public/skin/images/ui-icons_228ef1_256x240.png +0 -0
  80. data/site_template/public/skin/images/ui-icons_ef8c08_256x240.png +0 -0
  81. data/site_template/public/skin/images/ui-icons_ffd27a_256x240.png +0 -0
  82. data/site_template/public/skin/images/ui-icons_ffffff_256x240.png +0 -0
  83. data/site_template/public/skin/jquery-ui-1.7.2.custom.css +406 -0
  84. data/site_template/public/style/style.css +157 -0
  85. data/site_template/tmp/restart.txt +1 -0
  86. data/test/milk_test.rb +7 -0
  87. data/test/test_helper.rb +10 -0
  88. metadata +170 -0
@@ -0,0 +1,142 @@
1
+ module Milk
2
+ class Component
3
+
4
+ @@local_flag = {}
5
+
6
+ attr_accessor :parent
7
+ @parent = nil
8
+
9
+
10
+ # Don't store global properties or backreferences to the parent
11
+ def to_yaml_properties
12
+ (if respond_to? :global_properties
13
+ instance_variables.reject { |name| global_properties.member?(name) }
14
+ else
15
+ instance_variables
16
+ end).reject { |name| name == :@parent }
17
+ end
18
+
19
+ def app
20
+ page.app
21
+ end
22
+
23
+ def page
24
+ if @parent.class == Milk::Page
25
+ @parent
26
+ else
27
+ @parent.page
28
+ end
29
+ end
30
+
31
+ def self.local_properties(*props)
32
+ end
33
+
34
+ def self.global_properties(*props)
35
+ globals = props.collect{|name|"@#{name}".to_sym}
36
+ class_def :global_properties do
37
+ globals
38
+ end
39
+ end
40
+
41
+ def name
42
+ self.class.to_s
43
+ end
44
+
45
+ # All Components start out with default of no fields
46
+ def self.fields
47
+ []
48
+ end
49
+
50
+ # Assume no defaults
51
+ def self.defaults
52
+ {}
53
+ end
54
+
55
+ # Metaclass black magic to simulate appending items to a list
56
+ # This works by getting the old result of the fields class method
57
+ # and stores it in a closure, and then redefines the method, but with
58
+ # a new item appended.
59
+ def self.add_field(klass, field, label, options={})
60
+
61
+ # Merge in assumes options
62
+ options[:field] = field
63
+ options[:label] = label
64
+
65
+ # Fill in blanks with defaults
66
+ defaults.each do |k, v|
67
+ options[k] ||= v
68
+ end
69
+
70
+ field = klass.new(options)
71
+
72
+ newfields = self.fields + [field]
73
+ meta_def("fields") do
74
+ newfields
75
+ end
76
+ end
77
+
78
+ def self.method_missing(method, *args)
79
+ raise "Missing '#{method}' method" unless File.file? FIELDS_DIR+"/#{method}.rb"
80
+ klass = eval("Fields::" + method.to_s.gsub(/(^|_)(.)/) { $2.upcase })
81
+ add_field(klass, *args)
82
+ end
83
+
84
+ def save_settings
85
+ return unless respond_to? :global_properties
86
+ yaml_file = Milk::CONFIG_DIR + "/#{system_name}.yaml"
87
+ data = {}
88
+ global_properties.each do |name|
89
+ data[name.to_s.sub('@','')] = instance_variable_get(name)
90
+ end
91
+
92
+ File.open(yaml_file, "w") do |file|
93
+ file.write(YAML.dump(data))
94
+ end
95
+ end
96
+
97
+ def system_name
98
+ self.class.to_s.gsub(/([a-z])([A-Z])/) { "#{$1}_#{$2}" }.downcase
99
+ end
100
+
101
+ def load_settings
102
+ yaml_file = Milk::CONFIG_DIR + "/#{system_name}.yaml"
103
+ if File.file? yaml_file
104
+ YAML.load_file(yaml_file).each_pair do |key, value|
105
+ instance_variable_set("@#{key}".to_sym, value)
106
+ end
107
+ end
108
+ end
109
+
110
+ def haml(filename, context=self, extras={})
111
+ if block_given?
112
+ Page.haml(filename, context, extras) { yield }
113
+ else
114
+ Page.haml(filename, context, extras)
115
+ end
116
+ end
117
+
118
+ def partial(filename, vars, extras={})
119
+ obj = self.dup
120
+ vars.each do |key, value|
121
+ obj.instance_variable_set("@#{key}", value)
122
+ end
123
+ haml(filename, obj, extras)
124
+ end
125
+
126
+
127
+ def edit(prefix)
128
+ @prefix = prefix
129
+ haml_file = FIELDS_DIR + "/component.haml"
130
+ ::Haml::Engine.new(File.read(haml_file), :filename => haml_file).render(self)
131
+ end
132
+
133
+ def view
134
+ haml_file = Milk::COMPONENTS_DIR + "/" + system_name + ".haml"
135
+ raise "Missing template \"" + haml_file + "\"" unless File.file? haml_file
136
+ ::Haml::Engine.new(File.read(haml_file), :filename => haml_file).render(self)
137
+ end
138
+
139
+ end
140
+ end
141
+
142
+
data/lib/milk/field.rb ADDED
@@ -0,0 +1,60 @@
1
+ module Milk
2
+
3
+ # A field is a data type for part of a component. This way components can be
4
+ # quickly built without coding any logic. The fields take care of the heavy
5
+ # work.
6
+ class Field
7
+
8
+ attr_reader :field
9
+
10
+ # Store the field configurations
11
+ def initialize(props)
12
+ props.each do |key, value|
13
+ self.instance_variable_set('@' + key.to_s, value)
14
+ end
15
+ end
16
+
17
+ # This is the name shown to the user for the field.
18
+ def name
19
+ @label || self.class.to_s.rpartition('::').last
20
+ end
21
+
22
+ def form_field
23
+ @prefix
24
+ end
25
+
26
+ def value
27
+ @component.instance_variable_get('@' + @field.to_s)
28
+ end
29
+
30
+ # This is called to render the html for a field's form
31
+ def render(component, prefix)
32
+ @component = component
33
+ @prefix = prefix
34
+
35
+ name = self.class.to_s.rpartition('::').last.gsub(/([a-z])([A-Z])/) { "#{$1}_#{$2}" }.downcase
36
+ haml_file = "#{FIELDS_DIR}/#{name}.haml"
37
+ if File.file?(haml_file)
38
+ ::Haml::Engine.new(File.read(haml_file), :filename => haml_file).render(self)
39
+ else
40
+ "#{self.class} Not Implemented"
41
+ end
42
+ end
43
+
44
+ end
45
+
46
+ # This module is a namespace for all the subclasses of Milk::Field
47
+ # Is sets up autoloading for the fields classes
48
+ module Fields
49
+
50
+ Dir.glob(Milk::FIELDS_DIR + "/*.rb").each do |c|
51
+ name = c.split('/').last.gsub(/(.*)\.rb/) { $1 }
52
+ class_name = name.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
53
+ path = c.gsub(/(.*)\.rb/) { $1 }
54
+ autoload class_name.to_sym, path
55
+ end
56
+
57
+ end
58
+
59
+ end
60
+
@@ -0,0 +1,8 @@
1
+ %h3
2
+ %a{:href => "#"}&= name
3
+ %div
4
+ %input{:type=>"hidden", :name=>"#{@prefix}:class", :value=>self.class.to_s}
5
+ -self.class.fields.each do |field|
6
+ .field
7
+ %h4= field.name
8
+ .field-content= field.render(self, "#{@prefix}:#{field.field}")
@@ -0,0 +1,3 @@
1
+ .sub-fields
2
+ - value.each_with_index do |item, i|
3
+ = item.edit("#{@prefix}:#{i}")
@@ -0,0 +1,4 @@
1
+ module Milk::Fields
2
+ class ComponentArray < Milk::Field
3
+ end
4
+ end
@@ -0,0 +1,7 @@
1
+ %select{:name=>form_field}
2
+ - images.each do |img|
3
+ %option{:value=>img[:url], :selected=>value==img[:url], :title=>"#{img[:size]} bytes"}&= img[:filename]
4
+ %br
5
+ Alt:
6
+ %input{:name=>alt_form_field, :value=>alt_value}
7
+
@@ -0,0 +1,26 @@
1
+ module Milk::Fields
2
+ class ImageChooser < Milk::Field
3
+ @@images = []
4
+ IMAGE_DIR = Milk::PUBLIC_DIR + "/images"
5
+ Dir.glob(IMAGE_DIR + "/*").each do |img|
6
+ @@images << {
7
+ size: File.size(img),
8
+ url: img.sub(Milk::PUBLIC_DIR, ''),
9
+ filename: img.rpartition('/').last
10
+ }
11
+ end
12
+
13
+ def images
14
+ @@images
15
+ end
16
+
17
+ def alt_form_field
18
+ @prefix.rpartition(':').first + ":#{@alt_field}"
19
+ end
20
+
21
+ def alt_value
22
+ @component.instance_variable_get('@' + @alt_field.to_s)
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,90 @@
1
+ !!! xml
2
+ !!! 1.1
3
+ %html{:xmlns =>"http://www.w3.org/1999/xhtml"}
4
+ %head
5
+ %title Please Login
6
+ %style{:type=>"text/css"}
7
+ :sass
8
+ !width = 400
9
+ !height = 160
10
+ table, #shadow, .ui-widget-shadow
11
+ :width = !width + "px"
12
+ :height = !height + "px"
13
+ table#login, #shadow
14
+ :font-size 15px
15
+ :position absolute
16
+ :top 50%
17
+ :left 50%
18
+ :margin
19
+ :top = (-!height/2)+"px"
20
+ :left = (-!width/2)+"px"
21
+ table#login td, table#login th
22
+ :vertical-align middle
23
+ #login
24
+ tr.ui-state-error
25
+ td
26
+ :padding 5px 10px
27
+ :font-size 12px
28
+ span
29
+ :float left
30
+ :margin-right 0.3em
31
+ .ui-widget-header
32
+ :line-height 2em
33
+ :height 2em
34
+ button
35
+ :font-size 12px
36
+ :cursor pointer
37
+ :line-height 1em
38
+ :padding 2px 5px 2px 2px
39
+ .ui-icon
40
+ :float left
41
+ :line-height 1em
42
+
43
+ %link{ :rel => "shortcut icon", :href => "/favicon.ico", :type => "image/x-icon"}/
44
+ %link{ :href => "/skin/jquery-ui-1.7.2.custom.css", :media => "screen", :rel => "stylesheet", :type => "text/css" }/
45
+ %link{ :href => "/style/style.css", :media => "screen", :rel => "stylesheet", :type => "text/css" }/
46
+ %script{:src=>"/js/jquery-1.3.2.min.js", :type=>"text/javascript"}
47
+ %script{:src=>"/js/jquery.json-1.3.min.js", :type=>"text/javascript"}
48
+ %script{:src=>"/js/jquery-ui-1.7.2.custom.min.js", :type=>"text/javascript"}
49
+ %body
50
+ .ui-widget-overlay
51
+ %form{:action => "/login", :method=>"post"}
52
+ %input{:type=>"hidden", :name => "dest", :value => @req.path_info}
53
+ #shadow
54
+ .ui-widget-shadow
55
+ %table#login{:class => "ui-widget ui-widget-content ui-corner-all"}
56
+ %thead
57
+ %tr
58
+ %th{:colspan=>2, :class=>"ui-widget-header ui-corner-top"}
59
+ &= "Please Login to edit '#{@page.pagename}'"
60
+ - if f = flash
61
+ %tr.ui-state-error{:class=>"ui-corner-all"}
62
+ %td{:colspan=>2}
63
+ %span{:class => "ui-icon ui-icon-alert",:style=>"float:left"}
64
+ %strong Alert:
65
+ &= f
66
+ %tr
67
+ %th Email
68
+ %td
69
+ %input{:name => "email"}
70
+ %tr
71
+ %th Password
72
+ %td
73
+ %input{:type=>"password", :name => "password"}
74
+ %tr
75
+ %th
76
+ %td
77
+ %button{:type =>"submit", :title=>'Login to the backend to edit this page.'}
78
+ %span{:class=>'ui-icon ui-icon-unlocked'}
79
+ Login
80
+ :javascript
81
+ $(function() {
82
+ $("button")
83
+ .addClass("ui-state-default ui-corner-all")
84
+ .hover(
85
+ function() { $(this).addClass('ui-state-hover'); },
86
+ function() { $(this).removeClass('ui-state-hover'); }
87
+ );
88
+ });
89
+
90
+
@@ -0,0 +1 @@
1
+ %textarea.markdown{:class=>"ui-widget ui-widget-content ui-corner-all", :name => form_field}&= value
@@ -0,0 +1,4 @@
1
+ module Milk::Fields
2
+ class MarkdownField < Milk::Field
3
+ end
4
+ end
@@ -0,0 +1,3 @@
1
+ %select{:name=>form_field}
2
+ - pages.each do |page|
3
+ %option{:value=>page[:url], :selected=>value==page[:url], :title=>page[:file]}&= page[:name]
@@ -0,0 +1,17 @@
1
+ module Milk::Fields
2
+ class PageChooser < Milk::Field
3
+ @@pages = []
4
+ Dir.glob(Milk::PAGES_DIR + "/*.yaml").each do |page|
5
+ pagename = File.basename(page, '.yaml').rpartition('/').last.gsub('.','/')
6
+ @@pages << {
7
+ file: page,
8
+ name: pagename,
9
+ url: "/"+pagename
10
+ }
11
+ end
12
+
13
+ def pages
14
+ @@pages
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,6 @@
1
+ .sprite-select
2
+ %input{:type=>"hidden", :name=>form_field, :value=>value}
3
+ - @sprites.each do |sprite|
4
+ %div{:class => "ui-state-default ui-corner-all sprite-option" + ((value == sprite[:name]) ? " ui-state-highlight" : "")}
5
+ %span{:class => sprite[:css_class], :title => sprite[:name]}
6
+ %br.clear
@@ -0,0 +1,19 @@
1
+ module Milk::Fields
2
+ class SpriteChooser < Milk::Field
3
+
4
+ def initialize(*args)
5
+ super(*args)
6
+ @sprites = []
7
+ open(Milk::COMPONENTS_DIR+"/sprites.sass") do |sass|
8
+ sass.each do |line|
9
+ if match = @icon_classes.match(line)
10
+ @sprites << {
11
+ css_class: @main_class + " " + match[1],
12
+ name: match[2]
13
+ }
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1 @@
1
+ %input{:class=>"ui-widget ui-widget-content ui-corner-all", :type =>"text", :name=>form_field, :value=>value}
@@ -0,0 +1,4 @@
1
+ module Milk::Fields
2
+ class TextField < Milk::Field
3
+ end
4
+ end
@@ -0,0 +1,253 @@
1
+ !!! xml
2
+ !!! 1.1
3
+ %html{:xmlns =>"http://www.w3.org/1999/xhtml"}
4
+ %head
5
+ %title&= "Editing \"#{@pagename}\""
6
+ %style{:type=>"text/css"}
7
+ :sass
8
+ body, html
9
+ :border 0
10
+ :margin 0
11
+ :padding 0
12
+ body.busy
13
+ :cursor busy
14
+ div.component
15
+ &:hover
16
+ :border 10px solid #08f
17
+ #admin-title
18
+ :position absolute
19
+ :margin 0
20
+ :top 5px
21
+ :left 10px
22
+ :line-height 1em
23
+ :font-size 20px
24
+ :font-family monaco,monospace
25
+
26
+ #toolbar
27
+ :position absolute
28
+ :left 0
29
+ :bottom 0
30
+ :right 0
31
+ :padding 3px
32
+ .toolitem
33
+ :font-size 12px
34
+ :cursor pointer
35
+ :line-height 1em
36
+ :padding 2px 5px 2px 2px
37
+ .ui-icon
38
+ :float left
39
+ :line-height 1em
40
+ #frame
41
+ :position absolute
42
+ :top 0px
43
+ :left 0px
44
+ :right 0px
45
+ :bottom 0px
46
+ #left
47
+ :font-size 11px
48
+ :position absolute
49
+ :top 0px
50
+ :left 0px
51
+ :width 250px
52
+ :bottom 0px
53
+ h4
54
+ :font-size 14px
55
+ h3
56
+ :font-size 13px
57
+ #divider
58
+ :position absolute
59
+ :top 0px
60
+ :left 250px
61
+ :width 5px
62
+ :bottom 0px
63
+
64
+ #fields
65
+ :position absolute
66
+ :top 0px
67
+ :bottom 35px
68
+ :overflow auto
69
+ :left 0px
70
+ :right 0
71
+ .ui-accordion-content
72
+ :padding 10px
73
+ h4
74
+ :margin 0
75
+ .field-content
76
+ :margin-bottom 10px
77
+ input
78
+ :width 95%
79
+ :padding 2px
80
+ textarea
81
+ :width 100%
82
+ :min-height 330px
83
+ .sprite-select
84
+ .sprite-option
85
+ :padding 4px
86
+ :margin 2px
87
+ :float left
88
+ :cursor pointer
89
+
90
+ #preview
91
+ :position absolute
92
+ :top 0px
93
+ :left 255px
94
+ :right 0
95
+ :width auto
96
+ :bottom 0px
97
+ :overflow auto
98
+
99
+
100
+ %link{ :rel => "shortcut icon", :href => "/favicon.ico", :type => "image/x-icon"}/
101
+ %link{ :href => "/skin/jquery-ui-1.7.2.custom.css", :media => "screen", :rel => "stylesheet", :type => "text/css" }/
102
+ %link{ :href => "/style/style.css", :media => "screen", :rel => "stylesheet", :type => "text/css" }/
103
+ %script{:src=>"/js/jquery-1.3.2.min.js", :type=>"text/javascript"}
104
+ %script{:src=>"/js/jquery.json-1.3.min.js", :type=>"text/javascript"}
105
+ %script{:src=>"/js/jquery-ui-1.7.2.custom.min.js", :type=>"text/javascript"}
106
+ %body
107
+ #frame
108
+ #left
109
+ .ui-widget-overlay
110
+ %form#fields{:method => "post", :action => "/"+@pagename}
111
+ %h3
112
+ %a{:href => "#"} Page Settings
113
+ %div
114
+ %input{:type=>"hidden", :name=>"class", :value=>self.class.to_s}
115
+ -to_yaml_properties.each do |name|
116
+ - next if name == :@components
117
+ - fieldname = name.to_s.sub('@','')
118
+ .field
119
+ %h4= fieldname.capitalize + ":"
120
+ .field-content
121
+ %input{:type=>"text", :name=>fieldname, :value=>instance_variable_get(name)}
122
+ -@components.each_with_index do |component, i|
123
+ = component.edit("components:#{i}")
124
+ #toolbar{:class=>'ui-widget ui-widget-header'}
125
+ %button#save_button.toolitem{:title=>'Save changes and go to live page.'}
126
+ %span{:class=>'ui-icon ui-icon-disk'}
127
+ Save
128
+ %button#cancel_button.toolitem{:title=>'Cancel changes and go to live page.'}
129
+ %span{:class=>'ui-icon ui-icon-cancel'}
130
+ Cancel
131
+ %button#logout_button.toolitem{:title=>'Cancel changes and logout and go to live page.'}
132
+ %span{:class=>'ui-icon ui-icon-locked'}
133
+ Logout
134
+ #preview
135
+ = preview
136
+ #divider.ui-widget-header
137
+
138
+ :javascript
139
+ function on_click_sprite(e)
140
+ {
141
+ // Look up some useful variables
142
+ var current = e.currentTarget;
143
+ var sprite_select = $(current.parentNode);
144
+ var peers = $(".sprite-option", sprite_select);
145
+ var hidden_input = $('input', sprite_select)[0];
146
+ var inner_span = $('span', current)[0];
147
+
148
+ // Set the value on the hidden input
149
+ hidden_input.value = inner_span.title;
150
+
151
+ // Move the highlight
152
+ peers.removeClass('ui-state-highlight');
153
+ $(current).addClass('ui-state-highlight');
154
+ update_preview(50);
155
+ }
156
+
157
+ function jsonify(form)
158
+ {
159
+ var data = {}
160
+ $("input, textarea, select", form).each(function (i, field){
161
+ var parts = field.name.split(':');
162
+ var root = data;
163
+ var part = parts[0];
164
+ var numeric_regexp = /[0-9]+/;
165
+ for(i=0;i<parts.length-1;i++)
166
+ {
167
+ if (!root[part])
168
+ {
169
+ if (numeric_regexp.test(part))
170
+ root[part]={};
171
+ else
172
+ root[part]=[];
173
+ }
174
+ root = root[part];
175
+ part = parts[i + 1];
176
+ }
177
+ root[part] = field.value;
178
+ });
179
+ return $.toJSON(data);
180
+ }
181
+
182
+ function do_update_preview()
183
+ {
184
+ var preview = $("#preview");
185
+ $("body").addClass("busy")
186
+ $.ajax({
187
+ type: "POST",
188
+ url: $("form")[0].action,
189
+ contentType: "application/json",
190
+ data: jsonify($("form")[0]),
191
+ success: function(msg){
192
+ preview.html(msg);
193
+ $("body").removeClass("busy")
194
+ }
195
+ });
196
+ }
197
+
198
+ function update_preview(timeout)
199
+ {
200
+ clearTimeout(window.preview_timeout);
201
+ window.preview_timeout = setTimeout(do_update_preview, timeout);
202
+ }
203
+
204
+
205
+ $(function() {
206
+ $("#left").resizable({handles: "e", resize: function(event, ui) {
207
+ $("#divider").css("left", ui.size.width);
208
+ $("#preview").css("left", ui.size.width+5);
209
+ }});
210
+ $(".sub-fields").accordion({
211
+ collapsible: true,
212
+ autoHeight: false,
213
+ active: false
214
+ });
215
+ var sections = $("#fields").accordion({
216
+ autoHeight: false
217
+ });
218
+
219
+ $(".sprite-option").click(on_click_sprite);
220
+ $(".toolitem, .sprite-option")
221
+ .addClass("ui-state-default ui-corner-all")
222
+ .hover(
223
+ function() { $(this).addClass('ui-state-hover'); },
224
+ function() { $(this).removeClass('ui-state-hover'); }
225
+ );
226
+ $("#fields select, #fields input, #fields textarea").change(function(){
227
+ update_preview(100);
228
+ });
229
+ $("#fields select, #fields input, #fields textarea").keyup(function(){
230
+ update_preview(1000);
231
+ });
232
+ $("#save_button").click(function(){
233
+ $.ajax({
234
+ type: "PUT",
235
+ url: $("form")[0].action,
236
+ contentType: "application/json",
237
+ data: jsonify($("form")[0]),
238
+ success: function(msg){
239
+ window.location = $("form")[0].action.replace('https://', 'http://');
240
+ }
241
+ });
242
+ });
243
+
244
+ $("#cancel_button").click(function(){
245
+ window.location = $("form")[0].action.replace('https://', 'http://');
246
+ });
247
+ $("#logout_button").click(function(){
248
+ window.location = "/logout?dest="+$("form")[0].action.replace('https://', 'http://');
249
+ });
250
+
251
+ });
252
+
253
+