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
@@ -79,7 +79,7 @@
79
79
  background: static_url('images/sc-theme-repeat-x.png') no-repeat left -789px;
80
80
  }
81
81
 
82
- .sc-theme .sc-segmented-view .sc-segment label {
82
+ .sc-theme .sc-segmented-view .sc-segment-view label {
83
83
  background: static_url('images/sc-theme-repeat-x.png') repeat-x left -764px;
84
84
  text-shadow: #fff 0px 1px 0px;
85
85
  }
@@ -3,9 +3,7 @@
3
3
  # This is your Buildfile for your app, <%= namespace %>. This tells SproutCore
4
4
  # how to build your app. These settings override those in your project
5
5
  # Buildfile, which contains default settings for all apps in your project.
6
- #
7
- # This line tells SproutCore's CSS preprocessor what class names to target.
8
- # Since your app has a theme named '<%= css_name %>', and it is based on SproutCore's
9
- # Ace theme (named 'ace'), it is set to 'ace.<%= css_name %>'.
10
- config :<%= target_name %>, :css_theme => 'ace.<%= css_name %>'
6
+
7
+ # It is better to add :required targets here than in the global Buildfile.
8
+ config :<%= target_name %>, :required => :sproutcore
11
9
 
@@ -0,0 +1,18 @@
1
+ /*
2
+ This defines the global $theme variable for use inside your CSS.
3
+ The $theme variable holds the CSS class names for your theme.
4
+
5
+ You can then theme your app by using CSS like this:
6
+
7
+ $theme.button {
8
+ color: blue;
9
+ @include slices('white-button.png', $left: 3, $right: 3);
10
+ }
11
+
12
+ Any _theme.css file is prepended to all files inside its directory,
13
+ and any subdirectories that don't define their own _theme.css file.
14
+
15
+ This allows you to give different directories different values for
16
+ $theme if you wish.
17
+ */
18
+ $theme: '.ace.<%= css_name %>';
@@ -1,8 +1,8 @@
1
1
  <%= copyright_block(namespace, :ruby) %>
2
2
 
3
3
  # This is your Buildfile, which sets build settings for your project.
4
- # For example, this tells SproutCore's build tools that your requires
5
- # the SproutCore framework.
4
+ # For example, this tells SproutCore's build tools that EVERYTHING
5
+ # requires the SproutCore framework.
6
6
  config :all, :required => :sproutcore
7
7
 
8
8
  # In addition to this Buildfile, which gives settings for your entire project,
data/lib/sproutcore.rb CHANGED
@@ -47,7 +47,12 @@ module SproutCore
47
47
  # where you will find the build mode among other things set by sc-build.
48
48
  #
49
49
  def self.env
50
- @env ||= HashStruct.new(:build_mode => :debug, :buildfile_names => %w(Buildfile sc-config sc-config.rb))
50
+ @env ||= HashStruct.new(
51
+ :build_mode => :debug,
52
+ :buildfile_names => %w(Buildfile sc-config sc-config.rb),
53
+ :whitelist_name => "Whitelist",
54
+ :blacklist_name => "Blacklist"
55
+ )
51
56
  end
52
57
  def self.env=(hash); @env = HashStruct.new(hash); end
53
58
 
@@ -116,10 +121,30 @@ module SproutCore
116
121
  end
117
122
  end
118
123
 
119
- def self.yui_jar
120
- @yui_jar ||= begin
121
- yui_root = File.expand_path("../../vendor/sproutcore/lib", __FILE__)
122
- File.join(yui_root, 'yuicompressor-2.4.6.jar')
124
+ # Additional targets to be included in the project. Each item is a hash
125
+ # with :path and :name attributes
126
+ def self.include_targets
127
+ @include_targets ||= []
128
+ end
129
+
130
+ # Adds a target to be included in the project SproutCore builds.
131
+ #
132
+ # This is useful to make additional frameworks available to SproutCore apps.
133
+ def self.include_target(target_name, target_path)
134
+ include_targets << { :name => target_name, :path => target_path }
135
+ end
136
+
137
+ def self.html_jar
138
+ @html_jar ||= begin
139
+ yui_root = File.expand_path("../../vendor/sproutcore", __FILE__)
140
+ File.join(yui_root, 'SCCompiler.jar')
141
+ end
142
+ end
143
+
144
+ def self.js_jar
145
+ @js_jar ||= begin
146
+ yui_root = File.expand_path("../../vendor/sproutcore", __FILE__)
147
+ File.join(yui_root, 'lib/yuicompressor-2.4.6.jar')
123
148
  end
124
149
  end
125
150
 
@@ -13,3 +13,4 @@ require "sproutcore/builders/test"
13
13
  require "sproutcore/builders/test_index"
14
14
  require "sproutcore/builders/string_wrapper"
15
15
  require "sproutcore/builders/handlebars"
16
+ require "sproutcore/builders/split"
@@ -9,13 +9,18 @@ module SC
9
9
  def build(dst_path)
10
10
  instances = entry[:chance_instances] || [entry[:chance_instance]]
11
11
 
12
- # Ensure all entries are staged. If -c was used, they may have been
13
- # gotten rid of.
14
- entry[:source_entries].each {|e| e.stage! }
12
+ # Ensure all entries are staged. When Abbot updates, it may skip regenerating
13
+ # the manifest and just run us, in which case, the previous staged version
14
+ # will be out-of-date.
15
+ entry[:source_entries].each {|e| e.stage! if entry[:build_required] }
15
16
 
16
17
  chance_file = entry[:chance_file]
17
18
 
18
19
  src = instances.map {|chance|
20
+ # Because files were restaged, they could be out-of-date.
21
+ # Let's double-check them all.
22
+ chance.check_all_files
23
+
19
24
 
20
25
  src = ""
21
26
  src = chance.output_for chance_file unless chance.nil?
@@ -40,19 +45,6 @@ module SC
40
45
  #
41
46
  # The default will rewrite calls to static_url().
42
47
  def rewrite_inline_code(code)
43
- # look for sc_require, require or sc_resource. wrap in comment
44
- code.gsub!(/url\s*\(\s*["']mhtml\:chance-mhtml\.txt!(.+?)["']\s*\)/) {|mhtml|
45
- static_entry = entry.manifest.find_entry("__sc_chance_mhtml.txt")
46
-
47
- if !static_entry
48
- url = ''
49
- else
50
- url = static_entry.cacheable_url
51
- end
52
-
53
- "expression('url(\"mhtml:' + document.location.protocol + '//' + document.location.host + '" + url + "!" + $1 + "' + '\")')"
54
- }
55
-
56
48
  # chance_files refer, usually, to sprites.
57
49
  code.gsub!(/chance_file\(["'](.*?)['"]\)/) {|match|
58
50
  path = entry[:resource_name] + "-" + $1
@@ -63,6 +55,7 @@ module SC
63
55
  "static_url('#{$1}')"
64
56
  }
65
57
 
58
+ # look for sc_require, require or sc_resource. wrap in comment
66
59
  code.gsub!(/((sc_require|require|sc_resource)\(\s*['"].*["']\s*\)\s*\;)/, '/* \1 */')
67
60
  replace_static_url(code)
68
61
  code
@@ -112,7 +112,8 @@ module SC
112
112
  end
113
113
 
114
114
  def build(dst_path)
115
- if CONFIG[:html5_manifest]
115
+ # WE ARE DISABLING HTML5 MANIFEST FOR NOW. Because it doesn't work.
116
+ if false and CONFIG[:html5_manifest]
116
117
  $to_html5_manifest << dst_path
117
118
  $to_html5_manifest_networks = CONFIG[:html5_manifest_networks]
118
119
  @content_for_html5_manifest = true
@@ -32,26 +32,6 @@ module SC
32
32
  send("build_#{@kind}".to_sym, dst_path)
33
33
  end
34
34
 
35
- def build_css(dst_path)
36
- a = Regexp.new('^'+MANIFEST.build_root)
37
- if dst_path =~ a
38
- # $to_minify << dst_path
39
- FileUtils.mkdir_p(File.dirname(dst_path))
40
- FileUtils.copy(entry.source_path, dst_path)
41
- else
42
- FileUtils.mkdir_p(File.dirname(dst_path)) # make sure loc exists...
43
- filecompress = "java -Xmx128m -jar \"" + SC.yui_jar + "\" --type css --charset utf-8 --line-break 0 --nomunge --preserve-semi --disable-optimizations \"" + entry.source_path + "\" -o \"" + dst_path + "\" 2>&1"
44
- SC.logger.info 'Compressing CSS with YUI .... '+ dst_path
45
- SC.logger.debug `#{filecompress}`
46
-
47
- if $?.exitstatus != 0
48
- _report_error(output, entry.filename, entry.source_path)
49
- SC.logger.fatal("!!!!YUI compressor failed, please check that your css code is valid.")
50
- SC.logger.fatal("!!!!Failed compressing CSS... "+ dst_path)
51
- end
52
- end
53
- end
54
-
55
35
  # Minify some javascript by invoking the YUI compressor.
56
36
  def build_javascript(dst_path)
57
37
  entry.source_entry.build!
@@ -63,21 +43,10 @@ module SC
63
43
  SC::Helpers::Minifier << dst_path
64
44
  end
65
45
  end
66
-
67
- def build_inline_javascript(dst_path)
68
- SC.logger.info 'Compiling inline Javascript with YUI: ' + dst_path + "..."
69
- FileUtils.mkdir_p(File.dirname(dst_path)) # make sure loc exists...
70
- filecompress = "java -Xmx128m -jar \"" + SC.yui_jar + "\" --type js \"" + entry.source_path + "\" -o \"" + dst_path + "\" 2>&1"
71
- SC.logger.info 'Compiling with YUI: '+ filecompress + "..."
72
-
73
- output = `#{filecompress}` # It'd be nice to just read STDERR, but
74
- # I can't find a reasonable, commonly-
75
- # installed, works-on-all-OSes solution.
76
- if $?.exitstatus != 0
77
- _report_error(output, entry.filename, entry.source_path)
78
- SC.logger.fatal("!!!!YUI compiler failed, please check that your js code is valid")
79
- SC.logger.fatal("!!!!Failed compiling ... "+ dst_path)
80
- end
46
+
47
+ def build_html(dst_path)
48
+ entry.source_entry.build!
49
+ SC::Helpers::Minifier << dst_path
81
50
  end
82
51
 
83
52
  private
@@ -34,6 +34,13 @@ module SC
34
34
  scriptURL:'<%= @script %>',
35
35
  stringURL:'<%= @string %>'<% if @prefetched %>,
36
36
  isPrefetched: YES
37
+ <% end %><% if @inlined %>,
38
+ isLoaded: YES,
39
+ source: <%= @source %>
40
+ <% end %><% if @css_source %>,
41
+ cssSource: <%= @css_source %>
42
+ <% end %><% if @css_2x_source %>,
43
+ css2xSource: <%= @css_2x_source %>
37
44
  <% end %>
38
45
  })
39
46
  })();
