Skip to content

Commit

Permalink
feat: 将 __calc_style__ 函数插入到代码中
Browse files Browse the repository at this point in the history
  • Loading branch information
luckyadam committed Oct 17, 2023
1 parent 43b415d commit 65ec163
Show file tree
Hide file tree
Showing 5 changed files with 260 additions and 52 deletions.
191 changes: 175 additions & 16 deletions __test__/index.spec.mjs.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,165 @@ Generated by [AVA](https://avajs.dev).
`import React from 'react';␊
import './Mod.scss';␊
var __inner_style__ = {␊
instruction1: {␊
color: "#000",␊
font-size: "16px",␊
line-height: "1",␊
flex-shrink: "0px",␊
width: "116px",␊
display: "inline-flex"␊
},␊
cnt_row2: {␊
border-width: "1px",␊
border-style: "solid",␊
border-color: "#999",␊
border-radius: "12px",␊
display: "flex",␊
align-items: "flex-start",␊
justify-content: "space-between",␊
flex-shrink: "0px",␊
gap: "-94px",␊
position: "absolute",␊
top: "3px",␊
left: "201px",␊
width: "110px",␊
height: "23px",␊
padding-left: "8px",␊
padding-right: "8px",␊
padding-top: "4px",␊
padding-bottom: "4px",␊
z-index: "12"␊
},␊
cnt_row: {␊
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"␊
},␊
icon: {␊
width: "18px",␊
height: "18px"␊
},␊
mod: {␊
background-color: "#fff6f0",␊
border-radius: "8px",␊
width: "343px",␊
height: "166px",␊
font-family: "Source Han Sans CN",␊
font-weight: "500",␊
display: "flex",␊
flex-direction: "column",␊
align-items: "flex-start",␊
justify-content: "center",␊
flex-shrink: "0px",␊
gap: "8px",␊
padding-left: "16px",␊
padding-right: "16px",␊
padding-top: "29px",␊
padding-bottom: "29px"␊
},␊
cnt_col: {␊
display: "flex",␊
flex-direction: "column",␊
align-items: "flex-start",␊
justify-content: "center",␊
gap: "8px",␊
width: "145px",␊
height: "50px"␊
},␊
line1: {␊
text-overflow: "ellipsis",␊
white-space: "nowrap",␊
overflow: "hidden"␊
},␊
txt2: {␊
color: "#999",␊
font-size: "12px",␊
line-height: "1.83",␊
flex-shrink: "0px",␊
width: "290px",␊
display: "inline-flex"␊
},␊
img: {␊
width: "50px",␊
height: "50px"␊
},␊
img1: {␊
width: "6px",␊
height: "10px"␊
},␊
txt1: {␊
color: "#222",␊
font-size: "11px",␊
line-height: "1.36",␊
text-align: "center",␊
flex-shrink: "0px"␊
},␊
cnt_row3: {␊
display: "flex",␊
align-items: "center",␊
justify-content: "space-between",␊
gap: "-311px",␊
width: "311px",␊
height: "44px"␊
},␊
icon1: {␊
width: "15px",␊
height: "15px"␊
},␊
txt: {␊
color: "#999",␊
font-size: "12px",␊
line-height: "1",␊
flex-shrink: "0px",␊
display: "inline-flex"␊
},␊
instruction2: {␊
color: "#999",␊
font-size: "11px",␊
line-height: "1.36",␊
text-align: "center",␊
flex-shrink: "0px",␊
overflow: "hidden"␊
},␊
instruction: {␊
color: "#fff",␊
font-size: "12px",␊
line-height: "1",␊
flex-shrink: "0px",␊
display: "inline-flex"␊
},␊
cnt_row1: {␊
display: "flex",␊
align-items: "center",␊
justify-content: "flex-start",␊
gap: "10px",␊
position: "relative",␊
width: "311px",␊
height: "50px"␊
}␊
};␊
function __calc_style__(classnames, styleObj) {␊
var styleObjs = [];␊
var classes = classnames.split(' ');␊
for(var i = 0; i < classes.length; i++){␊
styleObjs.push(classes[i] in window.__inner_style__ ? window.__inner_style__[classes[i]] : {});␊
}␊
styleObjs.push(styleObj);␊
return Object.assign.apply(null, [␊
{}␊
].concat(styleObjs));␊
}␊
function Cc() {␊
return <div className='cc'>␊
Expand Down Expand Up @@ -47,25 +206,25 @@ Generated by [AVA](https://avajs.dev).
}␊
render() {␊
return <div className='mod' style={{␊
width: '500px',␊
height: 800,␊
background-color: "#fff6f0",␊
border-radius: "8px",␊
font-family: "Source Han Sans CN",␊
font-weight: "500",␊
display: "flex",␊
flex-direction: "column",␊
align-items: "flex-start",␊
justify-content: "center",␊
flex-shrink: "0px",␊
gap: "8px",␊
padding-left: "16px",␊
padding-right: "16px",␊
padding-bottom: "29px",␊
padding-top: "29px",␊
padding-bottom: "29px"␊
padding-right: "16px",␊
padding-left: "16px",␊
gap: "8px",␊
flex-shrink: "0px",␊
justify-content: "center",␊
align-items: "flex-start",␊
flex-direction: "column",␊
display: "flex",␊
font-weight: "500",␊
font-family: "Source Han Sans CN",␊
border-radius: "8px",␊
background-color: "#fff6f0",␊
width: '500px',␊
height: 800␊
}}>␊
<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;">␊
<div className={classnames('cnt_row')} style={__calc_style__(classnames('cnt_row'), null)}>␊
<>␊
Expand Down
Binary file modified __test__/index.spec.mjs.snap
Binary file not shown.
13 changes: 0 additions & 13 deletions src/scraper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,19 +66,6 @@ impl Element {
self.name.local.deref()
}

pub fn id(&self) -> Option<&str> {
self
.id
.get_or_init(|| {
self
.attrs
.iter()
.find(|(name, _)| name.local.as_ref() == "id")
.map(|(_, value)| value.clone())
})
.as_deref()
}

pub fn has_class(&self, class: &str, case_sensitive: CaseSensitivity) -> bool {
self
.classes()
Expand Down
50 changes: 44 additions & 6 deletions src/style_write.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use std::{cell::RefCell, collections::HashMap, rc::Rc};

use swc_common::{sync::Lrc, SourceMap, errors::{Handler, ColorConfig}};
use swc_ecma_ast::Program;
use swc_ecma_parser::{StringInput, Syntax, lexer::Lexer, Parser};
use swc_ecma_visit::VisitMutWith;

use crate::{
style_parser::StyleDeclaration,
visitor::{AstMutVisitor, JSXRecord, SpanKey},
visitor::{JSXRecord, SpanKey, ModuleMutVisitor, JSXMutVisitor},
};

pub struct StyleWrite<'i> {
Expand All @@ -31,11 +33,47 @@ impl<'i> StyleWrite<'i> {
}

pub fn write(&mut self) {
let mut style_visitor = AstMutVisitor::new(
self.jsx_record.clone(),
self.style_record.clone(),
self.all_style.clone(),
let insert_code = "
function __calc_style__(classnames, styleObj) {
var styleObjs = [];
var classes = classnames.split(' ');
for (var i = 0; i < classes.length; i++) {
styleObjs.push(classes[i] in window.__inner_style__ ? window.__inner_style__[classes[i]] : {});
}
styleObjs.push(styleObj);
return Object.assign.apply(null, [{}].concat(styleObjs));
}
";
let cm: Lrc<SourceMap> = Default::default();
let fm = cm.new_source_file(swc_common::FileName::Anon, insert_code.to_string());
let handler = Handler::with_tty_emitter(ColorConfig::Auto, true, false, Some(cm.clone()));
let lexer = Lexer::new(
Syntax::default(),
Default::default(),
StringInput::from(&*fm),
None,
);
self.module.borrow_mut().visit_mut_with(&mut style_visitor);
let mut parser = Parser::new_from(lexer);
let insert_module = Rc::new(RefCell::new(
parser
.parse_module()
.map_err(|e| e.into_diagnostic(&handler).emit())
.expect("解析插入代码失败")
));
{
let mut jsx_mut_visitor = JSXMutVisitor::new(
self.jsx_record.clone(),
self.style_record.clone(),

);
self.module.borrow_mut().visit_mut_with(&mut jsx_mut_visitor);
}
{
let mut insert_mut_visitor = ModuleMutVisitor::new(
self.all_style.clone(),
insert_module.clone(),
);
self.module.borrow_mut().visit_mut_with(&mut insert_mut_visitor);
}
}
}
58 changes: 41 additions & 17 deletions src/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ use html5ever::{tendril::StrTendril, Attribute};
use lightningcss::{stylesheet::PrinterOptions, traits::ToCss};
use swc_common::{Span, DUMMY_SP};
use swc_ecma_ast::{
AssignExpr, BindingIdent, CallExpr, Callee, Decl, Expr, ExprOrSpread, ExprStmt, Ident,
BindingIdent, CallExpr, Callee, Decl, Expr, ExprOrSpread, Ident,
ImportDecl, ImportSpecifier, JSXAttr, JSXAttrName, JSXAttrOrSpread, JSXAttrValue, JSXElement,
JSXElementName, JSXExpr, JSXExprContainer, JSXFragment, KeyValueProp, Lit, Module, ModuleDecl,
ModuleItem, Null, ObjectLit, Pat, PatOrExpr, Prop, PropName, PropOrSpread, Stmt, Str, VarDecl,
ModuleItem, Null, ObjectLit, Pat, Prop, PropName, PropOrSpread, Stmt, Str, VarDecl,
VarDeclKind, VarDeclarator,
};
use swc_ecma_visit::{
Expand Down Expand Up @@ -173,27 +173,21 @@ impl<'a> VisitAll for AstVisitor<'a> {
}
}

pub struct AstMutVisitor<'a> {
pub jsx_record: Rc<RefCell<JSXRecord>>,
pub style_record: Rc<RefCell<HashMap<SpanKey, StyleDeclaration<'a>>>>,
pub struct ModuleMutVisitor<'a> {
pub insert_module: Rc<RefCell<Module>>,
pub all_style: Rc<RefCell<HashMap<String, StyleDeclaration<'a>>>>,
}

impl<'a> AstMutVisitor<'a> {
impl<'a> ModuleMutVisitor<'a> {
pub fn new(
jsx_record: Rc<RefCell<JSXRecord>>,
style_record: Rc<RefCell<HashMap<SpanKey, StyleDeclaration<'a>>>>,
all_style: Rc<RefCell<HashMap<String, StyleDeclaration<'a>>>>,
insert_module: Rc<RefCell<Module>>,
) -> Self {
AstMutVisitor {
jsx_record,
style_record,
all_style,
}
ModuleMutVisitor { all_style, insert_module }
}
}

impl<'a> VisitMut for AstMutVisitor<'a> {
impl<'a> VisitMut for ModuleMutVisitor<'a> {
noop_visit_mut_type!();

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

// 将 inner_style_stmt 插入到 module 的最后一条 import 语句之后
let mut last_import_index: i32 = -1;
let mut last_import_index = 0;
for (index, stmt) in module.body.iter().enumerate() {
if let ModuleItem::ModuleDecl(ModuleDecl::Import(_)) = stmt {
last_import_index = index as i32;
last_import_index = index;
}
}
if last_import_index != 0 {
last_import_index += 1;
}
module.body.insert(
(last_import_index + 1) as usize,
last_import_index,
ModuleItem::Stmt(inner_style_stmt),
);
for item in self.insert_module.borrow().body.iter() {
if last_import_index != 0 {
last_import_index += 1;
}
module.body.insert(last_import_index, item.clone());
}
}
}

pub struct JSXMutVisitor<'a> {
pub jsx_record: Rc<RefCell<JSXRecord>>,
pub style_record: Rc<RefCell<HashMap<SpanKey, StyleDeclaration<'a>>>>,
}

impl<'a> JSXMutVisitor<'a> {
pub fn new(
jsx_record: Rc<RefCell<JSXRecord>>,
style_record: Rc<RefCell<HashMap<SpanKey, StyleDeclaration<'a>>>>,
) -> Self {
JSXMutVisitor {
jsx_record,
style_record,
}
}
}

impl<'a> VisitMut for JSXMutVisitor<'a> {
noop_visit_mut_type!();

fn visit_mut_jsx_element(&mut self, n: &mut JSXElement) {
let span_key = SpanKey(n.span);
if let Some(element) = self.jsx_record.borrow().get(&span_key) {
Expand Down

0 comments on commit 65ec163

Please sign in to comment.