sass 3.3.0.alpha.370 → 3.3.0.alpha.372

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/REVISION CHANGED
@@ -1 +1 @@
1
- cc1787dbfd5db4c5ecb498d6be100336c8e23ef0
1
+ 91702cc715e601a0bf682c87983f0b8d9ceb0963
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.3.0.alpha.370
1
+ 3.3.0.alpha.372
data/VERSION_DATE CHANGED
@@ -1 +1 @@
1
- 08 October 2013 21:30:40 GMT
1
+ 10 October 2013 16:29:15 GMT
@@ -1,7 +1,6 @@
1
1
  require 'set'
2
2
 
3
3
  module Sass
4
-
5
4
  # The abstract base class for lexical environments for SassScript.
6
5
  class BaseEnvironment
7
6
  class << self
@@ -56,12 +55,8 @@ module Sass
56
55
  # The options passed to the Sass Engine.
57
56
  attr_reader :options
58
57
 
59
- # [Environment] The caller environment
60
58
  attr_writer :caller
61
-
62
- # [Environment] The content environment
63
59
  attr_writer :content
64
- attr_writer :selector
65
60
 
66
61
  # variable
67
62
  # Script::Value
@@ -92,7 +87,9 @@ module Sass
92
87
 
93
88
  # The content passed to this environment. This is naturally only set
94
89
  # for mixin body environments with content passed in.
95
- # @return {Environment?}
90
+ #
91
+ # @return {[Array<Sass::Tree::Node>, Environment]?} The content nodes and
92
+ # the lexical environment of the content block.
96
93
  def content
97
94
  @content || (@parent && @parent.content)
98
95
  end
@@ -103,10 +100,26 @@ module Sass
103
100
  # @return [Selector::CommaSequence?] The current selector, with any
104
101
  # nesting fully resolved.
105
102
  def selector
106
- parent_selector = @caller ? @caller.selector : (@parent && @parent.selector)
107
- return parent_selector unless @selector
108
- return @selector.resolve_parent_refs(parent_selector) if parent_selector
109
- @selector
103
+ return if @no_selector
104
+ return @selector if @selector
105
+ return @caller.selector if @caller
106
+ return @parent.selector if @parent
107
+ nil
108
+ end
109
+
110
+ def selector=(value)
111
+ @selector = value
112
+ @no_selector = false
113
+ end
114
+
115
+ # Mark this environment as having no selector information. Unlike setting
116
+ # {#selector} to nil, this indicates that this environment should not
117
+ # inherit its {#parent}'s or {#caller}'s selector.
118
+ #
119
+ # This will be overwritten if {#selector} is set.
120
+ def no_selector!
121
+ @selector = nil
122
+ @no_selector = true
110
123
  end
111
124
 
112
125
  # The top-level Environment object.
@@ -18,9 +18,12 @@ module Sass
18
18
  # handling commas appropriately.
19
19
  #
20
20
  # @param super_cseq [CommaSequence] The parent selector
21
+ # @param implicit_parent [Boolean] Whether the the parent
22
+ # selector should automatically be prepended to the resolved
23
+ # selector if it contains no parent refs.
21
24
  # @return [CommaSequence] This selector, with parent references resolved
22
25
  # @raise [Sass::SyntaxError] If a parent selector is invalid
23
- def resolve_parent_refs(super_cseq)
26
+ def resolve_parent_refs(super_cseq, implicit_parent = true)
24
27
  if super_cseq.nil?
25
28
  if @members.any? do |sel|
26
29
  sel.members.any? do |sel_or_op|
@@ -36,7 +39,7 @@ module Sass
36
39
 
37
40
  CommaSequence.new(
38
41
  super_cseq.members.map do |super_seq|
39
- @members.map {|seq| seq.resolve_parent_refs(super_seq)}
42
+ @members.map {|seq| seq.resolve_parent_refs(super_seq, implicit_parent)}
40
43
  end.flatten)
41
44
  end
42
45
 
@@ -44,14 +44,20 @@ module Sass
44
44
  # handling commas appropriately.
45
45
  #
46
46
  # @param super_seq [Sequence] The parent selector sequence
47
+ # @param implicit_parent [Boolean] Whether the the parent
48
+ # selector should automatically be prepended to the resolved
49
+ # selector if it contains no parent refs.
47
50
  # @return [Sequence] This selector, with parent references resolved
48
51
  # @raise [Sass::SyntaxError] If a parent selector is invalid
49
- def resolve_parent_refs(super_seq)
52
+ def resolve_parent_refs(super_seq, implicit_parent)
50
53
  members = @members.dup
51
54
  nl = (members.first == "\n" && members.shift)
52
- unless members.any? do |seq_or_op|
53
- seq_or_op.is_a?(SimpleSequence) && seq_or_op.members.first.is_a?(Parent)
54
- end
55
+ contains_parent_ref = members.any? do |seq_or_op|
56
+ seq_or_op.is_a?(SimpleSequence) && seq_or_op.members.first.is_a?(Parent)
57
+ end
58
+ return self if !implicit_parent && !contains_parent_ref
59
+
60
+ unless contains_parent_ref
55
61
  old_members, members = members, []
