sproutcore 1.5.0.pre.4 → 1.5.0.pre.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (174) hide show
  1. data/CHANGELOG +6 -0
  2. data/VERSION.yml +1 -1
  3. data/lib/Buildfile +1 -1
  4. data/lib/buildtasks/build.rake +14 -6
  5. data/lib/buildtasks/manifest.rake +171 -72
  6. data/lib/frameworks/sproutcore/Buildfile +3 -5
  7. data/lib/frameworks/sproutcore/CHANGELOG.md +9 -0
  8. data/lib/frameworks/sproutcore/apps/test_controls/resources/main_page.js +2 -1
  9. data/lib/frameworks/sproutcore/apps/test_controls/resources/progress_page.js +7 -17
  10. data/lib/frameworks/sproutcore/frameworks/bootstrap/system/browser.js +7 -1
  11. data/lib/frameworks/sproutcore/frameworks/bootstrap/system/loader.js +14 -1
  12. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/browser.js +0 -2
  13. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/event.js +1 -1
  14. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/root_responder.js +14 -3
  15. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/template/collection.js +1 -1
  16. data/lib/frameworks/sproutcore/frameworks/datastore/models/record.js +2 -2
  17. data/lib/frameworks/sproutcore/frameworks/datastore/models/record_attribute.js +6 -0
  18. data/lib/frameworks/sproutcore/frameworks/datastore/system/store.js +1 -1
  19. data/lib/frameworks/sproutcore/frameworks/desktop/mixins/scrollable.js +1 -1
  20. data/lib/frameworks/sproutcore/frameworks/desktop/panes/alert.js +49 -4
  21. data/lib/frameworks/sproutcore/frameworks/desktop/panes/menu.js +8 -0
  22. data/lib/frameworks/sproutcore/frameworks/desktop/panes/panel.js +46 -1
  23. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/button.js +32 -5
  24. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/checkbox.js +32 -6
  25. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/disclosure.js +31 -3
  26. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/progress.js +15 -3
  27. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/radio.js +28 -7
  28. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/segmented.js +1 -1
  29. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/slider.js +20 -1
  30. data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/well.js +2 -4
  31. data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/alert/ui.js +40 -34
  32. data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/menu/ui.js +35 -0
  33. data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/panel/ui.js +43 -0
  34. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/button/ui.js +47 -0
  35. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/checkbox/methods.js +6 -16
  36. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/checkbox/ui.js +21 -0
  37. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/disclosure/ui.js +41 -1
  38. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/progress/ui.js +128 -0
  39. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/radio/ui.js +93 -3
  40. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/scroll/ui.js +13 -1
  41. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/scroller.js +28 -0
  42. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/methods.js +47 -0
  43. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/ui.js +51 -0
  44. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/toolbar/method.js +33 -0
  45. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/toolbar/ui.js +29 -0
  46. data/lib/frameworks/sproutcore/frameworks/desktop/views/checkbox.js +28 -0
  47. data/lib/frameworks/sproutcore/frameworks/desktop/views/disclosure.js +9 -1
  48. data/lib/frameworks/sproutcore/frameworks/desktop/views/list_item.js +148 -134
  49. data/lib/frameworks/sproutcore/frameworks/desktop/views/menu_item.js +18 -0
  50. data/lib/frameworks/sproutcore/frameworks/desktop/views/menu_scroll.js +30 -3
  51. data/lib/frameworks/sproutcore/frameworks/desktop/views/progress.js +9 -0
  52. data/lib/frameworks/sproutcore/frameworks/desktop/views/radio.js +52 -4
  53. data/lib/frameworks/sproutcore/frameworks/desktop/views/scroll.js +2 -1
  54. data/lib/frameworks/sproutcore/frameworks/desktop/views/scroller.js +36 -3
  55. data/lib/frameworks/sproutcore/frameworks/desktop/views/segmented.js +1 -1
  56. data/lib/frameworks/sproutcore/frameworks/desktop/views/slider.js +9 -1
  57. data/lib/frameworks/sproutcore/frameworks/desktop/views/split.js +15 -4
  58. data/lib/frameworks/sproutcore/frameworks/desktop/views/split_divider.js +1 -6
  59. data/lib/frameworks/sproutcore/frameworks/desktop/views/tab.js +4 -2
  60. data/lib/frameworks/sproutcore/frameworks/desktop/views/toolbar.js +7 -0
  61. data/lib/frameworks/sproutcore/frameworks/desktop/views/well.js +1 -2
  62. data/lib/frameworks/sproutcore/frameworks/forms/views/form.js +3 -1
  63. data/lib/frameworks/sproutcore/frameworks/foundation/english.lproj/bootstrap.rhtml +1 -1
  64. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/auto_resize.js +0 -9
  65. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/editable.js +1 -1
  66. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/flowed_layout.js +2 -0
  67. data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/canvas_image.js +1 -1
  68. data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/label.js +25 -1
  69. data/lib/frameworks/sproutcore/frameworks/foundation/system/chance.js +64 -0
  70. data/lib/frameworks/sproutcore/frameworks/foundation/system/module.js +34 -27
  71. data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/editable/ui.js +42 -0
  72. data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/inline_text_field/ui.js +62 -0
  73. data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/image/ui.js +0 -8
  74. data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/label/ui.js +12 -0
  75. data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/text_field/ui.js +48 -1
  76. data/lib/frameworks/sproutcore/frameworks/foundation/views/field.js +19 -0
  77. data/lib/frameworks/sproutcore/frameworks/foundation/views/image.js +2 -0
  78. data/lib/frameworks/sproutcore/frameworks/foundation/views/label.js +11 -5
  79. data/lib/frameworks/sproutcore/frameworks/foundation/views/text_field.js +152 -74
  80. data/lib/frameworks/sproutcore/frameworks/runtime/private/observer_queue.js +12 -9
  81. data/lib/frameworks/sproutcore/frameworks/runtime/system/logger.js +1476 -176
  82. data/lib/frameworks/sproutcore/frameworks/runtime/system/run_loop.js +0 -2
  83. data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/logger.js +227 -32
  84. data/lib/frameworks/sproutcore/frameworks/statechart/system/state.js +11 -11
  85. data/lib/frameworks/sproutcore/frameworks/statechart/system/statechart.js +1 -1
  86. data/lib/frameworks/sproutcore/frameworks/testing/system/runner.js +10 -0
  87. data/lib/frameworks/sproutcore/lib/index.rhtml +30 -8
  88. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/18px/segmented.css +4 -4
  89. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/24px/segmented.css +4 -4
  90. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/30px/segmented.css +4 -4
  91. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/44px/segmented.css +4 -4
  92. data/lib/frameworks/sproutcore/themes/ace/resources/segmented/segmented.css +4 -0
  93. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/slider.css +5 -1
  94. data/lib/frameworks/sproutcore/themes/ace/resources/slider/ace/slider.js +11 -3
  95. data/lib/frameworks/sproutcore/themes/ace/resources/well/well.css +7 -8
  96. data/lib/frameworks/sproutcore/themes/ace/resources/well/well.js +2 -4
  97. data/lib/gen/app/templates/apps/@target_name@/Buildfile +14 -0
  98. data/lib/gen/app/templates/apps/@target_name@/theme.js +27 -0
  99. data/lib/gen/html_app/templates/apps/@target_name@/resources/stylesheets/@target_name@.css +4 -0
  100. data/lib/gen/project/templates/@filename@/Buildfile +7 -2
  101. data/lib/gen/theme/templates/themes/@target_name@/Buildfile +3 -0
  102. data/lib/gen/theme/templates/themes/@target_name@/theme.js +23 -0
  103. data/lib/sproutcore/builders.rb +2 -0
  104. data/lib/sproutcore/builders/chance.rb +64 -0
  105. data/lib/sproutcore/builders/chance_file.rb +59 -0
  106. data/lib/sproutcore/builders/combine.rb +0 -45
  107. data/lib/sproutcore/builders/html.rb +1 -1
  108. data/lib/sproutcore/builders/minify.rb +5 -17
  109. data/lib/sproutcore/builders/module.rb +2 -2
  110. data/lib/sproutcore/builders/string_wrapper.rb +13 -15
  111. data/lib/sproutcore/helpers.rb +1 -1
  112. data/lib/sproutcore/helpers/minifier.rb +56 -0
  113. data/lib/sproutcore/helpers/static_helper.rb +86 -40
  114. data/lib/sproutcore/models/generator.rb +16 -0
  115. data/lib/sproutcore/models/manifest_entry.rb +8 -1
  116. data/lib/sproutcore/models/target.rb +101 -33
  117. data/lib/sproutcore/tools.rb +0 -7
  118. data/lib/sproutcore/tools/build.rb +2 -37
  119. data/spec/buildtasks/manifest/prepare_build_tasks/chance_spec.rb +100 -0
  120. data/spec/buildtasks/manifest/prepare_build_tasks/combine_spec.rb +86 -9
  121. data/spec/buildtasks/manifest/prepare_build_tasks/css_spec.rb +1 -1
  122. data/spec/buildtasks/manifest/prepare_build_tasks/minify_spec.rb +1 -1
  123. data/spec/buildtasks/manifest/prepare_build_tasks/module_info_spec.rb +96 -0
  124. data/spec/buildtasks/manifest/prepare_build_tasks/module_spec.rb +83 -0
  125. data/spec/buildtasks/manifest/prepare_build_tasks/packed_spec.rb +37 -4
  126. data/spec/buildtasks/manifest/spec_helper.rb +4 -0
  127. data/spec/fixtures/builder_tests/Buildfile +11 -9
  128. data/spec/fixtures/builder_tests/apps/chance_test/Buildfile +14 -0
  129. data/spec/fixtures/builder_tests/apps/chance_test/core.js +27 -0
  130. data/spec/fixtures/builder_tests/apps/chance_test/main.js +30 -0
  131. data/spec/fixtures/builder_tests/apps/chance_test/resources/demo.css +6 -0
  132. data/spec/fixtures/builder_tests/apps/chance_test/resources/last_file.css +7 -0
  133. data/spec/fixtures/builder_tests/apps/chance_test/resources/loading.rhtml +9 -0
  134. data/spec/fixtures/builder_tests/apps/chance_test/resources/main_page.js +24 -0
  135. data/spec/fixtures/builder_tests/apps/chance_test/resources/z_first_file.css +6 -0
  136. data/spec/fixtures/builder_tests/apps/chance_test/theme.js +27 -0
  137. data/spec/fixtures/builder_tests/apps/module_test/module.js +1 -0
  138. data/spec/fixtures/builder_tests/apps/module_test/modules/deferred_module/english.lproj/req_style_2.css +0 -0
  139. data/spec/fixtures/builder_tests/apps/module_test/modules/deferred_module/english.lproj/test.rhtml +1 -0
  140. data/spec/fixtures/builder_tests/apps/module_test/modules/deferred_module/javascript.js +1 -0
  141. data/spec/fixtures/builder_tests/apps/module_test/modules/deferred_module/lib/alt_layout.rhtml +0 -0
  142. data/spec/fixtures/builder_tests/apps/module_test/modules/deferred_module/req_js_2.js +0 -0
  143. data/spec/fixtures/builder_tests/apps/module_test/modules/dynamic_req_target_1/dynamic_req_js_1.js +0 -0
  144. data/spec/fixtures/builder_tests/apps/module_test/modules/dynamic_req_target_1/english.lproj/dynamic_req_style_1.css +0 -0
  145. data/spec/fixtures/builder_tests/apps/module_test/modules/inlined_module/README +0 -0
  146. data/spec/fixtures/builder_tests/apps/module_test/modules/required_target/english.lproj/req_style_1.css +0 -0
  147. data/spec/fixtures/builder_tests/apps/module_test/modules/required_target/english.lproj/strings.js +4 -0
  148. data/spec/fixtures/builder_tests/apps/module_test/modules/required_target/english.lproj/test.rhtml +1 -0
  149. data/spec/fixtures/builder_tests/apps/module_test/modules/required_target/req_js_1.js +0 -0
  150. data/spec/fixtures/helper_tests/apps/minifier_test/core.js +8 -0
  151. data/spec/fixtures/real_world/Buildfile +11 -1
  152. data/spec/fixtures/real_world/apps/account/modules/preferences/README +0 -0
  153. data/spec/fixtures/real_world/apps/calendar/modules/preferences/README +0 -0
  154. data/spec/fixtures/real_world/apps/contacts/modules/preferences/README +0 -0
  155. data/spec/fixtures/real_world/apps/contacts/modules/printing/README +0 -0
  156. data/spec/fixtures/real_world/apps/mail/modules/preferences/README +0 -0
  157. data/spec/fixtures/real_world/apps/mail/modules/printing/README +0 -0
  158. data/spec/fixtures/real_world/apps/photos/modules/email/README +0 -0
  159. data/spec/fixtures/real_world/apps/photos/modules/preferences/README +0 -0
  160. data/spec/lib/builders/chance_file_spec.rb +63 -0
  161. data/spec/lib/builders/chance_spec.rb +81 -0
  162. data/spec/lib/builders/module_spec.rb +133 -0
  163. data/spec/lib/helpers/minifier.rb +31 -0
  164. data/spec/lib/models/project/find_targets_for_spec.rb +1 -1
  165. data/vendor/chance/lib/chance/imagers/data_url.rb +68 -17
  166. data/vendor/chance/lib/chance/instance.rb +55 -30
  167. data/vendor/chance/lib/chance/parser.rb +1 -1
  168. data/vendor/chance/lib/chance/slicing.rb +39 -3
  169. metadata +52 -7
  170. data/lib/frameworks/sproutcore/frameworks/foundation/system/logger.js +0 -163
  171. data/lib/frameworks/sproutcore/frameworks/foundation/tests/system/logger.js +0 -44
  172. data/spec/buildtasks/manifest/prepare_build_tasks/bundle_spec.rb +0 -254
  173. data/spec/fixtures/builder_tests/apps/bundle_test/bundle.js +0 -1
  174. data/spec/lib/builders/bundle_spec.rb +0 -295
