sproutcore 1.6.0.1-java → 1.7.1.beta-java

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 (143) hide show
  1. data/CHANGELOG +21 -0
  2. data/Gemfile +5 -0
  3. data/Rakefile +26 -13
  4. data/VERSION.yml +2 -2
  5. data/lib/Buildfile +43 -4
  6. data/lib/buildtasks/build.rake +10 -0
  7. data/lib/buildtasks/helpers/file_rule.rb +22 -0
  8. data/lib/buildtasks/helpers/file_rule_list.rb +137 -0
  9. data/lib/buildtasks/manifest.rake +133 -122
  10. data/lib/frameworks/sproutcore/CHANGELOG.md +69 -2
  11. data/lib/frameworks/sproutcore/apps/tests/english.lproj/strings.js +1 -0
  12. data/lib/frameworks/sproutcore/frameworks/bootstrap/system/browser.js +28 -22
  13. data/lib/frameworks/sproutcore/frameworks/core_foundation/controllers/array.js +9 -5
  14. data/lib/frameworks/sproutcore/frameworks/core_foundation/controllers/controller.js +1 -1
  15. data/lib/frameworks/sproutcore/frameworks/core_foundation/controls/button.js +18 -13
  16. data/lib/frameworks/sproutcore/frameworks/core_foundation/ext/handlebars/bind.js +5 -3
  17. data/lib/frameworks/sproutcore/frameworks/core_foundation/ext/handlebars/collection.js +2 -0
  18. data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/action_support.js +80 -0
  19. data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/template_helpers/text_field_support.js +84 -116
  20. data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/pane.js +8 -5
  21. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/event.js +157 -157
  22. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/platform.js +5 -3
  23. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/root_responder.js +6 -6
  24. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/sparse_array.js +10 -7
  25. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/mixins/action_support.js +106 -0
  26. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template/collection.js +18 -0
  27. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template/handlebars.js +71 -1
  28. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/attribute_bindings_test.js +38 -0
  29. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/class_name_bindings_test.js +47 -0
  30. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layoutChildViews.js +18 -18
  31. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layoutStyle.js +42 -10
  32. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view.js +158 -1
  33. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/keyboard.js +26 -1
  34. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout_style.js +14 -8
  35. data/lib/frameworks/sproutcore/frameworks/datastore/models/record.js +15 -2
  36. data/lib/frameworks/sproutcore/frameworks/datastore/models/record_attribute.js +108 -108
  37. data/lib/frameworks/sproutcore/frameworks/datastore/system/query.js +1 -1
  38. data/lib/frameworks/sproutcore/frameworks/datastore/system/record_array.js +2 -4
  39. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/record/error_methods.js +2 -2
  40. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/single_attribute.js +26 -0
  41. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/query/builders.js +7 -0
  42. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/record_array/error_methods.js +1 -1
  43. data/lib/frameworks/sproutcore/frameworks/datetime/frameworks/core/system/datetime.js +4 -1
  44. data/lib/frameworks/sproutcore/frameworks/datetime/frameworks/core/tests/system/datetime.js +6 -0
  45. data/lib/frameworks/sproutcore/frameworks/desktop/panes/menu.js +26 -5
  46. data/lib/frameworks/sproutcore/frameworks/desktop/panes/picker.js +97 -96
  47. data/lib/frameworks/sproutcore/frameworks/desktop/system/drag.js +4 -3
  48. data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/menu/ui.js +17 -4
  49. data/lib/frameworks/sproutcore/frameworks/desktop/views/collection.js +7 -7
  50. data/lib/frameworks/sproutcore/frameworks/desktop/views/menu_item.js +7 -5
  51. data/lib/frameworks/sproutcore/frameworks/desktop/views/scroll.js +12 -3
  52. data/lib/frameworks/sproutcore/frameworks/desktop/views/web.js +23 -14
  53. data/lib/frameworks/sproutcore/frameworks/experimental/Buildfile +5 -1
  54. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/menu/render_delegates/menu_scroller.js +28 -0
  55. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/menu/tests/menu/scroll.js +235 -0
  56. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/menu/views/menu/scroll.js +363 -0
  57. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/menu/views/menu/scroller.js +250 -0
  58. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/render_delegates/desktop_scroller.js +92 -0
  59. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/render_delegates/native_scroll.js +25 -0
  60. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/render_delegates/scroll.js +33 -0
  61. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/render_delegates/touch_scroller.js +76 -0
  62. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/tests/scroll/integration.js +50 -0
  63. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/tests/scroll/methods.js +143 -0
  64. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/tests/scroll/ui.js +258 -0
  65. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/core_scroll.js +1164 -0
  66. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/core_scroller.js +332 -0
  67. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/desktop/scroll.js +236 -0
  68. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/desktop/scroller.js +347 -0
  69. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/scroll.js +15 -0
  70. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/scroller.js +10 -0
  71. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/touch/scroll.js +804 -0
  72. data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/touch/scroller.js +133 -0
  73. data/lib/frameworks/sproutcore/frameworks/foundation/resources/text_field.css +3 -3
  74. data/lib/frameworks/sproutcore/frameworks/foundation/validators/number.js +3 -1
  75. data/lib/frameworks/sproutcore/frameworks/foundation/views/text_field.js +3 -3
  76. data/lib/frameworks/sproutcore/frameworks/media/views/audio.js +2 -1
  77. data/lib/frameworks/sproutcore/frameworks/media/views/controls.js +2 -1
  78. data/lib/frameworks/sproutcore/frameworks/media/views/media_slider.js +2 -4
  79. data/lib/frameworks/sproutcore/frameworks/media/views/mini_controls.js +2 -4
  80. data/lib/frameworks/sproutcore/frameworks/media/views/simple_controls.js +2 -4
  81. data/lib/frameworks/sproutcore/frameworks/media/views/video.js +2 -2
  82. data/lib/frameworks/sproutcore/frameworks/routing/system/routes.js +29 -3
  83. data/lib/frameworks/sproutcore/frameworks/runtime/core.js +2 -2
  84. data/lib/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array/replace.js +1 -1
  85. data/lib/frameworks/sproutcore/frameworks/runtime/private/property_chain.js +2 -1
  86. data/lib/frameworks/sproutcore/frameworks/runtime/system/binding.js +3 -3
  87. data/lib/frameworks/sproutcore/frameworks/runtime/system/index_set.js +2 -2
  88. data/lib/frameworks/sproutcore/frameworks/runtime/system/object.js +1 -1
  89. data/lib/frameworks/sproutcore/themes/ace/resources/collection/normal/list_item.css +2 -2
  90. data/lib/frameworks/sproutcore/themes/legacy_theme/english.lproj/segmented.css +1 -1
  91. data/lib/gen/app/templates/apps/@target_name@/Buildfile +3 -5
  92. data/lib/gen/app/templates/apps/@target_name@/resources/_theme.css +18 -0
  93. data/lib/gen/project/templates/@filename@/Buildfile +2 -2
  94. data/lib/sproutcore.rb +30 -5
  95. data/lib/sproutcore/builders.rb +1 -0
  96. data/lib/sproutcore/builders/chance_file.rb +9 -16
  97. data/lib/sproutcore/builders/html.rb +2 -1
  98. data/lib/sproutcore/builders/minify.rb +4 -35
  99. data/lib/sproutcore/builders/module.rb +38 -1
  100. data/lib/sproutcore/builders/split.rb +63 -0
  101. data/lib/sproutcore/builders/strings.rb +7 -1
  102. data/lib/sproutcore/helpers.rb +1 -1
  103. data/lib/sproutcore/helpers/css_split.rb +190 -0
  104. data/lib/sproutcore/helpers/entry_sorter.rb +2 -0
  105. data/lib/sproutcore/helpers/minifier.rb +40 -16
  106. data/lib/sproutcore/helpers/static_helper.rb +35 -17
  107. data/lib/sproutcore/models/manifest.rb +26 -0
  108. data/lib/sproutcore/models/target.rb +12 -1
  109. data/lib/sproutcore/rack.rb +1 -0
  110. data/lib/sproutcore/rack/proxy.rb +244 -225
  111. data/lib/sproutcore/rack/restrict_ip.rb +67 -0
  112. data/lib/sproutcore/rack/service.rb +8 -2
  113. data/lib/sproutcore/tools.rb +102 -46
  114. data/lib/sproutcore/tools/build.rb +91 -43
  115. data/lib/sproutcore/tools/gen.rb +2 -3
  116. data/lib/sproutcore/tools/manifest.rb +22 -16
  117. data/lib/sproutcore/tools/server.rb +21 -0
  118. data/spec/buildtasks/helpers/accept_list +22 -0
  119. data/spec/buildtasks/helpers/accept_list.rb +128 -0
  120. data/spec/buildtasks/helpers/list.json +11 -0
  121. data/spec/buildtasks/manifest/prepare_build_tasks/chance_2x_spec.rb +1 -39
  122. data/spec/buildtasks/manifest/prepare_build_tasks/chance_spec.rb +0 -38
  123. data/spec/buildtasks/manifest/prepare_build_tasks/combine_spec.rb +4 -4
  124. data/spec/buildtasks/manifest/prepare_build_tasks/module_spec.rb +2 -2
  125. data/spec/buildtasks/manifest/prepare_build_tasks/packed_2x_indirect_spec.rb +7 -16
  126. data/spec/buildtasks/manifest/prepare_build_tasks/packed_2x_spec.rb +7 -17
  127. data/spec/buildtasks/manifest/prepare_build_tasks/packed_spec.rb +11 -6
  128. data/spec/fixtures/builder_tests/Buildfile +2 -1
  129. data/spec/fixtures/builder_tests/apps/module_test/modules/required_module/core.js +0 -0
  130. data/spec/lib/builders/module_spec.rb +1 -1
  131. data/spec/spec_helper.rb +1 -0
  132. data/sproutcore.gemspec +4 -9
  133. data/vendor/chance/lib/chance.rb +25 -6
  134. data/vendor/chance/lib/chance/factory.rb +45 -0
  135. data/vendor/chance/lib/chance/instance.rb +173 -28
  136. data/vendor/chance/lib/chance/instance/data_url.rb +0 -29
  137. data/vendor/chance/lib/chance/instance/slicing.rb +57 -4
  138. data/vendor/chance/lib/chance/instance/spriting.rb +112 -21
  139. data/vendor/chance/lib/chance/parser.rb +80 -52
  140. data/vendor/sproutcore/SCCompiler.jar +0 -0
  141. data/vendor/sproutcore/lib/args4j-2.0.12.jar +0 -0
  142. data/vendor/sproutcore/lib/yuicompressor-2.4.2.jar +0 -0
  143. metadata +84 -25
