swc_html_parser/parser/
active_formatting_element_stack.rs1use swc_html_ast::Token;
2
3use crate::parser::{is_same_node, RcNode, TokenAndInfo};
4
5#[derive(Debug)]
6pub enum ActiveFormattingElement {
7 Element(RcNode, TokenAndInfo),
8 Marker,
9}
10
11pub struct ActiveFormattingElementStack {
12 pub items: Vec<ActiveFormattingElement>,
13}
14
15impl ActiveFormattingElementStack {
16 pub fn new() -> Self {
17 ActiveFormattingElementStack {
18 items: Vec::with_capacity(8),
19 }
20 }
21
22 pub fn push(&mut self, value: ActiveFormattingElement) {
23 let mut count = 0;
38 let new_element = match &value {
39 ActiveFormattingElement::Element(node, token_and_info) => (node, token_and_info),
40 _ => {
41 unreachable!();
42 }
43 };
44
45 for element in self.items.iter().rev() {
46 let (node_in_element, token_and_info_in_element) = match &element {
47 ActiveFormattingElement::Marker => {
48 break;
49 }
50 ActiveFormattingElement::Element(node, token_and_info) => {
51 if get_namespace!(node) != get_namespace!(new_element.0)
52 || get_tag_name!(node) != get_tag_name!(new_element.0)
53 {
54 continue;
55 }
56
57 (node.clone(), token_and_info)
58 }
59 };
60
61 let attributes_in_element = match &token_and_info_in_element.token {
62 Token::StartTag { attributes, .. } | Token::EndTag { attributes, .. } => attributes,
63 _ => {
64 unreachable!()
65 }
66 };
67 let attributes_in_new_element = match &new_element.1.token {
68 Token::StartTag { attributes, .. } | Token::EndTag { attributes, .. } => attributes,
69 _ => {
70 unreachable!()
71 }
72 };
73
74 if attributes_in_element.len() != attributes_in_new_element.len() {
75 continue;
76 }
77
78 let mut sorted_attributes_in_element = attributes_in_element.clone();
79
80 for attribute in &mut sorted_attributes_in_element {
81 attribute.span = Default::default();
82 }
83
84 let mut sorted_attributes_in_new_element = attributes_in_new_element.clone();
85
86 for attribute in &mut sorted_attributes_in_new_element {
87 attribute.span = Default::default();
88 }
89
90 sorted_attributes_in_element.sort();
91 sorted_attributes_in_new_element.sort();
92
93 if sorted_attributes_in_element != sorted_attributes_in_new_element {
94 continue;
95 }
96
97 count += 1;
98
99 if count == 3 {
100 self.remove(&node_in_element);
101
102 break;
103 }
104 }
105
106 self.items.push(value);
108 }
109
110 pub fn remove(&mut self, node: &RcNode) {
111 let position = self.get_position(node);
112
113 if let Some(position) = position {
114 self.items.remove(position);
115 }
116 }
117
118 pub fn insert_marker(&mut self) {
119 self.items.push(ActiveFormattingElement::Marker);
120 }
121
122 pub fn get_position(&self, element: &RcNode) -> Option<usize> {
123 self.items.iter().position(|n| match *n {
124 ActiveFormattingElement::Marker => false,
125 ActiveFormattingElement::Element(ref handle, _) => is_same_node(handle, element),
126 })
127 }
128
129 pub fn clear_to_last_marker(&mut self) {
130 loop {
131 match self.items.pop() {
132 None | Some(ActiveFormattingElement::Marker) => break,
133 _ => (),
134 }
135 }
136 }
137}