Skip to content

Commit

Permalink
Merge pull request #178 from wechat-miniprogram/feat-host-selector-wa…
Browse files Browse the repository at this point in the history
…rnings

fix: `:host` style warnings
  • Loading branch information
LastLeaf authored Jul 10, 2024
2 parents 0f9698f + bc8159c commit 0490833
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 15 deletions.
27 changes: 26 additions & 1 deletion glass-easel-miniprogram-webpack-plugin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { promises as fs } from 'node:fs'
import * as path from 'node:path'
import { NormalModule, type Compiler, type WebpackPluginInstance } from 'webpack'
import chalk from 'chalk'
import { TmplGroup } from 'glass-easel-template-compiler'
import { escapeJsString } from './helpers'

Expand All @@ -11,6 +12,18 @@ type VirtualModulePluginType = {
writeModule: (p: string, c: string) => void
}

type Warning = {
isError: boolean
level: number
code: number
message: string
path: string
startLine: number
startColumn: number
endLine: number
endColumn: number
}

// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const chokidar = require('chokidar')
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
Expand Down Expand Up @@ -423,7 +436,19 @@ export class GlassEaselMiniprogramWebpackPlugin implements WebpackPluginInstance
x.options = {
addTemplate(content: string) {
wxmlContentMap[compPath] = content
depsTmplGroup.addTmpl(compPath, content)
const warnings = depsTmplGroup.addTmpl(compPath, content) as Warning[]
if (warnings && warnings.length > 0) {
warnings.forEach((warning) => {
const msgKindColored = warning.isError
? chalk.red('ERROR')
: chalk.yellow('WARN')
const msg = `[glass-easel-template-compiler] ${msgKindColored} ${warning.path}:${warning.startLine}:${warning.startColumn} (#${warning.code}): ${warning.message}`
// eslint-disable-next-line no-console
if (warning.isError) console.error(msg)
// eslint-disable-next-line no-console
else console.warn(msg)
})
}
const deps = depsTmplGroup
.getDirectDependencies(compPath)
.concat(depsTmplGroup.getScriptDependencies(compPath))
Expand Down
1 change: 1 addition & 0 deletions glass-easel-miniprogram-webpack-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"webpack": "^5.85.0"
},
"dependencies": {
"chalk": "4",
"chokidar": "^3.5.3",
"glass-easel-stylesheet-compiler": "workspace:*",
"glass-easel-template-compiler": "workspace:*",
Expand Down
12 changes: 12 additions & 0 deletions glass-easel-miniprogram-webpack-plugin/wxss_loader.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable */

const chalk = require('chalk')
const { SourceMapGenerator, SourceMapConsumer } = require('source-map')
const { StyleSheetTransformer } = require('glass-easel-stylesheet-compiler')

Expand All @@ -8,6 +9,17 @@ module.exports = function (src, prevMap, meta) {
const { classPrefix, compPath, setLowPriorityStyles } = this.query
const sst = new StyleSheetTransformer(this.resourcePath, src, classPrefix, 750, compPath)
setLowPriorityStyles(sst.getLowPriorityContent(), sst.getLowPrioritySourceMap())
const warnings = sst.extractWarnings()
if (warnings && warnings.length > 0) {
warnings.forEach((warning) => {
const msgKindColored = warning.isError
? chalk.red('ERROR')
: chalk.yellow('WARN')
const msg = `[glass-easel-stylesheet-compiler] ${msgKindColored} ${warning.path}:${warning.startLine}:${warning.startColumn} (#${warning.code}): ${warning.message}`
if (warning.isError) console.error(msg)
else console.warn(msg)
})
}
const ss = sst.getContent()
let map
if (this.sourceMap) {
Expand Down
61 changes: 52 additions & 9 deletions glass-easel-stylesheet-compiler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -432,22 +432,28 @@ fn parse_qualified_rule(input: &mut StepParser, ss: &mut StyleSheetTransformer)
let quoted_host_is = Token::QuotedString(host_is.clone().into());
let r = input.try_parse::<_, _, ParseError<()>>(|input| {
input.expect_colon()?;
input.expect_ident_matching("host")?;
let mut invalid = false;
let Ok(next) = input.next() else { return Ok(()) };
let mut invalid = match &*next {
Token::Ident(x) if x.as_bytes() == b"host" => None,
Token::Function(x) if x.as_bytes() == b"host" => Some(input.position()),
_ => { return Err(input.new_custom_error(())) }
};
let next = loop {
let Ok(next) = input.next() else { return Ok(()) };
if *next != Token::CurlyBracketBlock {
invalid = true;
let pos = input.position();
ss.add_warning(
error::ParseErrorKind::HostSelectorCombination,
pos..pos,
);
if invalid.is_none() {
invalid = Some(input.position());
}
} else {
break next;
}
};
if !invalid {
if let Some(pos) = invalid {
ss.add_warning(
error::ParseErrorKind::HostSelectorCombination,
pos..pos,
);
} else {
ss.write_in_low_priority(input, |ss, input| {
ss.append_token(StepToken::wrap_at(Token::SquareBracketBlock, &next), input, None);
ss.append_token(StepToken::wrap_at(Token::Ident("is".into()), &next), input, None);
Expand Down Expand Up @@ -883,6 +889,43 @@ mod test {
);
}

#[test]
fn illegal_host_combination() {
let trans = StyleSheetTransformer::from_css(
"",
r#"
:host(.a) {
color: red;
}
:host .a {
color: red;
}
.a { color: green }
"#,
StyleSheetOptions {
host_is: Some("TEST".to_string()),
..Default::default()
},
);
assert_eq!(
trans.warnings().map(|x| x.kind.clone()).collect::<Vec<_>>(),
[error::ParseErrorKind::HostSelectorCombination, error::ParseErrorKind::HostSelectorCombination],
);
let (output, lp) = trans.output_and_low_priority_output();
let mut s = Vec::new();
output.write(&mut s).unwrap();
assert_eq!(
std::str::from_utf8(&s).unwrap(),
r#".a{color:green}"#
);
let mut s = Vec::new();
lp.write(&mut s).unwrap();
assert_eq!(
std::str::from_utf8(&s).unwrap(),
r#""#
);
}

#[test]
fn host_select_inside_at_rules() {
let trans = StyleSheetTransformer::from_css(
Expand Down
8 changes: 3 additions & 5 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 0490833

Please sign in to comment.