Beginnings of at-rule parsing
This commit is contained in:
parent
6a4c68a833
commit
de742425d0
@ -1,25 +1,44 @@
|
|||||||
use cssparser::{
|
use cssparser::{
|
||||||
AtRuleParser, CowRcStr, DeclarationListParser, DeclarationParser, ParseError, Parser,
|
AtRuleParser, AtRuleType, CowRcStr, DeclarationListParser, DeclarationParser, ParseError, Parser,
|
||||||
ParserInput, QualifiedRuleParser, RuleListParser, SourceLocation,
|
ParserInput, QualifiedRuleParser, RuleListParser, SourceLocation,
|
||||||
};
|
};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::convert::Into;
|
use std::convert::Into;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum CssRule {
|
||||||
|
AtRule(CssAtRule),
|
||||||
|
StyleRule(CssStyleRule),
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: try to use CowRcStr instead of Strings in these structs.
|
// TODO: try to use CowRcStr instead of Strings in these structs.
|
||||||
// I tried to do it earlier but I ended up in lifetime hell in parse_block().
|
// I tried to do it earlier but I ended up in lifetime hell in parse_block().
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CssRule {
|
pub struct CssStyleRule {
|
||||||
pub selectors: String,
|
pub selectors: String,
|
||||||
pub declarations: Vec<CssDeclaration>,
|
pub declarations: Vec<CssDeclaration>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct CssAtRule {
|
||||||
|
// TODO: put name into the string cache
|
||||||
|
pub name: String,
|
||||||
|
pub prelude: String,
|
||||||
|
pub block: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CssDeclaration {
|
pub struct CssDeclaration {
|
||||||
pub property: String,
|
pub property: String,
|
||||||
pub value: String,
|
pub value: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct CssAtRulePrelude {
|
||||||
|
name: String,
|
||||||
|
prelude: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum CssError {}
|
pub enum CssError {}
|
||||||
|
|
||||||
@ -28,10 +47,60 @@ pub type CssParseError<'i> = ParseError<'i, CssError>;
|
|||||||
struct CssParser;
|
struct CssParser;
|
||||||
|
|
||||||
impl<'i> AtRuleParser<'i> for CssParser {
|
impl<'i> AtRuleParser<'i> for CssParser {
|
||||||
type PreludeBlock = ();
|
type PreludeBlock = CssAtRulePrelude;
|
||||||
type PreludeNoBlock = ();
|
type PreludeNoBlock = CssAtRulePrelude;
|
||||||
type AtRule = CssRule;
|
type AtRule = CssRule;
|
||||||
type Error = CssError;
|
type Error = CssError;
|
||||||
|
|
||||||
|
fn parse_prelude<'t>(
|
||||||
|
&mut self,
|
||||||
|
name: CowRcStr<'i>,
|
||||||
|
input: &mut Parser<'i, 't>,
|
||||||
|
) -> Result<AtRuleType<Self::PreludeNoBlock, Self::PreludeBlock>, CssParseError<'i>> {
|
||||||
|
let position = input.position();
|
||||||
|
while input.next().is_ok() {}
|
||||||
|
match_ignore_ascii_case! { &*name,
|
||||||
|
"import" | "namespace" | "charset" => {
|
||||||
|
Ok(AtRuleType::WithoutBlock(CssAtRulePrelude {
|
||||||
|
name: name.to_string(),
|
||||||
|
prelude: input.slice_from(position).to_string(),
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
Ok(AtRuleType::WithBlock(CssAtRulePrelude {
|
||||||
|
name: name.to_string(),
|
||||||
|
prelude: input.slice_from(position).to_string(),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_block<'t>(
|
||||||
|
&mut self,
|
||||||
|
prelude: Self::PreludeBlock,
|
||||||
|
_location: SourceLocation,
|
||||||
|
input: &mut Parser<'i, 't>
|
||||||
|
) -> Result<Self::AtRule, CssParseError<'i>> {
|
||||||
|
let position = input.position();
|
||||||
|
while input.next().is_ok() {}
|
||||||
|
Ok(CssRule::AtRule(CssAtRule {
|
||||||
|
name: prelude.name,
|
||||||
|
prelude: prelude.prelude,
|
||||||
|
block: Some(input.slice_from(position).to_string()),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rule_without_block(
|
||||||
|
&mut self,
|
||||||
|
prelude: Self::PreludeNoBlock,
|
||||||
|
_location: SourceLocation
|
||||||
|
) -> Self::AtRule {
|
||||||
|
CssRule::AtRule(CssAtRule {
|
||||||
|
name: prelude.name,
|
||||||
|
prelude: prelude.prelude,
|
||||||
|
block: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'i> QualifiedRuleParser<'i> for CssParser {
|
impl<'i> QualifiedRuleParser<'i> for CssParser {
|
||||||
@ -54,10 +123,10 @@ impl<'i> QualifiedRuleParser<'i> for CssParser {
|
|||||||
_location: SourceLocation,
|
_location: SourceLocation,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<CssRule, CssParseError<'i>> {
|
) -> Result<CssRule, CssParseError<'i>> {
|
||||||
Ok(CssRule {
|
Ok(CssRule::StyleRule(CssStyleRule {
|
||||||
selectors,
|
selectors,
|
||||||
declarations: parse_declarations(input).unwrap(),
|
declarations: parse_declarations(input).unwrap(),
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
22
src/main.rs
22
src/main.rs
@ -5,6 +5,7 @@ extern crate lazy_static;
|
|||||||
extern crate html5ever;
|
extern crate html5ever;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate maplit;
|
extern crate maplit;
|
||||||
|
#[macro_use]
|
||||||
extern crate cssparser;
|
extern crate cssparser;
|
||||||
extern crate string_cache;
|
extern crate string_cache;
|
||||||
extern crate typed_arena;
|
extern crate typed_arena;
|
||||||
@ -30,7 +31,7 @@ mod css_parser;
|
|||||||
use arena_dom::{create_element, html5ever_parse_slice_into_arena, Arena, NodeData, Ref};
|
use arena_dom::{create_element, html5ever_parse_slice_into_arena, Arena, NodeData, Ref};
|
||||||
use config::permissive::{ADD_ATTRIBUTES, ALL_ATTRIBUTES, ATTRIBUTES, ELEMENTS, PROTOCOLS};
|
use config::permissive::{ADD_ATTRIBUTES, ALL_ATTRIBUTES, ATTRIBUTES, ELEMENTS, PROTOCOLS};
|
||||||
use config::relaxed::CSS_PROPERTIES;
|
use config::relaxed::CSS_PROPERTIES;
|
||||||
use css_parser::{parse_css_style_attribute, parse_css_stylesheet};
|
use css_parser::{CssRule, parse_css_style_attribute, parse_css_stylesheet};
|
||||||
use css_property::CssProperty;
|
use css_property::CssProperty;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@ -91,9 +92,11 @@ fn transform_node<'arena>(node: Ref<'arena>, arena: Arena<'arena>) {
|
|||||||
dbg!(&rules);
|
dbg!(&rules);
|
||||||
let mut sanitized_css = String::new();
|
let mut sanitized_css = String::new();
|
||||||
for rule in rules {
|
for rule in rules {
|
||||||
sanitized_css += &rule.selectors.trim();
|
match rule {
|
||||||
|
CssRule::StyleRule(style_rule) => {
|
||||||
|
sanitized_css += &style_rule.selectors.trim();
|
||||||
sanitized_css += " {\n";
|
sanitized_css += " {\n";
|
||||||
for declaration in rule.declarations.into_iter() {
|
for declaration in style_rule.declarations.into_iter() {
|
||||||
let declaration_string = &declaration.to_string();
|
let declaration_string = &declaration.to_string();
|
||||||
if CSS_PROPERTIES
|
if CSS_PROPERTIES
|
||||||
.contains(&CssProperty::from(declaration.property))
|
.contains(&CssProperty::from(declaration.property))
|
||||||
@ -104,6 +107,19 @@ fn transform_node<'arena>(node: Ref<'arena>, arena: Arena<'arena>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
sanitized_css += "\n}";
|
sanitized_css += "\n}";
|
||||||
|
},
|
||||||
|
CssRule::AtRule(at_rule) => {
|
||||||
|
dbg!(&at_rule);
|
||||||
|
sanitized_css += &format!("@{} ", at_rule.name);
|
||||||
|
sanitized_css += &at_rule.prelude.trim();
|
||||||
|
if let Some(block) = at_rule.block {
|
||||||
|
sanitized_css += " {\n";
|
||||||
|
sanitized_css += &block.trim();
|
||||||
|
sanitized_css += "\n}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sanitized_css += "\n";
|
||||||
}
|
}
|
||||||
let sanitized_css = sanitized_css.trim();
|
let sanitized_css = sanitized_css.trim();
|
||||||
dbg!(&sanitized_css);
|
dbg!(&sanitized_css);
|
||||||
|
Loading…
Reference in New Issue
Block a user