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.
- data/CHANGELOG +21 -0
 - data/Gemfile +5 -0
 - data/Rakefile +26 -13
 - data/VERSION.yml +2 -2
 - data/lib/Buildfile +43 -4
 - data/lib/buildtasks/build.rake +10 -0
 - data/lib/buildtasks/helpers/file_rule.rb +22 -0
 - data/lib/buildtasks/helpers/file_rule_list.rb +137 -0
 - data/lib/buildtasks/manifest.rake +133 -122
 - data/lib/frameworks/sproutcore/CHANGELOG.md +69 -2
 - data/lib/frameworks/sproutcore/apps/tests/english.lproj/strings.js +1 -0
 - data/lib/frameworks/sproutcore/frameworks/bootstrap/system/browser.js +28 -22
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/controllers/array.js +9 -5
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/controllers/controller.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/controls/button.js +18 -13
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/ext/handlebars/bind.js +5 -3
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/ext/handlebars/collection.js +2 -0
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/action_support.js +80 -0
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/template_helpers/text_field_support.js +84 -116
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/pane.js +8 -5
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/system/event.js +157 -157
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/system/platform.js +5 -3
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/system/root_responder.js +6 -6
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/system/sparse_array.js +10 -7
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/mixins/action_support.js +106 -0
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template/collection.js +18 -0
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template/handlebars.js +71 -1
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/attribute_bindings_test.js +38 -0
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/class_name_bindings_test.js +47 -0
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layoutChildViews.js +18 -18
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layoutStyle.js +42 -10
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view.js +158 -1
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/keyboard.js +26 -1
 - data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout_style.js +14 -8
 - data/lib/frameworks/sproutcore/frameworks/datastore/models/record.js +15 -2
 - data/lib/frameworks/sproutcore/frameworks/datastore/models/record_attribute.js +108 -108
 - data/lib/frameworks/sproutcore/frameworks/datastore/system/query.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/datastore/system/record_array.js +2 -4
 - data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/record/error_methods.js +2 -2
 - data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/single_attribute.js +26 -0
 - data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/query/builders.js +7 -0
 - data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/record_array/error_methods.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/datetime/frameworks/core/system/datetime.js +4 -1
 - data/lib/frameworks/sproutcore/frameworks/datetime/frameworks/core/tests/system/datetime.js +6 -0
 - data/lib/frameworks/sproutcore/frameworks/desktop/panes/menu.js +26 -5
 - data/lib/frameworks/sproutcore/frameworks/desktop/panes/picker.js +97 -96
 - data/lib/frameworks/sproutcore/frameworks/desktop/system/drag.js +4 -3
 - data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/menu/ui.js +17 -4
 - data/lib/frameworks/sproutcore/frameworks/desktop/views/collection.js +7 -7
 - data/lib/frameworks/sproutcore/frameworks/desktop/views/menu_item.js +7 -5
 - data/lib/frameworks/sproutcore/frameworks/desktop/views/scroll.js +12 -3
 - data/lib/frameworks/sproutcore/frameworks/desktop/views/web.js +23 -14
 - data/lib/frameworks/sproutcore/frameworks/experimental/Buildfile +5 -1
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/menu/render_delegates/menu_scroller.js +28 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/menu/tests/menu/scroll.js +235 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/menu/views/menu/scroll.js +363 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/menu/views/menu/scroller.js +250 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/render_delegates/desktop_scroller.js +92 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/render_delegates/native_scroll.js +25 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/render_delegates/scroll.js +33 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/render_delegates/touch_scroller.js +76 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/tests/scroll/integration.js +50 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/tests/scroll/methods.js +143 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/tests/scroll/ui.js +258 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/core_scroll.js +1164 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/core_scroller.js +332 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/desktop/scroll.js +236 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/desktop/scroller.js +347 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/scroll.js +15 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/scroller.js +10 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/touch/scroll.js +804 -0
 - data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/views/touch/scroller.js +133 -0
 - data/lib/frameworks/sproutcore/frameworks/foundation/resources/text_field.css +3 -3
 - data/lib/frameworks/sproutcore/frameworks/foundation/validators/number.js +3 -1
 - data/lib/frameworks/sproutcore/frameworks/foundation/views/text_field.js +3 -3
 - data/lib/frameworks/sproutcore/frameworks/media/views/audio.js +2 -1
 - data/lib/frameworks/sproutcore/frameworks/media/views/controls.js +2 -1
 - data/lib/frameworks/sproutcore/frameworks/media/views/media_slider.js +2 -4
 - data/lib/frameworks/sproutcore/frameworks/media/views/mini_controls.js +2 -4
 - data/lib/frameworks/sproutcore/frameworks/media/views/simple_controls.js +2 -4
 - data/lib/frameworks/sproutcore/frameworks/media/views/video.js +2 -2
 - data/lib/frameworks/sproutcore/frameworks/routing/system/routes.js +29 -3
 - data/lib/frameworks/sproutcore/frameworks/runtime/core.js +2 -2
 - data/lib/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array/replace.js +1 -1
 - data/lib/frameworks/sproutcore/frameworks/runtime/private/property_chain.js +2 -1
 - data/lib/frameworks/sproutcore/frameworks/runtime/system/binding.js +3 -3
 - data/lib/frameworks/sproutcore/frameworks/runtime/system/index_set.js +2 -2
 - data/lib/frameworks/sproutcore/frameworks/runtime/system/object.js +1 -1
 - data/lib/frameworks/sproutcore/themes/ace/resources/collection/normal/list_item.css +2 -2
 - data/lib/frameworks/sproutcore/themes/legacy_theme/english.lproj/segmented.css +1 -1
 - data/lib/gen/app/templates/apps/@target_name@/Buildfile +3 -5
 - data/lib/gen/app/templates/apps/@target_name@/resources/_theme.css +18 -0
 - data/lib/gen/project/templates/@filename@/Buildfile +2 -2
 - data/lib/sproutcore.rb +30 -5
 - data/lib/sproutcore/builders.rb +1 -0
 - data/lib/sproutcore/builders/chance_file.rb +9 -16
 - data/lib/sproutcore/builders/html.rb +2 -1
 - data/lib/sproutcore/builders/minify.rb +4 -35
 - data/lib/sproutcore/builders/module.rb +38 -1
 - data/lib/sproutcore/builders/split.rb +63 -0
 - data/lib/sproutcore/builders/strings.rb +7 -1
 - data/lib/sproutcore/helpers.rb +1 -1
 - data/lib/sproutcore/helpers/css_split.rb +190 -0
 - data/lib/sproutcore/helpers/entry_sorter.rb +2 -0
 - data/lib/sproutcore/helpers/minifier.rb +40 -16
 - data/lib/sproutcore/helpers/static_helper.rb +35 -17
 - data/lib/sproutcore/models/manifest.rb +26 -0
 - data/lib/sproutcore/models/target.rb +12 -1
 - data/lib/sproutcore/rack.rb +1 -0
 - data/lib/sproutcore/rack/proxy.rb +244 -225
 - data/lib/sproutcore/rack/restrict_ip.rb +67 -0
 - data/lib/sproutcore/rack/service.rb +8 -2
 - data/lib/sproutcore/tools.rb +102 -46
 - data/lib/sproutcore/tools/build.rb +91 -43
 - data/lib/sproutcore/tools/gen.rb +2 -3
 - data/lib/sproutcore/tools/manifest.rb +22 -16
 - data/lib/sproutcore/tools/server.rb +21 -0
 - data/spec/buildtasks/helpers/accept_list +22 -0
 - data/spec/buildtasks/helpers/accept_list.rb +128 -0
 - data/spec/buildtasks/helpers/list.json +11 -0
 - data/spec/buildtasks/manifest/prepare_build_tasks/chance_2x_spec.rb +1 -39
 - data/spec/buildtasks/manifest/prepare_build_tasks/chance_spec.rb +0 -38
 - data/spec/buildtasks/manifest/prepare_build_tasks/combine_spec.rb +4 -4
 - data/spec/buildtasks/manifest/prepare_build_tasks/module_spec.rb +2 -2
 - data/spec/buildtasks/manifest/prepare_build_tasks/packed_2x_indirect_spec.rb +7 -16
 - data/spec/buildtasks/manifest/prepare_build_tasks/packed_2x_spec.rb +7 -17
 - data/spec/buildtasks/manifest/prepare_build_tasks/packed_spec.rb +11 -6
 - data/spec/fixtures/builder_tests/Buildfile +2 -1
 - data/spec/fixtures/builder_tests/apps/module_test/modules/required_module/core.js +0 -0
 - data/spec/lib/builders/module_spec.rb +1 -1
 - data/spec/spec_helper.rb +1 -0
 - data/sproutcore.gemspec +4 -9
 - data/vendor/chance/lib/chance.rb +25 -6
 - data/vendor/chance/lib/chance/factory.rb +45 -0
 - data/vendor/chance/lib/chance/instance.rb +173 -28
 - data/vendor/chance/lib/chance/instance/data_url.rb +0 -29
 - data/vendor/chance/lib/chance/instance/slicing.rb +57 -4
 - data/vendor/chance/lib/chance/instance/spriting.rb +112 -21
 - data/vendor/chance/lib/chance/parser.rb +80 -52
 - data/vendor/sproutcore/SCCompiler.jar +0 -0
 - data/vendor/sproutcore/lib/args4j-2.0.12.jar +0 -0
 - data/vendor/sproutcore/lib/yuicompressor-2.4.2.jar +0 -0
 - 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 
     | 
    
         
            -
            #  
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       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  
     | 
| 
       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( 
     | 
| 
      
 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 
     | 
    
         
            -
               
     | 
| 
       120 
     | 
    
         
            -
             
     | 
| 
       121 
     | 
    
         
            -
             
     | 
| 
       122 
     | 
    
         
            -
             
     | 
| 
      
 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 
     | 
    
         | 
    
        data/lib/sproutcore/builders.rb
    CHANGED
    
    
| 
         @@ -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.  
     | 
| 
       13 
     | 
    
         
            -
                  #  
     | 
| 
       14 
     | 
    
         
            -
                   
     | 
| 
      
 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 
     | 
    
         
            -
                   
     | 
| 
      
 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  
     | 
| 
       68 
     | 
    
         
            -
                   
     | 
| 
       69 
     | 
    
         
            -
                   
     | 
| 
       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 
     | 
    
         
            -
                      : 
     | 
| 
      
 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 
     | 
    
         
            -
                     
     | 
| 
      
 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
         
     | 
    
        data/lib/sproutcore/helpers.rb
    CHANGED
    
    
| 
         @@ -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 
     | 
    
         
            +
             
     |