Skip to content

Commit

Permalink
Merge pull request #770 from Sharktheone/document/handle
Browse files Browse the repository at this point in the history
  • Loading branch information
Sharktheone authored Jan 14, 2025
2 parents f843534 + df608f6 commit b7c5652
Show file tree
Hide file tree
Showing 44 changed files with 734 additions and 1,719 deletions.
14 changes: 7 additions & 7 deletions benches/tree_iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use gosub_html5::document::fragment::DocumentFragmentImpl;
use gosub_html5::parser::Html5Parser;
use gosub_interface::config::{HasCssSystem, HasDocument, HasHtmlParser};
use gosub_interface::document::DocumentBuilder;
use gosub_interface::document_handle::DocumentHandle;

use gosub_shared::byte_stream::{ByteStream, Encoding};
use gosub_shared::node::NodeId;

Expand Down Expand Up @@ -38,12 +38,12 @@ fn wikipedia_main_page(c: &mut Criterion) {
let mut stream = ByteStream::new(Encoding::UTF8, None);
let _ = stream.read_from_file(html_file);

let doc_handle: DocumentHandle<Config> = DocumentBuilderImpl::new_document(None);
let _ = Html5Parser::parse_document(&mut stream, doc_handle.clone(), None);
let mut doc = <DocumentBuilderImpl as DocumentBuilder<Config>>::new_document(None);
let _ = Html5Parser::<Config>::parse_document(&mut stream, &mut doc, None);

group.bench_function("wikipedia main page", |b| {
b.iter(|| {
let tree_iterator = TreeIterator::new(doc_handle.clone());
let tree_iterator = TreeIterator::<Config>::new(&doc);
let _ = tree_iterator.collect::<Vec<NodeId>>();
})
});
Expand All @@ -63,12 +63,12 @@ fn stackoverflow_home(c: &mut Criterion) {
let mut bytestream = ByteStream::new(Encoding::UTF8, None);
let _ = bytestream.read_from_file(html_file);

let doc_handle: DocumentHandle<Config> = DocumentBuilderImpl::new_document(None);
let _ = Html5Parser::parse_document(&mut bytestream, doc_handle.clone(), None);
let mut doc = <DocumentBuilderImpl as DocumentBuilder<Config>>::new_document(None);
let _ = Html5Parser::<Config>::parse_document(&mut bytestream, &mut doc, None);

group.bench_function("stackoverflow home", |b| {
b.iter(|| {
let tree_iterator = TreeIterator::new(doc_handle.clone());
let tree_iterator = TreeIterator::<Config>::new(&doc);
let _ = tree_iterator.collect::<Vec<NodeId>>();
})
});
Expand Down
17 changes: 6 additions & 11 deletions crates/gosub_css3/src/matcher/styling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use gosub_interface::config::HasDocument;
use gosub_interface::css3;
use gosub_interface::css3::{CssOrigin, CssPropertyMap};
use gosub_interface::document::Document;
use gosub_interface::document_handle::DocumentHandle;

use gosub_interface::node::ClassList;
use gosub_interface::node::ElementDataType;
use gosub_interface::node::Node;
Expand All @@ -20,12 +20,12 @@ use crate::system::Css3System;

// Matches a complete selector (all parts) against the given node(id)
pub(crate) fn match_selector<C: HasDocument>(
document: DocumentHandle<C>,
document: &C::Document,
node_id: NodeId,
selector: &CssSelector,
) -> (bool, Specificity) {
for part in &selector.parts {
if match_selector_parts(DocumentHandle::clone(&document), node_id, part) {
if match_selector_parts::<C>(document, node_id, part) {
return (true, Specificity::from(part.as_slice()));
}
}
Expand All @@ -44,13 +44,8 @@ fn consume<'a, T>(this: &mut &'a [T]) -> Option<&'a T> {
}

/// Returns true when the given node matches the part(s)
fn match_selector_parts<C: HasDocument>(
handle: DocumentHandle<C>,
node_id: NodeId,
mut parts: &[CssSelectorPart],
) -> bool {
let binding = handle.get();
let mut next_current_node = binding.node_by_id(node_id);
fn match_selector_parts<C: HasDocument>(doc: &C::Document, node_id: NodeId, mut parts: &[CssSelectorPart]) -> bool {
let mut next_current_node = doc.node_by_id(node_id);
if next_current_node.is_none() {
return false;
}
Expand All @@ -64,7 +59,7 @@ fn match_selector_parts<C: HasDocument>(
return false;
}

if !match_selector_part::<C>(part, current_node, &*binding, &mut next_current_node, &mut parts) {
if !match_selector_part::<C>(part, current_node, doc, &mut next_current_node, &mut parts) {
return false;
}

Expand Down
16 changes: 7 additions & 9 deletions crates/gosub_css3/src/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::stylesheet::{CssDeclaration, CssValue, Specificity};
use crate::{load_default_useragent_stylesheet, Css3};
use gosub_interface::config::{HasDocument, HasRenderTree};
use gosub_interface::css3::{CssOrigin, CssPropertyMap, CssSystem};
use gosub_interface::document_handle::DocumentHandle;

use gosub_interface::node::{ElementDataType, Node, TextDataType};
use gosub_interface::render_tree::{RenderTree, RenderTreeNode};
use gosub_shared::config::ParserConfig;
Expand All @@ -35,7 +35,7 @@ impl CssSystem for Css3System {
fn properties_from_node<C: HasDocument<CssSystem = Self>>(
node: &C::Node,
sheets: &[Self::Stylesheet],
handle: DocumentHandle<C>,
doc: &C::Document,
id: NodeId,
) -> Option<Self::PropertyMap> {
let mut css_map_entry = CssProperties::new();
Expand All @@ -51,7 +51,7 @@ impl CssSystem for Css3System {
for sheet in sheets {
for rule in &sheet.rules {
for selector in rule.selectors().iter() {
let (matched, specificity) = match_selector(DocumentHandle::clone(&handle), id, selector);
let (matched, specificity) = match_selector::<C>(doc, id, selector);

if !matched {
continue;
Expand All @@ -66,7 +66,7 @@ impl CssSystem for Css3System {
continue;
};

let value = resolve_functions(&declaration.value, node, handle.clone());
let value = resolve_functions::<C>(&declaration.value, node, doc);

let match_value = if let CssValue::List(value) = &value {
&**value
Expand Down Expand Up @@ -239,7 +239,7 @@ pub fn node_is_unrenderable<C: HasDocument>(node: &C::Node) -> bool {
false
}

pub fn resolve_functions<C: HasDocument>(value: &CssValue, node: &C::Node, handle: DocumentHandle<C>) -> CssValue {
pub fn resolve_functions<C: HasDocument>(value: &CssValue, node: &C::Node, doc: &C::Document) -> CssValue {
fn resolve<C: HasDocument>(val: &CssValue, node: &C::Node, doc: &C::Document) -> CssValue {
match val {
CssValue::Function(func, values) => {
Expand All @@ -256,12 +256,10 @@ pub fn resolve_functions<C: HasDocument>(value: &CssValue, node: &C::Node, handl
}
}

let doc = handle.get();

if let CssValue::List(list) = value {
let resolved = list.iter().map(|val| resolve::<C>(val, node, &*doc)).collect();
let resolved = list.iter().map(|val| resolve::<C>(val, node, doc)).collect();
CssValue::List(resolved)
} else {
resolve::<C>(value, node, &*doc)
resolve::<C>(value, node, doc)
}
}
6 changes: 3 additions & 3 deletions crates/gosub_html5/docs/parsing.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ Next, we need to create a document, which will be the main object that will be f
data that is generated during the parsing of the HTML. This also includes any stylesheets that are found, both internally and externally.

```rust
let doc_handle = DocumentBuilderImpl::new_document();
let doc = DocumentBuilderImpl::new_document();
```

Note that a doc_handle itself isn't a document, but a HANDLE to a document (a `DocumentHandle`). Once we have our document handle, we can start the parser
Once we have our document, we can start the parser
by calling the `parse_document` method on the `Html5Parser` struct. This method will return a list of parse errors, if any.

```rust
let parse_errors = Html5Parser::parse_document(&mut stream, doc_handle.clone(), None)?;
let parse_errors = Html5Parser::parse_document(&mut stream, &mut doc, None)?;

for e in parse_errors {
println!("Parse Error: {}", e.message);
Expand Down
24 changes: 8 additions & 16 deletions crates/gosub_html5/src/document/builder.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::node::HTML_NAMESPACE;
use crate::DocumentHandle;
use gosub_interface::config::HasDocument;
use gosub_interface::document::DocumentBuilder;
use gosub_interface::document::{Document, DocumentType};
Expand All @@ -12,35 +11,28 @@ pub struct DocumentBuilderImpl {}

impl<C: HasDocument> DocumentBuilder<C> for DocumentBuilderImpl {
/// Creates a new document with a document root node
fn new_document(url: Option<Url>) -> DocumentHandle<C> {
fn new_document(url: Option<Url>) -> C::Document {
C::Document::new(DocumentType::HTML, url, None)
}

/// Creates a new document fragment with the context as the root node
fn new_document_fragment(context_node: &C::Node, quirks_mode: QuirksMode) -> DocumentHandle<C> {
let handle = context_node.handle();

fn new_document_fragment(context_node: &C::Node, quirks_mode: QuirksMode) -> C::Document {
// Create a new document with an HTML node as the root node
let fragment_root_node = C::Document::new_element_node(
handle.clone(),
"html",
Some(HTML_NAMESPACE),
HashMap::new(),
context_node.location(),
);
let mut fragment_handle = C::Document::new(DocumentType::HTML, None, Some(fragment_root_node));
let fragment_root_node =
C::Document::new_element_node("html", Some(HTML_NAMESPACE), HashMap::new(), context_node.location());
let mut fragment = C::Document::new(DocumentType::HTML, None, Some(fragment_root_node));

// let context_node = context_node.clone();
match quirks_mode {
QuirksMode::Quirks => {
fragment_handle.get_mut().set_quirks_mode(QuirksMode::Quirks);
fragment.set_quirks_mode(QuirksMode::Quirks);
}
QuirksMode::LimitedQuirks => {
fragment_handle.get_mut().set_quirks_mode(QuirksMode::LimitedQuirks);
fragment.set_quirks_mode(QuirksMode::LimitedQuirks);
}
_ => {}
}

fragment_handle
fragment
}
}
Loading

0 comments on commit b7c5652

Please sign in to comment.