webgl: Implement WebGLContextEvent and use it on context creation error

spec: https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15
This commit is contained in:
Emilio Cobos Álvarez 2015-10-03 21:09:54 +02:00
parent 217c7da413
commit 7030f09823
8 changed files with 146 additions and 2 deletions

View file

@ -36,7 +36,8 @@ pub enum EventTypeId {
StorageEvent, StorageEvent,
UIEvent(UIEventTypeId), UIEvent(UIEventTypeId),
ErrorEvent, ErrorEvent,
CloseEvent CloseEvent,
WebGLContextEvent,
} }
#[derive(PartialEq, HeapSizeOf)] #[derive(PartialEq, HeapSizeOf)]

View file

@ -335,6 +335,7 @@ pub mod validitystate;
pub mod virtualmethods; pub mod virtualmethods;
pub mod webglactiveinfo; pub mod webglactiveinfo;
pub mod webglbuffer; pub mod webglbuffer;
pub mod webglcontextevent;
pub mod webglframebuffer; pub mod webglframebuffer;
pub mod webglobject; pub mod webglobject;
pub mod webglprogram; pub mod webglprogram;

View file

@ -0,0 +1,87 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
use dom::bindings::codegen::Bindings::WebGLContextEventBinding;
use dom::bindings::codegen::Bindings::WebGLContextEventBinding::WebGLContextEventInit;
use dom::bindings::codegen::Bindings::WebGLContextEventBinding::WebGLContextEventMethods;
use dom::bindings::codegen::InheritTypes::{WebGLContextEventDerived, EventCast};
use dom::bindings::error::Fallible;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{Root, RootedReference};
use dom::bindings::utils::reflect_dom_object;
use dom::event::{Event, EventBubbles, EventCancelable, EventTypeId};
use util::str::DOMString;
#[dom_struct]
pub struct WebGLContextEvent {
event: Event,
status_message: DOMString,
}
impl WebGLContextEventMethods for WebGLContextEvent {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15
fn StatusMessage(&self) -> DOMString {
self.status_message.clone()
}
}
impl WebGLContextEventDerived for Event {
fn is_webglcontextevent(&self) -> bool {
*self.type_id() == EventTypeId::WebGLContextEvent
}
}
impl WebGLContextEvent {
pub fn new_inherited(type_id: EventTypeId, status_message: DOMString) -> WebGLContextEvent {
WebGLContextEvent {
event: Event::new_inherited(type_id),
status_message: status_message,
}
}
pub fn new(global: GlobalRef,
type_: DOMString,
bubbles: EventBubbles,
cancelable: EventCancelable,
status_message: DOMString) -> Root<WebGLContextEvent> {
let event = reflect_dom_object(
box WebGLContextEvent::new_inherited(EventTypeId::WebGLContextEvent, status_message),
global,
WebGLContextEventBinding::Wrap);
{
let parent = EventCast::from_ref(event.r());
parent.InitEvent(type_, bubbles == EventBubbles::Bubbles, cancelable == EventCancelable::Cancelable);
}
event
}
pub fn Constructor(global: GlobalRef,
type_: DOMString,
init: &WebGLContextEventInit) -> Fallible<Root<WebGLContextEvent>> {
let status_message = match init.statusMessage.as_ref() {
Some(message) => message.clone(),
None => "".to_owned(),
};
let bubbles = if init.parent.bubbles {
EventBubbles::Bubbles
} else {
EventBubbles::DoesNotBubble
};
let cancelable = if init.parent.cancelable {
EventCancelable::Cancelable
} else {
EventCancelable::NotCancelable
};
Ok(WebGLContextEvent::new(global, type_,
bubbles,
cancelable,
status_message))
}
}

View file