@@ -23,11 +23,6 @@ module Chance
23
23
  output += "\n-webkit-background-size: #{width}px #{height}px;"
24
24
  end
25
25
 
26
-
27
- # FOR IE < 8:
28
- output += '*background-image: url("mhtml:chance-mhtml.txt!' + slice[:css_name] + '")'
29
- output += "\n"
30
-
31
26
  output
32
27
  }
33
28
 
@@ -57,29 +52,5 @@ module Chance
57
52
  end
58
53
  end
59
54
 
60
- def mhtml(opts)
61
- # If there are no slices, ensure that we return an empty file.
62
- return "" if @slices.length == 0
63
-
64
- output = "Content-Type: multipart/related; boundary=\"CHANCE__\"\r\n"
65
-
66
- @slices.each {|name, slice|
67
- output += "\r\n--CHANCE__\r\n"
68
- output += "Content-Location:" + slice[:css_name] + "\r\n"
69
- output += "Content-Type:image/png\r\n"
70
- output += "Content-Transfer-Encoding:base64\r\n\r\n"
71
-
72
- base64Image = base64_for(slice)
73
- output += base64Image.gsub("[^\r]\n", "\r\n")
74
-
75
- output
76
- }
77
-
78
- output += "\r\n--CHANCE__--"
79
-
80
- output
81
- end
82
-
83
-
84
55
  end
