Skip to content

Commit

Permalink
Merge pull request #730 from jaytaph/updates
Browse files Browse the repository at this point in the history
Added functionality to render tree from html-source instead of url
  • Loading branch information
jaytaph authored Dec 24, 2024
2 parents 1a5db5d + 9c53aca commit 32c75c9
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 20 deletions.
13 changes: 13 additions & 0 deletions crates/gosub_interface/src/draw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,19 @@ pub trait TreeDrawer<C: HasDrawComponents> {
where
Self: Sized;

fn from_source(
// The initial url that the source was loaded from
url: Url,
// Actual loaded source HTML
source_html: &str,
// Layouter that renders the tree
layouter: C::Layouter,
// Debug flag
debug: bool,
) -> gosub_shared::types::Result<Self>
where
Self: Sized;

fn clear_buffers(&mut self);
fn toggle_debug(&mut self);

Expand Down
11 changes: 9 additions & 2 deletions crates/gosub_renderer/src/draw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::debug::scale::px_scale;
use crate::draw::img::request_img;
use crate::draw::img_cache::ImageCache;
use crate::draw::testing::{test_add_element, test_restyle_element};
use crate::render_tree::{load_html_rendertree, load_html_rendertree_fetcher};
use crate::render_tree::{load_html_rendertree, load_html_rendertree_fetcher, load_html_rendertree_source};
use anyhow::anyhow;
use gosub_interface::config::{HasDrawComponents, HasHtmlParser};
use gosub_interface::css3::{CssProperty, CssPropertyMap, CssValue};
Expand Down Expand Up @@ -212,7 +212,14 @@ where
}

async fn from_url(url: Url, layouter: C::Layouter, debug: bool) -> Result<Self> {
let (rt, fetcher) = load_html_rendertree::<C>(url.clone()).await?;
let (rt, fetcher) = load_html_rendertree::<C>(url.clone(), None).await?;

Ok(Self::new(rt, layouter, fetcher, debug))
}

fn from_source(url: Url, source_html: &str, layouter: C::Layouter, debug: bool) -> Result<Self> {
let fetcher = Fetcher::new(url.clone());
let rt = load_html_rendertree_source::<C>(url, source_html)?;

Ok(Self::new(rt, layouter, fetcher, debug))
}
Expand Down
53 changes: 35 additions & 18 deletions crates/gosub_renderer/src/render_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,40 +10,33 @@ use gosub_shared::byte_stream::{ByteStream, Encoding};
use std::fs;
use url::Url;

/// Generates a render tree from the given URL.. if the source is given, the URL is not loaded, but the source HTML is used instead
pub(crate) async fn load_html_rendertree<
C: HasRenderTree<LayoutTree = RenderTree<C>, RenderTree = RenderTree<C>> + HasHtmlParser,
>(
url: Url,
source: Option<&str>,
) -> gosub_shared::types::Result<(RenderTree<C>, Fetcher)> {
let fetcher = Fetcher::new(url.clone());

let rt = load_html_rendertree_fetcher::<C>(url, &fetcher).await?;
let rt = match source {
Some(source) => load_html_rendertree_source::<C>(url, source)?,
None => load_html_rendertree_fetcher::<C>(url, &fetcher).await?,
};

Ok((rt, fetcher))
}

pub(crate) async fn load_html_rendertree_fetcher<
// Generate a render tree from the given source HTML. THe URL is needed to resolve relative URLs
// and also to set the base URL for the document.
pub(crate) fn load_html_rendertree_source<
C: HasRenderTree<LayoutTree = RenderTree<C>, RenderTree = RenderTree<C>> + HasHtmlParser,
>(
url: Url,
fetcher: &Fetcher,
source_html: &str,
) -> gosub_shared::types::Result<RenderTree<C>> {
let html = if url.scheme() == "http" || url.scheme() == "https" {
// Fetch the html from the url
let response = fetcher.get(url.as_ref()).await?;
if response.status != 200 {
bail!(format!("Could not get url. Status code {}", response.status));
}

String::from_utf8(response.body.clone())?
} else if url.scheme() == "file" {
fs::read_to_string(url.as_str().trim_start_matches("file://"))?
} else {
bail!("Unsupported url scheme: {}", url.scheme());
};

let mut stream = ByteStream::new(Encoding::UTF8, None);
stream.read_from_str(&html, Some(Encoding::UTF8));
stream.read_from_str(source_html, Some(Encoding::UTF8));
stream.close();

let mut doc_handle = C::DocumentBuilder::new_document(Some(url));
Expand All @@ -61,3 +54,27 @@ pub(crate) async fn load_html_rendertree_fetcher<

generate_render_tree(DocumentHandle::clone(&doc_handle))
}

/// Generates a render tree from the given URL. The complete HTML source is fetched from the URL async.
pub(crate) async fn load_html_rendertree_fetcher<
C: HasRenderTree<LayoutTree = RenderTree<C>, RenderTree = RenderTree<C>> + HasHtmlParser,
>(
url: Url,
fetcher: &Fetcher,
) -> gosub_shared::types::Result<RenderTree<C>> {
let html = if url.scheme() == "http" || url.scheme() == "https" {
// Fetch the html from the url
let response = fetcher.get(url.as_ref()).await?;
if response.status != 200 {
bail!(format!("Could not get url. Status code {}", response.status));
}

String::from_utf8(response.body.clone())?
} else if url.scheme() == "file" {
fs::read_to_string(url.as_str().trim_start_matches("file://"))?
} else {
bail!("Unsupported url scheme: {}", url.scheme());
};

load_html_rendertree_source(url, &html)
}
2 changes: 2 additions & 0 deletions src/prelude.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
pub use gosub_interface::config::*;
pub use gosub_interface::draw::TreeDrawer;
pub use gosub_interface::render_backend::ImageBuffer;
pub use gosub_interface::render_backend::RenderBackend;
pub use gosub_interface::render_backend::WindowedEventLoop;

pub use gosub_shared::geo::*;
Expand Down

0 comments on commit 32c75c9

Please sign in to comment.