mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
more refactoring
This commit is contained in:
parent
bb2536cd01
commit
45224028db
115 changed files with 3387 additions and 354 deletions
|
@ -39,7 +39,7 @@ use opaque_node::OpaqueNodeMethods;
|
||||||
use script::dom::attr::AttrValue;
|
use script::dom::attr::AttrValue;
|
||||||
use script::dom::bindings::codegen::InheritTypes::{CharacterDataTypeId, ElementTypeId};
|
use script::dom::bindings::codegen::InheritTypes::{CharacterDataTypeId, ElementTypeId};
|
||||||
use script::dom::bindings::codegen::InheritTypes::{HTMLElementTypeId, NodeTypeId};
|
use script::dom::bindings::codegen::InheritTypes::{HTMLElementTypeId, NodeTypeId};
|
||||||
use script::dom::bindings::conversions::Castable;
|
use script::dom::bindings::inheritance::Castable;
|
||||||
use script::dom::bindings::js::LayoutJS;
|
use script::dom::bindings::js::LayoutJS;
|
||||||
use script::dom::characterdata::LayoutCharacterDataHelpers;
|
use script::dom::characterdata::LayoutCharacterDataHelpers;
|
||||||
use script::dom::document::{Document, LayoutDocumentHelpers};
|
use script::dom::document::{Document, LayoutDocumentHelpers};
|
||||||
|
|
|
@ -16,13 +16,13 @@ pub fn expand_reflector(cx: &mut ExtCtxt, span: Span, _: &MetaItem, annotatable:
|
||||||
let struct_name = item.ident;
|
let struct_name = item.ident;
|
||||||
// This path has to be hardcoded, unfortunately, since we can't resolve paths at expansion time
|
// This path has to be hardcoded, unfortunately, since we can't resolve paths at expansion time
|
||||||
match def.fields.iter().find(
|
match def.fields.iter().find(
|
||||||
|f| match_ty_unwrap(&*f.node.ty, &["dom", "bindings", "utils", "Reflector"]).is_some()) {
|
|f| match_ty_unwrap(&*f.node.ty, &["dom", "bindings", "reflector", "Reflector"]).is_some()) {
|
||||||
// If it has a field that is a Reflector, use that
|
// If it has a field that is a Reflector, use that
|
||||||
Some(f) => {
|
Some(f) => {
|
||||||
let field_name = f.node.ident();
|
let field_name = f.node.ident();
|
||||||
let impl_item = quote_item!(cx,
|
let impl_item = quote_item!(cx,
|
||||||
impl ::dom::bindings::utils::Reflectable for $struct_name {
|
impl ::dom::bindings::reflector::Reflectable for $struct_name {
|
||||||
fn reflector<'a>(&'a self) -> &'a ::dom::bindings::utils::Reflector {
|
fn reflector<'a>(&'a self) -> &'a ::dom::bindings::reflector::Reflector {
|
||||||
&self.$field_name
|
&self.$field_name
|
||||||
}
|
}
|
||||||
fn init_reflector(&mut self, obj: *mut ::js::jsapi::JSObject) {
|
fn init_reflector(&mut self, obj: *mut ::js::jsapi::JSObject) {
|
||||||
|
@ -36,8 +36,8 @@ pub fn expand_reflector(cx: &mut ExtCtxt, span: Span, _: &MetaItem, annotatable:
|
||||||
None => {
|
None => {
|
||||||
let field_name = def.fields[0].node.ident();
|
let field_name = def.fields[0].node.ident();
|
||||||
let impl_item = quote_item!(cx,
|
let impl_item = quote_item!(cx,
|
||||||
impl ::dom::bindings::utils::Reflectable for $struct_name {
|
impl ::dom::bindings::reflector::Reflectable for $struct_name {
|
||||||
fn reflector<'a>(&'a self) -> &'a ::dom::bindings::utils::Reflector {
|
fn reflector<'a>(&'a self) -> &'a ::dom::bindings::reflector::Reflector {
|
||||||
self.$field_name.reflector()
|
self.$field_name.reflector()
|
||||||
}
|
}
|
||||||
fn init_reflector(&mut self, obj: *mut ::js::jsapi::JSObject) {
|
fn init_reflector(&mut self, obj: *mut ::js::jsapi::JSObject) {
|
||||||
|
|
|
@ -10,7 +10,7 @@ use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::inheritance::Castable;
|
use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::js::{JS, MutNullableHeap};
|
use dom::bindings::js::{JS, MutNullableHeap};
|
||||||
use dom::bindings::js::{LayoutJS, Root, RootedReference};
|
use dom::bindings::js::{LayoutJS, Root, RootedReference};
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::element::{AttributeMutation, Element};
|
use dom::element::{AttributeMutation, Element};
|
||||||
use dom::values::UNSIGNED_LONG_MAX;
|
use dom::values::UNSIGNED_LONG_MAX;
|
||||||
use dom::virtualmethods::vtable_for;
|
use dom::virtualmethods::vtable_for;
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
use dom::bindings::error::{Error, Fallible};
|
use dom::bindings::error::{Error, Fallible};
|
||||||
use dom::bindings::global::global_object_for_js_object;
|
use dom::bindings::global::global_object_for_js_object;
|
||||||
use dom::bindings::utils::Reflectable;
|
use dom::bindings::reflector::Reflectable;
|
||||||
use js::jsapi::GetGlobalForObjectCrossCompartment;
|
use js::jsapi::GetGlobalForObjectCrossCompartment;
|
||||||
use js::jsapi::{Heap, MutableHandleObject, RootedObject, RootedValue};
|
use js::jsapi::{Heap, MutableHandleObject, RootedObject, RootedValue};
|
||||||
use js::jsapi::{IsCallable, JSContext, JSObject, JS_WrapObject};
|
use js::jsapi::{IsCallable, JSContext, JSObject, JS_WrapObject};
|
||||||
|
|
|
@ -5197,6 +5197,7 @@ class CGBindingRoot(CGThing):
|
||||||
'dom::bindings::global::global_object_for_js_object',
|
'dom::bindings::global::global_object_for_js_object',
|
||||||
'dom::bindings::js::{JS, Root, RootedReference}',
|
'dom::bindings::js::{JS, Root, RootedReference}',
|
||||||
'dom::bindings::js::{OptionalRootedReference}',
|
'dom::bindings::js::{OptionalRootedReference}',
|
||||||
|
'dom::bindings::reflector::{Reflectable}',
|
||||||
'dom::bindings::utils::{create_dom_global, do_create_interface_objects}',
|
'dom::bindings::utils::{create_dom_global, do_create_interface_objects}',
|
||||||
'dom::bindings::utils::ConstantSpec',
|
'dom::bindings::utils::ConstantSpec',
|
||||||
'dom::bindings::utils::{DOMClass}',
|
'dom::bindings::utils::{DOMClass}',
|
||||||
|
@ -5206,7 +5207,6 @@ class CGBindingRoot(CGThing):
|
||||||
'dom::bindings::utils::{finalize_global, trace_global}',
|
'dom::bindings::utils::{finalize_global, trace_global}',
|
||||||
'dom::bindings::utils::has_property_on_prototype',
|
'dom::bindings::utils::has_property_on_prototype',
|
||||||
'dom::bindings::utils::is_platform_object',
|
'dom::bindings::utils::is_platform_object',
|
||||||
'dom::bindings::utils::{Reflectable}',
|
|
||||||
'dom::bindings::utils::throwing_constructor',
|
'dom::bindings::utils::throwing_constructor',
|
||||||
'dom::bindings::utils::get_dictionary_property',
|
'dom::bindings::utils::get_dictionary_property',
|
||||||
'dom::bindings::utils::set_dictionary_property',
|
'dom::bindings::utils::set_dictionary_property',
|
||||||
|
@ -5915,10 +5915,11 @@ class GlobalGenRoots():
|
||||||
|
|
||||||
descriptors = config.getDescriptors(register=True, isCallback=False)
|
descriptors = config.getDescriptors(register=True, isCallback=False)
|
||||||
imports = [CGGeneric("use dom::types::*;\n"),
|
imports = [CGGeneric("use dom::types::*;\n"),
|
||||||
CGGeneric("use dom::bindings::conversions::{Castable, DerivedFrom, get_dom_class};\n"),
|
CGGeneric("use dom::bindings::conversions::{DerivedFrom, get_dom_class};\n"),
|
||||||
|
CGGeneric("use dom::bindings::inheritance::Castable;\n"),
|
||||||
CGGeneric("use dom::bindings::js::{JS, LayoutJS, Root};\n"),
|
CGGeneric("use dom::bindings::js::{JS, LayoutJS, Root};\n"),
|
||||||
CGGeneric("use dom::bindings::trace::JSTraceable;\n"),
|
CGGeneric("use dom::bindings::trace::JSTraceable;\n"),
|
||||||
CGGeneric("use dom::bindings::utils::Reflectable;\n"),
|
CGGeneric("use dom::bindings::reflector::Reflectable;\n"),
|
||||||
CGGeneric("use js::jsapi::JSTracer;\n\n"),
|
CGGeneric("use js::jsapi::JSTracer;\n\n"),
|
||||||
CGGeneric("use std::mem;\n\n")]
|
CGGeneric("use std::mem;\n\n")]
|
||||||
allprotos = []
|
allprotos = []
|
||||||
|
|
|
@ -38,7 +38,8 @@ use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::num::Finite;
|
use dom::bindings::num::Finite;
|
||||||
use dom::bindings::str::{ByteString, USVString};
|
use dom::bindings::str::{ByteString, USVString};
|
||||||
use dom::bindings::utils::{DOMClass, Reflectable, Reflector};
|
use dom::bindings::reflector::{Reflectable, Reflector};
|
||||||
|
use dom::bindings::utils::DOMClass;
|
||||||
use js;
|
use js;
|
||||||
use js::glue::{GetProxyPrivate, IsWrapper, RUST_JS_NumberValue};
|
use js::glue::{GetProxyPrivate, IsWrapper, RUST_JS_NumberValue};
|
||||||
use js::glue::{RUST_JSID_IS_STRING, RUST_JSID_TO_STRING, UnwrapObject};
|
use js::glue::{RUST_JSID_IS_STRING, RUST_JSID_TO_STRING, UnwrapObject};
|
||||||
|
@ -56,7 +57,6 @@ use libc;
|
||||||
use num::Float;
|
use num::Float;
|
||||||
use num::traits::{Bounded, Zero};
|
use num::traits::{Bounded, Zero};
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::mem;
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::{char, ptr, slice};
|
use std::{char, ptr, slice};
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
|
|
|
@ -11,7 +11,8 @@ use devtools_traits::ScriptToDevtoolsControlMsg;
|
||||||
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
|
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
|
||||||
use dom::bindings::conversions::native_from_reflector_jsmanaged;
|
use dom::bindings::conversions::native_from_reflector_jsmanaged;
|
||||||
use dom::bindings::js::{JS, Root};
|
use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::utils::{Reflectable, Reflector};
|
use dom::bindings::reflector::Reflector;
|
||||||
|
use dom::bindings::reflector::Reflectable;
|
||||||
use dom::window::{self, ScriptHelpers};
|
use dom::window::{self, ScriptHelpers};
|
||||||
use dom::workerglobalscope::WorkerGlobalScope;
|
use dom::workerglobalscope::WorkerGlobalScope;
|
||||||
use ipc_channel::ipc::IpcSender;
|
use ipc_channel::ipc::IpcSender;
|
||||||
|
|
|
@ -2,9 +2,11 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
//! The `Castable` trait.
|
||||||
|
|
||||||
use dom::bindings::conversions::get_dom_class;
|
use dom::bindings::conversions::get_dom_class;
|
||||||
use dom::bindings::conversions::{DerivedFrom, IDLInterface};
|
use dom::bindings::conversions::{DerivedFrom, IDLInterface};
|
||||||
use dom::bindings::utils::Reflectable;
|
use dom::bindings::reflector::Reflectable;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
/// A trait to hold the cast functions of IDL interfaces that either derive
|
/// A trait to hold the cast functions of IDL interfaces that either derive
|
||||||
|
|
|
@ -28,7 +28,8 @@ use dom::bindings::conversions::DerivedFrom;
|
||||||
use dom::bindings::inheritance::Castable;
|
use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::trace::JSTraceable;
|
use dom::bindings::trace::JSTraceable;
|
||||||
use dom::bindings::trace::trace_reflector;
|
use dom::bindings::trace::trace_reflector;
|
||||||
use dom::bindings::utils::{Reflectable, Reflector};
|
use dom::bindings::reflector::Reflector;
|
||||||
|
use dom::bindings::reflector::Reflectable;
|
||||||
use dom::node::Node;
|
use dom::node::Node;
|
||||||
use js::jsapi::{Heap, JSObject, JSTracer};
|
use js::jsapi::{Heap, JSObject, JSTracer};
|
||||||
use js::jsval::JSVal;
|
use js::jsval::JSVal;
|
||||||
|
|
|
@ -137,14 +137,17 @@ pub mod cell;
|
||||||
pub mod conversions;
|
pub mod conversions;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod global;
|
pub mod global;
|
||||||
|
pub mod inheritance;
|
||||||
pub mod js;
|
pub mod js;
|
||||||
pub mod num;
|
pub mod num;
|
||||||
pub mod proxyhandler;
|
pub mod proxyhandler;
|
||||||
pub mod refcounted;
|
pub mod refcounted;
|
||||||
|
pub mod reflector;
|
||||||
pub mod str;
|
pub mod str;
|
||||||
pub mod structuredclone;
|
pub mod structuredclone;
|
||||||
pub mod trace;
|
pub mod trace;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
pub mod xmlname;
|
||||||
|
|
||||||
/// Generated JS-Rust bindings.
|
/// Generated JS-Rust bindings.
|
||||||
#[allow(missing_docs, non_snake_case)]
|
#[allow(missing_docs, non_snake_case)]
|
||||||
|
|
|
@ -25,7 +25,8 @@
|
||||||
use core::nonzero::NonZero;
|
use core::nonzero::NonZero;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::trace::trace_reflector;
|
use dom::bindings::trace::trace_reflector;
|
||||||
use dom::bindings::utils::{Reflectable, Reflector};
|
use dom::bindings::reflector::Reflector;
|
||||||
|
use dom::bindings::reflector::Reflectable;
|
||||||
use js::jsapi::{JSContext, JSTracer};
|
use js::jsapi::{JSContext, JSTracer};
|
||||||
use libc;
|
use libc;
|
||||||
use script_task::{CommonScriptMsg, ScriptChan};
|
use script_task::{CommonScriptMsg, ScriptChan};
|
||||||
|
|
79
components/script/dom/bindings/reflector.rs
Normal file
79
components/script/dom/bindings/reflector.rs
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
//! The `Reflector` struct.
|
||||||
|
|
||||||
|
use dom::bindings::global::GlobalRef;
|
||||||
|
use dom::bindings::js::Root;
|
||||||
|
use js::jsapi::{HandleObject, JSContext, JSObject};
|
||||||
|
use std::cell::UnsafeCell;
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
|
/// Create the reflector for a new DOM object and yield ownership to the
|
||||||
|
/// reflector.
|
||||||
|
pub fn reflect_dom_object<T: Reflectable>
|
||||||
|
(obj: Box<T>,
|
||||||
|
global: GlobalRef,
|
||||||
|
wrap_fn: extern "Rust" fn(*mut JSContext, GlobalRef, Box<T>) -> Root<T>)
|
||||||
|
-> Root<T> {
|
||||||
|
wrap_fn(global.get_cx(), global, obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A struct to store a reference to the reflector of a DOM object.
|
||||||
|
#[allow(raw_pointer_derive, unrooted_must_root)]
|
||||||
|
#[must_root]
|
||||||
|
#[servo_lang = "reflector"]
|
||||||
|
#[derive(HeapSizeOf)]
|
||||||
|
// If you're renaming or moving this field, update the path in plugins::reflector as well
|
||||||
|
pub struct Reflector {
|
||||||
|
#[ignore_heap_size_of = "defined and measured in rust-mozjs"]
|
||||||
|
object: UnsafeCell<*mut JSObject>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unrooted_must_root)]
|
||||||
|
impl PartialEq for Reflector {
|
||||||
|
fn eq(&self, other: &Reflector) -> bool {
|
||||||
|
unsafe { *self.object.get() == *other.object.get() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Reflector {
|
||||||
|
/// Get the reflector.
|
||||||
|
#[inline]
|
||||||
|
pub fn get_jsobject(&self) -> HandleObject {
|
||||||
|
unsafe { HandleObject::from_marked_location(self.object.get()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Initialize the reflector. (May be called only once.)
|
||||||
|
pub fn set_jsobject(&mut self, object: *mut JSObject) {
|
||||||
|
unsafe {
|
||||||
|
let obj = self.object.get();
|
||||||
|
assert!((*obj).is_null());
|
||||||
|
assert!(!object.is_null());
|
||||||
|
*obj = object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return a pointer to the memory location at which the JS reflector
|
||||||
|
/// object is stored. Used to root the reflector, as
|
||||||
|
/// required by the JSAPI rooting APIs.
|
||||||
|
pub fn rootable(&self) -> *mut *mut JSObject {
|
||||||
|
self.object.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create an uninitialized `Reflector`.
|
||||||
|
pub fn new() -> Reflector {
|
||||||
|
Reflector {
|
||||||
|
object: UnsafeCell::new(ptr::null_mut())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A trait to provide access to the `Reflector` for a DOM object.
|
||||||
|
pub trait Reflectable {
|
||||||
|
/// Returns the receiver's reflector.
|
||||||
|
fn reflector(&self) -> &Reflector;
|
||||||
|
/// Initializes the Reflector
|
||||||
|
fn init_reflector(&mut self, obj: *mut JSObject);
|
||||||
|
}
|
|
@ -35,7 +35,8 @@ use canvas_traits::{CompositionOrBlending, LineCapStyle, LineJoinStyle, Repetiti
|
||||||
use cssparser::RGBA;
|
use cssparser::RGBA;
|
||||||
use dom::bindings::js::{JS, Root};
|
use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::refcounted::Trusted;
|
use dom::bindings::refcounted::Trusted;
|
||||||
use dom::bindings::utils::{Reflectable, Reflector, WindowProxyHandler};
|
use dom::bindings::reflector::{Reflectable, Reflector};
|
||||||
|
use dom::bindings::utils::WindowProxyHandler;
|
||||||
use encoding::types::EncodingRef;
|
use encoding::types::EncodingRef;
|
||||||
use euclid::length::Length as EuclidLength;
|
use euclid::length::Length as EuclidLength;
|
||||||
use euclid::matrix2d::Matrix2D;
|
use euclid::matrix2d::Matrix2D;
|
||||||
|
|
|
@ -49,14 +49,10 @@ use js::rust::{GCMethods, ToString, define_methods, define_properties};
|
||||||
use js::{JSFUN_CONSTRUCTOR, JSPROP_ENUMERATE, JS_CALLEE};
|
use js::{JSFUN_CONSTRUCTOR, JSPROP_ENUMERATE, JS_CALLEE};
|
||||||
use js::{JSPROP_PERMANENT, JSPROP_READONLY};
|
use js::{JSPROP_PERMANENT, JSPROP_READONLY};
|
||||||
use libc::{self, c_uint};
|
use libc::{self, c_uint};
|
||||||
use std::cell::UnsafeCell;
|
|
||||||
use std::cmp::PartialEq;
|
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use string_cache::{Atom, Namespace};
|
|
||||||
use util::mem::HeapSizeOf;
|
use util::mem::HeapSizeOf;
|
||||||
use util::str::DOMString;
|
|
||||||
|
|
||||||
/// Proxy handler for a WindowProxy.
|
/// Proxy handler for a WindowProxy.
|
||||||
#[allow(raw_pointer_derive)]
|
#[allow(raw_pointer_derive)]
|
||||||
|
@ -391,74 +387,6 @@ pub fn initialize_global(global: *mut JSObject) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A trait to provide access to the `Reflector` for a DOM object.
|
|
||||||
pub trait Reflectable {
|
|
||||||
/// Returns the receiver's reflector.
|
|
||||||
fn reflector(&self) -> &Reflector;
|
|
||||||
/// Initializes the Reflector
|
|
||||||
fn init_reflector(&mut self, obj: *mut JSObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create the reflector for a new DOM object and yield ownership to the
|
|
||||||
/// reflector.
|
|
||||||
pub fn reflect_dom_object<T: Reflectable>
|
|
||||||
(obj: Box<T>,
|
|
||||||
global: GlobalRef,
|
|
||||||
wrap_fn: extern "Rust" fn(*mut JSContext, GlobalRef, Box<T>) -> Root<T>)
|
|
||||||
-> Root<T> {
|
|
||||||
wrap_fn(global.get_cx(), global, obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A struct to store a reference to the reflector of a DOM object.
|
|
||||||
#[allow(raw_pointer_derive, unrooted_must_root)]
|
|
||||||
#[must_root]
|
|
||||||
#[servo_lang = "reflector"]
|
|
||||||
#[derive(HeapSizeOf)]
|
|
||||||
// If you're renaming or moving this field, update the path in plugins::reflector as well
|
|
||||||
pub struct Reflector {
|
|
||||||
#[ignore_heap_size_of = "defined and measured in rust-mozjs"]
|
|
||||||
object: UnsafeCell<*mut JSObject>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unrooted_must_root)]
|
|
||||||
impl PartialEq for Reflector {
|
|
||||||
fn eq(&self, other: &Reflector) -> bool {
|
|
||||||
unsafe { *self.object.get() == *other.object.get() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Reflector {
|
|
||||||
/// Get the reflector.
|
|
||||||
#[inline]
|
|
||||||
pub fn get_jsobject(&self) -> HandleObject {
|
|
||||||
unsafe { HandleObject::from_marked_location(self.object.get()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Initialize the reflector. (May be called only once.)
|
|
||||||
pub fn set_jsobject(&mut self, object: *mut JSObject) {
|
|
||||||
unsafe {
|
|
||||||
let obj = self.object.get();
|
|
||||||
assert!((*obj).is_null());
|
|
||||||
assert!(!object.is_null());
|
|
||||||
*obj = object;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return a pointer to the memory location at which the JS reflector
|
|
||||||
/// object is stored. Used to root the reflector, as
|
|
||||||
/// required by the JSAPI rooting APIs.
|
|
||||||
pub fn rootable(&self) -> *mut *mut JSObject {
|
|
||||||
self.object.get()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create an uninitialized `Reflector`.
|
|
||||||
pub fn new() -> Reflector {
|
|
||||||
Reflector {
|
|
||||||
object: UnsafeCell::new(ptr::null_mut())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets the property `id` on `proxy`'s prototype. If it exists, `*found` is
|
/// Gets the property `id` on `proxy`'s prototype. If it exists, `*found` is
|
||||||
/// set to true and `*vp` to the value, otherwise `*found` is set to false.
|
/// set to true and `*vp` to the value, otherwise `*found` is set to false.
|
||||||
///
|
///
|
||||||
|
@ -800,21 +728,6 @@ pub unsafe extern fn generic_lenient_setter(cx: *mut JSContext,
|
||||||
generic_call(cx, argc, vp, true, call_setter)
|
generic_call(cx, argc, vp, true, call_setter)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Validate a qualified name. See https://dom.spec.whatwg.org/#validate for details.
|
|
||||||
pub fn validate_qualified_name(qualified_name: &str) -> ErrorResult {
|
|
||||||
match xml_name_type(qualified_name) {
|
|
||||||
XMLName::InvalidXMLName => {
|
|
||||||
// Step 1.
|
|
||||||
Err(Error::InvalidCharacter)
|
|
||||||
},
|
|
||||||
XMLName::Name => {
|
|
||||||
// Step 2.
|
|
||||||
Err(Error::Namespace)
|
|
||||||
},
|
|
||||||
XMLName::QName => Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe extern "C" fn instance_class_has_proto_at_depth(clasp: *const js::jsapi::Class,
|
unsafe extern "C" fn instance_class_has_proto_at_depth(clasp: *const js::jsapi::Class,
|
||||||
proto_id: u32,
|
proto_id: u32,
|
||||||
depth: u32) -> bool {
|
depth: u32) -> bool {
|
||||||
|
@ -827,155 +740,3 @@ unsafe extern "C" fn instance_class_has_proto_at_depth(clasp: *const js::jsapi::
|
||||||
pub const DOM_CALLBACKS: DOMCallbacks = DOMCallbacks {
|
pub const DOM_CALLBACKS: DOMCallbacks = DOMCallbacks {
|
||||||
instanceClassMatchesProto: Some(instance_class_has_proto_at_depth),
|
instanceClassMatchesProto: Some(instance_class_has_proto_at_depth),
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Validate a namespace and qualified name and extract their parts.
|
|
||||||
/// See https://dom.spec.whatwg.org/#validate-and-extract for details.
|
|
||||||
pub fn validate_and_extract(namespace: Option<DOMString>, qualified_name: &str)
|
|
||||||
-> Fallible<(Namespace, Option<Atom>, Atom)> {
|
|
||||||
// Step 1.
|
|
||||||
let namespace = namespace_from_domstring(namespace);
|
|
||||||
|
|
||||||
// Step 2.
|
|
||||||
try!(validate_qualified_name(qualified_name));
|
|
||||||
|
|
||||||
let colon = ':';
|
|
||||||
|
|
||||||
// Step 5.
|
|
||||||
let mut parts = qualified_name.splitn(2, colon);
|
|
||||||
|
|
||||||
let (maybe_prefix, local_name) = {
|
|
||||||
let maybe_prefix = parts.next();
|
|
||||||
let maybe_local_name = parts.next();
|
|
||||||
|
|
||||||
debug_assert!(parts.next().is_none());
|
|
||||||
|
|
||||||
if let Some(local_name) = maybe_local_name {
|
|
||||||
debug_assert!(!maybe_prefix.unwrap().is_empty());
|
|
||||||
|
|
||||||
(maybe_prefix, local_name)
|
|
||||||
} else {
|
|
||||||
(None, maybe_prefix.unwrap())
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
debug_assert!(!local_name.contains(colon));
|
|
||||||
|
|
||||||
match (namespace, maybe_prefix) {
|
|
||||||
(ns!(""), Some(_)) => {
|
|
||||||
// Step 6.
|
|
||||||
Err(Error::Namespace)
|
|
||||||
},
|
|
||||||
(ref ns, Some("xml")) if ns != &ns!(XML) => {
|
|
||||||
// Step 7.
|
|
||||||
Err(Error::Namespace)
|
|
||||||
},
|
|
||||||
(ref ns, p) if ns != &ns!(XMLNS) &&
|
|
||||||
(qualified_name == "xmlns" || p == Some("xmlns")) => {
|
|
||||||
// Step 8.
|
|
||||||
Err(Error::Namespace)
|
|
||||||
},
|
|
||||||
(ns!(XMLNS), p) if qualified_name != "xmlns" && p != Some("xmlns") => {
|
|
||||||
// Step 9.
|
|
||||||
Err(Error::Namespace)
|
|
||||||
},
|
|
||||||
(ns, p) => {
|
|
||||||
// Step 10.
|
|
||||||
Ok((ns, p.map(Atom::from_slice), Atom::from_slice(local_name)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Results of `xml_name_type`.
|
|
||||||
#[derive(PartialEq)]
|
|
||||||
#[allow(missing_docs)]
|
|
||||||
pub enum XMLName {
|
|
||||||
QName,
|
|
||||||
Name,
|
|
||||||
InvalidXMLName
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check if an element name is valid. See http://www.w3.org/TR/xml/#NT-Name
|
|
||||||
/// for details.
|
|
||||||
pub fn xml_name_type(name: &str) -> XMLName {
|
|
||||||
fn is_valid_start(c: char) -> bool {
|
|
||||||
match c {
|
|
||||||
':' |
|
|
||||||
'A' ... 'Z' |
|
|
||||||
'_' |
|
|
||||||
'a' ... 'z' |
|
|
||||||
'\u{C0}' ... '\u{D6}' |
|
|
||||||
'\u{D8}' ... '\u{F6}' |
|
|
||||||
'\u{F8}' ... '\u{2FF}' |
|
|
||||||
'\u{370}' ... '\u{37D}' |
|
|
||||||
'\u{37F}' ... '\u{1FFF}' |
|
|
||||||
'\u{200C}' ... '\u{200D}' |
|
|
||||||
'\u{2070}' ... '\u{218F}' |
|
|
||||||
'\u{2C00}' ... '\u{2FEF}' |
|
|
||||||
'\u{3001}' ... '\u{D7FF}' |
|
|
||||||
'\u{F900}' ... '\u{FDCF}' |
|
|
||||||
'\u{FDF0}' ... '\u{FFFD}' |
|
|
||||||
'\u{10000}' ... '\u{EFFFF}' => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_valid_continuation(c: char) -> bool {
|
|
||||||
is_valid_start(c) || match c {
|
|
||||||
'-' |
|
|
||||||
'.' |
|
|
||||||
'0' ... '9' |
|
|
||||||
'\u{B7}' |
|
|
||||||
'\u{300}' ... '\u{36F}' |
|
|
||||||
'\u{203F}' ... '\u{2040}' => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut iter = name.chars();
|
|
||||||
let mut non_qname_colons = false;
|
|
||||||
let mut seen_colon = false;
|
|
||||||
let mut last = match iter.next() {
|
|
||||||
None => return XMLName::InvalidXMLName,
|
|
||||||
Some(c) => {
|
|
||||||
if !is_valid_start(c) {
|
|
||||||
return XMLName::InvalidXMLName;
|
|
||||||
}
|
|
||||||
if c == ':' {
|
|
||||||
non_qname_colons = true;
|
|
||||||
}
|
|
||||||
c
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
for c in iter {
|
|
||||||
if !is_valid_continuation(c) {
|
|
||||||
return XMLName::InvalidXMLName;
|
|
||||||
}
|
|
||||||
if c == ':' {
|
|
||||||
match seen_colon {
|
|
||||||
true => non_qname_colons = true,
|
|
||||||
false => seen_colon = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
last = c
|
|
||||||
}
|
|
||||||
|
|
||||||
if last == ':' {
|
|
||||||
non_qname_colons = true
|
|
||||||
}
|
|
||||||
|
|
||||||
match non_qname_colons {
|
|
||||||
false => XMLName::QName,
|
|
||||||
true => XMLName::Name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert a possibly-null URL to a namespace.
|
|
||||||
///
|
|
||||||
/// If the URL is None, returns the empty namespace.
|
|
||||||
pub fn namespace_from_domstring(url: Option<DOMString>) -> Namespace {
|
|
||||||
match url {
|
|
||||||
None => ns!(""),
|
|
||||||
Some(ref s) => Namespace(Atom::from_slice(s)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
176
components/script/dom/bindings/xmlname.rs
Normal file
176
components/script/dom/bindings/xmlname.rs
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
//! Functions for validating and extracting qualified XML names.
|
||||||
|
|
||||||
|
use dom::bindings::error::{Error, ErrorResult, Fallible};
|
||||||
|
use string_cache::{Atom, Namespace};
|
||||||
|
use util::str::DOMString;
|
||||||
|
|
||||||
|
/// Validate a qualified name. See https://dom.spec.whatwg.org/#validate for details.
|
||||||
|
pub fn validate_qualified_name(qualified_name: &str) -> ErrorResult {
|
||||||
|
match xml_name_type(qualified_name) {
|
||||||
|
XMLName::InvalidXMLName => {
|
||||||
|
// Step 1.
|
||||||
|
Err(Error::InvalidCharacter)
|
||||||
|
},
|
||||||
|
XMLName::Name => {
|
||||||
|
// Step 2.
|
||||||
|
Err(Error::Namespace)
|
||||||
|
},
|
||||||
|
XMLName::QName => Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Validate a namespace and qualified name and extract their parts.
|
||||||
|
/// See https://dom.spec.whatwg.org/#validate-and-extract for details.
|
||||||
|
pub fn validate_and_extract(namespace: Option<DOMString>, qualified_name: &str)
|
||||||
|
-> Fallible<(Namespace, Option<Atom>, Atom)> {
|
||||||
|
// Step 1.
|
||||||
|
let namespace = namespace_from_domstring(namespace);
|
||||||
|
|
||||||
|
// Step 2.
|
||||||
|
try!(validate_qualified_name(qualified_name));
|
||||||
|
|
||||||
|
let colon = ':';
|
||||||
|
|
||||||
|
// Step 5.
|
||||||
|
let mut parts = qualified_name.splitn(2, colon);
|
||||||
|
|
||||||
|
let (maybe_prefix, local_name) = {
|
||||||
|
let maybe_prefix = parts.next();
|
||||||
|
let maybe_local_name = parts.next();
|
||||||
|
|
||||||
|
debug_assert!(parts.next().is_none());
|
||||||
|
|
||||||
|
if let Some(local_name) = maybe_local_name {
|
||||||
|
debug_assert!(!maybe_prefix.unwrap().is_empty());
|
||||||
|
|
||||||
|
(maybe_prefix, local_name)
|
||||||
|
} else {
|
||||||
|
(None, maybe_prefix.unwrap())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
debug_assert!(!local_name.contains(colon));
|
||||||
|
|
||||||
|
match (namespace, maybe_prefix) {
|
||||||
|
(ns!(""), Some(_)) => {
|
||||||
|
// Step 6.
|
||||||
|
Err(Error::Namespace)
|
||||||
|
},
|
||||||
|
(ref ns, Some("xml")) if ns != &ns!(XML) => {
|
||||||
|
// Step 7.
|
||||||
|
Err(Error::Namespace)
|
||||||
|
},
|
||||||
|
(ref ns, p) if ns != &ns!(XMLNS) &&
|
||||||
|
(qualified_name == "xmlns" || p == Some("xmlns")) => {
|
||||||
|
// Step 8.
|
||||||
|
Err(Error::Namespace)
|
||||||
|
},
|
||||||
|
(ns!(XMLNS), p) if qualified_name != "xmlns" && p != Some("xmlns") => {
|
||||||
|
// Step 9.
|
||||||
|
Err(Error::Namespace)
|
||||||
|
},
|
||||||
|
(ns, p) => {
|
||||||
|
// Step 10.
|
||||||
|
Ok((ns, p.map(Atom::from_slice), Atom::from_slice(local_name)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Results of `xml_name_type`.
|
||||||
|
#[derive(PartialEq)]
|
||||||
|
#[allow(missing_docs)]
|
||||||
|
pub enum XMLName {
|
||||||
|
QName,
|
||||||
|
Name,
|
||||||
|
InvalidXMLName
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check if an element name is valid. See http://www.w3.org/TR/xml/#NT-Name
|
||||||
|
/// for details.
|
||||||
|
pub fn xml_name_type(name: &str) -> XMLName {
|
||||||
|
fn is_valid_start(c: char) -> bool {
|
||||||
|
match c {
|
||||||
|
':' |
|
||||||
|
'A' ... 'Z' |
|
||||||
|
'_' |
|
||||||
|
'a' ... 'z' |
|
||||||
|
'\u{C0}' ... '\u{D6}' |
|
||||||
|
'\u{D8}' ... '\u{F6}' |
|
||||||
|
'\u{F8}' ... '\u{2FF}' |
|
||||||
|
'\u{370}' ... '\u{37D}' |
|
||||||
|
'\u{37F}' ... '\u{1FFF}' |
|
||||||
|
'\u{200C}' ... '\u{200D}' |
|
||||||
|
'\u{2070}' ... '\u{218F}' |
|
||||||
|
'\u{2C00}' ... '\u{2FEF}' |
|
||||||
|
'\u{3001}' ... '\u{D7FF}' |
|
||||||
|
'\u{F900}' ... '\u{FDCF}' |
|
||||||
|
'\u{FDF0}' ... '\u{FFFD}' |
|
||||||
|
'\u{10000}' ... '\u{EFFFF}' => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_valid_continuation(c: char) -> bool {
|
||||||
|
is_valid_start(c) || match c {
|
||||||
|
'-' |
|
||||||
|
'.' |
|
||||||
|
'0' ... '9' |
|
||||||
|
'\u{B7}' |
|
||||||
|
'\u{300}' ... '\u{36F}' |
|
||||||
|
'\u{203F}' ... '\u{2040}' => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut iter = name.chars();
|
||||||
|
let mut non_qname_colons = false;
|
||||||
|
let mut seen_colon = false;
|
||||||
|
let mut last = match iter.next() {
|
||||||
|
None => return XMLName::InvalidXMLName,
|
||||||
|
Some(c) => {
|
||||||
|
if !is_valid_start(c) {
|
||||||
|
return XMLName::InvalidXMLName;
|
||||||
|
}
|
||||||
|
if c == ':' {
|
||||||
|
non_qname_colons = true;
|
||||||
|
}
|
||||||
|
c
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for c in iter {
|
||||||
|
if !is_valid_continuation(c) {
|
||||||
|
return XMLName::InvalidXMLName;
|
||||||
|
}
|
||||||
|
if c == ':' {
|
||||||
|
match seen_colon {
|
||||||
|
true => non_qname_colons = true,
|
||||||
|
false => seen_colon = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
last = c
|
||||||
|
}
|
||||||
|
|
||||||
|
if last == ':' {
|
||||||
|
non_qname_colons = true
|
||||||
|
}
|
||||||
|
|
||||||
|
match non_qname_colons {
|
||||||
|
false => XMLName::QName,
|
||||||
|
true => XMLName::Name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert a possibly-null URL to a namespace.
|
||||||
|
///
|
||||||
|
/// If the URL is None, returns the empty namespace.
|
||||||
|
pub fn namespace_from_domstring(url: Option<DOMString>) -> Namespace {
|
||||||
|
match url {
|
||||||
|
None => ns!(""),
|
||||||
|
Some(ref s) => Namespace(Atom::from_slice(s)),
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::BlobBinding::BlobMethods;
|
||||||
use dom::bindings::error::Fallible;
|
use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::{GlobalField, GlobalRef};
|
use dom::bindings::global::{GlobalField, GlobalRef};
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use num::ToPrimitive;
|
use num::ToPrimitive;
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
|
|
|
@ -7,7 +7,8 @@ use dom::bindings::conversions::{ToJSValConvertible};
|
||||||
use dom::bindings::js::{JS, Root};
|
use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::proxyhandler::{fill_property_descriptor, get_property_descriptor};
|
use dom::bindings::proxyhandler::{fill_property_descriptor, get_property_descriptor};
|
||||||
use dom::bindings::utils::get_array_index_from_id;
|
use dom::bindings::utils::get_array_index_from_id;
|
||||||
use dom::bindings::utils::{Reflectable, WindowProxyHandler};
|
use dom::bindings::reflector::Reflectable;
|
||||||
|
use dom::bindings::utils::WindowProxyHandler;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::Element;
|
use dom::element::Element;
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
|
|
|
@ -10,7 +10,7 @@ use dom::bindings::error::{Error, ErrorResult};
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::num::Finite;
|
use dom::bindings::num::Finite;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::canvasrenderingcontext2d::parse_color;
|
use dom::canvasrenderingcontext2d::parse_color;
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#canvasgradient
|
// https://html.spec.whatwg.org/multipage/#canvasgradient
|
||||||
|
|
|
@ -6,7 +6,7 @@ use canvas_traits::{FillOrStrokeStyle, RepetitionStyle, SurfaceStyle};
|
||||||
use dom::bindings::codegen::Bindings::CanvasPatternBinding;
|
use dom::bindings::codegen::Bindings::CanvasPatternBinding;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::canvasgradient::ToFillOrStrokeStyle;
|
use dom::canvasgradient::ToFillOrStrokeStyle;
|
||||||
use euclid::size::Size2D;
|
use euclid::size::Size2D;
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ use dom::bindings::global::{GlobalField, GlobalRef};
|
||||||
use dom::bindings::inheritance::Castable;
|
use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::js::{JS, LayoutJS, Root};
|
use dom::bindings::js::{JS, LayoutJS, Root};
|
||||||
use dom::bindings::num::Finite;
|
use dom::bindings::num::Finite;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::canvasgradient::{CanvasGradient, CanvasGradientStyle, ToFillOrStrokeStyle};
|
use dom::canvasgradient::{CanvasGradient, CanvasGradientStyle, ToFillOrStrokeStyle};
|
||||||
use dom::canvaspattern::CanvasPattern;
|
use dom::canvaspattern::CanvasPattern;
|
||||||
use dom::htmlcanvaselement::HTMLCanvasElement;
|
use dom::htmlcanvaselement::HTMLCanvasElement;
|
||||||
|
|
|
@ -9,7 +9,7 @@ use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::inheritance::Castable;
|
use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::reflect_dom_object;
|
use dom::bindings::reflector::reflect_dom_object;
|
||||||
use dom::event::{Event, EventBubbles, EventCancelable};
|
use dom::event::{Event, EventBubbles, EventCancelable};
|
||||||
use script_task::ScriptChan;
|
use script_task::ScriptChan;
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
|
|
|
@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::ConsoleBinding;
|
||||||
use dom::bindings::codegen::Bindings::ConsoleBinding::ConsoleMethods;
|
use dom::bindings::codegen::Bindings::ConsoleBinding::ConsoleMethods;
|
||||||
use dom::bindings::global::{GlobalField, GlobalRef};
|
use dom::bindings::global::{GlobalField, GlobalRef};
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/Console
|
// https://developer.mozilla.org/en-US/docs/Web/API/Console
|
||||||
|
|
|
@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::CryptoBinding::CryptoMethods;
|
||||||
use dom::bindings::error::{Error, Fallible};
|
use dom::bindings::error::{Error, Fallible};
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use js::jsapi::{JSContext, JSObject};
|
use js::jsapi::{JSContext, JSObject};
|
||||||
use js::jsapi::{JS_GetArrayBufferViewType, JS_GetObjectAsArrayBufferView, Type};
|
use js::jsapi::{JS_GetArrayBufferViewType, JS_GetObjectAsArrayBufferView, Type};
|
||||||
use rand::{OsRng, Rng};
|
use rand::{OsRng, Rng};
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
use cssparser::serialize_identifier;
|
use cssparser::serialize_identifier;
|
||||||
use dom::bindings::error::{Error, Fallible};
|
use dom::bindings::error::{Error, Fallible};
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::utils::Reflector;
|
use dom::bindings::reflector::Reflector;
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
|
|
@ -7,7 +7,7 @@ use dom::bindings::error::{Error, ErrorResult, Fallible};
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::inheritance::Castable;
|
use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::js::{JS, Root};
|
use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::element::{Element, StylePriority};
|
use dom::element::{Element, StylePriority};
|
||||||
use dom::node::{Node, NodeDamage, document_from_node, window_from_node};
|
use dom::node::{Node, NodeDamage, document_from_node, window_from_node};
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
|
|
|
@ -9,7 +9,7 @@ use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::error::Fallible;
|
use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{MutHeapJSVal, Root};
|
use dom::bindings::js::{MutHeapJSVal, Root};
|
||||||
use dom::bindings::utils::reflect_dom_object;
|
use dom::bindings::reflector::reflect_dom_object;
|
||||||
use dom::event::Event;
|
use dom::event::Event;
|
||||||
use js::jsapi::{HandleValue, JSContext};
|
use js::jsapi::{HandleValue, JSContext};
|
||||||
use js::jsval::JSVal;
|
use js::jsval::JSVal;
|
||||||
|
|
|
@ -14,7 +14,7 @@ use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::js::{Root, RootCollection};
|
use dom::bindings::js::{Root, RootCollection};
|
||||||
use dom::bindings::refcounted::LiveDOMReferences;
|
use dom::bindings::refcounted::LiveDOMReferences;
|
||||||
use dom::bindings::structuredclone::StructuredCloneData;
|
use dom::bindings::structuredclone::StructuredCloneData;
|
||||||
use dom::bindings::utils::Reflectable;
|
use dom::bindings::reflector::Reflectable;
|
||||||
use dom::messageevent::MessageEvent;
|
use dom::messageevent::MessageEvent;
|
||||||
use dom::worker::{SimpleWorkerErrorHandler, TrustedWorkerAddress, WorkerMessageHandler};
|
use dom::worker::{SimpleWorkerErrorHandler, TrustedWorkerAddress, WorkerMessageHandler};
|
||||||
use dom::workerglobalscope::WorkerGlobalScope;
|
use dom::workerglobalscope::WorkerGlobalScope;
|
||||||
|
|
|
@ -24,9 +24,10 @@ use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root};
|
||||||
use dom::bindings::num::Finite;
|
use dom::bindings::num::Finite;
|
||||||
use dom::bindings::refcounted::Trusted;
|
use dom::bindings::refcounted::Trusted;
|
||||||
use dom::bindings::trace::RootedVec;
|
use dom::bindings::trace::RootedVec;
|
||||||
use dom::bindings::utils::XMLName::InvalidXMLName;
|
use dom::bindings::reflector::reflect_dom_object;
|
||||||
use dom::bindings::utils::{Reflectable, reflect_dom_object};
|
use dom::bindings::reflector::Reflectable;
|
||||||
use dom::bindings::utils::{validate_and_extract, xml_name_type};
|
use dom::bindings::xmlname::{validate_and_extract, xml_name_type};
|
||||||
|
use dom::bindings::xmlname::XMLName::InvalidXMLName;
|
||||||
use dom::comment::Comment;
|
use dom::comment::Comment;
|
||||||
use dom::customevent::CustomEvent;
|
use dom::customevent::CustomEvent;
|
||||||
use dom::documentfragment::DocumentFragment;
|
use dom::documentfragment::DocumentFragment;
|
||||||
|
|
|
@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::DOMExceptionBinding::DOMExceptionConstants
|
||||||
use dom::bindings::codegen::Bindings::DOMExceptionBinding::DOMExceptionMethods;
|
use dom::bindings::codegen::Bindings::DOMExceptionBinding::DOMExceptionMethods;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::inheritance::Castable;
|
use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::js::{JS, Root};
|
use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::utils::validate_qualified_name;
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::xmlname::validate_qualified_name;
|
||||||
use dom::document::DocumentSource;
|
use dom::document::DocumentSource;
|
||||||
use dom::document::{Document, IsHTMLDocument};
|
use dom::document::{Document, IsHTMLDocument};
|
||||||
use dom::documenttype::DocumentType;
|
use dom::documenttype::DocumentType;
|
||||||
|
|
|
@ -11,7 +11,7 @@ use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
|
||||||
use dom::bindings::error::Fallible;
|
use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, Root};
|
use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::document::DocumentSource;
|
use dom::document::DocumentSource;
|
||||||
use dom::document::{Document, IsHTMLDocument};
|
use dom::document::{Document, IsHTMLDocument};
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
|
|
|
@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::DOMPointReadOnlyBinding::DOMPointReadOnlyM
|
||||||
use dom::bindings::error::Fallible;
|
use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::reflect_dom_object;
|
use dom::bindings::reflector::reflect_dom_object;
|
||||||
use dom::dompointreadonly::{DOMPointReadOnly, DOMPointWriteMethods};
|
use dom::dompointreadonly::{DOMPointReadOnly, DOMPointWriteMethods};
|
||||||
|
|
||||||
// http://dev.w3.org/fxtf/geometry/Overview.html#dompoint
|
// http://dev.w3.org/fxtf/geometry/Overview.html#dompoint
|
||||||
|
|
|
@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::DOMPointReadOnlyBinding::{DOMPointReadOnly
|
||||||
use dom::bindings::error::Fallible;
|
use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
|
||||||
// http://dev.w3.org/fxtf/geometry/Overview.html#dompointreadonly
|
// http://dev.w3.org/fxtf/geometry/Overview.html#dompointreadonly
|
||||||
|
|
|
@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::DOMRectReadOnlyBinding::DOMRectReadOnlyMet
|
||||||
use dom::bindings::error::Fallible;
|
use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::reflect_dom_object;
|
use dom::bindings::reflector::reflect_dom_object;
|
||||||
use dom::domrectreadonly::DOMRectReadOnly;
|
use dom::domrectreadonly::DOMRectReadOnly;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
|
|
@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::DOMRectListBinding;
|
||||||
use dom::bindings::codegen::Bindings::DOMRectListBinding::DOMRectListMethods;
|
use dom::bindings::codegen::Bindings::DOMRectListBinding::DOMRectListMethods;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, Root};
|
use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::domrect::DOMRect;
|
use dom::domrect::DOMRect;
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::DOMRectReadOnlyBinding::{DOMRectReadOnlyMe
|
||||||
use dom::bindings::error::Fallible;
|
use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
|
|
@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::DOMStringMapBinding::DOMStringMapMethods;
|
||||||
use dom::bindings::error::ErrorResult;
|
use dom::bindings::error::ErrorResult;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, Root};
|
use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::node::window_from_node;
|
use dom::node::window_from_node;
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
|
|
|
@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::DOMTokenListBinding::DOMTokenListMethods;
|
||||||
use dom::bindings::error::{Error, ErrorResult, Fallible};
|
use dom::bindings::error::{Error, ErrorResult, Fallible};
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, Root};
|
use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::element::Element;
|
use dom::element::Element;
|
||||||
use dom::node::window_from_node;
|
use dom::node::window_from_node;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
|
|
|
@ -26,8 +26,8 @@ use dom::bindings::error::{Error, ErrorResult, Fallible};
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, LayoutJS, MutNullableHeap};
|
use dom::bindings::js::{JS, LayoutJS, MutNullableHeap};
|
||||||
use dom::bindings::js::{Root, RootedReference};
|
use dom::bindings::js::{Root, RootedReference};
|
||||||
use dom::bindings::utils::XMLName::InvalidXMLName;
|
use dom::bindings::xmlname::{namespace_from_domstring, validate_and_extract, xml_name_type};
|
||||||
use dom::bindings::utils::{namespace_from_domstring, validate_and_extract, xml_name_type};
|
use dom::bindings::xmlname::XMLName::InvalidXMLName;
|
||||||
use dom::characterdata::CharacterData;
|
use dom::characterdata::CharacterData;
|
||||||
use dom::create::create_element;
|
use dom::create::create_element;
|
||||||
use dom::document::{Document, LayoutDocumentHelpers};
|
use dom::document::{Document, LayoutDocumentHelpers};
|
||||||
|
|
|
@ -11,7 +11,7 @@ use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{MutHeapJSVal, Root};
|
use dom::bindings::js::{MutHeapJSVal, Root};
|
||||||
use dom::bindings::trace::JSTraceable;
|
use dom::bindings::trace::JSTraceable;
|
||||||
use dom::bindings::utils::reflect_dom_object;
|
use dom::bindings::reflector::reflect_dom_object;
|
||||||
use dom::event::{Event, EventBubbles, EventCancelable};
|
use dom::event::{Event, EventBubbles, EventCancelable};
|
||||||
use js::jsapi::{RootedValue, HandleValue, JSContext};
|
use js::jsapi::{RootedValue, HandleValue, JSContext};
|
||||||
use js::jsval::JSVal;
|
use js::jsval::JSVal;
|
||||||
|
|
|
@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::EventBinding::{EventConstants, EventMethod
|
||||||
use dom::bindings::error::Fallible;
|
use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, MutNullableHeap, Root};
|
use dom::bindings::js::{JS, MutNullableHeap, Root};
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::eventtarget::EventTarget;
|
use dom::eventtarget::EventTarget;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
|
|
@ -9,7 +9,8 @@ use dom::bindings::codegen::Bindings::EventListenerBinding::EventListener;
|
||||||
use dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods;
|
use dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::EventTargetTypeId;
|
use dom::bindings::codegen::InheritTypes::EventTargetTypeId;
|
||||||
use dom::bindings::error::{Error, Fallible, report_pending_exception};
|
use dom::bindings::error::{Error, Fallible, report_pending_exception};
|
||||||
use dom::bindings::utils::{Reflectable, Reflector};
|
use dom::bindings::reflector::Reflector;
|
||||||
|
use dom::bindings::reflector::Reflectable;
|
||||||
use dom::event::Event;
|
use dom::event::Event;
|
||||||
use dom::eventdispatcher::dispatch_event;
|
use dom::eventdispatcher::dispatch_event;
|
||||||
use dom::virtualmethods::VirtualMethods;
|
use dom::virtualmethods::VirtualMethods;
|
||||||
|
|
|
@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::FileBinding;
|
||||||
use dom::bindings::codegen::Bindings::FileBinding::FileMethods;
|
use dom::bindings::codegen::Bindings::FileBinding::FileMethods;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::reflect_dom_object;
|
use dom::bindings::reflector::reflect_dom_object;
|
||||||
use dom::blob::Blob;
|
use dom::blob::Blob;
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::FileListBinding;
|
||||||
use dom::bindings::codegen::Bindings::FileListBinding::FileListMethods;
|
use dom::bindings::codegen::Bindings::FileListBinding::FileListMethods;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, Root};
|
use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::file::File;
|
use dom::file::File;
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,8 @@ use dom::bindings::error::{Error, ErrorResult, Fallible};
|
||||||
use dom::bindings::global::{GlobalField, GlobalRef};
|
use dom::bindings::global::{GlobalField, GlobalRef};
|
||||||
use dom::bindings::js::{JS, MutNullableHeap, Root};
|
use dom::bindings::js::{JS, MutNullableHeap, Root};
|
||||||
use dom::bindings::refcounted::Trusted;
|
use dom::bindings::refcounted::Trusted;
|
||||||
use dom::bindings::utils::{Reflectable, reflect_dom_object};
|
use dom::bindings::reflector::reflect_dom_object;
|
||||||
|
use dom::bindings::reflector::Reflectable;
|
||||||
use dom::blob::Blob;
|
use dom::blob::Blob;
|
||||||
use dom::domexception::{DOMErrorName, DOMException};
|
use dom::domexception::{DOMErrorName, DOMException};
|
||||||
use dom::event::{Event, EventBubbles, EventCancelable};
|
use dom::event::{Event, EventBubbles, EventCancelable};
|
||||||
|
|
|
@ -11,7 +11,7 @@ use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::error::{Fallible};
|
use dom::bindings::error::{Fallible};
|
||||||
use dom::bindings::global::{GlobalField, GlobalRef};
|
use dom::bindings::global::{GlobalField, GlobalRef};
|
||||||
use dom::bindings::js::{JS, Root};
|
use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::blob::Blob;
|
use dom::blob::Blob;
|
||||||
use dom::file::File;
|
use dom::file::File;
|
||||||
use dom::htmlformelement::HTMLFormElement;
|
use dom::htmlformelement::HTMLFormElement;
|
||||||
|
|
|
@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::HTMLAreaElementBinding;
|
||||||
use dom::bindings::codegen::Bindings::HTMLAreaElementBinding::HTMLAreaElementMethods;
|
use dom::bindings::codegen::Bindings::HTMLAreaElementBinding::HTMLAreaElementMethods;
|
||||||
use dom::bindings::inheritance::Castable;
|
use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::js::{JS, MutNullableHeap, Root};
|
use dom::bindings::js::{JS, MutNullableHeap, Root};
|
||||||
use dom::bindings::utils::Reflectable;
|
use dom::bindings::reflector::Reflectable;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::domtokenlist::DOMTokenList;
|
use dom::domtokenlist::DOMTokenList;
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
|
|
|
@ -10,7 +10,7 @@ use dom::bindings::codegen::Bindings::HTMLBodyElementBinding::{self, HTMLBodyEle
|
||||||
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
|
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
|
||||||
use dom::bindings::inheritance::Castable;
|
use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::Reflectable;
|
use dom::bindings::reflector::Reflectable;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::{AttributeMutation, Element, RawLayoutElementHelpers};
|
use dom::element::{AttributeMutation, Element, RawLayoutElementHelpers};
|
||||||
use dom::eventtarget::EventTarget;
|
use dom::eventtarget::EventTarget;
|
||||||
|
|
|
@ -14,7 +14,7 @@ use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{HeapGCValue, JS, LayoutJS, Root};
|
use dom::bindings::js::{HeapGCValue, JS, LayoutJS, Root};
|
||||||
use dom::bindings::num::Finite;
|
use dom::bindings::num::Finite;
|
||||||
use dom::bindings::utils::{Reflectable};
|
use dom::bindings::reflector::Reflectable;
|
||||||
use dom::canvasrenderingcontext2d::{CanvasRenderingContext2D, LayoutCanvasRenderingContext2DHelpers};
|
use dom::canvasrenderingcontext2d::{CanvasRenderingContext2D, LayoutCanvasRenderingContext2DHelpers};
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::{AttributeMutation, Element};
|
use dom::element::{AttributeMutation, Element};
|
||||||
|
|
355
components/script/dom/htmlcanvaselement.rs.BACKUP.20128.rs
Normal file
355
components/script/dom/htmlcanvaselement.rs.BACKUP.20128.rs
Normal file
|
@ -0,0 +1,355 @@
|
||||||
|
/* 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 canvas_traits::{CanvasMsg, FromLayoutMsg};
|
||||||
|
use dom::attr::Attr;
|
||||||
|
use dom::bindings::cell::DOMRefCell;
|
||||||
|
use dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::CanvasRenderingContext2DMethods;
|
||||||
|
use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding;
|
||||||
|
use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding::HTMLCanvasElementMethods;
|
||||||
|
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLContextAttributes;
|
||||||
|
use dom::bindings::codegen::UnionTypes::CanvasRenderingContext2DOrWebGLRenderingContext;
|
||||||
|
<<<<<<< HEAD
|
||||||
|
use dom::bindings::conversions::Castable;
|
||||||
|
use dom::bindings::error::{Error, Fallible};
|
||||||
|
=======
|
||||||
|
use dom::bindings::inheritance::Castable;
|
||||||
|
>>>>>>> move Castable into dom::bindings::inheritance
|
||||||
|
use dom::bindings::global::GlobalRef;
|
||||||
|
use dom::bindings::js::{HeapGCValue, JS, LayoutJS, Root};
|
||||||
|
use dom::bindings::num::Finite;
|
||||||
|
use dom::bindings::utils::{Reflectable};
|
||||||
|
use dom::canvasrenderingcontext2d::{CanvasRenderingContext2D, LayoutCanvasRenderingContext2DHelpers};
|
||||||
|
use dom::document::Document;
|
||||||
|
use dom::element::{AttributeMutation, Element};
|
||||||
|
use dom::htmlelement::HTMLElement;
|
||||||
|
use dom::node::{Node, window_from_node};
|
||||||
|
use dom::virtualmethods::VirtualMethods;
|
||||||
|
use dom::webglrenderingcontext::{LayoutCanvasWebGLRenderingContextHelpers, WebGLRenderingContext};
|
||||||
|
use euclid::size::Size2D;
|
||||||
|
use image::ColorType;
|
||||||
|
use image::png::PNGEncoder;
|
||||||
|
use ipc_channel::ipc::{self, IpcSender};
|
||||||
|
use js::jsapi::{HandleValue, JSContext};
|
||||||
|
use offscreen_gl_context::GLContextAttributes;
|
||||||
|
use rustc_serialize::base64::{STANDARD, ToBase64};
|
||||||
|
use std::cell::Cell;
|
||||||
|
use std::iter::repeat;
|
||||||
|
use util::str::{DOMString, parse_unsigned_integer};
|
||||||
|
|
||||||
|
const DEFAULT_WIDTH: u32 = 300;
|
||||||
|
const DEFAULT_HEIGHT: u32 = 150;
|
||||||
|
|
||||||
|
#[must_root]
|
||||||
|
#[derive(JSTraceable, Clone, HeapSizeOf)]
|
||||||
|
pub enum CanvasContext {
|
||||||
|
Context2d(JS<CanvasRenderingContext2D>),
|
||||||
|
WebGL(JS<WebGLRenderingContext>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HeapGCValue for CanvasContext {}
|
||||||
|
|
||||||
|
#[dom_struct]
|
||||||
|
pub struct HTMLCanvasElement {
|
||||||
|
htmlelement: HTMLElement,
|
||||||
|
context: DOMRefCell<Option<CanvasContext>>,
|
||||||
|
width: Cell<u32>,
|
||||||
|
height: Cell<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for HTMLCanvasElement {
|
||||||
|
fn eq(&self, other: &HTMLCanvasElement) -> bool {
|
||||||
|
self as *const HTMLCanvasElement == &*other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HTMLCanvasElement {
|
||||||
|
fn new_inherited(localName: DOMString,
|
||||||
|
prefix: Option<DOMString>,
|
||||||
|
document: &Document) -> HTMLCanvasElement {
|
||||||
|
HTMLCanvasElement {
|
||||||
|
htmlelement: HTMLElement::new_inherited(localName, prefix, document),
|
||||||
|
context: DOMRefCell::new(None),
|
||||||
|
width: Cell::new(DEFAULT_WIDTH),
|
||||||
|
height: Cell::new(DEFAULT_HEIGHT),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unrooted_must_root)]
|
||||||
|
pub fn new(localName: DOMString,
|
||||||
|
prefix: Option<DOMString>,
|
||||||
|
document: &Document) -> Root<HTMLCanvasElement> {
|
||||||
|
let element = HTMLCanvasElement::new_inherited(localName, prefix, document);
|
||||||
|
Node::reflect_node(box element, document, HTMLCanvasElementBinding::Wrap)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recreate_contexts(&self) {
|
||||||
|
let size = self.get_size();
|
||||||
|
if let Some(ref context) = *self.context.borrow() {
|
||||||
|
match *context {
|
||||||
|
CanvasContext::Context2d(ref context) => context.recreate(size),
|
||||||
|
CanvasContext::WebGL(ref context) => context.recreate(size),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_size(&self) -> Size2D<i32> {
|
||||||
|
Size2D::new(self.width.get() as i32, self.height.get() as i32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct HTMLCanvasData {
|
||||||
|
pub renderer_id: Option<usize>,
|
||||||
|
pub ipc_renderer: Option<IpcSender<CanvasMsg>>,
|
||||||
|
pub width: u32,
|
||||||
|
pub height: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait LayoutHTMLCanvasElementHelpers {
|
||||||
|
fn data(&self) -> HTMLCanvasData;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> {
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
fn data(&self) -> HTMLCanvasData {
|
||||||
|
unsafe {
|
||||||
|
let canvas = &*self.unsafe_get();
|
||||||
|
let (renderer_id, ipc_renderer) = match canvas.context.borrow_for_layout().as_ref() {
|
||||||
|
Some(&CanvasContext::Context2d(ref context)) => {
|
||||||
|
let context = context.to_layout();
|
||||||
|
(Some(context.get_renderer_id()), Some(context.get_ipc_renderer()))
|
||||||
|
},
|
||||||
|
Some(&CanvasContext::WebGL(ref context)) => {
|
||||||
|
let context = context.to_layout();
|
||||||
|
(Some(context.get_renderer_id()), Some(context.get_ipc_renderer()))
|
||||||
|
},
|
||||||
|
None => (None, None),
|
||||||
|
};
|
||||||
|
|
||||||
|
HTMLCanvasData {
|
||||||
|
renderer_id: renderer_id,
|
||||||
|
ipc_renderer: ipc_renderer,
|
||||||
|
width: canvas.width.get(),
|
||||||
|
height: canvas.height.get(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl HTMLCanvasElement {
|
||||||
|
pub fn ipc_renderer(&self) -> Option<IpcSender<CanvasMsg>> {
|
||||||
|
self.context.borrow().as_ref().map(|context| {
|
||||||
|
match *context {
|
||||||
|
CanvasContext::Context2d(ref context) => context.ipc_renderer(),
|
||||||
|
CanvasContext::WebGL(ref context) => context.ipc_renderer(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_or_init_2d_context(&self) -> Option<Root<CanvasRenderingContext2D>> {
|
||||||
|
if self.context.borrow().is_none() {
|
||||||
|
let window = window_from_node(self);
|
||||||
|
let size = self.get_size();
|
||||||
|
let context = CanvasRenderingContext2D::new(GlobalRef::Window(window.r()), self, size);
|
||||||
|
*self.context.borrow_mut() = Some(CanvasContext::Context2d(JS::from_rooted(&context)));
|
||||||
|
}
|
||||||
|
|
||||||
|
match *self.context.borrow().as_ref().unwrap() {
|
||||||
|
CanvasContext::Context2d(ref context) => Some(context.root()),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_or_init_webgl_context(&self,
|
||||||
|
cx: *mut JSContext,
|
||||||
|
attrs: Option<HandleValue>) -> Option<Root<WebGLRenderingContext>> {
|
||||||
|
if self.context.borrow().is_none() {
|
||||||
|
let window = window_from_node(self);
|
||||||
|
let size = self.get_size();
|
||||||
|
|
||||||
|
let attrs = if let Some(webgl_attributes) = attrs {
|
||||||
|
if let Ok(ref attrs) = WebGLContextAttributes::new(cx, webgl_attributes) {
|
||||||
|
From::from(attrs)
|
||||||
|
} else {
|
||||||
|
debug!("Unexpected error on conversion of WebGLContextAttributes");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GLContextAttributes::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let maybe_ctx = WebGLRenderingContext::new(GlobalRef::Window(window.r()), self, size, attrs);
|
||||||
|
|
||||||
|
*self.context.borrow_mut() = maybe_ctx.map( |ctx| CanvasContext::WebGL(JS::from_rooted(&ctx)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(CanvasContext::WebGL(ref context)) = *self.context.borrow() {
|
||||||
|
Some(context.root())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_valid(&self) -> bool {
|
||||||
|
self.height.get() != 0 && self.width.get() != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fetch_all_data(&self) -> Option<(Vec<u8>, Size2D<i32>)> {
|
||||||
|
let size = self.get_size();
|
||||||
|
|
||||||
|
if size.width == 0 || size.height == 0 {
|
||||||
|
return None
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = if let Some(renderer) = self.ipc_renderer() {
|
||||||
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
|
let msg = CanvasMsg::FromLayout(FromLayoutMsg::SendPixelContents(sender));
|
||||||
|
renderer.send(msg).unwrap();
|
||||||
|
|
||||||
|
receiver.recv().unwrap().to_vec()
|
||||||
|
} else {
|
||||||
|
repeat(0xffu8).take((size.height as usize) * (size.width as usize) * 4).collect()
|
||||||
|
};
|
||||||
|
|
||||||
|
Some((data, size))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HTMLCanvasElementMethods for HTMLCanvasElement {
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-width
|
||||||
|
fn Width(&self) -> u32 {
|
||||||
|
self.width.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-width
|
||||||
|
fn SetWidth(&self, width: u32) {
|
||||||
|
self.upcast::<Element>().set_uint_attribute(&atom!("width"), width)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-height
|
||||||
|
fn Height(&self) -> u32 {
|
||||||
|
self.height.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-height
|
||||||
|
fn SetHeight(&self, height: u32) {
|
||||||
|
self.upcast::<Element>().set_uint_attribute(&atom!("height"), height)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-getcontext
|
||||||
|
fn GetContext(&self,
|
||||||
|
cx: *mut JSContext,
|
||||||
|
id: DOMString,
|
||||||
|
attributes: Vec<HandleValue>)
|
||||||
|
-> Option<CanvasRenderingContext2DOrWebGLRenderingContext> {
|
||||||
|
match &*id {
|
||||||
|
"2d" => {
|
||||||
|
self.get_or_init_2d_context()
|
||||||
|
.map(CanvasRenderingContext2DOrWebGLRenderingContext::eCanvasRenderingContext2D)
|
||||||
|
}
|
||||||
|
"webgl" | "experimental-webgl" => {
|
||||||
|
self.get_or_init_webgl_context(cx, attributes.get(0).map(|p| *p))
|
||||||
|
.map(CanvasRenderingContext2DOrWebGLRenderingContext::eWebGLRenderingContext)
|
||||||
|
}
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-todataurl
|
||||||
|
fn ToDataURL(&self,
|
||||||
|
_context: *mut JSContext,
|
||||||
|
_mime_type: Option<DOMString>,
|
||||||
|
_arguments: Vec<HandleValue>) -> Fallible<DOMString> {
|
||||||
|
|
||||||
|
// Step 1: Check the origin-clean flag (should be set in fillText/strokeText
|
||||||
|
// and currently unimplemented)
|
||||||
|
|
||||||
|
// Step 2.
|
||||||
|
if self.Width() == 0 || self.Height() == 0 {
|
||||||
|
return Ok("data:,".to_owned());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3.
|
||||||
|
if let Some(CanvasContext::Context2d(ref context)) = *self.context.borrow() {
|
||||||
|
let window = window_from_node(self);
|
||||||
|
let image_data = try!(context.GetImageData(Finite::wrap(0f64), Finite::wrap(0f64),
|
||||||
|
Finite::wrap(self.Width() as f64),
|
||||||
|
Finite::wrap(self.Height() as f64)));
|
||||||
|
let raw_data = image_data.get_data_array(&GlobalRef::Window(window.r()));
|
||||||
|
|
||||||
|
// Only handle image/png for now.
|
||||||
|
let mime_type = "image/png";
|
||||||
|
|
||||||
|
let mut encoded = Vec::new();
|
||||||
|
{
|
||||||
|
let encoder: PNGEncoder<&mut Vec<u8>> = PNGEncoder::new(&mut encoded);
|
||||||
|
encoder.encode(&raw_data, self.Width(), self.Height(), ColorType::RGBA(8)).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let encoded = encoded.to_base64(STANDARD);
|
||||||
|
Ok(format!("data:{};base64,{}", mime_type, encoded))
|
||||||
|
} else {
|
||||||
|
Err(Error::NotSupported)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VirtualMethods for HTMLCanvasElement {
|
||||||
|
fn super_type(&self) -> Option<&VirtualMethods> {
|
||||||
|
Some(self.upcast::<HTMLElement>() as &VirtualMethods)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) {
|
||||||
|
self.super_type().unwrap().attribute_mutated(attr, mutation);
|
||||||
|
let recreate = match attr.local_name() {
|
||||||
|
&atom!(width) => {
|
||||||
|
let width = mutation.new_value(attr).and_then(|value| {
|
||||||
|
parse_unsigned_integer(value.chars())
|
||||||
|
});
|
||||||
|
self.width.set(width.unwrap_or(DEFAULT_WIDTH));
|
||||||
|
true
|
||||||
|
},
|
||||||
|
&atom!(height) => {
|
||||||
|
let height = mutation.new_value(attr).and_then(|value| {
|
||||||
|
parse_unsigned_integer(value.chars())
|
||||||
|
});
|
||||||
|
self.height.set(height.unwrap_or(DEFAULT_HEIGHT));
|
||||||
|
true
|
||||||
|
},
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
if recreate {
|
||||||
|
self.recreate_contexts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a WebGLContextAttributes> for GLContextAttributes {
|
||||||
|
fn from(attrs: &'a WebGLContextAttributes) -> GLContextAttributes {
|
||||||
|
GLContextAttributes {
|
||||||
|
alpha: attrs.alpha,
|
||||||
|
depth: attrs.depth,
|
||||||
|
stencil: attrs.stencil,
|
||||||
|
antialias: attrs.antialias,
|
||||||
|
premultiplied_alpha: attrs.premultipliedAlpha,
|
||||||
|
preserve_drawing_buffer: attrs.preserveDrawingBuffer,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod utils {
|
||||||
|
use dom::window::Window;
|
||||||
|
use ipc_channel::ipc;
|
||||||
|
use net_traits::image_cache_task::{ImageCacheChan, ImageResponse};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
pub fn request_image_from_cache(window: &Window, url: Url) -> ImageResponse {
|
||||||
|
let image_cache = window.image_cache_task();
|
||||||
|
let (response_chan, response_port) = ipc::channel().unwrap();
|
||||||
|
image_cache.request_image(url, ImageCacheChan(response_chan), None);
|
||||||
|
let result = response_port.recv().unwrap();
|
||||||
|
result.image_response
|
||||||
|
}
|
||||||
|
}
|
355
components/script/dom/htmlcanvaselement.rs.BACKUP.20237.rs
Normal file
355
components/script/dom/htmlcanvaselement.rs.BACKUP.20237.rs
Normal file
|
@ -0,0 +1,355 @@
|
||||||
|
/* 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 canvas_traits::{CanvasMsg, FromLayoutMsg};
|
||||||
|
use dom::attr::Attr;
|
||||||
|
use dom::bindings::cell::DOMRefCell;
|
||||||
|
use dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::CanvasRenderingContext2DMethods;
|
||||||
|
use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding;
|
||||||
|
use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding::HTMLCanvasElementMethods;
|
||||||
|
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLContextAttributes;
|
||||||
|
use dom::bindings::codegen::UnionTypes::CanvasRenderingContext2DOrWebGLRenderingContext;
|
||||||
|
<<<<<<< HEAD
|
||||||
|
use dom::bindings::conversions::Castable;
|
||||||
|
use dom::bindings::error::{Error, Fallible};
|
||||||
|
=======
|
||||||
|
use dom::bindings::inheritance::Castable;
|
||||||
|
>>>>>>> move Castable into dom::bindings::inheritance
|
||||||
|
use dom::bindings::global::GlobalRef;
|
||||||
|
use dom::bindings::js::{HeapGCValue, JS, LayoutJS, Root};
|
||||||
|
use dom::bindings::num::Finite;
|
||||||
|
use dom::bindings::utils::{Reflectable};
|
||||||
|
use dom::canvasrenderingcontext2d::{CanvasRenderingContext2D, LayoutCanvasRenderingContext2DHelpers};
|
||||||
|
use dom::document::Document;
|
||||||
|
use dom::element::{AttributeMutation, Element};
|
||||||
|
use dom::htmlelement::HTMLElement;
|
||||||
|
use dom::node::{Node, window_from_node};
|
||||||
|
use dom::virtualmethods::VirtualMethods;
|
||||||
|
use dom::webglrenderingcontext::{LayoutCanvasWebGLRenderingContextHelpers, WebGLRenderingContext};
|
||||||
|
use euclid::size::Size2D;
|
||||||
|
use image::ColorType;
|
||||||
|
use image::png::PNGEncoder;
|
||||||
|
use ipc_channel::ipc::{self, IpcSender};
|
||||||
|
use js::jsapi::{HandleValue, JSContext};
|
||||||
|
use offscreen_gl_context::GLContextAttributes;
|
||||||
|
use rustc_serialize::base64::{STANDARD, ToBase64};
|
||||||
|
use std::cell::Cell;
|
||||||
|
use std::iter::repeat;
|
||||||
|
use util::str::{DOMString, parse_unsigned_integer};
|
||||||
|
|
||||||
|
const DEFAULT_WIDTH: u32 = 300;
|
||||||
|
const DEFAULT_HEIGHT: u32 = 150;
|
||||||
|
|
||||||
|
#[must_root]
|
||||||
|
#[derive(JSTraceable, Clone, HeapSizeOf)]
|
||||||
|
pub enum CanvasContext {
|
||||||
|
Context2d(JS<CanvasRenderingContext2D>),
|
||||||
|
WebGL(JS<WebGLRenderingContext>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HeapGCValue for CanvasContext {}
|
||||||
|
|
||||||
|
#[dom_struct]
|
||||||
|
pub struct HTMLCanvasElement {
|
||||||
|
htmlelement: HTMLElement,
|
||||||
|
context: DOMRefCell<Option<CanvasContext>>,
|
||||||
|
width: Cell<u32>,
|
||||||
|
height: Cell<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for HTMLCanvasElement {
|
||||||
|
fn eq(&self, other: &HTMLCanvasElement) -> bool {
|
||||||
|
self as *const HTMLCanvasElement == &*other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HTMLCanvasElement {
|
||||||
|
fn new_inherited(localName: DOMString,
|
||||||
|
prefix: Option<DOMString>,
|
||||||
|
document: &Document) -> HTMLCanvasElement {
|
||||||
|
HTMLCanvasElement {
|
||||||
|
htmlelement: HTMLElement::new_inherited(localName, prefix, document),
|
||||||
|
context: DOMRefCell::new(None),
|
||||||
|
width: Cell::new(DEFAULT_WIDTH),
|
||||||
|
height: Cell::new(DEFAULT_HEIGHT),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unrooted_must_root)]
|
||||||
|
pub fn new(localName: DOMString,
|
||||||
|
prefix: Option<DOMString>,
|
||||||
|
document: &Document) -> Root<HTMLCanvasElement> {
|
||||||
|
let element = HTMLCanvasElement::new_inherited(localName, prefix, document);
|
||||||
|
Node::reflect_node(box element, document, HTMLCanvasElementBinding::Wrap)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recreate_contexts(&self) {
|
||||||
|
let size = self.get_size();
|
||||||
|
if let Some(ref context) = *self.context.borrow() {
|
||||||
|
match *context {
|
||||||
|
CanvasContext::Context2d(ref context) => context.recreate(size),
|
||||||
|
CanvasContext::WebGL(ref context) => context.recreate(size),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_size(&self) -> Size2D<i32> {
|
||||||
|
Size2D::new(self.width.get() as i32, self.height.get() as i32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct HTMLCanvasData {
|
||||||
|
pub renderer_id: Option<usize>,
|
||||||
|
pub ipc_renderer: Option<IpcSender<CanvasMsg>>,
|
||||||
|
pub width: u32,
|
||||||
|
pub height: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait LayoutHTMLCanvasElementHelpers {
|
||||||
|
fn data(&self) -> HTMLCanvasData;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> {
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
fn data(&self) -> HTMLCanvasData {
|
||||||
|
unsafe {
|
||||||
|
let canvas = &*self.unsafe_get();
|
||||||
|
let (renderer_id, ipc_renderer) = match canvas.context.borrow_for_layout().as_ref() {
|
||||||
|
Some(&CanvasContext::Context2d(ref context)) => {
|
||||||
|
let context = context.to_layout();
|
||||||
|
(Some(context.get_renderer_id()), Some(context.get_ipc_renderer()))
|
||||||
|
},
|
||||||
|
Some(&CanvasContext::WebGL(ref context)) => {
|
||||||
|
let context = context.to_layout();
|
||||||
|
(Some(context.get_renderer_id()), Some(context.get_ipc_renderer()))
|
||||||
|
},
|
||||||
|
None => (None, None),
|
||||||
|
};
|
||||||
|
|
||||||
|
HTMLCanvasData {
|
||||||
|
renderer_id: renderer_id,
|
||||||
|
ipc_renderer: ipc_renderer,
|
||||||
|
width: canvas.width.get(),
|
||||||
|
height: canvas.height.get(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl HTMLCanvasElement {
|
||||||
|
pub fn ipc_renderer(&self) -> Option<IpcSender<CanvasMsg>> {
|
||||||
|
self.context.borrow().as_ref().map(|context| {
|
||||||
|
match *context {
|
||||||
|
CanvasContext::Context2d(ref context) => context.ipc_renderer(),
|
||||||
|
CanvasContext::WebGL(ref context) => context.ipc_renderer(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_or_init_2d_context(&self) -> Option<Root<CanvasRenderingContext2D>> {
|
||||||
|
if self.context.borrow().is_none() {
|
||||||
|
let window = window_from_node(self);
|
||||||
|
let size = self.get_size();
|
||||||
|
let context = CanvasRenderingContext2D::new(GlobalRef::Window(window.r()), self, size);
|
||||||
|
*self.context.borrow_mut() = Some(CanvasContext::Context2d(JS::from_rooted(&context)));
|
||||||
|
}
|
||||||
|
|
||||||
|
match *self.context.borrow().as_ref().unwrap() {
|
||||||
|
CanvasContext::Context2d(ref context) => Some(context.root()),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_or_init_webgl_context(&self,
|
||||||
|
cx: *mut JSContext,
|
||||||
|
attrs: Option<HandleValue>) -> Option<Root<WebGLRenderingContext>> {
|
||||||
|
if self.context.borrow().is_none() {
|
||||||
|
let window = window_from_node(self);
|
||||||
|
let size = self.get_size();
|
||||||
|
|
||||||
|
let attrs = if let Some(webgl_attributes) = attrs {
|
||||||
|
if let Ok(ref attrs) = WebGLContextAttributes::new(cx, webgl_attributes) {
|
||||||
|
From::from(attrs)
|
||||||
|
} else {
|
||||||
|
debug!("Unexpected error on conversion of WebGLContextAttributes");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GLContextAttributes::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let maybe_ctx = WebGLRenderingContext::new(GlobalRef::Window(window.r()), self, size, attrs);
|
||||||
|
|
||||||
|
*self.context.borrow_mut() = maybe_ctx.map( |ctx| CanvasContext::WebGL(JS::from_rooted(&ctx)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(CanvasContext::WebGL(ref context)) = *self.context.borrow() {
|
||||||
|
Some(context.root())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_valid(&self) -> bool {
|
||||||
|
self.height.get() != 0 && self.width.get() != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fetch_all_data(&self) -> Option<(Vec<u8>, Size2D<i32>)> {
|
||||||
|
let size = self.get_size();
|
||||||
|
|
||||||
|
if size.width == 0 || size.height == 0 {
|
||||||
|
return None
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = if let Some(renderer) = self.ipc_renderer() {
|
||||||
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
|
let msg = CanvasMsg::FromLayout(FromLayoutMsg::SendPixelContents(sender));
|
||||||
|
renderer.send(msg).unwrap();
|
||||||
|
|
||||||
|
receiver.recv().unwrap().to_vec()
|
||||||
|
} else {
|
||||||
|
repeat(0xffu8).take((size.height as usize) * (size.width as usize) * 4).collect()
|
||||||
|
};
|
||||||
|
|
||||||
|
Some((data, size))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HTMLCanvasElementMethods for HTMLCanvasElement {
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-width
|
||||||
|
fn Width(&self) -> u32 {
|
||||||
|
self.width.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-width
|
||||||
|
fn SetWidth(&self, width: u32) {
|
||||||
|
self.upcast::<Element>().set_uint_attribute(&atom!("width"), width)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-height
|
||||||
|
fn Height(&self) -> u32 {
|
||||||
|
self.height.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-height
|
||||||
|
fn SetHeight(&self, height: u32) {
|
||||||
|
self.upcast::<Element>().set_uint_attribute(&atom!("height"), height)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-getcontext
|
||||||
|
fn GetContext(&self,
|
||||||
|
cx: *mut JSContext,
|
||||||
|
id: DOMString,
|
||||||
|
attributes: Vec<HandleValue>)
|
||||||
|
-> Option<CanvasRenderingContext2DOrWebGLRenderingContext> {
|
||||||
|
match &*id {
|
||||||
|
"2d" => {
|
||||||
|
self.get_or_init_2d_context()
|
||||||
|
.map(CanvasRenderingContext2DOrWebGLRenderingContext::eCanvasRenderingContext2D)
|
||||||
|
}
|
||||||
|
"webgl" | "experimental-webgl" => {
|
||||||
|
self.get_or_init_webgl_context(cx, attributes.get(0).map(|p| *p))
|
||||||
|
.map(CanvasRenderingContext2DOrWebGLRenderingContext::eWebGLRenderingContext)
|
||||||
|
}
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-todataurl
|
||||||
|
fn ToDataURL(&self,
|
||||||
|
_context: *mut JSContext,
|
||||||
|
_mime_type: Option<DOMString>,
|
||||||
|
_arguments: Vec<HandleValue>) -> Fallible<DOMString> {
|
||||||
|
|
||||||
|
// Step 1: Check the origin-clean flag (should be set in fillText/strokeText
|
||||||
|
// and currently unimplemented)
|
||||||
|
|
||||||
|
// Step 2.
|
||||||
|
if self.Width() == 0 || self.Height() == 0 {
|
||||||
|
return Ok("data:,".to_owned());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3.
|
||||||
|
if let Some(CanvasContext::Context2d(ref context)) = *self.context.borrow() {
|
||||||
|
let window = window_from_node(self);
|
||||||
|
let image_data = try!(context.GetImageData(Finite::wrap(0f64), Finite::wrap(0f64),
|
||||||
|
Finite::wrap(self.Width() as f64),
|
||||||
|
Finite::wrap(self.Height() as f64)));
|
||||||
|
let raw_data = image_data.get_data_array(&GlobalRef::Window(window.r()));
|
||||||
|
|
||||||
|
// Only handle image/png for now.
|
||||||
|
let mime_type = "image/png";
|
||||||
|
|
||||||
|
let mut encoded = Vec::new();
|
||||||
|
{
|
||||||
|
let encoder: PNGEncoder<&mut Vec<u8>> = PNGEncoder::new(&mut encoded);
|
||||||
|
encoder.encode(&raw_data, self.Width(), self.Height(), ColorType::RGBA(8)).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let encoded = encoded.to_base64(STANDARD);
|
||||||
|
Ok(format!("data:{};base64,{}", mime_type, encoded))
|
||||||
|
} else {
|
||||||
|
Err(Error::NotSupported)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VirtualMethods for HTMLCanvasElement {
|
||||||
|
fn super_type(&self) -> Option<&VirtualMethods> {
|
||||||
|
Some(self.upcast::<HTMLElement>() as &VirtualMethods)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) {
|
||||||
|
self.super_type().unwrap().attribute_mutated(attr, mutation);
|
||||||
|
let recreate = match attr.local_name() {
|
||||||
|
&atom!(width) => {
|
||||||
|
let width = mutation.new_value(attr).and_then(|value| {
|
||||||
|
parse_unsigned_integer(value.chars())
|
||||||
|
});
|
||||||
|
self.width.set(width.unwrap_or(DEFAULT_WIDTH));
|
||||||
|
true
|
||||||
|
},
|
||||||
|
&atom!(height) => {
|
||||||
|
let height = mutation.new_value(attr).and_then(|value| {
|
||||||
|
parse_unsigned_integer(value.chars())
|
||||||
|
});
|
||||||
|
self.height.set(height.unwrap_or(DEFAULT_HEIGHT));
|
||||||
|
true
|
||||||
|
},
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
if recreate {
|
||||||
|
self.recreate_contexts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a WebGLContextAttributes> for GLContextAttributes {
|
||||||
|
fn from(attrs: &'a WebGLContextAttributes) -> GLContextAttributes {
|
||||||
|
GLContextAttributes {
|
||||||
|
alpha: attrs.alpha,
|
||||||
|
depth: attrs.depth,
|
||||||
|
stencil: attrs.stencil,
|
||||||
|
antialias: attrs.antialias,
|
||||||
|
premultiplied_alpha: attrs.premultipliedAlpha,
|
||||||
|
preserve_drawing_buffer: attrs.preserveDrawingBuffer,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod utils {
|
||||||
|
use dom::window::Window;
|
||||||
|
use ipc_channel::ipc;
|
||||||
|
use net_traits::image_cache_task::{ImageCacheChan, ImageResponse};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
pub fn request_image_from_cache(window: &Window, url: Url) -> ImageResponse {
|
||||||
|
let image_cache = window.image_cache_task();
|
||||||
|
let (response_chan, response_port) = ipc::channel().unwrap();
|
||||||
|
image_cache.request_image(url, ImageCacheChan(response_chan), None);
|
||||||
|
let result = response_port.recv().unwrap();
|
||||||
|
result.image_response
|
||||||
|
}
|
||||||
|
}
|
307
components/script/dom/htmlcanvaselement.rs.BASE.20128.rs
Normal file
307
components/script/dom/htmlcanvaselement.rs.BASE.20128.rs
Normal file
|
@ -0,0 +1,307 @@
|
||||||
|
/* 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 canvas_traits::{CanvasMsg, FromLayoutMsg};
|
||||||
|
use dom::attr::Attr;
|
||||||
|
use dom::bindings::cell::DOMRefCell;
|
||||||
|
use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding;
|
||||||
|
use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding::HTMLCanvasElementMethods;
|
||||||
|
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLContextAttributes;
|
||||||
|
use dom::bindings::codegen::UnionTypes::CanvasRenderingContext2DOrWebGLRenderingContext;
|
||||||
|
use dom::bindings::conversions::Castable;
|
||||||
|
use dom::bindings::global::GlobalRef;
|
||||||
|
use dom::bindings::js::{HeapGCValue, JS, LayoutJS, Root};
|
||||||
|
use dom::bindings::utils::{Reflectable};
|
||||||
|
use dom::canvasrenderingcontext2d::{CanvasRenderingContext2D, LayoutCanvasRenderingContext2DHelpers};
|
||||||
|
use dom::document::Document;
|
||||||
|
use dom::element::{AttributeMutation, Element};
|
||||||
|
use dom::htmlelement::HTMLElement;
|
||||||
|
use dom::node::{Node, window_from_node};
|
||||||
|
use dom::virtualmethods::VirtualMethods;
|
||||||
|
use dom::webglrenderingcontext::{LayoutCanvasWebGLRenderingContextHelpers, WebGLRenderingContext};
|
||||||
|
use euclid::size::Size2D;
|
||||||
|
use ipc_channel::ipc::{self, IpcSender};
|
||||||
|
use js::jsapi::{HandleValue, JSContext};
|
||||||
|
use offscreen_gl_context::GLContextAttributes;
|
||||||
|
use std::cell::Cell;
|
||||||
|
use std::iter::repeat;
|
||||||
|
use util::str::{DOMString, parse_unsigned_integer};
|
||||||
|
|
||||||
|
const DEFAULT_WIDTH: u32 = 300;
|
||||||
|
const DEFAULT_HEIGHT: u32 = 150;
|
||||||
|
|
||||||
|
#[must_root]
|
||||||
|
#[derive(JSTraceable, Clone, HeapSizeOf)]
|
||||||
|
pub enum CanvasContext {
|
||||||
|
Context2d(JS<CanvasRenderingContext2D>),
|
||||||
|
WebGL(JS<WebGLRenderingContext>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HeapGCValue for CanvasContext {}
|
||||||
|
|
||||||
|
#[dom_struct]
|
||||||
|
pub struct HTMLCanvasElement {
|
||||||
|
htmlelement: HTMLElement,
|
||||||
|
context: DOMRefCell<Option<CanvasContext>>,
|
||||||
|
width: Cell<u32>,
|
||||||
|
height: Cell<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for HTMLCanvasElement {
|
||||||
|
fn eq(&self, other: &HTMLCanvasElement) -> bool {
|
||||||
|
self as *const HTMLCanvasElement == &*other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HTMLCanvasElement {
|
||||||
|
fn new_inherited(localName: DOMString,
|
||||||
|
prefix: Option<DOMString>,
|
||||||
|
document: &Document) -> HTMLCanvasElement {
|
||||||
|
HTMLCanvasElement {
|
||||||
|
htmlelement: HTMLElement::new_inherited(localName, prefix, document),
|
||||||
|
context: DOMRefCell::new(None),
|
||||||
|
width: Cell::new(DEFAULT_WIDTH),
|
||||||
|
height: Cell::new(DEFAULT_HEIGHT),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unrooted_must_root)]
|
||||||
|
pub fn new(localName: DOMString,
|
||||||
|
prefix: Option<DOMString>,
|
||||||
|
document: &Document) -> Root<HTMLCanvasElement> {
|
||||||
|
let element = HTMLCanvasElement::new_inherited(localName, prefix, document);
|
||||||
|
Node::reflect_node(box element, document, HTMLCanvasElementBinding::Wrap)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recreate_contexts(&self) {
|
||||||
|
let size = self.get_size();
|
||||||
|
if let Some(ref context) = *self.context.borrow() {
|
||||||
|
match *context {
|
||||||
|
CanvasContext::Context2d(ref context) => context.recreate(size),
|
||||||
|
CanvasContext::WebGL(ref context) => context.recreate(size),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_size(&self) -> Size2D<i32> {
|
||||||
|
Size2D::new(self.width.get() as i32, self.height.get() as i32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct HTMLCanvasData {
|
||||||
|
pub renderer_id: Option<usize>,
|
||||||
|
pub ipc_renderer: Option<IpcSender<CanvasMsg>>,
|
||||||
|
pub width: u32,
|
||||||
|
pub height: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait LayoutHTMLCanvasElementHelpers {
|
||||||
|
fn data(&self) -> HTMLCanvasData;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> {
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
fn data(&self) -> HTMLCanvasData {
|
||||||
|
unsafe {
|
||||||
|
let canvas = &*self.unsafe_get();
|
||||||
|
let (renderer_id, ipc_renderer) = match canvas.context.borrow_for_layout().as_ref() {
|
||||||
|
Some(&CanvasContext::Context2d(ref context)) => {
|
||||||
|
let context = context.to_layout();
|
||||||
|
(Some(context.get_renderer_id()), Some(context.get_ipc_renderer()))
|
||||||
|
},
|
||||||
|
Some(&CanvasContext::WebGL(ref context)) => {
|
||||||
|
let context = context.to_layout();
|
||||||
|
(Some(context.get_renderer_id()), Some(context.get_ipc_renderer()))
|
||||||
|
},
|
||||||
|
None => (None, None),
|
||||||
|
};
|
||||||
|
|
||||||
|
HTMLCanvasData {
|
||||||
|
renderer_id: renderer_id,
|
||||||
|
ipc_renderer: ipc_renderer,
|
||||||
|
width: canvas.width.get(),
|
||||||
|
height: canvas.height.get(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl HTMLCanvasElement {
|
||||||
|
pub fn ipc_renderer(&self) -> Option<IpcSender<CanvasMsg>> {
|
||||||
|
self.context.borrow().as_ref().map(|context| {
|
||||||
|
match *context {
|
||||||
|
CanvasContext::Context2d(ref context) => context.ipc_renderer(),
|
||||||
|
CanvasContext::WebGL(ref context) => context.ipc_renderer(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_or_init_2d_context(&self) -> Option<Root<CanvasRenderingContext2D>> {
|
||||||
|
if self.context.borrow().is_none() {
|
||||||
|
let window = window_from_node(self);
|
||||||
|
let size = self.get_size();
|
||||||
|
let context = CanvasRenderingContext2D::new(GlobalRef::Window(window.r()), self, size);
|
||||||
|
*self.context.borrow_mut() = Some(CanvasContext::Context2d(JS::from_rooted(&context)));
|
||||||
|
}
|
||||||
|
|
||||||
|
match *self.context.borrow().as_ref().unwrap() {
|
||||||
|
CanvasContext::Context2d(ref context) => Some(context.root()),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_or_init_webgl_context(&self,
|
||||||
|
cx: *mut JSContext,
|
||||||
|
attrs: Option<HandleValue>) -> Option<Root<WebGLRenderingContext>> {
|
||||||
|
if self.context.borrow().is_none() {
|
||||||
|
let window = window_from_node(self);
|
||||||
|
let size = self.get_size();
|
||||||
|
|
||||||
|
let attrs = if let Some(webgl_attributes) = attrs {
|
||||||
|
if let Ok(ref attrs) = WebGLContextAttributes::new(cx, webgl_attributes) {
|
||||||
|
From::from(attrs)
|
||||||
|
} else {
|
||||||
|
debug!("Unexpected error on conversion of WebGLContextAttributes");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GLContextAttributes::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let maybe_ctx = WebGLRenderingContext::new(GlobalRef::Window(window.r()), self, size, attrs);
|
||||||
|
|
||||||
|
*self.context.borrow_mut() = maybe_ctx.map( |ctx| CanvasContext::WebGL(JS::from_rooted(&ctx)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(CanvasContext::WebGL(ref context)) = *self.context.borrow() {
|
||||||
|
Some(context.root())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_valid(&self) -> bool {
|
||||||
|
self.height.get() != 0 && self.width.get() != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fetch_all_data(&self) -> Option<(Vec<u8>, Size2D<i32>)> {
|
||||||
|
let size = self.get_size();
|
||||||
|
|
||||||
|
if size.width == 0 || size.height == 0 {
|
||||||
|
return None
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = if let Some(renderer) = self.ipc_renderer() {
|
||||||
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
|
let msg = CanvasMsg::FromLayout(FromLayoutMsg::SendPixelContents(sender));
|
||||||
|
renderer.send(msg).unwrap();
|
||||||
|
|
||||||
|
receiver.recv().unwrap().to_vec()
|
||||||
|
} else {
|
||||||
|
repeat(0xffu8).take((size.height as usize) * (size.width as usize) * 4).collect()
|
||||||
|
};
|
||||||
|
|
||||||
|
Some((data, size))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HTMLCanvasElementMethods for HTMLCanvasElement {
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-width
|
||||||
|
fn Width(&self) -> u32 {
|
||||||
|
self.width.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-width
|
||||||
|
fn SetWidth(&self, width: u32) {
|
||||||
|
self.upcast::<Element>().set_uint_attribute(&atom!("width"), width)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-height
|
||||||
|
fn Height(&self) -> u32 {
|
||||||
|
self.height.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-height
|
||||||
|
fn SetHeight(&self, height: u32) {
|
||||||
|
self.upcast::<Element>().set_uint_attribute(&atom!("height"), height)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-getcontext
|
||||||
|
fn GetContext(&self,
|
||||||
|
cx: *mut JSContext,
|
||||||
|
id: DOMString,
|
||||||
|
attributes: Vec<HandleValue>)
|
||||||
|
-> Option<CanvasRenderingContext2DOrWebGLRenderingContext> {
|
||||||
|
match &*id {
|
||||||
|
"2d" => {
|
||||||
|
self.get_or_init_2d_context()
|
||||||
|
.map(CanvasRenderingContext2DOrWebGLRenderingContext::eCanvasRenderingContext2D)
|
||||||
|
}
|
||||||
|
"webgl" | "experimental-webgl" => {
|
||||||
|
self.get_or_init_webgl_context(cx, attributes.get(0).map(|p| *p))
|
||||||
|
.map(CanvasRenderingContext2DOrWebGLRenderingContext::eWebGLRenderingContext)
|
||||||
|
}
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VirtualMethods for HTMLCanvasElement {
|
||||||
|
fn super_type(&self) -> Option<&VirtualMethods> {
|
||||||
|
Some(self.upcast::<HTMLElement>() as &VirtualMethods)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) {
|
||||||
|
self.super_type().unwrap().attribute_mutated(attr, mutation);
|
||||||
|
let recreate = match attr.local_name() {
|
||||||
|
&atom!(width) => {
|
||||||
|
let width = mutation.new_value(attr).and_then(|value| {
|
||||||
|
parse_unsigned_integer(value.chars())
|
||||||
|
});
|
||||||
|
self.width.set(width.unwrap_or(DEFAULT_WIDTH));
|
||||||
|
true
|
||||||
|
},
|
||||||
|
&atom!(height) => {
|
||||||
|
let height = mutation.new_value(attr).and_then(|value| {
|
||||||
|
parse_unsigned_integer(value.chars())
|
||||||
|
});
|
||||||
|
self.height.set(height.unwrap_or(DEFAULT_HEIGHT));
|
||||||
|
true
|
||||||
|
},
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
if recreate {
|
||||||
|
self.recreate_contexts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a WebGLContextAttributes> for GLContextAttributes {
|
||||||
|
fn from(attrs: &'a WebGLContextAttributes) -> GLContextAttributes {
|
||||||
|
GLContextAttributes {
|
||||||
|
alpha: attrs.alpha,
|
||||||
|
depth: attrs.depth,
|
||||||
|
stencil: attrs.stencil,
|
||||||
|
antialias: attrs.antialias,
|
||||||
|
premultiplied_alpha: attrs.premultipliedAlpha,
|
||||||
|
preserve_drawing_buffer: attrs.preserveDrawingBuffer,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod utils {
|
||||||
|
use dom::window::Window;
|
||||||
|
use ipc_channel::ipc;
|
||||||
|
use net_traits::image_cache_task::{ImageCacheChan, ImageResponse};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
pub fn request_image_from_cache(window: &Window, url: Url) -> ImageResponse {
|
||||||
|
let image_cache = window.image_cache_task();
|
||||||
|
let (response_chan, response_port) = ipc::channel().unwrap();
|
||||||
|
image_cache.request_image(url, ImageCacheChan(response_chan), None);
|
||||||
|
let result = response_port.recv().unwrap();
|
||||||
|
result.image_response
|
||||||
|
}
|
||||||
|
}
|
307
components/script/dom/htmlcanvaselement.rs.BASE.20237.rs
Normal file
307
components/script/dom/htmlcanvaselement.rs.BASE.20237.rs
Normal file
|
@ -0,0 +1,307 @@
|
||||||
|
/* 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 canvas_traits::{CanvasMsg, FromLayoutMsg};
|
||||||
|
use dom::attr::Attr;
|
||||||
|
use dom::bindings::cell::DOMRefCell;
|
||||||
|
use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding;
|
||||||
|
use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding::HTMLCanvasElementMethods;
|
||||||
|
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLContextAttributes;
|
||||||
|
use dom::bindings::codegen::UnionTypes::CanvasRenderingContext2DOrWebGLRenderingContext;
|
||||||
|
use dom::bindings::conversions::Castable;
|
||||||
|
use dom::bindings::global::GlobalRef;
|
||||||
|
use dom::bindings::js::{HeapGCValue, JS, LayoutJS, Root};
|
||||||
|
use dom::bindings::utils::{Reflectable};
|
||||||
|
use dom::canvasrenderingcontext2d::{CanvasRenderingContext2D, LayoutCanvasRenderingContext2DHelpers};
|
||||||
|
use dom::document::Document;
|
||||||
|
use dom::element::{AttributeMutation, Element};
|
||||||
|
use dom::htmlelement::HTMLElement;
|
||||||
|
use dom::node::{Node, window_from_node};
|
||||||
|
use dom::virtualmethods::VirtualMethods;
|
||||||
|
use dom::webglrenderingcontext::{LayoutCanvasWebGLRenderingContextHelpers, WebGLRenderingContext};
|
||||||
|
use euclid::size::Size2D;
|
||||||
|
use ipc_channel::ipc::{self, IpcSender};
|
||||||
|
use js::jsapi::{HandleValue, JSContext};
|
||||||
|
use offscreen_gl_context::GLContextAttributes;
|
||||||
|
use std::cell::Cell;
|
||||||
|
use std::iter::repeat;
|
||||||
|
use util::str::{DOMString, parse_unsigned_integer};
|
||||||
|
|
||||||
|
const DEFAULT_WIDTH: u32 = 300;
|
||||||
|
const DEFAULT_HEIGHT: u32 = 150;
|
||||||
|
|
||||||
|
#[must_root]
|
||||||
|
#[derive(JSTraceable, Clone, HeapSizeOf)]
|
||||||
|
pub enum CanvasContext {
|
||||||
|
Context2d(JS<CanvasRenderingContext2D>),
|
||||||
|
WebGL(JS<WebGLRenderingContext>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HeapGCValue for CanvasContext {}
|
||||||
|
|
||||||
|
#[dom_struct]
|
||||||
|
pub struct HTMLCanvasElement {
|
||||||
|
htmlelement: HTMLElement,
|
||||||
|
context: DOMRefCell<Option<CanvasContext>>,
|
||||||
|
width: Cell<u32>,
|
||||||
|
height: Cell<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for HTMLCanvasElement {
|
||||||
|
fn eq(&self, other: &HTMLCanvasElement) -> bool {
|
||||||
|
self as *const HTMLCanvasElement == &*other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HTMLCanvasElement {
|
||||||
|
fn new_inherited(localName: DOMString,
|
||||||
|
prefix: Option<DOMString>,
|
||||||
|
document: &Document) -> HTMLCanvasElement {
|
||||||
|
HTMLCanvasElement {
|
||||||
|
htmlelement: HTMLElement::new_inherited(localName, prefix, document),
|
||||||
|
context: DOMRefCell::new(None),
|
||||||
|
width: Cell::new(DEFAULT_WIDTH),
|
||||||
|
height: Cell::new(DEFAULT_HEIGHT),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unrooted_must_root)]
|
||||||
|
pub fn new(localName: DOMString,
|
||||||
|
prefix: Option<DOMString>,
|
||||||
|
document: &Document) -> Root<HTMLCanvasElement> {
|
||||||
|
let element = HTMLCanvasElement::new_inherited(localName, prefix, document);
|
||||||
|
Node::reflect_node(box element, document, HTMLCanvasElementBinding::Wrap)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recreate_contexts(&self) {
|
||||||
|
let size = self.get_size();
|
||||||
|
if let Some(ref context) = *self.context.borrow() {
|
||||||
|
match *context {
|
||||||
|
CanvasContext::Context2d(ref context) => context.recreate(size),
|
||||||
|
CanvasContext::WebGL(ref context) => context.recreate(size),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_size(&self) -> Size2D<i32> {
|
||||||
|
Size2D::new(self.width.get() as i32, self.height.get() as i32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct HTMLCanvasData {
|
||||||
|
pub renderer_id: Option<usize>,
|
||||||
|
pub ipc_renderer: Option<IpcSender<CanvasMsg>>,
|
||||||
|
pub width: u32,
|
||||||
|
pub height: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait LayoutHTMLCanvasElementHelpers {
|
||||||
|
fn data(&self) -> HTMLCanvasData;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> {
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
fn data(&self) -> HTMLCanvasData {
|
||||||
|
unsafe {
|
||||||
|
let canvas = &*self.unsafe_get();
|
||||||
|
let (renderer_id, ipc_renderer) = match canvas.context.borrow_for_layout().as_ref() {
|
||||||
|
Some(&CanvasContext::Context2d(ref context)) => {
|
||||||
|
let context = context.to_layout();
|
||||||
|
(Some(context.get_renderer_id()), Some(context.get_ipc_renderer()))
|
||||||
|
},
|
||||||
|
Some(&CanvasContext::WebGL(ref context)) => {
|
||||||
|
let context = context.to_layout();
|
||||||
|
(Some(context.get_renderer_id()), Some(context.get_ipc_renderer()))
|
||||||
|
},
|
||||||
|
None => (None, None),
|
||||||
|
};
|
||||||
|
|
||||||
|
HTMLCanvasData {
|
||||||
|
renderer_id: renderer_id,
|
||||||
|
ipc_renderer: ipc_renderer,
|
||||||
|
width: canvas.width.get(),
|
||||||
|
height: canvas.height.get(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl HTMLCanvasElement {
|
||||||
|
pub fn ipc_renderer(&self) -> Option<IpcSender<CanvasMsg>> {
|
||||||
|
self.context.borrow().as_ref().map(|context| {
|
||||||
|
match *context {
|
||||||
|
CanvasContext::Context2d(ref context) => context.ipc_renderer(),
|
||||||
|
CanvasContext::WebGL(ref context) => context.ipc_renderer(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_or_init_2d_context(&self) -> Option<Root<CanvasRenderingContext2D>> {
|
||||||
|
if self.context.borrow().is_none() {
|
||||||
|
let window = window_from_node(self);
|
||||||
|
let size = self.get_size();
|
||||||
|
let context = CanvasRenderingContext2D::new(GlobalRef::Window(window.r()), self, size);
|
||||||
|
*self.context.borrow_mut() = Some(CanvasContext::Context2d(JS::from_rooted(&context)));
|
||||||
|
}
|
||||||
|
|
||||||
|
match *self.context.borrow().as_ref().unwrap() {
|
||||||
|
CanvasContext::Context2d(ref context) => Some(context.root()),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_or_init_webgl_context(&self,
|
||||||
|
cx: *mut JSContext,
|
||||||
|
attrs: Option<HandleValue>) -> Option<Root<WebGLRenderingContext>> {
|
||||||
|
if self.context.borrow().is_none() {
|
||||||
|
let window = window_from_node(self);
|
||||||
|
let size = self.get_size();
|
||||||
|
|
||||||
|
let attrs = if let Some(webgl_attributes) = attrs {
|
||||||
|
if let Ok(ref attrs) = WebGLContextAttributes::new(cx, webgl_attributes) {
|
||||||
|
From::from(attrs)
|
||||||
|
} else {
|
||||||
|
debug!("Unexpected error on conversion of WebGLContextAttributes");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GLContextAttributes::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let maybe_ctx = WebGLRenderingContext::new(GlobalRef::Window(window.r()), self, size, attrs);
|
||||||
|
|
||||||
|
*self.context.borrow_mut() = maybe_ctx.map( |ctx| CanvasContext::WebGL(JS::from_rooted(&ctx)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(CanvasContext::WebGL(ref context)) = *self.context.borrow() {
|
||||||
|
Some(context.root())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_valid(&self) -> bool {
|
||||||
|
self.height.get() != 0 && self.width.get() != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fetch_all_data(&self) -> Option<(Vec<u8>, Size2D<i32>)> {
|
||||||
|
let size = self.get_size();
|
||||||
|
|
||||||
|
if size.width == 0 || size.height == 0 {
|
||||||
|
return None
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = if let Some(renderer) = self.ipc_renderer() {
|
||||||
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
|
let msg = CanvasMsg::FromLayout(FromLayoutMsg::SendPixelContents(sender));
|
||||||
|
renderer.send(msg).unwrap();
|
||||||
|
|
||||||
|
receiver.recv().unwrap().to_vec()
|
||||||
|
} else {
|
||||||
|
repeat(0xffu8).take((size.height as usize) * (size.width as usize) * 4).collect()
|
||||||
|
};
|
||||||
|
|
||||||
|
Some((data, size))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HTMLCanvasElementMethods for HTMLCanvasElement {
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-width
|
||||||
|
fn Width(&self) -> u32 {
|
||||||
|
self.width.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-width
|
||||||
|
fn SetWidth(&self, width: u32) {
|
||||||
|
self.upcast::<Element>().set_uint_attribute(&atom!("width"), width)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-height
|
||||||
|
fn Height(&self) -> u32 {
|
||||||
|
self.height.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-height
|
||||||
|
fn SetHeight(&self, height: u32) {
|
||||||
|
self.upcast::<Element>().set_uint_attribute(&atom!("height"), height)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-getcontext
|
||||||
|
fn GetContext(&self,
|
||||||
|
cx: *mut JSContext,
|
||||||
|
id: DOMString,
|
||||||
|
attributes: Vec<HandleValue>)
|
||||||
|
-> Option<CanvasRenderingContext2DOrWebGLRenderingContext> {
|
||||||
|
match &*id {
|
||||||
|
"2d" => {
|
||||||
|
self.get_or_init_2d_context()
|
||||||
|
.map(CanvasRenderingContext2DOrWebGLRenderingContext::eCanvasRenderingContext2D)
|
||||||
|
}
|
||||||
|
"webgl" | "experimental-webgl" => {
|
||||||
|
self.get_or_init_webgl_context(cx, attributes.get(0).map(|p| *p))
|
||||||
|
.map(CanvasRenderingContext2DOrWebGLRenderingContext::eWebGLRenderingContext)
|
||||||
|
}
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VirtualMethods for HTMLCanvasElement {
|
||||||
|
fn super_type(&self) -> Option<&VirtualMethods> {
|
||||||
|
Some(self.upcast::<HTMLElement>() as &VirtualMethods)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) {
|
||||||
|
self.super_type().unwrap().attribute_mutated(attr, mutation);
|
||||||
|
let recreate = match attr.local_name() {
|
||||||
|
&atom!(width) => {
|
||||||
|
let width = mutation.new_value(attr).and_then(|value| {
|
||||||
|
parse_unsigned_integer(value.chars())
|
||||||
|
});
|
||||||
|
self.width.set(width.unwrap_or(DEFAULT_WIDTH));
|
||||||
|
true
|
||||||
|
},
|
||||||
|
&atom!(height) => {
|
||||||
|
let height = mutation.new_value(attr).and_then(|value| {
|
||||||
|
parse_unsigned_integer(value.chars())
|
||||||
|
});
|
||||||
|
self.height.set(height.unwrap_or(DEFAULT_HEIGHT));
|
||||||
|
true
|
||||||
|
},
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
if recreate {
|
||||||
|
self.recreate_contexts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a WebGLContextAttributes> for GLContextAttributes {
|
||||||
|
fn from(attrs: &'a WebGLContextAttributes) -> GLContextAttributes {
|
||||||
|
GLContextAttributes {
|
||||||
|
alpha: attrs.alpha,
|
||||||
|
depth: attrs.depth,
|
||||||
|
stencil: attrs.stencil,
|
||||||
|
antialias: attrs.antialias,
|
||||||
|
premultiplied_alpha: attrs.premultipliedAlpha,
|
||||||
|
preserve_drawing_buffer: attrs.preserveDrawingBuffer,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod utils {
|
||||||
|
use dom::window::Window;
|
||||||
|
use ipc_channel::ipc;
|
||||||
|
use net_traits::image_cache_task::{ImageCacheChan, ImageResponse};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
pub fn request_image_from_cache(window: &Window, url: Url) -> ImageResponse {
|
||||||
|
let image_cache = window.image_cache_task();
|
||||||
|
let (response_chan, response_port) = ipc::channel().unwrap();
|
||||||
|
image_cache.request_image(url, ImageCacheChan(response_chan), None);
|
||||||
|
let result = response_port.recv().unwrap();
|
||||||
|
result.image_response
|
||||||
|
}
|
||||||
|
}
|
351
components/script/dom/htmlcanvaselement.rs.LOCAL.20128.rs
Normal file
351
components/script/dom/htmlcanvaselement.rs.LOCAL.20128.rs
Normal file
|
@ -0,0 +1,351 @@
|
||||||
|
/* 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 canvas_traits::{CanvasMsg, FromLayoutMsg};
|
||||||
|
use dom::attr::Attr;
|
||||||
|
use dom::bindings::cell::DOMRefCell;
|
||||||
|
use dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::CanvasRenderingContext2DMethods;
|
||||||
|
use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding;
|
||||||
|
use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding::HTMLCanvasElementMethods;
|
||||||
|
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLContextAttributes;
|
||||||
|
use dom::bindings::codegen::UnionTypes::CanvasRenderingContext2DOrWebGLRenderingContext;
|
||||||
|
use dom::bindings::conversions::Castable;
|
||||||
|
use dom::bindings::error::{Error, Fallible};
|
||||||
|
use dom::bindings::global::GlobalRef;
|
||||||
|
use dom::bindings::js::{HeapGCValue, JS, LayoutJS, Root};
|
||||||
|
use dom::bindings::num::Finite;
|
||||||
|
use dom::bindings::utils::{Reflectable};
|
||||||
|
use dom::canvasrenderingcontext2d::{CanvasRenderingContext2D, LayoutCanvasRenderingContext2DHelpers};
|
||||||
|
use dom::document::Document;
|
||||||
|
use dom::element::{AttributeMutation, Element};
|
||||||
|
use dom::htmlelement::HTMLElement;
|
||||||
|
use dom::node::{Node, window_from_node};
|
||||||
|
use dom::virtualmethods::VirtualMethods;
|
||||||
|
use dom::webglrenderingcontext::{LayoutCanvasWebGLRenderingContextHelpers, WebGLRenderingContext};
|
||||||
|
use euclid::size::Size2D;
|
||||||
|
use image::ColorType;
|
||||||
|
use image::png::PNGEncoder;
|
||||||
|
use ipc_channel::ipc::{self, IpcSender};
|
||||||
|
use js::jsapi::{HandleValue, JSContext};
|
||||||
|
use offscreen_gl_context::GLContextAttributes;
|
||||||
|
use rustc_serialize::base64::{STANDARD, ToBase64};
|
||||||
|
use std::cell::Cell;
|
||||||
|
use std::iter::repeat;
|
||||||
|
use util::str::{DOMString, parse_unsigned_integer};
|
||||||
|
|
||||||
|
const DEFAULT_WIDTH: u32 = 300;
|
||||||
|
const DEFAULT_HEIGHT: u32 = 150;
|
||||||
|
|
||||||
|
#[must_root]
|
||||||
|
#[derive(JSTraceable, Clone, HeapSizeOf)]
|
||||||
|
pub enum CanvasContext {
|
||||||
|
Context2d(JS<CanvasRenderingContext2D>),
|
||||||
|
WebGL(JS<WebGLRenderingContext>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HeapGCValue for CanvasContext {}
|
||||||
|
|
||||||
|
#[dom_struct]
|
||||||
|
pub struct HTMLCanvasElement {
|
||||||
|
htmlelement: HTMLElement,
|
||||||
|
context: DOMRefCell<Option<CanvasContext>>,
|
||||||
|
width: Cell<u32>,
|
||||||
|
height: Cell<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for HTMLCanvasElement {
|
||||||
|
fn eq(&self, other: &HTMLCanvasElement) -> bool {
|
||||||
|
self as *const HTMLCanvasElement == &*other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HTMLCanvasElement {
|
||||||
|
fn new_inherited(localName: DOMString,
|
||||||
|
prefix: Option<DOMString>,
|
||||||
|
document: &Document) -> HTMLCanvasElement {
|
||||||
|
HTMLCanvasElement {
|
||||||
|
htmlelement: HTMLElement::new_inherited(localName, prefix, document),
|
||||||
|
context: DOMRefCell::new(None),
|
||||||
|
width: Cell::new(DEFAULT_WIDTH),
|
||||||
|
height: Cell::new(DEFAULT_HEIGHT),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unrooted_must_root)]
|
||||||
|
pub fn new(localName: DOMString,
|
||||||
|
prefix: Option<DOMString>,
|
||||||
|
document: &Document) -> Root<HTMLCanvasElement> {
|
||||||
|
let element = HTMLCanvasElement::new_inherited(localName, prefix, document);
|
||||||
|
Node::reflect_node(box element, document, HTMLCanvasElementBinding::Wrap)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recreate_contexts(&self) {
|
||||||
|
let size = self.get_size();
|
||||||
|
if let Some(ref context) = *self.context.borrow() {
|
||||||
|
match *context {
|
||||||
|
CanvasContext::Context2d(ref context) => context.recreate(size),
|
||||||
|
CanvasContext::WebGL(ref context) => context.recreate(size),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_size(&self) -> Size2D<i32> {
|
||||||
|
Size2D::new(self.width.get() as i32, self.height.get() as i32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct HTMLCanvasData {
|
||||||
|
pub renderer_id: Option<usize>,
|
||||||
|
pub ipc_renderer: Option<IpcSender<CanvasMsg>>,
|
||||||
|
pub width: u32,
|
||||||
|
pub height: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait LayoutHTMLCanvasElementHelpers {
|
||||||
|
fn data(&self) -> HTMLCanvasData;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> {
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
fn data(&self) -> HTMLCanvasData {
|
||||||
|
unsafe {
|
||||||
|
let canvas = &*self.unsafe_get();
|
||||||
|
let (renderer_id, ipc_renderer) = match canvas.context.borrow_for_layout().as_ref() {
|
||||||
|
Some(&CanvasContext::Context2d(ref context)) => {
|
||||||
|
let context = context.to_layout();
|
||||||
|
(Some(context.get_renderer_id()), Some(context.get_ipc_renderer()))
|
||||||
|
},
|
||||||
|
Some(&CanvasContext::WebGL(ref context)) => {
|
||||||
|
let context = context.to_layout();
|
||||||
|
(Some(context.get_renderer_id()), Some(context.get_ipc_renderer()))
|
||||||
|
},
|
||||||
|
None => (None, None),
|
||||||
|
};
|
||||||
|
|
||||||
|
HTMLCanvasData {
|
||||||
|
renderer_id: renderer_id,
|
||||||
|
ipc_renderer: ipc_renderer,
|
||||||
|
width: canvas.width.get(),
|
||||||
|
height: canvas.height.get(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl HTMLCanvasElement {
|
||||||
|
pub fn ipc_renderer(&self) -> Option<IpcSender<CanvasMsg>> {
|
||||||
|
self.context.borrow().as_ref().map(|context| {
|
||||||
|
match *context {
|
||||||
|
CanvasContext::Context2d(ref context) => context.ipc_renderer(),
|
||||||
|
CanvasContext::WebGL(ref context) => context.ipc_renderer(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_or_init_2d_context(&self) -> Option<Root<CanvasRenderingContext2D>> {
|
||||||
|
if self.context.borrow().is_none() {
|
||||||
|
let window = window_from_node(self);
|
||||||
|
let size = self.get_size();
|
||||||
|
let context = CanvasRenderingContext2D::new(GlobalRef::Window(window.r()), self, size);
|
||||||
|
*self.context.borrow_mut() = Some(CanvasContext::Context2d(JS::from_rooted(&context)));
|
||||||
|
}
|
||||||
|
|
||||||
|
match *self.context.borrow().as_ref().unwrap() {
|
||||||
|
CanvasContext::Context2d(ref context) => Some(context.root()),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_or_init_webgl_context(&self,
|
||||||
|
cx: *mut JSContext,
|
||||||
|
attrs: Option<HandleValue>) -> Option<Root<WebGLRenderingContext>> {
|
||||||
|
if self.context.borrow().is_none() {
|
||||||
|
let window = window_from_node(self);
|
||||||
|
let size = self.get_size();
|
||||||
|
|
||||||
|
let attrs = if let Some(webgl_attributes) = attrs {
|
||||||
|
if let Ok(ref attrs) = WebGLContextAttributes::new(cx, webgl_attributes) {
|
||||||
|
From::from(attrs)
|
||||||
|
} else {
|
||||||
|
debug!("Unexpected error on conversion of WebGLContextAttributes");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GLContextAttributes::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let maybe_ctx = WebGLRenderingContext::new(GlobalRef::Window(window.r()), self, size, attrs);
|
||||||
|
|
||||||
|
*self.context.borrow_mut() = maybe_ctx.map( |ctx| CanvasContext::WebGL(JS::from_rooted(&ctx)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(CanvasContext::WebGL(ref context)) = *self.context.borrow() {
|
||||||
|
Some(context.root())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_valid(&self) -> bool {
|
||||||
|
self.height.get() != 0 && self.width.get() != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fetch_all_data(&self) -> Option<(Vec<u8>, Size2D<i32>)> {
|
||||||
|
let size = self.get_size();
|
||||||
|
|
||||||
|
if size.width == 0 || size.height == 0 {
|
||||||
|
return None
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = if let Some(renderer) = self.ipc_renderer() {
|
||||||
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
|
let msg = CanvasMsg::FromLayout(FromLayoutMsg::SendPixelContents(sender));
|
||||||
|
renderer.send(msg).unwrap();
|
||||||
|
|
||||||
|
receiver.recv().unwrap().to_vec()
|
||||||
|
} else {
|
||||||
|
repeat(0xffu8).take((size.height as usize) * (size.width as usize) * 4).collect()
|
||||||
|
};
|
||||||
|
|
||||||
|
Some((data, size))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HTMLCanvasElementMethods for HTMLCanvasElement {
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-width
|
||||||
|
fn Width(&self) -> u32 {
|
||||||
|
self.width.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-width
|
||||||
|
fn SetWidth(&self, width: u32) {
|
||||||
|
self.upcast::<Element>().set_uint_attribute(&atom!("width"), width)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-height
|
||||||
|
fn Height(&self) -> u32 {
|
||||||
|
self.height.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-height
|
||||||
|
fn SetHeight(&self, height: u32) {
|
||||||
|
self.upcast::<Element>().set_uint_attribute(&atom!("height"), height)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-getcontext
|
||||||
|
fn GetContext(&self,
|
||||||
|
cx: *mut JSContext,
|
||||||
|
id: DOMString,
|
||||||
|
attributes: Vec<HandleValue>)
|
||||||
|
-> Option<CanvasRenderingContext2DOrWebGLRenderingContext> {
|
||||||
|
match &*id {
|
||||||
|
"2d" => {
|
||||||
|
self.get_or_init_2d_context()
|
||||||
|
.map(CanvasRenderingContext2DOrWebGLRenderingContext::eCanvasRenderingContext2D)
|
||||||
|
}
|
||||||
|
"webgl" | "experimental-webgl" => {
|
||||||
|
self.get_or_init_webgl_context(cx, attributes.get(0).map(|p| *p))
|
||||||
|
.map(CanvasRenderingContext2DOrWebGLRenderingContext::eWebGLRenderingContext)
|
||||||
|
}
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-todataurl
|
||||||
|
fn ToDataURL(&self,
|
||||||
|
_context: *mut JSContext,
|
||||||
|
_mime_type: Option<DOMString>,
|
||||||
|
_arguments: Vec<HandleValue>) -> Fallible<DOMString> {
|
||||||
|
|
||||||
|
// Step 1: Check the origin-clean flag (should be set in fillText/strokeText
|
||||||
|
// and currently unimplemented)
|
||||||
|
|
||||||
|
// Step 2.
|
||||||
|
if self.Width() == 0 || self.Height() == 0 {
|
||||||
|
return Ok("data:,".to_owned());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3.
|
||||||
|
if let Some(CanvasContext::Context2d(ref context)) = *self.context.borrow() {
|
||||||
|
let window = window_from_node(self);
|
||||||
|
let image_data = try!(context.GetImageData(Finite::wrap(0f64), Finite::wrap(0f64),
|
||||||
|
Finite::wrap(self.Width() as f64),
|
||||||
|
Finite::wrap(self.Height() as f64)));
|
||||||
|
let raw_data = image_data.get_data_array(&GlobalRef::Window(window.r()));
|
||||||
|
|
||||||
|
// Only handle image/png for now.
|
||||||
|
let mime_type = "image/png";
|
||||||
|
|
||||||
|
let mut encoded = Vec::new();
|
||||||
|
{
|
||||||
|
let encoder: PNGEncoder<&mut Vec<u8>> = PNGEncoder::new(&mut encoded);
|
||||||
|
encoder.encode(&raw_data, self.Width(), self.Height(), ColorType::RGBA(8)).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let encoded = encoded.to_base64(STANDARD);
|
||||||
|
Ok(format!("data:{};base64,{}", mime_type, encoded))
|
||||||
|
} else {
|
||||||
|
Err(Error::NotSupported)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VirtualMethods for HTMLCanvasElement {
|
||||||
|
fn super_type(&self) -> Option<&VirtualMethods> {
|
||||||
|
Some(self.upcast::<HTMLElement>() as &VirtualMethods)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) {
|
||||||
|
self.super_type().unwrap().attribute_mutated(attr, mutation);
|
||||||
|
let recreate = match attr.local_name() {
|
||||||
|
&atom!(width) => {
|
||||||
|
let width = mutation.new_value(attr).and_then(|value| {
|
||||||
|
parse_unsigned_integer(value.chars())
|
||||||
|
});
|
||||||
|
self.width.set(width.unwrap_or(DEFAULT_WIDTH));
|
||||||
|
true
|
||||||
|
},
|
||||||
|
&atom!(height) => {
|
||||||
|
let height = mutation.new_value(attr).and_then(|value| {
|
||||||
|
parse_unsigned_integer(value.chars())
|
||||||
|
});
|
||||||
|
self.height.set(height.unwrap_or(DEFAULT_HEIGHT));
|
||||||
|
true
|
||||||
|
},
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
if recreate {
|
||||||
|
self.recreate_contexts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a WebGLContextAttributes> for GLContextAttributes {
|
||||||
|
fn from(attrs: &'a WebGLContextAttributes) -> GLContextAttributes {
|
||||||
|
GLContextAttributes {
|
||||||
|
alpha: attrs.alpha,
|
||||||
|
depth: attrs.depth,
|
||||||
|
stencil: attrs.stencil,
|
||||||
|
antialias: attrs.antialias,
|
||||||
|
premultiplied_alpha: attrs.premultipliedAlpha,
|
||||||
|
preserve_drawing_buffer: attrs.preserveDrawingBuffer,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod utils {
|
||||||
|
use dom::window::Window;
|
||||||
|
use ipc_channel::ipc;
|
||||||
|
use net_traits::image_cache_task::{ImageCacheChan, ImageResponse};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
pub fn request_image_from_cache(window: &Window, url: Url) -> ImageResponse {
|
||||||
|
let image_cache = window.image_cache_task();
|
||||||
|
let (response_chan, response_port) = ipc::channel().unwrap();
|
||||||
|
image_cache.request_image(url, ImageCacheChan(response_chan), None);
|
||||||
|
let result = response_port.recv().unwrap();
|
||||||
|
result.image_response
|
||||||
|
}
|
||||||
|
}
|
351
components/script/dom/htmlcanvaselement.rs.LOCAL.20237.rs
Normal file
351
components/script/dom/htmlcanvaselement.rs.LOCAL.20237.rs
Normal file
|
@ -0,0 +1,351 @@
|
||||||
|
/* 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 canvas_traits::{CanvasMsg, FromLayoutMsg};
|
||||||
|
use dom::attr::Attr;
|
||||||
|
use dom::bindings::cell::DOMRefCell;
|
||||||
|
use dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::CanvasRenderingContext2DMethods;
|
||||||
|
use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding;
|
||||||
|
use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding::HTMLCanvasElementMethods;
|
||||||
|
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLContextAttributes;
|
||||||
|
use dom::bindings::codegen::UnionTypes::CanvasRenderingContext2DOrWebGLRenderingContext;
|
||||||
|
use dom::bindings::conversions::Castable;
|
||||||
|
use dom::bindings::error::{Error, Fallible};
|
||||||
|
use dom::bindings::global::GlobalRef;
|
||||||
|
use dom::bindings::js::{HeapGCValue, JS, LayoutJS, Root};
|
||||||
|
use dom::bindings::num::Finite;
|
||||||
|
use dom::bindings::utils::{Reflectable};
|
||||||
|
use dom::canvasrenderingcontext2d::{CanvasRenderingContext2D, LayoutCanvasRenderingContext2DHelpers};
|
||||||
|
use dom::document::Document;
|
||||||
|
use dom::element::{AttributeMutation, Element};
|
||||||
|
use dom::htmlelement::HTMLElement;
|
||||||
|
use dom::node::{Node, window_from_node};
|
||||||
|
use dom::virtualmethods::VirtualMethods;
|
||||||
|
use dom::webglrenderingcontext::{LayoutCanvasWebGLRenderingContextHelpers, WebGLRenderingContext};
|
||||||
|
use euclid::size::Size2D;
|
||||||
|
use image::ColorType;
|
||||||
|
use image::png::PNGEncoder;
|
||||||
|
use ipc_channel::ipc::{self, IpcSender};
|
||||||
|
use js::jsapi::{HandleValue, JSContext};
|
||||||
|
use offscreen_gl_context::GLContextAttributes;
|
||||||
|
use rustc_serialize::base64::{STANDARD, ToBase64};
|
||||||
|
use std::cell::Cell;
|
||||||
|
use std::iter::repeat;
|
||||||
|
use util::str::{DOMString, parse_unsigned_integer};
|
||||||
|
|
||||||
|
const DEFAULT_WIDTH: u32 = 300;
|
||||||
|
const DEFAULT_HEIGHT: u32 = 150;
|
||||||
|
|
||||||
|
#[must_root]
|
||||||
|
#[derive(JSTraceable, Clone, HeapSizeOf)]
|
||||||
|
pub enum CanvasContext {
|
||||||
|
Context2d(JS<CanvasRenderingContext2D>),
|
||||||
|
WebGL(JS<WebGLRenderingContext>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HeapGCValue for CanvasContext {}
|
||||||
|
|
||||||
|
#[dom_struct]
|
||||||
|
pub struct HTMLCanvasElement {
|
||||||
|
htmlelement: HTMLElement,
|
||||||
|
context: DOMRefCell<Option<CanvasContext>>,
|
||||||
|
width: Cell<u32>,
|
||||||
|
height: Cell<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for HTMLCanvasElement {
|
||||||
|
fn eq(&self, other: &HTMLCanvasElement) -> bool {
|
||||||
|
self as *const HTMLCanvasElement == &*other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HTMLCanvasElement {
|
||||||
|
fn new_inherited(localName: DOMString,
|
||||||
|
prefix: Option<DOMString>,
|
||||||
|
document: &Document) -> HTMLCanvasElement {
|
||||||
|
HTMLCanvasElement {
|
||||||
|
htmlelement: HTMLElement::new_inherited(localName, prefix, document),
|
||||||
|
context: DOMRefCell::new(None),
|
||||||
|
width: Cell::new(DEFAULT_WIDTH),
|
||||||
|
height: Cell::new(DEFAULT_HEIGHT),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unrooted_must_root)]
|
||||||
|
pub fn new(localName: DOMString,
|
||||||
|
prefix: Option<DOMString>,
|
||||||
|
document: &Document) -> Root<HTMLCanvasElement> {
|
||||||
|
let element = HTMLCanvasElement::new_inherited(localName, prefix, document);
|
||||||
|
Node::reflect_node(box element, document, HTMLCanvasElementBinding::Wrap)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recreate_contexts(&self) {
|
||||||
|
let size = self.get_size();
|
||||||
|
if let Some(ref context) = *self.context.borrow() {
|
||||||
|
match *context {
|
||||||
|
CanvasContext::Context2d(ref context) => context.recreate(size),
|
||||||
|
CanvasContext::WebGL(ref context) => context.recreate(size),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_size(&self) -> Size2D<i32> {
|
||||||
|
Size2D::new(self.width.get() as i32, self.height.get() as i32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct HTMLCanvasData {
|
||||||
|
pub renderer_id: Option<usize>,
|
||||||
|
pub ipc_renderer: Option<IpcSender<CanvasMsg>>,
|
||||||
|
pub width: u32,
|
||||||
|
pub height: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait LayoutHTMLCanvasElementHelpers {
|
||||||
|
fn data(&self) -> HTMLCanvasData;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> {
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
fn data(&self) -> HTMLCanvasData {
|
||||||
|
unsafe {
|
||||||
|
let canvas = &*self.unsafe_get();
|
||||||
|
let (renderer_id, ipc_renderer) = match canvas.context.borrow_for_layout().as_ref() {
|
||||||
|
Some(&CanvasContext::Context2d(ref context)) => {
|
||||||
|
let context = context.to_layout();
|
||||||
|
(Some(context.get_renderer_id()), Some(context.get_ipc_renderer()))
|
||||||
|
},
|
||||||
|
Some(&CanvasContext::WebGL(ref context)) => {
|
||||||
|
let context = context.to_layout();
|
||||||
|
(Some(context.get_renderer_id()), Some(context.get_ipc_renderer()))
|
||||||
|
},
|
||||||
|
None => (None, None),
|
||||||
|
};
|
||||||
|
|
||||||
|
HTMLCanvasData {
|
||||||
|
renderer_id: renderer_id,
|
||||||
|
ipc_renderer: ipc_renderer,
|
||||||
|
width: canvas.width.get(),
|
||||||
|
height: canvas.height.get(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl HTMLCanvasElement {
|
||||||
|
pub fn ipc_renderer(&self) -> Option<IpcSender<CanvasMsg>> {
|
||||||
|
self.context.borrow().as_ref().map(|context| {
|
||||||
|
match *context {
|
||||||
|
CanvasContext::Context2d(ref context) => context.ipc_renderer(),
|
||||||
|
CanvasContext::WebGL(ref context) => context.ipc_renderer(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_or_init_2d_context(&self) -> Option<Root<CanvasRenderingContext2D>> {
|
||||||
|
if self.context.borrow().is_none() {
|
||||||
|
let window = window_from_node(self);
|
||||||
|
let size = self.get_size();
|
||||||
|
let context = CanvasRenderingContext2D::new(GlobalRef::Window(window.r()), self, size);
|
||||||
|
*self.context.borrow_mut() = Some(CanvasContext::Context2d(JS::from_rooted(&context)));
|
||||||
|
}
|
||||||
|
|
||||||
|
match *self.context.borrow().as_ref().unwrap() {
|
||||||
|
CanvasContext::Context2d(ref context) => Some(context.root()),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_or_init_webgl_context(&self,
|
||||||
|
cx: *mut JSContext,
|
||||||
|
attrs: Option<HandleValue>) -> Option<Root<WebGLRenderingContext>> {
|
||||||
|
if self.context.borrow().is_none() {
|
||||||
|
let window = window_from_node(self);
|
||||||
|
let size = self.get_size();
|
||||||
|
|
||||||
|
let attrs = if let Some(webgl_attributes) = attrs {
|
||||||
|
if let Ok(ref attrs) = WebGLContextAttributes::new(cx, webgl_attributes) {
|
||||||
|
From::from(attrs)
|
||||||
|
} else {
|
||||||
|
debug!("Unexpected error on conversion of WebGLContextAttributes");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GLContextAttributes::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let maybe_ctx = WebGLRenderingContext::new(GlobalRef::Window(window.r()), self, size, attrs);
|
||||||
|
|
||||||
|
*self.context.borrow_mut() = maybe_ctx.map( |ctx| CanvasContext::WebGL(JS::from_rooted(&ctx)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(CanvasContext::WebGL(ref context)) = *self.context.borrow() {
|
||||||
|
Some(context.root())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_valid(&self) -> bool {
|
||||||
|
self.height.get() != 0 && self.width.get() != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fetch_all_data(&self) -> Option<(Vec<u8>, Size2D<i32>)> {
|
||||||
|
let size = self.get_size();
|
||||||
|
|
||||||
|
if size.width == 0 || size.height == 0 {
|
||||||
|
return None
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = if let Some(renderer) = self.ipc_renderer() {
|
||||||
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
|
let msg = CanvasMsg::FromLayout(FromLayoutMsg::SendPixelContents(sender));
|
||||||
|
renderer.send(msg).unwrap();
|
||||||
|
|
||||||
|
receiver.recv().unwrap().to_vec()
|
||||||
|
} else {
|
||||||
|
repeat(0xffu8).take((size.height as usize) * (size.width as usize) * 4).collect()
|
||||||
|
};
|
||||||
|
|
||||||
|
Some((data, size))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HTMLCanvasElementMethods for HTMLCanvasElement {
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-width
|
||||||
|
fn Width(&self) -> u32 {
|
||||||
|
self.width.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-width
|
||||||
|
fn SetWidth(&self, width: u32) {
|
||||||
|
self.upcast::<Element>().set_uint_attribute(&atom!("width"), width)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-height
|
||||||
|
fn Height(&self) -> u32 {
|
||||||
|
self.height.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-height
|
||||||
|
fn SetHeight(&self, height: u32) {
|
||||||
|
self.upcast::<Element>().set_uint_attribute(&atom!("height"), height)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-getcontext
|
||||||
|
fn GetContext(&self,
|
||||||
|
cx: *mut JSContext,
|
||||||
|
id: DOMString,
|
||||||
|
attributes: Vec<HandleValue>)
|
||||||
|
-> Option<CanvasRenderingContext2DOrWebGLRenderingContext> {
|
||||||
|
match &*id {
|
||||||
|
"2d" => {
|
||||||
|
self.get_or_init_2d_context()
|
||||||
|
.map(CanvasRenderingContext2DOrWebGLRenderingContext::eCanvasRenderingContext2D)
|
||||||
|
}
|
||||||
|
"webgl" | "experimental-webgl" => {
|
||||||
|
self.get_or_init_webgl_context(cx, attributes.get(0).map(|p| *p))
|
||||||
|
.map(CanvasRenderingContext2DOrWebGLRenderingContext::eWebGLRenderingContext)
|
||||||
|
}
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-todataurl
|
||||||
|
fn ToDataURL(&self,
|
||||||
|
_context: *mut JSContext,
|
||||||
|
_mime_type: Option<DOMString>,
|
||||||
|
_arguments: Vec<HandleValue>) -> Fallible<DOMString> {
|
||||||
|
|
||||||
|
// Step 1: Check the origin-clean flag (should be set in fillText/strokeText
|
||||||
|
// and currently unimplemented)
|
||||||
|
|
||||||
|
// Step 2.
|
||||||
|
if self.Width() == 0 || self.Height() == 0 {
|
||||||
|
return Ok("data:,".to_owned());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3.
|
||||||
|
if let Some(CanvasContext::Context2d(ref context)) = *self.context.borrow() {
|
||||||
|
let window = window_from_node(self);
|
||||||
|
let image_data = try!(context.GetImageData(Finite::wrap(0f64), Finite::wrap(0f64),
|
||||||
|
Finite::wrap(self.Width() as f64),
|
||||||
|
Finite::wrap(self.Height() as f64)));
|
||||||
|
let raw_data = image_data.get_data_array(&GlobalRef::Window(window.r()));
|
||||||
|
|
||||||
|
// Only handle image/png for now.
|
||||||
|
let mime_type = "image/png";
|
||||||
|
|
||||||
|
let mut encoded = Vec::new();
|
||||||
|
{
|
||||||
|
let encoder: PNGEncoder<&mut Vec<u8>> = PNGEncoder::new(&mut encoded);
|
||||||
|
encoder.encode(&raw_data, self.Width(), self.Height(), ColorType::RGBA(8)).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let encoded = encoded.to_base64(STANDARD);
|
||||||
|
Ok(format!("data:{};base64,{}", mime_type, encoded))
|
||||||
|
} else {
|
||||||
|
Err(Error::NotSupported)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VirtualMethods for HTMLCanvasElement {
|
||||||
|
fn super_type(&self) -> Option<&VirtualMethods> {
|
||||||
|
Some(self.upcast::<HTMLElement>() as &VirtualMethods)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) {
|
||||||
|
self.super_type().unwrap().attribute_mutated(attr, mutation);
|
||||||
|
let recreate = match attr.local_name() {
|
||||||
|
&atom!(width) => {
|
||||||
|
let width = mutation.new_value(attr).and_then(|value| {
|
||||||
|
parse_unsigned_integer(value.chars())
|
||||||
|
});
|
||||||
|
self.width.set(width.unwrap_or(DEFAULT_WIDTH));
|
||||||
|
true
|
||||||
|
},
|
||||||
|
&atom!(height) => {
|
||||||
|
let height = mutation.new_value(attr).and_then(|value| {
|
||||||
|
parse_unsigned_integer(value.chars())
|
||||||
|
});
|
||||||
|
self.height.set(height.unwrap_or(DEFAULT_HEIGHT));
|
||||||
|
true
|
||||||
|
},
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
if recreate {
|
||||||
|
self.recreate_contexts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a WebGLContextAttributes> for GLContextAttributes {
|
||||||
|
fn from(attrs: &'a WebGLContextAttributes) -> GLContextAttributes {
|
||||||
|
GLContextAttributes {
|
||||||
|
alpha: attrs.alpha,
|
||||||
|
depth: attrs.depth,
|
||||||
|
stencil: attrs.stencil,
|
||||||
|
antialias: attrs.antialias,
|
||||||
|
premultiplied_alpha: attrs.premultipliedAlpha,
|
||||||
|
preserve_drawing_buffer: attrs.preserveDrawingBuffer,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod utils {
|
||||||
|
use dom::window::Window;
|
||||||
|
use ipc_channel::ipc;
|
||||||
|
use net_traits::image_cache_task::{ImageCacheChan, ImageResponse};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
pub fn request_image_from_cache(window: &Window, url: Url) -> ImageResponse {
|
||||||
|
let image_cache = window.image_cache_task();
|
||||||
|
let (response_chan, response_port) = ipc::channel().unwrap();
|
||||||
|
image_cache.request_image(url, ImageCacheChan(response_chan), None);
|
||||||
|
let result = response_port.recv().unwrap();
|
||||||
|
result.image_response
|
||||||
|
}
|
||||||
|
}
|
307
components/script/dom/htmlcanvaselement.rs.REMOTE.20128.rs
Normal file
307
components/script/dom/htmlcanvaselement.rs.REMOTE.20128.rs
Normal file
|
@ -0,0 +1,307 @@
|
||||||
|
/* 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 canvas_traits::{CanvasMsg, FromLayoutMsg};
|
||||||
|
use dom::attr::Attr;
|
||||||
|
use dom::bindings::cell::DOMRefCell;
|
||||||
|
use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding;
|
||||||
|
use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding::HTMLCanvasElementMethods;
|
||||||
|
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLContextAttributes;
|
||||||
|
use dom::bindings::codegen::UnionTypes::CanvasRenderingContext2DOrWebGLRenderingContext;
|
||||||
|
use dom::bindings::inheritance::Castable;
|
||||||
|
use dom::bindings::global::GlobalRef;
|
||||||
|
use dom::bindings::js::{HeapGCValue, JS, LayoutJS, Root};
|
||||||
|
use dom::bindings::utils::{Reflectable};
|
||||||
|
use dom::canvasrenderingcontext2d::{CanvasRenderingContext2D, LayoutCanvasRenderingContext2DHelpers};
|
||||||
|
use dom::document::Document;
|
||||||
|
use dom::element::{AttributeMutation, Element};
|
||||||
|
use dom::htmlelement::HTMLElement;
|
||||||
|
use dom::node::{Node, window_from_node};
|
||||||
|
use dom::virtualmethods::VirtualMethods;
|
||||||
|
use dom::webglrenderingcontext::{LayoutCanvasWebGLRenderingContextHelpers, WebGLRenderingContext};
|
||||||
|
use euclid::size::Size2D;
|
||||||
|
use ipc_channel::ipc::{self, IpcSender};
|
||||||
|
use js::jsapi::{HandleValue, JSContext};
|
||||||
|
use offscreen_gl_context::GLContextAttributes;
|
||||||
|
use std::cell::Cell;
|
||||||
|
use std::iter::repeat;
|
||||||
|
use util::str::{DOMString, parse_unsigned_integer};
|
||||||
|
|
||||||
|
const DEFAULT_WIDTH: u32 = 300;
|
||||||
|
const DEFAULT_HEIGHT: u32 = 150;
|
||||||
|
|
||||||
|
#[must_root]
|
||||||
|
#[derive(JSTraceable, Clone, HeapSizeOf)]
|
||||||
|
pub enum CanvasContext {
|
||||||
|
Context2d(JS<CanvasRenderingContext2D>),
|
||||||
|
WebGL(JS<WebGLRenderingContext>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HeapGCValue for CanvasContext {}
|
||||||
|
|
||||||
|
#[dom_struct]
|
||||||
|
pub struct HTMLCanvasElement {
|
||||||
|
htmlelement: HTMLElement,
|
||||||
|
context: DOMRefCell<Option<CanvasContext>>,
|
||||||
|
width: Cell<u32>,
|
||||||
|
height: Cell<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for HTMLCanvasElement {
|
||||||
|
fn eq(&self, other: &HTMLCanvasElement) -> bool {
|
||||||
|
self as *const HTMLCanvasElement == &*other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HTMLCanvasElement {
|
||||||
|
fn new_inherited(localName: DOMString,
|
||||||
|
prefix: Option<DOMString>,
|
||||||
|
document: &Document) -> HTMLCanvasElement {
|
||||||
|
HTMLCanvasElement {
|
||||||
|
htmlelement: HTMLElement::new_inherited(localName, prefix, document),
|
||||||
|
context: DOMRefCell::new(None),
|
||||||
|
width: Cell::new(DEFAULT_WIDTH),
|
||||||
|
height: Cell::new(DEFAULT_HEIGHT),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unrooted_must_root)]
|
||||||
|
pub fn new(localName: DOMString,
|
||||||
|
prefix: Option<DOMString>,
|
||||||
|
document: &Document) -> Root<HTMLCanvasElement> {
|
||||||
|
let element = HTMLCanvasElement::new_inherited(localName, prefix, document);
|
||||||
|
Node::reflect_node(box element, document, HTMLCanvasElementBinding::Wrap)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recreate_contexts(&self) {
|
||||||
|
let size = self.get_size();
|
||||||
|
if let Some(ref context) = *self.context.borrow() {
|
||||||
|
match *context {
|
||||||
|
CanvasContext::Context2d(ref context) => context.recreate(size),
|
||||||
|
CanvasContext::WebGL(ref context) => context.recreate(size),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_size(&self) -> Size2D<i32> {
|
||||||
|
Size2D::new(self.width.get() as i32, self.height.get() as i32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct HTMLCanvasData {
|
||||||
|
pub renderer_id: Option<usize>,
|
||||||
|
pub ipc_renderer: Option<IpcSender<CanvasMsg>>,
|
||||||
|
pub width: u32,
|
||||||
|
pub height: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait LayoutHTMLCanvasElementHelpers {
|
||||||
|
fn data(&self) -> HTMLCanvasData;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> {
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
fn data(&self) -> HTMLCanvasData {
|
||||||
|
unsafe {
|
||||||
|
let canvas = &*self.unsafe_get();
|
||||||
|
let (renderer_id, ipc_renderer) = match canvas.context.borrow_for_layout().as_ref() {
|
||||||
|
Some(&CanvasContext::Context2d(ref context)) => {
|
||||||
|
let context = context.to_layout();
|
||||||
|
(Some(context.get_renderer_id()), Some(context.get_ipc_renderer()))
|
||||||
|
},
|
||||||
|
Some(&CanvasContext::WebGL(ref context)) => {
|
||||||
|
let context = context.to_layout();
|
||||||
|
(Some(context.get_renderer_id()), Some(context.get_ipc_renderer()))
|
||||||
|
},
|
||||||
|
None => (None, None),
|
||||||
|
};
|
||||||
|
|
||||||
|
HTMLCanvasData {
|
||||||
|
renderer_id: renderer_id,
|
||||||
|
ipc_renderer: ipc_renderer,
|
||||||
|
width: canvas.width.get(),
|
||||||
|
height: canvas.height.get(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl HTMLCanvasElement {
|
||||||
|
pub fn ipc_renderer(&self) -> Option<IpcSender<CanvasMsg>> {
|
||||||
|
self.context.borrow().as_ref().map(|context| {
|
||||||
|
match *context {
|
||||||
|
CanvasContext::Context2d(ref context) => context.ipc_renderer(),
|
||||||
|
CanvasContext::WebGL(ref context) => context.ipc_renderer(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_or_init_2d_context(&self) -> Option<Root<CanvasRenderingContext2D>> {
|
||||||
|
if self.context.borrow().is_none() {
|
||||||
|
let window = window_from_node(self);
|
||||||
|
let size = self.get_size();
|
||||||
|
let context = CanvasRenderingContext2D::new(GlobalRef::Window(window.r()), self, size);
|
||||||
|
*self.context.borrow_mut() = Some(CanvasContext::Context2d(JS::from_rooted(&context)));
|
||||||
|
}
|
||||||
|
|
||||||
|
match *self.context.borrow().as_ref().unwrap() {
|
||||||
|
CanvasContext::Context2d(ref context) => Some(context.root()),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_or_init_webgl_context(&self,
|
||||||
|
cx: *mut JSContext,
|
||||||
|
attrs: Option<HandleValue>) -> Option<Root<WebGLRenderingContext>> {
|
||||||
|
if self.context.borrow().is_none() {
|
||||||
|
let window = window_from_node(self);
|
||||||
|
let size = self.get_size();
|
||||||
|
|
||||||
|
let attrs = if let Some(webgl_attributes) = attrs {
|
||||||
|
if let Ok(ref attrs) = WebGLContextAttributes::new(cx, webgl_attributes) {
|
||||||
|
From::from(attrs)
|
||||||
|
} else {
|
||||||
|
debug!("Unexpected error on conversion of WebGLContextAttributes");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GLContextAttributes::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let maybe_ctx = WebGLRenderingContext::new(GlobalRef::Window(window.r()), self, size, attrs);
|
||||||
|
|
||||||
|
*self.context.borrow_mut() = maybe_ctx.map( |ctx| CanvasContext::WebGL(JS::from_rooted(&ctx)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(CanvasContext::WebGL(ref context)) = *self.context.borrow() {
|
||||||
|
Some(context.root())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_valid(&self) -> bool {
|
||||||
|
self.height.get() != 0 && self.width.get() != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fetch_all_data(&self) -> Option<(Vec<u8>, Size2D<i32>)> {
|
||||||
|
let size = self.get_size();
|
||||||
|
|
||||||
|
if size.width == 0 || size.height == 0 {
|
||||||
|
return None
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = if let Some(renderer) = self.ipc_renderer() {
|
||||||
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
|
let msg = CanvasMsg::FromLayout(FromLayoutMsg::SendPixelContents(sender));
|
||||||
|
renderer.send(msg).unwrap();
|
||||||
|
|
||||||
|
receiver.recv().unwrap().to_vec()
|
||||||
|
} else {
|
||||||
|
repeat(0xffu8).take((size.height as usize) * (size.width as usize) * 4).collect()
|
||||||
|
};
|
||||||
|
|
||||||
|
Some((data, size))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HTMLCanvasElementMethods for HTMLCanvasElement {
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-width
|
||||||
|
fn Width(&self) -> u32 {
|
||||||
|
self.width.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-width
|
||||||
|
fn SetWidth(&self, width: u32) {
|
||||||
|
self.upcast::<Element>().set_uint_attribute(&atom!("width"), width)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-height
|
||||||
|
fn Height(&self) -> u32 {
|
||||||
|
self.height.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-height
|
||||||
|
fn SetHeight(&self, height: u32) {
|
||||||
|
self.upcast::<Element>().set_uint_attribute(&atom!("height"), height)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-getcontext
|
||||||
|
fn GetContext(&self,
|
||||||
|
cx: *mut JSContext,
|
||||||
|
id: DOMString,
|
||||||
|
attributes: Vec<HandleValue>)
|
||||||
|
-> Option<CanvasRenderingContext2DOrWebGLRenderingContext> {
|
||||||
|
match &*id {
|
||||||
|
"2d" => {
|
||||||
|
self.get_or_init_2d_context()
|
||||||
|
.map(CanvasRenderingContext2DOrWebGLRenderingContext::eCanvasRenderingContext2D)
|
||||||
|
}
|
||||||
|
"webgl" | "experimental-webgl" => {
|
||||||
|
self.get_or_init_webgl_context(cx, attributes.get(0).map(|p| *p))
|
||||||
|
.map(CanvasRenderingContext2DOrWebGLRenderingContext::eWebGLRenderingContext)
|
||||||
|
}
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VirtualMethods for HTMLCanvasElement {
|
||||||
|
fn super_type(&self) -> Option<&VirtualMethods> {
|
||||||
|
Some(self.upcast::<HTMLElement>() as &VirtualMethods)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) {
|
||||||
|
self.super_type().unwrap().attribute_mutated(attr, mutation);
|
||||||
|
let recreate = match attr.local_name() {
|
||||||
|
&atom!(width) => {
|
||||||
|
let width = mutation.new_value(attr).and_then(|value| {
|
||||||
|
parse_unsigned_integer(value.chars())
|
||||||
|
});
|
||||||
|
self.width.set(width.unwrap_or(DEFAULT_WIDTH));
|
||||||
|
true
|
||||||
|
},
|
||||||
|
&atom!(height) => {
|
||||||
|
let height = mutation.new_value(attr).and_then(|value| {
|
||||||
|
parse_unsigned_integer(value.chars())
|
||||||
|
});
|
||||||
|
self.height.set(height.unwrap_or(DEFAULT_HEIGHT));
|
||||||
|
true
|
||||||
|
},
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
if recreate {
|
||||||
|
self.recreate_contexts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a WebGLContextAttributes> for GLContextAttributes {
|
||||||
|
fn from(attrs: &'a WebGLContextAttributes) -> GLContextAttributes {
|
||||||
|
GLContextAttributes {
|
||||||
|
alpha: attrs.alpha,
|
||||||
|
depth: attrs.depth,
|
||||||
|
stencil: attrs.stencil,
|
||||||
|
antialias: attrs.antialias,
|
||||||
|
premultiplied_alpha: attrs.premultipliedAlpha,
|
||||||
|
preserve_drawing_buffer: attrs.preserveDrawingBuffer,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod utils {
|
||||||
|
use dom::window::Window;
|
||||||
|
use ipc_channel::ipc;
|
||||||
|
use net_traits::image_cache_task::{ImageCacheChan, ImageResponse};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
pub fn request_image_from_cache(window: &Window, url: Url) -> ImageResponse {
|
||||||
|
let image_cache = window.image_cache_task();
|
||||||
|
let (response_chan, response_port) = ipc::channel().unwrap();
|
||||||
|
image_cache.request_image(url, ImageCacheChan(response_chan), None);
|
||||||
|
let result = response_port.recv().unwrap();
|
||||||
|
result.image_response
|
||||||
|
}
|
||||||
|
}
|
307
components/script/dom/htmlcanvaselement.rs.REMOTE.20237.rs
Normal file
307
components/script/dom/htmlcanvaselement.rs.REMOTE.20237.rs
Normal file
|
@ -0,0 +1,307 @@
|
||||||
|
/* 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 canvas_traits::{CanvasMsg, FromLayoutMsg};
|
||||||
|
use dom::attr::Attr;
|
||||||
|
use dom::bindings::cell::DOMRefCell;
|
||||||
|
use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding;
|
||||||
|
use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding::HTMLCanvasElementMethods;
|
||||||
|
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLContextAttributes;
|
||||||
|
use dom::bindings::codegen::UnionTypes::CanvasRenderingContext2DOrWebGLRenderingContext;
|
||||||
|
use dom::bindings::inheritance::Castable;
|
||||||
|
use dom::bindings::global::GlobalRef;
|
||||||
|
use dom::bindings::js::{HeapGCValue, JS, LayoutJS, Root};
|
||||||
|
use dom::bindings::utils::{Reflectable};
|
||||||
|
use dom::canvasrenderingcontext2d::{CanvasRenderingContext2D, LayoutCanvasRenderingContext2DHelpers};
|
||||||
|
use dom::document::Document;
|
||||||
|
use dom::element::{AttributeMutation, Element};
|
||||||
|
use dom::htmlelement::HTMLElement;
|
||||||
|
use dom::node::{Node, window_from_node};
|
||||||
|
use dom::virtualmethods::VirtualMethods;
|
||||||
|
use dom::webglrenderingcontext::{LayoutCanvasWebGLRenderingContextHelpers, WebGLRenderingContext};
|
||||||
|
use euclid::size::Size2D;
|
||||||
|
use ipc_channel::ipc::{self, IpcSender};
|
||||||
|
use js::jsapi::{HandleValue, JSContext};
|
||||||
|
use offscreen_gl_context::GLContextAttributes;
|
||||||
|
use std::cell::Cell;
|
||||||
|
use std::iter::repeat;
|
||||||
|
use util::str::{DOMString, parse_unsigned_integer};
|
||||||
|
|
||||||
|
const DEFAULT_WIDTH: u32 = 300;
|
||||||
|
const DEFAULT_HEIGHT: u32 = 150;
|
||||||
|
|
||||||
|
#[must_root]
|
||||||
|
#[derive(JSTraceable, Clone, HeapSizeOf)]
|
||||||
|
pub enum CanvasContext {
|
||||||
|
Context2d(JS<CanvasRenderingContext2D>),
|
||||||
|
WebGL(JS<WebGLRenderingContext>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HeapGCValue for CanvasContext {}
|
||||||
|
|
||||||
|
#[dom_struct]
|
||||||
|
pub struct HTMLCanvasElement {
|
||||||
|
htmlelement: HTMLElement,
|
||||||
|
context: DOMRefCell<Option<CanvasContext>>,
|
||||||
|
width: Cell<u32>,
|
||||||
|
height: Cell<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for HTMLCanvasElement {
|
||||||
|
fn eq(&self, other: &HTMLCanvasElement) -> bool {
|
||||||
|
self as *const HTMLCanvasElement == &*other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HTMLCanvasElement {
|
||||||
|
fn new_inherited(localName: DOMString,
|
||||||
|
prefix: Option<DOMString>,
|
||||||
|
document: &Document) -> HTMLCanvasElement {
|
||||||
|
HTMLCanvasElement {
|
||||||
|
htmlelement: HTMLElement::new_inherited(localName, prefix, document),
|
||||||
|
context: DOMRefCell::new(None),
|
||||||
|
width: Cell::new(DEFAULT_WIDTH),
|
||||||
|
height: Cell::new(DEFAULT_HEIGHT),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unrooted_must_root)]
|
||||||
|
pub fn new(localName: DOMString,
|
||||||
|
prefix: Option<DOMString>,
|
||||||
|
document: &Document) -> Root<HTMLCanvasElement> {
|
||||||
|
let element = HTMLCanvasElement::new_inherited(localName, prefix, document);
|
||||||
|
Node::reflect_node(box element, document, HTMLCanvasElementBinding::Wrap)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recreate_contexts(&self) {
|
||||||
|
let size = self.get_size();
|
||||||
|
if let Some(ref context) = *self.context.borrow() {
|
||||||
|
match *context {
|
||||||
|
CanvasContext::Context2d(ref context) => context.recreate(size),
|
||||||
|
CanvasContext::WebGL(ref context) => context.recreate(size),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_size(&self) -> Size2D<i32> {
|
||||||
|
Size2D::new(self.width.get() as i32, self.height.get() as i32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct HTMLCanvasData {
|
||||||
|
pub renderer_id: Option<usize>,
|
||||||
|
pub ipc_renderer: Option<IpcSender<CanvasMsg>>,
|
||||||
|
pub width: u32,
|
||||||
|
pub height: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait LayoutHTMLCanvasElementHelpers {
|
||||||
|
fn data(&self) -> HTMLCanvasData;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> {
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
fn data(&self) -> HTMLCanvasData {
|
||||||
|
unsafe {
|
||||||
|
let canvas = &*self.unsafe_get();
|
||||||
|
let (renderer_id, ipc_renderer) = match canvas.context.borrow_for_layout().as_ref() {
|
||||||
|
Some(&CanvasContext::Context2d(ref context)) => {
|
||||||
|
let context = context.to_layout();
|
||||||
|
(Some(context.get_renderer_id()), Some(context.get_ipc_renderer()))
|
||||||
|
},
|
||||||
|
Some(&CanvasContext::WebGL(ref context)) => {
|
||||||
|
let context = context.to_layout();
|
||||||
|
(Some(context.get_renderer_id()), Some(context.get_ipc_renderer()))
|
||||||
|
},
|
||||||
|
None => (None, None),
|
||||||
|
};
|
||||||
|
|
||||||
|
HTMLCanvasData {
|
||||||
|
renderer_id: renderer_id,
|
||||||
|
ipc_renderer: ipc_renderer,
|
||||||
|
width: canvas.width.get(),
|
||||||
|
height: canvas.height.get(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl HTMLCanvasElement {
|
||||||
|
pub fn ipc_renderer(&self) -> Option<IpcSender<CanvasMsg>> {
|
||||||
|
self.context.borrow().as_ref().map(|context| {
|
||||||
|
match *context {
|
||||||
|
CanvasContext::Context2d(ref context) => context.ipc_renderer(),
|
||||||
|
CanvasContext::WebGL(ref context) => context.ipc_renderer(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_or_init_2d_context(&self) -> Option<Root<CanvasRenderingContext2D>> {
|
||||||
|
if self.context.borrow().is_none() {
|
||||||
|
let window = window_from_node(self);
|
||||||
|
let size = self.get_size();
|
||||||
|
let context = CanvasRenderingContext2D::new(GlobalRef::Window(window.r()), self, size);
|
||||||
|
*self.context.borrow_mut() = Some(CanvasContext::Context2d(JS::from_rooted(&context)));
|
||||||
|
}
|
||||||
|
|
||||||
|
match *self.context.borrow().as_ref().unwrap() {
|
||||||
|
CanvasContext::Context2d(ref context) => Some(context.root()),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_or_init_webgl_context(&self,
|
||||||
|
cx: *mut JSContext,
|
||||||
|
attrs: Option<HandleValue>) -> Option<Root<WebGLRenderingContext>> {
|
||||||
|
if self.context.borrow().is_none() {
|
||||||
|
let window = window_from_node(self);
|
||||||
|
let size = self.get_size();
|
||||||
|
|
||||||
|
let attrs = if let Some(webgl_attributes) = attrs {
|
||||||
|
if let Ok(ref attrs) = WebGLContextAttributes::new(cx, webgl_attributes) {
|
||||||
|
From::from(attrs)
|
||||||
|
} else {
|
||||||
|
debug!("Unexpected error on conversion of WebGLContextAttributes");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GLContextAttributes::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let maybe_ctx = WebGLRenderingContext::new(GlobalRef::Window(window.r()), self, size, attrs);
|
||||||
|
|
||||||
|
*self.context.borrow_mut() = maybe_ctx.map( |ctx| CanvasContext::WebGL(JS::from_rooted(&ctx)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(CanvasContext::WebGL(ref context)) = *self.context.borrow() {
|
||||||
|
Some(context.root())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_valid(&self) -> bool {
|
||||||
|
self.height.get() != 0 && self.width.get() != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fetch_all_data(&self) -> Option<(Vec<u8>, Size2D<i32>)> {
|
||||||
|
let size = self.get_size();
|
||||||
|
|
||||||
|
if size.width == 0 || size.height == 0 {
|
||||||
|
return None
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = if let Some(renderer) = self.ipc_renderer() {
|
||||||
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
|
let msg = CanvasMsg::FromLayout(FromLayoutMsg::SendPixelContents(sender));
|
||||||
|
renderer.send(msg).unwrap();
|
||||||
|
|
||||||
|
receiver.recv().unwrap().to_vec()
|
||||||
|
} else {
|
||||||
|
repeat(0xffu8).take((size.height as usize) * (size.width as usize) * 4).collect()
|
||||||
|
};
|
||||||
|
|
||||||
|
Some((data, size))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HTMLCanvasElementMethods for HTMLCanvasElement {
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-width
|
||||||
|
fn Width(&self) -> u32 {
|
||||||
|
self.width.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-width
|
||||||
|
fn SetWidth(&self, width: u32) {
|
||||||
|
self.upcast::<Element>().set_uint_attribute(&atom!("width"), width)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-height
|
||||||
|
fn Height(&self) -> u32 {
|
||||||
|
self.height.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-height
|
||||||
|
fn SetHeight(&self, height: u32) {
|
||||||
|
self.upcast::<Element>().set_uint_attribute(&atom!("height"), height)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-getcontext
|
||||||
|
fn GetContext(&self,
|
||||||
|
cx: *mut JSContext,
|
||||||
|
id: DOMString,
|
||||||
|
attributes: Vec<HandleValue>)
|
||||||
|
-> Option<CanvasRenderingContext2DOrWebGLRenderingContext> {
|
||||||
|
match &*id {
|
||||||
|
"2d" => {
|
||||||
|
self.get_or_init_2d_context()
|
||||||
|
.map(CanvasRenderingContext2DOrWebGLRenderingContext::eCanvasRenderingContext2D)
|
||||||
|
}
|
||||||
|
"webgl" | "experimental-webgl" => {
|
||||||
|
self.get_or_init_webgl_context(cx, attributes.get(0).map(|p| *p))
|
||||||
|
.map(CanvasRenderingContext2DOrWebGLRenderingContext::eWebGLRenderingContext)
|
||||||
|
}
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VirtualMethods for HTMLCanvasElement {
|
||||||
|
fn super_type(&self) -> Option<&VirtualMethods> {
|
||||||
|
Some(self.upcast::<HTMLElement>() as &VirtualMethods)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) {
|
||||||
|
self.super_type().unwrap().attribute_mutated(attr, mutation);
|
||||||
|
let recreate = match attr.local_name() {
|
||||||
|
&atom!(width) => {
|
||||||
|
let width = mutation.new_value(attr).and_then(|value| {
|
||||||
|
parse_unsigned_integer(value.chars())
|
||||||
|
});
|
||||||
|
self.width.set(width.unwrap_or(DEFAULT_WIDTH));
|
||||||
|
true
|
||||||
|
},
|
||||||
|
&atom!(height) => {
|
||||||
|
let height = mutation.new_value(attr).and_then(|value| {
|
||||||
|
parse_unsigned_integer(value.chars())
|
||||||
|
});
|
||||||
|
self.height.set(height.unwrap_or(DEFAULT_HEIGHT));
|
||||||
|
true
|
||||||
|
},
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
if recreate {
|
||||||
|
self.recreate_contexts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a WebGLContextAttributes> for GLContextAttributes {
|
||||||
|
fn from(attrs: &'a WebGLContextAttributes) -> GLContextAttributes {
|
||||||
|
GLContextAttributes {
|
||||||
|
alpha: attrs.alpha,
|
||||||
|
depth: attrs.depth,
|
||||||
|
stencil: attrs.stencil,
|
||||||
|
antialias: attrs.antialias,
|
||||||
|
premultiplied_alpha: attrs.premultipliedAlpha,
|
||||||
|
preserve_drawing_buffer: attrs.preserveDrawingBuffer,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod utils {
|
||||||
|
use dom::window::Window;
|
||||||
|
use ipc_channel::ipc;
|
||||||
|
use net_traits::image_cache_task::{ImageCacheChan, ImageResponse};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
pub fn request_image_from_cache(window: &Window, url: Url) -> ImageResponse {
|
||||||
|
let image_cache = window.image_cache_task();
|
||||||
|
let (response_chan, response_port) = ipc::channel().unwrap();
|
||||||
|
image_cache.request_image(url, ImageCacheChan(response_chan), None);
|
||||||
|
let result = response_port.recv().unwrap();
|
||||||
|
result.image_response
|
||||||
|
}
|
||||||
|
}
|
355
components/script/dom/htmlcanvaselement.rs.orig
Normal file
355
components/script/dom/htmlcanvaselement.rs.orig
Normal file
|
@ -0,0 +1,355 @@
|
||||||
|
/* 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 canvas_traits::{CanvasMsg, FromLayoutMsg};
|
||||||
|
use dom::attr::Attr;
|
||||||
|
use dom::bindings::cell::DOMRefCell;
|
||||||
|
use dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::CanvasRenderingContext2DMethods;
|
||||||
|
use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding;
|
||||||
|
use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding::HTMLCanvasElementMethods;
|
||||||
|
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLContextAttributes;
|
||||||
|
use dom::bindings::codegen::UnionTypes::CanvasRenderingContext2DOrWebGLRenderingContext;
|
||||||
|
<<<<<<< HEAD
|
||||||
|
use dom::bindings::conversions::Castable;
|
||||||
|
use dom::bindings::error::{Error, Fallible};
|
||||||
|
=======
|
||||||
|
use dom::bindings::inheritance::Castable;
|
||||||
|
>>>>>>> move Castable into dom::bindings::inheritance
|
||||||
|
use dom::bindings::global::GlobalRef;
|
||||||
|
use dom::bindings::js::{HeapGCValue, JS, LayoutJS, Root};
|
||||||
|
use dom::bindings::num::Finite;
|
||||||
|
use dom::bindings::utils::{Reflectable};
|
||||||
|
use dom::canvasrenderingcontext2d::{CanvasRenderingContext2D, LayoutCanvasRenderingContext2DHelpers};
|
||||||
|
use dom::document::Document;
|
||||||
|
use dom::element::{AttributeMutation, Element};
|
||||||
|
use dom::htmlelement::HTMLElement;
|
||||||
|
use dom::node::{Node, window_from_node};
|
||||||
|
use dom::virtualmethods::VirtualMethods;
|
||||||
|
use dom::webglrenderingcontext::{LayoutCanvasWebGLRenderingContextHelpers, WebGLRenderingContext};
|
||||||
|
use euclid::size::Size2D;
|
||||||
|
use image::ColorType;
|
||||||
|
use image::png::PNGEncoder;
|
||||||
|
use ipc_channel::ipc::{self, IpcSender};
|
||||||
|
use js::jsapi::{HandleValue, JSContext};
|
||||||
|
use offscreen_gl_context::GLContextAttributes;
|
||||||
|
use rustc_serialize::base64::{STANDARD, ToBase64};
|
||||||
|
use std::cell::Cell;
|
||||||
|
use std::iter::repeat;
|
||||||
|
use util::str::{DOMString, parse_unsigned_integer};
|
||||||
|
|
||||||
|
const DEFAULT_WIDTH: u32 = 300;
|
||||||
|
const DEFAULT_HEIGHT: u32 = 150;
|
||||||
|
|
||||||
|
#[must_root]
|
||||||
|
#[derive(JSTraceable, Clone, HeapSizeOf)]
|
||||||
|
pub enum CanvasContext {
|
||||||
|
Context2d(JS<CanvasRenderingContext2D>),
|
||||||
|
WebGL(JS<WebGLRenderingContext>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HeapGCValue for CanvasContext {}
|
||||||
|
|
||||||
|
#[dom_struct]
|
||||||
|
pub struct HTMLCanvasElement {
|
||||||
|
htmlelement: HTMLElement,
|
||||||
|
context: DOMRefCell<Option<CanvasContext>>,
|
||||||
|
width: Cell<u32>,
|
||||||
|
height: Cell<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for HTMLCanvasElement {
|
||||||
|
fn eq(&self, other: &HTMLCanvasElement) -> bool {
|
||||||
|
self as *const HTMLCanvasElement == &*other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HTMLCanvasElement {
|
||||||
|
fn new_inherited(localName: DOMString,
|
||||||
|
prefix: Option<DOMString>,
|
||||||
|
document: &Document) -> HTMLCanvasElement {
|
||||||
|
HTMLCanvasElement {
|
||||||
|
htmlelement: HTMLElement::new_inherited(localName, prefix, document),
|
||||||
|
context: DOMRefCell::new(None),
|
||||||
|
width: Cell::new(DEFAULT_WIDTH),
|
||||||
|
height: Cell::new(DEFAULT_HEIGHT),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unrooted_must_root)]
|
||||||
|
pub fn new(localName: DOMString,
|
||||||
|
prefix: Option<DOMString>,
|
||||||
|
document: &Document) -> Root<HTMLCanvasElement> {
|
||||||
|
let element = HTMLCanvasElement::new_inherited(localName, prefix, document);
|
||||||
|
Node::reflect_node(box element, document, HTMLCanvasElementBinding::Wrap)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recreate_contexts(&self) {
|
||||||
|
let size = self.get_size();
|
||||||
|
if let Some(ref context) = *self.context.borrow() {
|
||||||
|
match *context {
|
||||||
|
CanvasContext::Context2d(ref context) => context.recreate(size),
|
||||||
|
CanvasContext::WebGL(ref context) => context.recreate(size),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_size(&self) -> Size2D<i32> {
|
||||||
|
Size2D::new(self.width.get() as i32, self.height.get() as i32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct HTMLCanvasData {
|
||||||
|
pub renderer_id: Option<usize>,
|
||||||
|
pub ipc_renderer: Option<IpcSender<CanvasMsg>>,
|
||||||
|
pub width: u32,
|
||||||
|
pub height: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait LayoutHTMLCanvasElementHelpers {
|
||||||
|
fn data(&self) -> HTMLCanvasData;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> {
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
fn data(&self) -> HTMLCanvasData {
|
||||||
|
unsafe {
|
||||||
|
let canvas = &*self.unsafe_get();
|
||||||
|
let (renderer_id, ipc_renderer) = match canvas.context.borrow_for_layout().as_ref() {
|
||||||
|
Some(&CanvasContext::Context2d(ref context)) => {
|
||||||
|
let context = context.to_layout();
|
||||||
|
(Some(context.get_renderer_id()), Some(context.get_ipc_renderer()))
|
||||||
|
},
|
||||||
|
Some(&CanvasContext::WebGL(ref context)) => {
|
||||||
|
let context = context.to_layout();
|
||||||
|
(Some(context.get_renderer_id()), Some(context.get_ipc_renderer()))
|
||||||
|
},
|
||||||
|
None => (None, None),
|
||||||
|
};
|
||||||
|
|
||||||
|
HTMLCanvasData {
|
||||||
|
renderer_id: renderer_id,
|
||||||
|
ipc_renderer: ipc_renderer,
|
||||||
|
width: canvas.width.get(),
|
||||||
|
height: canvas.height.get(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl HTMLCanvasElement {
|
||||||
|
pub fn ipc_renderer(&self) -> Option<IpcSender<CanvasMsg>> {
|
||||||
|
self.context.borrow().as_ref().map(|context| {
|
||||||
|
match *context {
|
||||||
|
CanvasContext::Context2d(ref context) => context.ipc_renderer(),
|
||||||
|
CanvasContext::WebGL(ref context) => context.ipc_renderer(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_or_init_2d_context(&self) -> Option<Root<CanvasRenderingContext2D>> {
|
||||||
|
if self.context.borrow().is_none() {
|
||||||
|
let window = window_from_node(self);
|
||||||
|
let size = self.get_size();
|
||||||
|
let context = CanvasRenderingContext2D::new(GlobalRef::Window(window.r()), self, size);
|
||||||
|
*self.context.borrow_mut() = Some(CanvasContext::Context2d(JS::from_rooted(&context)));
|
||||||
|
}
|
||||||
|
|
||||||
|
match *self.context.borrow().as_ref().unwrap() {
|
||||||
|
CanvasContext::Context2d(ref context) => Some(context.root()),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_or_init_webgl_context(&self,
|
||||||
|
cx: *mut JSContext,
|
||||||
|
attrs: Option<HandleValue>) -> Option<Root<WebGLRenderingContext>> {
|
||||||
|
if self.context.borrow().is_none() {
|
||||||
|
let window = window_from_node(self);
|
||||||
|
let size = self.get_size();
|
||||||
|
|
||||||
|
let attrs = if let Some(webgl_attributes) = attrs {
|
||||||
|
if let Ok(ref attrs) = WebGLContextAttributes::new(cx, webgl_attributes) {
|
||||||
|
From::from(attrs)
|
||||||
|
} else {
|
||||||
|
debug!("Unexpected error on conversion of WebGLContextAttributes");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GLContextAttributes::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let maybe_ctx = WebGLRenderingContext::new(GlobalRef::Window(window.r()), self, size, attrs);
|
||||||
|
|
||||||
|
*self.context.borrow_mut() = maybe_ctx.map( |ctx| CanvasContext::WebGL(JS::from_rooted(&ctx)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(CanvasContext::WebGL(ref context)) = *self.context.borrow() {
|
||||||
|
Some(context.root())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_valid(&self) -> bool {
|
||||||
|
self.height.get() != 0 && self.width.get() != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fetch_all_data(&self) -> Option<(Vec<u8>, Size2D<i32>)> {
|
||||||
|
let size = self.get_size();
|
||||||
|
|
||||||
|
if size.width == 0 || size.height == 0 {
|
||||||
|
return None
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = if let Some(renderer) = self.ipc_renderer() {
|
||||||
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
|
let msg = CanvasMsg::FromLayout(FromLayoutMsg::SendPixelContents(sender));
|
||||||
|
renderer.send(msg).unwrap();
|
||||||
|
|
||||||
|
receiver.recv().unwrap().to_vec()
|
||||||
|
} else {
|
||||||
|
repeat(0xffu8).take((size.height as usize) * (size.width as usize) * 4).collect()
|
||||||
|
};
|
||||||
|
|
||||||
|
Some((data, size))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HTMLCanvasElementMethods for HTMLCanvasElement {
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-width
|
||||||
|
fn Width(&self) -> u32 {
|
||||||
|
self.width.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-width
|
||||||
|
fn SetWidth(&self, width: u32) {
|
||||||
|
self.upcast::<Element>().set_uint_attribute(&atom!("width"), width)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-height
|
||||||
|
fn Height(&self) -> u32 {
|
||||||
|
self.height.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-height
|
||||||
|
fn SetHeight(&self, height: u32) {
|
||||||
|
self.upcast::<Element>().set_uint_attribute(&atom!("height"), height)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-getcontext
|
||||||
|
fn GetContext(&self,
|
||||||
|
cx: *mut JSContext,
|
||||||
|
id: DOMString,
|
||||||
|
attributes: Vec<HandleValue>)
|
||||||
|
-> Option<CanvasRenderingContext2DOrWebGLRenderingContext> {
|
||||||
|
match &*id {
|
||||||
|
"2d" => {
|
||||||
|
self.get_or_init_2d_context()
|
||||||
|
.map(CanvasRenderingContext2DOrWebGLRenderingContext::eCanvasRenderingContext2D)
|
||||||
|
}
|
||||||
|
"webgl" | "experimental-webgl" => {
|
||||||
|
self.get_or_init_webgl_context(cx, attributes.get(0).map(|p| *p))
|
||||||
|
.map(CanvasRenderingContext2DOrWebGLRenderingContext::eWebGLRenderingContext)
|
||||||
|
}
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-canvas-todataurl
|
||||||
|
fn ToDataURL(&self,
|
||||||
|
_context: *mut JSContext,
|
||||||
|
_mime_type: Option<DOMString>,
|
||||||
|
_arguments: Vec<HandleValue>) -> Fallible<DOMString> {
|
||||||
|
|
||||||
|
// Step 1: Check the origin-clean flag (should be set in fillText/strokeText
|
||||||
|
// and currently unimplemented)
|
||||||
|
|
||||||
|
// Step 2.
|
||||||
|
if self.Width() == 0 || self.Height() == 0 {
|
||||||
|
return Ok("data:,".to_owned());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3.
|
||||||
|
if let Some(CanvasContext::Context2d(ref context)) = *self.context.borrow() {
|
||||||
|
let window = window_from_node(self);
|
||||||
|
let image_data = try!(context.GetImageData(Finite::wrap(0f64), Finite::wrap(0f64),
|
||||||
|
Finite::wrap(self.Width() as f64),
|
||||||
|
Finite::wrap(self.Height() as f64)));
|
||||||
|
let raw_data = image_data.get_data_array(&GlobalRef::Window(window.r()));
|
||||||
|
|
||||||
|
// Only handle image/png for now.
|
||||||
|
let mime_type = "image/png";
|
||||||
|
|
||||||
|
let mut encoded = Vec::new();
|
||||||
|
{
|
||||||
|
let encoder: PNGEncoder<&mut Vec<u8>> = PNGEncoder::new(&mut encoded);
|
||||||
|
encoder.encode(&raw_data, self.Width(), self.Height(), ColorType::RGBA(8)).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let encoded = encoded.to_base64(STANDARD);
|
||||||
|
Ok(format!("data:{};base64,{}", mime_type, encoded))
|
||||||
|
} else {
|
||||||
|
Err(Error::NotSupported)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VirtualMethods for HTMLCanvasElement {
|
||||||
|
fn super_type(&self) -> Option<&VirtualMethods> {
|
||||||
|
Some(self.upcast::<HTMLElement>() as &VirtualMethods)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) {
|
||||||
|
self.super_type().unwrap().attribute_mutated(attr, mutation);
|
||||||
|
let recreate = match attr.local_name() {
|
||||||
|
&atom!(width) => {
|
||||||
|
let width = mutation.new_value(attr).and_then(|value| {
|
||||||
|
parse_unsigned_integer(value.chars())
|
||||||
|
});
|
||||||
|
self.width.set(width.unwrap_or(DEFAULT_WIDTH));
|
||||||
|
true
|
||||||
|
},
|
||||||
|
&atom!(height) => {
|
||||||
|
let height = mutation.new_value(attr).and_then(|value| {
|
||||||
|
parse_unsigned_integer(value.chars())
|
||||||
|
});
|
||||||
|
self.height.set(height.unwrap_or(DEFAULT_HEIGHT));
|
||||||
|
true
|
||||||
|
},
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
if recreate {
|
||||||
|
self.recreate_contexts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a WebGLContextAttributes> for GLContextAttributes {
|
||||||
|
fn from(attrs: &'a WebGLContextAttributes) -> GLContextAttributes {
|
||||||
|
GLContextAttributes {
|
||||||
|
alpha: attrs.alpha,
|
||||||
|
depth: attrs.depth,
|
||||||
|
stencil: attrs.stencil,
|
||||||
|
antialias: attrs.antialias,
|
||||||
|
premultiplied_alpha: attrs.premultipliedAlpha,
|
||||||
|
preserve_drawing_buffer: attrs.preserveDrawingBuffer,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod utils {
|
||||||
|
use dom::window::Window;
|
||||||
|
use ipc_channel::ipc;
|
||||||
|
use net_traits::image_cache_task::{ImageCacheChan, ImageResponse};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
pub fn request_image_from_cache(window: &Window, url: Url) -> ImageResponse {
|
||||||
|
let image_cache = window.image_cache_task();
|
||||||
|
let (response_chan, response_port) = ipc::channel().unwrap();
|
||||||
|
image_cache.request_image(url, ImageCacheChan(response_chan), None);
|
||||||
|
let result = response_port.recv().unwrap();
|
||||||
|
result.image_response
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,8 @@ use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, Root};
|
use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::trace::JSTraceable;
|
use dom::bindings::trace::JSTraceable;
|
||||||
use dom::bindings::utils::{Reflector, namespace_from_domstring, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
|
use dom::bindings::xmlname::namespace_from_domstring;
|
||||||
use dom::element::Element;
|
use dom::element::Element;
|
||||||
use dom::node::{Node, TreeIterator};
|
use dom::node::{Node, TreeIterator};
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
|
|
|
@ -13,7 +13,7 @@ use dom::bindings::codegen::InheritTypes::{ElementTypeId, HTMLElementTypeId, Nod
|
||||||
use dom::bindings::inheritance::Castable;
|
use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::error::{Error, ErrorResult};
|
use dom::bindings::error::{Error, ErrorResult};
|
||||||
use dom::bindings::js::{JS, MutNullableHeap, Root};
|
use dom::bindings::js::{JS, MutNullableHeap, Root};
|
||||||
use dom::bindings::utils::Reflectable;
|
use dom::bindings::reflector::Reflectable;
|
||||||
use dom::cssstyledeclaration::{CSSModificationAccess, CSSStyleDeclaration};
|
use dom::cssstyledeclaration::{CSSModificationAccess, CSSStyleDeclaration};
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::domstringmap::DOMStringMap;
|
use dom::domstringmap::DOMStringMap;
|
||||||
|
|
|
@ -10,11 +10,11 @@ use dom::bindings::codegen::Bindings::HTMLFormElementBinding;
|
||||||
use dom::bindings::codegen::Bindings::HTMLFormElementBinding::HTMLFormElementMethods;
|
use dom::bindings::codegen::Bindings::HTMLFormElementBinding::HTMLFormElementMethods;
|
||||||
use dom::bindings::codegen::Bindings::HTMLInputElementBinding::HTMLInputElementMethods;
|
use dom::bindings::codegen::Bindings::HTMLInputElementBinding::HTMLInputElementMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::{ElementTypeId, HTMLElementTypeId, NodeTypeId};
|
use dom::bindings::codegen::InheritTypes::{ElementTypeId, HTMLElementTypeId, NodeTypeId};
|
||||||
use dom::bindings::conversions::{DerivedFrom};
|
use dom::bindings::conversions::DerivedFrom;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::inheritance::Castable;
|
use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::js::{Root};
|
use dom::bindings::js::{Root};
|
||||||
use dom::bindings::utils::Reflectable;
|
use dom::bindings::reflector::Reflectable;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::Element;
|
use dom::element::Element;
|
||||||
use dom::event::{Event, EventBubbles, EventCancelable};
|
use dom::event::{Event, EventBubbles, EventCancelable};
|
||||||
|
|
|
@ -11,7 +11,7 @@ use dom::bindings::error::{Error, ErrorResult, Fallible};
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::inheritance::Castable;
|
use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::js::{Root, LayoutJS};
|
use dom::bindings::js::{Root, LayoutJS};
|
||||||
use dom::bindings::utils::Reflectable;
|
use dom::bindings::reflector::Reflectable;
|
||||||
use dom::customevent::CustomEvent;
|
use dom::customevent::CustomEvent;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::{self, AttributeMutation, Element};
|
use dom::element::{self, AttributeMutation, Element};
|
||||||
|
|
|
@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::ImageDataBinding;
|
||||||
use dom::bindings::codegen::Bindings::ImageDataBinding::ImageDataMethods;
|
use dom::bindings::codegen::Bindings::ImageDataBinding::ImageDataMethods;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use euclid::size::Size2D;
|
use euclid::size::Size2D;
|
||||||
use js::jsapi::{Heap, JSContext, JSObject};
|
use js::jsapi::{Heap, JSContext, JSObject};
|
||||||
use js::jsapi::{JS_GetUint8ClampedArrayData, JS_NewUint8ClampedArray};
|
use js::jsapi::{JS_GetUint8ClampedArrayData, JS_NewUint8ClampedArray};
|
||||||
|
|
|
@ -9,7 +9,8 @@ use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::error::Fallible;
|
use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{Root, RootedReference};
|
use dom::bindings::js::{Root, RootedReference};
|
||||||
use dom::bindings::utils::{Reflectable, reflect_dom_object};
|
use dom::bindings::reflector::reflect_dom_object;
|
||||||
|
use dom::bindings::reflector::Reflectable;
|
||||||
use dom::event::Event;
|
use dom::event::Event;
|
||||||
use dom::uievent::UIEvent;
|
use dom::uievent::UIEvent;
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
|
|
|
@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::LocationBinding::LocationMethods;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, Root};
|
use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::str::USVString;
|
use dom::bindings::str::USVString;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::urlhelper::UrlHelper;
|
use dom::urlhelper::UrlHelper;
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
use url::{Url, UrlParser};
|
use url::{Url, UrlParser};
|
||||||
|
|
|
@ -9,7 +9,7 @@ use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::error::Fallible;
|
use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::reflect_dom_object;
|
use dom::bindings::reflector::reflect_dom_object;
|
||||||
use dom::event::Event;
|
use dom::event::Event;
|
||||||
use dom::eventtarget::EventTarget;
|
use dom::eventtarget::EventTarget;
|
||||||
use js::jsapi::{RootedValue, HandleValue, Heap, JSContext};
|
use js::jsapi::{RootedValue, HandleValue, Heap, JSContext};
|
||||||
|
|
|
@ -9,7 +9,7 @@ use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::error::Fallible;
|
use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference};
|
use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference};
|
||||||
use dom::bindings::utils::reflect_dom_object;
|
use dom::bindings::reflector::reflect_dom_object;
|
||||||
use dom::event::{Event, EventBubbles, EventCancelable};
|
use dom::event::{Event, EventBubbles, EventCancelable};
|
||||||
use dom::eventtarget::EventTarget;
|
use dom::eventtarget::EventTarget;
|
||||||
use dom::uievent::UIEvent;
|
use dom::uievent::UIEvent;
|
||||||
|
|
|
@ -8,7 +8,8 @@ use dom::bindings::codegen::Bindings::NamedNodeMapBinding::NamedNodeMapMethods;
|
||||||
use dom::bindings::error::{Error, Fallible};
|
use dom::bindings::error::{Error, Fallible};
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, Root};
|
use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::utils::{Reflector, namespace_from_domstring, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
|
use dom::bindings::xmlname::namespace_from_domstring;
|
||||||
use dom::element::Element;
|
use dom::element::Element;
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
use string_cache::Atom;
|
use string_cache::Atom;
|
||||||
|
|
|
@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::NavigatorBinding;
|
||||||
use dom::bindings::codegen::Bindings::NavigatorBinding::NavigatorMethods;
|
use dom::bindings::codegen::Bindings::NavigatorBinding::NavigatorMethods;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::navigatorinfo;
|
use dom::navigatorinfo;
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
|
|
|
@ -31,7 +31,8 @@ use dom::bindings::js::RootedReference;
|
||||||
use dom::bindings::js::{JS, LayoutJS, MutNullableHeap};
|
use dom::bindings::js::{JS, LayoutJS, MutNullableHeap};
|
||||||
use dom::bindings::trace::JSTraceable;
|
use dom::bindings::trace::JSTraceable;
|
||||||
use dom::bindings::trace::RootedVec;
|
use dom::bindings::trace::RootedVec;
|
||||||
use dom::bindings::utils::{Reflectable, namespace_from_domstring, reflect_dom_object};
|
use dom::bindings::reflector::{Reflectable, reflect_dom_object};
|
||||||
|
use dom::bindings::xmlname::namespace_from_domstring;
|
||||||
use dom::characterdata::CharacterData;
|
use dom::characterdata::CharacterData;
|
||||||
use dom::comment::Comment;
|
use dom::comment::Comment;
|
||||||
use dom::document::{Document, DocumentSource, IsHTMLDocument};
|
use dom::document::{Document, DocumentSource, IsHTMLDocument};
|
||||||
|
|
|
@ -11,7 +11,7 @@ use dom::bindings::codegen::Bindings::NodeIteratorBinding::NodeIteratorMethods;
|
||||||
use dom::bindings::error::Fallible;
|
use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, MutHeap, Root};
|
use dom::bindings::js::{JS, MutHeap, Root};
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::node::Node;
|
use dom::node::Node;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
|
|
@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::NodeListBinding;
|
||||||
use dom::bindings::codegen::Bindings::NodeListBinding::NodeListMethods;
|
use dom::bindings::codegen::Bindings::NodeListBinding::NodeListMethods;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference};
|
use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference};
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::node::{ChildrenMutation, Node};
|
use dom::node::{ChildrenMutation, Node};
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
|
|
@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::PerformanceBinding::PerformanceMethods;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, Root};
|
use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::num::Finite;
|
use dom::bindings::num::Finite;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::performancetiming::PerformanceTiming;
|
use dom::performancetiming::PerformanceTiming;
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
use time;
|
use time;
|
||||||
|
|
|
@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::PerformanceTimingBinding;
|
||||||
use dom::bindings::codegen::Bindings::PerformanceTimingBinding::PerformanceTimingMethods;
|
use dom::bindings::codegen::Bindings::PerformanceTimingBinding::PerformanceTimingMethods;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
|
|
@ -9,7 +9,7 @@ use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::error::Fallible;
|
use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::reflect_dom_object;
|
use dom::bindings::reflector::reflect_dom_object;
|
||||||
use dom::event::{Event, EventBubbles, EventCancelable};
|
use dom::event::{Event, EventBubbles, EventCancelable};
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::error::{Error, ErrorResult, Fallible};
|
use dom::bindings::error::{Error, ErrorResult, Fallible};
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, MutHeap, Root, RootedReference};
|
use dom::bindings::js::{JS, MutHeap, Root, RootedReference};
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::characterdata::CharacterData;
|
use dom::characterdata::CharacterData;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::documentfragment::DocumentFragment;
|
use dom::documentfragment::DocumentFragment;
|
||||||
|
|
|
@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::ScreenBinding;
|
||||||
use dom::bindings::codegen::Bindings::ScreenBinding::ScreenMethods;
|
use dom::bindings::codegen::Bindings::ScreenBinding::ScreenMethods;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
|
|
@ -12,7 +12,7 @@ use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, Root};
|
use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::refcounted::Trusted;
|
use dom::bindings::refcounted::Trusted;
|
||||||
use dom::bindings::trace::JSTraceable;
|
use dom::bindings::trace::JSTraceable;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::node::Node;
|
use dom::node::Node;
|
||||||
use dom::text::Text;
|
use dom::text::Text;
|
||||||
|
|
|
@ -9,7 +9,7 @@ use dom::bindings::error::{Error, ErrorResult};
|
||||||
use dom::bindings::global::{GlobalField, GlobalRef};
|
use dom::bindings::global::{GlobalField, GlobalRef};
|
||||||
use dom::bindings::js::{Root, RootedReference};
|
use dom::bindings::js::{Root, RootedReference};
|
||||||
use dom::bindings::refcounted::Trusted;
|
use dom::bindings::refcounted::Trusted;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::event::{Event, EventBubbles, EventCancelable};
|
use dom::event::{Event, EventBubbles, EventCancelable};
|
||||||
use dom::storageevent::StorageEvent;
|
use dom::storageevent::StorageEvent;
|
||||||
use dom::urlhelper::UrlHelper;
|
use dom::urlhelper::UrlHelper;
|
||||||
|
|
|
@ -9,7 +9,7 @@ use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::error::Fallible;
|
use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference};
|
use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference};
|
||||||
use dom::bindings::utils::{reflect_dom_object};
|
use dom::bindings::reflector::reflect_dom_object;
|
||||||
use dom::event::{Event, EventBubbles, EventCancelable};
|
use dom::event::{Event, EventBubbles, EventCancelable};
|
||||||
use dom::storage::Storage;
|
use dom::storage::Storage;
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
|
|
|
@ -18,7 +18,7 @@ use dom::bindings::global::{GlobalField, GlobalRef};
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::num::Finite;
|
use dom::bindings::num::Finite;
|
||||||
use dom::bindings::str::{ByteString, USVString};
|
use dom::bindings::str::{ByteString, USVString};
|
||||||
use dom::bindings::utils::Reflector;
|
use dom::bindings::reflector::Reflector;
|
||||||
use dom::blob::Blob;
|
use dom::blob::Blob;
|
||||||
use js::jsapi::{HandleValue, JSContext, JSObject};
|
use js::jsapi::{HandleValue, JSContext, JSObject};
|
||||||
use js::jsval::{JSVal, NullValue};
|
use js::jsval::{JSVal, NullValue};
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
// check-tidy: no specs after this line
|
// check-tidy: no specs after this line
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::TestBindingProxyBinding::TestBindingProxyMethods;
|
use dom::bindings::codegen::Bindings::TestBindingProxyBinding::TestBindingProxyMethods;
|
||||||
use dom::bindings::utils::Reflector;
|
use dom::bindings::reflector::Reflector;
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::str::USVString;
|
use dom::bindings::str::USVString;
|
||||||
use dom::bindings::trace::JSTraceable;
|
use dom::bindings::trace::JSTraceable;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use encoding::Encoding;
|
use encoding::Encoding;
|
||||||
use encoding::label::encoding_from_whatwg_label;
|
use encoding::label::encoding_from_whatwg_label;
|
||||||
use encoding::types::{DecoderTrap, EncodingRef};
|
use encoding::types::{DecoderTrap, EncodingRef};
|
||||||
|
|
|
@ -8,7 +8,7 @@ use dom::bindings::error::{Error, Fallible};
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::str::USVString;
|
use dom::bindings::str::USVString;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use encoding::label::encoding_from_whatwg_label;
|
use encoding::label::encoding_from_whatwg_label;
|
||||||
use encoding::types::EncodingRef;
|
use encoding::types::EncodingRef;
|
||||||
use encoding::{EncoderTrap, Encoding};
|
use encoding::{EncoderTrap, Encoding};
|
||||||
|
|
|
@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::TouchBinding::TouchMethods;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, MutHeap, Root};
|
use dom::bindings::js::{JS, MutHeap, Root};
|
||||||
use dom::bindings::num::Finite;
|
use dom::bindings::num::Finite;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::eventtarget::EventTarget;
|
use dom::eventtarget::EventTarget;
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::UIEventBinding::UIEventMethods;
|
||||||
use dom::bindings::inheritance::Castable;
|
use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, MutHeap, Root};
|
use dom::bindings::js::{JS, MutHeap, Root};
|
||||||
use dom::bindings::utils::reflect_dom_object;
|
use dom::bindings::reflector::reflect_dom_object;
|
||||||
use dom::event::{EventBubbles, EventCancelable};
|
use dom::event::{EventBubbles, EventCancelable};
|
||||||
use dom::touchlist::TouchList;
|
use dom::touchlist::TouchList;
|
||||||
use dom::uievent::UIEvent;
|
use dom::uievent::UIEvent;
|
||||||
|
|
|
@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::TouchListBinding;
|
||||||
use dom::bindings::codegen::Bindings::TouchListBinding::TouchListMethods;
|
use dom::bindings::codegen::Bindings::TouchListBinding::TouchListMethods;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, Root};
|
use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::touch::Touch;
|
use dom::touch::Touch;
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::js::{JS, MutHeap};
|
use dom::bindings::js::{JS, MutHeap};
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::node::Node;
|
use dom::node::Node;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
|
@ -10,7 +10,7 @@ use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::js::{JS, MutNullableHeap, RootedReference};
|
use dom::bindings::js::{JS, MutNullableHeap, RootedReference};
|
||||||
use dom::bindings::utils::reflect_dom_object;
|
use dom::bindings::reflector::reflect_dom_object;
|
||||||
use dom::event::{Event, EventBubbles, EventCancelable};
|
use dom::event::{Event, EventBubbles, EventCancelable};
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
|
|
@ -7,7 +7,7 @@ use dom::bindings::error::{Error, ErrorResult, Fallible};
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::str::USVString;
|
use dom::bindings::str::USVString;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::urlhelper::UrlHelper;
|
use dom::urlhelper::UrlHelper;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
|
|
@ -10,7 +10,7 @@ use dom::bindings::codegen::UnionTypes::StringOrURLSearchParams::{eString, eURLS
|
||||||
use dom::bindings::error::Fallible;
|
use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use encoding::types::EncodingRef;
|
use encoding::types::EncodingRef;
|
||||||
use url::form_urlencoded::{parse, serialize_with_encoding};
|
use url::form_urlencoded::{parse, serialize_with_encoding};
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
use dom::bindings::codegen::Bindings::ValidityStateBinding;
|
use dom::bindings::codegen::Bindings::ValidityStateBinding;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#validitystate
|
// https://html.spec.whatwg.org/multipage/#validitystate
|
||||||
|
|
|
@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::WebGLActiveInfoBinding;
|
||||||
use dom::bindings::codegen::Bindings::WebGLActiveInfoBinding::WebGLActiveInfoMethods;
|
use dom::bindings::codegen::Bindings::WebGLActiveInfoBinding::WebGLActiveInfoMethods;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
|
|
@ -7,7 +7,7 @@ use canvas_traits::{CanvasMsg, CanvasWebGLMsg, WebGLError, WebGLResult};
|
||||||
use dom::bindings::codegen::Bindings::WebGLBufferBinding;
|
use dom::bindings::codegen::Bindings::WebGLBufferBinding;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::reflect_dom_object;
|
use dom::bindings::reflector::reflect_dom_object;
|
||||||
use dom::webglobject::WebGLObject;
|
use dom::webglobject::WebGLObject;
|
||||||
use ipc_channel::ipc::{self, IpcSender};
|
use ipc_channel::ipc::{self, IpcSender};
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
|
|
@ -10,7 +10,7 @@ use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::error::Fallible;
|
use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::reflect_dom_object;
|
use dom::bindings::reflector::reflect_dom_object;
|
||||||
use dom::event::{Event, EventBubbles, EventCancelable};
|
use dom::event::{Event, EventBubbles, EventCancelable};
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ use canvas_traits::{CanvasMsg, CanvasWebGLMsg, WebGLFramebufferBindingRequest};
|
||||||
use dom::bindings::codegen::Bindings::WebGLFramebufferBinding;
|
use dom::bindings::codegen::Bindings::WebGLFramebufferBinding;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::reflect_dom_object;
|
use dom::bindings::reflector::reflect_dom_object;
|
||||||
use dom::webglobject::WebGLObject;
|
use dom::webglobject::WebGLObject;
|
||||||
use ipc_channel::ipc::{self, IpcSender};
|
use ipc_channel::ipc::{self, IpcSender};
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
use dom::bindings::codegen::Bindings::WebGLObjectBinding;
|
use dom::bindings::codegen::Bindings::WebGLObjectBinding;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct WebGLObject {
|
pub struct WebGLObject {
|
||||||
|
|
|
@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::WebGLProgramBinding;
|
||||||
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
|
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, MutNullableHeap, Root};
|
use dom::bindings::js::{JS, MutNullableHeap, Root};
|
||||||
use dom::bindings::utils::reflect_dom_object;
|
use dom::bindings::reflector::reflect_dom_object;
|
||||||
use dom::webglobject::WebGLObject;
|
use dom::webglobject::WebGLObject;
|
||||||
use dom::webglrenderingcontext::MAX_UNIFORM_AND_ATTRIBUTE_LEN;
|
use dom::webglrenderingcontext::MAX_UNIFORM_AND_ATTRIBUTE_LEN;
|
||||||
use dom::webglshader::WebGLShader;
|
use dom::webglshader::WebGLShader;
|
||||||
|
|
|
@ -7,7 +7,7 @@ use canvas_traits::{CanvasMsg, CanvasWebGLMsg};
|
||||||
use dom::bindings::codegen::Bindings::WebGLRenderbufferBinding;
|
use dom::bindings::codegen::Bindings::WebGLRenderbufferBinding;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::reflect_dom_object;
|
use dom::bindings::reflector::reflect_dom_object;
|
||||||
use dom::webglobject::WebGLObject;
|
use dom::webglobject::WebGLObject;
|
||||||
use ipc_channel::ipc::{self, IpcSender};
|
use ipc_channel::ipc::{self, IpcSender};
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
|
|
@ -9,11 +9,11 @@ use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderi
|
||||||
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::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::inheritance::Castable;
|
use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root};
|
use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root};
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||||
use dom::event::{Event, EventBubbles, EventCancelable};
|
use dom::event::{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;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue