aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
Diffstat (limited to 'components/script')
-rw-r--r--components/script/Cargo.toml12
-rw-r--r--components/script/cors.rs9
-rw-r--r--components/script/devtools.rs4
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py35
-rw-r--r--components/script/dom/bindings/interface.rs32
-rw-r--r--components/script/dom/bindings/proxyhandler.rs5
-rw-r--r--components/script/dom/bindings/str.rs3
-rw-r--r--components/script/dom/bindings/trace.rs3
-rw-r--r--components/script/dom/blob.rs22
-rw-r--r--components/script/dom/canvasrenderingcontext2d.rs13
-rw-r--r--components/script/dom/closeevent.rs16
-rw-r--r--components/script/dom/dedicatedworkerglobalscope.rs14
-rw-r--r--components/script/dom/document.rs97
-rw-r--r--components/script/dom/domtokenlist.rs26
-rw-r--r--components/script/dom/element.rs81
-rw-r--r--components/script/dom/errorevent.rs12
-rw-r--r--components/script/dom/event.rs42
-rw-r--r--components/script/dom/focusevent.rs16
-rw-r--r--components/script/dom/htmlanchorelement.rs343
-rw-r--r--components/script/dom/htmlbuttonelement.rs5
-rw-r--r--components/script/dom/htmlcanvaselement.rs25
-rw-r--r--components/script/dom/htmlcollection.rs31
-rw-r--r--components/script/dom/htmlfieldsetelement.rs2
-rw-r--r--components/script/dom/htmliframeelement.rs34
-rw-r--r--components/script/dom/htmlinputelement.rs45
-rw-r--r--components/script/dom/htmllabelelement.rs15
-rw-r--r--components/script/dom/htmlmetaelement.rs3
-rw-r--r--components/script/dom/htmlobjectelement.rs5
-rw-r--r--components/script/dom/htmloutputelement.rs2
-rw-r--r--components/script/dom/htmlscriptelement.rs21
-rw-r--r--components/script/dom/htmlselectelement.rs5
-rw-r--r--components/script/dom/htmltextareaelement.rs10
-rw-r--r--components/script/dom/keyboardevent.rs13
-rw-r--r--components/script/dom/mod.rs1
-rw-r--r--components/script/dom/mouseevent.rs14
-rw-r--r--components/script/dom/node.rs2
-rw-r--r--components/script/dom/progressevent.rs7
-rw-r--r--components/script/dom/storageevent.rs10
-rw-r--r--components/script/dom/testbinding.rs4
-rw-r--r--components/script/dom/touchevent.rs4
-rw-r--r--components/script/dom/uievent.rs11
-rw-r--r--components/script/dom/urlhelper.rs5
-rw-r--r--components/script/dom/validation.rs5
-rw-r--r--components/script/dom/validitystate.rs92
-rw-r--r--components/script/dom/webglbuffer.rs11
-rw-r--r--components/script/dom/webglcontextevent.rs14
-rw-r--r--components/script/dom/webglframebuffer.rs9
-rw-r--r--components/script/dom/webglprogram.rs23
-rw-r--r--components/script/dom/webglrenderbuffer.rs9
-rw-r--r--components/script/dom/webglrenderingcontext.rs111
-rw-r--r--components/script/dom/webglshader.rs11
-rw-r--r--components/script/dom/webgltexture.rs15
-rw-r--r--components/script/dom/webidls/Blob.webidl6
-rw-r--r--components/script/dom/webidls/BrowserElement.webidl6
-rw-r--r--components/script/dom/webidls/DOMTokenList.webidl2
-rw-r--r--components/script/dom/webidls/Element.webidl4
-rw-r--r--components/script/dom/webidls/HTMLAnchorElement.webidl2
-rw-r--r--components/script/dom/webidls/HTMLHyperlinkElementUtils.webidl30
-rw-r--r--components/script/dom/webidls/Navigator.webidl1
-rw-r--r--components/script/dom/webidls/TestBinding.webidl2
-rw-r--r--components/script/dom/webidls/ValidityState.webidl22
-rw-r--r--components/script/dom/window.rs12
-rw-r--r--components/script/dom/workerglobalscope.rs6
-rw-r--r--components/script/dom/xmlhttprequest.rs43
-rw-r--r--components/script/lib.rs2
-rw-r--r--components/script/script_thread.rs13
-rw-r--r--components/script/task_source/dom_manipulation.rs6
-rw-r--r--components/script/task_source/file_reading.rs6
-rw-r--r--components/script/task_source/history_traversal.rs6
-rw-r--r--components/script/task_source/networking.rs6
-rw-r--r--components/script/task_source/user_interaction.rs6
-rw-r--r--components/script/textinput.rs14
72 files changed, 1084 insertions, 470 deletions
diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml
index ffde81f1a91..fb90edec267 100644
--- a/components/script/Cargo.toml
+++ b/components/script/Cargo.toml
@@ -46,11 +46,8 @@ path = "../canvas_traits"
[dependencies.js]
git = "https://github.com/servo/rust-mozjs"
-[dependencies.offscreen_gl_context]
-git = "https://github.com/ecoal95/rust-offscreen-rendering-context"
-
[dependencies.angle]
-git = "https://github.com/ecoal95/angle"
+git = "https://github.com/emilio/angle"
branch = "servo"
[dependencies.ipc-channel]
@@ -63,6 +60,9 @@ features = ["unstable"]
[dependencies.gfx_traits]
path = "../gfx_traits"
+[dependencies.webrender_traits]
+git = "https://github.com/servo/webrender_traits"
+
[dependencies]
app_units = {version = "0.2.3", features = ["plugins"]}
bitflags = "0.3"
@@ -79,9 +79,11 @@ image = "0.7"
libc = "0.2"
log = "0.3.5"
num = "0.1.24"
+offscreen_gl_context = "0.1.2"
rand = "0.3"
phf = "0.7.13"
phf_macros = "0.7.13"
+range = { path = "../range" }
ref_filter_map = "1.0"
ref_slice = "0.1.0"
regex = "0.1.43"
@@ -94,4 +96,4 @@ time = "0.1.12"
unicase = "1.0"
url = {version = "0.5.7", features = ["heap_size"]}
uuid = "0.1.16"
-websocket = "0.15.2"
+websocket = "0.16.1"
diff --git a/components/script/cors.rs b/components/script/cors.rs
index b5ad670a38c..8be1ec9d6d2 100644
--- a/components/script/cors.rs
+++ b/components/script/cors.rs
@@ -394,9 +394,8 @@ impl CORSCache {
header_name: &str)
-> Option<&'a mut CORSCacheEntry> {
self.cleanup();
- let CORSCache(ref mut buf) = *self;
// Credentials are not yet implemented here
- buf.iter_mut().find(|e| {
+ self.0.iter_mut().find(|e| {
e.origin.scheme == request.origin.scheme && e.origin.host() == request.origin.host() &&
e.origin.port() == request.origin.port() && e.url == request.destination &&
e.header_or_method.match_header(header_name)
@@ -421,9 +420,8 @@ impl CORSCache {
-> Option<&'a mut CORSCacheEntry> {
// we can take the method from CORSRequest itself
self.cleanup();
- let CORSCache(ref mut buf) = *self;
// Credentials are not yet implemented here
- buf.iter_mut().find(|e| {
+ self.0.iter_mut().find(|e| {
e.origin.scheme == request.origin.scheme && e.origin.host() == request.origin.host() &&
e.origin.port() == request.origin.port() && e.url == request.destination &&
e.header_or_method.match_method(method)
@@ -445,8 +443,7 @@ impl CORSCache {
fn insert(&mut self, entry: CORSCacheEntry) {
self.cleanup();
- let CORSCache(ref mut buf) = *self;
- buf.push(entry);
+ self.0.push(entry);
}
}
diff --git a/components/script/devtools.rs b/components/script/devtools.rs
index f0ec814cdc2..a1f5f21573c 100644
--- a/components/script/devtools.rs
+++ b/components/script/devtools.rs
@@ -167,7 +167,7 @@ pub fn handle_get_cached_messages(_pipeline_id: PipelineId,
// TODO: make script error reporter pass all reported errors
// to devtools and cache them for returning here.
let msg = PageError {
- _type: "PageError".to_owned(),
+ type_: "PageError".to_owned(),
errorMessage: "page error test".to_owned(),
sourceName: String::new(),
lineText: String::new(),
@@ -186,7 +186,7 @@ pub fn handle_get_cached_messages(_pipeline_id: PipelineId,
if message_types.contains(CONSOLE_API) {
// TODO: do for real
let msg = ConsoleAPI {
- _type: "ConsoleAPI".to_owned(),
+ type_: "ConsoleAPI".to_owned(),
level: "error".to_owned(),
filename: "http://localhost/~mihai/mozilla/test.html".to_owned(),
lineNumber: 0,
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index 4468bb13b6b..51c29764125 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -1893,15 +1893,16 @@ class CGInterfaceObjectJSClass(CGThing):
constructor = CONSTRUCT_HOOK_NAME
else:
constructor = "throwing_constructor"
+ name = self.descriptor.interface.identifier.name
args = {
"constructor": constructor,
- "name": self.descriptor.interface.identifier.name,
- "id": self.descriptor.interface.identifier.name,
+ "id": name,
+ "representation": str_to_const_array("function %s() {\\n [native code]\\n}" % name),
"depth": self.descriptor.prototypeDepth
}
return """\
static InterfaceObjectClass: NonCallbackInterfaceObjectClass =
- NonCallbackInterfaceObjectClass::new(%(constructor)s, fun_to_string,
+ NonCallbackInterfaceObjectClass::new(%(constructor)s, %(representation)s,
PrototypeList::ID::%(id)s, %(depth)s);
""" % args
@@ -4824,21 +4825,6 @@ let args = CallArgs::from_vp(vp, argc);
return CGList([preamble, callGenerator])
-class CGClassFunToStringHook(CGAbstractExternMethod):
- """
- A hook to convert functions to strings.
- """
- def __init__(self, descriptor):
- args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', '_obj'),
- Argument('u32', '_indent')]
- CGAbstractExternMethod.__init__(self, descriptor, "fun_to_string", '*mut JSString', args)
-
- def definition_body(self):
- name = self.descriptor.interface.identifier.name
- string = str_to_const_array("function %s() {\\n [native code]\\n}" % name)
- return CGGeneric("JS_NewStringCopyZ(cx, %s as *const _ as *const libc::c_char)" % string)
-
-
class CGClassFinalizeHook(CGAbstractClassHook):
"""
A hook for finalize, used to release our native object.
@@ -5007,7 +4993,6 @@ class CGDescriptor(CGThing):
cgThings.append(CGClassConstructHook(descriptor, ctor))
if not descriptor.interface.isCallback():
cgThings.append(CGInterfaceObjectJSClass(descriptor))
- cgThings.append(CGClassFunToStringHook(descriptor))
if not descriptor.interface.isCallback():
cgThings.append(CGPrototypeJSClass(descriptor))
@@ -5201,6 +5186,14 @@ class CGDictionary(CGThing):
" }\n"
"}\n"
"\n"
+ "impl FromJSValConvertible for ${selfName} {\n"
+ " type Config = ();\n"
+ " unsafe fn from_jsval(cx: *mut JSContext, value: HandleValue, _option: ())\n"
+ " -> Result<${selfName}, ()> {\n"
+ " ${selfName}::new(cx, value)\n"
+ " }\n"
+ "}\n"
+ "\n"
"impl ToJSValConvertible for ${selfName} {\n"
" unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {\n"
" let obj = RootedObject::new(cx, JS_NewObject(cx, ptr::null()));\n"
@@ -5349,8 +5342,8 @@ class CGBindingRoot(CGThing):
# Do codegen for all the typdefs
for t in typedefs:
if t.innerType.isUnion():
- cgthings.extend([CGGeneric("\npub type %s = %s;\n\n" % (t.identifier.name,
- "UnionTypes::" + str(t.innerType)))])
+ cgthings.extend([CGGeneric("\npub use dom::bindings::codegen::UnionTypes::%s as %s;\n\n" %
+ (t.innerType, t.identifier.name))])
else:
assert not typeNeedsRooting(t.innerType, config.getDescriptorProvider)
cgthings.extend([CGGeneric("\npub type %s = " % (t.identifier.name)),
diff --git a/components/script/dom/bindings/interface.rs b/components/script/dom/bindings/interface.rs
index a5bc3ec513c..7db3c6e17c4 100644
--- a/components/script/dom/bindings/interface.rs
+++ b/components/script/dom/bindings/interface.rs
@@ -13,8 +13,9 @@ use js::jsapi::{HandleObject, HandleValue, JSClass, JSContext, JSFunctionSpec};
use js::jsapi::{JSPropertySpec, JSString, JS_DefineProperty1, JS_DefineProperty2};
use js::jsapi::{JS_DefineProperty4, JS_GetClass, JS_GetFunctionObject, JS_GetPrototype};
use js::jsapi::{JS_InternString, JS_LinkConstructorAndPrototype, JS_NewFunction, JS_NewObject};
-use js::jsapi::{JS_NewObjectWithUniqueType, JS_DefineProperty, MutableHandleObject};
-use js::jsapi::{MutableHandleValue, ObjectOps, RootedObject, RootedString, RootedValue, Value};
+use js::jsapi::{JS_NewObjectWithUniqueType, JS_NewStringCopyZ, JS_DefineProperty};
+use js::jsapi::{MutableHandleObject, MutableHandleValue, ObjectOps, RootedObject, RootedString};
+use js::jsapi::{RootedValue, Value};
use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, NullValue, UInt32Value};
use js::rust::{define_methods, define_properties};
use js::{JSPROP_ENUMERATE, JSFUN_CONSTRUCTOR, JSPROP_PERMANENT, JSPROP_READONLY};
@@ -79,17 +80,23 @@ pub fn define_constants(cx: *mut JSContext, obj: HandleObject, constants: &'stat
}
}
+unsafe extern "C" fn fun_to_string_hook(cx: *mut JSContext,
+ obj: HandleObject,
+ _indent: u32)
+ -> *mut JSString {
+ let js_class = JS_GetClass(obj.get());
+ assert!(!js_class.is_null());
+ let object_class = &*(js_class as *const NonCallbackInterfaceObjectClass);
+ assert!(object_class.representation.last() == Some(&0));
+ let ret = JS_NewStringCopyZ(cx, object_class.representation.as_ptr() as *const libc::c_char);
+ assert!(!ret.is_null());
+ ret
+}
+
/// A constructor class hook.
pub type ConstructorClassHook =
unsafe extern "C" fn(cx: *mut JSContext, argc: u32, vp: *mut Value) -> bool;
-/// A fun_to_string class hook.
-pub type FunToStringHook =
- unsafe extern "C" fn(cx: *mut JSContext,
- obj: HandleObject,
- indent: u32)
- -> *mut JSString;
-
/// The class of a non-callback interface object.
#[derive(Copy, Clone)]
pub struct NonCallbackInterfaceObjectClass {
@@ -99,6 +106,8 @@ pub struct NonCallbackInterfaceObjectClass {
pub proto_id: PrototypeList::ID,
/// The prototype depth of that interface, used in the hasInstance hook.
pub proto_depth: u16,
+ /// The string representation of the object (ends with '\0').
+ pub representation: &'static [u8],
}
unsafe impl Sync for NonCallbackInterfaceObjectClass {}
@@ -107,7 +116,7 @@ impl NonCallbackInterfaceObjectClass {
/// Create a new `NonCallbackInterfaceObjectClass` structure.
pub const fn new(
constructor: ConstructorClassHook,
- fun_to_string: FunToStringHook,
+ string_rep: &'static [u8],
proto_id: PrototypeList::ID,
proto_depth: u16)
-> NonCallbackInterfaceObjectClass {
@@ -157,11 +166,12 @@ impl NonCallbackInterfaceObjectClass {
getElements: None,
enumerate: None,
thisObject: None,
- funToString: Some(fun_to_string),
+ funToString: Some(fun_to_string_hook),
}
},
proto_id: proto_id,
proto_depth: proto_depth,
+ representation: string_rep,
}
}
diff --git a/components/script/dom/bindings/proxyhandler.rs b/components/script/dom/bindings/proxyhandler.rs
index 3d5a841edb3..31b5f3db2d0 100644
--- a/components/script/dom/bindings/proxyhandler.rs
+++ b/components/script/dom/bindings/proxyhandler.rs
@@ -57,9 +57,10 @@ pub unsafe extern "C" fn define_property(cx: *mut JSContext,
desc: Handle<JSPropertyDescriptor>,
result: *mut ObjectOpResult)
-> bool {
- // FIXME: Workaround for https://github.com/mozilla/rust/issues/13385
+ // FIXME: Workaround for https://github.com/rust-lang/rfcs/issues/718
let setter: *const libc::c_void = mem::transmute(desc.get().setter);
- let setter_stub: *const libc::c_void = mem::transmute(JS_StrictPropertyStub);
+ let setter_stub: unsafe extern fn(_, _, _, _, _) -> _ = JS_StrictPropertyStub;
+ let setter_stub: *const libc::c_void = mem::transmute(setter_stub);
if (desc.get().attrs & JSPROP_GETTER) != 0 && setter == setter_stub {
(*result).code_ = JSErrNum::JSMSG_GETTER_ONLY as ::libc::uintptr_t;
return true;
diff --git a/components/script/dom/bindings/str.rs b/components/script/dom/bindings/str.rs
index 6276c2c19bd..f1de6297ceb 100644
--- a/components/script/dom/bindings/str.rs
+++ b/components/script/dom/bindings/str.rs
@@ -58,8 +58,7 @@ impl Into<Vec<u8>> for ByteString {
impl Hash for ByteString {
fn hash<H: Hasher>(&self, state: &mut H) {
- let ByteString(ref vec) = *self;
- vec.hash(state);
+ self.0.hash(state);
}
}
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs
index 7bfb6978ee6..2491058750c 100644
--- a/components/script/dom/bindings/trace.rs
+++ b/components/script/dom/bindings/trace.rs
@@ -29,7 +29,6 @@
//! The `no_jsmanaged_fields!()` macro adds an empty implementation of `JSTraceable` to
//! a datatype.
-use canvas_traits::WebGLError;
use canvas_traits::{CanvasGradientStop, LinearGradientStyle, RadialGradientStyle};
use canvas_traits::{CompositionOrBlending, LineCapStyle, LineJoinStyle, RepetitionStyle};
use cssparser::RGBA;
@@ -91,7 +90,7 @@ use style::values::specified::Length;
use url::Url;
use util::str::{DOMString, LengthOrPercentageOrAuto};
use uuid::Uuid;
-
+use webrender_traits::WebGLError;
/// A trait to allow tracing (only) DOM objects.
pub trait JSTraceable {
diff --git a/components/script/dom/blob.rs b/components/script/dom/blob.rs
index dc24cbb01fc..9c23b8f6da0 100644
--- a/components/script/dom/blob.rs
+++ b/components/script/dom/blob.rs
@@ -4,11 +4,14 @@
use dom::bindings::codegen::Bindings::BlobBinding;
use dom::bindings::codegen::Bindings::BlobBinding::BlobMethods;
+use dom::bindings::codegen::UnionTypes::BlobOrString;
use dom::bindings::error::Fallible;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::Root;
use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::trace::JSTraceable;
+use encoding::all::UTF_8;
+use encoding::types::{EncoderTrap, Encoding};
use num::ToPrimitive;
use std::ascii::AsciiExt;
use std::borrow::ToOwned;
@@ -120,16 +123,29 @@ impl Blob {
// https://w3c.github.io/FileAPI/#constructorBlob
pub fn Constructor_(global: GlobalRef,
- blobParts: DOMString,
+ blobParts: Vec<BlobOrString>,
blobPropertyBag: &BlobBinding::BlobPropertyBag)
-> Fallible<Root<Blob>> {
- // TODO: accept other blobParts types - ArrayBuffer or ArrayBufferView or Blob
+
+ // TODO: accept other blobParts types - ArrayBuffer or ArrayBufferView
+ let bytes: Vec<u8> = blobParts.iter()
+ .flat_map(|bPart| {
+ match bPart {
+ &BlobOrString::String(ref s) => {
+ UTF_8.encode(s, EncoderTrap::Replace).unwrap()
+ },
+ &BlobOrString::Blob(ref b) => {
+ b.get_data().get_bytes().to_vec()
+ },
+ }
+ })
+ .collect();
let typeString = if is_ascii_printable(&blobPropertyBag.type_) {
&*blobPropertyBag.type_
} else {
""
};
- Ok(Blob::new(global, blobParts.into(), &typeString.to_ascii_lowercase()))
+ Ok(Blob::new(global, bytes, &typeString.to_ascii_lowercase()))
}
pub fn get_data(&self) -> &DataSlice {
diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs
index 97574187038..aa5c7d9f72b 100644
--- a/components/script/dom/canvasrenderingcontext2d.rs
+++ b/components/script/dom/canvasrenderingcontext2d.rs
@@ -62,7 +62,6 @@ enum CanvasFillOrStrokeStyle {
#[dom_struct]
pub struct CanvasRenderingContext2D {
reflector_: Reflector,
- renderer_id: usize,
#[ignore_heap_size_of = "Defined in ipc-channel"]
ipc_renderer: IpcSender<CanvasMsg>,
canvas: JS<HTMLCanvasElement>,
@@ -125,10 +124,9 @@ impl CanvasRenderingContext2D {
let (sender, receiver) = ipc::channel().unwrap();
let constellation_chan = global.constellation_chan();
constellation_chan.0.send(ConstellationMsg::CreateCanvasPaintThread(size, sender)).unwrap();
- let (ipc_renderer, renderer_id) = receiver.recv().unwrap();
+ let ipc_renderer = receiver.recv().unwrap();
CanvasRenderingContext2D {
reflector_: Reflector::new(),
- renderer_id: renderer_id,
ipc_renderer: ipc_renderer,
canvas: JS::from_ref(canvas),
state: DOMRefCell::new(CanvasContextState::new()),
@@ -501,9 +499,6 @@ impl CanvasRenderingContext2D {
}
}
- pub fn get_renderer_id(&self) -> usize {
- self.renderer_id
- }
pub fn get_ipc_renderer(&self) -> IpcSender<CanvasMsg> {
self.ipc_renderer.clone()
}
@@ -519,17 +514,11 @@ impl CanvasRenderingContext2D {
pub trait LayoutCanvasRenderingContext2DHelpers {
#[allow(unsafe_code)]
- unsafe fn get_renderer_id(&self) -> usize;
- #[allow(unsafe_code)]
unsafe fn get_ipc_renderer(&self) -> IpcSender<CanvasMsg>;
}
impl LayoutCanvasRenderingContext2DHelpers for LayoutJS<CanvasRenderingContext2D> {
#[allow(unsafe_code)]
- unsafe fn get_renderer_id(&self) -> usize {
- (*self.unsafe_get()).renderer_id
- }
- #[allow(unsafe_code)]
unsafe fn get_ipc_renderer(&self) -> IpcSender<CanvasMsg> {
(*self.unsafe_get()).ipc_renderer.clone()
}
diff --git a/components/script/dom/closeevent.rs b/components/script/dom/closeevent.rs
index edf0c6199df..b7181baa2ea 100644
--- a/components/script/dom/closeevent.rs
+++ b/components/script/dom/closeevent.rs
@@ -46,8 +46,8 @@ impl CloseEvent {
{
let event = ev.upcast::<Event>();
event.init_event(type_,
- bubbles == EventBubbles::Bubbles,
- cancelable == EventCancelable::Cancelable);
+ bool::from(bubbles),
+ bool::from(cancelable));
}
ev
}
@@ -56,16 +56,8 @@ impl CloseEvent {
type_: DOMString,
init: &CloseEventBinding::CloseEventInit)
-> Fallible<Root<CloseEvent>> {
- let bubbles = if init.parent.bubbles {
- EventBubbles::Bubbles
- } else {
- EventBubbles::DoesNotBubble
- };
- let cancelable = if init.parent.cancelable {
- EventCancelable::Cancelable
- } else {
- EventCancelable::NotCancelable
- };
+ let bubbles = EventBubbles::from(init.parent.bubbles);
+ let cancelable = EventCancelable::from(init.parent.cancelable);
Ok(CloseEvent::new(global,
Atom::from(type_),
bubbles,
diff --git a/components/script/dom/dedicatedworkerglobalscope.rs b/components/script/dom/dedicatedworkerglobalscope.rs
index c63b657cd19..e560f788278 100644
--- a/components/script/dom/dedicatedworkerglobalscope.rs
+++ b/components/script/dom/dedicatedworkerglobalscope.rs
@@ -32,7 +32,6 @@ use script_thread::ScriptThreadEventCategory::WorkerEvent;
use script_thread::{ScriptThread, ScriptChan, ScriptPort, StackRootTLS, CommonScriptMsg};
use script_traits::{TimerEvent, TimerSource};
use std::mem::replace;
-use std::rc::Rc;
use std::sync::mpsc::{Receiver, RecvError, Select, Sender, channel};
use url::Url;
use util::str::DOMString;
@@ -158,7 +157,7 @@ impl DedicatedWorkerGlobalScope {
worker_url: Url,
id: PipelineId,
from_devtools_receiver: Receiver<DevtoolScriptControlMsg>,
- runtime: Rc<Runtime>,
+ runtime: Runtime,
parent_sender: Box<ScriptChan + Send>,
own_sender: Sender<(TrustedWorkerAddress, WorkerScriptMsg)>,
receiver: Receiver<(TrustedWorkerAddress, WorkerScriptMsg)>,
@@ -185,24 +184,25 @@ impl DedicatedWorkerGlobalScope {
worker_url: Url,
id: PipelineId,
from_devtools_receiver: Receiver<DevtoolScriptControlMsg>,
- runtime: Rc<Runtime>,
+ runtime: Runtime,
parent_sender: Box<ScriptChan + Send>,
own_sender: Sender<(TrustedWorkerAddress, WorkerScriptMsg)>,
receiver: Receiver<(TrustedWorkerAddress, WorkerScriptMsg)>,
timer_event_chan: IpcSender<TimerEvent>,
timer_event_port: Receiver<(TrustedWorkerAddress, TimerEvent)>)
-> Root<DedicatedWorkerGlobalScope> {
+ let cx = runtime.cx();
let scope = box DedicatedWorkerGlobalScope::new_inherited(init,
worker_url,
id,
from_devtools_receiver,
- runtime.clone(),
+ runtime,
parent_sender,
own_sender,
receiver,
timer_event_chan,
timer_event_port);
- DedicatedWorkerGlobalScopeBinding::Wrap(runtime.cx(), scope)
+ DedicatedWorkerGlobalScopeBinding::Wrap(cx, scope)
}
pub fn run_worker_scope(init: WorkerGlobalScopeInit,
@@ -235,7 +235,7 @@ impl DedicatedWorkerGlobalScope {
}
};
- let runtime = Rc::new(ScriptThread::new_rt_and_cx());
+ let runtime = ScriptThread::new_rt_and_cx();
let (devtools_mpsc_chan, devtools_mpsc_port) = channel();
ROUTER.route_ipc_receiver_to_mpsc_sender(from_devtools_receiver, devtools_mpsc_chan);
@@ -249,7 +249,7 @@ impl DedicatedWorkerGlobalScope {
});
let global = DedicatedWorkerGlobalScope::new(
- init, url, id, devtools_mpsc_port, runtime.clone(),
+ init, url, id, devtools_mpsc_port, runtime,
parent_sender.clone(), own_sender, receiver,
timer_ipc_chan, timer_rx);
// FIXME(njn): workers currently don't have a unique ID suitable for using in reporter
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index 0a148f0cb69..a24580d0f95 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -77,6 +77,8 @@ use dom::touchlist::TouchList;
use dom::treewalker::TreeWalker;
use dom::uievent::UIEvent;
use dom::window::{ReflowReason, Window};
+use encoding::EncodingRef;
+use encoding::all::UTF_8;
use euclid::point::Point2D;
use html5ever::tree_builder::{LimitedQuirks, NoQuirks, Quirks, QuirksMode};
use ipc_channel::ipc::{self, IpcSender};
@@ -139,7 +141,7 @@ pub struct Document {
location: MutNullableHeap<JS<Location>>,
content_type: DOMString,
last_modified: Option<String>,
- encoding_name: DOMRefCell<DOMString>,
+ encoding: Cell<EncodingRef>,
is_html_document: bool,
url: Url,
quirks_mode: Cell<QuirksMode>,
@@ -156,7 +158,7 @@ pub struct Document {
anchors: MutNullableHeap<JS<HTMLCollection>>,
applets: MutNullableHeap<JS<HTMLCollection>>,
/// List of stylesheets associated with nodes in this document. |None| if the list needs to be refreshed.
- stylesheets: DOMRefCell<Option<Vec<Arc<Stylesheet>>>>,
+ stylesheets: DOMRefCell<Option<Vec<(JS<Node>, Arc<Stylesheet>)>>>,
/// Whether the list of stylesheets has changed since the last reflow was triggered.
stylesheets_changed_since_reflow: Cell<bool>,
ready_state: Cell<DocumentReadyState>,
@@ -297,11 +299,6 @@ impl Document {
}
#[inline]
- pub fn encoding_name(&self) -> Ref<DOMString> {
- self.encoding_name.borrow()
- }
-
- #[inline]
pub fn is_html_document(&self) -> bool {
self.is_html_document
}
@@ -394,36 +391,12 @@ impl Document {
}
}
- pub fn set_encoding_name(&self, name: DOMString) {
- *self.encoding_name.borrow_mut() = DOMString::from(
- match name.as_ref() {
- "utf-8" => "UTF-8",
- "ibm866" => "IBM866",
- "iso-8859-2" => "ISO-8859-2",
- "iso-8859-3" => "ISO-8859-3",
- "iso-8859-4" => "ISO-8859-4",
- "iso-8859-5" => "ISO-8859-5",
- "iso-8859-6" => "ISO-8859-6",
- "iso-8859-7" => "ISO-8859-7",
- "iso-8859-8" => "ISO-8859-8",
- "iso-8859-8-i" => "ISO-8859-8-I",
- "iso-8859-10" => "ISO-8859-10",
- "iso-8859-13" => "ISO-8859-13",
- "iso-8859-14" => "ISO-8859-14",
- "iso-8859-15" => "ISO-8859-15",
- "iso-8859-16" => "ISO-8859-16",
- "koi8-r" => "KOI8-R",
- "koi8-u" => "KOI8-U",
- "gbk" => "GBK",
- "big5" => "Big5",
- "euc-jp" => "EUC-JP",
- "iso-2022-jp" => "ISO-2022-JP",
- "shift_jis" => "Shift_JIS",
- "euc-kr" => "EUC-KR",
- "utf-16be" => "UTF-16BE",
- "utf-16le" => "UTF-16LE",
- _ => &*name
- });
+ pub fn encoding(&self) -> EncodingRef {
+ self.encoding.get()
+ }
+
+ pub fn set_encoding(&self, encoding: EncodingRef) {
+ self.encoding.set(encoding);
}
pub fn content_changed(&self, node: &Node, damage: NodeDamage) {
@@ -1562,7 +1535,7 @@ impl Document {
// https://dom.spec.whatwg.org/#concept-document-quirks
quirks_mode: Cell::new(NoQuirks),
// https://dom.spec.whatwg.org/#concept-document-encoding
- encoding_name: DOMRefCell::new(DOMString::from("UTF-8")),
+ encoding: Cell::new(UTF_8),
is_html_document: is_html_document == IsHTMLDocument::HTMLDocument,
id_map: DOMRefCell::new(HashMap::new()),
tag_map: DOMRefCell::new(HashMap::new()),
@@ -1663,11 +1636,11 @@ impl Document {
}
/// Returns the list of stylesheets associated with nodes in the document.
- pub fn stylesheets(&self) -> Ref<Vec<Arc<Stylesheet>>> {
+ pub fn stylesheets(&self) -> Vec<Arc<Stylesheet>> {
{
let mut stylesheets = self.stylesheets.borrow_mut();
if stylesheets.is_none() {
- let new_stylesheets: Vec<Arc<Stylesheet>> = self.upcast::<Node>()
+ *stylesheets = Some(self.upcast::<Node>()
.traverse_preorder()
.filter_map(|node| {
if let Some(node) = node.downcast::<HTMLStyleElement>() {
@@ -1678,13 +1651,14 @@ impl Document {
node.get_stylesheet()
} else {
None
- }
+ }.map(|stylesheet| (JS::from_rooted(&node), stylesheet))
})
- .collect();
- *stylesheets = Some(new_stylesheets);
+ .collect());
};
}
- Ref::map(self.stylesheets.borrow(), |t| t.as_ref().unwrap())
+ self.stylesheets.borrow().as_ref().unwrap().iter()
+ .map(|&(_, ref stylesheet)| stylesheet.clone())
+ .collect()
}
/// https://html.spec.whatwg.org/multipage/#appropriate-template-contents-owner-document
@@ -1800,12 +1774,6 @@ impl DocumentMethods for Document {
fn Domain(&self) -> DOMString {
// TODO: This should use the effective script origin when it exists
let origin = self.window.get_url();
-
- if let Some(&Host::Ipv6(ipv6)) = origin.host() {
- // Omit square brackets for IPv6 addresses.
- return DOMString::from(ipv6.to_string());
- }
-
DOMString::from(origin.serialize_host().unwrap_or_else(|| "".to_owned()))
}
@@ -1824,7 +1792,34 @@ impl DocumentMethods for Document {
// https://dom.spec.whatwg.org/#dom-document-characterset
fn CharacterSet(&self) -> DOMString {
- self.encoding_name.borrow().clone()
+ DOMString::from(match self.encoding.get().name() {
+ "utf-8" => "UTF-8",
+ "ibm866" => "IBM866",
+ "iso-8859-2" => "ISO-8859-2",
+ "iso-8859-3" => "ISO-8859-3",
+ "iso-8859-4" => "ISO-8859-4",
+ "iso-8859-5" => "ISO-8859-5",
+ "iso-8859-6" => "ISO-8859-6",
+ "iso-8859-7" => "ISO-8859-7",
+ "iso-8859-8" => "ISO-8859-8",
+ "iso-8859-8-i" => "ISO-8859-8-I",
+ "iso-8859-10" => "ISO-8859-10",
+ "iso-8859-13" => "ISO-8859-13",
+ "iso-8859-14" => "ISO-8859-14",
+ "iso-8859-15" => "ISO-8859-15",
+ "iso-8859-16" => "ISO-8859-16",
+ "koi8-r" => "KOI8-R",
+ "koi8-u" => "KOI8-U",
+ "gbk" => "GBK",
+ "big5" => "Big5",
+ "euc-jp" => "EUC-JP",
+ "iso-2022-jp" => "ISO-2022-JP",
+ "shift_jis" => "Shift_JIS",
+ "euc-kr" => "EUC-KR",
+ "utf-16be" => "UTF-16BE",
+ "utf-16le" => "UTF-16LE",
+ name => name
+ })
}
// https://dom.spec.whatwg.org/#dom-document-charset
diff --git a/components/script/dom/domtokenlist.rs b/components/script/dom/domtokenlist.rs
index f74887d0899..3968b2084cb 100644
--- a/components/script/dom/domtokenlist.rs
+++ b/components/script/dom/domtokenlist.rs
@@ -139,6 +139,32 @@ impl DOMTokenListMethods for DOMTokenList {
self.element.set_tokenlist_attribute(&self.local_name, value);
}
+ // https://dom.spec.whatwg.org/#dom-domtokenlist-replace
+ fn Replace(&self, token: DOMString, new_token: DOMString) -> ErrorResult {
+ if token.is_empty() || new_token.is_empty() {
+ // Step 1.
+ return Err(Error::Syntax);
+ }
+ if token.contains(HTML_SPACE_CHARACTERS) || new_token.contains(HTML_SPACE_CHARACTERS) {
+ // Step 2.
+ return Err(Error::InvalidCharacter);
+ }
+ // Steps 3-4.
+ let token = Atom::from(token);
+ let new_token = Atom::from(new_token);
+ let mut atoms = self.element.get_tokenlist_attribute(&self.local_name);
+ if let Some(pos) = atoms.iter().position(|atom| *atom == token) {
+ if !atoms.contains(&new_token) {
+ atoms[pos] = new_token;
+ } else {
+ atoms.remove(pos);
+ }
+ }
+ // Step 5.
+ self.element.set_atomic_tokenlist_attribute(&self.local_name, atoms);
+ Ok(())
+ }
+
// https://dom.spec.whatwg.org/#concept-dtl-serialize
fn Stringifier(&self) -> DOMString {
self.element.get_string_attribute(&self.local_name)
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index 25d9f0d45b8..677f9acda0e 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -47,7 +47,9 @@ use dom::htmlimageelement::{HTMLImageElement, LayoutHTMLImageElementHelpers};
use dom::htmlinputelement::{HTMLInputElement, LayoutHTMLInputElementHelpers};
use dom::htmllabelelement::HTMLLabelElement;
use dom::htmllegendelement::HTMLLegendElement;
+use dom::htmlobjectelement::HTMLObjectElement;
use dom::htmloptgroupelement::HTMLOptGroupElement;
+use dom::htmlselectelement::HTMLSelectElement;
use dom::htmltablecellelement::{HTMLTableCellElement, HTMLTableCellElementLayoutHelpers};
use dom::htmltableelement::{HTMLTableElement, HTMLTableElementLayoutHelpers};
use dom::htmltablerowelement::{HTMLTableRowElement, HTMLTableRowElementLayoutHelpers};
@@ -60,6 +62,7 @@ use dom::node::{NodeDamage, SEQUENTIALLY_FOCUSABLE, UnbindContext};
use dom::node::{document_from_node, window_from_node};
use dom::nodelist::NodeList;
use dom::text::Text;
+use dom::validation::Validatable;
use dom::virtualmethods::{VirtualMethods, vtable_for};
use html5ever::serialize;
use html5ever::serialize::SerializeOpts;
@@ -1075,7 +1078,7 @@ impl Element {
}
let url = self.get_string_attribute(local_name);
let doc = document_from_node(self);
- let base = doc.url();
+ let base = doc.base_url();
// https://html.spec.whatwg.org/multipage/#reflect
// XXXManishearth this doesn't handle `javascript:` urls properly
match base.join(&url) {
@@ -1165,6 +1168,35 @@ impl Element {
let node = self.upcast::<Node>();
node.owner_doc().element_attr_will_change(self);
}
+
+ // https://dom.spec.whatwg.org/#insert-adjacent
+ pub fn insert_adjacent(&self, where_: DOMString, node: &Node)
+ -> Fallible<Option<Root<Node>>> {
+ let self_node = self.upcast::<Node>();
+ match &*where_ {
+ "beforebegin" => {
+ if let Some(parent) = self_node.GetParentNode() {
+ Node::pre_insert(node, &parent, Some(self_node)).map(Some)
+ } else {
+ Ok(None)
+ }
+ }
+ "afterbegin" => {
+ Node::pre_insert(node, &self_node, self_node.GetFirstChild().r()).map(Some)
+ }
+ "beforeend" => {
+ Node::pre_insert(node, &self_node, None).map(Some)
+ }
+ "afterend" => {
+ if let Some(parent) = self_node.GetParentNode() {
+ Node::pre_insert(node, &parent, self_node.GetNextSibling().r()).map(Some)
+ } else {
+ Ok(None)
+ }
+ }
+ _ => Err(Error::Syntax)
+ }
+ }
}
impl ElementMethods for Element {
@@ -1617,6 +1649,23 @@ impl ElementMethods for Element {
}
}
}
+
+ // https://dom.spec.whatwg.org/#dom-element-insertadjacentelement
+ fn InsertAdjacentElement(&self, where_: DOMString, element: &Element)
+ -> Fallible<Option<Root<Element>>> {
+ let inserted_node = try!(self.insert_adjacent(where_, element.upcast()));
+ Ok(inserted_node.map(|node| Root::downcast(node).unwrap()))
+ }
+
+ // https://dom.spec.whatwg.org/#dom-element-insertadjacenttext
+ fn InsertAdjacentText(&self, where_: DOMString, data: DOMString)
+ -> ErrorResult {
+ // Step 1.
+ let text = Text::new(data, &document_from_node(self));
+
+ // Step 2.
+ self.insert_adjacent(where_, text.upcast()).map(|_| ())
+ }
}
pub fn fragment_affecting_attributes() -> [Atom; 3] {
@@ -1913,6 +1962,36 @@ impl Element {
})
}
+ // https://html.spec.whatwg.org/multipage/#category-submit
+ pub fn as_maybe_validatable(&self) -> Option<&Validatable> {
+ let element = match self.upcast::<Node>().type_id() {
+ NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement)) => {
+ let element = self.downcast::<HTMLInputElement>().unwrap();
+ Some(element as &Validatable)
+ },
+ NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLButtonElement)) => {
+ let element = self.downcast::<HTMLButtonElement>().unwrap();
+ Some(element as &Validatable)
+ },
+ NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLObjectElement)) => {
+ let element = self.downcast::<HTMLObjectElement>().unwrap();
+ Some(element as &Validatable)
+ },
+ NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLSelectElement)) => {
+ let element = self.downcast::<HTMLSelectElement>().unwrap();
+ Some(element as &Validatable)
+ },
+ NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTextAreaElement)) => {
+ let element = self.downcast::<HTMLTextAreaElement>().unwrap();
+ Some(element as &Validatable)
+ },
+ _ => {
+ None
+ }
+ };
+ element
+ }
+
pub fn click_in_progress(&self) -> bool {
self.upcast::<Node>().get_flag(CLICK_IN_PROGRESS)
}
diff --git a/components/script/dom/errorevent.rs b/components/script/dom/errorevent.rs
index c9d5a79b0fd..763fa823d17 100644
--- a/components/script/dom/errorevent.rs
+++ b/components/script/dom/errorevent.rs
@@ -60,8 +60,8 @@ impl ErrorEvent {
let ev = ErrorEvent::new_uninitialized(global);
{
let event = ev.upcast::<Event>();
- event.init_event(type_, bubbles == EventBubbles::Bubbles,
- cancelable == EventCancelable::Cancelable);
+ event.init_event(type_, bool::from(bubbles),
+ bool::from(cancelable));
*ev.message.borrow_mut() = message;
*ev.filename.borrow_mut() = filename;
ev.lineno.set(lineno);
@@ -88,13 +88,9 @@ impl ErrorEvent {
let col_num = init.colno.unwrap_or(0);
- let bubbles = if init.parent.bubbles { EventBubbles::Bubbles } else { EventBubbles::DoesNotBubble };
+ let bubbles = EventBubbles::from(init.parent.bubbles);
- let cancelable = if init.parent.cancelable {
- EventCancelable::Cancelable
- } else {
- EventCancelable::NotCancelable
- };
+ let cancelable = EventCancelable::from(init.parent.cancelable);
// Dictionaries need to be rooted
// https://github.com/servo/servo/issues/6381
diff --git a/components/script/dom/event.rs b/components/script/dom/event.rs
index 5aa97872647..97fc065d2b1 100644
--- a/components/script/dom/event.rs
+++ b/components/script/dom/event.rs
@@ -32,12 +32,48 @@ pub enum EventBubbles {
DoesNotBubble
}
+impl From<EventBubbles> for bool {
+ fn from(bubbles: EventBubbles) -> Self {
+ match bubbles {
+ EventBubbles::Bubbles => true,
+ EventBubbles::DoesNotBubble => false
+ }
+ }
+}
+
+impl From<bool> for EventBubbles {
+ fn from(boolean: bool) -> Self {
+ match boolean {
+ true => EventBubbles::Bubbles,
+ false => EventBubbles::DoesNotBubble
+ }
+ }
+}
+
#[derive(PartialEq, HeapSizeOf)]
pub enum EventCancelable {
Cancelable,
NotCancelable
}
+impl From<EventCancelable> for bool {
+ fn from(bubbles: EventCancelable) -> Self {
+ match bubbles {
+ EventCancelable::Cancelable => true,
+ EventCancelable::NotCancelable => false
+ }
+ }
+}
+
+impl From<bool> for EventCancelable {
+ fn from(boolean: bool) -> Self {
+ match boolean {
+ true => EventCancelable::Cancelable,
+ false => EventCancelable::NotCancelable
+ }
+ }
+}
+
#[dom_struct]
pub struct Event {
reflector_: Reflector,
@@ -87,15 +123,15 @@ impl Event {
bubbles: EventBubbles,
cancelable: EventCancelable) -> Root<Event> {
let event = Event::new_uninitialized(global);
- event.init_event(type_, bubbles == EventBubbles::Bubbles, cancelable == EventCancelable::Cancelable);
+ event.init_event(type_, bool::from(bubbles), bool::from(cancelable));
event
}
pub fn Constructor(global: GlobalRef,
type_: DOMString,
init: &EventBinding::EventInit) -> Fallible<Root<Event>> {
- let bubbles = if init.bubbles { EventBubbles::Bubbles } else { EventBubbles::DoesNotBubble };
- let cancelable = if init.cancelable { EventCancelable::Cancelable } else { EventCancelable::NotCancelable };
+ let bubbles = EventBubbles::from(init.bubbles);
+ let cancelable = EventCancelable::from(init.cancelable);
Ok(Event::new(global, Atom::from(type_), bubbles, cancelable))
}
diff --git a/components/script/dom/focusevent.rs b/components/script/dom/focusevent.rs
index 5ad61305637..84259749295 100644
--- a/components/script/dom/focusevent.rs
+++ b/components/script/dom/focusevent.rs
@@ -41,8 +41,8 @@ impl FocusEvent {
let event = box FocusEvent::new_inherited();
let ev = reflect_dom_object(event, GlobalRef::Window(window), FocusEventBinding::Wrap);
ev.upcast::<UIEvent>().InitUIEvent(type_,
- can_bubble == EventBubbles::Bubbles,
- cancelable == EventCancelable::Cancelable,
+ bool::from(can_bubble),
+ bool::from(cancelable),
view, detail);
ev.related_target.set(related_target);
ev
@@ -51,16 +51,8 @@ impl FocusEvent {
pub fn Constructor(global: GlobalRef,
type_: DOMString,
init: &FocusEventBinding::FocusEventInit) -> Fallible<Root<FocusEvent>> {
- let bubbles = if init.parent.parent.bubbles {
- EventBubbles::Bubbles
- } else {
- EventBubbles::DoesNotBubble
- };
- let cancelable = if init.parent.parent.cancelable {
- EventCancelable::Cancelable
- } else {
- EventCancelable::NotCancelable
- };
+ let bubbles = EventBubbles::from(init.parent.parent.bubbles);
+ let cancelable = EventCancelable::from(init.parent.parent.cancelable);
let event = FocusEvent::new(global.as_window(), type_,
bubbles,
cancelable,
diff --git a/components/script/dom/htmlanchorelement.rs b/components/script/dom/htmlanchorelement.rs
index 0a1e15ef193..16f47315b76 100644
--- a/components/script/dom/htmlanchorelement.rs
+++ b/components/script/dom/htmlanchorelement.rs
@@ -5,6 +5,7 @@
use dom::activation::Activatable;
use dom::attr::AttrValue;
+use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
use dom::bindings::codegen::Bindings::HTMLAnchorElementBinding;
use dom::bindings::codegen::Bindings::HTMLAnchorElementBinding::HTMLAnchorElementMethods;
@@ -12,6 +13,7 @@ use dom::bindings::codegen::Bindings::MouseEventBinding::MouseEventMethods;
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, MutNullableHeap, Root};
+use dom::bindings::str::USVString;
use dom::document::Document;
use dom::domtokenlist::DOMTokenList;
use dom::element::Element;
@@ -21,16 +23,19 @@ use dom::htmlelement::HTMLElement;
use dom::htmlimageelement::HTMLImageElement;
use dom::mouseevent::MouseEvent;
use dom::node::{Node, document_from_node, window_from_node};
+use dom::urlhelper::UrlHelper;
use dom::virtualmethods::VirtualMethods;
use num::ToPrimitive;
use std::default::Default;
use string_cache::Atom;
+use url::{Url, UrlParser};
use util::str::DOMString;
#[dom_struct]
pub struct HTMLAnchorElement {
htmlelement: HTMLElement,
rel_list: MutNullableHeap<JS<DOMTokenList>>,
+ url: DOMRefCell<Option<Url>>,
}
impl HTMLAnchorElement {
@@ -41,6 +46,7 @@ impl HTMLAnchorElement {
htmlelement:
HTMLElement::new_inherited(localName, prefix, document),
rel_list: Default::default(),
+ url: DOMRefCell::new(None),
}
}
@@ -51,6 +57,37 @@ impl HTMLAnchorElement {
let element = HTMLAnchorElement::new_inherited(localName, prefix, document);
Node::reflect_node(box element, document, HTMLAnchorElementBinding::Wrap)
}
+
+ // https://html.spec.whatwg.org/multipage/#concept-hyperlink-url-set
+ fn set_url(&self) {
+ let attribute = self.upcast::<Element>().get_attribute(&ns!(), &atom!("href"));
+ *self.url.borrow_mut() = attribute.and_then(|attribute| {
+ let document = document_from_node(self);
+ let mut parser = UrlParser::new();
+ parser.base_url(document.url());
+ parser.parse(&attribute.value()).ok()
+ });
+ }
+
+ // https://html.spec.whatwg.org/multipage/#reinitialise-url
+ fn reinitialize_url(&self) {
+ // Step 1.
+ match *self.url.borrow() {
+ None => return,
+ Some(ref url) if url.scheme == "blob" &&
+ url.non_relative_scheme_data().is_some() => return,
+ _ => (),
+ }
+
+ // Step 2.
+ self.set_url();
+ }
+
+ // https://html.spec.whatwg.org/multipage/#update-href
+ fn update_href(&self) {
+ self.upcast::<Element>().set_string_attribute(&atom!("href"),
+ self.url.borrow().as_ref().unwrap().serialize().into());
+ }
}
impl VirtualMethods for HTMLAnchorElement {
@@ -107,6 +144,312 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
// https://html.spec.whatwg.org/multipage/#dom-a-shape
make_setter!(SetShape, "shape");
+
+ // https://html.spec.whatwg.org/multipage/#dom-hyperlink-hash
+ fn Hash(&self) -> USVString {
+ // Step 1.
+ self.reinitialize_url();
+
+ match *self.url.borrow() {
+ // Step 3.
+ None => USVString(String::new()),
+ Some(ref url) => {
+ // Steps 3-4.
+ UrlHelper::Hash(url)
+ }
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-hyperlink-hash
+ fn SetHash(&self, value: USVString) {
+ // Step 1.
+ self.reinitialize_url();
+
+ // Step 3.
+ if let Some(url) = self.url.borrow_mut().as_mut() {
+ if url.scheme == "javascript" { return; }
+ // Steps 4-5.
+ UrlHelper::SetHash(url, value);
+ // Step 6.
+ self.update_href();
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-hyperlink-host
+ fn Host(&self) -> USVString {
+ // Step 1.
+ self.reinitialize_url();
+
+ match *self.url.borrow() {
+ // Step 3.
+ None => USVString(String::new()),
+ Some(ref url) => {
+ if url.host().is_none() {
+ USVString(String::new())
+ } else {
+ // Steps 4-5.
+ UrlHelper::Host(url)
+ }
+ }
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-hyperlink-host
+ fn SetHost(&self, value: USVString) {
+ // Step 1.
+ self.reinitialize_url();
+
+ // Step 3.
+ if let Some(url) = self.url.borrow_mut().as_mut() {
+ if url.non_relative_scheme_data().is_some() {
+ return;
+ }
+ // Step 4.
+ UrlHelper::SetHost(url, value);
+ // Step 5.
+ self.update_href();
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-hyperlink-hostname
+ fn Hostname(&self) -> USVString {
+ // Step 1.
+ self.reinitialize_url();
+
+ match *self.url.borrow() {
+ // Step 3.
+ None => USVString(String::new()),
+ Some(ref url) => {
+ // Step 4.
+ UrlHelper::Hostname(url)
+ }
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-hyperlink-hostname
+ fn SetHostname(&self, value: USVString) {
+ // Step 1.
+ self.reinitialize_url();
+
+ // Step 3.
+ if let Some(url) = self.url.borrow_mut().as_mut() {
+ if url.non_relative_scheme_data().is_some() {
+ return;
+ }
+ // Step 4.
+ UrlHelper::SetHostname(url, value);
+ // Step 5.
+ self.update_href();
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-hyperlink-href
+ fn Href(&self) -> USVString {
+ // Step 1.
+ self.reinitialize_url();
+
+ USVString(match *self.url.borrow() {
+ None => {
+ match self.upcast::<Element>().get_attribute(&ns!(), &atom!("href")) {
+ // Step 3.
+ None => String::new(),
+ // Step 4.
+ Some(attribute) => (**attribute.value()).to_owned(),
+ }
+ },
+ // Step 5.
+ Some(ref url) => url.serialize(),
+ })
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-hyperlink-href
+ fn SetHref(&self, value: USVString) {
+ self.upcast::<Element>().set_string_attribute(&atom!("href"),
+ DOMString::from_string(value.0));
+ self.set_url();
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-hyperlink-password
+ fn Password(&self) -> USVString {
+ // Step 1.
+ self.reinitialize_url();
+
+ match *self.url.borrow() {
+ // Step 3.
+ None => USVString(String::new()),
+ // Steps 3-4.
+ Some(ref url) => UrlHelper::Password(url)
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-hyperlink-password
+ fn SetPassword(&self, value: USVString) {
+ // Step 1.
+ self.reinitialize_url();
+
+ // Step 3.
+ if let Some(url) = self.url.borrow_mut().as_mut() {
+ if url.host().is_none() || url.non_relative_scheme_data().is_some() {
+ return;
+ }
+ // Step 4.
+ UrlHelper::SetPassword(url, value);
+ // Step 5.
+ self.update_href();
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-hyperlink-pathname
+ fn Pathname(&self) -> USVString {
+ // Step 1.
+ self.reinitialize_url();
+
+ match *self.url.borrow() {
+ // Step 3.
+ None => USVString(String::new()),
+ // Steps 4-5.
+ Some(ref url) => UrlHelper::Pathname(url)
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-hyperlink-pathname
+ fn SetPathname(&self, value: USVString) {
+ // Step 1.
+ self.reinitialize_url();
+
+ // Step 3.
+ if let Some(url) = self.url.borrow_mut().as_mut() {
+ if url.non_relative_scheme_data().is_some() { return; }
+ // Step 5.
+ UrlHelper::SetPathname(url, value);
+ // Step 6.
+ self.update_href();
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-hyperlink-port
+ fn Port(&self) -> USVString {
+ // Step 1.
+ self.reinitialize_url();
+
+ match *self.url.borrow() {
+ // Step 3.
+ None => USVString(String::new()),
+ // Step 4.
+ Some(ref url) => UrlHelper::Port(url)
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-hyperlink-port
+ fn SetPort(&self, value: USVString) {
+ // Step 1.
+ self.reinitialize_url();
+
+ // Step 3.
+ if let Some(url) = self.url.borrow_mut().as_mut() {
+ if url.host().is_none() ||
+ url.non_relative_scheme_data().is_some() ||
+ url.scheme == "file" {
+ return;
+ }
+ // Step 4.
+ UrlHelper::SetPort(url, value);
+ // Step 5.
+ self.update_href();
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-hyperlink-protocol
+ fn Protocol(&self) -> USVString {
+ // Step 1.
+ self.reinitialize_url();
+
+ match *self.url.borrow() {
+ // Step 2.
+ None => USVString(":".to_owned()),
+ // Step 3.
+ Some(ref url) => UrlHelper::Protocol(url)
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-hyperlink-protocol
+ fn SetProtocol(&self, value: USVString) {
+ // Step 1.
+ self.reinitialize_url();
+
+ // Step 2.
+ if let Some(url) = self.url.borrow_mut().as_mut() {
+ // Step 3.
+ UrlHelper::SetProtocol(url, value);
+ // Step 4.
+ self.update_href();
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-hyperlink-search
+ fn Search(&self) -> USVString {
+ // Step 1.
+ self.reinitialize_url();
+
+ match *self.url.borrow() {
+ // Step 2.
+ None => USVString(String::new()),
+ // Step 3.
+ Some(ref url) => UrlHelper::Search(url)
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-hyperlink-search
+ fn SetSearch(&self, value: USVString) {
+ // Step 1.
+ self.reinitialize_url();
+
+ // Step 3.
+ if let Some(url) = self.url.borrow_mut().as_mut() {
+ // Steps 4-5.
+ // TODO add this element's node document character encoding as
+ // encoding override (as described in the spec)
+ UrlHelper::SetSearch(url, value);
+ // Step 6.
+ self.update_href();
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-hyperlink-username
+ fn Username(&self) -> USVString {
+ // Step 1.
+ self.reinitialize_url();
+
+ match *self.url.borrow() {
+ // Step 2.
+ None => USVString(String::new()),
+ // Step 3.
+ Some(ref url) => UrlHelper::Username(url)
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-hyperlink-username
+ fn SetUsername(&self, value: USVString) {
+ // Step 1.
+ self.reinitialize_url();
+
+ // Step 3.
+ if let Some(url) = self.url.borrow_mut().as_mut() {
+ if url.host().is_none() || url.non_relative_scheme_data().is_some() {
+ return;
+ }
+
+ // Step 4.
+ UrlHelper::SetUsername(url, value);
+ // Step 5.
+ self.update_href();
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-hyperlink-href
+ fn Stringifier(&self) -> DOMString {
+ DOMString::from(self.Href().0)
+ }
}
impl Activatable for HTMLAnchorElement {
diff --git a/components/script/dom/htmlbuttonelement.rs b/components/script/dom/htmlbuttonelement.rs
index 661fb3d6f68..342d4173343 100644
--- a/components/script/dom/htmlbuttonelement.rs
+++ b/components/script/dom/htmlbuttonelement.rs
@@ -18,6 +18,7 @@ use dom::htmlformelement::{FormControl, FormSubmitter, ResetFrom};
use dom::htmlformelement::{SubmittedFrom, HTMLFormElement};
use dom::node::{Node, UnbindContext, document_from_node, window_from_node};
use dom::nodelist::NodeList;
+use dom::validation::Validatable;
use dom::validitystate::ValidityState;
use dom::virtualmethods::VirtualMethods;
use std::ascii::AsciiExt;
@@ -66,7 +67,7 @@ impl HTMLButtonElementMethods for HTMLButtonElement {
// https://html.spec.whatwg.org/multipage/#dom-cva-validity
fn Validity(&self) -> Root<ValidityState> {
let window = window_from_node(self);
- ValidityState::new(window.r())
+ ValidityState::new(window.r(), self.upcast())
}
// https://html.spec.whatwg.org/multipage/#dom-fe-disabled
@@ -203,6 +204,8 @@ impl VirtualMethods for HTMLButtonElement {
impl FormControl for HTMLButtonElement {}
+impl Validatable for HTMLButtonElement {}
+
impl Activatable for HTMLButtonElement {
fn as_element(&self) -> &Element {
self.upcast()
diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs
index 0288efc206a..622824f88d9 100644
--- a/components/script/dom/htmlcanvaselement.rs
+++ b/components/script/dom/htmlcanvaselement.rs
@@ -94,7 +94,6 @@ impl HTMLCanvasElement {
}
pub struct HTMLCanvasData {
- pub renderer_id: Option<usize>,
pub ipc_renderer: Option<IpcSender<CanvasMsg>>,
pub width: u32,
pub height: u32,
@@ -109,22 +108,20 @@ impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> {
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),
- };
+ let ipc_renderer = canvas.context.borrow_for_layout().as_ref().map(|context| {
+ match *context {
+ CanvasContext::Context2d(ref context) => {
+ context.to_layout().get_ipc_renderer()
+ },
+ CanvasContext::WebGL(ref context) => {
+ context.to_layout().get_ipc_renderer()
+ },
+ }
+ });
let width_attr = canvas.upcast::<Element>().get_attr_for_layout(&ns!(), &atom!("width"));
let height_attr = canvas.upcast::<Element>().get_attr_for_layout(&ns!(), &atom!("height"));
HTMLCanvasData {
- renderer_id: renderer_id,
ipc_renderer: ipc_renderer,
width: width_attr.map_or(DEFAULT_WIDTH, |val| val.as_uint()),
height: height_attr.map_or(DEFAULT_HEIGHT, |val| val.as_uint()),
@@ -209,7 +206,7 @@ impl HTMLCanvasElement {
CanvasData::Pixels(pixel_data)
=> pixel_data.image_data.to_vec(),
CanvasData::WebGL(_)
- // TODO(ecoal95): Not sure if WebGL canvas is required for 2d spec,
+ // TODO(emilio): Not sure if WebGL canvas is required for 2d spec,
// but I think it's not.
=> return None,
}
diff --git a/components/script/dom/htmlcollection.rs b/components/script/dom/htmlcollection.rs
index d36fb177e7b..25e17586f9b 100644
--- a/components/script/dom/htmlcollection.rs
+++ b/components/script/dom/htmlcollection.rs
@@ -11,7 +11,7 @@ use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::bindings::trace::JSTraceable;
use dom::bindings::xmlname::namespace_from_domstring;
use dom::element::Element;
-use dom::node::{Node, FollowingNodeIterator, PrecedingNodeIterator};
+use dom::node::Node;
use dom::window::Window;
use std::ascii::AsciiExt;
use std::cell::Cell;
@@ -208,7 +208,7 @@ impl HTMLCollection {
pub fn elements_iter_after(&self, after: &Node) -> HTMLCollectionElementsIter {
// Iterate forwards from a node.
HTMLCollectionElementsIter {
- node_iter: after.following_nodes(&self.root),
+ node_iter: box after.following_nodes(&self.root),
root: Root::from_ref(&self.root),
filter: &self.filter,
}
@@ -219,10 +219,10 @@ impl HTMLCollection {
self.elements_iter_after(&*self.root)
}
- pub fn elements_iter_before(&self, before: &Node) -> HTMLCollectionElementsRevIter {
+ pub fn elements_iter_before(&self, before: &Node) -> HTMLCollectionElementsIter {
// Iterate backwards from a node.
- HTMLCollectionElementsRevIter {
- node_iter: before.preceding_nodes(&self.root),
+ HTMLCollectionElementsIter {
+ node_iter: box before.preceding_nodes(&self.root),
root: Root::from_ref(&self.root),
filter: &self.filter,
}
@@ -232,7 +232,7 @@ impl HTMLCollection {
// TODO: Make this generic, and avoid code duplication
pub struct HTMLCollectionElementsIter<'a> {
- node_iter: FollowingNodeIterator,
+ node_iter: Box<Iterator<Item = Root<Node>>>,
root: Root<Node>,
filter: &'a Box<CollectionFilter>,
}
@@ -250,25 +250,6 @@ impl<'a> Iterator for HTMLCollectionElementsIter<'a> {
}
}
-pub struct HTMLCollectionElementsRevIter<'a> {
- node_iter: PrecedingNodeIterator,
- root: Root<Node>,
- filter: &'a Box<CollectionFilter>,
-}
-
-impl<'a> Iterator for HTMLCollectionElementsRevIter<'a> {
- type Item = Root<Element>;
-
- fn next(&mut self) -> Option<Self::Item> {
- let filter = &self.filter;
- let root = &self.root;
- self.node_iter.by_ref()
- .filter_map(Root::downcast)
- .filter(|element| filter.filter(&element, root))
- .next()
- }
-}
-
impl HTMLCollectionMethods for HTMLCollection {
// https://dom.spec.whatwg.org/#dom-htmlcollection-length
fn Length(&self) -> u32 {
diff --git a/components/script/dom/htmlfieldsetelement.rs b/components/script/dom/htmlfieldsetelement.rs
index 0390d9aa599..b9800dcd1f1 100644
--- a/components/script/dom/htmlfieldsetelement.rs
+++ b/components/script/dom/htmlfieldsetelement.rs
@@ -64,7 +64,7 @@ impl HTMLFieldSetElementMethods for HTMLFieldSetElement {
// https://html.spec.whatwg.org/multipage/#dom-cva-validity
fn Validity(&self) -> Root<ValidityState> {
let window = window_from_node(self);
- ValidityState::new(window.r())
+ ValidityState::new(window.r(), self.upcast())
}
// https://html.spec.whatwg.org/multipage/#dom-fieldset-disabled
diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs
index 4cf2c3f467e..4e7e6108785 100644
--- a/components/script/dom/htmliframeelement.rs
+++ b/components/script/dom/htmliframeelement.rs
@@ -6,6 +6,7 @@ use document_loader::{LoadType, LoadBlocker};
use dom::attr::{Attr, AttrValue};
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::BrowserElementBinding::BrowserElementIconChangeEventDetail;
+use dom::bindings::codegen::Bindings::BrowserElementBinding::BrowserElementLocationChangeEventDetail;
use dom::bindings::codegen::Bindings::BrowserElementBinding::BrowserElementSecurityChangeDetail;
use dom::bindings::codegen::Bindings::BrowserElementBinding::BrowserShowModalPromptEventDetail;
use dom::bindings::codegen::Bindings::HTMLIFrameElementBinding;
@@ -27,6 +28,7 @@ use dom::node::{Node, UnbindContext, window_from_node, document_from_node};
use dom::urlhelper::UrlHelper;
use dom::virtualmethods::VirtualMethods;
use dom::window::{ReflowReason, Window};
+use ipc_channel::ipc;
use js::jsapi::{JSAutoCompartment, JSAutoRequest, RootedValue, JSContext, MutableHandleValue};
use js::jsval::{UndefinedValue, NullValue};
use layout_interface::ReflowQueryType;
@@ -323,9 +325,16 @@ impl MozBrowserEventDetailBuilder for HTMLIFrameElement {
mixedState: None,
}.to_jsval(cx, rval);
}
- MozBrowserEvent::LocationChange(ref string) | MozBrowserEvent::TitleChange(ref string) => {
+ MozBrowserEvent::TitleChange(ref string) => {
string.to_jsval(cx, rval);
}
+ MozBrowserEvent::LocationChange(uri, can_go_back, can_go_forward) => {
+ BrowserElementLocationChangeEventDetail {
+ uri: Some(DOMString::from(uri)),
+ canGoBack: Some(can_go_back),
+ canGoForward: Some(can_go_forward),
+ }.to_jsval(cx, rval);
+ }
MozBrowserEvent::IconChange(rel, href, sizes) => {
BrowserElementIconChangeEventDetail {
rel: Some(DOMString::from(rel)),
@@ -551,9 +560,30 @@ impl VirtualMethods for HTMLIFrameElement {
let window = window_from_node(self);
let window = window.r();
+ // The only reason we're waiting for the iframe to be totally
+ // removed is to ensure the script thread can't add iframes faster
+ // than the compositor can remove them.
+ //
+ // Since most of this cleanup doesn't happen on same-origin
+ // iframes, and since that would cause a deadlock, don't do it.
let ConstellationChan(ref chan) = window.constellation_chan();
- let msg = ConstellationMsg::RemoveIFrame(pipeline_id);
+ let same_origin = if let Some(self_url) = self.get_url() {
+ let win_url = window_from_node(self).get_url();
+ UrlHelper::SameOrigin(&self_url, &win_url)
+ } else {
+ false
+ };
+ let (sender, receiver) = if same_origin {
+ (None, None)
+ } else {
+ let (sender, receiver) = ipc::channel().unwrap();
+ (Some(sender), Some(receiver))
+ };
+ let msg = ConstellationMsg::RemoveIFrame(pipeline_id, sender);
chan.send(msg).unwrap();
+ if let Some(receiver) = receiver {
+ receiver.recv().unwrap()
+ }
// Resetting the subpage id to None is required here so that
// if this iframe is subsequently re-added to the document
diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs
index 03c3bf83d0c..e14a91ae9d7 100644
--- a/components/script/dom/htmlinputelement.rs
+++ b/components/script/dom/htmlinputelement.rs
@@ -28,8 +28,10 @@ use dom::keyboardevent::KeyboardEvent;
use dom::node::{Node, NodeDamage, UnbindContext};
use dom::node::{document_from_node, window_from_node};
use dom::nodelist::NodeList;
+use dom::validation::Validatable;
use dom::virtualmethods::VirtualMethods;
use msg::constellation_msg::ConstellationChan;
+use range::Range;
use script_thread::ScriptThreadEventCategory::InputEvent;
use script_thread::{CommonScriptMsg, Runnable};
use script_traits::ScriptMsg as ConstellationMsg;
@@ -208,7 +210,7 @@ pub trait LayoutHTMLInputElementHelpers {
#[allow(unsafe_code)]
unsafe fn get_size_for_layout(self) -> u32;
#[allow(unsafe_code)]
- unsafe fn get_insertion_point_index_for_layout(self) -> Option<isize>;
+ unsafe fn get_selection_for_layout(self) -> Option<Range<isize>>;
#[allow(unsafe_code)]
unsafe fn get_checked_state_for_layout(self) -> bool;
#[allow(unsafe_code)]
@@ -241,7 +243,7 @@ impl LayoutHTMLInputElementHelpers for LayoutJS<HTMLInputElement> {
InputType::InputPassword => {
let text = get_raw_textinput_value(self);
if !text.is_empty() {
- // The implementation of get_insertion_point_index_for_layout expects a 1:1 mapping of chars.
+ // The implementation of get_selection_for_layout expects a 1:1 mapping of chars.
text.chars().map(|_| '●').collect()
} else {
String::from((*self.unsafe_get()).placeholder.borrow_for_layout().clone())
@@ -250,7 +252,7 @@ impl LayoutHTMLInputElementHelpers for LayoutJS<HTMLInputElement> {
_ => {
let text = get_raw_textinput_value(self);
if !text.is_empty() {
- // The implementation of get_insertion_point_index_for_layout expects a 1:1 mapping of chars.
+ // The implementation of get_selection_for_layout expects a 1:1 mapping of chars.
String::from(text)
} else {
String::from((*self.unsafe_get()).placeholder.borrow_for_layout().clone())
@@ -267,25 +269,24 @@ impl LayoutHTMLInputElementHelpers for LayoutJS<HTMLInputElement> {
#[allow(unrooted_must_root)]
#[allow(unsafe_code)]
- unsafe fn get_insertion_point_index_for_layout(self) -> Option<isize> {
+ unsafe fn get_selection_for_layout(self) -> Option<Range<isize>> {
if !(*self.unsafe_get()).upcast::<Element>().get_focus_state() {
return None;
}
- match (*self.unsafe_get()).input_type.get() {
- InputType::InputText => {
- let raw = self.get_value_for_layout();
- Some(search_index((*self.unsafe_get()).textinput.borrow_for_layout().edit_point.index,
- raw.char_indices()))
- }
- InputType::InputPassword => {
- // Use the raw textinput to get the index as long as we use a 1:1 char mapping
- // in get_input_value_for_layout.
- let raw = get_raw_textinput_value(self);
- Some(search_index((*self.unsafe_get()).textinput.borrow_for_layout().edit_point.index,
- raw.char_indices()))
- }
- _ => None
- }
+
+ // Use the raw textinput to get the index as long as we use a 1:1 char mapping
+ // in get_value_for_layout.
+ let raw = match (*self.unsafe_get()).input_type.get() {
+ InputType::InputText |
+ InputType::InputPassword => get_raw_textinput_value(self),
+ _ => return None
+ };
+ let textinput = (*self.unsafe_get()).textinput.borrow_for_layout();
+ let selection = textinput.get_absolute_selection_range();
+ let begin_byte = selection.begin();
+ let begin = search_index(begin_byte, raw.char_indices());
+ let length = search_index(selection.length(), raw[begin_byte..].char_indices());
+ Some(Range::new(begin, length))
}
#[allow(unrooted_must_root)]
@@ -861,10 +862,6 @@ impl VirtualMethods for HTMLInputElement {
}
if event.type_() == atom!("click") && !event.DefaultPrevented() {
- if let InputType::InputRadio = self.input_type.get() {
- self.update_checked_state(true, true);
- }
-
// TODO: Dispatch events for non activatable inputs
// https://html.spec.whatwg.org/multipage/#common-input-element-events
@@ -908,6 +905,8 @@ impl VirtualMethods for HTMLInputElement {
impl FormControl for HTMLInputElement {}
+impl Validatable for HTMLInputElement {}
+
impl Activatable for HTMLInputElement {
fn as_element(&self) -> &Element {
self.upcast()
diff --git a/components/script/dom/htmllabelelement.rs b/components/script/dom/htmllabelelement.rs
index 7042b98f0d7..90d4a16b86e 100644
--- a/components/script/dom/htmllabelelement.rs
+++ b/components/script/dom/htmllabelelement.rs
@@ -63,12 +63,15 @@ impl Activatable for HTMLLabelElement {
// https://html.spec.whatwg.org/multipage/#run-post-click-activation-steps
fn activation_behavior(&self, _event: &Event, _target: &EventTarget) {
- synthetic_click_activation(self.upcast::<Element>(),
- false,
- false,
- false,
- false,
- ActivationSource::NotFromClick);
+ if let Some(e) = self.GetControl() {
+ let elem = e.upcast::<Element>();
+ synthetic_click_activation(elem,
+ false,
+ false,
+ false,
+ false,
+ ActivationSource::NotFromClick);
+ }
}
// https://html.spec.whatwg.org/multipage/#implicit-submission
diff --git a/components/script/dom/htmlmetaelement.rs b/components/script/dom/htmlmetaelement.rs
index 779c5c79e07..73cc5c73aa0 100644
--- a/components/script/dom/htmlmetaelement.rs
+++ b/components/script/dom/htmlmetaelement.rs
@@ -73,6 +73,9 @@ impl HTMLMetaElement {
rules: vec![CSSRule::Viewport(translated_rule)],
origin: Origin::Author,
media: None,
+ // Viewport constraints are always recomputed on resize; they don't need to
+ // force all styles to be recomputed.
+ dirty_on_viewport_size_change: false,
}));
let doc = document_from_node(self);
doc.invalidate_stylesheets();
diff --git a/components/script/dom/htmlobjectelement.rs b/components/script/dom/htmlobjectelement.rs
index c60c4dd1d13..4d2b1cde778 100644
--- a/components/script/dom/htmlobjectelement.rs
+++ b/components/script/dom/htmlobjectelement.rs
@@ -13,6 +13,7 @@ use dom::element::{AttributeMutation, Element};
use dom::htmlelement::HTMLElement;
use dom::htmlformelement::{FormControl, HTMLFormElement};
use dom::node::{Node, window_from_node};
+use dom::validation::Validatable;
use dom::validitystate::ValidityState;
use dom::virtualmethods::VirtualMethods;
use net_traits::image::base::Image;
@@ -76,7 +77,7 @@ impl HTMLObjectElementMethods for HTMLObjectElement {
// https://html.spec.whatwg.org/multipage/#dom-cva-validity
fn Validity(&self) -> Root<ValidityState> {
let window = window_from_node(self);
- ValidityState::new(window.r())
+ ValidityState::new(window.r(), self.upcast())
}
// https://html.spec.whatwg.org/multipage/#dom-object-type
@@ -91,6 +92,8 @@ impl HTMLObjectElementMethods for HTMLObjectElement {
}
}
+impl Validatable for HTMLObjectElement {}
+
impl VirtualMethods for HTMLObjectElement {
fn super_type(&self) -> Option<&VirtualMethods> {
Some(self.upcast::<HTMLElement>() as &VirtualMethods)
diff --git a/components/script/dom/htmloutputelement.rs b/components/script/dom/htmloutputelement.rs
index 0a018f4217d..b614684b863 100644
--- a/components/script/dom/htmloutputelement.rs
+++ b/components/script/dom/htmloutputelement.rs
@@ -43,7 +43,7 @@ impl HTMLOutputElementMethods for HTMLOutputElement {
// https://html.spec.whatwg.org/multipage/#dom-cva-validity
fn Validity(&self) -> Root<ValidityState> {
let window = window_from_node(self);
- ValidityState::new(window.r())
+ ValidityState::new(window.r(), self.upcast())
}
// https://html.spec.whatwg.org/multipage/#dom-fae-form
diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs
index bbd1884dc4f..eb63d524c9c 100644
--- a/components/script/dom/htmlscriptelement.rs
+++ b/components/script/dom/htmlscriptelement.rs
@@ -25,7 +25,6 @@ use dom::node::{ChildrenMutation, CloneChildrenFlag, Node};
use dom::node::{document_from_node, window_from_node};
use dom::virtualmethods::VirtualMethods;
use dom::window::ScriptHelpers;
-use encoding::all::UTF_8;
use encoding::label::encoding_from_whatwg_label;
use encoding::types::{DecoderTrap, Encoding, EncodingRef};
use html5ever::tree_builder::NextParserState;
@@ -71,7 +70,7 @@ pub struct HTMLScriptElement {
#[ignore_heap_size_of = "Defined in rust-encoding"]
/// https://html.spec.whatwg.org/multipage/#concept-script-encoding
- block_character_encoding: DOMRefCell<EncodingRef>,
+ block_character_encoding: Cell<Option<EncodingRef>>,
}
impl HTMLScriptElement {
@@ -86,7 +85,7 @@ impl HTMLScriptElement {
ready_to_be_parser_executed: Cell::new(false),
parser_document: JS::from_ref(document),
load: DOMRefCell::new(None),
- block_character_encoding: DOMRefCell::new(UTF_8 as EncodingRef),
+ block_character_encoding: Cell::new(None),
}
}
@@ -248,7 +247,7 @@ impl HTMLScriptElement {
// Step 13.
if let Some(ref charset) = element.get_attribute(&ns!(), &atom!("charset")) {
if let Some(encodingRef) = encoding_from_whatwg_label(&charset.Value()) {
- *self.block_character_encoding.borrow_mut() = encodingRef;
+ self.block_character_encoding.set(Some(encodingRef));
}
}
@@ -391,10 +390,16 @@ impl HTMLScriptElement {
// Step 2.b.1.a.
ScriptOrigin::External(Ok((metadata, bytes))) => {
- // TODO(#9185): implement encoding determination.
- (DOMString::from(UTF_8.decode(&*bytes, DecoderTrap::Replace).unwrap()),
- true,
- metadata.final_url)
+ debug!("loading external script, url = {}", metadata.final_url);
+
+ let encoding = metadata.charset
+ .and_then(|encoding| encoding_from_whatwg_label(&encoding))
+ .or_else(|| self.block_character_encoding.get())
+ .unwrap_or_else(|| self.parser_document.encoding());
+
+ (DOMString::from(encoding.decode(&*bytes, DecoderTrap::Replace).unwrap()),
+ true,
+ metadata.final_url)
},
// Step 2.b.1.c.
diff --git a/components/script/dom/htmlselectelement.rs b/components/script/dom/htmlselectelement.rs
index 1b5ddb22183..d42ba617a75 100644
--- a/components/script/dom/htmlselectelement.rs
+++ b/components/script/dom/htmlselectelement.rs
@@ -18,6 +18,7 @@ use dom::htmlformelement::{FormControl, FormDatum, HTMLFormElement};
use dom::htmloptionelement::HTMLOptionElement;
use dom::node::{Node, UnbindContext, window_from_node};
use dom::nodelist::NodeList;
+use dom::validation::Validatable;
use dom::validitystate::ValidityState;
use dom::virtualmethods::VirtualMethods;
use string_cache::Atom;
@@ -130,7 +131,7 @@ impl HTMLSelectElementMethods for HTMLSelectElement {
// https://html.spec.whatwg.org/multipage/#dom-cva-validity
fn Validity(&self) -> Root<ValidityState> {
let window = window_from_node(self);
- ValidityState::new(window.r())
+ ValidityState::new(window.r(), self.upcast())
}
// Note: this function currently only exists for union.html.
@@ -234,3 +235,5 @@ impl VirtualMethods for HTMLSelectElement {
}
impl FormControl for HTMLSelectElement {}
+
+impl Validatable for HTMLSelectElement {}
diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs
index dfcfdc77f73..0f82919124f 100644
--- a/components/script/dom/htmltextareaelement.rs
+++ b/components/script/dom/htmltextareaelement.rs
@@ -23,8 +23,10 @@ use dom::keyboardevent::KeyboardEvent;
use dom::node::{ChildrenMutation, Node, NodeDamage, UnbindContext};
use dom::node::{document_from_node};
use dom::nodelist::NodeList;
+use dom::validation::Validatable;
use dom::virtualmethods::VirtualMethods;
use msg::constellation_msg::ConstellationChan;
+use range::Range;
use script_traits::ScriptMsg as ConstellationMsg;
use std::cell::Cell;
use string_cache::Atom;
@@ -45,7 +47,7 @@ pub trait LayoutHTMLTextAreaElementHelpers {
#[allow(unsafe_code)]
unsafe fn get_value_for_layout(self) -> String;
#[allow(unsafe_code)]
- unsafe fn get_absolute_insertion_point_for_layout(self) -> Option<usize>;
+ unsafe fn get_absolute_selection_for_layout(self) -> Option<Range<usize>>;
#[allow(unsafe_code)]
fn get_cols(self) -> u32;
#[allow(unsafe_code)]
@@ -61,10 +63,10 @@ impl LayoutHTMLTextAreaElementHelpers for LayoutJS<HTMLTextAreaElement> {
#[allow(unrooted_must_root)]
#[allow(unsafe_code)]
- unsafe fn get_absolute_insertion_point_for_layout(self) -> Option<usize> {
+ unsafe fn get_absolute_selection_for_layout(self) -> Option<Range<usize>> {
if (*self.unsafe_get()).upcast::<Element>().get_focus_state() {
Some((*self.unsafe_get()).textinput.borrow_for_layout()
- .get_absolute_insertion_point())
+ .get_absolute_selection_range())
} else {
None
}
@@ -334,3 +336,5 @@ impl VirtualMethods for HTMLTextAreaElement {
}
impl FormControl for HTMLTextAreaElement {}
+
+impl Validatable for HTMLTextAreaElement {}
diff --git a/components/script/dom/keyboardevent.rs b/components/script/dom/keyboardevent.rs
index 9feb08b7674..91d69e7cfd8 100644
--- a/components/script/dom/keyboardevent.rs
+++ b/components/script/dom/keyboardevent.rs
@@ -148,7 +148,7 @@ impl KeyboardEvent {
}
-// https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3Events-key.html
+// https://w3c.github.io/uievents-key/#key-value-tables
pub fn key_value(key: Key, mods: KeyModifiers) -> &'static str {
let shift = mods.contains(constellation_msg::SHIFT);
match key {
@@ -319,6 +319,8 @@ pub fn key_value(key: Key, mods: KeyModifiers) -> &'static str {
Key::RightAlt => "Alt",
Key::RightSuper => "Super",
Key::Menu => "ContextMenu",
+ Key::NavigateForward => "BrowserForward",
+ Key::NavigateBackward => "BrowserBack",
}
}
@@ -489,11 +491,13 @@ fn key_from_string(key_string: &str, location: u32) -> Option<Key> {
"Alt" if location == KeyboardEventConstants::DOM_KEY_LOCATION_RIGHT => Some(Key::RightAlt),
"Super" if location == KeyboardEventConstants::DOM_KEY_LOCATION_RIGHT => Some(Key::RightSuper),
"ContextMenu" => Some(Key::Menu),
+ "BrowserForward" => Some(Key::NavigateForward),
+ "BrowserBack" => Some(Key::NavigateBackward),
_ => None
}
}
-// https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3Events-code.html
+// https://w3c.github.io/uievents-code/#code-value-tables
fn code_value(key: Key) -> &'static str {
match key {
Key::Space => "Space",
@@ -613,7 +617,10 @@ fn code_value(key: Key) -> &'static str {
Key::LeftControl | Key::RightControl => "Control",
Key::LeftAlt | Key::RightAlt => "Alt",
Key::LeftSuper | Key::RightSuper => "Super",
- Key::Menu => "Menu",
+ Key::Menu => "ContextMenu",
+
+ Key::NavigateForward => "BrowserForward",
+ Key::NavigateBackward => "BrowserBackward",
}
}
diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs
index e75c717b154..662f41dc7a9 100644
--- a/components/script/dom/mod.rs
+++ b/components/script/dom/mod.rs
@@ -375,6 +375,7 @@ pub mod url;
pub mod urlhelper;
pub mod urlsearchparams;
pub mod userscripts;
+pub mod validation;
pub mod validitystate;
pub mod values;
pub mod virtualmethods;
diff --git a/components/script/dom/mouseevent.rs b/components/script/dom/mouseevent.rs
index 5bd6cb7ca06..3acebff3f46 100644
--- a/components/script/dom/mouseevent.rs
+++ b/components/script/dom/mouseevent.rs
@@ -74,7 +74,7 @@ impl MouseEvent {
button: i16,
relatedTarget: Option<&EventTarget>) -> Root<MouseEvent> {
let ev = MouseEvent::new_uninitialized(window);
- ev.InitMouseEvent(type_, canBubble == EventBubbles::Bubbles, cancelable == EventCancelable::Cancelable,
+ ev.InitMouseEvent(type_, bool::from(canBubble), bool::from(cancelable),
view, detail,
screenX, screenY, clientX, clientY,
ctrlKey, altKey, shiftKey, metaKey,
@@ -85,16 +85,8 @@ impl MouseEvent {
pub fn Constructor(global: GlobalRef,
type_: DOMString,
init: &MouseEventBinding::MouseEventInit) -> Fallible<Root<MouseEvent>> {
- let bubbles = if init.parent.parent.parent.bubbles {
- EventBubbles::Bubbles
- } else {
- EventBubbles::DoesNotBubble
- };
- let cancelable = if init.parent.parent.parent.cancelable {
- EventCancelable::Cancelable
- } else {
- EventCancelable::NotCancelable
- };
+ let bubbles = EventBubbles::from(init.parent.parent.parent.bubbles);
+ let cancelable = EventCancelable::from(init.parent.parent.parent.cancelable);
let event = MouseEvent::new(global.as_window(), type_,
bubbles,
cancelable,
diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs
index fed47bb7b24..730f69f24cd 100644
--- a/components/script/dom/node.rs
+++ b/components/script/dom/node.rs
@@ -1696,7 +1696,7 @@ impl Node {
NodeTypeId::Document(_) => {
let node_doc = node.downcast::<Document>().unwrap();
let copy_doc = copy.downcast::<Document>().unwrap();
- copy_doc.set_encoding_name(node_doc.encoding_name().clone());
+ copy_doc.set_encoding(node_doc.encoding());
copy_doc.set_quirks_mode(node_doc.quirks_mode());
},
NodeTypeId::Element(..) => {
diff --git a/components/script/dom/progressevent.rs b/components/script/dom/progressevent.rs
index e7b0b1510ef..215bcdd3db4 100644
--- a/components/script/dom/progressevent.rs
+++ b/components/script/dom/progressevent.rs
@@ -39,7 +39,7 @@ impl ProgressEvent {
ProgressEventBinding::Wrap);
{
let event = ev.upcast::<Event>();
- event.init_event(type_, can_bubble == EventBubbles::Bubbles, cancelable == EventCancelable::Cancelable);
+ event.init_event(type_, bool::from(can_bubble), bool::from(cancelable));
}
ev
}
@@ -47,9 +47,8 @@ impl ProgressEvent {
type_: DOMString,
init: &ProgressEventBinding::ProgressEventInit)
-> Fallible<Root<ProgressEvent>> {
- let bubbles = if init.parent.bubbles { EventBubbles::Bubbles } else { EventBubbles::DoesNotBubble };
- let cancelable = if init.parent.cancelable { EventCancelable::Cancelable }
- else { EventCancelable::NotCancelable };
+ let bubbles = EventBubbles::from(init.parent.bubbles);
+ let cancelable = EventCancelable::from(init.parent.cancelable);
let ev = ProgressEvent::new(global, Atom::from(type_), bubbles, cancelable,
init.lengthComputable, init.loaded, init.total);
Ok(ev)
diff --git a/components/script/dom/storageevent.rs b/components/script/dom/storageevent.rs
index 4c7200f5fc1..7d1f7520c4a 100644
--- a/components/script/dom/storageevent.rs
+++ b/components/script/dom/storageevent.rs
@@ -57,7 +57,7 @@ impl StorageEvent {
StorageEventBinding::Wrap);
{
let event = ev.upcast::<Event>();
- event.init_event(type_, bubbles == EventBubbles::Bubbles, cancelable == EventCancelable::Cancelable);
+ event.init_event(type_, bool::from(bubbles), bool::from(cancelable));
}
ev
}
@@ -70,12 +70,8 @@ impl StorageEvent {
let newValue = init.newValue.clone();
let url = init.url.clone();
let storageArea = init.storageArea.r();
- let bubbles = if init.parent.bubbles { EventBubbles::Bubbles } else { EventBubbles::DoesNotBubble };
- let cancelable = if init.parent.cancelable {
- EventCancelable::Cancelable
- } else {
- EventCancelable::NotCancelable
- };
+ let bubbles = EventBubbles::from(init.parent.bubbles);
+ let cancelable = EventCancelable::from(init.parent.cancelable);
let event = StorageEvent::new(global, Atom::from(type_),
bubbles, cancelable,
key, oldValue, newValue,
diff --git a/components/script/dom/testbinding.rs b/components/script/dom/testbinding.rs
index ae63c1f6e20..41a1ff188b2 100644
--- a/components/script/dom/testbinding.rs
+++ b/components/script/dom/testbinding.rs
@@ -27,6 +27,7 @@ use js::jsval::{JSVal, NullValue};
use std::borrow::ToOwned;
use std::ptr;
use std::rc::Rc;
+use util::prefs::{get_pref};
use util::str::DOMString;
#[dom_struct]
@@ -486,6 +487,9 @@ impl TestBindingMethods for TestBinding {
fn PassVariadicUnion6(&self, _: Vec<UnsignedLongOrBoolean>) {}
fn PassVariadicAny(&self, _: *mut JSContext, _: Vec<HandleValue>) {}
fn PassVariadicObject(&self, _: *mut JSContext, _: Vec<*mut JSObject>) {}
+ fn BooleanMozPreference(&self, pref_name: DOMString) -> bool {
+ get_pref(pref_name.as_ref()).as_boolean().unwrap_or(false)
+ }
}
impl TestBinding {
diff --git a/components/script/dom/touchevent.rs b/components/script/dom/touchevent.rs
index 5d6b85a550a..86f53968fe3 100644
--- a/components/script/dom/touchevent.rs
+++ b/components/script/dom/touchevent.rs
@@ -68,8 +68,8 @@ impl TouchEvent {
metaKey: bool) -> Root<TouchEvent> {
let ev = TouchEvent::new_uninitialized(window, touches, changed_touches, target_touches);
ev.upcast::<UIEvent>().InitUIEvent(type_,
- canBubble == EventBubbles::Bubbles,
- cancelable == EventCancelable::Cancelable,
+ bool::from(canBubble),
+ bool::from(cancelable),
view, detail);
ev.ctrl_key.set(ctrlKey);
ev.alt_key.set(altKey);
diff --git a/components/script/dom/uievent.rs b/components/script/dom/uievent.rs
index bc340638255..e962c10c8aa 100644
--- a/components/script/dom/uievent.rs
+++ b/components/script/dom/uievent.rs
@@ -48,20 +48,15 @@ impl UIEvent {
view: Option<&Window>,
detail: i32) -> Root<UIEvent> {
let ev = UIEvent::new_uninitialized(window);
- ev.InitUIEvent(type_, can_bubble == EventBubbles::Bubbles,
- cancelable == EventCancelable::Cancelable, view, detail);
+ ev.InitUIEvent(type_, bool::from(can_bubble), bool::from(cancelable), view, detail);
ev
}
pub fn Constructor(global: GlobalRef,
type_: DOMString,
init: &UIEventBinding::UIEventInit) -> Fallible<Root<UIEvent>> {
- let bubbles = if init.parent.bubbles { EventBubbles::Bubbles } else { EventBubbles::DoesNotBubble };
- let cancelable = if init.parent.cancelable {
- EventCancelable::Cancelable
- } else {
- EventCancelable::NotCancelable
- };
+ let bubbles = EventBubbles::from(init.parent.bubbles);
+ let cancelable = EventCancelable::from(init.parent.cancelable);
let event = UIEvent::new(global.as_window(), type_,
bubbles, cancelable,
init.view.r(), init.detail);
diff --git a/components/script/dom/urlhelper.rs b/components/script/dom/urlhelper.rs
index 580c541502d..ab0a0c5f8c0 100644
--- a/components/script/dom/urlhelper.rs
+++ b/components/script/dom/urlhelper.rs
@@ -21,6 +21,7 @@ impl UrlHelper {
}
pub fn SetHash(url: &mut Url, value: USVString) {
+ url.fragment = Some(String::new());
let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() };
let _ = wrapper.set_fragment(&value.0);
}
@@ -101,6 +102,9 @@ impl UrlHelper {
}
pub fn SetPathname(url: &mut Url, value: USVString) {
+ if let Some(path) = url.path_mut() {
+ path.clear();
+ }
let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() };
let _ = wrapper.set_path(&value.0);
}
@@ -149,6 +153,7 @@ impl UrlHelper {
}
pub fn SetSearch(url: &mut Url, value: USVString) {
+ url.query = Some(String::new());
let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() };
let _ = wrapper.set_query(&value.0);
}
diff --git a/components/script/dom/validation.rs b/components/script/dom/validation.rs
new file mode 100644
index 00000000000..e9a6a156848
--- /dev/null
+++ b/components/script/dom/validation.rs
@@ -0,0 +1,5 @@
+/* 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/. */
+
+pub trait Validatable {}
diff --git a/components/script/dom/validitystate.rs b/components/script/dom/validitystate.rs
index ae48a1624b0..bd2cbb21aa7 100644
--- a/components/script/dom/validitystate.rs
+++ b/components/script/dom/validitystate.rs
@@ -3,29 +3,109 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::Bindings::ValidityStateBinding;
+use dom::bindings::codegen::Bindings::ValidityStateBinding::ValidityStateMethods;
use dom::bindings::global::GlobalRef;
-use dom::bindings::js::Root;
+use dom::bindings::js::{JS, Root};
use dom::bindings::reflector::{Reflector, reflect_dom_object};
+use dom::element::Element;
use dom::window::Window;
+// https://html.spec.whatwg.org/multipage/#validity-states
+#[derive_JSTraceable]
+#[derive_HeapSizeOf]
+pub enum ValidityStatus {
+ ValueMissing,
+ TypeMismatch,
+ PatternMismatch,
+ TooLong,
+ TooShort,
+ RangeUnderflow,
+ RangeOverflow,
+ StepMismatch,
+ BadInput,
+ CustomError,
+ Valid
+}
+
// https://html.spec.whatwg.org/multipage/#validitystate
#[dom_struct]
pub struct ValidityState {
reflector_: Reflector,
- state: u8,
+ element: JS<Element>,
+ state: ValidityStatus
}
+
impl ValidityState {
- fn new_inherited() -> ValidityState {
+ fn new_inherited(element: &Element) -> ValidityState {
ValidityState {
reflector_: Reflector::new(),
- state: 0,
+ element: JS::from_ref(element),
+ state: ValidityStatus::Valid
}
}
- pub fn new(window: &Window) -> Root<ValidityState> {
- reflect_dom_object(box ValidityState::new_inherited(),
+ pub fn new(window: &Window, element: &Element) -> Root<ValidityState> {
+ reflect_dom_object(box ValidityState::new_inherited(element),
GlobalRef::Window(window),
ValidityStateBinding::Wrap)
}
}
+
+impl ValidityStateMethods for ValidityState {
+
+ // https://html.spec.whatwg.org/multipage/#dom-validitystate-valuemissing
+ fn ValueMissing(&self) -> bool {
+ false
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-validitystate-typemismatch
+ fn TypeMismatch(&self) -> bool {
+ false
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-validitystate-patternmismatch
+ fn PatternMismatch(&self) -> bool {
+ false
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-validitystate-toolong
+ fn TooLong(&self) -> bool {
+ false
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-validitystate-tooshort
+ fn TooShort(&self) -> bool {
+ false
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-validitystate-rangeunderflow
+ fn RangeUnderflow(&self) -> bool {
+ false
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-validitystate-rangeoverflow
+ fn RangeOverflow(&self) -> bool {
+ false
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-validitystate-stepmismatch
+ fn StepMismatch(&self) -> bool {
+ false
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-validitystate-badinput
+ fn BadInput(&self) -> bool {
+ false
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-validitystate-customerror
+ fn CustomError(&self) -> bool {
+ false
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-validitystate-valid
+ fn Valid(&self) -> bool {
+ false
+ }
+}
diff --git a/components/script/dom/webglbuffer.rs b/components/script/dom/webglbuffer.rs
index cfb9cdc4810..0fedc762f4c 100644
--- a/components/script/dom/webglbuffer.rs
+++ b/components/script/dom/webglbuffer.rs
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
-use canvas_traits::{CanvasMsg, CanvasWebGLMsg, WebGLError, WebGLResult};
+use canvas_traits::CanvasMsg;
use dom::bindings::codegen::Bindings::WebGLBufferBinding;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::Root;
@@ -11,6 +11,7 @@ use dom::bindings::reflector::reflect_dom_object;
use dom::webglobject::WebGLObject;
use ipc_channel::ipc::{self, IpcSender};
use std::cell::Cell;
+use webrender_traits::{WebGLCommand, WebGLError, WebGLResult};
#[dom_struct]
pub struct WebGLBuffer {
@@ -39,7 +40,7 @@ impl WebGLBuffer {
pub fn maybe_new(global: GlobalRef, renderer: IpcSender<CanvasMsg>)
-> Option<Root<WebGLBuffer>> {
let (sender, receiver) = ipc::channel().unwrap();
- renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateBuffer(sender))).unwrap();
+ renderer.send(CanvasMsg::WebGL(WebGLCommand::CreateBuffer(sender))).unwrap();
let result = receiver.recv().unwrap();
result.map(|buffer_id| WebGLBuffer::new(global, renderer, *buffer_id))
@@ -65,7 +66,7 @@ impl WebGLBuffer {
} else {
self.target.set(Some(target));
}
- self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BindBuffer(target, self.id))).unwrap();
+ self.renderer.send(CanvasMsg::WebGL(WebGLCommand::BindBuffer(target, self.id))).unwrap();
Ok(())
}
@@ -78,7 +79,7 @@ impl WebGLBuffer {
}
self.capacity.set(data.len());
self.renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::BufferData(target, data.to_vec(), usage)))
+ .send(CanvasMsg::WebGL(WebGLCommand::BufferData(target, data.to_vec(), usage)))
.unwrap();
Ok(())
@@ -91,7 +92,7 @@ impl WebGLBuffer {
pub fn delete(&self) {
if !self.is_deleted.get() {
self.is_deleted.set(true);
- let _ = self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteBuffer(self.id)));
+ let _ = self.renderer.send(CanvasMsg::WebGL(WebGLCommand::DeleteBuffer(self.id)));
}
}
}
diff --git a/components/script/dom/webglcontextevent.rs b/components/script/dom/webglcontextevent.rs
index 195848273fe..ac93727eb7c 100644
--- a/components/script/dom/webglcontextevent.rs
+++ b/components/script/dom/webglcontextevent.rs
@@ -53,7 +53,7 @@ impl WebGLContextEvent {
{
let parent = event.upcast::<Event>();
- parent.init_event(type_, bubbles == EventBubbles::Bubbles, cancelable == EventCancelable::Cancelable);
+ parent.init_event(type_, bool::from(bubbles), bool::from(cancelable));
}
event
@@ -67,17 +67,9 @@ impl WebGLContextEvent {
None => DOMString::new(),
};
- let bubbles = if init.parent.bubbles {
- EventBubbles::Bubbles
- } else {
- EventBubbles::DoesNotBubble
- };
+ let bubbles = EventBubbles::from(init.parent.bubbles);
- let cancelable = if init.parent.cancelable {
- EventCancelable::Cancelable
- } else {
- EventCancelable::NotCancelable
- };
+ let cancelable = EventCancelable::from(init.parent.cancelable);
Ok(WebGLContextEvent::new(global, Atom::from(type_),
bubbles,
diff --git a/components/script/dom/webglframebuffer.rs b/components/script/dom/webglframebuffer.rs
index 86ed0e61b30..9dc4d7c16be 100644
--- a/components/script/dom/webglframebuffer.rs
+++ b/components/script/dom/webglframebuffer.rs
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
-use canvas_traits::{CanvasMsg, CanvasWebGLMsg, WebGLFramebufferBindingRequest};
+use canvas_traits::{CanvasMsg};
use dom::bindings::codegen::Bindings::WebGLFramebufferBinding;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::Root;
@@ -11,6 +11,7 @@ use dom::bindings::reflector::reflect_dom_object;
use dom::webglobject::WebGLObject;
use ipc_channel::ipc::{self, IpcSender};
use std::cell::Cell;
+use webrender_traits::{WebGLCommand, WebGLFramebufferBindingRequest};
#[dom_struct]
pub struct WebGLFramebuffer {
@@ -34,7 +35,7 @@ impl WebGLFramebuffer {
pub fn maybe_new(global: GlobalRef, renderer: IpcSender<CanvasMsg>)
-> Option<Root<WebGLFramebuffer>> {
let (sender, receiver) = ipc::channel().unwrap();
- renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateFramebuffer(sender))).unwrap();
+ renderer.send(CanvasMsg::WebGL(WebGLCommand::CreateFramebuffer(sender))).unwrap();
let result = receiver.recv().unwrap();
result.map(|fb_id| WebGLFramebuffer::new(global, renderer, *fb_id))
@@ -53,14 +54,14 @@ impl WebGLFramebuffer {
}
pub fn bind(&self, target: u32) {
- let cmd = CanvasWebGLMsg::BindFramebuffer(target, WebGLFramebufferBindingRequest::Explicit(self.id));
+ let cmd = WebGLCommand::BindFramebuffer(target, WebGLFramebufferBindingRequest::Explicit(self.id));
self.renderer.send(CanvasMsg::WebGL(cmd)).unwrap();
}
pub fn delete(&self) {
if !self.is_deleted.get() {
self.is_deleted.set(true);
- let _ = self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteFramebuffer(self.id)));
+ let _ = self.renderer.send(CanvasMsg::WebGL(WebGLCommand::DeleteFramebuffer(self.id)));
}
}
}
diff --git a/components/script/dom/webglprogram.rs b/components/script/dom/webglprogram.rs
index 42eb0a23581..338a1e8d46b 100644
--- a/components/script/dom/webglprogram.rs
+++ b/components/script/dom/webglprogram.rs
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
-use canvas_traits::{CanvasMsg, CanvasWebGLMsg, WebGLError, WebGLResult, WebGLParameter};
+use canvas_traits::CanvasMsg;
use dom::bindings::codegen::Bindings::WebGLProgramBinding;
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
use dom::bindings::global::GlobalRef;
@@ -15,6 +15,7 @@ use dom::webglshader::WebGLShader;
use ipc_channel::ipc::{self, IpcSender};
use std::cell::Cell;
use util::str::DOMString;
+use webrender_traits::{WebGLCommand, WebGLError, WebGLParameter, WebGLResult};
#[dom_struct]
pub struct WebGLProgram {
@@ -42,7 +43,7 @@ impl WebGLProgram {
pub fn maybe_new(global: GlobalRef, renderer: IpcSender<CanvasMsg>)
-> Option<Root<WebGLProgram>> {
let (sender, receiver) = ipc::channel().unwrap();
- renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateProgram(sender))).unwrap();
+ renderer.send(CanvasMsg::WebGL(WebGLCommand::CreateProgram(sender))).unwrap();
let result = receiver.recv().unwrap();
result.map(|program_id| WebGLProgram::new(global, renderer, *program_id))
@@ -63,13 +64,13 @@ impl WebGLProgram {
pub fn delete(&self) {
if !self.is_deleted.get() {
self.is_deleted.set(true);
- let _ = self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteProgram(self.id)));
+ let _ = self.renderer.send(CanvasMsg::WebGL(WebGLCommand::DeleteProgram(self.id)));
}
}
/// glLinkProgram
pub fn link(&self) {
- self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::LinkProgram(self.id))).unwrap();
+ self.renderer.send(CanvasMsg::WebGL(WebGLCommand::LinkProgram(self.id))).unwrap();
}
/// glUseProgram
@@ -84,7 +85,7 @@ impl WebGLProgram {
_ => return Err(WebGLError::InvalidOperation),
}
- self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::UseProgram(self.id))).unwrap();
+ self.renderer.send(CanvasMsg::WebGL(WebGLCommand::UseProgram(self.id))).unwrap();
Ok(())
}
@@ -96,7 +97,7 @@ impl WebGLProgram {
_ => return Err(WebGLError::InvalidOperation),
};
- // TODO(ecoal95): Differentiate between same shader already assigned and other previous
+ // TODO(emilio): Differentiate between same shader already assigned and other previous
// shader.
if shader_slot.get().is_some() {
return Err(WebGLError::InvalidOperation);
@@ -104,7 +105,7 @@ impl WebGLProgram {
shader_slot.set(Some(shader));
- self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::AttachShader(self.id, shader.id()))).unwrap();
+ self.renderer.send(CanvasMsg::WebGL(WebGLCommand::AttachShader(self.id, shader.id()))).unwrap();
Ok(())
}
@@ -121,7 +122,7 @@ impl WebGLProgram {
}
self.renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::BindAttribLocation(self.id, index, String::from(name))))
+ .send(CanvasMsg::WebGL(WebGLCommand::BindAttribLocation(self.id, index, String::from(name))))
.unwrap();
Ok(())
}
@@ -139,7 +140,7 @@ impl WebGLProgram {
let (sender, receiver) = ipc::channel().unwrap();
self.renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::GetAttribLocation(self.id, String::from(name), sender)))
+ .send(CanvasMsg::WebGL(WebGLCommand::GetAttribLocation(self.id, String::from(name), sender)))
.unwrap();
Ok(receiver.recv().unwrap())
}
@@ -157,7 +158,7 @@ impl WebGLProgram {
let (sender, receiver) = ipc::channel().unwrap();
self.renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::GetUniformLocation(self.id, String::from(name), sender)))
+ .send(CanvasMsg::WebGL(WebGLCommand::GetUniformLocation(self.id, String::from(name), sender)))
.unwrap();
Ok(receiver.recv().unwrap())
}
@@ -165,7 +166,7 @@ impl WebGLProgram {
/// glGetProgramParameter
pub fn parameter(&self, param_id: u32) -> WebGLResult<WebGLParameter> {
let (sender, receiver) = ipc::channel().unwrap();
- self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::GetProgramParameter(self.id, param_id, sender))).unwrap();
+ self.renderer.send(CanvasMsg::WebGL(WebGLCommand::GetProgramParameter(self.id, param_id, sender))).unwrap();
receiver.recv().unwrap()
}
}
diff --git a/components/script/dom/webglrenderbuffer.rs b/components/script/dom/webglrenderbuffer.rs
index 5257c4782a9..a63bd1c975a 100644
--- a/components/script/dom/webglrenderbuffer.rs
+++ b/components/script/dom/webglrenderbuffer.rs
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
-use canvas_traits::{CanvasMsg, CanvasWebGLMsg};
+use canvas_traits::CanvasMsg;
use dom::bindings::codegen::Bindings::WebGLRenderbufferBinding;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::Root;
@@ -11,6 +11,7 @@ use dom::bindings::reflector::reflect_dom_object;
use dom::webglobject::WebGLObject;
use ipc_channel::ipc::{self, IpcSender};
use std::cell::Cell;
+use webrender_traits::WebGLCommand;
#[dom_struct]
pub struct WebGLRenderbuffer {
@@ -34,7 +35,7 @@ impl WebGLRenderbuffer {
pub fn maybe_new(global: GlobalRef, renderer: IpcSender<CanvasMsg>)
-> Option<Root<WebGLRenderbuffer>> {
let (sender, receiver) = ipc::channel().unwrap();
- renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateRenderbuffer(sender))).unwrap();
+ renderer.send(CanvasMsg::WebGL(WebGLCommand::CreateRenderbuffer(sender))).unwrap();
let result = receiver.recv().unwrap();
result.map(|renderbuffer_id| WebGLRenderbuffer::new(global, renderer, *renderbuffer_id))
@@ -53,13 +54,13 @@ impl WebGLRenderbuffer {
}
pub fn bind(&self, target: u32) {
- self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BindRenderbuffer(target, self.id))).unwrap();
+ self.renderer.send(CanvasMsg::WebGL(WebGLCommand::BindRenderbuffer(target, self.id))).unwrap();
}
pub fn delete(&self) {
if !self.is_deleted.get() {
self.is_deleted.set(true);
- let _ = self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteRenderbuffer(self.id)));
+ let _ = self.renderer.send(CanvasMsg::WebGL(WebGLCommand::DeleteRenderbuffer(self.id)));
}
}
}
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs
index aba9e32b45f..e614b7afc6f 100644
--- a/components/script/dom/webglrenderingcontext.rs
+++ b/components/script/dom/webglrenderingcontext.rs
@@ -2,9 +2,7 @@
* 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::WebGLError::*;
-use canvas_traits::{CanvasCommonMsg, CanvasMsg, CanvasWebGLMsg, WebGLError};
-use canvas_traits::{WebGLFramebufferBindingRequest, WebGLParameter};
+use canvas_traits::{CanvasCommonMsg, CanvasMsg};
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::{WebGLRenderingContextMethods};
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::{self, WebGLContextAttributes};
@@ -37,6 +35,8 @@ use script_traits::ScriptMsg as ConstellationMsg;
use std::cell::Cell;
use util::str::DOMString;
use util::vec::byte_swap;
+use webrender_traits::WebGLError::*;
+use webrender_traits::{WebGLCommand, WebGLError, WebGLFramebufferBindingRequest, WebGLParameter};
pub const MAX_UNIFORM_AND_ATTRIBUTE_LEN: usize = 256;
@@ -68,7 +68,6 @@ bitflags! {
#[dom_struct]
pub struct WebGLRenderingContext {
reflector_: Reflector,
- renderer_id: usize,
#[ignore_heap_size_of = "Defined in ipc-channel"]
ipc_renderer: IpcSender<CanvasMsg>,
canvas: JS<HTMLCanvasElement>,
@@ -95,10 +94,9 @@ impl WebGLRenderingContext {
.unwrap();
let result = receiver.recv().unwrap();
- result.map(|(ipc_renderer, renderer_id)| {
+ result.map(|ipc_renderer| {
WebGLRenderingContext {
reflector_: Reflector::new(),
- renderer_id: renderer_id,
ipc_renderer: ipc_renderer,
canvas: JS::from_ref(canvas),
last_error: Cell::new(None),
@@ -166,7 +164,7 @@ impl WebGLRenderingContext {
fn vertex_attrib(&self, indx: u32, x: f32, y: f32, z: f32, w: f32) {
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::VertexAttrib(indx, x, y, z, w)))
+ .send(CanvasMsg::WebGL(WebGLCommand::VertexAttrib(indx, x, y, z, w)))
.unwrap();
}
}
@@ -187,7 +185,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
fn DrawingBufferWidth(&self) -> i32 {
let (sender, receiver) = ipc::channel().unwrap();
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::DrawingBufferWidth(sender)))
+ .send(CanvasMsg::WebGL(WebGLCommand::DrawingBufferWidth(sender)))
.unwrap();
receiver.recv().unwrap()
}
@@ -196,7 +194,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
fn DrawingBufferHeight(&self) -> i32 {
let (sender, receiver) = ipc::channel().unwrap();
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::DrawingBufferHeight(sender)))
+ .send(CanvasMsg::WebGL(WebGLCommand::DrawingBufferHeight(sender)))
.unwrap();
receiver.recv().unwrap()
}
@@ -206,7 +204,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
fn GetBufferParameter(&self, _cx: *mut JSContext, target: u32, parameter: u32) -> JSVal {
let (sender, receiver) = ipc::channel().unwrap();
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::GetBufferParameter(target, parameter, sender)))
+ .send(CanvasMsg::WebGL(WebGLCommand::GetBufferParameter(target, parameter, sender)))
.unwrap();
match handle_potential_webgl_error!(self, receiver.recv().unwrap(), WebGLParameter::Invalid) {
WebGLParameter::Int(val) => Int32Value(val),
@@ -222,7 +220,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
fn GetParameter(&self, cx: *mut JSContext, parameter: u32) -> JSVal {
let (sender, receiver) = ipc::channel().unwrap();
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::GetParameter(parameter, sender)))
+ .send(CanvasMsg::WebGL(WebGLCommand::GetParameter(parameter, sender)))
.unwrap();
match handle_potential_webgl_error!(self, receiver.recv().unwrap(), WebGLParameter::Invalid) {
WebGLParameter::Int(val) => Int32Value(val),
@@ -262,7 +260,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// If the send does not succeed, assume context lost
if let Err(_) = self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::GetContextAttributes(sender))) {
+ .send(CanvasMsg::WebGL(WebGLCommand::GetContextAttributes(sender))) {
return None;
}
let attrs = receiver.recv().unwrap();
@@ -291,37 +289,37 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn ActiveTexture(&self, texture: u32) {
- self.ipc_renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::ActiveTexture(texture))).unwrap();
+ self.ipc_renderer.send(CanvasMsg::WebGL(WebGLCommand::ActiveTexture(texture))).unwrap();
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn BlendColor(&self, r: f32, g: f32, b: f32, a: f32) {
- self.ipc_renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BlendColor(r, g, b, a))).unwrap();
+ self.ipc_renderer.send(CanvasMsg::WebGL(WebGLCommand::BlendColor(r, g, b, a))).unwrap();
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn BlendEquation(&self, mode: u32) {
- self.ipc_renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BlendEquation(mode))).unwrap();
+ self.ipc_renderer.send(CanvasMsg::WebGL(WebGLCommand::BlendEquation(mode))).unwrap();
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn BlendEquationSeparate(&self, mode_rgb: u32, mode_alpha: u32) {
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::BlendEquationSeparate(mode_rgb, mode_alpha)))
+ .send(CanvasMsg::WebGL(WebGLCommand::BlendEquationSeparate(mode_rgb, mode_alpha)))
.unwrap();
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn BlendFunc(&self, src_factor: u32, dest_factor: u32) {
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::BlendFunc(src_factor, dest_factor)))
+ .send(CanvasMsg::WebGL(WebGLCommand::BlendFunc(src_factor, dest_factor)))
.unwrap();
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn BlendFuncSeparate(&self, src_rgb: u32, dest_rgb: u32, src_alpha: u32, dest_alpha: u32) {
self.ipc_renderer.send(
- CanvasMsg::WebGL(CanvasWebGLMsg::BlendFuncSeparate(src_rgb, dest_rgb, src_alpha, dest_alpha))).unwrap();
+ CanvasMsg::WebGL(WebGLCommand::BlendFuncSeparate(src_rgb, dest_rgb, src_alpha, dest_alpha))).unwrap();
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9
@@ -358,7 +356,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
} else {
// Unbind the current buffer
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::BindBuffer(target, 0)))
+ .send(CanvasMsg::WebGL(WebGLCommand::BindBuffer(target, 0)))
.unwrap()
}
}
@@ -373,7 +371,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
framebuffer.bind(target)
} else {
// Bind the default framebuffer
- let cmd = CanvasWebGLMsg::BindFramebuffer(target, WebGLFramebufferBindingRequest::Default);
+ let cmd = WebGLCommand::BindFramebuffer(target, WebGLFramebufferBindingRequest::Default);
self.ipc_renderer.send(CanvasMsg::WebGL(cmd)).unwrap();
}
}
@@ -389,7 +387,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
} else {
// Unbind the currently bound renderbuffer
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::BindRenderbuffer(target, 0)))
+ .send(CanvasMsg::WebGL(WebGLCommand::BindRenderbuffer(target, 0)))
.unwrap()
}
}
@@ -411,7 +409,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
} else {
// Unbind the currently bound texture
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::BindTexture(target, 0)))
+ .send(CanvasMsg::WebGL(WebGLCommand::BindTexture(target, 0)))
.unwrap()
}
}
@@ -472,7 +470,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
return self.webgl_error(InvalidValue);
}
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::BufferSubData(target, offset as isize, data_vec)))
+ .send(CanvasMsg::WebGL(WebGLCommand::BufferSubData(target, offset as isize, data_vec)))
.unwrap()
} else {
self.webgl_error(InvalidValue);
@@ -498,35 +496,35 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.11
fn Clear(&self, mask: u32) {
- self.ipc_renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::Clear(mask))).unwrap();
+ self.ipc_renderer.send(CanvasMsg::WebGL(WebGLCommand::Clear(mask))).unwrap();
self.mark_as_dirty();
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn ClearColor(&self, red: f32, green: f32, blue: f32, alpha: f32) {
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::ClearColor(red, green, blue, alpha)))
+ .send(CanvasMsg::WebGL(WebGLCommand::ClearColor(red, green, blue, alpha)))
.unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn ClearDepth(&self, depth: f32) {
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::ClearDepth(depth as f64)))
+ .send(CanvasMsg::WebGL(WebGLCommand::ClearDepth(depth as f64)))
.unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn ClearStencil(&self, stencil: i32) {
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::ClearStencil(stencil)))
+ .send(CanvasMsg::WebGL(WebGLCommand::ClearStencil(stencil)))
.unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn ColorMask(&self, r: bool, g: bool, b: bool, a: bool) {
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::ColorMask(r, g, b, a)))
+ .send(CanvasMsg::WebGL(WebGLCommand::ColorMask(r, g, b, a)))
.unwrap()
}
@@ -535,7 +533,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
match mode {
constants::FRONT | constants::BACK | constants::FRONT_AND_BACK =>
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::CullFace(mode)))
+ .send(CanvasMsg::WebGL(WebGLCommand::CullFace(mode)))
.unwrap(),
_ => self.webgl_error(InvalidEnum),
}
@@ -546,7 +544,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
match mode {
constants::CW | constants::CCW =>
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::FrontFace(mode)))
+ .send(CanvasMsg::WebGL(WebGLCommand::FrontFace(mode)))
.unwrap(),
_ => self.webgl_error(InvalidEnum),
}
@@ -559,7 +557,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
constants::GREATER | constants::NOTEQUAL |
constants::GEQUAL | constants::ALWAYS =>
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::DepthFunc(func)))
+ .send(CanvasMsg::WebGL(WebGLCommand::DepthFunc(func)))
.unwrap(),
_ => self.webgl_error(InvalidEnum),
}
@@ -568,14 +566,14 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn DepthMask(&self, flag: bool) {
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::DepthMask(flag)))
+ .send(CanvasMsg::WebGL(WebGLCommand::DepthMask(flag)))
.unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn DepthRange(&self, near: f32, far: f32) {
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::DepthRange(near as f64, far as f64)))
+ .send(CanvasMsg::WebGL(WebGLCommand::DepthRange(near as f64, far as f64)))
.unwrap()
}
@@ -586,7 +584,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
constants::POLYGON_OFFSET_FILL | constants::SAMPLE_ALPHA_TO_COVERAGE | constants::SAMPLE_COVERAGE |
constants::SAMPLE_COVERAGE_INVERT | constants::SCISSOR_TEST =>
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::Enable(cap)))
+ .send(CanvasMsg::WebGL(WebGLCommand::Enable(cap)))
.unwrap(),
_ => self.webgl_error(InvalidEnum),
}
@@ -599,7 +597,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
constants::POLYGON_OFFSET_FILL | constants::SAMPLE_ALPHA_TO_COVERAGE | constants::SAMPLE_COVERAGE |
constants::SAMPLE_COVERAGE_INVERT | constants::SCISSOR_TEST =>
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::Disable(cap)))
+ .send(CanvasMsg::WebGL(WebGLCommand::Disable(cap)))
.unwrap(),
_ => self.webgl_error(InvalidEnum),
}
@@ -612,7 +610,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
}
}
- // TODO(ecoal95): Probably in the future we should keep track of the
+ // TODO(emilio): Probably in the future we should keep track of the
// generated objects, either here or in the webgl thread
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
fn CreateBuffer(&self) -> Option<Root<WebGLBuffer>> {
@@ -701,7 +699,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
self.webgl_error(InvalidValue);
} else {
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::DrawArrays(mode, first, count)))
+ .send(CanvasMsg::WebGL(WebGLCommand::DrawArrays(mode, first, count)))
.unwrap();
self.mark_as_dirty();
}
@@ -741,7 +739,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
constants::TRIANGLE_STRIP | constants::TRIANGLE_FAN |
constants::TRIANGLES => {
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::DrawElements(mode, count, type_, offset)))
+ .send(CanvasMsg::WebGL(WebGLCommand::DrawElements(mode, count, type_, offset)))
.unwrap();
self.mark_as_dirty();
},
@@ -752,7 +750,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
fn EnableVertexAttribArray(&self, attrib_id: u32) {
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::EnableVertexAttribArray(attrib_id)))
+ .send(CanvasMsg::WebGL(WebGLCommand::EnableVertexAttribArray(attrib_id)))
.unwrap()
}
@@ -827,7 +825,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
}
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::Hint(target, mode)))
+ .send(CanvasMsg::WebGL(WebGLCommand::Hint(target, mode)))
.unwrap()
}
@@ -838,7 +836,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
}
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::LineWidth(width)))
+ .send(CanvasMsg::WebGL(WebGLCommand::LineWidth(width)))
.unwrap()
}
@@ -891,21 +889,21 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
}
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::PixelStorei(param_name, param_value)))
+ .send(CanvasMsg::WebGL(WebGLCommand::PixelStorei(param_name, param_value)))
.unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn PolygonOffset(&self, factor: f32, units: f32) {
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::PolygonOffset(factor, units)))
+ .send(CanvasMsg::WebGL(WebGLCommand::PolygonOffset(factor, units)))
.unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.4
fn Scissor(&self, x: i32, y: i32, width: i32, height: i32) {
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::Scissor(x, y, width, height)))
+ .send(CanvasMsg::WebGL(WebGLCommand::Scissor(x, y, width, height)))
.unwrap()
}
@@ -947,7 +945,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
};
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::Uniform1f(uniform.id(), val)))
+ .send(CanvasMsg::WebGL(WebGLCommand::Uniform1f(uniform.id(), val)))
.unwrap()
}
@@ -977,7 +975,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
};
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::Uniform4f(uniform.id(), x, y, z, w)))
+ .send(CanvasMsg::WebGL(WebGLCommand::Uniform4f(uniform.id(), x, y, z, w)))
.unwrap()
}
@@ -1088,7 +1086,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
normalized: bool, stride: i32, offset: i64) {
if let constants::FLOAT = data_type {
let msg = CanvasMsg::WebGL(
- CanvasWebGLMsg::VertexAttribPointer2f(attrib_id, size, normalized, stride, offset as u32));
+ WebGLCommand::VertexAttribPointer2f(attrib_id, size, normalized, stride, offset as u32));
self.ipc_renderer.send(msg).unwrap()
} else {
panic!("VertexAttribPointer: Data Type not supported")
@@ -1098,7 +1096,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.4
fn Viewport(&self, x: i32, y: i32, width: i32, height: i32) {
self.ipc_renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::Viewport(x, y, width, height)))
+ .send(CanvasMsg::WebGL(WebGLCommand::Viewport(x, y, width, height)))
.unwrap()
}
@@ -1118,8 +1116,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
if texture.is_none() {
return self.webgl_error(InvalidOperation);
}
- // TODO(ecoal95): Validate more parameters
-
+ // TODO(emilio): Validate more parameters
let source = match source {
Some(s) => s,
None => return,
@@ -1146,7 +1143,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
};
let size = Size2D::new(img.width as i32, img.height as i32);
- // TODO(ecoal95): Validate that the format argument is coherent with the image.
+ // TODO(emilio): Validate that the format argument is coherent with the image.
// RGB8 should be easy to support too
let mut data = match img.format {
PixelFormat::RGBA8 => img.bytes.to_vec(),
@@ -1157,7 +1154,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
(data, size)
},
- // TODO(ecoal95): Getting canvas data is implemented in CanvasRenderingContext2D, but
+ // TODO(emilio): Getting canvas data is implemented in CanvasRenderingContext2D, but
// we need to refactor it moving it to `HTMLCanvasElement` and supporting WebGLContext
ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement::HTMLCanvasElement(canvas) => {
let canvas = canvas.r();
@@ -1172,8 +1169,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
=> unimplemented!(),
};
- // TODO(ecoal95): Invert axis, convert colorspace, premultiply alpha if requested
- let msg = CanvasWebGLMsg::TexImage2D(target, level, internal_format as i32,
+ // TODO(emilio): Invert axis, convert colorspace, premultiply alpha if requested
+ let msg = WebGLCommand::TexImage2D(target, level, internal_format as i32,
size.width, size.height,
format, data_type, pixels);
@@ -1195,17 +1192,11 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
pub trait LayoutCanvasWebGLRenderingContextHelpers {
#[allow(unsafe_code)]
- unsafe fn get_renderer_id(&self) -> usize;
- #[allow(unsafe_code)]
unsafe fn get_ipc_renderer(&self) -> IpcSender<CanvasMsg>;
}
impl LayoutCanvasWebGLRenderingContextHelpers for LayoutJS<WebGLRenderingContext> {
#[allow(unsafe_code)]
- unsafe fn get_renderer_id(&self) -> usize {
- (*self.unsafe_get()).renderer_id
- }
- #[allow(unsafe_code)]
unsafe fn get_ipc_renderer(&self) -> IpcSender<CanvasMsg> {
(*self.unsafe_get()).ipc_renderer.clone()
}
diff --git a/components/script/dom/webglshader.rs b/components/script/dom/webglshader.rs
index 9c4548f1675..03c39b698b0 100644
--- a/components/script/dom/webglshader.rs
+++ b/components/script/dom/webglshader.rs
@@ -4,7 +4,7 @@
// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
use angle::hl::{BuiltInResources, Output, ShaderValidator};
-use canvas_traits::{CanvasMsg, CanvasWebGLMsg, WebGLResult, WebGLParameter};
+use canvas_traits::CanvasMsg;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::WebGLShaderBinding;
use dom::bindings::global::GlobalRef;
@@ -15,6 +15,7 @@ use ipc_channel::ipc::{self, IpcSender};
use std::cell::Cell;
use std::sync::{ONCE_INIT, Once};
use util::str::DOMString;
+use webrender_traits::{WebGLCommand, WebGLParameter, WebGLResult};
#[derive(Clone, Copy, PartialEq, Debug, JSTraceable, HeapSizeOf)]
pub enum ShaderCompilationStatus {
@@ -63,7 +64,7 @@ impl WebGLShader {
renderer: IpcSender<CanvasMsg>,
shader_type: u32) -> Option<Root<WebGLShader>> {
let (sender, receiver) = ipc::channel().unwrap();
- renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateShader(shader_type, sender))).unwrap();
+ renderer.send(CanvasMsg::WebGL(WebGLCommand::CreateShader(shader_type, sender))).unwrap();
let result = receiver.recv().unwrap();
result.map(|shader_id| WebGLShader::new(global, renderer, *shader_id, shader_type))
@@ -103,7 +104,7 @@ impl WebGLShader {
// NOTE: At this point we should be pretty sure that the compilation in the paint thread
// will succeed.
// It could be interesting to retrieve the info log from the paint thread though
- let msg = CanvasWebGLMsg::CompileShader(self.id, translated_source);
+ let msg = WebGLCommand::CompileShader(self.id, translated_source);
self.renderer.send(CanvasMsg::WebGL(msg)).unwrap();
self.compilation_status.set(ShaderCompilationStatus::Succeeded);
},
@@ -122,7 +123,7 @@ impl WebGLShader {
pub fn delete(&self) {
if !self.is_deleted.get() {
self.is_deleted.set(true);
- let _ = self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteShader(self.id)));
+ let _ = self.renderer.send(CanvasMsg::WebGL(WebGLCommand::DeleteShader(self.id)));
}
}
@@ -134,7 +135,7 @@ impl WebGLShader {
/// glGetParameter
pub fn parameter(&self, param_id: u32) -> WebGLResult<WebGLParameter> {
let (sender, receiver) = ipc::channel().unwrap();
- self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::GetShaderParameter(self.id, param_id, sender))).unwrap();
+ self.renderer.send(CanvasMsg::WebGL(WebGLCommand::GetShaderParameter(self.id, param_id, sender))).unwrap();
receiver.recv().unwrap()
}
diff --git a/components/script/dom/webgltexture.rs b/components/script/dom/webgltexture.rs
index e7f645ce235..e40938d84f1 100644
--- a/components/script/dom/webgltexture.rs
+++ b/components/script/dom/webgltexture.rs
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
-use canvas_traits::{CanvasMsg, CanvasWebGLMsg, WebGLError, WebGLResult};
+use canvas_traits::CanvasMsg;
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
use dom::bindings::codegen::Bindings::WebGLTextureBinding;
use dom::bindings::global::GlobalRef;
@@ -12,6 +12,7 @@ use dom::bindings::reflector::reflect_dom_object;
use dom::webglobject::WebGLObject;
use ipc_channel::ipc::{self, IpcSender};
use std::cell::Cell;
+use webrender_traits::{WebGLCommand, WebGLError, WebGLResult};
pub enum TexParameterValue {
Float(f32),
@@ -43,7 +44,7 @@ impl WebGLTexture {
pub fn maybe_new(global: GlobalRef, renderer: IpcSender<CanvasMsg>)
-> Option<Root<WebGLTexture>> {
let (sender, receiver) = ipc::channel().unwrap();
- renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateTexture(sender))).unwrap();
+ renderer.send(CanvasMsg::WebGL(WebGLCommand::CreateTexture(sender))).unwrap();
let result = receiver.recv().unwrap();
result.map(|texture_id| WebGLTexture::new(global, renderer, *texture_id))
@@ -70,7 +71,7 @@ impl WebGLTexture {
self.target.set(Some(target));
}
- self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BindTexture(target, self.id))).unwrap();
+ self.renderer.send(CanvasMsg::WebGL(WebGLCommand::BindTexture(target, self.id))).unwrap();
Ok(())
}
@@ -78,7 +79,7 @@ impl WebGLTexture {
pub fn delete(&self) {
if !self.is_deleted.get() {
self.is_deleted.set(true);
- let _ = self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteTexture(self.id)));
+ let _ = self.renderer.send(CanvasMsg::WebGL(WebGLCommand::DeleteTexture(self.id)));
}
}
@@ -104,7 +105,7 @@ impl WebGLTexture {
constants::NEAREST_MIPMAP_LINEAR |
constants::LINEAR_MIPMAP_LINEAR => {
self.renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::TexParameteri(target, name, int_value)))
+ .send(CanvasMsg::WebGL(WebGLCommand::TexParameteri(target, name, int_value)))
.unwrap();
Ok(())
},
@@ -117,7 +118,7 @@ impl WebGLTexture {
constants::NEAREST |
constants::LINEAR => {
self.renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::TexParameteri(target, name, int_value)))
+ .send(CanvasMsg::WebGL(WebGLCommand::TexParameteri(target, name, int_value)))
.unwrap();
Ok(())
},
@@ -132,7 +133,7 @@ impl WebGLTexture {
constants::MIRRORED_REPEAT |
constants::REPEAT => {
self.renderer
- .send(CanvasMsg::WebGL(CanvasWebGLMsg::TexParameteri(target, name, int_value)))
+ .send(CanvasMsg::WebGL(WebGLCommand::TexParameteri(target, name, int_value)))
.unwrap();
Ok(())
},
diff --git a/components/script/dom/webidls/Blob.webidl b/components/script/dom/webidls/Blob.webidl
index 5f338a15239..bad890fafdc 100644
--- a/components/script/dom/webidls/Blob.webidl
+++ b/components/script/dom/webidls/Blob.webidl
@@ -4,11 +4,9 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// http://dev.w3.org/2006/webapi/FileAPI/#dfn-Blob
-//[Exposed=Window,Worker][Constructor,
-// Constructor(sequence<(ArrayBuffer or ArrayBufferView or Blob or DOMString)> blobParts,
-// optional BlobPropertyBag options)]
[Constructor,
- Constructor(DOMString blobParts, optional BlobPropertyBag options),
+ Constructor(sequence<(/*ArrayBuffer or ArrayBufferView or */Blob or DOMString)> blobParts,
+ optional BlobPropertyBag options),
Exposed=Window/*,Worker*/]
interface Blob {
diff --git a/components/script/dom/webidls/BrowserElement.webidl b/components/script/dom/webidls/BrowserElement.webidl
index 33f1fa6fd5e..6e658a1b5b7 100644
--- a/components/script/dom/webidls/BrowserElement.webidl
+++ b/components/script/dom/webidls/BrowserElement.webidl
@@ -54,6 +54,12 @@ dictionary BrowserElementSecurityChangeDetail {
boolean mixedContent;
};
+dictionary BrowserElementLocationChangeEventDetail {
+ DOMString uri;
+ boolean canGoBack;
+ boolean canGoForward;
+};
+
dictionary BrowserElementIconChangeEventDetail {
DOMString rel;
DOMString href;
diff --git a/components/script/dom/webidls/DOMTokenList.webidl b/components/script/dom/webidls/DOMTokenList.webidl
index c9125285f74..21be3590c0a 100644
--- a/components/script/dom/webidls/DOMTokenList.webidl
+++ b/components/script/dom/webidls/DOMTokenList.webidl
@@ -18,6 +18,8 @@ interface DOMTokenList {
void remove(DOMString... tokens);
[Throws]
boolean toggle(DOMString token, optional boolean force);
+ [Throws]
+ void replace(DOMString token, DOMString newToken);
[Pure]
attribute DOMString value;
diff --git a/components/script/dom/webidls/Element.webidl b/components/script/dom/webidls/Element.webidl
index c5c395536ac..9bc5ff64597 100644
--- a/components/script/dom/webidls/Element.webidl
+++ b/components/script/dom/webidls/Element.webidl
@@ -70,6 +70,10 @@ interface Element : Node {
HTMLCollection getElementsByTagName(DOMString localName);
HTMLCollection getElementsByTagNameNS(DOMString? namespace, DOMString localName);
HTMLCollection getElementsByClassName(DOMString classNames);
+ [Throws]
+ Element? insertAdjacentElement(DOMString where_, Element element);
+ [Throws]
+ void insertAdjacentText(DOMString where_, DOMString data);
};
// http://dev.w3.org/csswg/cssom-view/#extensions-to-the-element-interface
diff --git a/components/script/dom/webidls/HTMLAnchorElement.webidl b/components/script/dom/webidls/HTMLAnchorElement.webidl
index 6585e1ccc56..bfca9b31b7d 100644
--- a/components/script/dom/webidls/HTMLAnchorElement.webidl
+++ b/components/script/dom/webidls/HTMLAnchorElement.webidl
@@ -26,7 +26,7 @@ interface HTMLAnchorElement : HTMLElement {
// also has obsolete members
};
-//HTMLAnchorElement implements HTMLHyperlinkElementUtils;
+HTMLAnchorElement implements HTMLHyperlinkElementUtils;
// https://html.spec.whatwg.org/multipage/#HTMLAnchorElement-partial
partial interface HTMLAnchorElement {
diff --git a/components/script/dom/webidls/HTMLHyperlinkElementUtils.webidl b/components/script/dom/webidls/HTMLHyperlinkElementUtils.webidl
index c8d7a35493d..0efcea09710 100644
--- a/components/script/dom/webidls/HTMLHyperlinkElementUtils.webidl
+++ b/components/script/dom/webidls/HTMLHyperlinkElementUtils.webidl
@@ -4,17 +4,23 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://html.spec.whatwg.org/multipage/#htmlhyperlinkelementutils
-//[NoInterfaceObject/*, Exposed=Window*/]
-//interface HTMLHyperlinkElementUtils {
+[NoInterfaceObject/*, Exposed=Window*/]
+interface HTMLHyperlinkElementUtils {
// stringifier attribute USVString href;
+ attribute USVString href;
// attribute USVString origin;
-// attribute USVString protocol;
-// attribute USVString username;
-// attribute USVString password;
-// attribute USVString host;
-// attribute USVString hostname;
-// attribute USVString port;
-// attribute USVString pathname;
-// attribute USVString search;
-// attribute USVString hash;
-//};
+ attribute USVString protocol;
+ attribute USVString username;
+ attribute USVString password;
+ attribute USVString host;
+ attribute USVString hostname;
+ attribute USVString port;
+ attribute USVString pathname;
+ attribute USVString search;
+ attribute USVString hash;
+
+ // Adding a separate stringifier method until
+ // https://github.com/servo/servo/issues/7590 adds attribute stringifier
+ // support.
+ stringifier;
+};
diff --git a/components/script/dom/webidls/Navigator.webidl b/components/script/dom/webidls/Navigator.webidl
index c23415aa094..50f695279ff 100644
--- a/components/script/dom/webidls/Navigator.webidl
+++ b/components/script/dom/webidls/Navigator.webidl
@@ -36,5 +36,6 @@ interface NavigatorBluetooth {
[NoInterfaceObject/*, Exposed=Window,Worker*/]
interface NavigatorLanguage {
readonly attribute DOMString language;
+ // https://github.com/servo/servo/issues/10073
//readonly attribute DOMString[] languages;
};
diff --git a/components/script/dom/webidls/TestBinding.webidl b/components/script/dom/webidls/TestBinding.webidl
index 269114dbf80..9047833bfa8 100644
--- a/components/script/dom/webidls/TestBinding.webidl
+++ b/components/script/dom/webidls/TestBinding.webidl
@@ -29,6 +29,7 @@ dictionary TestDictionary {
any anyValue;
object objectValue;
TestDictionaryDefaults dict;
+ sequence<TestDictionaryDefaults> seqDict;
};
dictionary TestDictionaryDefaults {
@@ -398,4 +399,5 @@ interface TestBinding {
static attribute boolean booleanAttributeStatic;
static void receiveVoidStatic();
+ boolean BooleanMozPreference(DOMString pref_name);
};
diff --git a/components/script/dom/webidls/ValidityState.webidl b/components/script/dom/webidls/ValidityState.webidl
index c6f9c7ba0e2..7ed0167b010 100644
--- a/components/script/dom/webidls/ValidityState.webidl
+++ b/components/script/dom/webidls/ValidityState.webidl
@@ -5,15 +5,15 @@
// https://html.spec.whatwg.org/multipage/#validitystate
interface ValidityState {
- //readonly attribute boolean valueMissing;
- //readonly attribute boolean typeMismatch;
- //readonly attribute boolean patternMismatch;
- //readonly attribute boolean tooLong;
- //readonly attribute boolean tooShort;
- //readonly attribute boolean rangeUnderflow;
- //readonly attribute boolean rangeOverflow;
- //readonly attribute boolean stepMismatch;
- //readonly attribute boolean badInput;
- //readonly attribute boolean customError;
- //readonly attribute boolean valid;
+ readonly attribute boolean valueMissing;
+ readonly attribute boolean typeMismatch;
+ readonly attribute boolean patternMismatch;
+ readonly attribute boolean tooLong;
+ readonly attribute boolean tooShort;
+ readonly attribute boolean rangeUnderflow;
+ readonly attribute boolean rangeOverflow;
+ readonly attribute boolean stepMismatch;
+ readonly attribute boolean badInput;
+ readonly attribute boolean customError;
+ readonly attribute boolean valid;
};
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index df7d1f92de7..a8b55cf8c06 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -996,7 +996,7 @@ impl Window {
page_clip_rect: self.page_clip_rect.get(),
},
document: self.Document().upcast::<Node>().to_trusted_node_address(),
- document_stylesheets: document.stylesheets().clone(),
+ document_stylesheets: document.stylesheets(),
stylesheets_changed: stylesheets_changed,
window_size: window_size,
script_join_chan: join_chan,
@@ -1021,7 +1021,11 @@ impl Window {
debug!("script: layout joined");
- self.pending_reflow_count.set(0);
+ // Pending reflows require display, so only reset the pending reflow count if this reflow
+ // was to be displayed.
+ if goal == ReflowGoal::ForDisplay {
+ self.pending_reflow_count.set(0);
+ }
if let Some(marker) = marker {
self.emit_timeline_marker(marker.end());
@@ -1056,7 +1060,7 @@ impl Window {
// When all these conditions are met, notify the constellation
// that this pipeline is ready to write the image (from the script thread
// perspective at least).
- if opts::get().output_file.is_some() && for_display {
+ if (opts::get().output_file.is_some() || opts::get().exit_after_load) && for_display {
let document = self.Document();
// Checks if the html element has reftest-wait attribute present.
@@ -1104,7 +1108,7 @@ impl Window {
pub fn hit_test_query(&self, hit_test_request: Point2D<f32>, update_cursor: bool)
-> Option<UntrustedNodeAddress> {
- self.reflow(ReflowGoal::ForDisplay,
+ self.reflow(ReflowGoal::ForScriptQuery,
ReflowQueryType::HitTestQuery(hit_test_request, update_cursor),
ReflowReason::Query);
self.layout_rpc.hit_test().node_address
diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs
index 7ab29945961..fcc6bbdd151 100644
--- a/components/script/dom/workerglobalscope.rs
+++ b/components/script/dom/workerglobalscope.rs
@@ -55,8 +55,8 @@ pub struct WorkerGlobalScope {
eventtarget: EventTarget,
worker_id: WorkerId,
worker_url: Url,
- #[ignore_heap_size_of = "Defined in std"]
- runtime: Rc<Runtime>,
+ #[ignore_heap_size_of = "Defined in js"]
+ runtime: Runtime,
next_worker_id: Cell<WorkerId>,
#[ignore_heap_size_of = "Defined in std"]
resource_thread: ResourceThread,
@@ -94,7 +94,7 @@ pub struct WorkerGlobalScope {
impl WorkerGlobalScope {
pub fn new_inherited(init: WorkerGlobalScopeInit,
worker_url: Url,
- runtime: Rc<Runtime>,
+ runtime: Runtime,
from_devtools_receiver: Receiver<DevtoolScriptControlMsg>,
timer_event_chan: IpcSender<TimerEvent>)
-> WorkerGlobalScope {
diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs
index 7de3d956437..20a729c70c0 100644
--- a/components/script/dom/xmlhttprequest.rs
+++ b/components/script/dom/xmlhttprequest.rs
@@ -62,6 +62,7 @@ use time;
use timers::{OneshotTimerCallback, OneshotTimerHandle};
use url::Url;
use url::percent_encoding::{utf8_percent_encode, USERNAME_ENCODE_SET, PASSWORD_ENCODE_SET};
+use util::prefs;
use util::str::DOMString;
pub type SendParam = BlobOrStringOrURLSearchParams;
@@ -118,7 +119,7 @@ pub struct XMLHttpRequest {
timeout: Cell<u32>,
with_credentials: Cell<bool>,
upload: JS<XMLHttpRequestUpload>,
- response_url: String,
+ response_url: DOMRefCell<String>,
status: Cell<u16>,
status_text: DOMRefCell<ByteString>,
response: DOMRefCell<ByteString>,
@@ -160,7 +161,7 @@ impl XMLHttpRequest {
timeout: Cell::new(0u32),
with_credentials: Cell::new(false),
upload: JS::from_rooted(&XMLHttpRequestUpload::new(global)),
- response_url: String::from(""),
+ response_url: DOMRefCell::new(String::from("")),
status: Cell::new(0),
status_text: DOMRefCell::new(ByteString::new(vec!())),
response: DOMRefCell::new(ByteString::new(vec!())),
@@ -691,7 +692,7 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
// https://xhr.spec.whatwg.org/#the-responseurl-attribute
fn ResponseURL(&self) -> USVString {
- USVString(self.response_url.clone())
+ USVString(self.response_url.borrow().clone())
}
// https://xhr.spec.whatwg.org/#the-status-attribute
@@ -866,16 +867,37 @@ impl XMLHttpRequest {
fn process_headers_available(&self, cors_request: Option<CORSRequest>,
gen_id: GenerationId, metadata: Metadata) -> Result<(), Error> {
- if let Some(ref req) = cors_request {
- match metadata.headers {
- Some(ref h) if allow_cross_origin_request(req, h) => {},
- _ => {
- self.process_partial_response(XHRProgress::Errored(gen_id, Error::Network));
- return Err(Error::Network);
+ let bypass_cross_origin_check = {
+ // We want to be able to do cross-origin requests in browser.html.
+ // If the XHR happens in a top level window and the mozbrowser
+ // preference is enabled, we allow bypassing the CORS check.
+ // This is a temporary measure until we figure out Servo privilege
+ // story. See https://github.com/servo/servo/issues/9582
+ if let GlobalRoot::Window(win) = self.global() {
+ let is_root_pipeline = win.parent_info().is_none();
+ let is_mozbrowser_enabled = prefs::get_pref("dom.mozbrowser.enabled").as_boolean().unwrap_or(false);
+ is_root_pipeline && is_mozbrowser_enabled
+ } else {
+ false
+ }
+ };
+
+ if !bypass_cross_origin_check {
+ if let Some(ref req) = cors_request {
+ match metadata.headers {
+ Some(ref h) if allow_cross_origin_request(req, h) => {},
+ _ => {
+ self.process_partial_response(XHRProgress::Errored(gen_id, Error::Network));
+ return Err(Error::Network);
+ }
}
}
+ } else {
+ debug!("Bypassing cross origin check");
}
+ *self.response_url.borrow_mut() = metadata.final_url.serialize_no_fragment();
+
// XXXManishearth Clear cache entries in case of a network error
self.process_partial_response(XHRProgress::HeadersReceived(gen_id,
metadata.headers,
@@ -980,6 +1002,7 @@ impl XMLHttpRequest {
// Subsubsteps 5-7
self.send_flag.set(false);
+
self.change_ready_state(XMLHttpRequestState::Done);
return_if_fetch_was_terminated!();
// Subsubsteps 10-12
@@ -1150,7 +1173,7 @@ impl XMLHttpRequest {
_ => { return None; }
}
// Step 9
- temp_doc.set_encoding_name(DOMString::from(charset.name()));
+ temp_doc.set_encoding(charset);
// Step 13
self.response_xml.set(Some(temp_doc.r()));
return self.response_xml.get();
diff --git a/components/script/lib.rs b/components/script/lib.rs
index 99a3bb7ce9b..fa6dc8a385e 100644
--- a/components/script/lib.rs
+++ b/components/script/lib.rs
@@ -58,6 +58,7 @@ extern crate phf;
#[macro_use]
extern crate profile_traits;
extern crate rand;
+extern crate range;
extern crate ref_filter_map;
extern crate ref_slice;
extern crate regex;
@@ -75,6 +76,7 @@ extern crate url;
#[macro_use]
extern crate util;
extern crate uuid;
+extern crate webrender_traits;
extern crate websocket;
extern crate xml5ever;
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index 9cfc2627786..c591cd955a3 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -321,13 +321,11 @@ pub struct SendableMainThreadScriptChan(pub Sender<CommonScriptMsg>);
impl ScriptChan for SendableMainThreadScriptChan {
fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> {
- let SendableMainThreadScriptChan(ref chan) = *self;
- chan.send(msg).map_err(|_| ())
+ self.0.send(msg).map_err(|_| ())
}
fn clone(&self) -> Box<ScriptChan + Send> {
- let SendableMainThreadScriptChan(ref chan) = *self;
- box SendableMainThreadScriptChan((*chan).clone())
+ box SendableMainThreadScriptChan((&self.0).clone())
}
}
@@ -345,13 +343,11 @@ pub struct MainThreadScriptChan(pub Sender<MainThreadScriptMsg>);
impl ScriptChan for MainThreadScriptChan {
fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> {
- let MainThreadScriptChan(ref chan) = *self;
- chan.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ())
+ self.0.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ())
}
fn clone(&self) -> Box<ScriptChan + Send> {
- let MainThreadScriptChan(ref chan) = *self;
- box MainThreadScriptChan((*chan).clone())
+ box MainThreadScriptChan((&self.0).clone())
}
}
@@ -552,6 +548,7 @@ impl ScriptThreadFactory for ScriptThread {
let reporter_name = format!("script-reporter-{}", id);
mem_profiler_chan.run_with_memory_reporting(|| {
script_thread.start();
+ let _ = script_thread.compositor.borrow_mut().send(ScriptToCompositorMsg::Exited);
let _ = script_thread.content_process_shutdown_chan.send(());
}, reporter_name, channel_for_reporter, CommonScriptMsg::CollectReports);
diff --git a/components/script/task_source/dom_manipulation.rs b/components/script/task_source/dom_manipulation.rs
index d60ce7de93d..9676ade6ded 100644
--- a/components/script/task_source/dom_manipulation.rs
+++ b/components/script/task_source/dom_manipulation.rs
@@ -16,13 +16,11 @@ pub struct DOMManipulationTaskSource(pub Sender<MainThreadScriptMsg>);
impl TaskSource<DOMManipulationTask> for DOMManipulationTaskSource {
fn queue(&self, msg: DOMManipulationTask) -> Result<(), ()> {
- let DOMManipulationTaskSource(ref chan) = *self;
- chan.send(MainThreadScriptMsg::DOMManipulation(msg)).map_err(|_| ())
+ self.0.send(MainThreadScriptMsg::DOMManipulation(msg)).map_err(|_| ())
}
fn clone(&self) -> Box<TaskSource<DOMManipulationTask> + Send> {
- let DOMManipulationTaskSource(ref chan) = *self;
- box DOMManipulationTaskSource((*chan).clone())
+ box DOMManipulationTaskSource((&self.0).clone())
}
}
diff --git a/components/script/task_source/file_reading.rs b/components/script/task_source/file_reading.rs
index e4afad34b4b..30e9530a76d 100644
--- a/components/script/task_source/file_reading.rs
+++ b/components/script/task_source/file_reading.rs
@@ -10,12 +10,10 @@ pub struct FileReadingTaskSource(pub Sender<MainThreadScriptMsg>);
impl ScriptChan for FileReadingTaskSource {
fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> {
- let FileReadingTaskSource(ref chan) = *self;
- chan.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ())
+ self.0.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ())
}
fn clone(&self) -> Box<ScriptChan + Send> {
- let FileReadingTaskSource(ref chan) = *self;
- box FileReadingTaskSource((*chan).clone())
+ box FileReadingTaskSource((&self.0).clone())
}
}
diff --git a/components/script/task_source/history_traversal.rs b/components/script/task_source/history_traversal.rs
index 0916c121345..c2d276e6eec 100644
--- a/components/script/task_source/history_traversal.rs
+++ b/components/script/task_source/history_traversal.rs
@@ -10,12 +10,10 @@ pub struct HistoryTraversalTaskSource(pub Sender<MainThreadScriptMsg>);
impl ScriptChan for HistoryTraversalTaskSource {
fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> {
- let HistoryTraversalTaskSource(ref chan) = *self;
- chan.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ())
+ self.0.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ())
}
fn clone(&self) -> Box<ScriptChan + Send> {
- let HistoryTraversalTaskSource(ref chan) = *self;
- box HistoryTraversalTaskSource((*chan).clone())
+ box HistoryTraversalTaskSource((&self.0).clone())
}
}
diff --git a/components/script/task_source/networking.rs b/components/script/task_source/networking.rs
index 8ebeecdb965..83160468395 100644
--- a/components/script/task_source/networking.rs
+++ b/components/script/task_source/networking.rs
@@ -10,12 +10,10 @@ pub struct NetworkingTaskSource(pub Sender<MainThreadScriptMsg>);
impl ScriptChan for NetworkingTaskSource {
fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> {
- let NetworkingTaskSource(ref chan) = *self;
- chan.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ())
+ self.0.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ())
}
fn clone(&self) -> Box<ScriptChan + Send> {
- let NetworkingTaskSource(ref chan) = *self;
- box NetworkingTaskSource((*chan).clone())
+ box NetworkingTaskSource((&self.0).clone())
}
}
diff --git a/components/script/task_source/user_interaction.rs b/components/script/task_source/user_interaction.rs
index 7912eac720d..254b0d008d1 100644
--- a/components/script/task_source/user_interaction.rs
+++ b/components/script/task_source/user_interaction.rs
@@ -10,12 +10,10 @@ pub struct UserInteractionTaskSource(pub Sender<MainThreadScriptMsg>);
impl ScriptChan for UserInteractionTaskSource {
fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> {
- let UserInteractionTaskSource(ref chan) = *self;
- chan.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ())
+ self.0.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ())
}
fn clone(&self) -> Box<ScriptChan + Send> {
- let UserInteractionTaskSource(ref chan) = *self;
- box UserInteractionTaskSource((*chan).clone())
+ box UserInteractionTaskSource((&self.0).clone())
}
}
diff --git a/components/script/textinput.rs b/components/script/textinput.rs
index 35b49ee57a4..cc5936d42b0 100644
--- a/components/script/textinput.rs
+++ b/components/script/textinput.rs
@@ -8,6 +8,7 @@ use clipboard_provider::ClipboardProvider;
use dom::keyboardevent::{KeyboardEvent, key_value};
use msg::constellation_msg::{ALT, CONTROL, SHIFT, SUPER};
use msg::constellation_msg::{Key, KeyModifiers};
+use range::Range;
use std::borrow::ToOwned;
use std::cmp::{max, min};
use std::default::Default;
@@ -20,7 +21,7 @@ pub enum Selection {
NotSelected
}
-#[derive(JSTraceable, Copy, Clone, HeapSizeOf)]
+#[derive(JSTraceable, Copy, Clone, HeapSizeOf, PartialEq)]
pub struct TextPoint {
/// 0-based line number
pub line: usize,
@@ -123,7 +124,7 @@ impl<T: ClipboardProvider> TextInput<T> {
/// Remove a character at the current editing point
pub fn delete_char(&mut self, dir: Direction) {
- if self.selection_begin.is_none() {
+ if self.selection_begin.is_none() || self.selection_begin == Some(self.edit_point) {
self.adjust_horizontal_by_one(dir, Selection::Selected);
}
self.replace_selection(DOMString::new());
@@ -154,6 +155,15 @@ impl<T: ClipboardProvider> TextInput<T> {
})
}
+ pub fn get_absolute_selection_range(&self) -> Range<usize> {
+ match self.get_sorted_selection() {
+ Some((begin, _end)) =>
+ Range::new(self.get_absolute_point_for_text_point(&begin), self.selection_len()),
+ None =>
+ Range::new(self.get_absolute_insertion_point(), 0)
+ }
+ }
+
pub fn get_selection_text(&self) -> Option<String> {
self.get_sorted_selection().map(|(begin, end)| {
if begin.line != end.line {