css_modules 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dce9ca6ecb86907f4b2b6dd0b19eed2769d56f8a
4
- data.tar.gz: ef5476565fb76bb21618521dbe9e7e57c0adbef0
3
+ metadata.gz: 403f0b499fe5a5237f4bfc5c21a92829bc4bc9bc
4
+ data.tar.gz: 862dca4771710a27d889663475c1e65bdb8feeae
5
5
  SHA512:
6
- metadata.gz: 386082a080e70bef2535c1bb7730f6203969f8d7655563572b427ffffbbcb96d197ac638e2a4abf8db14bbaaf50529ac414073e7703e8fa0f1ad10d397e79b38
7
- data.tar.gz: fee03dea66978d5af49efb5a68b0702e0fc85ccfb8d1cca2ad683358dec4c325f6acfc13276bea7981c2f8b7503888a5a3f6111724e57254f280837f483587d6
6
+ metadata.gz: bad7f00717805d0c236dfc0b62f9ada3fbce90141452b3e6e51b85582ca74b10e16c5eaebc550f77557e8f787614dc9cb7346d636d15ae09bd955b889478017d
7
+ data.tar.gz: d1c2adbd20eb6d351bd2c7f8bedde52a7abde889e4c30858b502868fc5599fc0cc3c9dfbe653b14121aa096b8dff95a3fa30cd521162f8d543598736b5162a5c
data/README.md CHANGED
@@ -114,12 +114,10 @@ $ gem install css_modules
114
114
 
115
115
  ## TODO
116
116
 
117
- - Support minified identifiers for Production Env
118
117
  - Dead code warning for Development env:
119
118
  - Warn when not all styles are used?
120
119
  - Sprockets require CSS to JS? `require_styles` ?
121
120
  - Support plain `.css`
122
- - Use Sass's built-in parser?
123
121
  - Support Sprockets 3+
124
122
  - Check for hash collisions in development
125
123
  - Fix bundle cache
