aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/eventtarget.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/eventtarget.rs')
-rw-r--r--components/script/dom/eventtarget.rs48
1 files changed, 37 insertions, 11 deletions
diff --git a/components/script/dom/eventtarget.rs b/components/script/dom/eventtarget.rs
index ea259a6d2d7..cb42539a8e5 100644
--- a/components/script/dom/eventtarget.rs
+++ b/components/script/dom/eventtarget.rs
@@ -30,6 +30,7 @@ use crate::dom::element::Element;
use crate::dom::errorevent::ErrorEvent;
use crate::dom::event::{Event, EventBubbles, EventCancelable, EventStatus};
use crate::dom::globalscope::GlobalScope;
+use crate::dom::htmlformelement::FormControlElementHelpers;
use crate::dom::node::document_from_node;
use crate::dom::virtualmethods::VirtualMethods;
use crate::dom::window::Window;
@@ -452,35 +453,50 @@ impl EventTarget {
}
// https://html.spec.whatwg.org/multipage/#getting-the-current-value-of-the-event-handler
+ // step 3
#[allow(unsafe_code)]
fn get_compiled_event_handler(
&self,
handler: InternalRawUncompiledHandler,
ty: &Atom,
) -> Option<CommonEventHandler> {
- // Step 1.1
+ // Step 3.1
let element = self.downcast::<Element>();
let document = match element {
Some(element) => document_from_node(element),
None => self.downcast::<Window>().unwrap().Document(),
};
- // Step 1.2
+ // Step 3.2
if !document.is_scripting_enabled() {
return None;
}
- // Step 1.3
+ // Step 3.3
let body: Vec<u16> = handler.source.encode_utf16().collect();
- // TODO step 1.5 (form owner)
+ // Step 3.4 is handler.line
- // Step 1.6
+ // Step 3.5
+ let form_owner = element
+ .and_then(|e| e.as_maybe_form_control())
+ .and_then(|f| f.form_owner());
+
+ // Step 3.6 TODO: settings objects not implemented
+
+ // Step 3.7 is written as though we call the parser separately
+ // from the compiler; since we just call CompileFunction with
+ // source text, we handle parse errors later
+
+ // Step 3.8 TODO: settings objects not implemented
+
+ // Step 3.9
let window = document.window();
let url_serialized = CString::new(handler.url.to_string()).unwrap();
let name = CString::new(&**ty).unwrap();
+ // Step 3.9, subsection ParameterList
static mut ARG_NAMES: [*const c_char; 1] = [b"event\0" as *const u8 as *const c_char];
static mut ERROR_ARG_NAMES: [*const c_char; 5] = [
b"event\0" as *const u8 as *const c_char,
@@ -489,7 +505,6 @@ impl EventTarget {
b"colno\0" as *const u8 as *const c_char,
b"error\0" as *const u8 as *const c_char,
];
- // step 10
let is_error = ty == &atom!("error") && self.is::<Window>();
let args = unsafe {
if is_error {
@@ -501,11 +516,19 @@ impl EventTarget {
let cx = window.get_cx();
let options = CompileOptionsWrapper::new(*cx, url_serialized.as_ptr(), handler.line as u32);
- // TODO step 1.10.1-3 (document, form owner, element in scope chain)
+ // Step 3.9, subsection Scope steps 1-6
let scopechain = AutoObjectVectorWrapper::new(*cx);
- let _ac = enter_realm(&*window);
+ if let Some(element) = element {
+ scopechain.append(document.reflector().get_jsobject().get());
+ if let Some(form_owner) = form_owner {
+ scopechain.append(form_owner.reflector().get_jsobject().get());
+ }
+ scopechain.append(element.reflector().get_jsobject().get());
+ }
+
+ let _ac = enter_realm(&*window); // TODO 3.8 should replace this
rooted!(in(*cx) let mut handler = ptr::null_mut::<JSFunction>());
let rv = unsafe {
CompileFunction(
@@ -525,17 +548,20 @@ impl EventTarget {
)
};
if !rv || handler.get().is_null() {
- // Step 1.8.2
+ // Step 3.7
unsafe {
let _ac = JSAutoRealm::new(*cx, self.reflector().get_jsobject().get());
// FIXME(#13152): dispatch error event.
report_pending_exception(*cx, false);
}
- // Step 1.8.1 / 1.8.3
return None;
}
- // TODO step 1.11-13
+ // Step 3.10 happens when we drop _ac
+
+ // TODO Step 3.11
+
+ // Step 3.12
let funobj = unsafe { JS_GetFunctionObject(handler.get()) };
assert!(!funobj.is_null());
// Step 1.14