flams_ftml/parser/
nodes.rs

1/*! slightly adapted from [Kuchikiki](https://github.com/brave/kuchikiki) */
2
3use flams_ontology::{narration::notations::OpNotation, DocumentRange};
4use flams_utils::vecmap::VecMap;
5use ftml_extraction::prelude::{FTMLElements, FTMLNode, FTMLTag, NotationSpec};
6use html5ever::{
7    interface::{ElemName, QuirksMode},
8    local_name, ns,
9    serialize::{Serialize, SerializeOpts, TraversalScope},
10    tendril::StrTendril,
11    LocalName, Namespace, QualName,
12};
13use std::{
14    borrow::Borrow,
15    cell::{Cell, RefCell},
16    fmt::Debug,
17    ops::Deref,
18    rc::{Rc, Weak},
19};
20
21#[derive(Debug, PartialEq, Eq, Clone)]
22pub struct Attributes(pub VecMap<QualName, StrTendril>);
23impl Attributes {
24    pub fn len(&self) -> usize {
25        self.0
26            .iter()
27            .map(|(k, v)| {
28                k.prefix
29                    .as_ref()
30                    .map(|e| e.as_bytes().len() + ":".len())
31                    .unwrap_or_default()
32                    + k.local.as_bytes().len()
33                    + " =\"\"".len()
34                    + escaped_len(v, true)
35            })
36            .sum()
37    }
38    pub(crate) fn update(&mut self, tag: FTMLTag, v: &impl ToString) {
39        if let Some((_, a)) = self
40            .0
41             .0
42            .iter_mut()
43            .find(|(k, _)| *k.local == *tag.attr_name())
44        {
45            *a = v.to_string().into();
46        }
47    }
48
49    pub(crate) fn new_attr(&mut self, key: &str, value: String) {
50        self.0.insert(
51            QualName::new(None, Namespace::from(""), LocalName::from(key.to_string())),
52            value.into(),
53        );
54    }
55}
56
57impl From<Vec<html5ever::Attribute>> for Attributes {
58    fn from(value: Vec<html5ever::Attribute>) -> Self {
59        Self(
60            value
61                .into_iter()
62                .map(|html5ever::Attribute { name, value }| (name, value))
63                .collect(),
64        )
65    }
66}
67impl ftml_extraction::prelude::Attributes for Attributes {
68    type KeyIter<'a> = std::iter::Map<
69        std::slice::Iter<'a, (QualName, StrTendril)>,
70        fn(&(QualName, StrTendril)) -> &str,
71    >;
72    type Value<'a> = &'a str;
73    fn keys(&self) -> Self::KeyIter<'_> {
74        self.0 .0.iter().map(|(k, _)| &k.local)
75    }
76    fn value(&self, key: &str) -> Option<Self::Value<'_>> {
77        self.0
78             .0
79            .iter()
80            .find(|(k, _)| &k.local == key)
81            .map(|(_, v)| &**v)
82    }
83    fn set(&mut self, key: &str, value: &str) {
84        if let Some((_, v)) = self.0 .0.iter_mut().find(|(k, _)| &k.local == key) {
85            *v = value.into();
86        }
87    }
88    fn take(&mut self, key: &str) -> Option<String> {
89        //self.value(key).map(|t| t.to_string())
90        let i = self
91            .0
92            .iter()
93            .enumerate()
94            .find_map(|(i, (e, _))| if &e.local == key { Some(i) } else { None })?;
95        let v = self.0.remove_index(i).1;
96        Some(v.to_string())
97    }
98}
99
100/// Node data specific to the node type.
101#[derive(Debug)]
102pub enum NodeData {
103    /// Element node
104    Element(ElementData),
105
106    /// Text node
107    Text(RefCell<StrTendril>),
108
109    /// Comment node
110    Comment(StrTendril),
111
112    /// Processing instruction node
113    ProcessingInstruction(StrTendril, StrTendril),
114
115    /// Doctype node
116    Doctype {
117        name: StrTendril,
118        public_id: StrTendril,
119        system_id: StrTendril,
120    },
121
122    /// Document node
123    Document(Cell<QuirksMode>),
124}
125
126/// Data specific to element nodes.
127pub struct ElementData {
128    /// The namespace and local name of the element, such as `ns!(html)` and `body`.
129    pub name: QualName,
130
131    /// The attributes of the elements.
132    pub attributes: RefCell<Attributes>,
133    pub start_offset: Cell<usize>,
134    pub end_offset: Cell<usize>,
135    pub closed: Cell<bool>,
136    pub ftml: Cell<Option<FTMLElements>>,
137}
138impl Debug for ElementData {
139    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
140        write!(f, "{:?}[{:?}]", self.name, self.attributes)
141    }
142}
143
144#[derive(Clone, Debug)]
145pub struct NodeRef(pub Rc<Node>);
146
147impl FTMLNode for NodeRef {
148    type Ancestors<'a> = Ancestors;
149    #[inline]
150    fn ancestors(&self) -> Self::Ancestors<'_> {
151        Ancestors(Some(self.clone()))
152    }
153    fn with_elements<R>(&mut self, mut f: impl FnMut(Option<&mut FTMLElements>) -> R) -> R {
154        if let Some(elem) = self.as_element() {
155            if let Some(mut e) = elem.ftml.take() {
156                let ret = f(Some(&mut e));
157                elem.ftml.set(Some(e));
158                return ret;
159            }
160        }
161        f(None)
162    }
163
164    #[allow(clippy::cast_possible_wrap)]
165    fn delete(&self) {
166        self.len_update(-(self.len() as isize));
167        let mut p = self.parent();
168        self.detach();
169        /*while let Some(pr) = &mut p {
170            assert_eq!(pr.len(),pr.string().len());
171            p = pr.parent();
172        }*/
173    }
174    #[inline]
175    fn delete_children(&self) {
176        for c in self.children() {
177            c.delete();
178        }
179    }
180    fn range(&self) -> DocumentRange {
181        self.as_element()
182            .map_or(DocumentRange { start: 0, end: 0 }, |elem| {
183                let start = elem.start_offset.get();
184                let end = elem.end_offset.get();
185                DocumentRange { start, end }
186            })
187    }
188    fn inner_range(&self) -> DocumentRange {
189        self.as_element()
190            .map_or(DocumentRange { start: 0, end: 0 }, |elem| {
191                let tag_len = tag_len(&elem.name);
192                let attr_len = elem.attributes.borrow().len();
193                let start = elem.start_offset.get() + tag_len + attr_len;
194                let end = elem.end_offset.get() - (tag_len + 1);
195                DocumentRange { start, end }
196            })
197    }
198    fn string(&self) -> String {
199        let mut html = Vec::new();
200        let _ = html5ever::serialize(
201            &mut html,
202            self,
203            SerializeOpts {
204                traversal_scope: TraversalScope::IncludeNode,
205                ..Default::default()
206            },
207        );
208        String::from_utf8_lossy(&html).into() //from_utf8_lossy_owned(html)
209    }
210    fn inner_string(&self) -> String {
211        let mut html = Vec::new();
212        let _ = html5ever::serialize(
213            &mut html,
214            self,
215            SerializeOpts {
216                traversal_scope: TraversalScope::ChildrenOnly(None),
217                ..Default::default()
218            },
219        );
220        String::from_utf8_lossy(&html).into()
221    }
222
223    #[inline]
224    fn as_notation(&self) -> Option<NotationSpec> {
225        Some(filter_node(self.deep_clone()).do_notation())
226    }
227    #[inline]
228    fn as_op_notation(&self) -> Option<OpNotation> {
229        Some(filter_node(self.deep_clone()).do_op_notation())
230    }
231    #[inline]
232    fn as_term(&self) -> flams_ontology::content::terms::Term {
233        super::termsnotations::filter_node_term(self.clone()).do_term()
234    }
235}
236
237fn filter_node(mut node: NodeRef) -> NodeRef {
238    while let Some(e) = node.as_element() {
239        {
240            use ftml_extraction::prelude::Attributes;
241            let mut attrs = e.attributes.borrow_mut();
242            attrs.remove(FTMLTag::NotationComp);
243            attrs.remove(FTMLTag::NotationOpComp);
244            attrs.remove(FTMLTag::NotationId);
245            attrs.remove(FTMLTag::Term);
246            attrs.remove(FTMLTag::Head);
247        }
248        let num_children = node
249            .children()
250            .filter(|n| n.as_element().is_some() || n.as_text().is_some())
251            .count();
252        if matches!(e.name.local.as_ref(), "math") && num_children == 1 {
253            if let Some(n) = node.children().find(|n| n.as_element().is_some()) {
254                node = n;
255                continue;
256            }
257        }
258        if matches!(e.name.local.as_ref(), "mrow" | "span" | "div")
259            && num_children == 1
260            && node
261                .as_element()
262                .is_some_and(|n| n.attributes.borrow().0 .0.is_empty())
263        {
264            if let Some(n) = node.children().find(|n| n.as_element().is_some()) {
265                node = n;
266                continue;
267            }
268        }
269        break;
270    }
271    node
272}
273
274impl NodeRef {
275    pub(super) fn deep_clone(&self) -> Self {
276        let ret = Self(Rc::new(Node {
277            parent: Cell::new(None),
278            previous_sibling: Cell::new(None),
279            next_sibling: Cell::new(None),
280            first_child: Cell::new(None),
281            last_child: Cell::new(None),
282            data: match &self.data {
283                NodeData::Comment(c) => NodeData::Comment(c.clone()),
284                NodeData::Text(t) => NodeData::Text(t.clone()),
285                NodeData::Document(d) => NodeData::Document(d.clone()),
286                NodeData::Element(e) => NodeData::Element(ElementData {
287                    name: e.name.clone(),
288                    attributes: e.attributes.clone(),
289                    ftml: Cell::new({
290                        let orig = e.ftml.take();
291                        e.ftml.set(orig.clone());
292                        orig
293                    }),
294                    start_offset: e.start_offset.clone(),
295                    end_offset: e.end_offset.clone(),
296                    closed: e.closed.clone(),
297                }),
298                NodeData::ProcessingInstruction(target, data) => {
299                    NodeData::ProcessingInstruction(target.clone(), data.clone())
300                }
301                NodeData::Doctype {
302                    name,
303                    public_id,
304                    system_id,
305                } => NodeData::Doctype {
306                    name: name.clone(),
307                    public_id: public_id.clone(),
308                    system_id: system_id.clone(),
309                },
310            },
311        }));
312        for c in self.children() {
313            match &c.data {
314                NodeData::Comment(_) => continue,
315                NodeData::Text(t) if t.borrow().trim().is_empty() => continue,
316                _ => ret.append(c.deep_clone()),
317            }
318        }
319        ret
320    }
321}
322
323impl Deref for NodeRef {
324    type Target = Node;
325    #[inline]
326    fn deref(&self) -> &Node {
327        &self.0
328    }
329}
330
331impl Eq for NodeRef {}
332impl PartialEq for NodeRef {
333    #[inline]
334    fn eq(&self, other: &Self) -> bool {
335        let a: *const Node = &*self.0;
336        let b: *const Node = &*other.0;
337        a == b
338    }
339}
340
341/// A node inside a DOM-like tree.
342pub struct Node {
343    parent: Cell<Option<Weak<Node>>>,
344    previous_sibling: Cell<Option<Weak<Node>>>,
345    next_sibling: Cell<Option<Rc<Node>>>,
346    first_child: Cell<Option<Rc<Node>>>,
347    last_child: Cell<Option<Weak<Node>>>,
348    data: NodeData,
349}
350impl std::fmt::Debug for Node {
351    #[inline]
352    #[allow(clippy::ref_as_ptr)]
353    fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
354        write!(f, "{:?} @ {:?}", self.data, self as *const Self)
355    }
356}
357impl Drop for Node {
358    fn drop(&mut self) {
359        fn non_recursive_drop_unique_rc(mut rc: Rc<Node>, stack: &mut Vec<Rc<Node>>) {
360            loop {
361                if let Some(child) = rc.first_child.take_if_unique_strong() {
362                    stack.push(rc);
363                    rc = child;
364                    continue;
365                }
366                if let Some(sibling) = rc.next_sibling.take_if_unique_strong() {
367                    // The previous value of `rc: Rc<Node>` is dropped here.
368                    // Since it was unique, the corresponding `Node` is dropped as well.
369                    // `<Node as Drop>::drop` does not call `drop_rc`
370                    // as both the first child and next sibling were already taken.
371                    // Weak reference counts decremented here for `Cell`s that are `Some`:
372                    // * `rc.parent`: still has a strong reference in `stack` or elsewhere
373                    // * `rc.last_child`: this is the last weak ref. Deallocated now.
374                    // * `rc.previous_sibling`: this is the last weak ref. Deallocated now.
375                    rc = sibling;
376                    continue;
377                }
378                if let Some(parent) = stack.pop() {
379                    // Same as in the above comment.
380                    rc = parent;
381                    continue;
382                }
383                return;
384            }
385        }
386        // `.take_if_unique_strong()` temporarily leaves the tree in an inconsistent state,
387        // as the corresponding `Weak` reference in the other direction is not removed.
388        // It is important that all `Some(_)` strong references it returns
389        // are dropped by the end of this `drop` call,
390        // and that no user code is invoked in-between.
391
392        // Sharing `stack` between these two calls is not necessary,
393        // but it allows re-using memory allocations.
394        let mut stack = Vec::new();
395        if let Some(rc) = self.first_child.take_if_unique_strong() {
396            non_recursive_drop_unique_rc(rc, &mut stack);
397        }
398        if let Some(rc) = self.next_sibling.take_if_unique_strong() {
399            non_recursive_drop_unique_rc(rc, &mut stack);
400        }
401    }
402}
403
404impl NodeRef {
405    #[allow(clippy::cast_sign_loss)]
406    #[allow(clippy::cast_possible_wrap)]
407    fn len_update(&self, len: isize) {
408        if let Some(e) = self.as_element() {
409            //assert!((e.end_offset.get() as isize + len) >= e.start_offset.get() as isize);
410            e.end_offset
411                .set(((e.end_offset.get() as isize) + len) as usize);
412        }
413        let mut cur = self.clone();
414        while let Some(n) = cur.next_sibling() {
415            if let Some(e) = n.as_element() {
416                //assert!((e.end_offset.get() as isize + len) >= e.start_offset.get() as isize);
417                e.start_offset
418                    .set(((e.start_offset.get() as isize) + len) as usize);
419                e.end_offset
420                    .set(((e.end_offset.get() as isize) + len) as usize);
421            }
422            cur = n;
423        }
424        if let Some(p) = self.parent() {
425            p.len_update(len);
426        }
427    }
428
429    #[inline]
430    pub fn children(&self) -> Siblings {
431        match (self.first_child(), self.last_child()) {
432            (Some(first_child), Some(last_child)) => Siblings(Some(State {
433                next: first_child,
434                next_back: last_child,
435            })),
436            (None, None) => Siblings(None),
437            _ => unreachable!(),
438        }
439    }
440    pub fn len(&self) -> usize {
441        match &self.data {
442            NodeData::Comment(c) => 0, // c.as_bytes().len() + "<!---->".len(),
443            NodeData::Text(t) => t.borrow().as_bytes().len(),
444            NodeData::Element(e) => e.end_offset.get() - e.start_offset.get(),
445            NodeData::Doctype { name, .. } => "<!DOCTYPE >".len() + name.as_bytes().len(),
446            NodeData::ProcessingInstruction(target, data) => {
447                "<? >".len() + target.as_bytes().len() + data.as_bytes().len()
448            }
449            NodeData::Document(_) => self.children().map(|c| c.len()).sum(),
450        }
451    }
452
453    /// Create a new node.
454    #[inline]
455    pub fn new(data: NodeData) -> Self {
456        Self(Rc::new(Node {
457            parent: Cell::new(None),
458            first_child: Cell::new(None),
459            last_child: Cell::new(None),
460            previous_sibling: Cell::new(None),
461            next_sibling: Cell::new(None),
462            data,
463        }))
464    }
465
466    pub fn update_len(e: &ElementData) {
467        let len = Self::base_len(&e.name) + e.attributes.borrow().len();
468        e.end_offset.set(e.start_offset.get() + len);
469    }
470
471    fn self_closing(name: &QualName) -> bool {
472        use html5ever::namespace_url;
473        name.ns == ns!(html)
474            && matches!(
475                name.local,
476                local_name!("area")
477                    | local_name!("base")
478                    | local_name!("basefont")
479                    | local_name!("bgsound")
480                    | local_name!("br")
481                    | local_name!("col")
482                    | local_name!("embed")
483                    | local_name!("frame")
484                    | local_name!("hr")
485                    | local_name!("img")
486                    | local_name!("input")
487                    | local_name!("keygen")
488                    | local_name!("link")
489                    | local_name!("meta")
490                    | local_name!("param")
491                    | local_name!("source")
492                    | local_name!("track")
493                    | local_name!("wbr")
494            )
495    }
496
497    fn base_len(name: &QualName) -> usize {
498        let tag_len = tag_len(name);
499        if Self::self_closing(name) {
500            tag_len
501        } else {
502            2 * tag_len + 1
503        }
504    }
505
506    /// Create a new element node.
507    #[inline]
508    pub fn new_element(name: QualName, attributes: Attributes) -> Self {
509        let attrs_len: usize = attributes.len();
510        let base_len = Self::base_len(&name);
511        Self::new(NodeData::Element(ElementData {
512            name,
513            attributes: RefCell::new(attributes),
514            start_offset: Cell::new(0),
515            end_offset: Cell::new(base_len + attrs_len),
516            closed: Cell::new(false),
517            ftml: Cell::new(None),
518        }))
519    }
520
521    /// Create a new text node.
522    #[inline]
523    pub fn new_text(value: StrTendril) -> Self {
524        Self::new(NodeData::Text(RefCell::new(value)))
525    }
526
527    /// Create a new comment node.
528    #[inline]
529    pub fn new_comment(value: StrTendril) -> Self {
530        Self::new(NodeData::Comment(value))
531    }
532
533    /// Create a new processing instruction node.
534    #[inline]
535    pub fn new_processing_instruction(target: StrTendril, data: StrTendril) -> Self {
536        Self::new(NodeData::ProcessingInstruction(target, data))
537    }
538
539    /// Create a new doctype node.
540    #[inline]
541    pub fn new_doctype(name: StrTendril, public_id: StrTendril, system_id: StrTendril) -> Self {
542        Self::new(NodeData::Doctype {
543            name,
544            public_id,
545            system_id,
546        })
547    }
548
549    /// Create a new document node.
550    #[inline]
551    pub fn new_document() -> Self {
552        Self::new(NodeData::Document(Cell::new(QuirksMode::NoQuirks)))
553    }
554}
555
556impl Node {
557    /// Return a reference to this node’s node-type-specific data.
558    #[inline]
559    pub const fn data(&self) -> &NodeData {
560        &self.data
561    }
562
563    /// If this node is an element, return a reference to element-specific data.
564    #[inline]
565    pub const fn as_element(&self) -> Option<&ElementData> {
566        match self.data {
567            NodeData::Element(ref value) => Some(value),
568            _ => None,
569        }
570    }
571
572    /// If this node is a document, return a reference to element-specific data.
573    #[inline]
574    pub const fn as_document(&self) -> Option<&Cell<QuirksMode>> {
575        match self.data {
576            NodeData::Document(ref value) => Some(value),
577            _ => None,
578        }
579    }
580
581    /// If this node is a text node, return a reference to its contents.
582    #[inline]
583    pub const fn as_text(&self) -> Option<&RefCell<StrTendril>> {
584        match self.data {
585            NodeData::Text(ref value) => Some(value),
586            _ => None,
587        }
588    }
589
590    /// Return a reference to the parent node, unless this node is the root of the tree.
591    #[inline]
592    pub fn parent(&self) -> Option<NodeRef> {
593        self.parent.upgrade().map(NodeRef)
594    }
595
596    /// Return a reference to the first child of this node, unless it has no child.
597    #[inline]
598    pub fn first_child(&self) -> Option<NodeRef> {
599        self.first_child.clone_inner().map(NodeRef)
600    }
601
602    /// Return a reference to the last child of this node, unless it has no child.
603    #[inline]
604    pub fn last_child(&self) -> Option<NodeRef> {
605        self.last_child.upgrade().map(NodeRef)
606    }
607
608    /// Return a reference to the previous sibling of this node, unless it is a first child.
609    #[inline]
610    pub fn previous_sibling(&self) -> Option<NodeRef> {
611        self.previous_sibling.upgrade().map(NodeRef)
612    }
613
614    /// Return a reference to the next sibling of this node, unless it is a last child.
615    #[inline]
616    pub fn next_sibling(&self) -> Option<NodeRef> {
617        self.next_sibling.clone_inner().map(NodeRef)
618    }
619
620    /// Detach a node from its parent and siblings. Children are not affected.
621    ///
622    /// To remove a node and its descendants, detach it and drop any strong reference to it.
623    pub fn detach(&self) {
624        let parent_weak = self.parent.take();
625        let previous_sibling_weak = self.previous_sibling.take();
626        let next_sibling_strong = self.next_sibling.take();
627
628        let previous_sibling_opt = previous_sibling_weak.as_ref().and_then(Weak::upgrade);
629
630        if let Some(next_sibling_ref) = next_sibling_strong.as_ref() {
631            next_sibling_ref
632                .previous_sibling
633                .replace(previous_sibling_weak);
634        } else if let Some(parent_ref) = parent_weak.as_ref() {
635            if let Some(parent_strong) = parent_ref.upgrade() {
636                parent_strong.last_child.replace(previous_sibling_weak);
637            }
638        }
639
640        if let Some(previous_sibling_strong) = previous_sibling_opt {
641            previous_sibling_strong
642                .next_sibling
643                .replace(next_sibling_strong);
644        } else if let Some(parent_ref) = parent_weak.as_ref() {
645            if let Some(parent_strong) = parent_ref.upgrade() {
646                parent_strong.first_child.replace(next_sibling_strong);
647            }
648        }
649    }
650}
651
652impl NodeRef {
653    /// Append a new child to this node, after existing children.
654    ///
655    /// The new child is detached from its previous position.
656    pub fn append(&self, new_child: Self) {
657        new_child.detach();
658        new_child.parent.replace(Some(Rc::downgrade(&self.0)));
659        if let Some(last_child_weak) = self.last_child.replace(Some(Rc::downgrade(&new_child.0))) {
660            if let Some(last_child) = last_child_weak.upgrade() {
661                new_child.previous_sibling.replace(Some(last_child_weak));
662                debug_assert!(last_child.next_sibling.is_none());
663                last_child.next_sibling.replace(Some(new_child.0));
664                return;
665            }
666        }
667        debug_assert!(self.first_child.is_none());
668        self.first_child.replace(Some(new_child.0));
669    }
670
671    /*
672    /// Prepend a new child to this node, before existing children.
673    ///
674    /// The new child is detached from its previous position.
675    pub fn prepend(&self, new_child: Self) {
676        new_child.detach();
677        new_child.parent.replace(Some(Rc::downgrade(&self.0)));
678        if let Some(first_child) = self.first_child.take() {
679            debug_assert!(first_child.previous_sibling.is_none());
680            first_child
681                .previous_sibling
682                .replace(Some(Rc::downgrade(&new_child.0)));
683            new_child.next_sibling.replace(Some(first_child));
684        } else {
685            debug_assert!(self.first_child.is_none());
686            self.last_child.replace(Some(Rc::downgrade(&new_child.0)));
687        }
688        self.first_child.replace(Some(new_child.0));
689    }
690
691    /// Insert a new sibling after this node.
692    ///
693    /// The new sibling is detached from its previous position.
694    pub fn insert_after(&self, new_sibling: Self) {
695        new_sibling.detach();
696        new_sibling.parent.replace(self.parent.clone_inner());
697        new_sibling
698            .previous_sibling
699            .replace(Some(Rc::downgrade(&self.0)));
700        if let Some(next_sibling) = self.next_sibling.take() {
701            debug_assert!(next_sibling.previous_sibling().unwrap() == *self);
702            next_sibling
703                .previous_sibling
704                .replace(Some(Rc::downgrade(&new_sibling.0)));
705            new_sibling.next_sibling.replace(Some(next_sibling));
706        } else if let Some(parent) = self.parent() {
707            debug_assert!(parent.last_child().unwrap() == *self);
708            parent
709                .last_child
710                .replace(Some(Rc::downgrade(&new_sibling.0)));
711        }
712        self.next_sibling.replace(Some(new_sibling.0));
713    }
714     */
715
716    /*
717    /// Insert a new sibling before this node.
718    ///
719    /// The new sibling is detached from its previous position.
720    pub fn insert_before(&self, new_sibling: Self) {
721        new_sibling.detach();
722        new_sibling.parent.replace(self.parent.clone_inner());
723        new_sibling.next_sibling.replace(Some(self.0.clone()));
724        if let Some(previous_sibling_weak) = self
725            .previous_sibling
726            .replace(Some(Rc::downgrade(&new_sibling.0)))
727        {
728            if let Some(previous_sibling) = previous_sibling_weak.upgrade() {
729                new_sibling
730                    .previous_sibling
731                    .replace(Some(previous_sibling_weak));
732                debug_assert!(previous_sibling.next_sibling().unwrap_or_else(|| unreachable!()) == *self);
733                previous_sibling.next_sibling.replace(Some(new_sibling.0));
734                return;
735            }
736        }
737        if let Some(parent) = self.parent() {
738            debug_assert!(parent.first_child().unwrap_or_else(|| unreachable!()) == *self);
739            parent.first_child.replace(Some(new_sibling.0));
740        }
741    }
742     */
743}
744
745#[inline]
746pub fn tag_len(name: &QualName) -> usize {
747    name.prefix
748        .as_ref()
749        .map(|e| e.len() + 1 /* ':' */)
750        .unwrap_or_default()
751        + name.local.len()
752        + "<>".len()
753}
754
755pub fn escaped_len(str: &str, attr_mode: bool) -> usize {
756    str.chars()
757        .map(|b| match b {
758            '&' => "&amp;".len(),
759            '\u{00A0}' => "&nbsp;".len(),
760            '"' if attr_mode => "&quot;".len(),
761            '<' if !attr_mode => "&lt;".len(),
762            '>' if !attr_mode => "&gt;".len(),
763            c => c.len_utf8(),
764        })
765        .sum()
766}
767
768pub struct Ancestors(Option<NodeRef>);
769impl Iterator for Ancestors {
770    type Item = NodeRef;
771    fn next(&mut self) -> Option<Self::Item> {
772        if let Some(n) = &self.0 {
773            let p = n.parent();
774            std::mem::replace(&mut self.0, p)
775        } else {
776            None
777        }
778    }
779}
780
781#[derive(Debug, Clone)]
782struct State<T> {
783    next: T,
784    next_back: T,
785}
786/// A double-ended iterator of sibling nodes.
787#[derive(Debug, Clone)]
788pub struct Siblings(Option<State<NodeRef>>);
789
790macro_rules! siblings_next {
791    ($next: ident, $next_back: ident, $next_sibling: ident) => {
792        fn $next(&mut self) -> Option<NodeRef> {
793            #![allow(non_shorthand_field_patterns)]
794            self.0.take().map(
795                |State {
796                     $next: next,
797                     $next_back: next_back,
798                 }| {
799                    if let Some(sibling) = next.$next_sibling() {
800                        if next != next_back {
801                            self.0 = Some(State {
802                                $next: sibling,
803                                $next_back: next_back,
804                            })
805                        }
806                    }
807                    next
808                },
809            )
810        }
811    };
812}
813
814impl Iterator for Siblings {
815    type Item = NodeRef;
816    siblings_next!(next, next_back, next_sibling);
817}
818
819impl DoubleEndedIterator for Siblings {
820    siblings_next!(next_back, next, previous_sibling);
821}
822
823impl Serialize for NodeRef {
824    fn serialize<S>(
825        &self,
826        serializer: &mut S,
827        traversal_scope: TraversalScope,
828    ) -> std::io::Result<()>
829    where
830        S: html5ever::serialize::Serializer,
831    {
832        match (traversal_scope, self.data()) {
833            (ref scope, NodeData::Element(element)) => {
834                if *scope == TraversalScope::IncludeNode {
835                    let attrs = element.attributes.borrow();
836
837                    serializer.start_elem(
838                        element.name.clone(),
839                        attrs.0.iter().map(|(name, value)| (name, &**value)),
840                    )?;
841                }
842                let children = self.children();
843
844                for child in children {
845                    Serialize::serialize(&child, serializer, TraversalScope::IncludeNode)?;
846                }
847
848                if *scope == TraversalScope::IncludeNode {
849                    serializer.end_elem(element.name.clone())?;
850                }
851                Ok(())
852            }
853
854            (_, &NodeData::Document(_)) => {
855                for child in self.children() {
856                    Serialize::serialize(&child, serializer, TraversalScope::IncludeNode)?;
857                }
858                Ok(())
859            }
860
861            (TraversalScope::ChildrenOnly(_), _) => Ok(()),
862
863            (TraversalScope::IncludeNode, NodeData::Doctype { name, .. }) => {
864                serializer.write_doctype(name)
865            }
866            (TraversalScope::IncludeNode, NodeData::Text(text)) => {
867                serializer.write_text(&text.borrow())
868            }
869            (TraversalScope::IncludeNode, NodeData::Comment(_text)) => Ok(()), //serializer.write_comment(text),
870            (TraversalScope::IncludeNode, NodeData::ProcessingInstruction(target, data)) => {
871                serializer.write_processing_instruction(target, data)
872            }
873        }
874    }
875}
876
877trait CellOption {
878    fn is_none(&self) -> bool;
879}
880
881impl<T> CellOption for Cell<Option<T>> {
882    #[inline]
883    fn is_none(&self) -> bool {
884        unsafe { (*self.as_ptr()).is_none() }
885    }
886}
887
888trait CellOptionWeak<T> {
889    fn upgrade(&self) -> Option<Rc<T>>;
890    //fn clone_inner(&self) -> Option<Weak<T>>;
891}
892
893impl<T> CellOptionWeak<T> for Cell<Option<Weak<T>>> {
894    #[inline]
895    fn upgrade(&self) -> Option<Rc<T>> {
896        unsafe { (*self.as_ptr()).as_ref().and_then(Weak::upgrade) }
897    }
898    /*
899    #[inline]
900    fn clone_inner(&self) -> Option<Weak<T>> {
901        unsafe { (*self.as_ptr()).clone() }
902    }
903    */
904}
905
906trait CellOptionRc<T> {
907    /// Return `Some` if this `Rc` is the only strong reference count,
908    /// even if there are weak references.
909    fn take_if_unique_strong(&self) -> Option<Rc<T>>;
910    fn clone_inner(&self) -> Option<Rc<T>>;
911}
912
913impl<T> CellOptionRc<T> for Cell<Option<Rc<T>>> {
914    #[inline]
915    fn take_if_unique_strong(&self) -> Option<Rc<T>> {
916        unsafe {
917            match *self.as_ptr() {
918                None => None,
919                Some(ref rc) if Rc::strong_count(rc) > 1 => None,
920                // Not borrowing the `Rc<T>` here
921                // as we would be invalidating that borrow while it is outstanding:
922                Some(_) => self.take(),
923            }
924        }
925    }
926
927    #[inline]
928    fn clone_inner(&self) -> Option<Rc<T>> {
929        unsafe { (*self.as_ptr()).clone() }
930    }
931}