Skip to content

Commit

Permalink
Add basic printing to DOM element filter
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielleHuisman committed Sep 8, 2024
1 parent 50e22e5 commit 7d64ae9
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 26 deletions.
3 changes: 3 additions & 0 deletions packages/dom/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ regex.workspace = true
thiserror.workspace = true
wasm-bindgen.workspace = true
web-sys = { workspace = true, features = [
"Comment",
"Document",
"DocumentFragment",
"Element",
"HtmlCollection",
"HtmlElement",
Expand All @@ -26,6 +28,7 @@ web-sys = { workspace = true, features = [
"HtmlOptionsCollection",
"HtmlSelectElement",
"NodeList",
"Text",
"Window",
] }

Expand Down
158 changes: 149 additions & 9 deletions packages/dom/src/dom_element_filter.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,94 @@
use pretty_format::{Config, Plugin, Printer, Refs};
use regex::Regex;
use wasm_bindgen::{JsCast, JsValue};
use web_sys::{Element, Node};
use web_sys::{Comment, Element, Node, Text};

fn escape_html(text: String) -> String {
text.replace('<', "&lt;").replace('>', "&gt;")
}

fn print_props(
_config: &Config,
_indentation: String,
_depth: usize,
_refs: &Refs,
_printer: &Printer,
) -> String {
todo!()
}

fn print_children(
_config: &Config,
_indentation: String,
_depth: usize,
_refs: &Refs,
_printer: &Printer,
) -> String {
todo!()
}

fn print_text(text: String, config: &Config) -> String {
let content_color = config.colors.content;
content_color.paint(&escape_html(text))
}

fn print_comment(text: String, config: &Config) -> String {
let comment_color = config.colors.comment;
comment_color.paint(&format!("<!--{}-->", escape_html(text)))
}

fn print_element(
r#type: String,
printed_props: String,
printed_children: String,
config: Config,
indentation: String,
) -> String {
let tag_color = config.colors.tag;

tag_color.paint(&format!(
"<{}{}{}>",
r#type,
if printed_props.is_empty() {
"".into()
} else {
format!(
"{}{}{}{}{}",
tag_color.close(),
printed_props,
config.spacing_outer,
indentation,
tag_color.open()
)
},
if printed_children.is_empty() {
if !printed_props.is_empty() && !config.min {
"/".into()
} else {
" /".into()
}
} else {
format!(
">{}{}{}{}{}</{}",
tag_color.close(),
printed_children,
config.spacing_outer,
indentation,
tag_color.open(),
r#type
)
}
))
}

fn print_element_as_leaf(r#type: String, config: &Config) -> String {
let tag_color = config.colors.tag;
format!(
"{} …{}",
tag_color.paint(&format!("<{}", r#type)),
tag_color.paint(" />")
)
}

fn is_custom_element(val: &JsValue) -> bool {
val.dyn_ref::<Element>()
Expand All @@ -14,7 +101,7 @@ fn test_node(val: &JsValue) -> bool {
let node_type = node.node_type();

(node_type == Node::ELEMENT_NODE
&& Regex::new(r"")
&& Regex::new(r"^((HTML|SVG)\w*)?Element$")
.expect("Regex should be valid.")
.is_match(&constructor_name)
|| is_custom_element(val))
Expand All @@ -24,6 +111,18 @@ fn test_node(val: &JsValue) -> bool {
})
}

fn node_is_text(node: &Node) -> bool {
node.node_type() == Node::TEXT_NODE
}

fn node_is_comment(node: &Node) -> bool {
node.node_type() == Node::COMMENT_NODE
}

fn node_is_fragment(node: &Node) -> bool {
node.node_type() == Node::DOCUMENT_FRAGMENT_NODE
}

pub struct DomElementFilter {}

impl DomElementFilter {
Expand All @@ -39,13 +138,54 @@ impl Plugin for DomElementFilter {

fn serialize(
&self,
_val: &JsValue,
_config: Config,
_indentation: String,
_depth: usize,
_refs: Refs,
_printer: &Printer,
val: &JsValue,
config: Config,
indentation: String,
depth: usize,
refs: Refs,
printer: &Printer,
) -> String {
todo!()
let node: &Node = val.unchecked_ref();

if node_is_text(node) {
return print_text(node.unchecked_ref::<Text>().data(), &config);
}

if node_is_comment(node) {
return print_comment(node.unchecked_ref::<Comment>().data(), &config);
}

let r#type = if node_is_fragment(node) {
"DocumentFragment".into()
} else {
node.unchecked_ref::<Element>().tag_name().to_lowercase()
};

let depth = depth + 1;
if depth > config.max_depth {
return print_element_as_leaf(r#type, &config);
}

print_element(
r#type,
print_props(
// TODO: props,
&config,
format!("{}{}", indentation, &config.indent),
depth,
&refs,
printer,
),
print_children(
// TODO: children,
&config,
format!("{}{}", indentation, &config.indent),
depth,
&refs,
printer,
),
config,
indentation,
)
}
}
46 changes: 29 additions & 17 deletions packages/pretty-format/src/types.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,46 @@
use std::rc::Rc;

use ansi_style::{Style, StyleBuilder};
use ansi_style::Color;
use wasm_bindgen::JsValue;

#[derive(Debug, Default)]
#[derive(Debug)]
pub struct Colors {
pub comment: Style,
pub content: Style,
pub prop: Style,
pub tag: Style,
pub value: Style,
pub comment: Color,
pub content: Color,
pub prop: Color,
pub tag: Color,
pub value: Color,
}

impl Default for Colors {
fn default() -> Self {
Self {
comment: Color::Any,
content: Color::Any,
prop: Color::Any,
tag: Color::Any,
value: Color::Any,
}
}
}

#[derive(Clone, Debug)]
pub struct Theme {
pub comment: Style,
pub content: Style,
pub prop: Style,
pub tag: Style,
pub value: Style,
pub comment: Color,
pub content: Color,
pub prop: Color,
pub tag: Color,
pub value: Color,
}

impl Default for Theme {
fn default() -> Self {
Self {
comment: StyleBuilder::new().black_bright().build(),
content: StyleBuilder::new().build(),
prop: StyleBuilder::new().yellow().build(),
tag: StyleBuilder::new().cyan().build(),
value: StyleBuilder::new().green().build(),
comment: Color::BlackBright,
content: Color::Any,
prop: Color::Yellow,
tag: Color::Cyan,
value: Color::Green,
}
}
}
Expand Down

0 comments on commit 7d64ae9

Please sign in to comment.