85
56
  end
@@ -2,17 +2,57 @@ require "chance/perf"
2
2
 
3
3
  module Chance
4
4
  class Instance
5
-
6
5
  # The Slicing module handles taking a collection of slice definitions to
7
6
  # produce sliced images. It uses ChunkyPNG to perform the slicing, and
8
7
  # stores the sliced image in the slice definition.
9
8
  module Slicing
9
+ class << self
10
+ def add_canvas_to_cache(canvas, file, rect)
11
+ if @canvas_cache.nil?
12
+ @canvas_cache = {}
13
+ end
14
+
15
+ left = rect[:left]
16
+ top = rect[:top]
17
+ width = rect[:width]
18
+ height = rect[:height]
19
+
20
+ key = "#{file[:path]}:#{left},#{top},#{width},#{height}"
21
+ @canvas_cache[key] = {
22
+ mtime: file[:mtime],
23
+ canvas: canvas
24
+ }
25
+ end
26
+
27
+ def get_canvas_from_cache(file, rect)
28
+ if @canvas_cache.nil?
29
+ @canvas_cache = {}
30
+ end
31
+
32
+ left = rect[:left]
33
+ top = rect[:top]
34
+ width = rect[:width]
35
+ height = rect[:height]
36
+
37
+ key = "#{file[:path]}:#{left},#{top},#{width},#{height}"
38
+ hash = @canvas_cache[key]
39
+
40
+ # Check to see if it is new enough
41
+ if not hash.nil? and hash[:mtime] == file[:mtime]
42
+ return hash[:canvas]
43
+ end
44
+
45
+ @canvas_cache[key] = nil
46
+ nil
47
+ end
48
+ end
49
+
10
50
  # performs the slicing indicated by each slice definition, and puts the resulting
11
51
  # image in the slice definition's :image property.
12
52
  #
13
53
  # if x2 is supplied, this will assume it is a second pass to locate any @2x images
14
54
  # and use them to replace the originals.
15
- def slice_images(opts)
55
+ def slice_images(opts)
16
56
  slices = @slices
17
57
  output = ""
18
58
 
@@ -21,7 +61,7 @@ module Chance
21
61
  # Otherwise, consumers will use slice[:file] [:canvas] or [:contents]
22
62
  # to get the original data as needed.
23
63
  slice[:canvas] = nil
24
-
64
+
25
65
  # In any case, if there is one, we need to get the original file and canvas;
