lightningcss 0.1.1-x86_64-linux-gnu → 0.2.0-x86_64-linux-gnu
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/README.md +14 -0
- data/ext/lightningcss/extconf.rb +14 -3
- data/ext/lightningcss/include/lightningcss.h +9 -0
- data/ext/lightningcss/lightningcss.c +40 -17
- data/lib/lightningcss/3.2/lightningcss.so +0 -0
- data/lib/lightningcss/3.3/lightningcss.so +0 -0
- data/lib/lightningcss/3.4/lightningcss.so +0 -0
- data/lib/lightningcss/4.0/lightningcss.so +0 -0
- data/lib/lightningcss/options.rb +13 -5
- data/lib/lightningcss/transformer.rb +1 -1
- data/lib/lightningcss/version.rb +1 -1
- data/lib/lightningcss.rb +5 -3
- data/rust/Cargo.lock +1 -1
- data/rust/Cargo.toml +1 -1
- data/rust/build.rs +10 -0
- data/rust/cbindgen.toml +1 -0
- data/rust/src/lib.rs +103 -37
- data/rust/src/scope.rs +4 -2
- data/sig/lightningcss/options.rbs +6 -4
- data/sig/lightningcss/transformer.rbs +2 -2
- data/sig/lightningcss.rbs +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 60b9bf5ff6f7226f2deb903411280800ba1bb5e4d270fd32cc7c28ae23f82e54
|
|
4
|
+
data.tar.gz: 3199cdeaca6c86296bd0d05c7350d450694e00c71d26a72a9cfe70acbc71e249
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 562c17a0bedbc7c0c971b20df9da6352b108b1607321f9ada7021c6d696515e8a371003a78ed90b4bd69fd60c01b6027016414f834cb5d5e27206a5e6b4c57e3
|
|
7
|
+
data.tar.gz: e0b92d822c7244d589aa00c021338c27455cbaf845494eeac942a01a29e8c346b47141d7a87c752337d2a52152a51a5332fbcf1277deabc7873492b4da211e3f
|
data/README.md
CHANGED
|
@@ -62,6 +62,20 @@ LightningCSS.transform(".a { color: lab(50% 40 59) }", targets: { chrome: 80 },
|
|
|
62
62
|
LightningCSS.bundle("app/assets/stylesheets/application.css", minify: true).code
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
+
A bundle names every file it reads by the path it read it from, so it takes no `filename` and says so when given one.
|
|
66
|
+
|
|
67
|
+
It answers the same result a transform does. Every warning names the file it came from, and compiling as a CSS module renames the names in every file it read while exporting the ones the entry wrote. A file it imported is hashed on its own, so its names never collide with the entry's.
|
|
68
|
+
|
|
69
|
+
```ruby
|
|
70
|
+
result = LightningCSS.bundle("app/assets/stylesheets/application.css", css_modules: true)
|
|
71
|
+
|
|
72
|
+
result.exports
|
|
73
|
+
#=> {"application" => "_8Z4fiW_application"}
|
|
74
|
+
|
|
75
|
+
result.warnings.first
|
|
76
|
+
#=> "'deep' is not recognized as a valid pseudo-class. ... at app/assets/stylesheets/layout.css:0:9"
|
|
77
|
+
```
|
|
78
|
+
|
|
65
79
|
#### CSS modules
|
|
66
80
|
|
|
67
81
|
Compiling as a CSS module renames every class, id, `@keyframes`, and custom identifier, and reports what each name became.
|
data/ext/lightningcss/extconf.rb
CHANGED
|
@@ -65,12 +65,12 @@ if target_platform
|
|
|
65
65
|
|
|
66
66
|
system("rustup target add #{target_platform}") || warn("lightningcss: Failed to add Rust target #{target_platform}")
|
|
67
67
|
|
|
68
|
-
cargo_args = "--release --target #{target_platform}"
|
|
68
|
+
cargo_args = "--release --locked --target #{target_platform}"
|
|
69
69
|
lib_dir = File.join(target_dir, target_platform, "release")
|
|
70
70
|
else
|
|
71
71
|
puts "lightningcss: Compiling Rust library for native platform..."
|
|
72
72
|
|
|
73
|
-
cargo_args = "--release"
|
|
73
|
+
cargo_args = "--release --locked"
|
|
74
74
|
lib_dir = File.join(target_dir, "release")
|
|
75
75
|
end
|
|
76
76
|
|
|
@@ -84,7 +84,18 @@ end
|
|
|
84
84
|
|
|
85
85
|
static_lib = File.join(lib_dir, "liblightningcss_ffi.a")
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
developing = File.exist?(File.join(root_dir, ".git"))
|
|
88
|
+
|
|
89
|
+
if File.exist?(static_lib) && !developing
|
|
90
|
+
vendored = File.join(ext_dir, "liblightningcss_ffi.a")
|
|
91
|
+
|
|
92
|
+
FileUtils.cp(static_lib, vendored)
|
|
93
|
+
FileUtils.rm_rf(target_dir)
|
|
94
|
+
|
|
95
|
+
puts "lightningcss: Static library vendored at #{vendored}, Rust build directory removed"
|
|
96
|
+
|
|
97
|
+
$LDFLAGS << " #{vendored}"
|
|
98
|
+
elsif File.exist?(static_lib)
|
|
88
99
|
puts "lightningcss: Static library found at #{static_lib}"
|
|
89
100
|
|
|
90
101
|
$LDFLAGS << " #{static_lib}"
|
|
@@ -7,9 +7,18 @@
|
|
|
7
7
|
#ifndef LIGHTNINGCSS_H
|
|
8
8
|
#define LIGHTNINGCSS_H
|
|
9
9
|
|
|
10
|
+
typedef enum LightningCssErrorCode {
|
|
11
|
+
LIGHTNING_CSS_ERROR_CODE_NONE = 0,
|
|
12
|
+
LIGHTNING_CSS_ERROR_CODE_PARSE,
|
|
13
|
+
LIGHTNING_CSS_ERROR_CODE_OPTION,
|
|
14
|
+
LIGHTNING_CSS_ERROR_CODE_BUNDLE,
|
|
15
|
+
LIGHTNING_CSS_ERROR_CODE_INTERNAL,
|
|
16
|
+
} LightningCssErrorCode;
|
|
17
|
+
|
|
10
18
|
typedef struct LightningCssResult {
|
|
11
19
|
char *value;
|
|
12
20
|
char *error;
|
|
21
|
+
enum LightningCssErrorCode code;
|
|
13
22
|
} LightningCssResult;
|
|
14
23
|
|
|
15
24
|
struct LightningCssResult lightningcss_transform(const char *code, const char *options_json);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#include <ruby.h>
|
|
2
2
|
#include <ruby/encoding.h>
|
|
3
|
+
#include <ruby/thread.h>
|
|
3
4
|
#include "include/lightningcss.h"
|
|
4
5
|
|
|
5
6
|
static VALUE rb_mLightningCSS;
|
|
@@ -9,6 +10,15 @@ static VALUE rb_eParseError;
|
|
|
9
10
|
static VALUE rb_eOptionError;
|
|
10
11
|
static VALUE rb_eBundleError;
|
|
11
12
|
|
|
13
|
+
typedef struct LightningCssResult (*lightningcss_function)(const char *, const char *);
|
|
14
|
+
|
|
15
|
+
struct call_arguments {
|
|
16
|
+
lightningcss_function function;
|
|
17
|
+
const char *input;
|
|
18
|
+
const char *options;
|
|
19
|
+
struct LightningCssResult result;
|
|
20
|
+
};
|
|
21
|
+
|
|
12
22
|
static VALUE make_utf8_string(const char *cstring) {
|
|
13
23
|
return rb_enc_str_new_cstr(cstring, rb_utf8_encoding());
|
|
14
24
|
}
|
|
@@ -22,26 +32,19 @@ static VALUE take_utf8_string(char *cstring) {
|
|
|
22
32
|
return string;
|
|
23
33
|
}
|
|
24
34
|
|
|
25
|
-
static VALUE error_class_for(
|
|
26
|
-
|
|
27
|
-
return
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return rb_eBundleError;
|
|
35
|
+
static VALUE error_class_for(enum LightningCssErrorCode code) {
|
|
36
|
+
switch (code) {
|
|
37
|
+
case LIGHTNING_CSS_ERROR_CODE_PARSE: return rb_eParseError;
|
|
38
|
+
case LIGHTNING_CSS_ERROR_CODE_OPTION: return rb_eOptionError;
|
|
39
|
+
case LIGHTNING_CSS_ERROR_CODE_BUNDLE: return rb_eBundleError;
|
|
40
|
+
default: return rb_eError;
|
|
32
41
|
}
|
|
33
|
-
|
|
34
|
-
if (strstr(message, "Invalid scope selector") || strstr(message, "Scope selector")) {
|
|
35
|
-
return rb_eOptionError;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return rb_eParseError;
|
|
39
42
|
}
|
|
40
43
|
|
|
41
44
|
static VALUE unwrap(struct LightningCssResult result) {
|
|
42
45
|
if (result.error) {
|
|
43
46
|
VALUE message = make_utf8_string(result.error);
|
|
44
|
-
VALUE error_class = error_class_for(result.
|
|
47
|
+
VALUE error_class = error_class_for(result.code);
|
|
45
48
|
|
|
46
49
|
lightningcss_result_free(result);
|
|
47
50
|
|
|
@@ -61,22 +64,42 @@ static VALUE unwrap(struct LightningCssResult result) {
|
|
|
61
64
|
return value;
|
|
62
65
|
}
|
|
63
66
|
|
|
67
|
+
static void *without_gvl(void *data) {
|
|
68
|
+
struct call_arguments *arguments = (struct call_arguments *) data;
|
|
69
|
+
|
|
70
|
+
arguments->result = arguments->function(arguments->input, arguments->options);
|
|
71
|
+
|
|
72
|
+
return NULL;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
static VALUE call(lightningcss_function function, VALUE input, VALUE options) {
|
|
76
|
+
struct call_arguments arguments;
|
|
77
|
+
|
|
78
|
+
arguments.function = function;
|
|
79
|
+
arguments.input = StringValueCStr(input);
|
|
80
|
+
arguments.options = StringValueCStr(options);
|
|
81
|
+
|
|
82
|
+
rb_thread_call_without_gvl(without_gvl, &arguments, NULL, NULL);
|
|
83
|
+
|
|
84
|
+
return unwrap(arguments.result);
|
|
85
|
+
}
|
|
86
|
+
|
|
64
87
|
static VALUE rb_transform(VALUE self, VALUE code, VALUE options) {
|
|
65
88
|
(void) self;
|
|
66
89
|
|
|
67
|
-
return
|
|
90
|
+
return call(lightningcss_transform, code, options);
|
|
68
91
|
}
|
|
69
92
|
|
|
70
93
|
static VALUE rb_transform_style_attribute(VALUE self, VALUE code, VALUE options) {
|
|
71
94
|
(void) self;
|
|
72
95
|
|
|
73
|
-
return
|
|
96
|
+
return call(lightningcss_transform_style_attribute, code, options);
|
|
74
97
|
}
|
|
75
98
|
|
|
76
99
|
static VALUE rb_bundle(VALUE self, VALUE path, VALUE options) {
|
|
77
100
|
(void) self;
|
|
78
101
|
|
|
79
|
-
return
|
|
102
|
+
return call(lightningcss_bundle, path, options);
|
|
80
103
|
}
|
|
81
104
|
|
|
82
105
|
static VALUE rb_native_version(VALUE self) {
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/lib/lightningcss/options.rb
CHANGED
|
@@ -26,15 +26,23 @@ module LightningCSS
|
|
|
26
26
|
:targets
|
|
27
27
|
].freeze #: Array[Symbol]
|
|
28
28
|
|
|
29
|
+
BUNDLE = [
|
|
30
|
+
:minify,
|
|
31
|
+
:error_recovery,
|
|
32
|
+
:targets,
|
|
33
|
+
:css_modules,
|
|
34
|
+
:scope
|
|
35
|
+
].freeze #: Array[Symbol]
|
|
36
|
+
|
|
29
37
|
attr_reader :to_h #: Hash[Symbol, untyped]
|
|
30
38
|
|
|
31
|
-
#: (Hash[Symbol, untyped], ?
|
|
32
|
-
def self.serialize(options, allowed
|
|
33
|
-
new(
|
|
39
|
+
#: (Hash[Symbol, untyped], ?Array[Symbol], ?String) -> String
|
|
40
|
+
def self.serialize(options, allowed = KNOWN, subject = "a transform")
|
|
41
|
+
new(options, allowed, subject).to_json
|
|
34
42
|
end
|
|
35
43
|
|
|
36
|
-
#: (?
|
|
37
|
-
def initialize(allowed
|
|
44
|
+
#: (Hash[Symbol, untyped], ?Array[Symbol], ?String) -> void
|
|
45
|
+
def initialize(options, allowed = KNOWN, subject = "a transform")
|
|
38
46
|
given = options.transform_keys(&:to_sym)
|
|
39
47
|
|
|
40
48
|
validate!(given.keys, allowed, subject)
|
|
@@ -28,7 +28,7 @@ module LightningCSS
|
|
|
28
28
|
|
|
29
29
|
alias call transform
|
|
30
30
|
|
|
31
|
-
#: (String, ?
|
|
31
|
+
#: (String, ?minify: bool, ?error_recovery: bool, ?targets: browsers?, ?css_modules: css_modules?, ?scope: String?) -> LightningCSS::Result
|
|
32
32
|
def bundle(path, **overrides)
|
|
33
33
|
LightningCSS.bundle(path, **options, **overrides)
|
|
34
34
|
end
|
data/lib/lightningcss/version.rb
CHANGED
data/lib/lightningcss.rb
CHANGED
|
@@ -36,14 +36,16 @@ module LightningCSS
|
|
|
36
36
|
Result.from_json(Backend.transform(code.to_s, Options.serialize(options)))
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
-
#: (String, ?
|
|
39
|
+
#: (String, ?minify: bool, ?error_recovery: bool, ?targets: browsers?, ?css_modules: css_modules?, ?scope: String?) -> LightningCSS::Result
|
|
40
40
|
def self.bundle(path, **options)
|
|
41
|
-
|
|
41
|
+
serialized = Options.serialize(options, Options::BUNDLE, "a bundle")
|
|
42
|
+
|
|
43
|
+
Result.from_json(Backend.bundle(path.to_s, serialized))
|
|
42
44
|
end
|
|
43
45
|
|
|
44
46
|
#: (String, ?filename: String?, ?minify: bool, ?error_recovery: bool, ?targets: browsers?) -> LightningCSS::Result
|
|
45
47
|
def self.transform_style_attribute(code, **options)
|
|
46
|
-
serialized = Options.serialize(options,
|
|
48
|
+
serialized = Options.serialize(options, Options::STYLE_ATTRIBUTE, "a style attribute")
|
|
47
49
|
|
|
48
50
|
Result.from_json(Backend.transform_style_attribute(code.to_s, serialized))
|
|
49
51
|
end
|
data/rust/Cargo.lock
CHANGED
data/rust/Cargo.toml
CHANGED
data/rust/build.rs
CHANGED
|
@@ -18,6 +18,16 @@ fn main() {
|
|
|
18
18
|
|
|
19
19
|
println!("cargo:rerun-if-changed={}", lock_path.display());
|
|
20
20
|
|
|
21
|
+
println!(
|
|
22
|
+
"cargo:rerun-if-changed={}",
|
|
23
|
+
PathBuf::from(&crate_dir).join("src").display()
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
println!(
|
|
27
|
+
"cargo:rerun-if-changed={}",
|
|
28
|
+
PathBuf::from(&crate_dir).join("cbindgen.toml").display()
|
|
29
|
+
);
|
|
30
|
+
|
|
21
31
|
println!(
|
|
22
32
|
"cargo:rustc-env=LIGHTNINGCSS_VERSION={}",
|
|
23
33
|
locked_version(&lock_path, "lightningcss")
|
data/rust/cbindgen.toml
CHANGED
data/rust/src/lib.rs
CHANGED
|
@@ -17,7 +17,7 @@ use std::os::raw::c_char;
|
|
|
17
17
|
use std::ptr;
|
|
18
18
|
use std::sync::{Arc, RwLock};
|
|
19
19
|
|
|
20
|
-
use lightningcss::bundler::{Bundler, FileProvider};
|
|
20
|
+
use lightningcss::bundler::{BundleErrorKind, Bundler, FileProvider};
|
|
21
21
|
use lightningcss::stylesheet::{MinifyOptions, ParserOptions, PrinterOptions, StyleAttribute, StyleSheet};
|
|
22
22
|
use lightningcss::visitor::Visit;
|
|
23
23
|
|
|
@@ -27,10 +27,21 @@ use crate::scope::Scoper;
|
|
|
27
27
|
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
|
28
28
|
pub const LIGHTNINGCSS_VERSION: &str = env!("LIGHTNINGCSS_VERSION");
|
|
29
29
|
|
|
30
|
+
#[repr(C)]
|
|
31
|
+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
32
|
+
pub enum LightningCssErrorCode {
|
|
33
|
+
None = 0,
|
|
34
|
+
Parse,
|
|
35
|
+
Option,
|
|
36
|
+
Bundle,
|
|
37
|
+
Internal,
|
|
38
|
+
}
|
|
39
|
+
|
|
30
40
|
#[repr(C)]
|
|
31
41
|
pub struct LightningCssResult {
|
|
32
42
|
pub value: *mut c_char,
|
|
33
43
|
pub error: *mut c_char,
|
|
44
|
+
pub code: LightningCssErrorCode,
|
|
34
45
|
}
|
|
35
46
|
|
|
36
47
|
impl LightningCssResult {
|
|
@@ -38,13 +49,50 @@ impl LightningCssResult {
|
|
|
38
49
|
Self {
|
|
39
50
|
value: into_c_string(value),
|
|
40
51
|
error: ptr::null_mut(),
|
|
52
|
+
code: LightningCssErrorCode::None,
|
|
41
53
|
}
|
|
42
54
|
}
|
|
43
55
|
|
|
44
|
-
fn err(
|
|
56
|
+
fn err(failure: Failure) -> Self {
|
|
45
57
|
Self {
|
|
46
58
|
value: ptr::null_mut(),
|
|
47
|
-
error: into_c_string(message
|
|
59
|
+
error: into_c_string(failure.message),
|
|
60
|
+
code: failure.code,
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
pub struct Failure {
|
|
66
|
+
code: LightningCssErrorCode,
|
|
67
|
+
message: String,
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
impl Failure {
|
|
71
|
+
fn parse(message: impl Into<String>) -> Self {
|
|
72
|
+
Self {
|
|
73
|
+
code: LightningCssErrorCode::Parse,
|
|
74
|
+
message: message.into(),
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
fn option(message: impl Into<String>) -> Self {
|
|
79
|
+
Self {
|
|
80
|
+
code: LightningCssErrorCode::Option,
|
|
81
|
+
message: message.into(),
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
fn bundle(message: impl Into<String>) -> Self {
|
|
86
|
+
Self {
|
|
87
|
+
code: LightningCssErrorCode::Bundle,
|
|
88
|
+
message: message.into(),
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
fn internal(message: impl Into<String>) -> Self {
|
|
93
|
+
Self {
|
|
94
|
+
code: LightningCssErrorCode::Internal,
|
|
95
|
+
message: message.into(),
|
|
48
96
|
}
|
|
49
97
|
}
|
|
50
98
|
}
|
|
@@ -53,17 +101,17 @@ fn into_c_string(value: impl Into<Vec<u8>>) -> *mut c_char {
|
|
|
53
101
|
CString::new(value).unwrap_or_default().into_raw()
|
|
54
102
|
}
|
|
55
103
|
|
|
56
|
-
unsafe fn borrow_str<'a>(pointer: *const c_char, label: &str) -> Result<&'a str,
|
|
104
|
+
unsafe fn borrow_str<'a>(pointer: *const c_char, label: &str) -> Result<&'a str, Failure> {
|
|
57
105
|
if pointer.is_null() {
|
|
58
|
-
return Err(format!("{label} is null"));
|
|
106
|
+
return Err(Failure::internal(format!("{label} is null")));
|
|
59
107
|
}
|
|
60
108
|
|
|
61
109
|
CStr::from_ptr(pointer)
|
|
62
110
|
.to_str()
|
|
63
|
-
.map_err(|error| format!("Invalid UTF-8 in {label}: {error}"))
|
|
111
|
+
.map_err(|error| Failure::internal(format!("Invalid UTF-8 in {label}: {error}")))
|
|
64
112
|
}
|
|
65
113
|
|
|
66
|
-
unsafe fn borrow_options(pointer: *const c_char) -> Result<TransformOptions,
|
|
114
|
+
unsafe fn borrow_options(pointer: *const c_char) -> Result<TransformOptions, Failure> {
|
|
67
115
|
if pointer.is_null() {
|
|
68
116
|
return Ok(TransformOptions::default());
|
|
69
117
|
}
|
|
@@ -74,13 +122,13 @@ unsafe fn borrow_options(pointer: *const c_char) -> Result<TransformOptions, Str
|
|
|
74
122
|
return Ok(TransformOptions::default());
|
|
75
123
|
}
|
|
76
124
|
|
|
77
|
-
serde_json::from_str(json).map_err(|error| format!("Invalid options: {error}"))
|
|
125
|
+
serde_json::from_str(json).map_err(|error| Failure::option(format!("Invalid options: {error}")))
|
|
78
126
|
}
|
|
79
127
|
|
|
80
|
-
fn transform_source(code: &str, options: &TransformOptions) -> Result<TransformResult,
|
|
128
|
+
fn transform_source(code: &str, options: &TransformOptions) -> Result<TransformResult, Failure> {
|
|
81
129
|
let filename = options.filename.clone().unwrap_or_default();
|
|
82
130
|
let css_modules = match &options.css_modules {
|
|
83
|
-
Some(modules) => Some(modules.to_config()?),
|
|
131
|
+
Some(modules) => Some(modules.to_config().map_err(Failure::option)?),
|
|
84
132
|
None => None,
|
|
85
133
|
};
|
|
86
134
|
|
|
@@ -94,14 +142,14 @@ fn transform_source(code: &str, options: &TransformOptions) -> Result<TransformR
|
|
|
94
142
|
..ParserOptions::default()
|
|
95
143
|
};
|
|
96
144
|
|
|
97
|
-
let mut stylesheet = StyleSheet::parse(code, parser_options).map_err(|error| error.to_string())?;
|
|
145
|
+
let mut stylesheet = StyleSheet::parse(code, parser_options).map_err(|error| Failure::parse(error.to_string()))?;
|
|
98
146
|
|
|
99
147
|
if let Some(fragment) = &options.scope {
|
|
100
|
-
let mut scoper = Scoper::parse(fragment)?;
|
|
148
|
+
let mut scoper = Scoper::parse(fragment).map_err(Failure::option)?;
|
|
101
149
|
|
|
102
150
|
stylesheet
|
|
103
151
|
.visit(&mut scoper)
|
|
104
|
-
.map_err(|error| format!("Failed to scope stylesheet: {error:?}"))?;
|
|
152
|
+
.map_err(|error| Failure::internal(format!("Failed to scope stylesheet: {error:?}")))?;
|
|
105
153
|
}
|
|
106
154
|
|
|
107
155
|
let targets = options.to_targets();
|
|
@@ -112,7 +160,7 @@ fn transform_source(code: &str, options: &TransformOptions) -> Result<TransformR
|
|
|
112
160
|
targets,
|
|
113
161
|
..MinifyOptions::default()
|
|
114
162
|
})
|
|
115
|
-
.map_err(|error| format!("Failed to minify: {error}"))?;
|
|
163
|
+
.map_err(|error| Failure::internal(format!("Failed to minify: {error}")))?;
|
|
116
164
|
}
|
|
117
165
|
|
|
118
166
|
let printed = stylesheet
|
|
@@ -124,7 +172,7 @@ fn transform_source(code: &str, options: &TransformOptions) -> Result<TransformR
|
|
|
124
172
|
analyze_dependencies: None,
|
|
125
173
|
pseudo_classes: None,
|
|
126
174
|
})
|
|
127
|
-
.map_err(|error| format!("Failed to print: {error}"))?;
|
|
175
|
+
.map_err(|error| Failure::internal(format!("Failed to print: {error}")))?;
|
|
128
176
|
|
|
129
177
|
let exports = printed.exports.map(|exports| {
|
|
130
178
|
exports
|
|
@@ -145,31 +193,37 @@ fn transform_source(code: &str, options: &TransformOptions) -> Result<TransformR
|
|
|
145
193
|
})
|
|
146
194
|
}
|
|
147
195
|
|
|
148
|
-
fn bundle_source(path: &str, options: &TransformOptions) -> Result<TransformResult,
|
|
196
|
+
fn bundle_source(path: &str, options: &TransformOptions) -> Result<TransformResult, Failure> {
|
|
149
197
|
let css_modules = match &options.css_modules {
|
|
150
|
-
Some(modules) => Some(modules.to_config()?),
|
|
198
|
+
Some(modules) => Some(modules.to_config().map_err(Failure::option)?),
|
|
151
199
|
None => None,
|
|
152
200
|
};
|
|
153
201
|
|
|
202
|
+
let provider = FileProvider::new();
|
|
203
|
+
let collected = Arc::new(RwLock::new(Vec::new()));
|
|
204
|
+
|
|
154
205
|
let parser_options = ParserOptions {
|
|
155
206
|
css_modules,
|
|
156
207
|
error_recovery: options.error_recovery,
|
|
208
|
+
warnings: Some(collected.clone()),
|
|
157
209
|
..ParserOptions::default()
|
|
158
210
|
};
|
|
159
211
|
|
|
160
|
-
let provider = FileProvider::new();
|
|
161
212
|
let mut bundler = Bundler::new(&provider, None, parser_options);
|
|
162
213
|
|
|
163
214
|
let mut stylesheet = bundler
|
|
164
215
|
.bundle(std::path::Path::new(path))
|
|
165
|
-
.map_err(|error| error.
|
|
216
|
+
.map_err(|error| match &error.kind {
|
|
217
|
+
BundleErrorKind::ParserError(_) => Failure::parse(error.to_string()),
|
|
218
|
+
_ => Failure::bundle(error.to_string()),
|
|
219
|
+
})?;
|
|
166
220
|
|
|
167
221
|
if let Some(fragment) = &options.scope {
|
|
168
|
-
let mut scoper = Scoper::parse(fragment)?;
|
|
222
|
+
let mut scoper = Scoper::parse(fragment).map_err(Failure::option)?;
|
|
169
223
|
|
|
170
224
|
stylesheet
|
|
171
225
|
.visit(&mut scoper)
|
|
172
|
-
.map_err(|error| format!("Failed to scope stylesheet: {error:?}"))?;
|
|
226
|
+
.map_err(|error| Failure::internal(format!("Failed to scope stylesheet: {error:?}")))?;
|
|
173
227
|
}
|
|
174
228
|
|
|
175
229
|
let targets = options.to_targets();
|
|
@@ -180,7 +234,7 @@ fn bundle_source(path: &str, options: &TransformOptions) -> Result<TransformResu
|
|
|
180
234
|
targets,
|
|
181
235
|
..MinifyOptions::default()
|
|
182
236
|
})
|
|
183
|
-
.map_err(|error| format!("Failed to minify: {error}"))?;
|
|
237
|
+
.map_err(|error| Failure::internal(format!("Failed to minify: {error}")))?;
|
|
184
238
|
}
|
|
185
239
|
|
|
186
240
|
let printed = stylesheet
|
|
@@ -189,23 +243,35 @@ fn bundle_source(path: &str, options: &TransformOptions) -> Result<TransformResu
|
|
|
189
243
|
targets,
|
|
190
244
|
..PrinterOptions::default()
|
|
191
245
|
})
|
|
192
|
-
.map_err(|error| format!("Failed to print: {error}"))?;
|
|
246
|
+
.map_err(|error| Failure::internal(format!("Failed to print: {error}")))?;
|
|
247
|
+
|
|
248
|
+
let exports = printed.exports.map(|exports| {
|
|
249
|
+
exports
|
|
250
|
+
.into_iter()
|
|
251
|
+
.map(|(local, export)| (local, export.name))
|
|
252
|
+
.collect::<HashMap<String, String>>()
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
let warnings = collected
|
|
256
|
+
.read()
|
|
257
|
+
.map(|warnings| warnings.iter().map(|warning| warning.to_string()).collect())
|
|
258
|
+
.unwrap_or_default();
|
|
193
259
|
|
|
194
260
|
Ok(TransformResult {
|
|
195
261
|
code: printed.code,
|
|
196
|
-
exports
|
|
197
|
-
warnings
|
|
262
|
+
exports,
|
|
263
|
+
warnings,
|
|
198
264
|
})
|
|
199
265
|
}
|
|
200
266
|
|
|
201
|
-
fn transform_attribute(code: &str, options: &TransformOptions) -> Result<TransformResult,
|
|
267
|
+
fn transform_attribute(code: &str, options: &TransformOptions) -> Result<TransformResult, Failure> {
|
|
202
268
|
let parser_options = ParserOptions {
|
|
203
269
|
filename: options.filename.clone().unwrap_or_default(),
|
|
204
270
|
error_recovery: options.error_recovery,
|
|
205
271
|
..ParserOptions::default()
|
|
206
272
|
};
|
|
207
273
|
|
|
208
|
-
let mut attribute = StyleAttribute::parse(code, parser_options).map_err(|error| error.to_string())?;
|
|
274
|
+
let mut attribute = StyleAttribute::parse(code, parser_options).map_err(|error| Failure::parse(error.to_string()))?;
|
|
209
275
|
|
|
210
276
|
let targets = options.to_targets();
|
|
211
277
|
|
|
@@ -220,7 +286,7 @@ fn transform_attribute(code: &str, options: &TransformOptions) -> Result<Transfo
|
|
|
220
286
|
targets,
|
|
221
287
|
..PrinterOptions::default()
|
|
222
288
|
})
|
|
223
|
-
.map_err(|error| format!("Failed to print: {error}"))?;
|
|
289
|
+
.map_err(|error| Failure::internal(format!("Failed to print: {error}")))?;
|
|
224
290
|
|
|
225
291
|
Ok(TransformResult {
|
|
226
292
|
code: printed.code,
|
|
@@ -229,13 +295,13 @@ fn transform_attribute(code: &str, options: &TransformOptions) -> Result<Transfo
|
|
|
229
295
|
})
|
|
230
296
|
}
|
|
231
297
|
|
|
232
|
-
fn to_result(outcome: Result<TransformResult,
|
|
298
|
+
fn to_result(outcome: Result<TransformResult, Failure>) -> LightningCssResult {
|
|
233
299
|
match outcome {
|
|
234
300
|
Ok(result) => match serde_json::to_string(&result) {
|
|
235
301
|
Ok(json) => LightningCssResult::ok(json),
|
|
236
|
-
Err(error) => LightningCssResult::err(format!("Failed to serialize result: {error}")),
|
|
302
|
+
Err(error) => LightningCssResult::err(Failure::internal(format!("Failed to serialize result: {error}"))),
|
|
237
303
|
},
|
|
238
|
-
Err(
|
|
304
|
+
Err(failure) => LightningCssResult::err(failure),
|
|
239
305
|
}
|
|
240
306
|
}
|
|
241
307
|
|
|
@@ -246,12 +312,12 @@ pub unsafe extern "C" fn lightningcss_transform(
|
|
|
246
312
|
) -> LightningCssResult {
|
|
247
313
|
let code = match borrow_str(code, "code") {
|
|
248
314
|
Ok(code) => code,
|
|
249
|
-
Err(
|
|
315
|
+
Err(failure) => return LightningCssResult::err(failure),
|
|
250
316
|
};
|
|
251
317
|
|
|
252
318
|
let options = match borrow_options(options_json) {
|
|
253
319
|
Ok(options) => options,
|
|
254
|
-
Err(
|
|
320
|
+
Err(failure) => return LightningCssResult::err(failure),
|
|
255
321
|
};
|
|
256
322
|
|
|
257
323
|
to_result(transform_source(code, &options))
|
|
@@ -264,12 +330,12 @@ pub unsafe extern "C" fn lightningcss_transform_style_attribute(
|
|
|
264
330
|
) -> LightningCssResult {
|
|
265
331
|
let code = match borrow_str(code, "code") {
|
|
266
332
|
Ok(code) => code,
|
|
267
|
-
Err(
|
|
333
|
+
Err(failure) => return LightningCssResult::err(failure),
|
|
268
334
|
};
|
|
269
335
|
|
|
270
336
|
let options = match borrow_options(options_json) {
|
|
271
337
|
Ok(options) => options,
|
|
272
|
-
Err(
|
|
338
|
+
Err(failure) => return LightningCssResult::err(failure),
|
|
273
339
|
};
|
|
274
340
|
|
|
275
341
|
to_result(transform_attribute(code, &options))
|
|
@@ -279,12 +345,12 @@ pub unsafe extern "C" fn lightningcss_transform_style_attribute(
|
|
|
279
345
|
pub unsafe extern "C" fn lightningcss_bundle(path: *const c_char, options_json: *const c_char) -> LightningCssResult {
|
|
280
346
|
let path = match borrow_str(path, "path") {
|
|
281
347
|
Ok(path) => path,
|
|
282
|
-
Err(
|
|
348
|
+
Err(failure) => return LightningCssResult::err(failure),
|
|
283
349
|
};
|
|
284
350
|
|
|
285
351
|
let options = match borrow_options(options_json) {
|
|
286
352
|
Ok(options) => options,
|
|
287
|
-
Err(
|
|
353
|
+
Err(failure) => return LightningCssResult::err(failure),
|
|
288
354
|
};
|
|
289
355
|
|
|
290
356
|
to_result(bundle_source(path, &options))
|
data/rust/src/scope.rs
CHANGED
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
//! `parcel_selectors` stores a selector in reverse match order, so `Selector::append` lands the
|
|
5
5
|
//! fragment in the last compound and before any pseudo-element, which is where a scope belongs:
|
|
6
6
|
//!
|
|
7
|
-
//!
|
|
8
|
-
//!
|
|
7
|
+
//! ```text
|
|
8
|
+
//! .card .title -> .card .title[data-herb-scope-abc]
|
|
9
|
+
//! .item::before -> .item[data-herb-scope-abc]::before
|
|
10
|
+
//! ```
|
|
9
11
|
//!
|
|
10
12
|
//! A fragment is anything that parses as one compound selector, so an attribute and a `:where()`
|
|
11
13
|
//! carrying its own alternatives are both expressible.
|
|
@@ -13,13 +13,15 @@ module LightningCSS
|
|
|
13
13
|
|
|
14
14
|
STYLE_ATTRIBUTE: Array[Symbol]
|
|
15
15
|
|
|
16
|
+
BUNDLE: Array[Symbol]
|
|
17
|
+
|
|
16
18
|
attr_reader to_h: Hash[Symbol, untyped]
|
|
17
19
|
|
|
18
|
-
# : (Hash[Symbol, untyped], ?
|
|
19
|
-
def self.serialize: (Hash[Symbol, untyped], ?
|
|
20
|
+
# : (Hash[Symbol, untyped], ?Array[Symbol], ?String) -> String
|
|
21
|
+
def self.serialize: (Hash[Symbol, untyped], ?Array[Symbol], ?String) -> String
|
|
20
22
|
|
|
21
|
-
# : (?
|
|
22
|
-
def initialize: (?
|
|
23
|
+
# : (Hash[Symbol, untyped], ?Array[Symbol], ?String) -> void
|
|
24
|
+
def initialize: (Hash[Symbol, untyped], ?Array[Symbol], ?String) -> void
|
|
23
25
|
|
|
24
26
|
# : (?untyped) -> String
|
|
25
27
|
def to_json: (?untyped) -> String
|
|
@@ -21,8 +21,8 @@ module LightningCSS
|
|
|
21
21
|
|
|
22
22
|
alias call transform
|
|
23
23
|
|
|
24
|
-
# : (String, ?
|
|
25
|
-
def bundle: (String, ?
|
|
24
|
+
# : (String, ?minify: bool, ?error_recovery: bool, ?targets: browsers?, ?css_modules: css_modules?, ?scope: String?) -> LightningCSS::Result
|
|
25
|
+
def bundle: (String, ?minify: bool, ?error_recovery: bool, ?targets: browsers?, ?css_modules: css_modules?, ?scope: String?) -> LightningCSS::Result
|
|
26
26
|
|
|
27
27
|
# : (String, ?filename: String?, ?minify: bool, ?error_recovery: bool, ?targets: browsers?) -> LightningCSS::Result
|
|
28
28
|
def transform_style_attribute: (String, ?filename: String?, ?minify: bool, ?error_recovery: bool, ?targets: browsers?) -> LightningCSS::Result
|
data/sig/lightningcss.rbs
CHANGED
|
@@ -17,8 +17,8 @@ module LightningCSS
|
|
|
17
17
|
# : (String, ?filename: String?, ?minify: bool, ?error_recovery: bool, ?targets: browsers?, ?css_modules: css_modules?, ?scope: String?) -> LightningCSS::Result
|
|
18
18
|
def self.transform: (String, ?filename: String?, ?minify: bool, ?error_recovery: bool, ?targets: browsers?, ?css_modules: css_modules?, ?scope: String?) -> LightningCSS::Result
|
|
19
19
|
|
|
20
|
-
# : (String, ?
|
|
21
|
-
def self.bundle: (String, ?
|
|
20
|
+
# : (String, ?minify: bool, ?error_recovery: bool, ?targets: browsers?, ?css_modules: css_modules?, ?scope: String?) -> LightningCSS::Result
|
|
21
|
+
def self.bundle: (String, ?minify: bool, ?error_recovery: bool, ?targets: browsers?, ?css_modules: css_modules?, ?scope: String?) -> LightningCSS::Result
|
|
22
22
|
|
|
23
23
|
# : (String, ?filename: String?, ?minify: bool, ?error_recovery: bool, ?targets: browsers?) -> LightningCSS::Result
|
|
24
24
|
def self.transform_style_attribute: (String, ?filename: String?, ?minify: bool, ?error_recovery: bool, ?targets: browsers?) -> LightningCSS::Result
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lightningcss
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: x86_64-linux-gnu
|
|
6
6
|
authors:
|
|
7
7
|
- Marco Roth
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-08-
|
|
11
|
+
date: 2026-08-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: Ruby bindings for Lightning CSS, an extremely fast CSS parser, transformer,
|
|
14
14
|
bundler, and minifier.
|