deadfire 0.4.0 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 82f838eee7d8e2ef83b302d7de509c428af8584567892296fd3011df42cb0990
4
- data.tar.gz: 1a4b828032eda5dae38d3da5f820081402f7e66f919b2720ff8f9be65d6d8bf0
3
+ metadata.gz: bf5ff2b972555ed94df49077860d3a5097400ada7b48aa753cfea0297eef953d
4
+ data.tar.gz: ae2b3e72441a00b32658cb8998b92f71ae33f5197cefa973cff7d4a688bb2b12
5
5
  SHA512:
6
- metadata.gz: a724bdb7b939e5b4404ee5cee4266ad6c278ac5d4e7fc74f560884f4b30fc123c3492a52abd5028adbc9f579dd690beb26d0de2460e8cb3b8e482d44ce77e733
7
- data.tar.gz: e353841bfb20e25ff0ff1556d555443546783a744cf96b2a2149862cf8dbebb31bb9c48f50d68f20355ea036c36e22ca4ac9f059413df500974f4888849673bd
6
+ metadata.gz: 998ae91967f0cea560a426d521bd1882e764e4168aab5c12af464a8b9d40d3d7849320c88a636f4755df98c009c55a7cabc7e79c04f615b1a8fe37ec71a5e45b
7
+ data.tar.gz: 53e6a195fa84207d70e0cf4d23d258cae2c82c52d5e614f48c925b75b398d3d9630a0e90e19290efe0dcc7952ec56495ff35efec5d2ea7d51f2cd2dcabb9baef
@@ -6,7 +6,10 @@ jobs:
6
6
  strategy:
7
7
  fail-fast: false
8
8
  matrix:
9
- ruby: [head, 3.3, 3.2, 3.1, 3.0, 2.7]
9
+ experimental: [false]
10
+ ruby: [3.3, 3.2, 3.1, 3.0]
11
+ include:
12
+ - { ruby: head, experimental: true }
10
13
  steps:
11
14
  - uses: actions/checkout@v3
12
15
  - name: Set up Ruby