@@ -37,14 +37,14 @@ var CSSModule = (function() {
37
37
 
38
38
  function modulizeSelector(moduleName, selectorName, environment) {
39
39
  if (environment === "production") {
40
- return moduleName.substr(0, 1) + computeHash(moduleName + selectorName) + selectorName.substr(0, 1);
40
+ return moduleName.substr(0, 1) + computeHash(moduleName) + selectorName;
41
41
  } else {
42
- return moduleName + "_" + computeHash(moduleName + selectorName) + "_" + selectorName;
42
+ return moduleName + "_" + computeHash(moduleName) + "_" + selectorName;
43
43
  }
44
44
  }
45
45
 
46
46
  function _CSSModule(moduleName, selectorName, environment) {
47
- environment || (environment = "<% Rails.env %>")
47
+ environment || (environment = "<% CSSModules.env.to_s %>")
48
48
 
49
49
  if (selectorName) {
50
50
  return modulizeSelector(moduleName, selectorName, environment);
@@ -1,5 +1,5 @@
1
- require "css_parser"
2
1
  require "css_modules/transform"
2
+ require "sass"
3
3
 
4
4
  module CSSModules
5
5
  module Rewrite
@@ -13,19 +13,13 @@ module CSSModules
13
13
  # so that selectors can only be accessed programatically,
14
14
  # not by class name literals.
15
15
  def rewrite_css(css_module_code)
16
- parser = CssParser::Parser.new
17
- parser.load_string!(css_module_code)
16
+ # Parse incoming CSS into an AST
17
+ css_root = Sass::SCSS::CssParser.new(css_module_code, "(CSSModules)", 1).parse
18
18
 
19
- rules = ""
19
+ Sass::Tree::Visitors::SetOptions.visit(css_root, {})
20
+ ModuleVisitor.visit(css_root)
20
21
 
21
- parser.each_selector do |selector, declarations, specificity|
22
- prettified_declarations = declarations.gsub(/;\s+/, ";\n ")
23
- modulized_selector = parse_selector(selector)
24
- rules << "#{modulized_selector} {\n #{prettified_declarations}\n}\n"
25
- end
26
-
27
- rules.strip!
28
- rules
22
+ css_root.render
29
23
  end
30
24
 
31
25
  # Combine `module_name` and `selector`, but don't prepend a `.` or `#`
@@ -34,37 +28,63 @@ module CSSModules
34
28
  # @param selector [String] A would-be DOM selector (without the leading `.` or `#`)
35
29
  # @return [String] An opaque selector for this module-selector pair
36
30
  def modulize_selector(module_name, selector)
37
- tran = Rails.env.production? ? Transform::ProductionTransform : Transform::DevelopmentTransform
31
+ tran = CSSModules.env == :production ? Transform::ProductionTransform : Transform::DevelopmentTransform
38
32
  tran.transform(module_name, selector)
39
33
  end
40
34
 
41
- private
42
- module_function
35
+ class ModuleVisitor < Sass::Tree::Visitors::Base
36
+ # No need to `yield` here since we run _after_ Sass -- it's already flattened.
37
+ # @return [void]
38
+ def visit_rule(node)
39
+ node.rule = node.rule.map { |r| transform_selector(r) }
40
+ node.parsed_rules = rebuild_parsed_rules(node.parsed_rules)
41
+ end
42
+
43
+ private
43
44
 
44
- # This parses the selector for `:module` definitions or does nothing.
45
- def parse_selector(selector)
46
- matches = RE_MODULE.match(selector)
47
- if matches.nil?
48
- selector
49
- else
50
- module_name = matches[:module_name]
51
- declaration_parts = matches[:declarations].split(" ")
52
- declaration_parts
53
- .map { |declaration_or_operator| rebuild_selector(module_name, declaration_or_operator) }
54
- .join(" ")
45
+ def rebuild_parsed_rules(parsed_rules)
46
+ new_members = parsed_rules.members.map do |member_seq|
47
+ # `member_seq` is actually a deeply-nested array-like thing
48
+ # but since we're running _after_ Sass itself,
49
+ # we know all the tricky stuff is already taken care of.
50
+ # So now we can flatten it and re-parse it, no problem.
51
+ rule_s = member_seq.to_s
52
+ transformed_rule_s = transform_selector(rule_s)
53
+ selector_to_sass(transformed_rule_s)
54
+ end
55
+ Sass::Selector::CommaSequence.new(new_members)
56
+ end
57
+
58
+ def selector_to_sass(selector)
59
+ # This strips off leading whitespace, should I be putting it back on?
60
+ Sass::SCSS::StaticParser.new(selector.strip, nil, 1).parse_selector
61
+ end
62
+
63
+ # This parses the selector for `:module` definitions or does nothing.
64
+ def transform_selector(selector)
65
+ matches = Rewrite::RE_MODULE.match(selector)
66
+ if matches.nil?
67
+ selector
68
+ else
69
+ module_name = matches[:module_name]
70
+ declaration_parts = matches[:declarations].split(" ")
71
+ declaration_parts
72
+ .map { |declaration_or_operator| rebuild_selector(module_name, declaration_or_operator) }
73
+ .join(" ")
74
+ end
55
75
  end
56
- end
57
76
 
58
- # If `selector` is a class or ID, scope it to this module.
59
- # If it is a bare element, leave it unscoped.
60
- def rebuild_selector(module_ident, selector)
61
- case selector[0]
62
- when "#"
63
- "##{modulize_selector(module_ident, selector[1..-1])}"
64
- when "."
65
- ".#{modulize_selector(module_ident, selector[1..-1])}"
66
- else
67
- selector
77
+ # If `selector` is a class or ID, scope it to this module.
78
+ # If it is a bare element, leave it unscoped.
79
+ def rebuild_selector(module_name, selector)
80
+ case selector[0]
81
+ when "#"
82
+ "##{Rewrite.modulize_selector(module_name, selector[1..-1])}"
83
+ when "."
84
+ ".#{Rewrite.modulize_selector(module_name, selector[1..-1])}"
85
+ else
86
+ selector
87
+ end
68
88
  end
69
89
  end
70
90
  end
@@ -25,13 +25,13 @@ module CSSModules
25
25
 
26
26
  module DevelopmentTransform
27
27
  def self.transform(module_name, selector_name)
28
- "#{module_name}_#{Transform.compute_hash(module_name + selector_name)}_#{selector_name}"
28
+ "#{module_name}_#{Transform.compute_hash(module_name)}_#{selector_name}"
29
29
  end
30
30
  end
31
31
 
32
32
  module ProductionTransform
33
33
  def self.transform(module_name, selector_name)
34
- "#{module_name[0]}#{Transform.compute_hash(module_name + selector_name)}#{selector_name[0]}"
34
+ "#{module_name[0]}#{Transform.compute_hash(module_name)}#{selector_name}"
35
35
  end
36
36
  end
37
37
  end
@@ -1,3 +1,3 @@
1
1
  module CSSModules
2
- VERSION = '0.2.0'
2
+ VERSION = '0.3.0'
3
3
  end
data/lib/css_modules.rb CHANGED
@@ -2,3 +2,12 @@ require "css_modules/engine"
2
2
  require "css_modules/version"
3
3
  require "css_modules/rewrite"
4
4
  require "css_modules/view_helper"
5
+
6
+
7
+ module CSSModules
8
+ class << self
9
+ attr_accessor :env
10
+ end
11
+ # If `:production`, then we use shorter hashes
12
+ self.env = Rails.env.production? ? :production : :development
13
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: css_modules
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-12 00:00:00.000000000 Z
11
+ date: 2016-10-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -25,19 +25,19 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: css_parser
28
+ name: sass
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '3.2'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '3.2'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: sqlite3
43
43
  requirement: !ruby/object:Gem::Requirement