@@ -56,6 +63,32 @@ module SC
56
63
 
57
64
  module_info = t.module_info({ :variation => entry[:variation] })
58
65
 
66
+ # Handle inlined modules. Inlined modules get included as strings
67
+ # in the module info.
68
+ source = nil, css_source = nil, css_2x_source = nil
69
+
70
+ # if (and only if) the module is inlined, we must include the source
71
+ # for the JS AND CSS inline as well (as strings)
72
+ if t[:inlined_module]
73
+ source = File.read(script_entry.stage![:staging_path]).to_json
74
+
75
+ css_entry = manifest.find_entry('stylesheet.css')
76
+ if css_entry
77
+ css_path = css_entry.stage![:staging_path]
78
+
79
+ # We must check if the file exists because there are cases where we can have
80
+ # an entry but no file: no file is added if the file is empty, but the file
81
+ # could be empty if all input files are empty or full of comments.
82
+ css_source = File.read(css_path).to_json if File.exist? css_path
83
+ end
84
+
85
+ css_2x_entry = manifest.find_entry('stylesheet@2x.css')
86
+ if css_2x_entry
87
+ css_2x_path = css_2x_entry.stage![:staging_path]
88
+ css_2x_source = File.read(css_2x_path).to_json if File.exist? css_2x_path
89
+ end
90
+ end
91
+
59
92
  output << eruby.evaluate({
60
93
  :target_name => t[:target_name].to_s.sub(/^\//,''),
61
94
  :dependencies => module_info[:requires].map{ |t| "'#{t[:target_name].to_s.sub(/^\//,'')}'" },
@@ -63,7 +96,11 @@ module SC
63
96
  :styles2x => module_info[:css_2x_urls].map {|url| "'#{url}'"},
64
97
  :script => script_url,
65
98
  :string => string_url,
66
- :prefetched => t[:prefetched_module]
99
+ :source => source,
100
+ :inlined => t[:inlined_module],
101
+ :prefetched => t[:prefetched_module],
102
+ :css_source => css_source,
103
+ :css_2x_source => css_2x_source
67
104
  })
68
105
  end
69
106
  writelines dst_path, [output]
@@ -0,0 +1,63 @@
1
+ # ===========================================================================
2
+ # Project: Abbot - SproutCore Build Tools
3
+ # Copyright: ©2011 Apple Inc.
4
+ # ===========================================================================
5
+
6
+ require "sproutcore/builders/base"
7
+ require 'fileutils'
8
+
9
+ module SC
10
+
11
+ # This builder is used to split packed CSS files, ironically enough,
12
+ # into smaller CSS files. This is due to an IE limitation of ~4096 maximum
13
+ # selectors per file.
14
+ #
15
+ # This is a bit hacky, but we add additional manifest entries even though, technically,
16
+ # the manifest generation process is finished. We do this because we have NO WAY
17
+ # of knowing how many selectors there will be until CSS is both built and packed.
18
+ #
19
+ # The static HTML helper makes sure to build! the packed stylesheet entries first so
20
+ # that this rule has been processed. After that, it looks for [:split_entries] on the
21
+ # packed entry.
22
+ class Builder::SplitCSS < Builder::Base
23
+ def build(dst_path)
24
+ e = entry.source_entry
25
+ e.stage!
26
+
27
+ src = File.read(entry[:staging_path])
28
+ files = SC::Helpers::SplitCSS.split_css src
29
+
30
+ if files.length > 1 and entry.target.config[:split_css_for_ie]
31
+ entry[:split_entries] = []
32
+ entry[:is_split] = true
33
+ entry.hide!
34
+
35
+
36
+ files.each_index {|index|
37
+ name = entry[:filename].sub /\.css$/, ""
38
+
39
+ path = dst_path.sub /\.css$/, ""
40
+ path = "#{path}-#{index}.css"
41
+
42
+ writeline path, files[index]
43
+
44
+ # Is this hacky? Yes. But IE is stupid. So we have to modify the manifest
45
+ # very late, because we don't know the
46
+ resource_name = "#{name}-#{index}.css"
47
+ split_entry = entry.manifest.add_composite resource_name,
48
+ :staging_path => path,
49
+ :build_path => path,
50
+ :source_entries => [entry],
51
+ :url => [entry.manifest[:url_root], resource_name].join("/"),
52
+ :timestamp => entry[:timestamp]
53
+
54
+ entry[:split_entries] << split_entry
55
+ }
56
+ else
57
+ e.build!
58
+ end
59
+ end
60
+
61
+ end
62
+
63
+ end
@@ -33,7 +33,13 @@ module SC
33
33
  str.scan(/['"](.+)['"]\s*:\s*['"](.+)['"],?\s*$/) do |x,y|
34
34
  # x & y are JS strings that must be evaled as such..
35
35
  #x = eval(%("#{x}"))
36
- y = eval(%[<<__EOF__\n#{y}\n__EOF__]).chop
36
+ begin
37
+ y = eval(%[<<__EOF__\n#{y}\n__EOF__]).chop
38
+ rescue SyntaxError
39
+ puts "Invalid string in #{source_path}:"
40
+ puts $&
41
+ exit
42
+ end
37
43
  ret[x] = y
38
44
  end
39
45
  return ret
@@ -8,4 +8,4 @@ require "sproutcore/helpers/static_helper"
8
8
  require "sproutcore/helpers/tag_helper"
9
9
  require "sproutcore/helpers/text_helper"
10
10
  require "sproutcore/helpers/minifier"
11
-
11
+ require "sproutcore/helpers/css_split"
@@ -0,0 +1,190 @@
1
+ # THE PARSER
2
+ #
3
+ # The parser will not bother splitting into tokens. We are _a_
4
+ # step up from Regular Expressions, not a thousand steps.
5
+ #
6
+ # In short, we keep track of two things: { } and strings.
7
+ #
8
+ # Other than that, we look for @theme, slices(), and slice(),
9
+ # in their various forms.
10
+ #
11
+ # Our method is to scan until we hit a delimiter followed by any
12
+ # of the following:
13
+ #
14
+ # - @theme
15
+ # - @include slices(
16
+ # - slices(
17
+ # - slice(
18
+ #
19
+ # Options
20
+ # --------------------------------
21
+ # You may pass a few configuration options to a Chance instance:
22
+ #
23
+ # - :theme: a selector that will make up the initial value of the $theme
24
+ # variable. For example: :theme => "ace.test-controls"
25
+ #
26
+ #
27
+ # How Slice & Slices work
28
+ # -------------------------------
29
+ # @include slice() and @include slices() are not actually responsible
30
+ # for slicing the image. They do not know the image's width or height.
31
+ #
32
+ # All that they do is determine the slice's configuration, including
33
+ # its file name, the rectangle to slice, etc.
34
+ require "stringio"
35
+
36
+
37
+ module SC::Helpers
38
+
39
+ module SplitCSS
40
+ UNTIL_SINGLE_QUOTE = /(?!\\)'/
41
+ UNTIL_DOUBLE_QUOTE = /(?!\\)"/
42
+
43
+ BEGIN_SCOPE = /\{/
44
+ END_SCOPE = /\}/
45
+ NORMAL_SCAN_UNTIL = /[^{},]+/
46
+
47
+ MAX_SELECTOR_COUNT = 4000
48
+
49
+ def self.split_css(input)
50
+ scanner = StringScanner.new(input)
51
+
52
+ current = ""
53
+ ret = [current]
54
+
55
+ selectors = ""
56
+ in_selector = false
57
+ selector_count = 0
58
+
59
+ while not scanner.eos?
60
+ # Handle any strings, etc. This also handles whitespace, strings, blah.
61
+ # Basically, unless we see a scope, we know we are in a selector.
62
+ selectors << handle_skip(scanner)
63
+
64
+ # Handle scope
65
+ if scanner.match?(BEGIN_SCOPE)
66
+ # Push the current selectors
67
+ current << selectors
68
+ selectors = ""
69
+ in_selector = false
70
+
71
+ current << handle_scope(scanner)
72
+
73
+ # For readability and reliability in certain browsers, add a newline at the end
74
+ # of each rule.
75
+ current << "\n"
76
+ next
77
+ end
78
+
79
+ # Handle , -- which would mean we are finishing a selector
80
+ if scanner.match? /,/
81
+ selectors << scanner.scan(/,/)
82
+ in_selector = false
83
+
84
+ next
85
+ end
86
+
87
+ if not in_selector
88
+ # At this point we MUST be in a selector.
89
+ in_selector = true
90
+ selector_count += 1
91
+
92
+ if selector_count > MAX_SELECTOR_COUNT
93
+ current = ""
94
+ ret << current
95
+
96
+ selector_count = 0
97
+ end
98
+ end
99
+
100
+ # skip over anything that our tokens do not start with. We implement this differently
101
+ # since these are ONLY selectors, and therefore we must add them to selector instead of output.
102
+ res = scanner.scan(NORMAL_SCAN_UNTIL)
103
+ break if scanner.eos?
104
+
105
+ if res.nil?
106
+ selectors << scanner.getch
107
+ else
108
+ selectors << res
109
+ end
110
+ end
111
+
112
+ ret
113
+ end
114
+
115
+ def self.handle_scope(scanner)
116
+ str = ""
117
+
118
+ # Consume the begin scope we matched
119
+ str << scanner.scan(BEGIN_SCOPE)
120
+
121
+ while not scanner.eos?
122
+ str << handle_skip(scanner)
123
+
124
+ if scanner.match? BEGIN_SCOPE
125
+ str << self.handle_scope(scanner)
126
+ end
127
+
128
+ if scanner.match? END_SCOPE
129
+ str << scanner.scan(END_SCOPE)
130
+ return str
131
+ end
132
+
133
+ str << handle_content(scanner)
134
+ end
135
+
136
+ str
137
+ end
138
+
139
+ def self.handle_content(scanner)
140
+ str = ""
141
+
142
+ res = scanner.scan(NORMAL_SCAN_UNTIL)
143
+ if res.nil?
144
+ str << scanner.getch
145
+ else
146
+ str << res
147
+ end
148
+
149
+ str
150
+ end
151
+
152
+ def self.handle_skip(scanner)
153
+ str = ""
154
+
155
+ while true do
156
+ if scanner.match?(/\s+/)
157
+ str << scanner.scan(/\s+/)
158
+ next
159
+ end
160
+ if scanner.match?(/\/\*/)
161
+ str << handle_comment(scanner)
162
+ next
163
+ end
164
+ if scanner.match?(/["']/)
165
+ str << handle_string(scanner)
166
+ next
167
+ end
168
+ break
169
+ end
170
+
171
+ str
172
+ end
173
+
174
+ def self.handle_comment(scanner)
175
+ str = '/*'
176
+
177
+ scanner.pos += 2
178
+ str << scanner.scan_until(/\*\//)
179
+ end
180
+
181
+ def self.handle_string(scanner)
182
+ str = scanner.getch
183
+ str += scanner.scan_until(str == "'" ? UNTIL_SINGLE_QUOTE : UNTIL_DOUBLE_QUOTE)
184
+
185
+ str
186
+ end
187
+
188
+ end
189
+ end
190
+