26
66
  # this process also tells us if the slice is 2x, etc.
27
67
  canvas = canvas_for slice, opts
@@ -53,7 +93,17 @@ module Chance
53
93
  rect = slice_rect(slice, canvas_width / f, canvas_height / f)
54
94
 
55
95
  if not rect.nil?
56
- slice[:canvas] = canvas.crop(rect[:left] * f, rect[:top] * f, rect[:width] * f, rect[:height] * f)
96
+
97
+ ## CHECK CACHE ##
98
+ file = file_for(slice, opts)
99
+ cached_canvas = Chance::Instance::Slicing.get_canvas_from_cache(file, rect)
100
+ if cached_canvas
101
+ slice[:canvas] = cached_canvas
102
+ else
103
+ slice[:canvas] = canvas.crop(rect[:left] * f, rect[:top] * f, rect[:width] * f, rect[:height] * f)
104
+ Chance::Instance::Slicing.add_canvas_to_cache(slice[:canvas], file, rect)
105
+ end
106
+
57
107
  canvas_width = rect[:height] * f
58
108
  canvas_height = rect[:width] * f
59
109
  end
@@ -62,8 +112,11 @@ module Chance
62
112
  slice[:target_width] = canvas_width / f
63
113
  slice[:target_height] = canvas_height / f
64
114
  end
115
+
116
+
65
117
 
66
118
  end
119
+
67
120
  end
68
121
 
69
122
  # Returns either a RMagick image or a ChunkyPNG canvas for a slice, as applicable.
@@ -18,12 +18,12 @@ module Chance
18
18
  # images in the class's @sprites property and updating the individual slices
19
19
  # with a :sprite property containing the identifier of the sprite, and offset
20
20
  # properties for the offsets within the image.
21
- def generate_sprite_definitions(opts)
21
+ def generate_sprite_definitions(opts)
22
22
  @sprites = {}
23
23
 
24
24
  group_slices_into_sprites(opts)
25
25
  @sprites.each do |key, sprite|
26
- layout_slices_in_sprite sprite
26
+ layout_slices_in_sprite sprite, opts
27
27
  end
28
28
  end
29
29
 
@@ -70,7 +70,7 @@ module Chance
70
70
  # Determines the name of the sprite for the given slice. The sprite
71
71
  # by this name may not exist yet.
72
72
  def sprite_name_for_slice(slice, opts)
73
- if slice[:repeat] == "repeat-both"
73
+ if slice[:repeat] == "repeat"
74
74
  return slice[:path] + (opts[:x2] ? "@2x" : "")
75
75
  end
76
76
 
@@ -79,10 +79,23 @@ module Chance
79
79
 
80
80
  # Performs the layout operation, laying either up-to-down, or "
81
81
  # (for repeat-y slices) left-to-right.
82
- def layout_slices_in_sprite(sprite)
82
+ def layout_slices_in_sprite(sprite, opts)
83
83
  # The position is the position in the layout direction. In vertical mode
84
84
  # (the usual) it is the Y position.
85
85
  pos = 0
86
+
87
+ # Adds some padding that will be painted with a pattern so that it is apparent that
88
+ # CSS is wrong.
89
+ # NOTE: though this is only in debug mode, we DO need to make sure it is on a 2px boundary.
90
+ # This makes sure 2x works properly.
91
+ padding = @options[:pad_sprites_for_debugging] ? 2 : 0
92
+
93
+ # The position within a row. It starts at 0 even if we have padding,
94
+ # because we always just add padding when we set the individual x/y pos.
95
+ inset = 0
96
+
97
+ # The length of the row. Length, when layout out vertically (the usual), is the height
98
+ row_length = 0
86
99
 
87
100
  # The size is the current size of the sprite in the non-layout direction;
88
101
  # for example, in the usual, vertical mode, the size is the width.
@@ -94,17 +107,19 @@ module Chance
94
107
  smallest_size = nil
95
108
 
96
109
  is_horizontal = sprite[:use_horizontal_layout]
