sproutcore 1.6.0.1-java → 1.7.1.beta-java

Sign up to get free protection for your applications and to get access to all the features.
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
+