56
62
  members << nl if nl
57
63
  members << SimpleSequence.new([Parent.new], false)
@@ -8,14 +8,15 @@ module Sass
8
8
  # in addition to nodes for CSS rules and properties.
9
9
  # Nodes that only appear in this state are called **dynamic nodes**.
10
10
  #
11
- # {Tree::Visitors::Perform} creates a static Sass tree, which is different.
12
- # It still has nodes for CSS rules and properties
13
- # but it doesn't have any dynamic-generation-related nodes.
14
- # The nodes in this state are in the same structure as the Sass document:
15
- # rules and properties are nested beneath one another.
16
- # Nodes that can be in this state or in the dynamic state
17
- # are called **static nodes**; nodes that can only be in this state
18
- # are called **solely static nodes**.
11
+ # {Tree::Visitors::Perform} creates a static Sass tree, which is
12
+ # different. It still has nodes for CSS rules and properties but it
13
+ # doesn't have any dynamic-generation-related nodes. The nodes in
14
+ # this state are in a similar structure to the Sass document: rules
15
+ # and properties are nested beneath one another, although the
16
+ # {Tree::RuleNode} selectors are already in their final state. Nodes
17
+ # that can be in this state or in the dynamic state are called
18
+ # **static nodes**; nodes that can only be in this state are called
19
+ # **solely static nodes**.
19
20
  #
20
21
  # {Tree::Visitors::Cssize} is then used to create a static CSS tree.
21
22
  # This is like a static Sass tree,
@@ -16,18 +16,17 @@ module Sass::Tree
16
16
  # @return [Array<String, Sass::Script::Tree::Node>]
17
17
  attr_accessor :rule
18
18
 
19
- # The CSS selector for this rule,
20
- # without any unresolved interpolation
21
- # but with parent references still intact.
22
- # It's only set once {Tree::Visitors::Perform} has been run.
23
- #
19
+ # The CSS selector for this rule, without any unresolved
20
+ # interpolation but with parent references still intact. It's only
21
+ # guaranteed to be set once {Tree::Visitors::Perform} has been
22
+ # run, but it may be set before then for optimization reasons.
24
23
  #
25
24
  # @return [Selector::CommaSequence]
26
25
  attr_accessor :parsed_rules
27
26
 
28
- # The CSS selector for this rule,
29
- # without any unresolved interpolation or parent references.
30
- # It's only set once {Tree::Visitors::Cssize} has been run.
27
+ # The CSS selector for this rule, without any unresolved
28
+ # interpolation or parent references. It's only set once
29
+ # {Tree::Visitors::Perform} has been run.
31
30
  #
32
31
  # @return [Selector::CommaSequence]
33
32
  attr_accessor :resolved_rules
@@ -191,14 +191,9 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
191
191
  result
192
192
  end
193
193
 
194
- # Resolves parent references and nested selectors,
195
- # and updates the indentation of the rule node based on the nesting level.
194
+ # Updates the indentation of the rule node based on the nesting
195
+ # level. The selectors were resolved in {Perform}.
196
196
  def visit_rule(node)
197
- parent_resolved_rules = parent.is_a?(Sass::Tree::RuleNode) ? parent.resolved_rules : nil
198
- # It's possible for resolved_rules to be set
199
- # if we've duplicated this node during @media bubbling
200
- node.resolved_rules ||= node.parsed_rules.resolve_parent_refs(parent_resolved_rules)
201
-
202
197
  yield
203
198
 
204
199
  rules = node.children.select {|c| c.is_a?(Sass::Tree::RuleNode) || c.bubbles?}
@@ -330,7 +330,7 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
330
330
 
331
331
  self.class.perform_arguments(mixin, args, keywords, splat) do |env|
332
332
  env.caller = Sass::Environment.new(@environment)
333
- env.content = node.children if node.has_children
333
+ env.content = [node.children, @environment] if node.has_children
334
334
 
335
335
  trace_node = Sass::Tree::TraceNode.from_node(node.name, node)
336
336
  with_environment(env) {trace_node.children = mixin.tree.map {|c| visit(c)}.flatten}
@@ -346,11 +346,13 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
346
346
  end
347
347
 
348
348
  def visit_content(node)
349
- content = @environment.content
349
+ content, content_env = @environment.content
350
350
  return [] unless content
351
351
  @environment.stack.with_mixin(node.filename, node.line, '@content') do
352
352
  trace_node = Sass::Tree::TraceNode.from_node('@content', node)
353
- with_environment(@environment.caller) do
353
+ content_env = Sass::Environment.new(content_env)
354
+ content_env.caller = Sass::Environment.new(@environment)
355
+ with_environment(content_env) do
354
356
  trace_node.children = content.map {|c| visit(c.dup)}.flatten
355
357
  end
356
358
  trace_node
