Skip to content

Commit 65ec163

Browse files
committed
feat: 将 __calc_style__ 函数插入到代码中
1 parent 43b415d commit 65ec163

File tree

5 files changed

+260
-52
lines changed

5 files changed

+260
-52
lines changed

__test__/index.spec.mjs.md

Lines changed: 175 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,165 @@ Generated by [AVA](https://avajs.dev).
1010
1111
`import React from 'react';␊
1212
import './Mod.scss';␊
13+
var __inner_style__ = {␊
14+
instruction1: {␊
15+
color: "#000",␊
16+
font-size: "16px",␊
17+
line-height: "1",␊
18+
flex-shrink: "0px",␊
19+
width: "116px",␊
20+
display: "inline-flex"␊
21+
},␊
22+
cnt_row2: {␊
23+
border-width: "1px",␊
24+
border-style: "solid",␊
25+
border-color: "#999",␊
26+
border-radius: "12px",␊
27+
display: "flex",␊
28+
align-items: "flex-start",␊
29+
justify-content: "space-between",␊
30+
flex-shrink: "0px",␊
31+
gap: "-94px",␊
32+
position: "absolute",␊
33+
top: "3px",␊
34+
left: "201px",␊
35+
width: "110px",␊
36+
height: "23px",␊
37+
padding-left: "8px",␊
38+
padding-right: "8px",␊
39+
padding-top: "4px",␊
40+
padding-bottom: "4px",␊
41+
z-index: "12"␊
42+
},␊
43+
cnt_row: {␊
44+
width: "176px",␊
45+
height: "24px",␊
46+
border-radius: "100px",␊
47+
background-color: "#000000b3",␊
48+
display: "flex",␊
49+
align-items: "center",␊
50+
justify-content: "center",␊
51+
flex-shrink: "0px",␊
52+
gap: "4px",␊
53+
padding-left: "4px",␊
54+
padding-right: "8px",␊
55+
padding-top: "8px",␊
56+
padding-bottom: "8px"␊
57+
},␊
58+
icon: {␊
59+
width: "18px",␊
60+
height: "18px"␊
61+
},␊
62+
mod: {␊
63+
background-color: "#fff6f0",␊
64+
border-radius: "8px",␊
65+
width: "343px",␊
66+
height: "166px",␊
67+
font-family: "Source Han Sans CN",␊
68+
font-weight: "500",␊
69+
display: "flex",␊
70+
flex-direction: "column",␊
71+
align-items: "flex-start",␊
72+
justify-content: "center",␊
73+
flex-shrink: "0px",␊
74+
gap: "8px",␊
75+
padding-left: "16px",␊
76+
padding-right: "16px",␊
77+
padding-top: "29px",␊
78+
padding-bottom: "29px"␊
79+
},␊
80+
cnt_col: {␊
81+
display: "flex",␊
82+
flex-direction: "column",␊
83+
align-items: "flex-start",␊
84+
justify-content: "center",␊
85+
gap: "8px",␊
86+
width: "145px",␊
87+
height: "50px"␊
88+
},␊
89+
line1: {␊
90+
text-overflow: "ellipsis",␊
91+
white-space: "nowrap",␊
92+
overflow: "hidden"␊
93+
},␊
94+
txt2: {␊
95+
color: "#999",␊
96+
font-size: "12px",␊
97+
line-height: "1.83",␊
98+
flex-shrink: "0px",␊
99+
width: "290px",␊
100+
display: "inline-flex"␊
101+
},␊
102+
img: {␊
103+
width: "50px",␊
104+
height: "50px"␊
105+
},␊
106+
img1: {␊
107+
width: "6px",␊
108+
height: "10px"␊
109+
},␊
110+
txt1: {␊
111+
color: "#222",␊
112+
font-size: "11px",␊
113+
line-height: "1.36",␊
114+
text-align: "center",␊
115+
flex-shrink: "0px"␊
116+
},␊
117+
cnt_row3: {␊
118+
display: "flex",␊
119+
align-items: "center",␊
120+
justify-content: "space-between",␊
121+
gap: "-311px",␊
122+
width: "311px",␊
123+
height: "44px"␊
124+
},␊
125+
icon1: {␊
126+
width: "15px",␊
127+
height: "15px"␊
128+
},␊
129+
txt: {␊
130+
color: "#999",␊
131+
font-size: "12px",␊
132+
line-height: "1",␊
133+
flex-shrink: "0px",␊
134+
display: "inline-flex"␊
135+
},␊
136+
instruction2: {␊
137+
color: "#999",␊
138+
font-size: "11px",␊
139+
line-height: "1.36",␊
140+
text-align: "center",␊
141+
flex-shrink: "0px",␊
142+
overflow: "hidden"␊
143+
},␊
144+
instruction: {␊
145+
color: "#fff",␊
146+
font-size: "12px",␊
147+
line-height: "1",␊
148+
flex-shrink: "0px",␊
149+
display: "inline-flex"␊
150+
},␊
151+
cnt_row1: {␊
152+
display: "flex",␊
153+
align-items: "center",␊
154+
justify-content: "flex-start",␊
155+
gap: "10px",␊
156+
position: "relative",␊
157+
width: "311px",␊
158+
height: "50px"␊
159+
}␊
160+
};␊
161+
function __calc_style__(classnames, styleObj) {␊
162+
var styleObjs = [];␊
163+
var classes = classnames.split(' ');␊
164+
for(var i = 0; i < classes.length; i++){␊
165+
styleObjs.push(classes[i] in window.__inner_style__ ? window.__inner_style__[classes[i]] : {});␊
166+
}␊
167+
styleObjs.push(styleObj);␊
168+
return Object.assign.apply(null, [␊
169+
{}␊
170+
].concat(styleObjs));␊
171+
}␊
13172
function Cc() {␊
14173
return <div className='cc'>␊
15174
@@ -47,25 +206,25 @@ Generated by [AVA](https://avajs.dev).
47206
}␊
48207
render() {␊
49208
return <div className='mod' style={{␊
50-
width: '500px',␊
51-
height: 800,␊
52-
background-color: "#fff6f0",␊
53-
border-radius: "8px",␊
54-
font-family: "Source Han Sans CN",␊
55-
font-weight: "500",␊
56-
display: "flex",␊
57-
flex-direction: "column",␊
58-
align-items: "flex-start",␊
59-
justify-content: "center",␊
60-
flex-shrink: "0px",␊
61-
gap: "8px",␊
62-
padding-left: "16px",␊
63-
padding-right: "16px",␊
209+
padding-bottom: "29px",␊
64210
padding-top: "29px",␊
65-
padding-bottom: "29px"␊
211+
padding-right: "16px",␊
212+
padding-left: "16px",␊
213+
gap: "8px",␊
214+
flex-shrink: "0px",␊
215+
justify-content: "center",␊
216+
align-items: "flex-start",␊
217+
flex-direction: "column",␊
218+
display: "flex",␊
219+
font-weight: "500",␊
220+
font-family: "Source Han Sans CN",␊
221+
border-radius: "8px",␊
222+
background-color: "#fff6f0",␊
223+
width: '500px',␊
224+
height: 800␊
66225
}}>␊
67226
68-
<div className='cnt_row' style="width:176px;height:24px;border-radius:100px;background-color:#000000b3;display:flex;align-items:center;justify-content:center;flex-shrink:0px;gap:4px;padding-left:4px;padding-right:8px;padding-top:8px;padding-bottom:8px;">␊
227+
<div className={classnames('cnt_row')} style={__calc_style__(classnames('cnt_row'), null)}>␊
69228
70229
<>␊
71230

__test__/index.spec.mjs.snap

651 Bytes
Binary file not shown.

src/scraper.rs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -66,19 +66,6 @@ impl Element {
6666
self.name.local.deref()
6767
}
6868

69-
pub fn id(&self) -> Option<&str> {
70-
self
71-
.id
72-
.get_or_init(|| {
73-
self
74-
.attrs
75-
.iter()
76-
.find(|(name, _)| name.local.as_ref() == "id")
77-
.map(|(_, value)| value.clone())
78-
})
79-
.as_deref()
80-
}
81-
8269
pub fn has_class(&self, class: &str, case_sensitive: CaseSensitivity) -> bool {
8370
self
8471
.classes()

src/style_write.rs

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
use std::{cell::RefCell, collections::HashMap, rc::Rc};
22

3+
use swc_common::{sync::Lrc, SourceMap, errors::{Handler, ColorConfig}};
34
use swc_ecma_ast::Program;
5+
use swc_ecma_parser::{StringInput, Syntax, lexer::Lexer, Parser};
46
use swc_ecma_visit::VisitMutWith;
57

68
use crate::{
79
style_parser::StyleDeclaration,
8-
visitor::{AstMutVisitor, JSXRecord, SpanKey},
10+
visitor::{JSXRecord, SpanKey, ModuleMutVisitor, JSXMutVisitor},
911
};
1012

1113
pub struct StyleWrite<'i> {
@@ -31,11 +33,47 @@ impl<'i> StyleWrite<'i> {
3133
}
3234

3335
pub fn write(&mut self) {
34-
let mut style_visitor = AstMutVisitor::new(
35-
self.jsx_record.clone(),
36-
self.style_record.clone(),
37-
self.all_style.clone(),
36+
let insert_code = "
37+
function __calc_style__(classnames, styleObj) {
38+
var styleObjs = [];
39+
var classes = classnames.split(' ');
40+
for (var i = 0; i < classes.length; i++) {
41+
styleObjs.push(classes[i] in window.__inner_style__ ? window.__inner_style__[classes[i]] : {});
42+
}
43+
styleObjs.push(styleObj);
44+
return Object.assign.apply(null, [{}].concat(styleObjs));
45+
}
46+
";
47+
let cm: Lrc<SourceMap> = Default::default();
48+
let fm = cm.new_source_file(swc_common::FileName::Anon, insert_code.to_string());
49+
let handler = Handler::with_tty_emitter(ColorConfig::Auto, true, false, Some(cm.clone()));
50+
let lexer = Lexer::new(
51+
Syntax::default(),
52+
Default::default(),
53+
StringInput::from(&*fm),
54+
None,
3855
);
39-
self.module.borrow_mut().visit_mut_with(&mut style_visitor);
56+
let mut parser = Parser::new_from(lexer);
57+
let insert_module = Rc::new(RefCell::new(
58+
parser
59+
.parse_module()
60+
.map_err(|e| e.into_diagnostic(&handler).emit())
61+
.expect("解析插入代码失败")
62+
));
63+
{
64+
let mut jsx_mut_visitor = JSXMutVisitor::new(
65+
self.jsx_record.clone(),
66+
self.style_record.clone(),
67+
68+
);
69+
self.module.borrow_mut().visit_mut_with(&mut jsx_mut_visitor);
70+
}
71+
{
72+
let mut insert_mut_visitor = ModuleMutVisitor::new(
73+
self.all_style.clone(),
74+
insert_module.clone(),
75+
);
76+
self.module.borrow_mut().visit_mut_with(&mut insert_mut_visitor);
77+
}
4078
}
4179
}

src/visitor.rs

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ use html5ever::{tendril::StrTendril, Attribute};
99
use lightningcss::{stylesheet::PrinterOptions, traits::ToCss};
1010
use swc_common::{Span, DUMMY_SP};
1111
use swc_ecma_ast::{
12-
AssignExpr, BindingIdent, CallExpr, Callee, Decl, Expr, ExprOrSpread, ExprStmt, Ident,
12+
BindingIdent, CallExpr, Callee, Decl, Expr, ExprOrSpread, Ident,
1313
ImportDecl, ImportSpecifier, JSXAttr, JSXAttrName, JSXAttrOrSpread, JSXAttrValue, JSXElement,
1414
JSXElementName, JSXExpr, JSXExprContainer, JSXFragment, KeyValueProp, Lit, Module, ModuleDecl,
15-
ModuleItem, Null, ObjectLit, Pat, PatOrExpr, Prop, PropName, PropOrSpread, Stmt, Str, VarDecl,
15+
ModuleItem, Null, ObjectLit, Pat, Prop, PropName, PropOrSpread, Stmt, Str, VarDecl,
1616
VarDeclKind, VarDeclarator,
1717
};
1818
use swc_ecma_visit::{
@@ -173,27 +173,21 @@ impl<'a> VisitAll for AstVisitor<'a> {
173173
}
174174
}
175175

176-
pub struct AstMutVisitor<'a> {
177-
pub jsx_record: Rc<RefCell<JSXRecord>>,
178-
pub style_record: Rc<RefCell<HashMap<SpanKey, StyleDeclaration<'a>>>>,
176+
pub struct ModuleMutVisitor<'a> {
177+
pub insert_module: Rc<RefCell<Module>>,
179178
pub all_style: Rc<RefCell<HashMap<String, StyleDeclaration<'a>>>>,
180179
}
181180

182-
impl<'a> AstMutVisitor<'a> {
181+
impl<'a> ModuleMutVisitor<'a> {
183182
pub fn new(
184-
jsx_record: Rc<RefCell<JSXRecord>>,
185-
style_record: Rc<RefCell<HashMap<SpanKey, StyleDeclaration<'a>>>>,
186183
all_style: Rc<RefCell<HashMap<String, StyleDeclaration<'a>>>>,
184+
insert_module: Rc<RefCell<Module>>,
187185
) -> Self {
188-
AstMutVisitor {
189-
jsx_record,
190-
style_record,
191-
all_style,
192-
}
186+
ModuleMutVisitor { all_style, insert_module }
193187
}
194188
}
195189

196-
impl<'a> VisitMut for AstMutVisitor<'a> {
190+
impl<'a> VisitMut for ModuleMutVisitor<'a> {
197191
noop_visit_mut_type!();
198192

199193
fn visit_mut_module(&mut self, module: &mut Module) {
@@ -251,18 +245,48 @@ impl<'a> VisitMut for AstMutVisitor<'a> {
251245
})));
252246

253247
// 将 inner_style_stmt 插入到 module 的最后一条 import 语句之后
254-
let mut last_import_index: i32 = -1;
248+
let mut last_import_index = 0;
255249
for (index, stmt) in module.body.iter().enumerate() {
256250
if let ModuleItem::ModuleDecl(ModuleDecl::Import(_)) = stmt {
257-
last_import_index = index as i32;
251+
last_import_index = index;
258252
}
259253
}
254+
if last_import_index != 0 {
255+
last_import_index += 1;
256+
}
260257
module.body.insert(
261-
(last_import_index + 1) as usize,
258+
last_import_index,
262259
ModuleItem::Stmt(inner_style_stmt),
263260
);
261+
for item in self.insert_module.borrow().body.iter() {
262+
if last_import_index != 0 {
263+
last_import_index += 1;
264+
}
265+
module.body.insert(last_import_index, item.clone());
266+
}
267+
}
268+
}
269+
270+
pub struct JSXMutVisitor<'a> {
271+
pub jsx_record: Rc<RefCell<JSXRecord>>,
272+
pub style_record: Rc<RefCell<HashMap<SpanKey, StyleDeclaration<'a>>>>,
273+
}
274+
275+
impl<'a> JSXMutVisitor<'a> {
276+
pub fn new(
277+
jsx_record: Rc<RefCell<JSXRecord>>,
278+
style_record: Rc<RefCell<HashMap<SpanKey, StyleDeclaration<'a>>>>,
279+
) -> Self {
280+
JSXMutVisitor {
281+
jsx_record,
282+
style_record,
283+
}
264284
}
285+
}
265286

287+
impl<'a> VisitMut for JSXMutVisitor<'a> {
288+
noop_visit_mut_type!();
289+
266290
fn visit_mut_jsx_element(&mut self, n: &mut JSXElement) {
267291
let span_key = SpanKey(n.span);
268292
if let Some(element) = self.jsx_record.borrow().get(&span_key) {

0 commit comments

Comments
 (0)