deadfire 0.4.0 → 0.5.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/.github/workflows/ci.yml +4 -1
- data/.gitignore +1 -0
- data/Gemfile.lock +96 -4
- data/README.md +3 -53
- data/changelog.md +9 -1
- data/deadfire.gemspec +6 -1
- data/lib/.keep +0 -0
- data/lib/deadfire/asset_loader.rb +67 -0
- data/lib/deadfire/asset_registry.rb +88 -0
- data/lib/deadfire/ast_printer.rb +6 -1
- data/lib/deadfire/configuration.rb +11 -1
- data/lib/deadfire/css_generator.rb +1 -1
- data/lib/deadfire/front_end/apply_node.rb +1 -1
- data/lib/deadfire/front_end/parser.rb +0 -4
- data/lib/deadfire/front_end/stylesheet_node.rb +1 -1
- data/lib/deadfire/interpreter.rb +6 -10
- data/lib/deadfire/mixin_parser.rb +51 -0
- data/lib/deadfire/parser_engine.rb +11 -1
- data/lib/deadfire/railtie.rb +38 -0
- data/lib/deadfire/spec.rb +2 -0
- data/lib/deadfire/version.rb +1 -1
- data/lib/deadfire.rb +6 -2
- metadata +66 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b92ff55d4eb765b9042dad38b321944bacf5334db4d2cfe17aabc8fa6c6fcbf3
|
4
|
+
data.tar.gz: 956b776ba58413cc70e70fe8b98a8392ea7091994127070852323c84ca7b2dcf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6172c9434d1aeaafe2ff0a45e257ddc022214f5f81895cf3d763327d26e087e5ce50cd0b585a1a3c47cb193f8048c4a14c59ef4d4ca508988a62b6e229ba7409
|
7
|
+
data.tar.gz: eb267997efa8f7a953d9bb7fc385147aefff84684db57f7caa45c21f34cf89776af42c0ba9694e6887b30f894dc50bdb75ab8c98a61ff4343c772f170cfb995c
|
data/.github/workflows/ci.yml
CHANGED
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,14 +1,61 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
deadfire (0.
|
4
|
+
deadfire (0.5.0)
|
5
|
+
actionpack (>= 7.0.0)
|
6
|
+
activesupport (>= 7.0.0)
|
7
|
+
propshaft (>= 0.9.0)
|
8
|
+
railties (>= 7.0.0)
|
5
9
|
|
6
10
|
GEM
|
7
11
|
remote: https://rubygems.org/
|
8
12
|
specs:
|
13
|
+
actionpack (7.1.3.4)
|
14
|
+
actionview (= 7.1.3.4)
|
15
|
+
activesupport (= 7.1.3.4)
|
16
|
+
nokogiri (>= 1.8.5)
|
17
|
+
racc
|
18
|
+
rack (>= 2.2.4)
|
19
|
+
rack-session (>= 1.0.1)
|
20
|
+
rack-test (>= 0.6.3)
|
21
|
+
rails-dom-testing (~> 2.2)
|
22
|
+
rails-html-sanitizer (~> 1.6)
|
23
|
+
actionview (7.1.3.4)
|
24
|
+
activesupport (= 7.1.3.4)
|
25
|
+
builder (~> 3.1)
|
26
|
+
erubi (~> 1.11)
|
27
|
+
rails-dom-testing (~> 2.2)
|
28
|
+
rails-html-sanitizer (~> 1.6)
|
29
|
+
activesupport (7.1.3.4)
|
30
|
+
base64
|
31
|
+
bigdecimal
|
32
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
33
|
+
connection_pool (>= 2.2.5)
|
34
|
+
drb
|
35
|
+
i18n (>= 1.6, < 2)
|
36
|
+
minitest (>= 5.1)
|
37
|
+
mutex_m
|
38
|
+
tzinfo (~> 2.0)
|
9
39
|
ansi (1.5.0)
|
10
|
-
|
11
|
-
|
40
|
+
base64 (0.2.0)
|
41
|
+
bigdecimal (3.1.8)
|
42
|
+
builder (3.3.0)
|
43
|
+
concurrent-ruby (1.3.4)
|
44
|
+
connection_pool (2.4.1)
|
45
|
+
crass (1.0.6)
|
46
|
+
drb (2.2.1)
|
47
|
+
erubi (1.13.0)
|
48
|
+
i18n (1.14.6)
|
49
|
+
concurrent-ruby (~> 1.0)
|
50
|
+
io-console (0.7.2)
|
51
|
+
irb (1.14.0)
|
52
|
+
rdoc (>= 4.0.0)
|
53
|
+
reline (>= 0.4.2)
|
54
|
+
loofah (2.23.1)
|
55
|
+
crass (~> 1.0.2)
|
56
|
+
nokogiri (>= 1.12.0)
|
57
|
+
mini_portile2 (2.8.7)
|
58
|
+
minitest (5.25.1)
|
12
59
|
minitest-focus (1.3.1)
|
13
60
|
minitest (>= 4, < 6)
|
14
61
|
minitest-reporters (1.5.0)
|
@@ -16,8 +63,53 @@ GEM
|
|
16
63
|
builder
|
17
64
|
minitest (>= 5.0)
|
18
65
|
ruby-progressbar
|
66
|
+
mutex_m (0.2.0)
|
67
|
+
nokogiri (1.16.7)
|
68
|
+
mini_portile2 (~> 2.8.2)
|
69
|
+
racc (~> 1.4)
|
70
|
+
propshaft (0.9.0)
|
71
|
+
actionpack (>= 7.0.0)
|
72
|
+
activesupport (>= 7.0.0)
|
73
|
+
rack
|
74
|
+
railties (>= 7.0.0)
|
75
|
+
psych (5.1.2)
|
76
|
+
stringio
|
77
|
+
racc (1.8.1)
|
78
|
+
rack (3.1.8)
|
79
|
+
rack-session (2.0.0)
|
80
|
+
rack (>= 3.0.0)
|
81
|
+
rack-test (2.1.0)
|
82
|
+
rack (>= 1.3)
|
83
|
+
rackup (2.1.0)
|
84
|
+
rack (>= 3)
|
85
|
+
webrick (~> 1.8)
|
86
|
+
rails-dom-testing (2.2.0)
|
87
|
+
activesupport (>= 5.0.0)
|
88
|
+
minitest
|
89
|
+
nokogiri (>= 1.6)
|
90
|
+
rails-html-sanitizer (1.6.0)
|
91
|
+
loofah (~> 2.21)
|
92
|
+
nokogiri (~> 1.14)
|
93
|
+
railties (7.1.3.4)
|
94
|
+
actionpack (= 7.1.3.4)
|
95
|
+
activesupport (= 7.1.3.4)
|
96
|
+
irb
|
97
|
+
rackup (>= 1.0.0)
|
98
|
+
rake (>= 12.2)
|
99
|
+
thor (~> 1.0, >= 1.2.2)
|
100
|
+
zeitwerk (~> 2.6)
|
19
101
|
rake (12.3.3)
|
102
|
+
rdoc (6.7.0)
|
103
|
+
psych (>= 4.0.0)
|
104
|
+
reline (0.5.9)
|
105
|
+
io-console (~> 0.5)
|
20
106
|
ruby-progressbar (1.11.0)
|
107
|
+
stringio (3.1.1)
|
108
|
+
thor (1.3.1)
|
109
|
+
tzinfo (2.0.6)
|
110
|
+
concurrent-ruby (~> 1.0)
|
111
|
+
webrick (1.9.0)
|
112
|
+
zeitwerk (2.6.16)
|
21
113
|
|
22
114
|
PLATFORMS
|
23
115
|
ruby
|
@@ -30,4 +122,4 @@ DEPENDENCIES
|
|
30
122
|
rake
|
31
123
|
|
32
124
|
BUNDLED WITH
|
33
|
-
2.
|
125
|
+
2.6.1
|
data/README.md
CHANGED
@@ -79,31 +79,6 @@ Re-use the styles using @apply:
|
|
79
79
|
}
|
80
80
|
```
|
81
81
|
|
82
|
-
### Nesting
|
83
|
-
|
84
|
-
The CSS nesting feature, as described in the CSS Nesting specification (https://drafts.csswg.org/css-nesting/), allows for more intuitive and concise styling by enabling the nesting of CSS rules within one another. This feature simplifies the structure of stylesheets and improves readability.
|
85
|
-
|
86
|
-
Now that nesting has been upstreamed to CSS, meaning it is now a part of the official CSS specification. As a result, Deafire will leverage the native CSS nesting feature instead of implementing this feature (which was the original goal of this project).
|
87
|
-
|
88
|
-
Example:
|
89
|
-
|
90
|
-
```css
|
91
|
-
.foo {
|
92
|
-
color: green;
|
93
|
-
}
|
94
|
-
.foo .bar {
|
95
|
-
font-size: 1.4rem;
|
96
|
-
}
|
97
|
-
|
98
|
-
/* can be simplified to */
|
99
|
-
.foo {
|
100
|
-
color: green;
|
101
|
-
.bar {
|
102
|
-
font-size: 1.4rem;
|
103
|
-
}
|
104
|
-
}
|
105
|
-
```
|
106
|
-
|
107
82
|
### Fault tolerant
|
108
83
|
|
109
84
|
When Deadfire encounters an error, such as a missing mixin or other issues, it does not immediately raise an error that would halt the execution. Instead, it continues processing the CSS code and collects the encountered errors. These errors are then reported through the ErrorReporter class, allowing you to handle or display them as needed.
|
@@ -128,39 +103,14 @@ Or install it yourself as:
|
|
128
103
|
|
129
104
|
## Deadfire + Ruby on Rails
|
130
105
|
|
131
|
-
|
132
|
-
|
133
|
-
### Propshaft
|
134
|
-
|
135
|
-
To setup Propshaft to use Deadfire as a preprocessor:
|
106
|
+
Propshaft is the new asset pipeline for Rails, to use Deadfire as a preprocessor add the deadfire gem to your Gemfile.
|
136
107
|
|
137
108
|
```ruby
|
138
|
-
|
139
|
-
class DeadfireCompiler < Propshaft::Compiler
|
140
|
-
def compile(logical_path, input)
|
141
|
-
Deadfire.parse(input, root_path: Rails.root.join("app", "assets", "stylesheets"))
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
Rails.application.config.assets.compilers << ["text/css", DeadfireCompiler]
|
109
|
+
gem "deadfire"
|
146
110
|
```
|
147
|
-
### Sprockets
|
148
111
|
|
149
|
-
|
150
|
-
|
151
|
-
```ruby
|
152
|
-
# config/initializers/assets.rb
|
153
|
-
class DeadfireProcessor
|
154
|
-
def call(input)
|
155
|
-
return { data: Deadfire.parse(input[:data]) }
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
Deadfire.configuration.root_path = Rails.root.join('app', 'assets', 'stylesheets')
|
160
|
-
Sprockets.register_preprocessor('text/css', DeadfireProcessor.new)
|
161
|
-
```
|
112
|
+
That's all, your css file should now be run through Deadfire.
|
162
113
|
|
163
|
-
Your css file should now be run through Deadfire.
|
164
114
|
## Development
|
165
115
|
|
166
116
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/changelog.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
## Changelog
|
2
|
-
### 0.
|
2
|
+
### 0.6.0 (current)
|
3
|
+
|
4
|
+
### 0.5.0 (12 Dec 2024)
|
5
|
+
- Drop ruby 2.7
|
6
|
+
- Add a railties to make it real simple to pre-process every file for a simple setup
|
7
|
+
- Added the asset registry to make it easier to control how or which file is used as a mixin
|
8
|
+
- Excluded files are no longer pro-processed
|
9
|
+
- Make rails + propshaft dependencies
|
3
10
|
|
4
11
|
### 0.4.0 (18 May 2024)
|
5
12
|
- Fix parsing comments that have 2 stars e.g. /**
|
@@ -15,6 +22,7 @@
|
|
15
22
|
Deadfire will look for the file nav.css, then nav.scss in the `config.root_path` in the case when a file extension is not included.
|
16
23
|
|
17
24
|
- Simplify the configuration by having one option called compressed instead of keep_newlines and keep_comments.
|
25
|
+
- Add the ability to exclude files from being pre-processed via the `config.deadfire.excluded_files` option.
|
18
26
|
|
19
27
|
### 0.3.0 (15 November 2023)
|
20
28
|
|
data/deadfire.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.summary = "Deadfire - lightweight css preprocessor"
|
10
10
|
spec.homepage = "https://github.com/hahmed/deadfire"
|
11
11
|
spec.license = "MIT"
|
12
|
-
spec.required_ruby_version = Gem::Requirement.new(">=
|
12
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 3.0")
|
13
13
|
|
14
14
|
spec.metadata["homepage_uri"] = spec.homepage
|
15
15
|
spec.metadata["source_code_uri"] = "https://github.com/hahmed/deadfire"
|
@@ -23,4 +23,9 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.bindir = "exe"
|
24
24
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
25
25
|
spec.require_paths = ["lib"]
|
26
|
+
|
27
|
+
spec.add_dependency "actionpack", ">= 7.0.0"
|
28
|
+
spec.add_dependency "activesupport", ">= 7.0.0"
|
29
|
+
spec.add_dependency "railties", ">= 7.0.0"
|
30
|
+
spec.add_dependency "propshaft", ">= 0.9.0"
|
26
31
|
end
|
data/lib/.keep
ADDED
File without changes
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Deadfire
|
4
|
+
# AssetLoader is responsible for loading mixin templates from the file system which can be used to mixin css into
|
5
|
+
# your stylesheet.
|
6
|
+
class AssetLoader
|
7
|
+
attr_reader :settings
|
8
|
+
|
9
|
+
def initialize(path)
|
10
|
+
@path = path
|
11
|
+
@cache = ActiveSupport::Cache::FileStore.new("tmp/deadfire_cache")
|
12
|
+
end
|
13
|
+
|
14
|
+
def cache_css(name, value)
|
15
|
+
cached_mixins[name] = value
|
16
|
+
end
|
17
|
+
|
18
|
+
def cached_css(name)
|
19
|
+
cached_mixins[name]
|
20
|
+
end
|
21
|
+
|
22
|
+
def preload(force_reload=false)
|
23
|
+
if force_reload
|
24
|
+
@_cached_mixins = nil
|
25
|
+
end
|
26
|
+
|
27
|
+
cached_mixins
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def cached_mixins
|
33
|
+
@_cached_mixins ||= load_mixins
|
34
|
+
end
|
35
|
+
|
36
|
+
def load_mixins
|
37
|
+
Array.wrap(Deadfire.configuration.asset_registry.mixins_for(@path)).each.with_object({}) do |filename, data|
|
38
|
+
unless File.exist?(filename)
|
39
|
+
Deadfire.config.logger.error("Mixin not found: #{filename}")
|
40
|
+
next
|
41
|
+
end
|
42
|
+
|
43
|
+
stat = File.stat(filename)
|
44
|
+
key = "#{filename}-#{stat.mtime.hash}"
|
45
|
+
|
46
|
+
content = @cache.fetch(key)
|
47
|
+
|
48
|
+
if content.nil?
|
49
|
+
content = load_and_parse_mixin(filename, key)
|
50
|
+
end
|
51
|
+
|
52
|
+
content.each do |key, value|
|
53
|
+
Deadfire.config.logger.warn("Mixin '#{key}' will be overrided with a new value.") if data.key?(key)
|
54
|
+
|
55
|
+
data[key] = value
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def load_and_parse_mixin(filename, key)
|
61
|
+
content = File.read(filename)
|
62
|
+
mixins = ParserEngine.new(content).load_mixins
|
63
|
+
@cache.write(key, mixins)
|
64
|
+
mixins
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Deadfire
|
4
|
+
class AssetRegistry
|
5
|
+
attr_reader :settings
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@settings = Hash.new { |h, k| h[k] = [] }
|
9
|
+
end
|
10
|
+
|
11
|
+
# for a given path, load all the mixins that are registered
|
12
|
+
# this makes it possible to load admin or other scoped mixins for a
|
13
|
+
# specific path
|
14
|
+
def register_path(path, *mixins)
|
15
|
+
normalized_mixins = Array.wrap(mixins).map { |p| full_path(p) }
|
16
|
+
normalize_path = strip_path(path).to_s
|
17
|
+
@settings[normalize_path].concat(normalized_mixins)
|
18
|
+
end
|
19
|
+
|
20
|
+
# for a given path, load all the mixins that are registered
|
21
|
+
# e.g. admin/ or admin will load all mixins for admin, if admin is a scope
|
22
|
+
# all mixins for admin/* will be loaded
|
23
|
+
def mixins_for(path)
|
24
|
+
return [] unless path.present?
|
25
|
+
|
26
|
+
mixins = []
|
27
|
+
|
28
|
+
mixins.concat Array.wrap(@settings[path])
|
29
|
+
|
30
|
+
if settings["*"].present?
|
31
|
+
mixins.concat Array.wrap(settings["*"])
|
32
|
+
end
|
33
|
+
|
34
|
+
scope = scope_from_path(path)
|
35
|
+
|
36
|
+
if scope.present? && settings[scope].present?
|
37
|
+
mixins.concat Array.wrap(settings[scope])
|
38
|
+
end
|
39
|
+
|
40
|
+
mixins.compact.uniq
|
41
|
+
end
|
42
|
+
|
43
|
+
def clear
|
44
|
+
@settings.clear
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def full_path(filename)
|
50
|
+
if File.exist?(filename)
|
51
|
+
filename
|
52
|
+
else
|
53
|
+
normalize_path(filename)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def normalize_path(filename)
|
58
|
+
path = File.join(Deadfire.config.root_path, filename)
|
59
|
+
path = css_extension(path)
|
60
|
+
|
61
|
+
unless File.exist?(path)
|
62
|
+
raise "Error finding asset path #{path}"
|
63
|
+
end
|
64
|
+
|
65
|
+
path
|
66
|
+
end
|
67
|
+
|
68
|
+
def css_extension(filename)
|
69
|
+
filename.end_with?(".css") ? filename : "#{filename}.css"
|
70
|
+
end
|
71
|
+
|
72
|
+
def scope?(path)
|
73
|
+
path.include?("/")
|
74
|
+
end
|
75
|
+
|
76
|
+
def scope_from_path(path)
|
77
|
+
if scope?(path)
|
78
|
+
path.split("/")[0...-1].join("/")
|
79
|
+
else
|
80
|
+
nil
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def strip_path(path)
|
85
|
+
path.split("/").last
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
data/lib/deadfire/ast_printer.rb
CHANGED
@@ -13,7 +13,7 @@ module Deadfire
|
|
13
13
|
def visit_stylesheet_node(node)
|
14
14
|
puts "StylesheetNode"
|
15
15
|
node.statements.each do |statement|
|
16
|
-
#
|
16
|
+
# todo
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
@@ -54,5 +54,10 @@ module Deadfire
|
|
54
54
|
puts "CommentNode"
|
55
55
|
puts " Comment: #{node.comment.lexeme}"
|
56
56
|
end
|
57
|
+
|
58
|
+
def visit_newline_node(node)
|
59
|
+
puts "NewlineNode"
|
60
|
+
puts " Newline: #{node.text}"
|
61
|
+
end
|
57
62
|
end
|
58
63
|
end
|
@@ -3,7 +3,7 @@ require "logger"
|
|
3
3
|
|
4
4
|
module Deadfire
|
5
5
|
class Configuration
|
6
|
-
attr_reader :directories, :root_path, :compressed, :logger, :supressed
|
6
|
+
attr_reader :directories, :root_path, :compressed, :logger, :supressed, :excluded_files, :asset_registry
|
7
7
|
|
8
8
|
def initialize
|
9
9
|
@directories = []
|
@@ -11,6 +11,8 @@ module Deadfire
|
|
11
11
|
@compressed = false
|
12
12
|
@logger = Logger.new(STDOUT, level: :warn)
|
13
13
|
@supressed = true
|
14
|
+
@excluded_files = []
|
15
|
+
@asset_registry = AssetRegistry.new
|
14
16
|
end
|
15
17
|
|
16
18
|
def root_path=(value)
|
@@ -33,5 +35,13 @@ module Deadfire
|
|
33
35
|
def supressed=(value)
|
34
36
|
@supressed = value
|
35
37
|
end
|
38
|
+
|
39
|
+
def excluded_files=(value)
|
40
|
+
@excluded_files = value
|
41
|
+
end
|
42
|
+
|
43
|
+
def preprocess(*mixins, path: "*")
|
44
|
+
@asset_registry.register_path(path, *mixins)
|
45
|
+
end
|
36
46
|
end
|
37
47
|
end
|
data/lib/deadfire/interpreter.rb
CHANGED
@@ -1,12 +1,10 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Deadfire
|
4
4
|
class Interpreter # :nodoc:
|
5
|
-
|
6
|
-
self.cached_apply_rules = Hash.new { |h, k| h[k] = nil }
|
7
|
-
|
8
|
-
def initialize(error_reporter)
|
5
|
+
def initialize(error_reporter, asset_loader)
|
9
6
|
@error_reporter = error_reporter
|
7
|
+
@asset_loader = asset_loader
|
10
8
|
end
|
11
9
|
|
12
10
|
def interpret(node)
|
@@ -27,8 +25,8 @@ module Deadfire
|
|
27
25
|
if node.block
|
28
26
|
visit_block_node(node.block, node)
|
29
27
|
|
30
|
-
unless
|
31
|
-
|
28
|
+
unless @asset_loader.cached_css(node.selector.selector)
|
29
|
+
@asset_loader.cache_css(node.selector.selector, node.block) if node.selector.cacheable?
|
32
30
|
end
|
33
31
|
end
|
34
32
|
end
|
@@ -60,9 +58,7 @@ module Deadfire
|
|
60
58
|
def apply_mixin(mixin, node)
|
61
59
|
updated_declarations = []
|
62
60
|
mixin.mixin_names.each do |mixin_name|
|
63
|
-
if
|
64
|
-
cached_block = Interpreter.cached_apply_rules[mixin_name]
|
65
|
-
|
61
|
+
if cached_block = @asset_loader.cached_css(mixin_name)
|
66
62
|
# NOTE: remove the left and right brace but we probably don't need to do this, how can this be simplified?
|
67
63
|
cached_block.declarations[1...-1].each do |cached_declaration|
|
68
64
|
updated_declarations << cached_declaration
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Deadfire
|
4
|
+
class MixinParser # :nodoc:
|
5
|
+
attr_reader :mixins
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@mixins = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def interpret(node)
|
12
|
+
node.accept(self)
|
13
|
+
end
|
14
|
+
|
15
|
+
def visit_stylesheet_node(node)
|
16
|
+
node.statements.each { |child| child.accept(self) }
|
17
|
+
end
|
18
|
+
|
19
|
+
def visit_at_rule_node(node)
|
20
|
+
if node.block
|
21
|
+
visit_block_node(node.block, node)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def visit_ruleset_node(node)
|
26
|
+
if node.block
|
27
|
+
visit_block_node(node.block, node)
|
28
|
+
|
29
|
+
if node.selector.cacheable?
|
30
|
+
if @mixins.key?(node.selector.selector)
|
31
|
+
Deadfire.config.logger.warn("Mixin '#{node.selector.selector}' will be overrided with a new value.")
|
32
|
+
end
|
33
|
+
|
34
|
+
@mixins[node.selector.selector] = node.block
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def visit_block_node(node, parent)
|
40
|
+
end
|
41
|
+
|
42
|
+
def visit_comment_node(node)
|
43
|
+
end
|
44
|
+
|
45
|
+
def visit_apply_node(node)
|
46
|
+
end
|
47
|
+
|
48
|
+
def visit_newline_node(node)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -7,12 +7,13 @@ module Deadfire
|
|
7
7
|
def initialize(content, options = {})
|
8
8
|
@error_reporter = ErrorReporter.new
|
9
9
|
@options = {}
|
10
|
+
@asset_loader = AssetLoader.new(options[:filename])
|
10
11
|
@scanner = FrontEnd::Scanner.new(content, error_reporter)
|
11
12
|
end
|
12
13
|
|
13
14
|
def parse
|
14
15
|
ast = _parse
|
15
|
-
interpreter = Interpreter.new(error_reporter)
|
16
|
+
interpreter = Interpreter.new(error_reporter, @asset_loader)
|
16
17
|
ast.statements.each do |node|
|
17
18
|
interpreter.interpret(node)
|
18
19
|
end
|
@@ -31,6 +32,15 @@ module Deadfire
|
|
31
32
|
@error_reporter.errors?
|
32
33
|
end
|
33
34
|
|
35
|
+
def load_mixins
|
36
|
+
ast = _parse
|
37
|
+
parser = MixinParser.new
|
38
|
+
ast.statements.each do |node|
|
39
|
+
parser.interpret(node)
|
40
|
+
end
|
41
|
+
parser.mixins
|
42
|
+
end
|
43
|
+
|
34
44
|
private
|
35
45
|
|
36
46
|
def _parse
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "rails"
|
3
|
+
require "propshaft"
|
4
|
+
|
5
|
+
module Deadfire
|
6
|
+
class Railties < ::Rails::Railtie
|
7
|
+
config.deadfire = ActiveSupport::OrderedOptions.new
|
8
|
+
config.deadfire.root_path = nil
|
9
|
+
config.deadfire.excluded_files = []
|
10
|
+
|
11
|
+
initializer :deadfire do |app|
|
12
|
+
Deadfire.configure do |deadfire_config|
|
13
|
+
deadfire_config.root_path = config.deadfire.root_path || app.root.join("app", "assets", "stylesheets")
|
14
|
+
deadfire_config.excluded_files = config.deadfire.excluded_files
|
15
|
+
deadfire_config.compressed = config.assets.compressed
|
16
|
+
deadfire_config.logger = config.assets.logger || Rails.logger
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class DeadfireCompiler < ::Propshaft::Compiler
|
21
|
+
def compile(logical_path, input)
|
22
|
+
path = logical_path.path.to_s
|
23
|
+
|
24
|
+
return input if Deadfire.config.excluded_files.include?(path)
|
25
|
+
|
26
|
+
# by default, all files in the will be preprocessed
|
27
|
+
if Deadfire.config.asset_registry.settings.empty?
|
28
|
+
all_files = Dir.glob("#{Deadfire.config.root_path}/**/*.css")
|
29
|
+
Deadfire.config.preprocess(*all_files)
|
30
|
+
end
|
31
|
+
|
32
|
+
Deadfire.parse(input, filename: logical_path.logical_path.to_s)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
config.assets.compilers << ["text/css", DeadfireCompiler]
|
37
|
+
end
|
38
|
+
end
|
data/lib/deadfire/spec.rb
CHANGED
@@ -23,6 +23,7 @@ module Deadfire
|
|
23
23
|
PAGE = "@page"
|
24
24
|
FONT_FACE = "@font-face"
|
25
25
|
KEYFRAMES = "@keyframes"
|
26
|
+
WEBKIT_KEYFRAMES = "@-webkit-keyframes"
|
26
27
|
SUPPORTS = "@supports"
|
27
28
|
NAMESPACE = "@namespace"
|
28
29
|
COUNTER_STYLE = "@counter-style"
|
@@ -38,6 +39,7 @@ module Deadfire
|
|
38
39
|
PAGE,
|
39
40
|
FONT_FACE,
|
40
41
|
KEYFRAMES,
|
42
|
+
WEBKIT_KEYFRAMES,
|
41
43
|
SUPPORTS,
|
42
44
|
NAMESPACE,
|
43
45
|
COUNTER_STYLE,
|
data/lib/deadfire/version.rb
CHANGED
data/lib/deadfire.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "deadfire/ast_printer"
|
4
|
+
require_relative "deadfire/asset_loader"
|
5
|
+
require_relative "deadfire/asset_registry"
|
4
6
|
require_relative "deadfire/css_generator"
|
5
7
|
require_relative "deadfire/configuration"
|
6
8
|
require_relative "deadfire/errors"
|
7
9
|
require_relative "deadfire/error_reporter"
|
8
10
|
require_relative "deadfire/interpreter"
|
11
|
+
require_relative "deadfire/mixin_parser"
|
9
12
|
require_relative "deadfire/parser_engine"
|
10
13
|
require_relative "deadfire/spec"
|
11
14
|
require_relative "deadfire/filename_helper"
|
@@ -47,9 +50,10 @@ module Deadfire
|
|
47
50
|
config.compressed = options[:compressed]
|
48
51
|
end
|
49
52
|
|
50
|
-
parser = ParserEngine.new(content)
|
51
|
-
# TODO: hook into a logger and report the errors
|
53
|
+
parser = ParserEngine.new(content, filename: options[:filename])
|
52
54
|
parser.parse
|
53
55
|
end
|
54
56
|
end
|
55
57
|
end
|
58
|
+
|
59
|
+
require_relative "deadfire/railtie"
|
metadata
CHANGED
@@ -1,15 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: deadfire
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Haroon Ahmed
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
12
|
-
dependencies:
|
11
|
+
date: 2024-12-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: actionpack
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 7.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 7.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activesupport
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 7.0.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 7.0.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: railties
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 7.0.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 7.0.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: propshaft
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.9.0
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.9.0
|
13
69
|
description:
|
14
70
|
email:
|
15
71
|
- haroon.ahmed25@gmail.com
|
@@ -37,7 +93,10 @@ files:
|
|
37
93
|
- bin/test
|
38
94
|
- changelog.md
|
39
95
|
- deadfire.gemspec
|
96
|
+
- lib/.keep
|
40
97
|
- lib/deadfire.rb
|
98
|
+
- lib/deadfire/asset_loader.rb
|
99
|
+
- lib/deadfire/asset_registry.rb
|
41
100
|
- lib/deadfire/ast_printer.rb
|
42
101
|
- lib/deadfire/configuration.rb
|
43
102
|
- lib/deadfire/css_generator.rb
|
@@ -57,7 +116,9 @@ files:
|
|
57
116
|
- lib/deadfire/front_end/stylesheet_node.rb
|
58
117
|
- lib/deadfire/front_end/token.rb
|
59
118
|
- lib/deadfire/interpreter.rb
|
119
|
+
- lib/deadfire/mixin_parser.rb
|
60
120
|
- lib/deadfire/parser_engine.rb
|
121
|
+
- lib/deadfire/railtie.rb
|
61
122
|
- lib/deadfire/spec.rb
|
62
123
|
- lib/deadfire/version.rb
|
63
124
|
homepage: https://github.com/hahmed/deadfire
|
@@ -75,14 +136,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
75
136
|
requirements:
|
76
137
|
- - ">="
|
77
138
|
- !ruby/object:Gem::Version
|
78
|
-
version: '
|
139
|
+
version: '3.0'
|
79
140
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
141
|
requirements:
|
81
142
|
- - ">="
|
82
143
|
- !ruby/object:Gem::Version
|
83
144
|
version: '0'
|
84
145
|
requirements: []
|
85
|
-
rubygems_version: 3.5.
|
146
|
+
rubygems_version: 3.5.9
|
86
147
|
signing_key:
|
87
148
|
specification_version: 4
|
88
149
|
summary: Deadfire - lightweight css preprocessor
|