Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/common css repeat #31

Open
wants to merge 4 commits into
base: arkts
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions __test__/fixure/pesudo.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { View, Text } from '@tarojs/components'
import React from 'react'
import './pesudo.scss'
import { View, Text } from "@tarojs/components";
import React from "react";
import "./pesudo.scss";

export default function Pesudo() {
return <View>
<View className='a' compileMode></View>
<View className='a'></View>
</View>
return (
<View>
<View className='a' compileMode></View>
<View className='a'></View>
<View className='w-[300px] h-[50px] p-2 bg-[rgba(0,0,0,0.5)]'></View>
</View>
);
}
22 changes: 22 additions & 0 deletions __test__/fixure/pesudo.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
.a {
box-shadow: 0px 0px rgba(0, 0, 0, 0.04);
transform: translate(0, 0) rotate(0) skewX(0) skewY(0) scaleX(1) scaleY(1);
color: var(--primary-color);
}

.gap-4 {
gap: 16px;
}

.w-\[300px\] {
width: 300px
}

.h-\[50px\] {
width: 300px
}

.p-2 {
padding: 8px;
}

.bg-\[rgba\(0\2c 0\2c 0\2c 0\.5\)\] {
background-color: rgba(0,0,0,0.5);
}
2 changes: 2 additions & 0 deletions src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ pub const NESTING_STYLE: &'static str = "__nesting_style__";
pub const COMBINE_NESTING_STYLE: &'static str = "__combine_nesting_style__";
pub const NESTINT_STYLE_DATA: &'static str = "__nesting_style_data__";
pub const ENV_FUN: &'static str = "__env__";
pub const VAR_FUN: &'static str = "__var__";
pub const GLOBAL_SHARED: &'static str = "__global_shared__";

// pub const CALC_DYMAMIC_STYLE: &'static str = "calcDynamicStyle";
pub const CALC_STATIC_STYLE: &'static str = "calcStaticStyle";
Expand Down
11 changes: 7 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ use style_parser::StyleParser;
use style_propetries::unit::Platform;

use swc_core::{
ecma::codegen::{text_writer::JsWriter, Emitter},
common::{comments::SingleThreadedComments, sync::Lrc, SourceMap}
common::{comments::SingleThreadedComments, sync::Lrc, SourceMap}, ecma::{ast::Bool, codegen::{text_writer::JsWriter, Emitter}}
};
use crate::{document::JSXDocument, style_write::StyleWrite};

Expand All @@ -32,7 +31,8 @@ mod parse_style_properties;
#[napi(object)]
#[derive(Deserialize)]
pub struct ParseOptions {
pub platform_string: String
pub platform_string: String,
pub is_entry: bool
}

#[napi(object)]
Expand All @@ -49,6 +49,8 @@ pub fn parse(component: String, styles: Vec<String>, options: ParseOptions) -> P
_ => Platform::Harmony
};

let is_entry = options.is_entry || false;

let mut is_enable_nesting = true;

// 解析组件文件
Expand All @@ -59,7 +61,7 @@ pub fn parse(component: String, styles: Vec<String>, options: ParseOptions) -> P

// 解析样式文件
let css = styles.join("\n");
let mut style_parser = StyleParser::new(&document, platform.clone());
let mut style_parser = StyleParser::new(&document, platform.clone(), is_entry.clone());
style_parser.parse(&css);
let style_data = style_parser.calc();

Expand All @@ -76,6 +78,7 @@ pub fn parse(component: String, styles: Vec<String>, options: ParseOptions) -> P
style_data.pesudo_style_record.clone(),
style_data.all_style.clone(),
is_enable_nesting,
is_entry,
);
style_write.write(platform, document.taro_components.clone());

