From 8cb5cf0252c6b23c01f8dbeafcb0d10b0de7eb48 Mon Sep 17 00:00:00 2001 From: Tal Hayon Date: Sun, 8 Aug 2021 23:38:55 +0300 Subject: [PATCH] web: Adds support for base embed/object attribute (Part of #4258) --- web/packages/core/src/load-options.ts | 8 ++++++ web/packages/core/src/ruffle-embed.ts | 7 ++++- web/packages/core/src/ruffle-object.ts | 9 ++++++ web/src/lib.rs | 5 ++++ web/src/navigator.rs | 38 ++++++++++++++++++++------ 5 files changed, 57 insertions(+), 10 deletions(-) diff --git a/web/packages/core/src/load-options.ts b/web/packages/core/src/load-options.ts index 262350eef363..296dfd09cf97 100644 --- a/web/packages/core/src/load-options.ts +++ b/web/packages/core/src/load-options.ts @@ -178,6 +178,14 @@ export interface BaseLoadOptions { secs: number; nanos: number; }; + + /** + * Specifies the base directory or URL used to resolve all relative path statements in the SWF file. + * null means the current directory. + * + * @default null + */ + base?: string | null; } /** diff --git a/web/packages/core/src/ruffle-embed.ts b/web/packages/core/src/ruffle-embed.ts index 9d4392b4731f..4fa706fdb388 100644 --- a/web/packages/core/src/ruffle-embed.ts +++ b/web/packages/core/src/ruffle-embed.ts @@ -49,6 +49,7 @@ export class RuffleEmbed extends RufflePlayer { ), parameters: this.attributes.getNamedItem("flashvars")?.value, backgroundColor: this.attributes.getNamedItem("bgcolor")?.value, + base: this.attributes.getNamedItem("base")?.value, }); } } @@ -105,7 +106,11 @@ export class RuffleEmbed extends RufflePlayer { } const src = this.attributes.getNamedItem("src"); if (src) { - this.load({ url: src.value, parameters }); + this.load({ + url: src.value, + parameters, + base: this.attributes.getNamedItem("base")?.value, + }); } } } diff --git a/web/packages/core/src/ruffle-object.ts b/web/packages/core/src/ruffle-object.ts index c1bdcc89ab41..d304f1823441 100644 --- a/web/packages/core/src/ruffle-object.ts +++ b/web/packages/core/src/ruffle-object.ts @@ -112,6 +112,12 @@ export class RuffleObject extends RufflePlayer { this.getAttribute("bgcolor") ); + const base = findCaseInsensitive( + this.params, + "base", + this.getAttribute("base") + ); + if (url) { const options: URLLoadOptions = { url }; options.allowScriptAccess = isScriptAccessAllowed( @@ -124,6 +130,9 @@ export class RuffleObject extends RufflePlayer { if (backgroundColor) { options.backgroundColor = backgroundColor; } + if (base) { + options.base = base; + } // Kick off the SWF download. this.load(options); diff --git a/web/src/lib.rs b/web/src/lib.rs index 34ab1b66c5e7..1024439c2fde 100644 --- a/web/src/lib.rs +++ b/web/src/lib.rs @@ -138,6 +138,9 @@ pub struct Config { #[serde(rename = "upgradeToHttps")] upgrade_to_https: bool, + #[serde(rename = "base")] + base_url: Option, + #[serde(rename = "warnOnUnsupportedContent")] warn_on_unsupported_content: bool, @@ -155,6 +158,7 @@ impl Default for Config { background_color: Default::default(), letterbox: Default::default(), upgrade_to_https: true, + base_url: None, warn_on_unsupported_content: true, log_level: log::Level::Error, max_execution_duration: Duration::from_secs(15), @@ -457,6 +461,7 @@ impl Ruffle { let navigator = Box::new(navigator::WebNavigatorBackend::new( allow_script_access, config.upgrade_to_https, + config.base_url, )); let storage = match window.local_storage() { Ok(Some(s)) => { diff --git a/web/src/navigator.rs b/web/src/navigator.rs index dba868be067f..397bd9873dc0 100644 --- a/web/src/navigator.rs +++ b/web/src/navigator.rs @@ -10,17 +10,24 @@ use std::time::Duration; use url::Url; use wasm_bindgen::JsCast; use wasm_bindgen_futures::{spawn_local, JsFuture}; -use web_sys::{window, Blob, BlobPropertyBag, Performance, Request, RequestInit, Response}; +use web_sys::{ + window, Blob, BlobPropertyBag, Document, Performance, Request, RequestInit, Response, +}; pub struct WebNavigatorBackend { performance: Performance, start_time: f64, allow_script_access: bool, upgrade_to_https: bool, + base_url: Option, } impl WebNavigatorBackend { - pub fn new(allow_script_access: bool, upgrade_to_https: bool) -> Self { + pub fn new( + allow_script_access: bool, + upgrade_to_https: bool, + base_url: Option, + ) -> Self { let window = web_sys::window().expect("window()"); let performance = window.performance().expect("window.performance()"); @@ -33,6 +40,17 @@ impl WebNavigatorBackend { performance, allow_script_access, upgrade_to_https, + base_url, + } + } + + fn base_uri(&self, document: &Document) -> Option { + if let Some(base_url) = self.base_url.clone() { + Some(base_url) + } else if let Ok(Some(base_uri)) = document.base_uri() { + Some(base_uri) + } else { + None } } } @@ -51,12 +69,14 @@ impl NavigatorBackend for WebNavigatorBackend { if let Some(window) = window() { let document = window.document().expect("Could not get document"); - let url = if let Ok(Some(base_uri)) = document.base_uri() { - if let Ok(new_url) = url_from_relative_url(&base_uri, &url) { - new_url - } else { - return; - } + + let base_uri = match self.base_uri(&document) { + Some(base_uri) => base_uri, + _ => return, + }; + + let url = if let Ok(new_url) = url_from_relative_url(&base_uri, &url) { + new_url } else { return; }; @@ -209,7 +229,7 @@ impl NavigatorBackend for WebNavigatorBackend { let window = web_sys::window().expect("window()"); let document = window.document().expect("document()"); - if let Ok(Some(base_uri)) = document.base_uri() { + if let Some(base_uri) = self.base_uri(&document) { if let Ok(new_url) = url_from_relative_url(&base_uri, url) { return String::from(new_url).into(); }