css_modules 0.1.0 → 0.2.0
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.
- checksums.yaml +4 -4
- data/README.md +5 -0
- data/lib/css_modules/assets/css_module.js.erb +59 -0
- data/lib/css_modules/rewrite.rb +9 -13
- data/lib/css_modules/transform.rb +38 -0
- data/lib/css_modules/version.rb +1 -1
- metadata +3 -2
- data/lib/css_modules/assets/css_module.js +0 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dce9ca6ecb86907f4b2b6dd0b19eed2769d56f8a
|
4
|
+
data.tar.gz: ef5476565fb76bb21618521dbe9e7e57c0adbef0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 386082a080e70bef2535c1bb7730f6203969f8d7655563572b427ffffbbcb96d197ac638e2a4abf8db14bbaaf50529ac414073e7703e8fa0f1ad10d397e79b38
|
7
|
+
data.tar.gz: fee03dea66978d5af49efb5a68b0702e0fc85ccfb8d1cca2ad683358dec4c325f6acfc13276bea7981c2f8b7503888a5a3f6111724e57254f280837f483587d6
|
data/README.md
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# CSSModules
|
2
2
|
|
3
|
+
[](https://travis-ci.org/rmosolgo/css_modules)
|
4
|
+
[](https://badge.fury.io/rb/css_modules)
|
5
|
+
|
3
6
|
An alternative to "magic string" classnames in Sass or SCSS. Currently supports Sprockets 2 only 😖.
|
4
7
|
|
5
8
|
Thanks to [Fatih Kadir Akın](https://twitter.com/fkadev) for his post, ["How I Implemented CSS Modules in Ruby on Rails, Easily"](https://medium.com/@fkadev/how-i-implemented-css-modules-to-ruby-on-rails-easily-abb324ce22d), which led the way on this idea!
|
@@ -118,6 +121,8 @@ $ gem install css_modules
|
|
118
121
|
- Support plain `.css`
|
119
122
|
- Use Sass's built-in parser?
|
120
123
|
- Support Sprockets 3+
|
124
|
+
- Check for hash collisions in development
|
125
|
+
- Fix bundle cache
|
121
126
|
|
122
127
|
## License
|
123
128
|
|
@@ -0,0 +1,59 @@
|
|
1
|
+
// Usage:
|
2
|
+
//
|
3
|
+
// - Call with a module name + selector name to get a transformed (opaque) selector
|
4
|
+
//
|
5
|
+
// ```js
|
6
|
+
// CSSModule("events_index", "header")
|
7
|
+
// // => "..." (some opaque string that matches the stylesheet)
|
8
|
+
// ```
|
9
|
+
//
|
10
|
+
// - Call with a module name to get a function for modulizing selectors
|
11
|
+
//
|
12
|
+
// ```js
|
13
|
+
// var eventsModule = CSSModule("events_index")
|
14
|
+
// var headerSelector = eventsModule("header")
|
15
|
+
// var footerSelector = eventsModule("footer")
|
16
|
+
// ```
|
17
|
+
//
|
18
|
+
// This behavior has to match `CSSModules::Rewrite` in Ruby
|
19
|
+
// so that generated selectors match.
|
20
|
+
var CSSModule = (function() {
|
21
|
+
// This matches Transform.compute_hash in Ruby
|
22
|
+
var HASH_LIMIT = 10009;
|
23
|
+
var SUM_SIZE = 4;
|
24
|
+
function computeHash(inputString) {
|
25
|
+
var bytesCount = 0;
|
26
|
+
var stringSum = 0;
|
27
|
+
var byte;
|
28
|
+
for(var i = 0; i < inputString.length; i++) {
|
29
|
+
byte = inputString.charCodeAt(i);
|
30
|
+
stringSum += (byte * Math.pow(256, bytesCount))
|
31
|
+
bytesCount += 1;
|
32
|
+
bytesCount %= SUM_SIZE;
|
33
|
+
}
|
34
|
+
|
35
|
+
return stringSum % HASH_LIMIT;
|
36
|
+
};
|
37
|
+
|
38
|
+
function modulizeSelector(moduleName, selectorName, environment) {
|
39
|
+
if (environment === "production") {
|
40
|
+
return moduleName.substr(0, 1) + computeHash(moduleName + selectorName) + selectorName.substr(0, 1);
|
41
|
+
} else {
|
42
|
+
return moduleName + "_" + computeHash(moduleName + selectorName) + "_" + selectorName;
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
function _CSSModule(moduleName, selectorName, environment) {
|
47
|
+
environment || (environment = "<% Rails.env %>")
|
48
|
+
|
49
|
+
if (selectorName) {
|
50
|
+
return modulizeSelector(moduleName, selectorName, environment);
|
51
|
+
} else {
|
52
|
+
return function(selectorName) {
|
53
|
+
return modulizeSelector(moduleName, selectorName, environment);
|
54
|
+
};
|
55
|
+
}
|
56
|
+
};
|
57
|
+
|
58
|
+
return _CSSModule;
|
59
|
+
})();
|
data/lib/css_modules/rewrite.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require "css_parser"
|
2
|
-
require "
|
2
|
+
require "css_modules/transform"
|
3
3
|
|
4
4
|
module CSSModules
|
5
5
|
module Rewrite
|
@@ -30,9 +30,12 @@ module CSSModules
|
|
30
30
|
|
31
31
|
# Combine `module_name` and `selector`, but don't prepend a `.` or `#`
|
32
32
|
# because this value will be inserted into the HTML page as `class=` or `id=`
|
33
|
+
# @param module_name [String] A CSS module name
|
34
|
+
# @param selector [String] A would-be DOM selector (without the leading `.` or `#`)
|
35
|
+
# @return [String] An opaque selector for this module-selector pair
|
33
36
|
def modulize_selector(module_name, selector)
|
34
|
-
|
35
|
-
|
37
|
+
tran = Rails.env.production? ? Transform::ProductionTransform : Transform::DevelopmentTransform
|
38
|
+
tran.transform(module_name, selector)
|
36
39
|
end
|
37
40
|
|
38
41
|
private
|
@@ -44,7 +47,7 @@ module CSSModules
|
|
44
47
|
if matches.nil?
|
45
48
|
selector
|
46
49
|
else
|
47
|
-
module_name =
|
50
|
+
module_name = matches[:module_name]
|
48
51
|
declaration_parts = matches[:declarations].split(" ")
|
49
52
|
declaration_parts
|
50
53
|
.map { |declaration_or_operator| rebuild_selector(module_name, declaration_or_operator) }
|
@@ -57,19 +60,12 @@ module CSSModules
|
|
57
60
|
def rebuild_selector(module_ident, selector)
|
58
61
|
case selector[0]
|
59
62
|
when "#"
|
60
|
-
"##{module_ident
|
63
|
+
"##{modulize_selector(module_ident, selector[1..-1])}"
|
61
64
|
when "."
|
62
|
-
".#{module_ident
|
65
|
+
".#{modulize_selector(module_ident, selector[1..-1])}"
|
63
66
|
else
|
64
67
|
selector
|
65
68
|
end
|
66
69
|
end
|
67
|
-
|
68
|
-
def transform_name(css_module_name)
|
69
|
-
# Some base64 characters aren't valid for CSS (eg, `=`)
|
70
|
-
opaque_string = Base64.encode64(css_module_name).gsub(/[^a-zA-Z0-9]/, "")
|
71
|
-
# p [css_module_name, opaque_string]
|
72
|
-
"#{opaque_string}_#{css_module_name}"
|
73
|
-
end
|
74
70
|
end
|
75
71
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module CSSModules
|
2
|
+
module Transform
|
3
|
+
# Hash outputs will be within the range `0..HASH_LIMIT-1`
|
4
|
+
HASH_LIMIT = 10009
|
5
|
+
# How big of a chunk should we use for folding over the string?
|
6
|
+
SUM_SIZE = 4
|
7
|
+
|
8
|
+
# Generate a short, random-ish token for `input_string`.
|
9
|
+
# This has to be replicable in JS.
|
10
|
+
# Ruby's `#hash` is randomly seeded, so we can't reuse that!
|
11
|
+
# @param input_string [String] A string to hash
|
12
|
+
# @return [String] a deterministic output for `input_string`
|
13
|
+
def self.compute_hash(input_string)
|
14
|
+
bytes_count = 0
|
15
|
+
string_sum = 0
|
16
|
+
|
17
|
+
input_string.each_byte do |byte|
|
18
|
+
string_sum += byte * (256 ** bytes_count)
|
19
|
+
bytes_count += 1
|
20
|
+
bytes_count %= SUM_SIZE
|
21
|
+
end
|
22
|
+
|
23
|
+
string_sum % HASH_LIMIT
|
24
|
+
end
|
25
|
+
|
26
|
+
module DevelopmentTransform
|
27
|
+
def self.transform(module_name, selector_name)
|
28
|
+
"#{module_name}_#{Transform.compute_hash(module_name + selector_name)}_#{selector_name}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module ProductionTransform
|
33
|
+
def self.transform(module_name, selector_name)
|
34
|
+
"#{module_name[0]}#{Transform.compute_hash(module_name + selector_name)}#{selector_name[0]}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/css_modules/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: css_modules
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Mosolgo
|
@@ -78,9 +78,10 @@ files:
|
|
78
78
|
- Rakefile
|
79
79
|
- lib/css_modules.rb
|
80
80
|
- lib/css_modules/assets/base64.js
|
81
|
-
- lib/css_modules/assets/css_module.js
|
81
|
+
- lib/css_modules/assets/css_module.js.erb
|
82
82
|
- lib/css_modules/engine.rb
|
83
83
|
- lib/css_modules/rewrite.rb
|
84
|
+
- lib/css_modules/transform.rb
|
84
85
|
- lib/css_modules/version.rb
|
85
86
|
- lib/css_modules/view_helper.rb
|
86
87
|
homepage: https://github.com/rmosolgo/css_modules
|
@@ -1,31 +0,0 @@
|
|
1
|
-
// Usage:
|
2
|
-
//
|
3
|
-
// - Call with a module name + selector name to get a transformed (opaque) selector
|
4
|
-
//
|
5
|
-
// ```js
|
6
|
-
// CSSModule("events_index", "header")
|
7
|
-
// // => "..." (some opaque string that matches the stylesheet)
|
8
|
-
// ```
|
9
|
-
//
|
10
|
-
// - Call with a module name to get a function for modulizing selectors
|
11
|
-
//
|
12
|
-
// ```js
|
13
|
-
// var eventsModule = CSSModule("events_index")
|
14
|
-
// var headerSelector = eventsModule("header")
|
15
|
-
// var footerSelector = eventsModule("footer")
|
16
|
-
// ```
|
17
|
-
//
|
18
|
-
// This behavior has to match `CSSModules::Rewrite` in Ruby
|
19
|
-
// so that generated selectors match.
|
20
|
-
function CSSModule(moduleName, selectorName) {
|
21
|
-
// This matches `Rewrite`:
|
22
|
-
var opaqueString = btoa(moduleName).replace(/[^a-zA-Z0-9]/g, "")
|
23
|
-
var transformedModuleName = opaqueString + "_" + moduleName;
|
24
|
-
if (selectorName) {
|
25
|
-
return transformedModuleName + "_" + selectorName;
|
26
|
-
} else {
|
27
|
-
return function(selectorName) {
|
28
|
-
return transformedModuleName + "_" + selectorName;
|
29
|
-
};
|
30
|
-
}
|
31
|
-
};
|