@@ -0,0 +1,81 @@
1
+ require "lib/builders/spec_helper"
2
+
3
+ describe SC::Builder::Chance do
4
+
5
+ include SC::SpecHelpers
6
+ include SC::BuilderSpecHelper
7
+
8
+ before do
9
+ std_before :chance_test
10
+ end
11
+
12
+ after do
13
+ std_after
14
+ end
15
+
16
+ it "should combine CSS files according to sc_require statements" do
17
+ # Chance's output is not guaranteed to be the same each time it runs.
18
+ # It will have the same effect, but details (such as some class names)
19
+ # will differ.
20
+ #
21
+ # To accurately test, we must simply look for file names in the comments
22
+ # SCSS writes and make sure the files are in the right order.
23
+
24
+ # First, generate the entries to be handed to the Chance entry.
25
+ file_names = %w(z_first_file.css demo.css last_file.css)
26
+ entries = file_names.reverse.map do |filename|
27
+ path = File.join(@target.source_root, 'resources', filename)
28
+ entry = @manifest.add_entry filename,
29
+ :source_path => path,
30
+ :staging_path => path,
31
+ :build_path => path
32
+
33
+ File.exist?(entry.source_path).should be_true
34
+ entry
35
+ end
36
+
37
+ entries.length.should > 0
38
+ file_names.length.should > 0
39
+
40
+ # We will hand the entries over in the WRONG order, because Chance parses
41
+ # the sc_require to determine the correct order. ordered entries should be ignored
42
+ filename = "stylesheet.css"
43
+ entry = @manifest.add_composite filename,
44
+ :source_entries => entries,
45
+ :ordered_entries => entries
46
+
47
+ dest = entry.build_path
48
+
49
+ # Build using the entry we created
50
+ SC::Builder::Chance.build(entry, dest)
51
+ result = File.readlines(dest)*""
52
+
53
+ # Check that a chance instance is created
54
+ # since we don't have any sc_require, it should have the same output
55
+ entry[:chance].files["chance.css"].should == result
56
+
57
+ # We also expect the 2x to be the same.
58
+ entry[:chance].files["chance@2x.css"].should == result
59
+
60
+ # Check that all files were generated
61
+ %w(chance.css chance@2x.css chance.js chance-mhtml.txt).each {|e|
62
+ entry[:chance].files.should include(e)
63
+ }
64
+
65
+ # We loop through. If the file name matches the last one, we skip the check; if it does not,
66
+ # we check that it is the next item in file_names
67
+ last = "chance_main.css"
68
+ result.gsub(/\/\* line [0-9]+, (.*?)\s*\*\//) {|e|
69
+ next if $1 == last
70
+
71
+ # Chance appends .scss, so we have to expect that
72
+ last = file_names.shift + ".scss"
73
+ $1.end_with?(last).should be_true
74
+ }
75
+
76
+ file_names.length.should == 0
77
+
78
+ end
79
+
80
+
81
+ end
@@ -0,0 +1,133 @@
1
+ require "lib/builders/spec_helper"
2
+
3
+ describe 'SC::Builder::ModuleInfo' do
4
+
5
+ include SC::SpecHelpers
6
+ include SC::BuilderSpecHelper
7
+
8
+ describe "app target" do
9
+
10
+ before do
11
+ std_before :module_test
12
+
13
+ # most of these tests assume load_debug is turned off like it would be
14
+ # in production mode
15
+ @target.config.load_debug = false
16
+ @target.config.theme = nil
17
+ @target.config.use_packed = false
18
+ @target.config.timestamp_urls = false
19
+
20
+ # make sure all targets have the same settings...
21
+ @target.expand_required_targets.each do |t|
22
+ t.config.timestamp_urls = false
23
+ end
24
+
25
+ # make sure all targets have the same settings...
26
+ @target.modules.each do |t|
27
+ t.config.timestamp_urls = false
28
+ end
29
+
30
+ # run std rules to run manifest. Then verify preconditions to make sure
31
+ # no other changes to the build system effect the ability of these tests
32
+ # to run properly.
33
+ @manifest.build!
34
+ end
35
+
36
+ after do
37
+ std_after
38
+ end
39
+
40
+ it "VERIFY PRECONDITIONS" do
41
+ @target.should be_loadable
42
+ end
43
+
44
+ it "should require all the required targets" do
45
+ req = @target.required_targets
46
+
47
+ req.size.should == 1
48
+ req.first.target_name.should == :'/module_test/inlined_module'
49
+ end
50
+
51
+ it "should require one deferred module" do
52
+ req = @target.modules
53
+
54
+ req.size.should == 4
55
+ req.first.target_name.should == :'/module_test/deferred_module'
56
+ req[1].target_name.should == :'/module_test/required_target'
57
+ req[2].target_name.should == :'/module_test/inlined_module'
58
+ req[3].target_name.should == :'/module_test/dynamic_req_target_1'
59
+ end
60
+ end
61
+
62
+ describe "static framework target" do
63
+
64
+ before do
65
+ std_before :req_target_1
66
+
67
+ # most of these tests assume load_debug is turned off like it would be
68
+ # in production mode
69
+ @target.config.load_debug = false
70
+ @target.config.theme = nil
71
+ @target.config.timestamp_urls = false
72
+
73
+ # run std rules to run manifest. Then verify preconditions to make sure
74
+ # no other changes to the build system effect the ability of these tests
75
+ # to run properly.
76
+ @manifest.build!
77
+ end
78
+
79
+ after do
80
+ std_after
81
+ end
82
+
83
+ it "VERIFY PRECONDITIONS" do
84
+ @target.should_not be_loadable
85
+ end
86
+
87
+ it "should not require a dynamic framework" do
88
+ (req = @target.modules).size.should == 0
89
+ end
90
+ end
91
+
92
+ describe "dynamic framework target" do
93
+
94
+ before do
95
+ std_before :req_target_2
96
+
97
+ # most of these tests assume load_debug is turned off like it would be
98
+ # in production mode
99
+ @target.config.load_debug = false
100
+ @target.config.theme = nil
101
+ @target.config.timestamp_urls = false
102
+
103
+ # make sure all targets have the same settings...
104
+ @target.expand_required_targets.each do |t|
105
+ t.config.timestamp_urls = false
106
+ end
107
+
108
+ # make sure all targets have the same settings...
109
+ @target.modules.each do |t|
110
+ t.config.timestamp_urls = false
111
+ end
112
+
113
+ # run std rules to run manifest. Then verify preconditions to make sure
114
+ # no other changes to the build system effect the ability of these tests
115
+ # to run properly.
116
+ @manifest.build!
117
+ end
118
+
119
+ after do
120
+ std_after
121
+ end
122
+
123
+ it "VERIFY PRECONDITIONS" do
124
+ @target.should_not be_loadable
125
+ end
126
+
127
+ it "should require its own dynamic framework" do
128
+ (req = @target.modules).size.should == 0
129
+ (req = @target.required_targets).size.should == 1
130
+ end
131
+ end
132
+
133
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe SC::Helpers::Minifier do
4
+ include SC::SpecHelpers
5
+
6
+ before do
7
+ @project = temp_project :helper_tests
8
+ @target = @project.target_for :minifier_test
9
+ @manifest = @target.manifest_for :language => :en
10
+ @manifest.prepare!
11
+ end
12
+
13
+ it "saves items to be minified" do
14
+ SC::Helpers::Minifier << "/test/path"
15
+ SC::Helpers::Minifier << "/second/path"
16
+
17
+ SC::Helpers::Minifier.queue.should include("/test/path")
18
+ SC::Helpers::Minifier.queue.should include("/second/path")
19
+ end
20
+
21
+ it "minifies a file when given a path" do
22
+ source_path = File.join(@target.source_root, 'core.js')
23
+
24
+ SC::Helpers::Minifier.minify!(source_path)
25
+
26
+ # Fixture file contains nothing but comments. They should all be removed
27
+ # after minification.
28
+ IO.read(source_path).should == ""
29
+ end
30
+
31
+ end
@@ -33,7 +33,7 @@ describe SC::Project, 'find_targets_for' do
33
33
  target_types[:clients].should eql(:app)