Expand Down
5 changes: 3 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub fn main() {
let css = fs::read_to_string("__test__/fixure/pesudo.scss").unwrap();

let platform = Platform::Harmony;

let is_entry = false; // 是否是入口文件
let mut is_enable_nesting = true;

// 解析组件文件
Expand All @@ -40,7 +40,7 @@ pub fn main() {
document.parse(component, cm.clone(), &comments);

// 解析样式文件
let mut style_parser = StyleParser::new(&document, platform.clone());
let mut style_parser = StyleParser::new(&document, platform.clone(), is_entry.clone());
style_parser.parse(&css);
let style_data = style_parser.calc();

Expand All @@ -57,6 +57,7 @@ pub fn main() {
style_data.pesudo_style_record.clone(),
style_data.all_style.clone(),
is_enable_nesting,
is_entry
);
style_write.write(platform, document.taro_components.clone());

Expand Down
31 changes: 30 additions & 1 deletion src/parse_style_properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use lightningcss::{properties::{custom::TokenOrValue, Property}, stylesheet::Pri
use swc_core::{common::DUMMY_SP, ecma::{ast::{self}, utils::quote_ident}};
use swc_core::ecma::ast::*;

use crate::{constants::ENV_FUN, style_parser::KeyFrameItem, style_propetries::{animation::Animation, aspect_ratio::AspactRatio, background::Background, background_image::BackgroundImage, background_position::BackgroundPosition, background_repeat::BackgroundRepeat, background_size::BackgroundSize, border::Border, border_color::BorderColor, border_radius::BorderRadius, border_style::BorderStyle, border_width::BorderWidth, box_shadow::BoxShadow, color::ColorProperty, display::Display, expr::Expr, flex::Flex, flex_align::FlexAlign, flex_basis::FlexBasis, flex_direction::FlexDirection, flex_wrap::FlexWrap, font_size::FontSize, font_style::FontStyle, font_weight::FontWeight, gap::Gap, item_align::ItemAlign, length_value::LengthValueProperty, letter_spacing::LetterSpacing, line_height::LineHeight, marin_padding::MarginPadding, max_size::MaxSizeProperty, normal::Normal, number::NumberProperty, overflow::Overflow, size::SizeProperty, style_value_type::StyleValueType, text_align::TextAlign, text_decoration::TextDecoration, text_overflow::TextOverflow, text_shadow::TextShadow, text_transform::TextTransform, transform::Transform, transform_origin::TransformOrigin, unit::{generate_expr_by_length_value, Platform}, vertical_align::VerticalAlign}};
use crate::{constants::ENV_FUN, constants::VAR_FUN, style_parser::KeyFrameItem, style_propetries::{animation::Animation, aspect_ratio::AspactRatio, background::Background, background_image::BackgroundImage, background_position::BackgroundPosition, background_repeat::BackgroundRepeat, background_size::BackgroundSize, border::Border, border_color::BorderColor, border_radius::BorderRadius, border_style::BorderStyle, border_width::BorderWidth, box_shadow::BoxShadow, color::ColorProperty, display::Display, expr::Expr, flex::Flex, flex_align::FlexAlign, flex_basis::FlexBasis, flex_direction::FlexDirection, flex_wrap::FlexWrap, font_size::FontSize, font_style::FontStyle, font_weight::FontWeight, gap::Gap, item_align::ItemAlign, length_value::LengthValueProperty, letter_spacing::LetterSpacing, line_height::LineHeight, marin_padding::MarginPadding, max_size::MaxSizeProperty, normal::Normal, number::NumberProperty, overflow::Overflow, size::SizeProperty, style_value_type::StyleValueType, text_align::TextAlign, text_decoration::TextDecoration, text_overflow::TextOverflow, text_shadow::TextShadow, text_transform::TextTransform, transform::Transform, transform_origin::TransformOrigin, unit::{generate_expr_by_length_value, Platform}, vertical_align::VerticalAlign}};

pub fn parse_style_properties(properties: &Vec<(String, Property)>, keyframes_map: Option<Rc<RefCell<HashMap<String, Vec<KeyFrameItem>>>>>) -> Vec<StyleValueType> {
let mut final_properties = vec![];
Expand Down Expand Up @@ -44,6 +44,35 @@ pub fn parse_style_properties(properties: &Vec<(String, Property)>, keyframes_ma
type_args: None
}))));
},
TokenOrValue::Var(env) => {
is_env = true;
let mut args = vec![
ExprOrSpread {
spread: None,
expr: Box::new(ast::Expr::Lit(Lit::Str(env.name.to_css_string(PrinterOptions::default()).unwrap().into())))
}
];
// env.name.to_css_string(PrinterOptions::default()).unwrap()))
if env.fallback.is_some() {
let fallback = env.fallback.as_ref().unwrap().0.get(0);
if let Some(token) = fallback {
if let TokenOrValue::Length(length) = token {
args.push(
ExprOrSpread {
spread: None,
expr: Box::new(generate_expr_by_length_value(length, Platform::Harmony))
}
)
}
}
}
final_properties.push(StyleValueType::Expr(Expr::new(id.to_string(), ast::Expr::Call(CallExpr {
span: DUMMY_SP,
callee: Callee::Expr(Box::new(ast::Expr::Ident(quote_ident!(VAR_FUN)))),
args: args,
type_args: None
}))));
},
_ => {}
}
});
Expand Down
19 changes: 12 additions & 7 deletions src/style_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::{rc::Rc, cell::RefCell, convert::Infallible, collections::HashMap, hash

use lightningcss::{declaration::DeclarationBlock, properties::Property, rules::{keyframes::KeyframeSelector, CssRule}, stylesheet::{ParserOptions, PrinterOptions, StyleSheet}, traits::ToCss, visit_types, visitor::{Visit, VisitTypes, Visitor}};

use crate::{constants::SUPPORT_PSEUDO_KEYS, document::JSXDocument, style_propetries::{style_value_type::StyleValueType, unit::Platform}, utils::to_camel_case, visitor::SpanKey};
use crate::{constants::SUPPORT_PSEUDO_KEYS, document::JSXDocument, style_propetries::{style_value_type::StyleValueType, unit::Platform}, utils::{is_tailwind_arbitrary, to_camel_case}, visitor::SpanKey};

use super::parse_style_properties::parse_style_properties;

Expand Down Expand Up @@ -58,9 +58,11 @@ impl<'i> Visitor<'i> for StyleVisitor<'i> {
// 属性规则收集
CssRule::Style(style) => {
let selectors_str = style.selectors.to_string();
let selectors: Vec<&str> = selectors_str.split(",").collect::<Vec<&str>>();
// FEATURE: 按照,分割选择器,且保证,前面不是转义字符,以支持 tailwind.css 动态类名
let selectors: Vec<&str> = selectors_str.split("(?<!\\\\),").collect::<Vec<&str>>();
for index in 0..selectors.len() {
let selector = selectors[index].trim().to_string();
// FEATURE: 优化 key 的生成 移除 key 中的 \\ 转义,以支持 tailwind.css 动态类名匹配
let selector = selectors[index].trim().to_string().replace("\\", "");
let mut all_style = self.all_style.borrow_mut();
let decorations = all_style.iter_mut().find(|(id, _)| id == &selector);
if let Some((_, declarations)) = decorations {
Expand Down Expand Up @@ -132,16 +134,18 @@ pub struct StyleParser<'i> {
pub all_style: Rc<RefCell<Vec<(String, Vec<StyleDeclaration<'i>>)>>>,
pub keyframes: Rc<RefCell<HashMap<String, Vec<KeyFrameItem>>>>,
pub document: &'i JSXDocument,
pub platform: Platform
pub platform: Platform,
pub is_entry: bool
}

impl<'i> StyleParser<'i> {
pub fn new(document: &'i JSXDocument, platform:Platform) -> Self {
pub fn new(document: &'i JSXDocument, platform:Platform, is_entry: bool) -> Self {
StyleParser {
all_style: Rc::new(RefCell::new(vec![])),
keyframes: Rc::new(RefCell::new(HashMap::new())),
document,
platform
platform,
is_entry
}
}

Expand Down Expand Up @@ -191,7 +195,8 @@ impl<'i> StyleParser<'i> {
})
.collect::<Vec<(_, _)>>(); // Specify the lifetime of the tuple elements to match the input data
// 判断是否含有嵌套选择器
if selector.contains(" ") || selector.chars().filter(|&c| c == '.').count() > 1 {
// FEATURE: 此处会误判,比如 tailwind 动态样式中 bg-[rgba(0,0,0,0.5)]
if selector.contains(" ") || (selector.chars().filter(|&c| c == '.').count() > 1 && !is_tailwind_arbitrary(&selector)) {
has_nesting = true
}
final_all_style.push((selector.to_owned(), properties));
Expand Down
22 changes: 16 additions & 6 deletions src/style_propetries/transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,14 +159,24 @@ impl From<(String, &Property<'_>)> for Transform {
transform.push(Matrix4::Scales(scale));
}
LNTransform::ScaleX(x) => {
let mut scale = Scale::new();
scale.x = Some(x.clone());
transform.push(Matrix4::Scales(scale));
// 如果 transform 已经存在 scale 则不再添加,直接取出已经存在的 scale 进行修改
if let Some(Matrix4::Scales(scale)) = transform.iter_mut().find(|m| matches!(m, Matrix4::Scales(_))) {
scale.x = Some(x.clone());
} else {
let mut scale = Scale::new();
scale.x = Some(x.clone());
transform.push(Matrix4::Scales(scale));
}
}
LNTransform::ScaleY(y) => {
let mut scale = Scale::new();
scale.x = Some(y.clone());
transform.push(Matrix4::Scales(scale));
// 如果 transform 已经存在 scale 则不再添加,直接取出已经存在的 scale 进行修改
if let Some(Matrix4::Scales(scale)) = transform.iter_mut().find(|m| matches!(m, Matrix4::Scales(_))) {
scale.y = Some(y.clone());
} else {
let mut scale = Scale::new();
scale.y = Some(y.clone());
transform.push(Matrix4::Scales(scale));
}
}
LNTransform::ScaleZ(z) => {
let mut scale = Scale::new();
Expand Down
7 changes: 5 additions & 2 deletions src/style_write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub struct StyleWrite<'i> {
pub pesudo_style_record: Rc<RefCell<HashMap<SpanKey, Vec<(String, Vec<(String, Property<'i>)>)>>>>,
pub all_style: Rc<RefCell<HashMap<String, StyleValue>>>,
pub is_enable_nesting: bool,
pub is_entry: bool,
}

impl<'i> StyleWrite<'i> {
Expand All @@ -25,14 +26,16 @@ impl<'i> StyleWrite<'i> {
jsx_record: Rc<RefCell<JSXRecord>>,
pesudo_style_record: Rc<RefCell<HashMap<SpanKey, Vec<(String, Vec<(String, Property<'i>)>)>>>>,
all_style: Rc<RefCell<HashMap<String, StyleValue>>>,
is_enable_nesting: bool
is_enable_nesting: bool,
is_entry: bool,
) -> Self {
StyleWrite {
module,
jsx_record,
pesudo_style_record,
all_style,
is_enable_nesting,
is_entry,
}
}

Expand All @@ -54,7 +57,7 @@ impl<'i> StyleWrite<'i> {
}
// 插入样式表
{
let mut insert_mut_visitor = ModuleMutVisitor::new(self.all_style.clone(),platform.clone(), self.is_enable_nesting);
let mut insert_mut_visitor = ModuleMutVisitor::new(self.all_style.clone(),platform.clone(), self.is_enable_nesting, self.is_entry);
self
.module
.borrow_mut()
Expand Down
10 changes: 10 additions & 0 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,11 @@ pub fn split_selector(selector: &str) -> Vec<TSelector> {

// 分割类名 .a.b.c => ["a", "b", "c"]
fn split_classes(input: &str) -> TSelector {
// 如果是 tailwindcss 的任意类,进行如下转换 例如:.bg-[rgba(0,0,0,0.5)] => bg-[rgba(0,0,0,0.5)] , .w-[100px] => w-[100px]
if is_tailwind_arbitrary(input) {
return TSelector::String(input[1..].to_string());
}

let mut matches = Vec::new();
let mut current_class = String::new();
for char in input.chars() {
Expand All @@ -222,3 +227,8 @@ fn split_classes(input: &str) -> TSelector {
TSelector::String(input.replace(".", ""))
}
}

// 是否是 tailwind.css 的任意值类名
pub fn is_tailwind_arbitrary(input: &str) -> bool {
input.contains('[') && input.contains(']')
}
Loading