Auto merge of #26434 - jdm:playground, r=Manishearth

Allow BabylonJS playground to load

These changes fix the JS errors that currently appear when loading the page. You can't use the editor, but the webgl canvas works just fine.

---
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #26428 and fix #25478
- [x] There are tests for these changes
This commit is contained in:
bors-servo 2020-05-13 15:40:23 -04:00 committed by GitHub
commit 52d9fb57fb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 69 additions and 46 deletions

View file

@ -3669,6 +3669,11 @@ impl ProfilerMetadataFactory for Document {
} }
impl DocumentMethods for Document { impl DocumentMethods for Document {
// https://w3c.github.io/editing/ActiveDocuments/execCommand.html#querycommandsupported()
fn QueryCommandSupported(&self, _command: DOMString) -> bool {
false
}
// https://drafts.csswg.org/cssom/#dom-document-stylesheets // https://drafts.csswg.org/cssom/#dom-document-stylesheets
fn StyleSheets(&self) -> DomRoot<StyleSheetList> { fn StyleSheets(&self) -> DomRoot<StyleSheetList> {
self.stylesheet_list.or_init(|| { self.stylesheet_list.or_init(|| {

View file

@ -690,12 +690,15 @@ fn inner_invoke(
object.remove_listener_if_once(&event.type_(), &event_listener); object.remove_listener_if_once(&event.type_(), &event_listener);
} }
// Step 2.6-2.8 // Step 2.6
// FIXME(#25478): we need to get the global that the event let global = listener.associated_global();
// listener is going to be called on, then if it's a Window
// set its .event to the event, remembering the previous // Step 2.7-2.8
// value of its .event. This allows events to just use let current_event = if let Some(window) = global.downcast::<Window>() {
// the word "event" instead of taking the event as an argument. window.set_current_event(Some(event))
} else {
None
};
// Step 2.9 TODO: EventListener passive option not implemented // Step 2.9 TODO: EventListener passive option not implemented
@ -712,8 +715,9 @@ fn inner_invoke(
// Step 2.11 TODO: passive not implemented // Step 2.11 TODO: passive not implemented
// Step 2.12 // Step 2.12
// TODO This is where we put back the .event we if let Some(window) = global.downcast::<Window>() {
// had before step 2.6. window.set_current_event(current_event.as_ref().map(|e| &**e));
}
// Step 2.13: short-circuit instead of going to next listener // Step 2.13: short-circuit instead of going to next listener
if event.stop_immediate.get() { if event.stop_immediate.get() {

View file

@ -150,6 +150,23 @@ pub enum CompiledEventListener {
} }
impl CompiledEventListener { impl CompiledEventListener {
#[allow(unsafe_code)]
pub fn associated_global(&self) -> DomRoot<GlobalScope> {
let obj = match self {
CompiledEventListener::Listener(listener) => listener.callback(),
CompiledEventListener::Handler(CommonEventHandler::EventHandler(handler)) => {
handler.callback()
},
CompiledEventListener::Handler(CommonEventHandler::ErrorEventHandler(handler)) => {
handler.callback()
},
CompiledEventListener::Handler(CommonEventHandler::BeforeUnloadEventHandler(
handler,
)) => handler.callback(),
};
unsafe { GlobalScope::from_object(obj) }
}
// https://html.spec.whatwg.org/multipage/#the-event-handler-processing-algorithm // https://html.spec.whatwg.org/multipage/#the-event-handler-processing-algorithm
pub fn call_or_handle_event( pub fn call_or_handle_event(
&self, &self,

View file

@ -142,7 +142,7 @@ partial /*sealed*/ interface Document {
// boolean queryCommandEnabled(DOMString commandId); // boolean queryCommandEnabled(DOMString commandId);
// boolean queryCommandIndeterm(DOMString commandId); // boolean queryCommandIndeterm(DOMString commandId);
// boolean queryCommandState(DOMString commandId); // boolean queryCommandState(DOMString commandId);
// boolean queryCommandSupported(DOMString commandId); boolean queryCommandSupported(DOMString commandId);
// DOMString queryCommandValue(DOMString commandId); // DOMString queryCommandValue(DOMString commandId);
// special event handler IDL attributes that only apply to Document objects // special event handler IDL attributes that only apply to Document objects

View file

@ -180,6 +180,10 @@ partial interface Window {
Selection? getSelection(); Selection? getSelection();
}; };
// https://dom.spec.whatwg.org/#interface-window-extensions
partial interface Window {
[Replaceable] readonly attribute any event; // historical
};
dictionary WindowPostMessageOptions : PostMessageOptions { dictionary WindowPostMessageOptions : PostMessageOptions {
USVString targetOrigin = "/"; USVString targetOrigin = "/";

View file

@ -83,6 +83,7 @@ use euclid::default::{Point2D as UntypedPoint2D, Rect as UntypedRect};
use euclid::{Point2D, Rect, Scale, Size2D, Vector2D}; use euclid::{Point2D, Rect, Scale, Size2D, Vector2D};
use ipc_channel::ipc::IpcSender; use ipc_channel::ipc::IpcSender;
use ipc_channel::router::ROUTER; use ipc_channel::router::ROUTER;
use js::conversions::ToJSValConvertible;
use js::jsapi::Heap; use js::jsapi::Heap;
use js::jsapi::JSAutoRealm; use js::jsapi::JSAutoRealm;
use js::jsapi::JSObject; use js::jsapi::JSObject;
@ -340,6 +341,9 @@ pub struct Window {
/// those values will cause the marker to be set to false. /// those values will cause the marker to be set to false.
#[ignore_malloc_size_of = "Rc is hard"] #[ignore_malloc_size_of = "Rc is hard"]
layout_marker: DomRefCell<Rc<Cell<bool>>>, layout_marker: DomRefCell<Rc<Cell<bool>>>,
/// https://dom.spec.whatwg.org/#window-current-event
current_event: DomRefCell<Option<Dom<Event>>>,
} }
impl Window { impl Window {
@ -1334,9 +1338,34 @@ impl WindowMethods for Window {
fn GetSelection(&self) -> Option<DomRoot<Selection>> { fn GetSelection(&self) -> Option<DomRoot<Selection>> {
self.document.get().and_then(|d| d.GetSelection()) self.document.get().and_then(|d| d.GetSelection())
} }
// https://dom.spec.whatwg.org/#dom-window-event
#[allow(unsafe_code)]
fn Event(&self, cx: JSContext) -> JSVal {
rooted!(in(*cx) let mut rval = UndefinedValue());
if let Some(ref event) = *self.current_event.borrow() {
unsafe {
event
.reflector()
.get_jsobject()
.to_jsval(*cx, rval.handle_mut());
}
}
rval.get()
}
} }
impl Window { impl Window {
pub(crate) fn set_current_event(&self, event: Option<&Event>) -> Option<DomRoot<Event>> {
let current = self
.current_event
.borrow()
.as_ref()
.map(|e| DomRoot::from_ref(&**e));
*self.current_event.borrow_mut() = event.map(|e| Dom::from_ref(e));
current
}
/// https://html.spec.whatwg.org/multipage/#window-post-message-steps /// https://html.spec.whatwg.org/multipage/#window-post-message-steps
fn post_message_impl( fn post_message_impl(
&self, &self,
@ -2375,6 +2404,7 @@ impl Window {
event_loop_waker, event_loop_waker,
visible: Cell::new(true), visible: Cell::new(true),
layout_marker: DomRefCell::new(Rc::new(Cell::new(true))), layout_marker: DomRefCell::new(Rc::new(Cell::new(true))),
current_event: DomRefCell::new(None),
}); });
unsafe { WindowBinding::Wrap(JSContext::from_ptr(runtime.cx()), win) } unsafe { WindowBinding::Wrap(JSContext::from_ptr(runtime.cx()), win) }

View file

@ -1,19 +1,6 @@
[event-global.html] [event-global.html]
[event exists on window, which is initially set to undefined]
expected: FAIL
[window.event is only defined during dispatch]
expected: FAIL
[window.event is undefined if the target is in a shadow tree (event dispatched outside shadow tree)] [window.event is undefined if the target is in a shadow tree (event dispatched outside shadow tree)]
expected: FAIL expected: FAIL
[window.event is undefined if the target is in a shadow tree (event dispatched inside shadow tree)] [window.event is undefined if the target is in a shadow tree (event dispatched inside shadow tree)]
expected: FAIL expected: FAIL
[window.event is set to the current event during dispatch]
expected: FAIL
[window.event is set to the current event, which is the event passed to dispatch]
expected: FAIL

View file

@ -152,9 +152,6 @@
[AbortSignal interface object length] [AbortSignal interface object length]
expected: FAIL expected: FAIL
[Window interface: attribute event]
expected: FAIL
[AbortController interface: new AbortController() must inherit property "abort()" with the proper type] [AbortController interface: new AbortController() must inherit property "abort()" with the proper type]
expected: FAIL expected: FAIL

View file

@ -1417,9 +1417,6 @@
[Document interface: iframe.contentDocument must inherit property "dir" with the proper type] [Document interface: iframe.contentDocument must inherit property "dir" with the proper type]
expected: FAIL expected: FAIL
[Document interface: new Document() must inherit property "queryCommandSupported(DOMString)" with the proper type]
expected: FAIL
[Window interface: attribute onsecuritypolicyviolation] [Window interface: attribute onsecuritypolicyviolation]
expected: FAIL expected: FAIL
@ -1441,9 +1438,6 @@
[Window interface: attribute menubar] [Window interface: attribute menubar]
expected: FAIL expected: FAIL
[Document interface: calling queryCommandSupported(DOMString) on documentWithHandlers with too few arguments must throw TypeError]
expected: FAIL
[Document interface: attribute designMode] [Document interface: attribute designMode]
expected: FAIL expected: FAIL
@ -1480,15 +1474,9 @@
[Document interface: calling execCommand(DOMString, boolean, DOMString) on new Document() with too few arguments must throw TypeError] [Document interface: calling execCommand(DOMString, boolean, DOMString) on new Document() with too few arguments must throw TypeError]
expected: FAIL expected: FAIL
[Document interface: calling queryCommandSupported(DOMString) on new Document() with too few arguments must throw TypeError]
expected: FAIL
[Window interface: operation focus()] [Window interface: operation focus()]
expected: FAIL expected: FAIL
[Document interface: documentWithHandlers must inherit property "queryCommandSupported(DOMString)" with the proper type]
expected: FAIL
[Window interface: attribute scrollbars] [Window interface: attribute scrollbars]
expected: FAIL expected: FAIL
@ -1516,9 +1504,6 @@
[Document interface: iframe.contentDocument must inherit property "queryCommandValue(DOMString)" with the proper type] [Document interface: iframe.contentDocument must inherit property "queryCommandValue(DOMString)" with the proper type]
expected: FAIL expected: FAIL
[Document interface: operation queryCommandSupported(DOMString)]
expected: FAIL
[Document interface: iframe.contentDocument must inherit property "all" with the proper type] [Document interface: iframe.contentDocument must inherit property "all" with the proper type]
expected: FAIL expected: FAIL
@ -1588,9 +1573,6 @@
[Window interface: window must inherit property "blur()" with the proper type] [Window interface: window must inherit property "blur()" with the proper type]
expected: FAIL expected: FAIL
[Document interface: iframe.contentDocument must inherit property "queryCommandSupported(DOMString)" with the proper type]
expected: FAIL
[Document interface: calling execCommand(DOMString, boolean, DOMString) on iframe.contentDocument with too few arguments must throw TypeError] [Document interface: calling execCommand(DOMString, boolean, DOMString) on iframe.contentDocument with too few arguments must throw TypeError]
expected: FAIL expected: FAIL
@ -1621,9 +1603,6 @@
[Document interface: iframe.contentDocument must inherit property "queryCommandEnabled(DOMString)" with the proper type] [Document interface: iframe.contentDocument must inherit property "queryCommandEnabled(DOMString)" with the proper type]
expected: FAIL expected: FAIL
[Document interface: calling queryCommandSupported(DOMString) on iframe.contentDocument with too few arguments must throw TypeError]
expected: FAIL
[Window interface: operation blur()] [Window interface: operation blur()]
expected: FAIL expected: FAIL