34
34
  target_types[:frameworks].should eql(:framework)
35
35
  target_types[:themes].should eql(:theme)
36
- target_types[:bundles].should eql(:framework)
36
+ target_types[:modules].should eql(:module)
37
37
  project.config.allow_nested_targets.should be_true
38
38
 
39
39
  # Note, this expectation assumes the fixtures in find_targets/standard has
@@ -7,6 +7,11 @@ module Chance
7
7
  # The DataURL Imager creates CSS with data urls for each slice.
8
8
  class DataURLImager < Chance::Imager
9
9
 
10
+ # Creates CSS for the slices to be provided to SCSS.
11
+ # This CSS is incomplete; it will need postprocessing. This CSS
12
+ # is generated with the set of slice definitions in @slices; the actual
13
+ # slicing operation has not yet taken place. The postprocessing portion
14
+ # receives sliced versions.
10
15
  def css
11
16
  output = ""
12
17
  slices = @slices
@@ -14,34 +19,80 @@ module Chance
14
19
  slices.each do |name, slice|
15
20
  # so, the path should be the path in the chance instance
16
21
  output += "." + slice[:css_name] + " { "
17
- output += "background: url("
22
+ output += "_sc_chance: \"#{name}\";"
23
+ output += "} \n"
24
+ end
18
25
 
19
- # set the mime type from the extension (while taking care of .jpg extensions)
20
- mimeType = (slice[:path] =~ /jpg$/) ? "image/jpeg" : "image/" + slice[:path].slice(/(gif|jpeg|png)$/)
26
+ return output
21
27
 
22
- output += '"data:' + mimeType
23
- output += ';base64,'
28
+ end
24
29
 
25
- # ChunkyPNG & RMagick images respond to to_blob, other images will be encoded from their contents
26
- if (slice[:image].respond_to? "to_blob")
27
- method = slice[:image].method(:to_blob)
30
+ def postprocess_css(src, slices)
31
+ src.gsub (/_sc_chance\:\s*["'](.*)["']\s*;/) {|match|
32
+ slice = slices[$1]
33
+
34
+ output = 'background: url("data:image/png;base64,'
35
+
36
+ base64Image = Base64.encode64(slice[:image].to_blob(:fast_rgba)).gsub("\n", "")
37
+ output += base64Image
28
38
 
29
- # ChunkyPNG takes an argument to to_blob
30
- slice[:image] = (method.arity == 1) ? slice[:image].to_blob(:fast_rgba) : slice[:image].to_blob
31
- end
39
+ output += '");'
40
+ output += "\n"
32
41
 
33
- base64Image = Base64.encode64(slice[:image])
42
+ # FOR IE < 8:
43
+ output += '*background: url("mhtml:chance-mhtml.txt!' + slice[:css_name] + '");'
44
+ output += "\n"
34
45
 
46
+ output
47
+ }
48
+ end
49
+
50
+ def postprocess_css_2x(src, slices)
51
+ src.gsub (/_sc_chance\:\s*["'](.*)["']\s*;/) {|match|
52
+ slice = slices[$1]
53
+
54
+ output = 'background: url("data:image/png;base64,'
55
+
56
+ base64Image = Base64.encode64(slice[:image].to_blob(:fast_rgba)).gsub("\n", "")
35
57
  output += base64Image
36
58
 
37
- output += '"'
38
- output += ");"
39
- output += "} \n"
40
- end
59
+ output += '");'
41
60
 
42
- return output
61
+ output += "\n-webkit-background-size: " + slice[:target_width].to_s + "px "
62
+ output += slice[:target_height].to_s + "px;\n"
63
+
64
+ output
65
+ }
43
66
  end
44
67
 
68
+ def preload_javascript
69
+ slices = @slices
70
+
71
+ output = "if (typeof CHANCE_SLICES === 'undefined') var CHANCE_SLICES = [];"
72
+ output += "CHANCE_SLICES = CHANCE_SLICES.concat(["
73
+ output += slices.map {|name, slice| "'" + slice[:css_name] + "'" }.join(",\n")
74
+ output += "]);"
75
+ end
76
+
77
+ def mhtml(slices)
78
+ output = "Content-Type: multipart/related; boundary=\"CHANCE__BOUNDARY__\"\r\n"
79
+
80
+ slices.each {|name, slice|
81
+ output += "\n--CHANCE__BOUNDARY__\r\n"
82
+ output += "Content-Location:" + slice[:css_name] + "\r\n"
83
+ output += "Content-Transfer-Encoding:base64\r\n\r\n"
84
+
85
+ base64Image = Base64.encode64(slice[:image].to_blob(:fast_rgba)).gsub("\n", "")
86
+ output += base64Image
87
+ output += "\r\n"
88
+
89
+ output
90
+ }
91
+
92
+ output += "--CHANCE__BOUNDARY__--"
93
+
94
+ output
95
+ end
45
96
  end
46
97
 
47
98
  end
@@ -8,7 +8,6 @@ require 'chance/sass_extensions'
8
8
  require 'chance/perf'
9
9
  require 'chance/slicing'
10
10
 
11
- require 'digest/md5'
12
11
 
13
12
 
14
13
  Compass.discover_extensions!
@@ -42,18 +41,28 @@ module Chance
42
41
 
43
42
  @@generation = 0
44
43
 
45
- attr_accessor :css
46
-
44
+ attr_accessor :files
45
+
47
46
  def initialize(options = {})
48
47
  @options = options
49
48
  @options[:theme] = "" if @options[:theme].nil?
50
-
49
+
51
50
  if @options[:theme].length > 0 and @options[:theme][0] != "."
52
51
  @options[:theme] = "." + @options[:theme].to_s
53
52
  end
54
-
55
- @files = { }
56
- @css = nil
53
+
54
+ # The mapped files are a map from file names in the Chance Instance to
55
+ # their identifiers in Chance itself.
56
+ @mapped_files = { }
57
+
58
+ # The @files set is the set of output files. The user of Chance should
59
+ # make each of these files available. Also, the files must be able to
60
+ # reference each other. You can supply a wrapper (in the :url_wrapper
61
+ # option).
62
+ #
63
+ # The Abbot build tools supply `static_url($url);`, which wraps all of
64
+ # the URLs with `static_url` so they can be replaced.
65
+ @files = {}
57
66
  end
58
67
 
59
68
  # maps a path relative to the instance to a file identifier
@@ -69,14 +78,14 @@ module Chance
69
78
 
70
79
  raise FileNotFoundError.new(path) unless file
71
80
 
72
- @files[path] = identifier
81
+ @mapped_files[path] = identifier
73
82
  end
74
83
 
75
84
  # unmaps a path from its identifier. In short, removes a file
76
85
  # from this Chance instance. The file will remain in Chance's "virtual filesystem".
77
86
  def unmap_file(path)
78
87
  path = path.to_s
79
- @files.delete path
88
+ @mapped_files.delete path
80
89
  end
81
90
 
82
91
  # Using a path relative to this instance, gets an actual Chance file
@@ -84,9 +93,9 @@ module Chance
84
93
  # content will have been read, and if it is an image file, will have been
85
94
  # loaded as an actual image.
86
95
  def get_file(path)
87
- raise FileNotFoundError.new(path) unless @files[path]
96
+ raise FileNotFoundError.new(path) unless @mapped_files[path]
88
97
 
89
- return Chance.get_file(@files[path])
98
+ return Chance.get_file(@mapped_files[path])
90
99
  end
91
100
 
92
101
  # Generates the output CSS.
@@ -102,12 +111,8 @@ module Chance
102
111
  # The output of this process is a "virtual" file that imports all of the
103
112
  # SCSS files used by this Chance instance. This also sets up the @slices hash.
104
113
  import_css = _preprocess
105
-
106
- # Step 2: Slice images. The sliced canvases are saved in the individual slice
107
- # hashes.
108
- slice_images
109
-
110
- # Step 3: Generate CSS and images needed for output. For now, we hard-code
114
+
115
+ # Step 2: Generate CSS and images needed for output. For now, we hard-code
111
116
  # data url imager. Later, we will have a spriting imager.
112
117
  @imager = Chance::DataURLImager.new(@slices, self)
113
118
 
@@ -124,23 +129,39 @@ module Chance
124
129
  # else
125
130
  importer = nil
126
131
  css = @imager.css + "\n" + import_css
132
+ preload_javascript = @imager.preload_javascript
127
133
  cache_store = nil
128
134
  # end
129
135
 
130
- # Step 4: Apply Sass Engine
136
+ # Step 3: Apply Sass Engine
131
137
  engine = Sass::Engine.new(css, Compass.sass_engine_options.merge({
132
138
  :syntax => :scss,
133
139
  :importer => importer,
134
140
  :filename => "chance_main.css",
135
- :cache_store => cache_store
141
+ :cache_store => cache_store,
142
+ :cache_location => "./tmp/sass-cache"
136
143
  }))
137
144
 
138
145
  css = engine.render
146
+
147
+ # STEP 4: Slice images and postprocess into CSS
148
+ slice_images
149
+
150
+ # Normal variant (with IE7 compat)
151
+ css_normal = @imager.postprocess_css css, @slices
152
+ mhtml = @imager.mhtml(@slices)
153
+
154
+ # 2x variant
155
+ slice_images(true)
156
+ css_2x = @imager.postprocess_css_2x css, @slices
139
157
  ensure
140
158
  Chance._current_instance = nil
141
159
  end
142
160
 
143
- @css = css
161
+ @files["chance.css"] = css_normal
162
+ @files["chance@2x.css"] = css_2x
163
+ @files["chance.js"] = preload_javascript
164
+ @files["chance-mhtml.txt"] = mhtml
144
165
  end
145
166
 
146
167
  # Looks up a slice that has been found by parsing the CSS. This is used by
@@ -172,7 +193,7 @@ module Chance
172
193
  return if file[:included] === @@generation
173
194
 
174
195
  requires = file[:requires]
175
- requires.each {|r| _include_file(@files[r]) } unless requires.nil?
196
+ requires.each {|r| _include_file(@mapped_files[r]) } unless requires.nil?
176
197
 
177
198
  file[:included] = @@generation
178
199
 
@@ -186,7 +207,7 @@ module Chance
186
207
  @options[:slices] = @slices
187
208
 
188
209
  @@generation = @@generation + 1
189
- files = @files.values
210
+ files = @mapped_files.values
190
211
  @file_list = []
191
212
 
192
213
  files.each {|f| _include_file(f) }
@@ -196,30 +217,34 @@ module Chance
196
217
  # its method of determing the current file name is a marker in the
197
218
  # file. We may want to consider changing this to a parser option
198
219
  # now that we don't need this feature so much, but this works for now.
199
- content = "@_chance_file " + @files.invert[file[:path]] + ";\n"
220
+ content = "@_chance_file " + @mapped_files.key(file[:path]) + ";\n"
200
221
  content += "$theme: '" + @options[:theme] + "';"
201
222
  content += file[:content]
202
-
223
+
203
224
  parser = Chance::Parser.new(content, @options)
204
225
  parser.parse
205
226
  file[:parsed_css] = parser.css
206
-
227
+
207
228
  # NO IMPORTERS FOR NOW
208
229
  #if Chance::SUPPORTS_IMPORTERS
209
230
  # css = "@import \"" + file [:path] + ".scss\";"
210
231
  #else
232
+ tmp_path = File.join("./tmp/chance/", file[:path])
233
+
234
+ # SCSS requires the file names to end with ".scss", but we may
235
+ # already be getting files named *.scss. So, only add the extension
236
+ # if it is not already there.
237
+ tmp_path += ".scss" unless tmp_path.end_with? ".scss"
211
238
 
212
- path_hash = Digest::MD5.hexdigest(file[:path])
213
- tmp_path = "./tmp/chance/#{path_hash}.scss"
214
239
  FileUtils.mkdir_p(File.dirname(tmp_path))
215
-
240
+
216
241
  f = File.new(tmp_path, "w")
217
242
  f.write(parser.css)
218
243
  f.close
219
-
244
+
220
245
  css = "@import \"" + tmp_path + "\";"
221
246
  # end
222
-
247
+
223
248
  css
224
249
  }.join("\n")
225
250
  end