cataract 0.6.0 → 0.6.1
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/test.yml +1 -1
- data/.rubocop.yml +8 -1
- data/BENCHMARKS.md +65 -51
- data/CHANGELOG.md +5 -0
- data/README.md +1 -1
- data/cataract.gemspec +1 -1
- data/ext/cataract/cataract.c +20 -0
- data/lib/cataract/pure/flatten.rb +29 -2
- data/lib/cataract/version.rb +1 -1
- data/lib/cataract.rb +2 -2
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9e71b572a92ec74936764b374fa8846d340715a04e08f870ace3212037e4fdc5
|
|
4
|
+
data.tar.gz: 0bf71b6b6bed0ddbcecf8041daa6fdd25cead81ff136243378389fe6fa9954a7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7e91e3991a7ed47e542ba6bece13da4aaf990259848f3eb3f1505747b808847df1c738c956687f6349898cf7584e3d510775c55100ba26e726dbec1b11a2d3d7
|
|
7
|
+
data.tar.gz: cbdadf47b0853006532a37be7d08418edfdb90398a4373e84d038f833ef3e9f2722997ce8bb097e2a757a3f0cdb3c47082347e68252e3d233910e7ce0c4b4a90
|
data/.github/workflows/test.yml
CHANGED
data/.rubocop.yml
CHANGED
|
@@ -8,7 +8,7 @@ plugins:
|
|
|
8
8
|
- rubocop-minitest
|
|
9
9
|
|
|
10
10
|
AllCops:
|
|
11
|
-
TargetRubyVersion: 3.
|
|
11
|
+
TargetRubyVersion: 3.3
|
|
12
12
|
NewCops: enable
|
|
13
13
|
SuggestExtensions: false
|
|
14
14
|
Exclude:
|
|
@@ -178,5 +178,12 @@ Cataract/BanAssertIncludes:
|
|
|
178
178
|
- 'test/color/**/*.rb'
|
|
179
179
|
- 'test/test_benchmark_doc_generator.rb'
|
|
180
180
|
- 'test/test_speedup_calculator.rb'
|
|
181
|
+
# Benchmark harness tests assert on generated markdown and on the wording
|
|
182
|
+
# of mismatch errors, not on parsed CSS.
|
|
183
|
+
- 'test/test_ruby_mode.rb'
|
|
184
|
+
- 'test/test_backend.rb'
|
|
185
|
+
- 'test/test_benchmark_implementation.rb'
|
|
186
|
+
- 'test/test_result_table.rb'
|
|
187
|
+
- 'test/test_benchmark_plumbing.rb'
|
|
181
188
|
- 'test/test_parse_errors.rb' # Parse error tests check error messages with assert_match
|
|
182
189
|
- 'test/support/**/*' # Support files define assert_contains which uses assert_includes internally
|
data/BENCHMARKS.md
CHANGED
|
@@ -4,51 +4,54 @@
|
|
|
4
4
|
|
|
5
5
|
# Performance Benchmarks
|
|
6
6
|
|
|
7
|
-
Performance comparison between Cataract's C extension and pure Ruby implementations.
|
|
7
|
+
Performance comparison between Cataract's C extension and pure Ruby implementations, including pure Ruby under the interpreter, YJIT, and ZJIT.
|
|
8
8
|
|
|
9
9
|
## Test Environment
|
|
10
10
|
|
|
11
|
-
- **Ruby**: ruby 4.0.
|
|
11
|
+
- **Ruby**: ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +ZJIT +PRISM [arm64-darwin25]
|
|
12
12
|
- **CPU**: Apple M1 Pro
|
|
13
13
|
- **Memory**: 32GB
|
|
14
14
|
- **OS**: macOS 26.3.1
|
|
15
|
-
- **Generated**: 2026-07-
|
|
15
|
+
- **Generated**: 2026-07-30T21:02:54-05:00
|
|
16
16
|
|
|
17
17
|
## CSS Parsing
|
|
18
18
|
|
|
19
19
|
Time to parse CSS into internal data structures
|
|
20
20
|
|
|
21
|
-
| Test Case | Native | Pure (no
|
|
22
|
-
|
|
23
|
-
| Small CSS (64 lines, 1.0KB) |
|
|
24
|
-
| Medium CSS with @media (139 lines, 1.6KB) |
|
|
25
|
-
| Selector lists (3500 lines, 62.5KB, 500 lists) |
|
|
21
|
+
| Test Case | Native | Pure (no JIT) | Pure (YJIT) | Pure (ZJIT) |
|
|
22
|
+
| --------- | ------ | ------------- | ----------- | ----------- |
|
|
23
|
+
| Small CSS (64 lines, 1.0KB) | 31.29K i/s | 3.3K i/s | 13.76K i/s | 7.53K i/s |
|
|
24
|
+
| Medium CSS with @media (139 lines, 1.6KB) | 28.46K i/s | 2.06K i/s | 8.88K i/s | 4.78K i/s |
|
|
25
|
+
| Selector lists (3500 lines, 62.5KB, 500 lists) | 369.3 i/s | 57.5 i/s | 216.9 i/s | 125.5 i/s |
|
|
26
26
|
|
|
27
27
|
### Speedups
|
|
28
28
|
|
|
29
29
|
| Comparison | Speedup |
|
|
30
30
|
|------------|---------|
|
|
31
|
-
| Native vs Pure (no
|
|
32
|
-
| Native vs Pure (YJIT) |
|
|
31
|
+
| Native vs Pure (no JIT) | 11.42x faster (avg) |
|
|
32
|
+
| Native vs Pure (YJIT) | 2.74x faster (avg) |
|
|
33
|
+
| Native vs Pure (ZJIT) | 4.92x faster (avg) |
|
|
33
34
|
| YJIT impact on Pure Ruby | 4.15x faster (avg) |
|
|
35
|
+
| ZJIT impact on Pure Ruby | 2.31x faster (avg) |
|
|
36
|
+
| ZJIT vs YJIT | 1.79x slower (avg) |
|
|
34
37
|
|
|
35
38
|
### Parse Error Checking Overhead
|
|
36
39
|
|
|
37
40
|
Parse error detection can be enabled with `raise_parse_errors: true`. This compares performance impact:
|
|
38
41
|
|
|
39
|
-
| Configuration | Native | Pure (no
|
|
40
|
-
|
|
41
|
-
| Medium CSS (139 lines) - no error checking |
|
|
42
|
-
| Medium CSS (139 lines) - with error checking |
|
|
42
|
+
| Configuration | Native | Pure (no JIT) | Pure (YJIT) | Pure (ZJIT) |
|
|
43
|
+
| ------------- | ------ | ------------- | ----------- | ----------- |
|
|
44
|
+
| Medium CSS (139 lines) - no error checking | 27.71K i/s | 2.09K i/s | 8.62K i/s | 4.84K i/s |
|
|
45
|
+
| Medium CSS (139 lines) - with error checking | 27.36K i/s | 1.92K i/s | 7.97K i/s | 4.55K i/s |
|
|
43
46
|
|
|
44
47
|
**Overhead Analysis:**
|
|
45
48
|
|
|
46
|
-
|
|
47
49
|
| Implementation | Overhead |
|
|
48
50
|
|----------------|----------|
|
|
49
|
-
| Native | 1.
|
|
50
|
-
| Pure (no
|
|
51
|
-
| Pure (YJIT) |
|
|
51
|
+
| Native | 1.3% slower |
|
|
52
|
+
| Pure (no JIT) | 9.0% slower |
|
|
53
|
+
| Pure (YJIT) | 8.2% slower |
|
|
54
|
+
| Pure (ZJIT) | 6.3% slower |
|
|
52
55
|
|
|
53
56
|
---
|
|
54
57
|
|
|
@@ -56,21 +59,24 @@ Parse error detection can be enabled with `raise_parse_errors: true`. This compa
|
|
|
56
59
|
|
|
57
60
|
Time to convert parsed CSS back to string format
|
|
58
61
|
|
|
59
|
-
| Test Case | Native | Pure (no
|
|
60
|
-
|
|
61
|
-
| to_s (Bootstrap - 191KB) |
|
|
62
|
-
| to_s (Compact utilities - 2.9KB) |
|
|
63
|
-
| to_formatted_s (Nested CSS - 1.3KB) |
|
|
64
|
-
| to_s with selector_lists (3.4KB) |
|
|
65
|
-
| Media filtering (Bootstrap print only) | 1.
|
|
62
|
+
| Test Case | Native | Pure (no JIT) | Pure (YJIT) | Pure (ZJIT) |
|
|
63
|
+
| --------- | ------ | ------------- | ----------- | ----------- |
|
|
64
|
+
| to_s (Bootstrap - 191KB) | 984.2 i/s | 301.6 i/s | 484.0 i/s | 338.1 i/s |
|
|
65
|
+
| to_s (Compact utilities - 2.9KB) | 50.4K i/s | 11.02K i/s | 18.96K i/s | 10.9K i/s |
|
|
66
|
+
| to_formatted_s (Nested CSS - 1.3KB) | 151.49K i/s | 54.68K i/s | 87.22K i/s | 64.4K i/s |
|
|
67
|
+
| to_s with selector_lists (3.4KB) | 14.99K i/s | 6.72K i/s | 10.69K i/s | 7.87K i/s |
|
|
68
|
+
| Media filtering (Bootstrap print only) | 1.1K i/s | 464.3 i/s | 694.0 i/s | 528.0 i/s |
|
|
66
69
|
|
|
67
70
|
### Speedups
|
|
68
71
|
|
|
69
72
|
| Comparison | Speedup |
|
|
70
73
|
|------------|---------|
|
|
71
|
-
| Native vs Pure (no
|
|
72
|
-
| Native vs Pure (YJIT) | 1.
|
|
73
|
-
|
|
|
74
|
+
| Native vs Pure (no JIT) | 3.04x faster (avg) |
|
|
75
|
+
| Native vs Pure (YJIT) | 1.88x faster (avg) |
|
|
76
|
+
| Native vs Pure (ZJIT) | 2.77x faster (avg) |
|
|
77
|
+
| YJIT impact on Pure Ruby | 1.6x faster (avg) |
|
|
78
|
+
| ZJIT impact on Pure Ruby | 1.12x faster (avg) |
|
|
79
|
+
| ZJIT vs YJIT | 1.43x slower (avg) |
|
|
74
80
|
|
|
75
81
|
---
|
|
76
82
|
|
|
@@ -78,22 +84,25 @@ Time to convert parsed CSS back to string format
|
|
|
78
84
|
|
|
79
85
|
Time to calculate CSS selector specificity values
|
|
80
86
|
|
|
81
|
-
| Test Case | Native | Pure (no
|
|
82
|
-
|
|
83
|
-
| Simple Selectors | 1.
|
|
84
|
-
| Compound Selectors |
|
|
85
|
-
| Combinators |
|
|
86
|
-
| Pseudo-classes & Pseudo-elements |
|
|
87
|
-
| :not() Pseudo-class (CSS3) |
|
|
88
|
-
| Complex Real-world Selectors |
|
|
87
|
+
| Test Case | Native | Pure (no JIT) | Pure (YJIT) | Pure (ZJIT) |
|
|
88
|
+
| --------- | ------ | ------------- | ----------- | ----------- |
|
|
89
|
+
| Simple Selectors | 1.02M i/s | 413.96K i/s | 1.43M i/s | 749.57K i/s |
|
|
90
|
+
| Compound Selectors | 997.92K i/s | 183.13K i/s | 498.8K i/s | 404.43K i/s |
|
|
91
|
+
| Combinators | 757.46K i/s | 136.54K i/s | 267.01K i/s | 260.74K i/s |
|
|
92
|
+
| Pseudo-classes & Pseudo-elements | 757.92K i/s | 113.58K i/s | 224.99K i/s | 209.63K i/s |
|
|
93
|
+
| :not() Pseudo-class (CSS3) | 883.15K i/s | 110.53K i/s | 237.8K i/s | 189.57K i/s |
|
|
94
|
+
| Complex Real-world Selectors | 913.36K i/s | 55.32K i/s | 120.83K i/s | 116.13K i/s |
|
|
89
95
|
|
|
90
96
|
### Speedups
|
|
91
97
|
|
|
92
98
|
| Comparison | Speedup |
|
|
93
99
|
|------------|---------|
|
|
94
|
-
| Native vs Pure (no
|
|
95
|
-
| Native vs Pure (YJIT) |
|
|
96
|
-
|
|
|
100
|
+
| Native vs Pure (no JIT) | 7.44x faster (avg) |
|
|
101
|
+
| Native vs Pure (YJIT) | 3.37x faster (avg) |
|
|
102
|
+
| Native vs Pure (ZJIT) | 3.81x faster (avg) |
|
|
103
|
+
| YJIT impact on Pure Ruby | 2.41x faster (avg) |
|
|
104
|
+
| ZJIT impact on Pure Ruby | 1.93x faster (avg) |
|
|
105
|
+
| ZJIT vs YJIT | 1.2x slower (avg) |
|
|
97
106
|
|
|
98
107
|
---
|
|
99
108
|
|
|
@@ -101,22 +110,25 @@ Time to calculate CSS selector specificity values
|
|
|
101
110
|
|
|
102
111
|
Time to flatten multiple CSS rule sets with same selector
|
|
103
112
|
|
|
104
|
-
| Test Case | Native | Pure (no
|
|
105
|
-
|
|
106
|
-
| No shorthand properties (large) |
|
|
107
|
-
| Simple properties |
|
|
108
|
-
| Cascade with specificity |
|
|
109
|
-
| Important declarations |
|
|
110
|
-
| Shorthand expansion |
|
|
111
|
-
| Complex flattening |
|
|
113
|
+
| Test Case | Native | Pure (no JIT) | Pure (YJIT) | Pure (ZJIT) |
|
|
114
|
+
| --------- | ------ | ------------- | ----------- | ----------- |
|
|
115
|
+
| No shorthand properties (large) | 13.28K i/s | 2.85K i/s | 5.37K i/s | 3.44K i/s |
|
|
116
|
+
| Simple properties | 138.9K i/s | 54.39K i/s | 84.42K i/s | 65.18K i/s |
|
|
117
|
+
| Cascade with specificity | 168.14K i/s | 52.88K i/s | 86.97K i/s | 65.61K i/s |
|
|
118
|
+
| Important declarations | 167.4K i/s | 53.61K i/s | 87.29K i/s | 65.6K i/s |
|
|
119
|
+
| Shorthand expansion | 132.57K i/s | 46.27K i/s | 78.43K i/s | 58.86K i/s |
|
|
120
|
+
| Complex flattening | 32.18K i/s | 11.32K i/s | 17.41K i/s | 14.11K i/s |
|
|
112
121
|
|
|
113
122
|
### Speedups
|
|
114
123
|
|
|
115
124
|
| Comparison | Speedup |
|
|
116
125
|
|------------|---------|
|
|
117
|
-
| Native vs Pure (no
|
|
118
|
-
| Native vs Pure (YJIT) | 1.
|
|
119
|
-
|
|
|
126
|
+
| Native vs Pure (no JIT) | 3.2x faster (avg) |
|
|
127
|
+
| Native vs Pure (YJIT) | 1.92x faster (avg) |
|
|
128
|
+
| Native vs Pure (ZJIT) | 2.61x faster (avg) |
|
|
129
|
+
| YJIT impact on Pure Ruby | 1.66x faster (avg) |
|
|
130
|
+
| ZJIT impact on Pure Ruby | 1.23x faster (avg) |
|
|
131
|
+
| ZJIT vs YJIT | 1.33x slower (avg) |
|
|
120
132
|
|
|
121
133
|
---
|
|
122
134
|
|
|
@@ -140,4 +152,6 @@ rake benchmark:generate_docs
|
|
|
140
152
|
|
|
141
153
|
- Benchmarks use benchmark-ips with 1-2s warmup and 2-5s measurement periods
|
|
142
154
|
- Measurements show median iterations per second (i/s)
|
|
143
|
-
-
|
|
155
|
+
- Each backend/JIT combination is measured in its own subprocess - Ruby allows only one JIT active per process, and each subprocess verifies the JIT it was launched with is the one actually running before measuring anything
|
|
156
|
+
- The C extension is measured without a JIT: its speed doesn't depend on a JIT compiling Cataract's own code
|
|
157
|
+
- ZJIT is an experimental, method-based JIT introduced in Ruby 4.0. It is not enabled by default and is not yet expected to outperform YJIT; it's included here to track its progress release over release
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
## [0.6.1] - 2026-07-31
|
|
2
|
+
|
|
3
|
+
- Fix: parsing after `Process.warmup` or `GC.compact` could raise `TypeError: uninitialized class`, or crash the process with a segfault, in the C extension. Cataract's struct classes (`Rule`, `Declaration`, `AtRule`, `Stylesheet`, `ImportStatement`, `MediaQuery`, `ConditionalGroup`) and its exception classes were cached in C globals that were never registered with the GC; compaction relocates objects, leaving those cached pointers dangling, and every subsequent parse then built its structs from a stale address. Nothing unusual was needed to hit this - `Process.warmup` compacts the heap and is commonly called once after boot. Present since the C extension shipped; the pure Ruby backend was unaffected.
|
|
4
|
+
- Fix: flattening a layered (comma-separated) `background` kept only the last layer in the pure Ruby backend - `background: url(a.png), url(b.png)` flattened to `background: url(b.png)`, discarding the rest with no error. Gradients were also misclassified, since only `url(...)` counted as a background image: `background: linear-gradient(#fff, #000), radial-gradient(circle, red, blue)` came back reordered and malformed, as `radial-gradient(circle, red, blue) linear-gradient(#fff, #000),`. The C extension was unaffected.
|
|
5
|
+
|
|
1
6
|
## [0.6.0] - 2026-07-30
|
|
2
7
|
|
|
3
8
|
- Security: `ImportResolver.validate_url`'s `dangerous_path_prefixes` check now canonicalizes the `file://` path (via `File.expand_path`) before comparing against blocked prefixes, instead of comparing the raw path string. Previously a path containing `..` that didn't literally start with a blocked prefix (e.g. `file:///var/../etc/passwd`) bypassed the check entirely, even though the file was actually read from the resolved location. Reachable via `Stylesheet#load_uri`/`#load_file` (file scheme allowed by default) and via `@import` when a caller opts `file` into `allowed_schemes`.
|
data/README.md
CHANGED
data/cataract.gemspec
CHANGED
|
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
|
12
12
|
spec.description = 'A performant CSS parser with C extensions for accurate parsing of complex CSS structures including media queries, nested selectors, and CSS Color Level 4'
|
|
13
13
|
spec.homepage = 'https://github.com/jamescook/cataract'
|
|
14
14
|
spec.license = 'MIT'
|
|
15
|
-
spec.required_ruby_version = Gem::Requirement.new('>= 3.
|
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 3.3.0')
|
|
16
16
|
|
|
17
17
|
spec.metadata['homepage_uri'] = spec.homepage
|
|
18
18
|
spec.metadata['source_code_uri'] = spec.homepage
|
data/ext/cataract/cataract.c
CHANGED
|
@@ -1325,6 +1325,26 @@ void Init_native_extension(void) {
|
|
|
1325
1325
|
// with its own #to_s, not something this backend attaches methods to.
|
|
1326
1326
|
cStylesheet = rb_define_class_under(mCataract, "Stylesheet", rb_cObject);
|
|
1327
1327
|
|
|
1328
|
+
// Register the cached class and exception VALUEs with the GC.
|
|
1329
|
+
//
|
|
1330
|
+
// Keeping them alive isn't the concern - the constants above do that. GC
|
|
1331
|
+
// compaction is: it moves objects, and an unregistered C global is left
|
|
1332
|
+
// pointing at the old address. rb_struct_new(cRule, ...) on a stale
|
|
1333
|
+
// pointer then fails with "uninitialized class", so any caller that
|
|
1334
|
+
// compacts the heap - Process.warmup and GC.compact both do - breaks
|
|
1335
|
+
// every subsequent parse.
|
|
1336
|
+
rb_global_variable(&cRule);
|
|
1337
|
+
rb_global_variable(&cDeclaration);
|
|
1338
|
+
rb_global_variable(&cAtRule);
|
|
1339
|
+
rb_global_variable(&cStylesheet);
|
|
1340
|
+
rb_global_variable(&cImportStatement);
|
|
1341
|
+
rb_global_variable(&cMediaQuery);
|
|
1342
|
+
rb_global_variable(&cConditionalGroup);
|
|
1343
|
+
rb_global_variable(&eCataractError);
|
|
1344
|
+
rb_global_variable(&eDepthError);
|
|
1345
|
+
rb_global_variable(&eSizeError);
|
|
1346
|
+
rb_global_variable(&eParseError);
|
|
1347
|
+
|
|
1328
1348
|
// Every native-specific entry point lives under Cataract::Backends::Native,
|
|
1329
1349
|
// never directly on Cataract itself, so the pure Ruby backend can be loaded
|
|
1330
1350
|
// in the same process without either backend clobbering the other's methods.
|
|
@@ -166,6 +166,13 @@ module Cataract
|
|
|
166
166
|
BACKGROUND_ATTACHMENT_KEYWORDS = %w[scroll fixed local].freeze
|
|
167
167
|
BACKGROUND_POSITION_KEYWORDS = %w[left right center top bottom].freeze
|
|
168
168
|
|
|
169
|
+
# Gradient functions that set background-image. Mirrors the set the C
|
|
170
|
+
# extension recognizes, so both backends classify the same tokens.
|
|
171
|
+
BACKGROUND_IMAGE_FUNCTIONS = %w[
|
|
172
|
+
linear-gradient( radial-gradient( conic-gradient(
|
|
173
|
+
repeating-linear-gradient( repeating-radial-gradient(
|
|
174
|
+
].freeze
|
|
175
|
+
|
|
169
176
|
# Merge stylesheet according to CSS cascade rules
|
|
170
177
|
#
|
|
171
178
|
# @param stylesheet [Stylesheet] Stylesheet to merge
|
|
@@ -830,8 +837,17 @@ module Cataract
|
|
|
830
837
|
position = nil
|
|
831
838
|
|
|
832
839
|
parts.each do |part|
|
|
833
|
-
if
|
|
834
|
-
|
|
840
|
+
if background_image?(part)
|
|
841
|
+
# Layered backgrounds are comma-separated and arrive as one part
|
|
842
|
+
# per layer. Assigning would keep only the last and silently drop
|
|
843
|
+
# the rest, so append instead. split_on_whitespace builds each
|
|
844
|
+
# part fresh, so appending mutates a string we own - no
|
|
845
|
+
# allocation, and nothing else references it.
|
|
846
|
+
if image
|
|
847
|
+
image << ' ' << part
|
|
848
|
+
else
|
|
849
|
+
image = part
|
|
850
|
+
end
|
|
835
851
|
elsif BACKGROUND_REPEAT_KEYWORDS.include?(part)
|
|
836
852
|
repeat = part
|
|
837
853
|
elsif BACKGROUND_ATTACHMENT_KEYWORDS.include?(part)
|
|
@@ -858,6 +874,17 @@ module Cataract
|
|
|
858
874
|
result
|
|
859
875
|
end
|
|
860
876
|
|
|
877
|
+
# Value tokens that set background-image: a url, any of the gradient
|
|
878
|
+
# functions, or the `none` keyword. Gradients count as images; left out
|
|
879
|
+
# they fall through to the position and color branches and end up
|
|
880
|
+
# filed as neither.
|
|
881
|
+
def background_image?(value)
|
|
882
|
+
return true if value == 'none'
|
|
883
|
+
return true if starts_with_url?(value)
|
|
884
|
+
|
|
885
|
+
BACKGROUND_IMAGE_FUNCTIONS.any? { |function| value.start_with?(function) }
|
|
886
|
+
end
|
|
887
|
+
|
|
861
888
|
# Check if value starts with 'url('
|
|
862
889
|
def starts_with_url?(value)
|
|
863
890
|
return false if value.bytesize < 4
|
data/lib/cataract/version.rb
CHANGED
data/lib/cataract.rb
CHANGED
|
@@ -86,8 +86,8 @@ module Cataract
|
|
|
86
86
|
#
|
|
87
87
|
# @see Stylesheet#parse
|
|
88
88
|
# @see Stylesheet.parse
|
|
89
|
-
def parse_css(css, **
|
|
90
|
-
Stylesheet.parse(css, **
|
|
89
|
+
def parse_css(css, **)
|
|
90
|
+
Stylesheet.parse(css, **)
|
|
91
91
|
end
|
|
92
92
|
|
|
93
93
|
# Flatten CSS rules according to CSS cascade rules.
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cataract
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.6.
|
|
4
|
+
version: 0.6.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- James Cook
|
|
@@ -121,14 +121,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
121
121
|
requirements:
|
|
122
122
|
- - ">="
|
|
123
123
|
- !ruby/object:Gem::Version
|
|
124
|
-
version: 3.
|
|
124
|
+
version: 3.3.0
|
|
125
125
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
126
126
|
requirements:
|
|
127
127
|
- - ">="
|
|
128
128
|
- !ruby/object:Gem::Version
|
|
129
129
|
version: '0'
|
|
130
130
|
requirements: []
|
|
131
|
-
rubygems_version: 4.0.
|
|
131
|
+
rubygems_version: 4.0.16
|
|
132
132
|
specification_version: 4
|
|
133
133
|
summary: High-performance CSS parser with C extensions
|
|
134
134
|
test_files: []
|