97
-
98
- sprite[:slices].each do |slice|
110
+
111
+ # Figure out slice width/heights. We cannot rely on slicing to do this for us
112
+ # because some images may be being passed through as-is.
113
+ sprite[:slices].each {|slice|
99
114
  # We must find a canvas either on the slice (if it was actually sliced),
100
115
  # or on the slice's file. Otherwise, we're in big shit.
101
116
  canvas = slice[:canvas] || slice[:file][:canvas]
102
-
117
+
103
118
  # TODO: MAKE A BETTER ERROR.
104
119
  unless canvas
105
- throw "Could not sprite image " + slice[:path] + "; if it is not a PNG"
120
+ throw "Could not sprite image " + slice[:path] + "; if it is not a PNG, make sure you have rmagick installed"
106
121
  end
107
-
122
+
108
123
  # RMagick has a different API than ChunkyPNG; we have to detect
109
124
  # which one we are using, and use the correct API accordingly.
110
125
  if canvas.respond_to?('columns')
@@ -114,10 +129,10 @@ module Chance
114
129
  slice_width = canvas.width
115
130
  slice_height = canvas.height
116
131
  end
117
-
132
+
118
133
  slice_length = is_horizontal ? slice_width : slice_height
119
134
  slice_size = is_horizontal ? slice_height : slice_width
120
-
135
+
121
136
  # When repeating, we must use the least common multiple so that
122
137
  # we can ensure the repeat pattern works even with multiple repeat
123
138
  # sizes. However, we should take into account how much extra we are
@@ -128,8 +143,41 @@ module Chance
128
143
 
129
144
  size = size.lcm slice_size
130
145
  else
131
- size = [size, slice_size].max
146
+ size = [size, slice_size + padding * 2].max
147
+ end
148
+
149
+ slice[:slice_width] = slice_width.to_i
150
+ slice[:slice_height] = slice_height.to_i
151
+ }
152
+
153
+ # Sort slices from widest/tallest (dependent on is_horizontal) or is_vertical
154
+ # NOTE: This means we are technically sorting reversed
155
+ sprite[:slices].sort! {|a, b|
156
+ # WHY <=> NO WORK?
157
+ if is_horizontal
158
+ b[:slice_height] <=> a[:slice_height]
159
+ else
160
+ b[:slice_width] <=> a[:slice_width]
161
+ end
162
+ }
163
+
164
+ sprite[:slices].each do |slice|
165
+ # We must find a canvas either on the slice (if it was actually sliced),
166
+ # or on the slice's file. Otherwise, we're in big shit.
167
+ canvas = slice[:canvas] || slice[:file][:canvas]
168
+
169
+ slice_width = slice[:slice_width]
170
+ slice_height = slice[:slice_height]
171
+
172
+ slice_length = is_horizontal ? slice_width : slice_height
173
+ slice_size = is_horizontal ? slice_height : slice_width
174
+
175
+ if slice[:repeat] != "no-repeat" or inset + slice_size + padding * 2 > size or not @options[:optimize_sprites]
176
+ pos += row_length
177
+ inset = 0
178
+ row_length = 0
132
179
  end
180
+
133
181
 
134
182
  # We have extras for manual tweaking of offsetx/y. We have to make sure there
135
183
  # is padding for this (on either side)
@@ -149,20 +197,44 @@ module Chance
149
197
  elsif slice[:max_offset_y] > 0 and not is_horizontal
150
198
  pos += slice[:max_offset_y]
151
199
  end
152
-
153
-
154
- slice[:sprite_slice_x] = is_horizontal ? pos : 0
155
- slice[:sprite_slice_y] = is_horizontal ? 0 : pos
200
+
201
+ slice[:sprite_slice_x] = (is_horizontal ? pos : inset)
202
+ slice[:sprite_slice_y] = (is_horizontal ? inset : pos)
203
+
204
+ # add padding for x, only if it a) doesn't repeat or b) repeats vertically because it has horizontal layout
205
+ if slice[:repeat] == "no-repeat" or slice[:repeat] == "repeat-y"
206
+ slice[:sprite_slice_x] += padding
207
+ end
208
+
209
+ if slice[:repeat] == "no-repeat" or slice[:repeat] == "repeat-x"
210
+ slice[:sprite_slice_y] += padding
211
+ end
212
+
156
213
  slice[:sprite_slice_width] = slice_width
157
214
  slice[:sprite_slice_height] = slice_height
158
215
 
159
- pos += slice_length
216
+ inset += slice_size + padding * 2
217
+
218
+ # We pad the row length ONLY if it is a repeat-x, repeat-y, or no-repeat image.
219
+ # If it is 'repeat', we do not pad it, because it should be processed raw.
220
+ row_length = [slice_length + (slice[:repeat] != "repeat" ? padding * 2 : 0), row_length].max
221
+
222
+ # In 2X, make sure we are aligned on a 2px grid.
223
+ # We correct this AFTER positioning because we always position on an even grid anyway;
224
+ # we just may leave that even grid if we have an odd-sized image. We do this after positioning
225
+ # so that the next loop knows if there is space.
226
+ if opts[:x2]
227
+ row_length = (row_length.to_f / 2).ceil * 2
228
+ inset = (inset.to_f / 2).ceil * 2
229
+ end
230
+
160
231
  end
232
+ pos += row_length
161
233
 
162
234
  # TODO: USE A CONSTANT FOR THIS WARNING
163
235
  smallest_size = size if smallest_size == nil
164
236
  if size - smallest_size > 10
165
- puts "WARNING: Used more than 10 extra rows or columns to accomdate repeating slices."
237
+ puts "WARNING: Used more than 10 extra rows or columns to accommodate repeating slices."
166
238
  puts "Wasted up to " + (pos * size-smallest_size).to_s + " pixels"
