mirror of
https://github.com/servo/servo.git
synced 2025-06-21 15:49:04 +01:00
Implement element upgrade algorithm
This commit is contained in:
parent
8c5005fc44
commit
ec528e944a
1 changed files with 68 additions and 2 deletions
|
@ -20,14 +20,14 @@ use dom::domexception::{DOMErrorName, DOMException};
|
||||||
use dom::element::Element;
|
use dom::element::Element;
|
||||||
use dom::globalscope::GlobalScope;
|
use dom::globalscope::GlobalScope;
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::node::Node;
|
use dom::node::{document_from_node, Node, window_from_node};
|
||||||
use dom::promise::Promise;
|
use dom::promise::Promise;
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use html5ever::{LocalName, Namespace, Prefix};
|
use html5ever::{LocalName, Namespace, Prefix};
|
||||||
use js::conversions::ToJSValConvertible;
|
use js::conversions::ToJSValConvertible;
|
||||||
use js::jsapi::{Construct1, IsCallable, IsConstructor, HandleValueArray, HandleObject, MutableHandleValue};
|
use js::jsapi::{Construct1, IsCallable, IsConstructor, HandleValueArray, HandleObject, MutableHandleValue};
|
||||||
use js::jsapi::{Heap, JS_GetProperty, JSAutoCompartment, JSContext};
|
use js::jsapi::{Heap, JS_GetProperty, JS_SameValue, JSAutoCompartment, JSContext};
|
||||||
use js::jsval::{JSVal, NullValue, ObjectValue, UndefinedValue};
|
use js::jsval::{JSVal, NullValue, ObjectValue, UndefinedValue};
|
||||||
use microtask::Microtask;
|
use microtask::Microtask;
|
||||||
use script_thread::ScriptThread;
|
use script_thread::ScriptThread;
|
||||||
|
@ -462,6 +462,72 @@ impl CustomElementDefinition {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// https://html.spec.whatwg.org/multipage/#concept-upgrade-an-element
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
fn upgrade_element(definition: Rc<CustomElementDefinition>, element: &Element) {
|
||||||
|
// TODO: Steps 1-2
|
||||||
|
// Track custom element state
|
||||||
|
|
||||||
|
// Step 3
|
||||||
|
for attr in element.attrs().iter() {
|
||||||
|
let local_name = attr.local_name().clone();
|
||||||
|
let value = DOMString::from(&**attr.value());
|
||||||
|
let namespace = attr.namespace().clone();
|
||||||
|
ScriptThread::enqueue_callback_reaction(element,
|
||||||
|
CallbackReaction::AttributeChanged(local_name, None, Some(value), namespace));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 4
|
||||||
|
if element.is_connected() {
|
||||||
|
ScriptThread::enqueue_callback_reaction(element, CallbackReaction::Connected);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 5
|
||||||
|
definition.construction_stack.borrow_mut().push(ConstructionStackEntry::Element(Root::from_ref(element)));
|
||||||
|
|
||||||
|
// Step 6
|
||||||
|
let window = window_from_node(element);
|
||||||
|
let cx = window.get_cx();
|
||||||
|
rooted!(in(cx) let constructor = ObjectValue(definition.constructor.callback()));
|
||||||
|
rooted!(in(cx) let mut element_val = UndefinedValue());
|
||||||
|
unsafe { element.to_jsval(cx, element_val.handle_mut()); }
|
||||||
|
rooted!(in(cx) let mut construct_result = ptr::null_mut());
|
||||||
|
{
|
||||||
|
// Go into the constructor's compartment
|
||||||
|
let _ac = JSAutoCompartment::new(cx, definition.constructor.callback());
|
||||||
|
let args = HandleValueArray::new();
|
||||||
|
// Step 7
|
||||||
|
if unsafe { !Construct1(cx, constructor.handle(), &args, construct_result.handle_mut()) } {
|
||||||
|
// TODO: Catch exceptions
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Step 8
|
||||||
|
let mut same = false;
|
||||||
|
rooted!(in(cx) let construct_result_val = ObjectValue(construct_result.get()));
|
||||||
|
if unsafe { !JS_SameValue(cx, construct_result_val.handle(), element_val.handle(), &mut same) } {
|
||||||
|
// TODO: Catch exceptions
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if !same {
|
||||||
|
// TODO: Throw InvalidStateError
|
||||||
|
}
|
||||||
|
}
|
||||||
|
definition.construction_stack.borrow_mut().pop();
|
||||||
|
// TODO: Handle Exceptions
|
||||||
|
|
||||||
|
element.set_custom_element_definition(definition);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://html.spec.whatwg.org/multipage/#concept-try-upgrade
|
||||||
|
pub fn try_upgrade_element(element: &Element) {
|
||||||
|
// Step 1
|
||||||
|
let document = document_from_node(element);
|
||||||
|
if let Some(definition) = document.lookup_custom_element_definition(element.local_name().clone(), element.get_is()) {
|
||||||
|
// Step 2
|
||||||
|
ScriptThread::enqueue_upgrade_reaction(element, definition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(HeapSizeOf, JSTraceable)]
|
#[derive(HeapSizeOf, JSTraceable)]
|
||||||
#[must_root]
|
#[must_root]
|
||||||
pub enum CustomElementReaction {
|
pub enum CustomElementReaction {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue