mirror of
https://github.com/servo/servo.git
synced 2025-08-04 05:00:08 +01:00
Scope chain is now constructed
This commit is contained in:
parent
2373769e76
commit
59f66fe09d
3 changed files with 95 additions and 11 deletions
|
@ -30,6 +30,7 @@ use crate::dom::element::Element;
|
||||||
use crate::dom::errorevent::ErrorEvent;
|
use crate::dom::errorevent::ErrorEvent;
|
||||||
use crate::dom::event::{Event, EventBubbles, EventCancelable, EventStatus};
|
use crate::dom::event::{Event, EventBubbles, EventCancelable, EventStatus};
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
|
use crate::dom::htmlformelement::FormControlElementHelpers;
|
||||||
use crate::dom::node::document_from_node;
|
use crate::dom::node::document_from_node;
|
||||||
use crate::dom::virtualmethods::VirtualMethods;
|
use crate::dom::virtualmethods::VirtualMethods;
|
||||||
use crate::dom::window::Window;
|
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
|
// https://html.spec.whatwg.org/multipage/#getting-the-current-value-of-the-event-handler
|
||||||
|
// step 3
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
fn get_compiled_event_handler(
|
fn get_compiled_event_handler(
|
||||||
&self,
|
&self,
|
||||||
handler: InternalRawUncompiledHandler,
|
handler: InternalRawUncompiledHandler,
|
||||||
ty: &Atom,
|
ty: &Atom,
|
||||||
) -> Option<CommonEventHandler> {
|
) -> Option<CommonEventHandler> {
|
||||||
// Step 1.1
|
// Step 3.1
|
||||||
let element = self.downcast::<Element>();
|
let element = self.downcast::<Element>();
|
||||||
let document = match element {
|
let document = match element {
|
||||||
Some(element) => document_from_node(element),
|
Some(element) => document_from_node(element),
|
||||||
None => self.downcast::<Window>().unwrap().Document(),
|
None => self.downcast::<Window>().unwrap().Document(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Step 1.2
|
// Step 3.2
|
||||||
if !document.is_scripting_enabled() {
|
if !document.is_scripting_enabled() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 1.3
|
// Step 3.3
|
||||||
let body: Vec<u16> = handler.source.encode_utf16().collect();
|
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 window = document.window();
|
||||||
|
|
||||||
let url_serialized = CString::new(handler.url.to_string()).unwrap();
|
let url_serialized = CString::new(handler.url.to_string()).unwrap();
|
||||||
let name = CString::new(&**ty).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 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] = [
|
static mut ERROR_ARG_NAMES: [*const c_char; 5] = [
|
||||||
b"event\0" as *const u8 as *const c_char,
|
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"colno\0" as *const u8 as *const c_char,
|
||||||
b"error\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 is_error = ty == &atom!("error") && self.is::<Window>();
|
||||||
let args = unsafe {
|
let args = unsafe {
|
||||||
if is_error {
|
if is_error {
|
||||||
|
@ -501,11 +516,19 @@ impl EventTarget {
|
||||||
|
|
||||||
let cx = window.get_cx();
|
let cx = window.get_cx();
|
||||||
let options = CompileOptionsWrapper::new(*cx, url_serialized.as_ptr(), handler.line as u32);
|
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 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>());
|
rooted!(in(*cx) let mut handler = ptr::null_mut::<JSFunction>());
|
||||||
let rv = unsafe {
|
let rv = unsafe {
|
||||||
CompileFunction(
|
CompileFunction(
|
||||||
|
@ -525,17 +548,20 @@ impl EventTarget {
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
if !rv || handler.get().is_null() {
|
if !rv || handler.get().is_null() {
|
||||||
// Step 1.8.2
|
// Step 3.7
|
||||||
unsafe {
|
unsafe {
|
||||||
let _ac = JSAutoRealm::new(*cx, self.reflector().get_jsobject().get());
|
let _ac = JSAutoRealm::new(*cx, self.reflector().get_jsobject().get());
|
||||||
// FIXME(#13152): dispatch error event.
|
// FIXME(#13152): dispatch error event.
|
||||||
report_pending_exception(*cx, false);
|
report_pending_exception(*cx, false);
|
||||||
}
|
}
|
||||||
// Step 1.8.1 / 1.8.3
|
|
||||||
return None;
|
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()) };
|
let funobj = unsafe { JS_GetFunctionObject(handler.get()) };
|
||||||
assert!(!funobj.is_null());
|
assert!(!funobj.is_null());
|
||||||
// Step 1.14
|
// Step 1.14
|
||||||
|
|
|
@ -11453,6 +11453,12 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"mozilla/compile-event-handler-lexical-scopes-simple.html": [
|
||||||
|
[
|
||||||
|
"mozilla/compile-event-handler-lexical-scopes-simple.html",
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"mozilla/createEvent-storageevent.html": [
|
"mozilla/createEvent-storageevent.html": [
|
||||||
[
|
[
|
||||||
"mozilla/createEvent-storageevent.html",
|
"mozilla/createEvent-storageevent.html",
|
||||||
|
@ -18589,6 +18595,10 @@
|
||||||
"8e06ffcc0933719b4b79ea6656d6635cc121d900",
|
"8e06ffcc0933719b4b79ea6656d6635cc121d900",
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
|
"mozilla/compile-event-handler-lexical-scopes-simple.html": [
|
||||||
|
"7d1e1839390ea16183bffd09eef4e3445d5d8e16",
|
||||||
|
"testharness"
|
||||||
|
],
|
||||||
"mozilla/createEvent-storageevent.html": [
|
"mozilla/createEvent-storageevent.html": [
|
||||||
"f5deb0173b1459a655ecd62d1c1fd1b45c42c35b",
|
"f5deb0173b1459a655ecd62d1c1fd1b45c42c35b",
|
||||||
"testharness"
|
"testharness"
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Lexical scopes when compiling an inline event handler (easy mode)</title>
|
||||||
|
<link rel="help" href="https://html.spec.whatwg.org/C/#getting-the-current-value-of-the-event-handler">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
setup({allow_uncaught_exception: true});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- Testing just the core of
|
||||||
|
html/webappapis/scripting/events/compile-event-handler-lexical-scopes.html
|
||||||
|
to have a test for it that works while #25199 is open -->
|
||||||
|
|
||||||
|
<form method="POST">
|
||||||
|
<input value="hello" onclick="
|
||||||
|
window.testResults.value = value;
|
||||||
|
window.testResults.self = this;
|
||||||
|
window.testResults.method = method;
|
||||||
|
window.testResults.contentType = contentType;
|
||||||
|
window.testResults.input_var = input_var;
|
||||||
|
window.testResults.form_var = form_var;
|
||||||
|
window.testResults.doc_var = doc_var;
|
||||||
|
">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
window.testResults = {};
|
||||||
|
|
||||||
|
document.querySelector("input").input_var = 1;
|
||||||
|
document.querySelector("form").form_var = 2;
|
||||||
|
document.doc_var = 3;
|
||||||
|
|
||||||
|
document.querySelector("input").click();
|
||||||
|
|
||||||
|
assert_equals(window.testResults.value, "hello");
|
||||||
|
assert_in_array(window.testResults.method, ["POST","post"]);
|
||||||
|
assert_equals(window.testResults.contentType, "text/html");
|
||||||
|
assert_equals(window.testResults.self, document.querySelector("input"));
|
||||||
|
assert_equals(window.testResults.input_var, 1);
|
||||||
|
assert_equals(window.testResults.form_var, 2);
|
||||||
|
assert_equals(window.testResults.doc_var, 3);
|
||||||
|
}, "Element, form owner, and document all expose expandos and IDL properties");
|
||||||
|
</script>
|
Loading…
Add table
Add a link
Reference in a new issue