167
239
  end
168
240
 
@@ -177,6 +249,14 @@ module Chance
177
249
  def generate_sprite(sprite)
178
250
  canvas = canvas_for_sprite(sprite)
179
251
  sprite[:canvas] = canvas
252
+
253
+ # If we are padding sprites, we should paint the background something really
254
+ # obvious & obnoxious. Say, magenta. That's obnoxious. A nice light purple wouldn't
255
+ # be bad, but magenta... that will stick out like a sore thumb (I hope)
256
+ if @options[:pad_sprites_for_debugging]
257
+ magenta = ChunkyPNG::Color.rgb(255, 0, 255)
258
+ canvas.rect(0, 0, sprite[:width], sprite[:height], magenta, magenta)
259
+ end
180
260
 
181
261
  sprite[:slices].each do |slice|
182
262
  x = slice[:sprite_slice_x]
@@ -221,14 +301,18 @@ module Chance
221
301
 
222
302
  # Repeat the pattern to fill the width/height.
223
303
  while top < height do
304
+ left = 0
305
+
224
306
  while left < width do
225
- if target.respond_to?(:compose)
226
- target.compose!(source_canvas, left + x, top + y)
307
+ if target.respond_to?(:replace!)
308
+ target.replace!(source_canvas, left + x, top + y)
227
309
  else
228
310
  target.composite!(source_canvas, left + x, top + y)
229
311
  end
312
+
230
313
  left += source_width
231
314
  end
315
+
232
316
  top += source_height
233
317
  end
234
318
 
@@ -295,7 +379,14 @@ module Chance
295
379
 
296
380
  generate_sprite(sprite) if not sprite[:has_generated]
297
381
 
298
- sprite[:canvas].to_blob
382
+ ret = sprite[:canvas].to_blob
383
+
384
+ if Chance.clear_files_immediately
385
+ sprite[:canvas] = nil
386
+ sprite[:has_generated] = false
387
+ end
388
+
389
+ ret
299
390
  end
300
391
 
301
392
  def sprite_names(opts={})
@@ -23,15 +23,6 @@
23
23
  # - :theme: a selector that will make up the initial value of the $theme
24
24
  # variable. For example: :theme => "ace.test-controls"
25
25
  #
26
- # - :compress: if true, the slice names in the CSS will be shortened.
27
- # This has two drawbacks: 1) the slice names will not be helpful for
28
- # debugging, and 2) if using Chance in a standalone way and committing
29
- # the output to a source control system, the output can change dramatically
30
- # between runs, even if the input CSS is unchanged.
31
- #
32
- # As the most common use of Chance is as part of the SC build tools,
33
- # and this debugging support is usually only required to debug Chance
34
- # itself, :compress defaults to true
35
26
  #
36
27
  # How Slice & Slices work
37
28
  # -------------------------------
@@ -56,16 +47,15 @@ module Chance
56
47
  BEGIN_SCOPE = /\{/
57
48
  END_SCOPE = /\}/
58
49
  THEME_DIRECTIVE = /@theme\s*/
59
- SELECTOR_THEME_VARIABLE = /\$theme\./
50
+ SELECTOR_THEME_VARIABLE = /\$theme(?=[^\w:-])/
60
51
  INCLUDE_SLICES_DIRECTIVE = /@include\s+slices\s*/
61
52
  INCLUDE_SLICE_DIRECTIVE = /@include\s+slice\s*/
62
53
  CHANCE_FILE_DIRECTIVE = /@_chance_file /
63
54
  NORMAL_SCAN_UNTIL = /[^{}@$]+/
64
55
 
65
- @@uid = 0
66
56
 
67
57
  def initialize(string, opts = {})
68
- @opts = { :theme => "", :compress => true }
58
+ @opts = { :theme => "" }
69
59
  @opts.merge!(opts)
70
60
  @path = ""
71
61
 
@@ -77,9 +67,6 @@ module Chance
77
67
 
78
68
  @theme = @opts[:theme]
79
69
 
80
- @@uid += 1
81
- @uid = @@uid
82
-
83
70
  end
84
71
 
85
72
  # SLICE MANAGEMENT
@@ -135,12 +122,8 @@ module Chance
135
122
  slice[:max_offset_x] = [slice[:max_offset_x], opts[:offset_x]].max
136
123
  slice[:max_offset_y] = [slice[:max_offset_y], opts[:offset_y]].max
137
124
  else
138
- parts = slice_path.split("/")
139
- css_name = "__slice_" + parts.join("_")
140
-
141
- if @opts[:compress]
142
- css_name = "__s" + @uid.to_s + "_" + @slices.length.to_s
143
- end
125
+ modified_path = @opts[:instance_id].to_s.gsub(/[^a-zA-Z0-9]/, '_') + "_" + slice_path.gsub(/[^a-zA-Z0-9]/, '_')
126
+ css_name = "__chance_slice_#{modified_path}"
144
127
 
145
128
  slice = opts.merge({
146
129
  :name => slice_path,
@@ -151,12 +134,16 @@ module Chance
151
134
  :max_offset_x => opts[:offset_x],
152
135
  :max_offset_y => opts[:offset_y],
153
136
  :imaged_offset_x => 0, # the imaging process will re-define these.
154
- :imaged_offset_y => 0
137
+ :imaged_offset_y => 0,
138
+
139
+ :used_by => []
155
140
  })
156
141
 
157
142
  @slices[slice_path] = slice
158
143
  end
159
144
 
145
+ slice[:used_by] << { :path => @path }
146
+
160
147
  return slice
161
148
  end
162
149
 
@@ -358,7 +345,7 @@ module Chance
358
345
  scanner = @scanner
359
346
  scanner.scan SELECTOR_THEME_VARIABLE
360
347
 
361
- output = "\#{$theme}."
348
+ output = "\#{$theme}"
362
349
 
363
350
  return output
364
351
  end
@@ -486,7 +473,7 @@ module Chance
486
473
 
487
474
  # We prefix with -chance; this should let everything be passed through more
488
475
  # or less as-is. Postprocessing will turn it into -background-position.
489
- output += "-chance-offset: \"#{slice[:name]}\" #{slice[:offset_x]} #{slice[:offset_y]};"
476
+ output += "-chance-offset: \"#{slice[:name]}\" #{offset[0]} #{offset[1]};"
490
477
  output += "background-repeat: " + slice[:repeat]
491
478
  return output
492
479
  end
@@ -564,17 +551,25 @@ module Chance
564
551
  fill_width = Integer(fill[0])
565
552
  fill_height = Integer(fill[1])
566
553
 
567
- skip_top_left = values.include? 'skip-top-left'
568
- skip_top = values.include? 'skip-top'
569
- skip_top_right = values.include? 'skip-top-right'
554
+ # skip control
555
+ skip = arguments[:skip]
556
+ if skip.nil?
557
+ skip = []
558
+ else
559
+ skip = skip.split /\s+/
560
+ end
561
+
562
+ skip_top_left = skip.include? 'top-left'
563
+ skip_top = skip.include? 'top'
564
+ skip_top_right = skip.include? 'skip-top-right'
570
565
 
571
- skip_left = values.include? 'skip-left'
572
- skip_middle = values.include? 'skip-middle'
573
- skip_right = values.include? 'skip-right'
566
+ skip_left = skip.include? 'left'
567
+ skip_middle = skip.include? 'middle'
568
+ skip_right = skip.include? 'right'
574
569
 
575
- skip_bottom_left = values.include? 'skip-bottom-left'
576
- skip_bottom = values.include? 'skip-bottom'
577
- skip_bottom_right = values.include? 'skip-bottom-right'
570
+ skip_bottom_left = skip.include? 'bottom-left'
571
+ skip_bottom = skip.include? 'bottom'
572
+ skip_bottom_right = skip.include? 'bottom-right'
578
573
 
579
574
  filename = parse_string(arguments[0])
580
575
 
@@ -645,7 +640,7 @@ module Chance
645
640
  :sprite_padding => arguments[:"middle-padding"],
646
641
  :offset => arguments[:"middle-offset"],
647
642
  :filename => filename,
648
- :repeat => fill_height != 0 ? (fill_width != 0 ? "repeat-both" : "repeat-y") : (fill_width != 0 ? "repeat-x" : nil)
643
+ :repeat => fill_height != 0 ? (fill_width != 0 ? "repeat" : "repeat-y") : (fill_width != 0 ? "repeat-x" : nil)
649
644
 
650
645
 
651
646
  # fill in width, height or right, bottom depending on fill settings
@@ -734,9 +729,18 @@ module Chance
734
729
  output = ""
735
730
 
736
731
  # LEFT
737
- if should_include_slice?(top_left_slice) and not skip_top_left
732
+ # NOTE: we write it even if we are supposed to skip; we only wrap the slice include portion in
733
+ if should_include_slice?(top_left_slice)
738
734
  output += "& > .top-left {\n"
739
- output += generate_slice_include(top_left_slice) + ";"
735
+
736
+ # IF we are skipping the top left slice, we don't want the actual slice include-- but the layout
737
+ # information we still want. So, only bracket the generate_slice_include.
738
+ #
739
+ # Potential issue: slice_layout doesn't handle repeat settings. In theory, this should rarely be
740
+ # an issue (because you aren't setting a background for the skipped slice.
741
+ if not skip_top_left
742
+ output += generate_slice_include(top_left_slice) + ";"
743
+ end
740
744
 
741
745
  output += "\nposition: absolute;\n"
742
746
  output += slice_layout(top_left_slice)
