use crate::Tag;
use super::{Builder, Mode, Next, Ns, Open, is_ws};
impl<'a> Builder<'a> {
pub(super) fn in_frameset_modes(&self) -> bool {
self.mode > Mode::InBody
}
pub(super) fn frameset_ok_after(&mut self, tag: Tag) {
use Tag::*;
if self.frameset_ok
&& matches!(
tag,
Pre | Listing
| Li
| Dd
| Dt
| Button
| Applet
| Marquee
| Object
| Table
| Area
| Br
| Embed
| Img
| Keygen
| Wbr
| Input
| Hr
| Textarea
| Xmp
| Iframe
| Select
| Template
)
&& !(tag == Input && self.hidden_input())
{
self.frameset_ok = false;
}
}
pub(super) fn insert_frameset(&mut self, name: (usize, usize)) {
let id = self.create(Tag::Frameset, name);
self.append(self.html, id);
self.stack.push(Open {
id,
tag: Tag::Frameset,
ns: Ns::Html,
});
self.mode = Mode::InFrameset;
}
pub(super) fn frameset_in_body(&mut self, name: (usize, usize)) {
let replaces = self.frameset_ok
&& self.stack.len() >= 2
&& self.stack[1].id == self.body
&& !self.in_template();
if !replaces {
self.scratch.clear();
return;
}
self.detach(self.body);
self.pop_to(1);
self.insert_frameset(name);
}
pub(super) fn frameset_start_tag(&mut self, tag: Tag, name: (usize, usize)) -> Next {
match tag {
Tag::Html => self.merge_attrs(self.html),
Tag::Frameset if self.mode == Mode::InFrameset => {
self.insert(tag, name, Ns::Html, true, false);
}
Tag::Frame if self.mode == Mode::InFrameset => {
self.insert(tag, name, Ns::Html, false, false);
}
Tag::Noframes => {
self.insert(tag, name, Ns::Html, true, false);
return Next::RawText;
}
_ => self.scratch.clear(),
}
Next::Data
}
pub(super) fn frameset_end_tag(&mut self, tag: Tag) {
if self.current_is(Tag::Noframes) {
if tag == Tag::Noframes {
self.pop();
}
return;
}
match (self.mode, tag) {
(Mode::InFrameset, Tag::Frameset) => {
if self.stack.len() > 1 {
self.pop();
}
if !self.current_is(Tag::Frameset) {
self.mode = Mode::AfterFrameset;
}
}
(Mode::AfterFrameset, Tag::Html) => self.mode = Mode::AfterAfterFrameset,
_ => {}
}
}
pub(super) fn frameset_text(&mut self, s: usize, e: usize) {
let raw = &self.src.as_bytes()[s..e];
if raw.iter().all(|&c| is_ws(c)) {
let span = crate::dom::Span::source(s, e);
self.add_text(span, false);
return;
}
let ws: String = raw
.iter()
.filter(|&&c| is_ws(c))
.map(|&c| c as char)
.collect();
if !ws.is_empty() {
let start = self.buf.len();
self.buf.push_str(&ws);
self.add_text(crate::dom::Span::owned(start, self.buf.len()), false);
}
}
}