data/.gitignore CHANGED
@@ -6,3 +6,4 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+ /data/
data/Gemfile.lock CHANGED
@@ -1,14 +1,61 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- deadfire (0.4.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
- builder (3.2.4)
11
- minitest (5.14.3)
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.2.22
125
+ 2.6.1
data/README.md CHANGED
@@ -79,34 +79,9 @@ 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
- 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.
84
+ When Deadfire encounters an error, such as a missing mixin or other issues, it does not 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.
110
85
 
111
86
  By adopting this fault-tolerant approach, Deadfire aims to provide more flexibility and resilience when dealing with CSS code that may contain errors or inconsistencies. It allows you to gather information about the encountered issues and take appropriate actions based on the reported errors.
112
87
 
@@ -126,41 +101,36 @@ Or install it yourself as:
126
101
 
127
102
  `> gem install deadfire`
128
103
 
129
- ## Deadfire + Ruby on Rails
104
+ ## Ruby on Rails
130
105
 
131
- After adding Deadfire gem to your rails application, open the file `config/initializers/assets.rb` or create a new initializer `config/initializers/deadfire.rb`.
106
+ Deadfire aims to work alongside the new asset pipeline, Propshaft.
132
107
 
133
- ### Propshaft
108
+ With the gem included in your app's Gemfile, by default all your css files will be pre-processed.
134
109
 
135
- To setup Propshaft to use Deadfire as a preprocessor:
110
+ For more control over the files you want to pre-process;
111
+
112
+ `Deadfire.configuration.root_path` - change the root path where files are processed e.g. tailwind is bundled into `app/assets/builds/tailwind.css`
113
+ which means the root_path will need updating, whereas the default deadfire root_path is `app/assetss/stylesheets`.
136
114
 
137
115
  ```ruby
138
116
  # config/initializers/assets.rb
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]
117
+ Deadfire.configuration.root_path = Rails.root.join("app/assets").to_s
146
118
  ```
147
- ### Sprockets
148
119
 
149
- To setup Sprocket to use Deadfire as a preprocessor:
120
+ `Deadfire.configuration.preprocess` - configure exactly which files you want to pre-process, which caches all the utility classes declared
121
+ so they are available using `@apply` in your stylesheets.
150
122
 
151
123
  ```ruby
152
124
  # 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)
125
+ Deadfire.configuration.preprocess("builds/tailwind.css")
126
+ ```
127
+
128
+ To preprocess a file for a specific path like admin e.g. /admin/users, use the path keyword;
129
+
130
+ ```ruby
131
+ Deadfire.configuration.preprocess("builds/tailwind.css", path: "admin")
161
132
  ```
162
133
 
163
- Your css file should now be run through Deadfire.
164
134
  ## Development
165
135
 
166
136
  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,15 @@
1
1
  ## Changelog
2
- ### 0.5.0 (current)
2
+ ### 0.7.0 (current)
3
+
4
+ ### 0.6.0 (15 Jan 2025)
5
+ - Drop config.deadfire.* instead the Deadfire.configuration is preferred for configuring deadfire.
6
+
7
+ ### 0.5.0 (12 Dec 2024)
8
+ - Drop ruby 2.7
9
+ - Add a railties to make it real simple to pre-process every file for a simple setup
10
+ - Added the asset registry to make it easier to control how or which file is used as a mixin
11
+ - Excluded files are no longer pro-processed
12
+ - Make rails + propshaft dependencies
3
13
 
4
14
  ### 0.4.0 (18 May 2024)
5
15
  - Fix parsing comments that have 2 stars e.g. /**
@@ -15,6 +25,7 @@
15
25
  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
26
 
17
27
  - Simplify the configuration by having one option called compressed instead of keep_newlines and keep_comments.
28
+ - Add the ability to exclude files from being pre-processed via the `config.deadfire.excluded_files` option.
18
29
 
19
30
  ### 0.3.0 (15 November 2023)
20
31
 
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(">= 2.7")
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
@@ -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
- # something
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
@@ -1,4 +1,4 @@
1
- # Frozen_string_literal: true
1
+ # frozen_string_literal: true
2
2
  require "stringio"
3
3
 
4
4
  module Deadfire
@@ -1,4 +1,4 @@
1
- # Frozen_string_literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Deadfire
4
4
  class ApplyNode
@@ -78,10 +78,6 @@ module Deadfire
78
78
  check(:at_rule)
79
79
  end
80
80
 
81
- def matches_nested_rule?
82
- match?(:ampersand)
83
- end
84
-
85
81
  def parse_block
86
82
  block = BlockNode.new
87
83
  block << previous
@@ -13,7 +13,7 @@ module Deadfire
13
13
  visitor.visit_stylesheet_node(self)
14
14
  end
15
15
 
16
- def << (node)
16
+ def <<(node)
17
17
  @statements << node
18
18
  end
19
19
  end
@@ -1,12 +1,10 @@
1
- # Frozen_string_literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Deadfire
4
4
  class Interpreter # :nodoc:
5
- singleton_class.attr_accessor :cached_apply_rules
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 Interpreter.cached_apply_rules[node.selector.selector]
31
- Interpreter.cached_apply_rules[node.selector.selector] = node.block if node.selector.cacheable?
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 Interpreter.cached_apply_rules[mixin_name]
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,35 @@
1
+ # frozen_string_literal: true
2
+ require "rails"
3
+ require "propshaft"
4
+
5
+ module Deadfire
6
+ class Railties < ::Rails::Railtie
7
+ initializer :deadfire do |app|
8
+ Deadfire.configure do |deadfire_config|
9
+ deadfire_config.root_path = Rails.root.join("app/assets/stylesheets").to_s unless deadfire_config.root_path.present?
10
+
11
+ deadfire_config.excluded_files = []
12
+ deadfire_config.compressed = config.assets.compressed
13
+ deadfire_config.logger = config.assets.logger || Rails.logger
14
+ end
15
+
16
+ class DeadfireCompiler < ::Propshaft::Compiler
17
+ def compile(logical_path, input)
18
+ path = logical_path.path.to_s
19
+
20
+ return input if Deadfire.config.excluded_files.include?(path)
21
+
22
+ # by default, all files in the will be preprocessed
23
+ if Deadfire.config.asset_registry.settings.empty?
24
+ all_files = Dir.glob("#{Deadfire.config.root_path}/**/*.css")
25
+ Deadfire.config.preprocess(*all_files)
26
+ end
27
+
28
+ Deadfire.parse(input, filename: logical_path.logical_path.to_s)
29
+ end
30
+ end
31
+
32
+ config.assets.compilers << ["text/css", DeadfireCompiler]
33
+ end
34
+ end
35
+ 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,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Deadfire
4
- VERSION = "0.4.0"
4
+ VERSION = "0.6.0"
5
5
  end
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,16 +1,72 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deadfire
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Haroon Ahmed
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-05-18 00:00:00.000000000 Z
12
- dependencies: []
13
- description:
11
+ date: 2025-01-15 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
69
+ description:
14
70
  email:
15
71
  - haroon.ahmed25@gmail.com
16
72
  executables: []
@@ -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
@@ -67,7 +128,7 @@ metadata:
67
128
  homepage_uri: https://github.com/hahmed/deadfire
68
129
  source_code_uri: https://github.com/hahmed/deadfire
69
130
  changelog_uri: https://github.com/hahmed/deadfire/changelog.md
70
- post_install_message:
131
+ post_install_message:
71
132
  rdoc_options: []
72
133
  require_paths:
73
134
  - lib
@@ -75,15 +136,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
75
136
  requirements:
76
137
  - - ">="
77
138
  - !ruby/object:Gem::Version
78
- version: '2.7'
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.6
86
- signing_key:
146
+ rubygems_version: 3.0.3.1
147
+ signing_key:
87
148
  specification_version: 4
88
149
  summary: Deadfire - lightweight css preprocessor
89
150
  test_files: []