@@ -744,9 +748,12 @@ module Chance
744
748
  output += "}\n"
745
749
  end
746
750
 
747
- if should_include_slice?(left_slice) and not skip_left
751
+ if should_include_slice?(left_slice)
748
752
  output += "& > .left {\n"
749
- output += generate_slice_include(left_slice) + ";"
753
+
754
+ if not skip_left
755
+ output += generate_slice_include(left_slice) + ";"
756
+ end
750
757
 
751
758
  output += "\nposition: absolute;\n"
752
759
  output += slice_layout(left_slice.merge({ :bottom => bottom }))
@@ -754,9 +761,12 @@ module Chance
754
761
  output += "}\n"
755
762
  end
756
763
 
757
- if should_include_slice?(bottom_left_slice) and not skip_bottom_left
764
+ if should_include_slice?(bottom_left_slice)
758
765
  output += "& > .bottom-left {\n"
759
- output += generate_slice_include(bottom_left_slice) + ";"
766
+
767
+ if not skip_bottom_left
768
+ output += generate_slice_include(bottom_left_slice) + ";"
769
+ end
760
770
 
761
771
  output += "\nposition: absolute;\n"
762
772
  output += slice_layout(bottom_left_slice)
@@ -765,9 +775,12 @@ module Chance
765
775
  end
766
776
 
767
777
  # MIDDLE
768
- if should_include_slice?(top_slice) and not skip_top
778
+ if should_include_slice?(top_slice)
769
779
  output += "& > .top {\n"
770
- output += generate_slice_include(top_slice) + ";"
780
+
781
+ if not skip_top
782
+ output += generate_slice_include(top_slice) + ";"
783
+ end
771
784
 
772
785
  output += "\nposition: absolute;\n"
773
786
  output += slice_layout(top_slice.merge({ :right => right }))
@@ -775,9 +788,12 @@ module Chance
775
788
  output += "}\n"
776
789
  end
777
790
 
778
- if should_include_slice?(middle_slice) and not skip_middle
791
+ if should_include_slice?(middle_slice)
779
792
  output += "& > .middle {\n"
780
- output += generate_slice_include(middle_slice) + ";"
793
+
794
+ if not skip_middle
795
+ output += generate_slice_include(middle_slice) + ";"
796
+ end
781
797
 
782
798
  output += "\nposition: absolute;\n"
783
799
  output += slice_layout(middle_slice.merge({ :bottom => bottom, :right => right }))
@@ -786,9 +802,12 @@ module Chance
786
802
  output += "}\n"
787
803
  end
788
804
 
789
- if should_include_slice?(bottom_slice) and not skip_bottom
805
+ if should_include_slice?(bottom_slice)
790
806
  output += "& > .bottom {\n"
791
- output += generate_slice_include(bottom_slice) + ";"
807
+
808
+ if not skip_bottom
809
+ output += generate_slice_include(bottom_slice) + ";"
810
+ end
792
811
 
793
812
  output += "\nposition: absolute;\n"
794
813
  output += slice_layout(bottom_slice.merge({ :right => right }))
@@ -798,9 +817,12 @@ module Chance
798
817
  end
799
818
 
800
819
  # RIGHT
801
- if should_include_slice?(top_right_slice) and not skip_top_right
820
+ if should_include_slice?(top_right_slice)
802
821
  output += "& > .top-right {\n"
803
- output += generate_slice_include(top_right_slice) + ";"
822
+
823
+ if not skip_top_right
824
+ output += generate_slice_include(top_right_slice) + ";"
825
+ end
804
826
 
805
827
  output += "\nposition: absolute;\n"
806
828
  output += slice_layout(top_right_slice)
@@ -808,9 +830,12 @@ module Chance
808
830
  output += "}\n"
809
831
  end
810
832
 
811
- if should_include_slice?(right_slice) and not skip_right
833
+ if should_include_slice?(right_slice)
812
834
  output += "& > .right {\n"
813
- output += generate_slice_include(right_slice) + ";"
835
+
836
+ if not skip_right
837
+ output += generate_slice_include(right_slice) + ";"
838
+ end
814
839
 
815
840
  output += "\nposition: absolute;\n"
816
841
  output += slice_layout(right_slice.merge({ :bottom => bottom }))
@@ -818,9 +843,12 @@ module Chance
818
843
  output += "}\n"
819
844
  end
820
845
 
821
- if should_include_slice?(bottom_right_slice) and not skip_bottom_right
846
+ if should_include_slice?(bottom_right_slice)
822
847
  output += "& > .bottom-right {\n"
823
- output += generate_slice_include(bottom_right_slice) + ";"
848
+
849
+ if not skip_bottom_right
850
+ output += generate_slice_include(bottom_right_slice) + ";"
851
+ end
824
852
 
825
853
  output += "\nposition: absolute;\n"
826
854
  output += slice_layout(bottom_right_slice)