css_modules 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://travis-ci.org/rmosolgo/css_modules.svg?branch=master)](https://travis-ci.org/rmosolgo/css_modules)
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/css_modules.svg)](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
|
-
};
|