css_modules 0.1.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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +124 -0
- data/Rakefile +20 -0
- data/lib/css_modules/assets/base64.js +136 -0
- data/lib/css_modules/assets/css_module.js +31 -0
- data/lib/css_modules/engine.rb +17 -0
- data/lib/css_modules/rewrite.rb +75 -0
- data/lib/css_modules/version.rb +3 -0
- data/lib/css_modules/view_helper.rb +56 -0
- data/lib/css_modules.rb +4 -0
- metadata +110 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 431374aa2a26649b2dac684cf81efe66e419c84c
|
4
|
+
data.tar.gz: 2dffe66a072a52b0c60074940be0774a6513e7a1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b89042953316ab3a5b1b17c7c46eb5d2882e529415f5fb7a1c5247d3628ca1cd11aa796b09c9d0318c89578fe384a896f014d124f3f5616d07047b073fcc4c5f
|
7
|
+
data.tar.gz: 9c6387bfb0e5b68e7f5879c2999e4cd994c1b3ddfa03449ac18b5213f276ca7bff7f6c4abe9227732f8430134f68a59d2db39673594b9128fc2f992d3656dc5e
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2016 Robert Mosolgo
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
# CSSModules
|
2
|
+
|
3
|
+
An alternative to "magic string" classnames in Sass or SCSS. Currently supports Sprockets 2 only 😖.
|
4
|
+
|
5
|
+
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!
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
### Add modules to stylesheets
|
10
|
+
|
11
|
+
Your `.sass` or `.scss` stylesheets can define modules with `:module(module_name)`:
|
12
|
+
|
13
|
+
```scss
|
14
|
+
:module(events) {
|
15
|
+
.header {
|
16
|
+
font-style: bold;
|
17
|
+
}
|
18
|
+
|
19
|
+
.link:visited {
|
20
|
+
color: purple;
|
21
|
+
}
|
22
|
+
|
23
|
+
#footer {
|
24
|
+
font-size: 0.8em;
|
25
|
+
}
|
26
|
+
}
|
27
|
+
```
|
28
|
+
|
29
|
+
Sass requires an extra `\`:
|
30
|
+
|
31
|
+
```sass
|
32
|
+
\:module(events)
|
33
|
+
.header
|
34
|
+
font-style: bold
|
35
|
+
```
|
36
|
+
|
37
|
+
### Put modulized names into HTML
|
38
|
+
|
39
|
+
To access the contents of a module in a view, you must include the helpers in your controller:
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
class EventsController < ApplicationController
|
43
|
+
helper CSSModules::ViewHelper
|
44
|
+
end
|
45
|
+
```
|
46
|
+
|
47
|
+
(To use the view helper _everywhere_, include it in `ApplicationController`.)
|
48
|
+
|
49
|
+
Then, in your view, you can access the module & its contents by name:
|
50
|
+
|
51
|
+
```erb
|
52
|
+
<!-- access by module + identifier -->
|
53
|
+
<h1 id="<%= css_module("events", "main_header") %>">
|
54
|
+
Events
|
55
|
+
</h1>
|
56
|
+
|
57
|
+
<!-- block helper -->
|
58
|
+
<% css_module("events") do |events_module| %>
|
59
|
+
<div id="<%= events_module.selector("footer") %>">
|
60
|
+
<%= link_to "Home", "/", class: events_module.selector("link") %>
|
61
|
+
© My company
|
62
|
+
</div>
|
63
|
+
<% end %>
|
64
|
+
```
|
65
|
+
|
66
|
+
### Use modulized names in JavaScript
|
67
|
+
|
68
|
+
In JavaScript, you can include a helper to access module styles:
|
69
|
+
|
70
|
+
```jsx
|
71
|
+
//= require css_module
|
72
|
+
|
73
|
+
// Module + identifier
|
74
|
+
var headerClass = CSSModule("events", "header")
|
75
|
+
$("." + headerClass).text() // => "Events"
|
76
|
+
|
77
|
+
// Or module helper function
|
78
|
+
var eventsModule = CSSModule("events")
|
79
|
+
|
80
|
+
function header() {
|
81
|
+
var headerClass = eventsModule("header")
|
82
|
+
return (
|
83
|
+
<h1 className={headerClass}>Events</h1>
|
84
|
+
)
|
85
|
+
}
|
86
|
+
```
|
87
|
+
|
88
|
+
`CSSModule` requires the global JS function `btoa`. To include a polyfill from this gem, add:
|
89
|
+
|
90
|
+
```js
|
91
|
+
//= require base64
|
92
|
+
```
|
93
|
+
|
94
|
+
## Installation
|
95
|
+
|
96
|
+
Add this line to your application's Gemfile:
|
97
|
+
|
98
|
+
```ruby
|
99
|
+
gem 'css_modules'
|
100
|
+
```
|
101
|
+
|
102
|
+
And then execute:
|
103
|
+
```bash
|
104
|
+
$ bundle
|
105
|
+
```
|
106
|
+
|
107
|
+
Or install it yourself as:
|
108
|
+
```bash
|
109
|
+
$ gem install css_modules
|
110
|
+
```
|
111
|
+
|
112
|
+
## TODO
|
113
|
+
|
114
|
+
- Support minified identifiers for Production Env
|
115
|
+
- Dead code warning for Development env:
|
116
|
+
- Warn when not all styles are used?
|
117
|
+
- Sprockets require CSS to JS? `require_styles` ?
|
118
|
+
- Support plain `.css`
|
119
|
+
- Use Sass's built-in parser?
|
120
|
+
- Support Sprockets 3+
|
121
|
+
|
122
|
+
## License
|
123
|
+
|
124
|
+
[MIT](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'bundler/gem_tasks'
|
8
|
+
|
9
|
+
require 'rake/testtask'
|
10
|
+
|
11
|
+
Rake::TestTask.new(:test) do |t|
|
12
|
+
t.libs << 'lib'
|
13
|
+
t.libs << 'test'
|
14
|
+
t.pattern = 'test/**/*_test.rb'
|
15
|
+
t.verbose = false
|
16
|
+
t.warning = false
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
task default: :test
|
@@ -0,0 +1,136 @@
|
|
1
|
+
// btoa polyfill, from https://jsfiddle.net/gabrieleromanato/qaght/
|
2
|
+
var Base64 = {
|
3
|
+
|
4
|
+
|
5
|
+
_keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
|
6
|
+
|
7
|
+
|
8
|
+
encode: function(input) {
|
9
|
+
var output = "";
|
10
|
+
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
|
11
|
+
var i = 0;
|
12
|
+
|
13
|
+
input = Base64._utf8_encode(input);
|
14
|
+
|
15
|
+
while (i < input.length) {
|
16
|
+
|
17
|
+
chr1 = input.charCodeAt(i++);
|
18
|
+
chr2 = input.charCodeAt(i++);
|
19
|
+
chr3 = input.charCodeAt(i++);
|
20
|
+
|
21
|
+
enc1 = chr1 >> 2;
|
22
|
+
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
|
23
|
+
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
|
24
|
+
enc4 = chr3 & 63;
|
25
|
+
|
26
|
+
if (isNaN(chr2)) {
|
27
|
+
enc3 = enc4 = 64;
|
28
|
+
} else if (isNaN(chr3)) {
|
29
|
+
enc4 = 64;
|
30
|
+
}
|
31
|
+
|
32
|
+
output = output + this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) + this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
|
33
|
+
|
34
|
+
}
|
35
|
+
|
36
|
+
return output;
|
37
|
+
},
|
38
|
+
|
39
|
+
|
40
|
+
decode: function(input) {
|
41
|
+
var output = "";
|
42
|
+
var chr1, chr2, chr3;
|
43
|
+
var enc1, enc2, enc3, enc4;
|
44
|
+
var i = 0;
|
45
|
+
|
46
|
+
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
|
47
|
+
|
48
|
+
while (i < input.length) {
|
49
|
+
|
50
|
+
enc1 = this._keyStr.indexOf(input.charAt(i++));
|
51
|
+
enc2 = this._keyStr.indexOf(input.charAt(i++));
|
52
|
+
enc3 = this._keyStr.indexOf(input.charAt(i++));
|
53
|
+
enc4 = this._keyStr.indexOf(input.charAt(i++));
|
54
|
+
|
55
|
+
chr1 = (enc1 << 2) | (enc2 >> 4);
|
56
|
+
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
|
57
|
+
chr3 = ((enc3 & 3) << 6) | enc4;
|
58
|
+
|
59
|
+
output = output + String.fromCharCode(chr1);
|
60
|
+
|
61
|
+
if (enc3 != 64) {
|
62
|
+
output = output + String.fromCharCode(chr2);
|
63
|
+
}
|
64
|
+
if (enc4 != 64) {
|
65
|
+
output = output + String.fromCharCode(chr3);
|
66
|
+
}
|
67
|
+
|
68
|
+
}
|
69
|
+
|
70
|
+
output = Base64._utf8_decode(output);
|
71
|
+
|
72
|
+
return output;
|
73
|
+
|
74
|
+
},
|
75
|
+
|
76
|
+
_utf8_encode: function(string) {
|
77
|
+
string = string.replace(/\r\n/g, "\n");
|
78
|
+
var utftext = "";
|
79
|
+
|
80
|
+
for (var n = 0; n < string.length; n++) {
|
81
|
+
|
82
|
+
var c = string.charCodeAt(n);
|
83
|
+
|
84
|
+
if (c < 128) {
|
85
|
+
utftext += String.fromCharCode(c);
|
86
|
+
}
|
87
|
+
else if ((c > 127) && (c < 2048)) {
|
88
|
+
utftext += String.fromCharCode((c >> 6) | 192);
|
89
|
+
utftext += String.fromCharCode((c & 63) | 128);
|
90
|
+
}
|
91
|
+
else {
|
92
|
+
utftext += String.fromCharCode((c >> 12) | 224);
|
93
|
+
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
|
94
|
+
utftext += String.fromCharCode((c & 63) | 128);
|
95
|
+
}
|
96
|
+
|
97
|
+
}
|
98
|
+
|
99
|
+
return utftext;
|
100
|
+
},
|
101
|
+
|
102
|
+
_utf8_decode: function(utftext) {
|
103
|
+
var string = "";
|
104
|
+
var i = 0;
|
105
|
+
var c = c1 = c2 = 0;
|
106
|
+
|
107
|
+
while (i < utftext.length) {
|
108
|
+
|
109
|
+
c = utftext.charCodeAt(i);
|
110
|
+
|
111
|
+
if (c < 128) {
|
112
|
+
string += String.fromCharCode(c);
|
113
|
+
i++;
|
114
|
+
}
|
115
|
+
else if ((c > 191) && (c < 224)) {
|
116
|
+
c2 = utftext.charCodeAt(i + 1);
|
117
|
+
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
|
118
|
+
i += 2;
|
119
|
+
}
|
120
|
+
else {
|
121
|
+
c2 = utftext.charCodeAt(i + 1);
|
122
|
+
c3 = utftext.charCodeAt(i + 2);
|
123
|
+
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
|
124
|
+
i += 3;
|
125
|
+
}
|
126
|
+
|
127
|
+
}
|
128
|
+
|
129
|
+
return string;
|
130
|
+
}
|
131
|
+
|
132
|
+
}
|
133
|
+
|
134
|
+
if (!btoa) {
|
135
|
+
var btoa = function(str) { return Base64.encode(str) }
|
136
|
+
}
|
@@ -0,0 +1,31 @@
|
|
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
|
+
};
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module CSSModules
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
isolate_namespace CSSModules
|
4
|
+
|
5
|
+
initializer "css_modules.register_preprocessor" do |app|
|
6
|
+
# Make css_module.js accessible to Sprockets
|
7
|
+
app.config.assets.paths << File.expand_path("../assets", __FILE__)
|
8
|
+
|
9
|
+
# This is Sprockets 2 only :S
|
10
|
+
app.config.assets.configure do |env|
|
11
|
+
env.register_postprocessor('text/css', :css_modules) do |context, data|
|
12
|
+
CSSModules::Rewrite.rewrite_css(data)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require "css_parser"
|
2
|
+
require "base64"
|
3
|
+
|
4
|
+
module CSSModules
|
5
|
+
module Rewrite
|
6
|
+
# Module Scopes
|
7
|
+
# :module(login) { .button {color: red;} }
|
8
|
+
RE_MODULE = /^\:module\((?<module_name>.*?)\)\s+(?<declarations>.*)/
|
9
|
+
|
10
|
+
module_function
|
11
|
+
# Take css module code as input, and rewrite it as
|
12
|
+
# browser-friendly CSS code. Apply opaque transformations
|
13
|
+
# so that selectors can only be accessed programatically,
|
14
|
+
# not by class name literals.
|
15
|
+
def rewrite_css(css_module_code)
|
16
|
+
parser = CssParser::Parser.new
|
17
|
+
parser.load_string!(css_module_code)
|
18
|
+
|
19
|
+
rules = ""
|
20
|
+
|
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
|
29
|
+
end
|
30
|
+
|
31
|
+
# Combine `module_name` and `selector`, but don't prepend a `.` or `#`
|
32
|
+
# because this value will be inserted into the HTML page as `class=` or `id=`
|
33
|
+
def modulize_selector(module_name, selector)
|
34
|
+
transformed_name = transform_name(module_name)
|
35
|
+
"#{transformed_name}_#{selector}"
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
module_function
|
40
|
+
|
41
|
+
# This parses the selector for `:module` definitions or does nothing.
|
42
|
+
def parse_selector(selector)
|
43
|
+
matches = RE_MODULE.match(selector)
|
44
|
+
if matches.nil?
|
45
|
+
selector
|
46
|
+
else
|
47
|
+
module_name = transform_name(matches[:module_name])
|
48
|
+
declaration_parts = matches[:declarations].split(" ")
|
49
|
+
declaration_parts
|
50
|
+
.map { |declaration_or_operator| rebuild_selector(module_name, declaration_or_operator) }
|
51
|
+
.join(" ")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# If `selector` is a class or ID, scope it to this module.
|
56
|
+
# If it is a bare element, leave it unscoped.
|
57
|
+
def rebuild_selector(module_ident, selector)
|
58
|
+
case selector[0]
|
59
|
+
when "#"
|
60
|
+
"##{module_ident}_#{selector[1..-1]}"
|
61
|
+
when "."
|
62
|
+
".#{module_ident}_#{selector[1..-1]}"
|
63
|
+
else
|
64
|
+
selector
|
65
|
+
end
|
66
|
+
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
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module CSSModules
|
2
|
+
# Provides helpers to the view layer.
|
3
|
+
# Add it to a controller with Rails' `helper` method.
|
4
|
+
#
|
5
|
+
# @example including ViewHelper in ApplicationController (and therefore all its descendants)
|
6
|
+
# class ApplicationController < ActionController::Base
|
7
|
+
# helper CSSModules::ViewHelper
|
8
|
+
# end
|
9
|
+
module ViewHelper
|
10
|
+
# @overload css_module(module_name, selector_name)
|
11
|
+
# Apply the styles from `module_name` for `selector_name`
|
12
|
+
#
|
13
|
+
# @example Getting a selector within a module
|
14
|
+
# css_module("events_index", "header")
|
15
|
+
# # => "..." (opaque string which matches the stylesheet)
|
16
|
+
#
|
17
|
+
# @param module_name
|
18
|
+
# @param selector_name DOM id or class name
|
19
|
+
# @return [String] modulized selector name for `class=` or `id=` in a view
|
20
|
+
#
|
21
|
+
# @overload css_module(module_name, &block)
|
22
|
+
# Modulize selectors within a block using the yielded helper.
|
23
|
+
#
|
24
|
+
# @example modulizing a few selectors
|
25
|
+
# <% css_module("events_index") do |events_module| %>
|
26
|
+
# <h1 class="<%= events_module.selector("heading") %>">All events</h1>
|
27
|
+
# <p id="<%= events_module.selector("description") %>"> ... </p>
|
28
|
+
# <% end %>
|
29
|
+
#
|
30
|
+
# @param module_name
|
31
|
+
# @yieldparam [ModuleLookup] a helper for modulizing selectors within `module_name`
|
32
|
+
# @return [void]
|
33
|
+
def css_module(module_name, selector_name = nil, &block)
|
34
|
+
if selector_name.nil? && block_given?
|
35
|
+
lookup = ModuleLookup.new(module_name)
|
36
|
+
yield(lookup)
|
37
|
+
nil
|
38
|
+
elsif selector_name.present?
|
39
|
+
CSSModules::Rewrite.modulize_selector(module_name.to_s, selector_name.to_s)
|
40
|
+
else
|
41
|
+
raise("css_module must be called with a module_name and either a selector_name or a block")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Shorthand for getting several classnames from one module
|
46
|
+
class ModuleLookup
|
47
|
+
def initialize(module_name)
|
48
|
+
@module_name = module_name.to_s
|
49
|
+
end
|
50
|
+
|
51
|
+
def selector(selector_name)
|
52
|
+
CSSModules::Rewrite.modulize_selector(@module_name, selector_name.to_s)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/css_modules.rb
ADDED
metadata
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: css_modules
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Robert Mosolgo
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-10-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: css_parser
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sqlite3
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: execjs
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Provides a css-module-like experience to Sass/SCSS, Rails views and JavaScript
|
70
|
+
email:
|
71
|
+
- rdmosolgo@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- MIT-LICENSE
|
77
|
+
- README.md
|
78
|
+
- Rakefile
|
79
|
+
- lib/css_modules.rb
|
80
|
+
- lib/css_modules/assets/base64.js
|
81
|
+
- lib/css_modules/assets/css_module.js
|
82
|
+
- lib/css_modules/engine.rb
|
83
|
+
- lib/css_modules/rewrite.rb
|
84
|
+
- lib/css_modules/version.rb
|
85
|
+
- lib/css_modules/view_helper.rb
|
86
|
+
homepage: https://github.com/rmosolgo/css_modules
|
87
|
+
licenses:
|
88
|
+
- MIT
|
89
|
+
metadata: {}
|
90
|
+
post_install_message:
|
91
|
+
rdoc_options: []
|
92
|
+
require_paths:
|
93
|
+
- lib
|
94
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
requirements: []
|
105
|
+
rubyforge_project:
|
106
|
+
rubygems_version: 2.5.1
|
107
|
+
signing_key:
|
108
|
+
specification_version: 4
|
109
|
+
summary: Prevent naming conflicts in Sass stylesheets
|
110
|
+
test_files: []
|