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

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