@@ -378,15 +380,28 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
378
380
  # Runs SassScript interpolation in the selector,
379
381
  # and then parses the result into a {Sass::Selector::CommaSequence}.
380
382
  def visit_rule(node)
383
+ old_at_root, @at_root = @at_root, false
381
384
  parser = Sass::SCSS::StaticParser.new(run_interp(node.rule),
382
385
  node.filename, node.options[:importer], node.line)
383
386
  node.parsed_rules ||= parser.parse_selector
387
+ node.resolved_rules = node.parsed_rules.resolve_parent_refs(@environment.selector, !old_at_root)
384
388
  node.stack_trace = @environment.stack.to_s if node.options[:trace_selectors]
385
389
  with_environment Sass::Environment.new(@environment, node.options) do
386
- @environment.selector = node.parsed_rules
390
+ @environment.selector = node.resolved_rules
387
391
  node.children = node.children.map {|c| visit(c)}.flatten
388
392
  end
389
393
  node
394
+ ensure
395
+ @at_root = old_at_root
396
+ end
397
+
398
+ # Sets a variable that indicates that the first level of rule nodes
399
+ # shouldn't include the parent selector by default.
400
+ def visit_atroot(node)
401
+ old_at_root, @at_root = @at_root, true
402
+ yield.children
403
+ ensure
404
+ @at_root = old_at_root
390
405
  end
391
406
 
392
407
  # Loads the new variable value into the environment.
@@ -424,7 +439,11 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
424
439
 
425
440
  def visit_directive(node)
426
441
  node.resolved_value = run_interp(node.value)
427
- yield
442
+ with_environment Sass::Environment.new(@environment) do
443
+ @environment.no_selector!
444
+ node.children = node.children.map {|c| visit(c)}.flatten
445
+ node
446
+ end
428
447
  end
429
448
 
430
449
  def visit_media(node)
@@ -1958,6 +1958,51 @@ CSS
1958
1958
  SCSS
1959
1959
  end
1960
1960
 
1961
+ def test_at_root_with_parent_ref
1962
+ assert_equal <<CSS, render(<<SCSS)
1963
+ .foo {
1964
+ a: b; }
1965
+ CSS
1966
+ .foo {
1967
+ @at-root & {
1968
+ a: b;
1969
+ }
1970
+ }
1971
+ SCSS
1972
+ end
1973
+
1974
+ def test_multi_level_at_root_with_parent_ref
1975
+ assert_equal <<CSS, render(<<SCSS)
1976
+ .foo .bar {
1977
+ a: b; }
1978
+ CSS
1979
+ .foo {
1980
+ @at-root & {
1981
+ .bar {
1982
+ @at-root & {
1983
+ a: b;
1984
+ }
1985
+ }
1986
+ }
1987
+ }
1988
+ SCSS
1989
+ end
1990
+
1991
+ def test_multi_level_at_root_with_inner_parent_ref
1992
+ assert_equal <<CSS, render(<<SCSS)
1993
+ .bar {
1994
+ a: b; }
1995
+ CSS
1996
+ .foo {
1997
+ @at-root .bar {
1998
+ @at-root & {
1999
+ a: b;
2000
+ }
2001
+ }
2002
+ }
2003
+ SCSS
2004
+ end
2005
+
1961
2006
  ## Selector Script
1962
2007
 
1963
2008
  def test_selector_script
@@ -2105,6 +2150,21 @@ CSS
2105
2150
  SCSS
2106
2151
  end
2107
2152
 
2153
+ def test_multi_level_at_root_with_inner_selector_script
2154
+ assert_equal <<CSS, render(<<SCSS)
2155
+ .bar {
2156
+ a: b; }
2157
+ CSS
2158
+ .foo {
2159
+ @at-root .bar {
2160
+ @at-root \#{&} {
2161
+ a: b;
2162
+ }
2163
+ }
2164
+ }
2165
+ SCSS
2166
+ end
2167
+
2108
2168
  def test_at_root_with_at_root_through_mixin
2109
2169
  assert_equal(<<CSS, render(<<SCSS))
2110
2170
  .bar-baz {
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sass
3
3
  version: !ruby/object:Gem::Version
4
- hash: 592302569
4
+ hash: 592302565
5
5
  prerelease: 6
6
6
  segments:
7
7
  - 3
8
8
  - 3
9
9
  - 0
10
10
  - alpha
11
- - 370
12
- version: 3.3.0.alpha.370
11
+ - 372
12
+ version: 3.3.0.alpha.372
13
13
  platform: ruby
14
14
  authors:
15
15
  - Nathan Weizenbaum
@@ -19,7 +19,7 @@ autorequire:
19
19
  bindir: bin
20
20
  cert_chain: []
21
21
 
22
- date: 2013-10-08 00:00:00 -04:00
22
+ date: 2013-10-10 00:00:00 -04:00
23
23
  default_executable:
24
24
  dependencies:
25
25
  - !ruby/object:Gem::Dependency