mirror of
https://github.com/zaphar/wasm-web-components.git
synced 2025-07-21 19:40:30 -04:00
Allow specifying the window to create elements in
This commit is contained in:
parent
ff6e9a5079
commit
7ffcab1416
@ -126,12 +126,10 @@ fn expand_struct_trait_shim(struct_name: &Ident, observed_attrs: Literal) -> syn
|
|||||||
|
|
||||||
connectedCallback() {{
|
connectedCallback() {{
|
||||||
this._impl.connected_impl(this);
|
this._impl.connected_impl(this);
|
||||||
console.log(this.textContent);
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
disconnectedCallback() {{
|
disconnectedCallback() {{
|
||||||
this._impl.disconnected_impl(this);
|
this._impl.disconnected_impl(this);
|
||||||
console.log(this.textContent);
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
static get observedAttributes() {{
|
static get observedAttributes() {{
|
||||||
@ -139,7 +137,6 @@ fn expand_struct_trait_shim(struct_name: &Ident, observed_attrs: Literal) -> syn
|
|||||||
}}
|
}}
|
||||||
|
|
||||||
adoptedCallback() {{
|
adoptedCallback() {{
|
||||||
console.log('In adoptedCallback');
|
|
||||||
this._impl.adopted_impl(this);
|
this._impl.adopted_impl(this);
|
||||||
}}
|
}}
|
||||||
|
|
||||||
@ -185,16 +182,6 @@ fn expand_wasm_shim(struct_name: &Ident) -> syn::ItemImpl {
|
|||||||
Self::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen::prelude::wasm_bindgen]
|
|
||||||
pub fn create() -> web_sys::Element {
|
|
||||||
window()
|
|
||||||
.unwrap()
|
|
||||||
.document()
|
|
||||||
.unwrap()
|
|
||||||
.create_element(Self::element_name())
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[wasm_bindgen::prelude::wasm_bindgen]
|
#[wasm_bindgen::prelude::wasm_bindgen]
|
||||||
pub fn connected_impl(&self, element: &web_sys::HtmlElement) {
|
pub fn connected_impl(&self, element: &web_sys::HtmlElement) {
|
||||||
use #trait_path;
|
use #trait_path;
|
||||||
|
@ -42,4 +42,5 @@ features = [
|
|||||||
"ShadowRootInit",
|
"ShadowRootInit",
|
||||||
"ShadowRootMode",
|
"ShadowRootMode",
|
||||||
"Window",
|
"Window",
|
||||||
|
"console"
|
||||||
]
|
]
|
@ -1,6 +1,6 @@
|
|||||||
use js_sys::Function;
|
use js_sys::Function;
|
||||||
use wasm_bindgen::{convert::IntoWasmAbi, prelude::Closure, JsValue};
|
use wasm_bindgen::{convert::IntoWasmAbi, prelude::Closure, JsValue};
|
||||||
use web_sys::{window, Element, HtmlElement};
|
use web_sys::{window, Element, Event, HtmlElement, Window};
|
||||||
|
|
||||||
/// This attribute proc-macro will generate the following trait implementations
|
/// This attribute proc-macro will generate the following trait implementations
|
||||||
/// * [WebComponentDef](trait@WebComponentDef)
|
/// * [WebComponentDef](trait@WebComponentDef)
|
||||||
@ -27,8 +27,11 @@ pub trait WebComponentDef: IntoWasmAbi + Default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn create() -> Element {
|
fn create() -> Element {
|
||||||
window()
|
Self::create_in_window(window().unwrap())
|
||||||
.unwrap()
|
}
|
||||||
|
|
||||||
|
fn create_in_window(window: Window) -> Element {
|
||||||
|
window
|
||||||
.document()
|
.document()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.create_element(Self::element_name())
|
.create_element(Self::element_name())
|
||||||
@ -88,7 +91,7 @@ mod tests {
|
|||||||
use wasm_bindgen::{JsCast, JsValue};
|
use wasm_bindgen::{JsCast, JsValue};
|
||||||
use wasm_bindgen_test::wasm_bindgen_test;
|
use wasm_bindgen_test::wasm_bindgen_test;
|
||||||
use web_sys::Text;
|
use web_sys::Text;
|
||||||
use web_sys::{window, HtmlElement};
|
use web_sys::{console, window, HtmlElement};
|
||||||
|
|
||||||
use wasm_web_component_macros::web_component;
|
use wasm_web_component_macros::web_component;
|
||||||
|
|
||||||
@ -102,6 +105,76 @@ mod tests {
|
|||||||
pub fn log_with_val(message: String, val: &JsValue);
|
pub fn log_with_val(message: String, val: &JsValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Timer<'a> {
|
||||||
|
name: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Timer<'a> {
|
||||||
|
pub fn new(name: &'a str) -> Timer<'a> {
|
||||||
|
console::time_with_label(name);
|
||||||
|
Timer { name }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Drop for Timer<'a> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
console::time_end_with_label(self.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen_test]
|
||||||
|
pub fn bench_mark_elements() {
|
||||||
|
#[web_component(observed_attrs = "['class']")]
|
||||||
|
pub struct BenchElement {}
|
||||||
|
|
||||||
|
impl WebComponentBinding for BenchElement {
|
||||||
|
fn connected(&self, element: &HtmlElement) {
|
||||||
|
let node = Text::new().unwrap();
|
||||||
|
node.set_text_content(Some("Added a text node on connect".into()));
|
||||||
|
element.append_child(&node).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn disconnected(&self, element: &HtmlElement) {
|
||||||
|
let node = element.first_child().unwrap();
|
||||||
|
element.remove_child(&node).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn adopted(&self, element: &HtmlElement) {
|
||||||
|
let node = Text::new().unwrap();
|
||||||
|
node.set_text_content(Some("Added a text node on adopt".into()));
|
||||||
|
element.append_child(&node).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn attribute_changed(
|
||||||
|
&self,
|
||||||
|
element: &HtmlElement,
|
||||||
|
name: JsValue,
|
||||||
|
old_value: JsValue,
|
||||||
|
new_value: JsValue,
|
||||||
|
) {
|
||||||
|
let node = element.first_child().unwrap();
|
||||||
|
node.set_text_content(Some(&format!(
|
||||||
|
"Setting {} from {} to {}",
|
||||||
|
name.as_string().unwrap_or("None".to_owned()),
|
||||||
|
old_value.as_string().unwrap_or("None".to_owned()),
|
||||||
|
new_value.as_string().unwrap_or("None".to_owned()),
|
||||||
|
)));
|
||||||
|
element.append_child(&node).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer::new("custom-element::timing");
|
||||||
|
let handle = BenchElement::define();
|
||||||
|
|
||||||
|
let body = window().unwrap().document().unwrap().body().unwrap();
|
||||||
|
for _ in 1..100000 {
|
||||||
|
let el = BenchElement::create();
|
||||||
|
body.append_child(&el).unwrap();
|
||||||
|
el.set_attribute("class", "foo").unwrap();
|
||||||
|
body.remove_child(&el).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE(jwall): We can only construct the web component once and since the lifetime of the component internals is tied
|
// NOTE(jwall): We can only construct the web component once and since the lifetime of the component internals is tied
|
||||||
// to the handle we run this all in one single function.
|
// to the handle we run this all in one single function.
|
||||||
#[wasm_bindgen_test]
|
#[wasm_bindgen_test]
|
||||||
@ -115,28 +188,20 @@ mod tests {
|
|||||||
|
|
||||||
impl WebComponentBinding for MyElementImpl {
|
impl WebComponentBinding for MyElementImpl {
|
||||||
fn connected(&self, element: &HtmlElement) {
|
fn connected(&self, element: &HtmlElement) {
|
||||||
log("Firing connected call back".to_owned());
|
|
||||||
let node = Text::new().unwrap();
|
let node = Text::new().unwrap();
|
||||||
node.set_text_content(Some("Added a text node on connect".into()));
|
node.set_text_content(Some("Added a text node on connect".into()));
|
||||||
element.append_child(&node).unwrap();
|
element.append_child(&node).unwrap();
|
||||||
log(format!(
|
|
||||||
"element contents: {}",
|
|
||||||
&element.text_content().unwrap()
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn disconnected(&self, element: &HtmlElement) {
|
fn disconnected(&self, element: &HtmlElement) {
|
||||||
log("Firing discconnected call back".to_owned());
|
|
||||||
let node = element.first_child().unwrap();
|
let node = element.first_child().unwrap();
|
||||||
element.remove_child(&node).unwrap();
|
element.remove_child(&node).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn adopted(&self, element: &HtmlElement) {
|
fn adopted(&self, element: &HtmlElement) {
|
||||||
log("Firing adopted call back".to_owned());
|
|
||||||
let node = Text::new().unwrap();
|
let node = Text::new().unwrap();
|
||||||
node.set_text_content(Some("Added a text node on adopt".into()));
|
node.set_text_content(Some("Added a text node on adopt".into()));
|
||||||
element.append_child(&node).unwrap();
|
element.append_child(&node).unwrap();
|
||||||
log_with_val("element: ".to_owned(), element);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn attribute_changed(
|
fn attribute_changed(
|
||||||
@ -146,7 +211,6 @@ mod tests {
|
|||||||
old_value: JsValue,
|
old_value: JsValue,
|
||||||
new_value: JsValue,
|
new_value: JsValue,
|
||||||
) {
|
) {
|
||||||
log("Firing attribute changed callback".to_owned());
|
|
||||||
let node = element.first_child().unwrap();
|
let node = element.first_child().unwrap();
|
||||||
node.set_text_content(Some(&format!(
|
node.set_text_content(Some(&format!(
|
||||||
"Setting {} from {} to {}",
|
"Setting {} from {} to {}",
|
||||||
@ -155,7 +219,6 @@ mod tests {
|
|||||||
new_value.as_string().unwrap_or("None".to_owned()),
|
new_value.as_string().unwrap_or("None".to_owned()),
|
||||||
)));
|
)));
|
||||||
element.append_child(&node).unwrap();
|
element.append_child(&node).unwrap();
|
||||||
log_with_val("element: ".to_owned(), element);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let obj = MyElementImpl::define().expect("Failed to define web component");
|
let obj = MyElementImpl::define().expect("Failed to define web component");
|
||||||
@ -187,16 +250,19 @@ mod tests {
|
|||||||
"Setting class from None to foo"
|
"Setting class from None to foo"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// NOTE(jwall): If we are running headless then this can fail sometimes.
|
||||||
|
// We don't fail the test when that happens.
|
||||||
|
if let Ok(Some(new_window)) = window().unwrap().open() {
|
||||||
// Test the adopted callback
|
// Test the adopted callback
|
||||||
// First we need a new window with a new document to perform the adoption with.
|
// First we need a new window with a new document to perform the adoption with.
|
||||||
let new_window = window().unwrap().open().unwrap().unwrap();
|
|
||||||
// Then we can have the new document adopt this node.
|
|
||||||
new_window.document().unwrap().adopt_node(&element).unwrap();
|
new_window.document().unwrap().adopt_node(&element).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
element.text_content().unwrap(),
|
element.text_content().unwrap(),
|
||||||
"Added a text node on adopt"
|
"Added a text node on adopt"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// Then we can have the new document adopt this node.
|
||||||
|
}
|
||||||
|
|
||||||
#[wasm_bindgen_test]
|
#[wasm_bindgen_test]
|
||||||
fn test_component_no_element_name() {
|
fn test_component_no_element_name() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user