@ -8,16 +8,18 @@ use canvas_traits::{WebGLFramebufferBindingRequest, WebGLShaderParameter};
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::{WebGLRenderingContextMethods}; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::{WebGLRenderingContextMethods};
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::{self, WebGLContextAttributes}; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::{self, WebGLContextAttributes};
use dom::bindings::codegen::InheritTypes::NodeCast; use dom::bindings::codegen::InheritTypes::{EventCast, EventTargetCast, NodeCast};
use dom::bindings::codegen::UnionTypes::ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement; use dom::bindings::codegen::UnionTypes::ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement;
use dom::bindings::conversions::ToJSValConvertible; use dom::bindings::conversions::ToJSValConvertible;
use dom::bindings::global::{GlobalField, GlobalRef}; use dom::bindings::global::{GlobalField, GlobalRef};
use dom::bindings::js::{JS, LayoutJS, Root}; use dom::bindings::js::{JS, LayoutJS, Root};
use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::bindings::utils::{Reflector, reflect_dom_object};
use dom::event::{EventBubbles, EventCancelable};
use dom::htmlcanvaselement::HTMLCanvasElement; use dom::htmlcanvaselement::HTMLCanvasElement;
use dom::htmlcanvaselement::utils as canvas_utils; use dom::htmlcanvaselement::utils as canvas_utils;
use dom::node::{NodeDamage, window_from_node}; use dom::node::{NodeDamage, window_from_node};
use dom::webglbuffer::WebGLBuffer; use dom::webglbuffer::WebGLBuffer;
use dom::webglcontextevent::WebGLContextEvent;
use dom::webglframebuffer::WebGLFramebuffer; use dom::webglframebuffer::WebGLFramebuffer;
use dom::webglprogram::WebGLProgram; use dom::webglprogram::WebGLProgram;
use dom::webglrenderbuffer::WebGLRenderbuffer; use dom::webglrenderbuffer::WebGLRenderbuffer;
@ -115,6 +117,15 @@ impl WebGLRenderingContext {
WebGLRenderingContextBinding::Wrap)), WebGLRenderingContextBinding::Wrap)),
Err(msg) => { Err(msg) => {
error!("Couldn't create WebGLRenderingContext: {}", msg); error!("Couldn't create WebGLRenderingContext: {}", msg);
let event = WebGLContextEvent::new(global, "webglcontextcreationerror".to_owned(),
EventBubbles::DoesNotBubble,
EventCancelable::Cancelable,
msg);
let event = EventCast::from_ref(event.r());
let target = EventTargetCast::from_ref(canvas);
event.fire(target);
None None
} }
} }

View file

@ -0,0 +1,15 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15
[Constructor(DOMString type, optional WebGLContextEventInit eventInit)]
interface WebGLContextEvent : Event {
readonly attribute DOMString statusMessage;
};
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15
dictionary WebGLContextEventInit : EventInit {
DOMString statusMessage;
};

View file

@ -821,6 +821,12 @@
"url": "/_mozilla/mozilla/union.html" "url": "/_mozilla/mozilla/union.html"
} }
], ],
"mozilla/webgl_context_creation_error.html": [
{
"path": "mozilla/webgl_context_creation_error.html",
"url": "/_mozilla/mozilla/webgl_context_creation_error.html"
}
],
"mozilla/websocket_connection_fail.html": [ "mozilla/websocket_connection_fail.html": [
{ {
"path": "mozilla/websocket_connection_fail.html", "path": "mozilla/websocket_connection_fail.html",

View file

@ -205,6 +205,7 @@ var interfaceNamesInGlobalScope = [
"WebGLRenderingContext", "WebGLRenderingContext",
"WebGLUniformLocation", "WebGLUniformLocation",
"WebGLBuffer", "WebGLBuffer",
"WebGLContextEvent",
"WebGLFramebuffer", "WebGLFramebuffer",
"WebGLRenderbuffer", "WebGLRenderbuffer",
"WebGLTexture", "WebGLTexture",

View file

@ -0,0 +1,22 @@
<!doctype html>
<meta charset="utf-8">
<title>WebGLContextEvent "webglcontextcreationerror" event</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
async_test(function() {
var canvas = document.createElement('canvas');
canvas.addEventListener("webglcontextcreationerror", this.step_func_done(function(e) {
assert_true(e.__proto__ === WebGLContextEvent.prototype,
"webglcontextcreationevent should be a WebGLContextEvent");
assert_true(typeof(e.statusMessage) === "string",
"'statusMessage' should be a string, " + typeof(e.statusMessage) + " found");
}), false);
// Antialising actually is not supported and thus triggers the error event
var gl = canvas.getContext('webgl', { antialiasing: true });
assert_false(!!gl, "WebGLContext creation succeeded, please update this test!");
});
</script>