diff --git a/Rakefile b/Rakefile index 22bfdc567c..83f247a4bd 100644 --- a/Rakefile +++ b/Rakefile @@ -39,15 +39,19 @@ END # ----- Packaging ----- -require 'rake/gempackagetask' -load scope('haml.gemspec') - -Rake::GemPackageTask.new(HAML_GEMSPEC) do |pkg| - if Rake.application.top_level_tasks.include?('release') - pkg.need_tar_gz = true - pkg.need_tar_bz2 = true - pkg.need_zip = true - end +# Don't use Rake::GemPackageTast because we want prerequisites to run +# before we load the gemspec. +desc "Build all the packages." +task :package => [:revision_file, :submodules] do + load scope('haml.gemspec') + Gem::Builder.new(HAML_GEMSPEC).build + pkg = "#{HAML_GEMSPEC.name}-#{HAML_GEMSPEC.version}" + mkdir_p "pkg" + verbose(true) {mv "#{pkg}.gem", "pkg/#{pkg}.gem"} + + sh %{rm -f pkg/#{pkg}.tar.gz} + verbose(false) {HAML_GEMSPEC.files.each {|f| sh %{tar rf pkg/#{pkg}.tar #{f}}}} + sh %{gzip pkg/#{pkg}.tar} end task :revision_file do @@ -62,8 +66,6 @@ task :revision_file do File.open(scope('REVISION'), 'w') { |f| f.puts "(unknown)" } end end -Rake::Task[:package].prerequisites.insert(0, :revision_file) -Rake::Task[:package].prerequisites.insert(0, :submodules) # We also need to get rid of this file after packaging. at_exit { File.delete(scope('REVISION')) rescue nil } @@ -81,8 +83,6 @@ task :release => [:check_release, :release_elpa, :package] do version = File.read(scope("VERSION")).strip sh %{rubyforge add_release haml haml "#{name} (v#{version})" pkg/haml-#{version}.gem} sh %{rubyforge add_file haml haml "#{name} (v#{version})" pkg/haml-#{version}.tar.gz} - sh %{rubyforge add_file haml haml "#{name} (v#{version})" pkg/haml-#{version}.tar.bz2} - sh %{rubyforge add_file haml haml "#{name} (v#{version})" pkg/haml-#{version}.zip} sh %{gem push pkg/haml-#{version}.gem} end diff --git a/VERSION b/VERSION index 9c3ce65283..af6f4bcf15 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.0.rc.2 +3.0.0.rc.3 diff --git a/doc-src/HAML_CHANGELOG.md b/doc-src/HAML_CHANGELOG.md index f7c59e4f0a..d93d19ea0b 100644 --- a/doc-src/HAML_CHANGELOG.md +++ b/doc-src/HAML_CHANGELOG.md @@ -3,7 +3,16 @@ * Table of contents {:toc} -## 3.0.0.rc.3 (Unreleased) +## 3.0.0.rc.4 (Unreleased) + +### Rails Beta Support + +* Setting options via `Haml::Template.options` in the initializer + now works without using `ActiveSupport.on_load(:action_view)`. + +## 3.0.0.rc.3 + +[Tagged on GitHub](http://github.com/nex3/haml/commit/3.0.0.rc.3). ### Rails Beta Support diff --git a/doc-src/SASS_CHANGELOG.md b/doc-src/SASS_CHANGELOG.md index d78e8a5d46..e8225ecd40 100644 --- a/doc-src/SASS_CHANGELOG.md +++ b/doc-src/SASS_CHANGELOG.md @@ -3,7 +3,38 @@ * Table of contents {:toc} -## 3.0.0.rc.3 (Unreleased) +## 3.0.0.rc.4 (Unreleased) + +* Don't check stylesheets for each request when running tests in Rails. + This should speed up some tests significantly. + +* Don't add extra newlines between variables with `sass-convert`. + +## 3.0.0.rc.3 + +[Tagged on GitHub](http://github.com/nex3/haml/commit/3.0.0.rc.3). + +### `@extend` Support + +It's now possible to create a loop of `@extend` relations. +For example, + + .blueLink { + color: blue; + @extend .link; } + + .link { + font-weight: bold; + @extend .blueLink; } + +Before, this would have raised an error. +Now it produces the following CSS: + + .link, .blueLink { + color: blue; } + + .blueLink, .link { + font-weight: bold; } ### Rails Beta Support @@ -20,6 +51,8 @@ The Sass Rails plugin now works using Rack middleware by default. * Don't die when given a 70 kb property. +* `sass --watch` now works with a single file on OS X. + ## 3.0.0.rc.2 [Tagged on GitHub](http://github.com/nex3/haml/commit/3.0.0.rc.2). diff --git a/lib/haml/railtie.rb b/lib/haml/railtie.rb index e4c94f081b..93d5c1af3c 100644 --- a/lib/haml/railtie.rb +++ b/lib/haml/railtie.rb @@ -5,5 +5,6 @@ # Rails 3.0.0.beta.2+ if defined?(ActiveSupport) && Haml::Util.has?(:public_method, ActiveSupport, :on_load) + require 'haml/template/options' ActiveSupport.on_load(:action_view) {Haml.init_rails(binding)} end diff --git a/lib/haml/template.rb b/lib/haml/template.rb index 7029d6ec23..83ba4cc1ec 100644 --- a/lib/haml/template.rb +++ b/lib/haml/template.rb @@ -1,3 +1,4 @@ +require 'haml/template/options' require 'haml/engine' require 'haml/helpers/action_view_mods' require 'haml/helpers/action_view_extensions' @@ -5,15 +6,6 @@ module Haml # The class that keeps track of the global options for Haml within Rails. module Template - extend self - - @options = {} - # The options hash for Haml when used within Rails. - # See {file:HAML_REFERENCE.md#haml_options the Haml options documentation}. - # - # @return [{Symbol => Object}] - attr_accessor :options - # Enables integration with the Rails 2.2.5+ XSS protection, # if it's available and enabled. # diff --git a/lib/haml/template/options.rb b/lib/haml/template/options.rb new file mode 100644 index 0000000000..cf0ddc79b1 --- /dev/null +++ b/lib/haml/template/options.rb @@ -0,0 +1,16 @@ +# We keep options in its own self-contained file +# so that we can load it independently in Rails 3, +# where the full template stuff is lazy-loaded. + +module Haml + module Template + extend self + + @options = {} + # The options hash for Haml when used within Rails. + # See {file:HAML_REFERENCE.md#haml_options the Haml options documentation}. + # + # @return [{Symbol => Object}] + attr_accessor :options + end +end diff --git a/lib/sass/plugin.rb b/lib/sass/plugin.rb index bb42193071..8e00b751b9 100644 --- a/lib/sass/plugin.rb +++ b/lib/sass/plugin.rb @@ -291,6 +291,15 @@ def watch(individual_files = []) raise e end + unless individual_files.empty? && FSSM::Backends::Default.name == "FSSM::Backends::FSEvents" + # As of FSSM 0.1.4, it doesn't support FSevents on individual files, + # but it also isn't smart enough to switch to polling itself. + require 'fssm/backends/polling' + Haml::Util.silence_warnings do + FSSM::Backends.const_set(:Default, FSSM::Backends::Polling) + end + end + # TODO: Keep better track of what depends on what # so we don't have to run a global update every time anything changes. FSSM.monitor do |mon| diff --git a/lib/sass/plugin/rails.rb b/lib/sass/plugin/rails.rb index 116c948dd4..1b6f15e46d 100644 --- a/lib/sass/plugin/rails.rb +++ b/lib/sass/plugin/rails.rb @@ -4,7 +4,7 @@ Sass::Plugin.options.merge!(:template_location => Haml::Util.rails_root + '/public/stylesheets/sass', :css_location => Haml::Util.rails_root + '/public/stylesheets', :cache_location => Haml::Util.rails_root + '/tmp/sass-cache', - :always_check => Haml::Util.rails_env != "production", + :always_check => Haml::Util.rails_env == "development", :quiet => Haml::Util.rails_env != "production", :full_exception => Haml::Util.rails_env != "production") diff --git a/lib/sass/selector/sequence.rb b/lib/sass/selector/sequence.rb index 54700d875a..5dac0c5821 100644 --- a/lib/sass/selector/sequence.rb +++ b/lib/sass/selector/sequence.rb @@ -76,10 +76,10 @@ def resolve_parent_refs(super_seq) # by extending this selector with `extends`. # These correspond to a {CommaSequence}'s {CommaSequence#members members array}. # @see CommaSequence#do_extend - def do_extend(extends, supers = []) + def do_extend(extends, seen = Set.new) paths = Haml::Util.paths(members.map do |sseq_or_op| next [[sseq_or_op]] unless sseq_or_op.is_a?(SimpleSequence) - extended = sseq_or_op.do_extend(extends, supers) + extended = sseq_or_op.do_extend(extends, seen) choices = extended.map {|seq| seq.members} choices.unshift([sseq_or_op]) unless extended.any? {|seq| seq.superselector?(sseq_or_op)} choices diff --git a/lib/sass/selector/simple_sequence.rb b/lib/sass/selector/simple_sequence.rb index 88badc4650..6afe0b54e1 100644 --- a/lib/sass/selector/simple_sequence.rb +++ b/lib/sass/selector/simple_sequence.rb @@ -61,7 +61,7 @@ def resolve_parent_refs(super_seq) # @return [Array] A list of selectors generated # by extending this selector with `extends`. # @see CommaSequence#do_extend - def do_extend(extends, supers = []) + def do_extend(extends, seen = Set.new) extends.get(members.to_set).map do |seq, sels| # If A {@extend B} and C {...}, # seq is A, sels is B, and self is C @@ -69,13 +69,10 @@ def do_extend(extends, supers = []) self_without_sel = self.members - sels next unless unified = seq.members.last.unify(self_without_sel) [sels, seq.members[0...-1] + [unified]] - end.compact.map {|sels, seq| [sels, Sequence.new(seq)]}.map do |sels, seq| - seqs = seq.do_extend(extends, supers.unshift(sels)) - supers.shift - seqs + end.compact.map do |sels, seq| + seq = Sequence.new(seq) + seen.include?(sels) ? [] : seq.do_extend(extends, seen + [sels]) end.flatten.uniq - rescue SystemStackError - handle_extend_loop(supers) end # Unifies this selector with another {SimpleSequence}'s {SimpleSequence#members members array}, @@ -140,33 +137,6 @@ def eql?(other) other.class == self.class && other.base.eql?(self.base) && Haml::Util.set_eql?(other.rest, self.rest) end - - private - - # Raise a {Sass::SyntaxError} describing a loop of `@extend` directives. - # - # @param supers [Array] The stack of selectors that contains the loop, - # ordered from deepest to most shallow. - # @raise [Sass::SyntaxError] Describing the loop - def handle_extend_loop(supers) - supers.inject([]) do |sseqs, sseq| - next sseqs.push(sseq) unless sseqs.first.eql?(sseq) - conses = Haml::Util.enum_cons(sseqs.push(sseq), 2).to_a - _, i = Haml::Util.enum_with_index(conses).max do |((_, sseq1), _), ((_, sseq2), _)| - sseq1.first.line <=> sseq2.first.line - end - loop = (conses[i..-1] + conses[0...i]).map do |sseq1, sseq2| - sel1 = SimpleSequence.new(sseq1).inspect - sel2 = SimpleSequence.new(sseq2).inspect - str = " #{sel1} extends #{sel2} on line #{sseq2.first.line}" - str << " of " << sseq2.first.filename if sseq2.first.filename - str - end.join(",\n") - raise Sass::SyntaxError.new("An @extend loop was found:\n#{loop}") - end - # Should never get here - raise Sass::SyntaxError.new("An @extend loop exists, but the exact loop couldn't be found") - end end end end diff --git a/lib/sass/tree/root_node.rb b/lib/sass/tree/root_node.rb index 4071c0e830..07c1763fd7 100644 --- a/lib/sass/tree/root_node.rb +++ b/lib/sass/tree/root_node.rb @@ -68,7 +68,8 @@ def to_src(opts, fmt) child.send("to_#{fmt}", 0, opts) + if nxt && (child.is_a?(CommentNode) && child.line + child.value.count("\n") + 1 == nxt.line) || - (child.is_a?(ImportNode) && nxt.is_a?(ImportNode) && child.line + 1 == nxt.line) + (child.is_a?(ImportNode) && nxt.is_a?(ImportNode) && child.line + 1 == nxt.line) || + (child.is_a?(VariableNode) && nxt.is_a?(VariableNode) && child.line + 1 == nxt.line) "" else "\n" diff --git a/test/sass/conversion_test.rb b/test/sass/conversion_test.rb index ca8eac62ea..18db9b58d9 100755 --- a/test/sass/conversion_test.rb +++ b/test/sass/conversion_test.rb @@ -888,6 +888,24 @@ def test_guarded_variable_definition assert_sass_to_scss '$var: 12px $bar baz !default;', '$var ||= 12px $bar "baz"' end + def test_multiple_variable_definitions + assert_renders <