aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom')
-rw-r--r--components/script/dom/attr.rs46
-rw-r--r--components/script/dom/bindings/js.rs7
-rw-r--r--components/script/dom/bindings/str.rs2
-rw-r--r--components/script/dom/bindings/trace.rs136
-rw-r--r--components/script/dom/canvasgradient.rs2
-rw-r--r--components/script/dom/canvasrenderingcontext2d.rs14
-rw-r--r--components/script/dom/cssstyledeclaration.rs81
-rw-r--r--components/script/dom/document.rs2
-rw-r--r--components/script/dom/domimplementation.rs2
-rw-r--r--components/script/dom/domrectlist.rs8
-rw-r--r--components/script/dom/domtokenlist.rs8
-rw-r--r--components/script/dom/element.rs62
-rw-r--r--components/script/dom/eventdispatcher.rs21
-rw-r--r--components/script/dom/htmlcollection.rs14
-rw-r--r--components/script/dom/htmlelement.rs8
-rw-r--r--components/script/dom/htmlscriptelement.rs35
-rw-r--r--components/script/dom/keyboardevent.rs4
-rw-r--r--components/script/dom/macros.rs1
-rw-r--r--components/script/dom/mod.rs1
-rw-r--r--components/script/dom/navigator.rs4
-rw-r--r--components/script/dom/navigatorinfo.rs4
-rw-r--r--components/script/dom/node.rs18
-rw-r--r--components/script/dom/nodelist.rs3
-rw-r--r--components/script/dom/storage.rs98
-rw-r--r--components/script/dom/textencoder.rs94
-rw-r--r--components/script/dom/treewalker.rs12
-rw-r--r--components/script/dom/uievent.rs3
-rw-r--r--components/script/dom/urlsearchparams.rs9
-rw-r--r--components/script/dom/validitystate.rs1
-rw-r--r--components/script/dom/webidls/CSSStyleDeclaration.webidl6
-rw-r--r--components/script/dom/webidls/CanvasRenderingContext2D.webidl1
-rw-r--r--components/script/dom/webidls/EventHandler.webidl1
-rw-r--r--components/script/dom/webidls/Navigator.webidl2
-rw-r--r--components/script/dom/webidls/TextEncoder.webidl12
-rw-r--r--components/script/dom/websocket.rs2
-rw-r--r--components/script/dom/window.rs28
-rw-r--r--components/script/dom/worker.rs1
-rw-r--r--components/script/dom/workerglobalscope.rs5
-rw-r--r--components/script/dom/workerlocation.rs1
-rw-r--r--components/script/dom/workernavigator.rs5
40 files changed, 581 insertions, 183 deletions
diff --git a/components/script/dom/attr.rs b/components/script/dom/attr.rs
index f201c768187..a2b8ac77afe 100644
--- a/components/script/dom/attr.rs
+++ b/components/script/dom/attr.rs
@@ -3,8 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::cell::DOMRefCell;
-use dom::bindings::codegen::Bindings::AttrBinding;
-use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
+use dom::bindings::codegen::Bindings::AttrBinding::{self, AttrMethods};
use dom::bindings::codegen::InheritTypes::NodeCast;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, JSRef, Temporary};
@@ -41,7 +40,7 @@ pub enum AttrValue {
impl AttrValue {
pub fn from_serialized_tokenlist(tokens: DOMString) -> AttrValue {
let mut atoms: Vec<Atom> = vec!();
- for token in split_html_space_chars(tokens.as_slice()).map(|slice| Atom::from_slice(slice)) {
+ for token in split_html_space_chars(&tokens).map(Atom::from_slice) {
if !atoms.iter().any(|atom| *atom == token) {
atoms.push(token);
}
@@ -50,10 +49,7 @@ impl AttrValue {
}
pub fn from_atomic_tokens(atoms: Vec<Atom>) -> AttrValue {
- let tokens = {
- let slices: Vec<&str> = atoms.iter().map(|atom| atom.as_slice()).collect();
- slices.connect("\x20")
- };
+ let tokens = atoms.iter().map(Atom::as_slice).collect::<Vec<_>>().connect("\x20");
AttrValue::TokenList(tokens, atoms)
}
@@ -64,7 +60,7 @@ impl AttrValue {
}
pub fn from_atomic(string: DOMString) -> AttrValue {
- let value = Atom::from_slice(string.as_slice());
+ let value = Atom::from_slice(&string);
AttrValue::Atom(value)
}
@@ -80,13 +76,14 @@ impl Str for AttrValue {
fn as_slice<'a>(&'a self) -> &'a str {
match *self {
AttrValue::String(ref value) |
- AttrValue::TokenList(ref value, _) |
- AttrValue::UInt(ref value, _) => value.as_slice(),
- AttrValue::Atom(ref value) => value.as_slice(),
+ AttrValue::TokenList(ref value, _) |
+ AttrValue::UInt(ref value, _) => &value,
+ AttrValue::Atom(ref value) => &value,
}
}
}
+// https://dom.spec.whatwg.org/#interface-attr
#[dom_struct]
pub struct Attr {
reflector_: Reflector,
@@ -101,8 +98,7 @@ pub struct Attr {
}
impl Attr {
- fn new_inherited(local_name: Atom, value: AttrValue,
- name: Atom, namespace: Namespace,
+ fn new_inherited(local_name: Atom, value: AttrValue, name: Atom, namespace: Namespace,
prefix: Option<DOMString>, owner: Option<JSRef<Element>>) -> Attr {
Attr {
reflector_: Reflector::new(),
@@ -111,15 +107,17 @@ impl Attr {
name: name,
namespace: namespace,
prefix: prefix,
- owner: owner.map(|o| JS::from_rooted(o)),
+ owner: owner.map(JS::from_rooted),
}
}
pub fn new(window: JSRef<Window>, local_name: Atom, value: AttrValue,
name: Atom, namespace: Namespace,
prefix: Option<DOMString>, owner: Option<JSRef<Element>>) -> Temporary<Attr> {
- reflect_dom_object(box Attr::new_inherited(local_name, value, name, namespace, prefix, owner),
- GlobalRef::Window(window), AttrBinding::Wrap)
+ reflect_dom_object(
+ box Attr::new_inherited(local_name, value, name, namespace, prefix, owner),
+ GlobalRef::Window(window),
+ AttrBinding::Wrap)
}
#[inline]
@@ -139,19 +137,20 @@ impl Attr {
}
impl<'a> AttrMethods for JSRef<'a, Attr> {
+ // https://dom.spec.whatwg.org/#dom-attr-localname
fn LocalName(self) -> DOMString {
self.local_name().as_slice().to_owned()
}
+ // https://dom.spec.whatwg.org/#dom-attr-value
fn Value(self) -> DOMString {
self.value().as_slice().to_owned()
}
+ // https://dom.spec.whatwg.org/#dom-attr-value
fn SetValue(self, value: DOMString) {
match self.owner {
- None => {
- *self.value.borrow_mut() = AttrValue::String(value)
- }
+ None => *self.value.borrow_mut() = AttrValue::String(value),
Some(o) => {
let owner = o.root();
let value = owner.r().parse_attribute(&self.namespace, self.local_name(), value);
@@ -160,26 +159,32 @@ impl<'a> AttrMethods for JSRef<'a, Attr> {
}
}
+ // https://dom.spec.whatwg.org/#dom-attr-textcontent
fn TextContent(self) -> DOMString {
self.Value()
}
+ // https://dom.spec.whatwg.org/#dom-attr-textcontent
fn SetTextContent(self, value: DOMString) {
self.SetValue(value)
}
+ // https://dom.spec.whatwg.org/#dom-attr-nodevalue
fn NodeValue(self) -> DOMString {
self.Value()
}
+ // https://dom.spec.whatwg.org/#dom-attr-nodevalue
fn SetNodeValue(self, value: DOMString) {
self.SetValue(value)
}
+ // https://dom.spec.whatwg.org/#dom-attr-name
fn Name(self) -> DOMString {
self.name.as_slice().to_owned()
}
+ // https://dom.spec.whatwg.org/#dom-attr-namespaceuri
fn GetNamespaceURI(self) -> Option<DOMString> {
let Namespace(ref atom) = self.namespace;
match atom.as_slice() {
@@ -188,14 +193,17 @@ impl<'a> AttrMethods for JSRef<'a, Attr> {
}
}
+ // https://dom.spec.whatwg.org/#dom-attr-prefix
fn GetPrefix(self) -> Option<DOMString> {
self.prefix.clone()
}
+ // https://dom.spec.whatwg.org/#dom-attr-ownerelement
fn GetOwnerElement(self) -> Option<Temporary<Element>> {
self.owner.map(|o| Temporary::new(o))
}
+ // https://dom.spec.whatwg.org/#dom-attr-specified
fn Specified(self) -> bool {
true // Always returns true
}
diff --git a/components/script/dom/bindings/js.rs b/components/script/dom/bindings/js.rs
index f390a6444ee..84644a8428f 100644
--- a/components/script/dom/bindings/js.rs
+++ b/components/script/dom/bindings/js.rs
@@ -57,7 +57,7 @@ use js::jsval::JSVal;
use layout_interface::TrustedNodeAddress;
use script_task::STACK_ROOTS;
-use util::smallvec::{SmallVec, SmallVec16};
+use util::smallvec::{SmallVec, SmallVec24};
use core::nonzero::NonZero;
use std::cell::{Cell, UnsafeCell};
@@ -610,7 +610,7 @@ impl<T: Assignable<U>, U: Reflectable> TemporaryPushable<T> for Vec<JS<U>> {
/// See also [*Exact Stack Rooting - Storing a GCPointer on the CStack*]
/// (https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals/GC/Exact_Stack_Rooting).
pub struct RootCollection {
- roots: UnsafeCell<SmallVec16<*mut JSObject>>,
+ roots: UnsafeCell<SmallVec24<*mut JSObject>>,
}
/// A pointer to a RootCollection, for use in global variables.
@@ -622,7 +622,7 @@ impl RootCollection {
/// Create an empty collection of roots
pub fn new() -> RootCollection {
RootCollection {
- roots: UnsafeCell::new(SmallVec16::new()),
+ roots: UnsafeCell::new(SmallVec24::new()),
}
}
@@ -632,6 +632,7 @@ impl RootCollection {
let roots = self.roots.get();
(*roots).push(untracked.js_ptr);
debug!(" rooting {:?}", untracked.js_ptr);
+ assert!(!(*roots).spilled());
}
}
diff --git a/components/script/dom/bindings/str.rs b/components/script/dom/bindings/str.rs
index 88561210617..95ee01d8517 100644
--- a/components/script/dom/bindings/str.rs
+++ b/components/script/dom/bindings/str.rs
@@ -24,7 +24,7 @@ impl ByteString {
/// otherwise.
pub fn as_str<'a>(&'a self) -> Option<&'a str> {
let ByteString(ref vec) = *self;
- str::from_utf8(vec.as_slice()).ok()
+ str::from_utf8(&vec).ok()
}
/// Returns the underlying vector as a slice.
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs
index fe3129dce07..0dbe3bd4c78 100644
--- a/components/script/dom/bindings/trace.rs
+++ b/components/script/dom/bindings/trace.rs
@@ -57,11 +57,13 @@ use msg::constellation_msg::ConstellationChan;
use util::smallvec::{SmallVec1, SmallVec};
use util::str::{LengthOrPercentageOrAuto};
use std::cell::{Cell, RefCell};
-use std::collections::HashMap;
+use std::collections::{HashMap, HashSet};
use std::collections::hash_state::HashState;
use std::ffi::CString;
use std::hash::{Hash, Hasher};
+use std::intrinsics::return_address;
use std::old_io::timer::Timer;
+use std::ops::{Deref, DerefMut};
use std::rc::Rc;
use std::sync::mpsc::{Receiver, Sender};
use string_cache::{Atom, Namespace};
@@ -291,3 +293,135 @@ impl JSTraceable for Box<LayoutRPC+'static> {
// Do nothing
}
}
+
+/// Holds a set of vectors that need to be rooted
+pub struct RootedCollectionSet {
+ set: Vec<HashSet<*const RootedVec<()>>>
+}
+
+/// TLV Holds a set of vectors that need to be rooted
+thread_local!(pub static ROOTED_COLLECTIONS: Rc<RefCell<RootedCollectionSet>> =
+ Rc::new(RefCell::new(RootedCollectionSet::new())));
+
+enum CollectionType {
+ DOMObjects,
+ JSVals,
+ JSObjects,
+}
+
+
+impl RootedCollectionSet {
+ fn new() -> RootedCollectionSet {
+ RootedCollectionSet {
+ set: vec!(HashSet::new(), HashSet::new(), HashSet::new())
+ }
+ }
+
+ fn remove<T: VecRootableType>(collection: &RootedVec<T>) {
+ ROOTED_COLLECTIONS.with(|ref collections| {
+ let type_ = VecRootableType::tag(None::<T>);
+ let mut collections = collections.borrow_mut();
+ assert!(collections.set[type_ as uint].remove(&(collection as *const _ as *const _)));
+ });
+ }
+
+ fn add<T: VecRootableType>(collection: &RootedVec<T>) {
+ ROOTED_COLLECTIONS.with(|ref collections| {
+ let type_ = VecRootableType::tag(None::<T>);
+ let mut collections = collections.borrow_mut();
+ collections.set[type_ as uint].insert(collection as *const _ as *const _);
+ })
+ }
+
+ unsafe fn trace(&self, tracer: *mut JSTracer) {
+ fn trace_collection_type<T: JSTraceable>(tracer: *mut JSTracer,
+ collections: &HashSet<*const RootedVec<()>>) {
+ for collection in collections {
+ let collection: *const RootedVec<()> = *collection;
+ let collection = collection as *const RootedVec<T>;
+ unsafe {
+ let _ = (*collection).trace(tracer);
+ }
+ }
+ }
+
+ let dom_collections = &self.set[CollectionType::DOMObjects as uint] as *const _ as *const HashSet<*const RootedVec<*const Reflector>>;
+ for dom_collection in (*dom_collections).iter() {
+ for reflector in (**dom_collection).iter() {
+ trace_reflector(tracer, "", &**reflector);
+ }
+ }
+
+ trace_collection_type::<JSVal>(tracer, &self.set[CollectionType::JSVals as uint]);
+ trace_collection_type::<*mut JSObject>(tracer, &self.set[CollectionType::JSObjects as uint]);
+ }
+}
+
+
+/// Trait implemented by all types that can be used with RootedVec
+trait VecRootableType {
+ /// Return the type tag used to determine how to trace RootedVec
+ fn tag(_a: Option<Self>) -> CollectionType;
+}
+
+impl<T: Reflectable> VecRootableType for JS<T> {
+ fn tag(_a: Option<JS<T>>) -> CollectionType { CollectionType::DOMObjects }
+}
+
+impl VecRootableType for JSVal {
+ fn tag(_a: Option<JSVal>) -> CollectionType { CollectionType::JSVals }
+}
+
+impl VecRootableType for *mut JSObject {
+ fn tag(_a: Option<*mut JSObject>) -> CollectionType { CollectionType::JSObjects }
+}
+
+/// A vector of items that are rooted for the lifetime
+/// of this struct
+#[allow(unrooted_must_root)]
+#[jstraceable]
+pub struct RootedVec<T> {
+ v: Vec<T>
+}
+
+
+impl<T: VecRootableType> RootedVec<T> {
+ /// Create a vector of items of type T that is rooted for
+ /// the lifetime of this struct
+ pub fn new() -> RootedVec<T> {
+ unsafe {
+ RootedCollectionSet::add::<T>(&*(return_address() as *const _));
+ }
+ RootedVec::<T> { v: vec!() }
+ }
+
+}
+
+#[unsafe_destructor]
+impl<T: VecRootableType> Drop for RootedVec<T> {
+ fn drop(&mut self) {
+ RootedCollectionSet::remove(self);
+ }
+}
+
+impl<T> Deref for RootedVec<T> {
+ type Target = Vec<T>;
+ fn deref(&self) -> &Vec<T> {
+ &self.v
+ }
+}
+
+impl<T> DerefMut for RootedVec<T> {
+ fn deref_mut(&mut self) -> &mut Vec<T> {
+ &mut self.v
+ }
+}
+
+
+/// SM Callback that traces the rooted collections
+pub unsafe extern fn trace_collections(tracer: *mut JSTracer, _data: *mut libc::c_void) {
+ ROOTED_COLLECTIONS.with(|ref collections| {
+ let collections = collections.borrow();
+ collections.trace(tracer);
+ });
+}
diff --git a/components/script/dom/canvasgradient.rs b/components/script/dom/canvasgradient.rs
index 349d434114c..2b193697124 100644
--- a/components/script/dom/canvasgradient.rs
+++ b/components/script/dom/canvasgradient.rs
@@ -52,7 +52,7 @@ impl<'a> CanvasGradientMethods for JSRef<'a, CanvasGradient> {
self.stops.borrow_mut().push(CanvasGradientStop {
offset: (*offset) as f64,
- color: parse_color(color.as_slice()).unwrap_or(default_black),
+ color: parse_color(&color).unwrap_or(default_black),
});
}
}
diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs
index 6a3689e1459..4145c8e28cc 100644
--- a/components/script/dom/canvasrenderingcontext2d.rs
+++ b/components/script/dom/canvasrenderingcontext2d.rs
@@ -460,15 +460,21 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
Point2D(x as f32, y as f32))).unwrap();
}
- fn Arc(self, x: Finite<f64>, y: Finite<f64>, r: Finite<f64>, start: Finite<f64>, end: Finite<f64>, ccw: bool) {
+ fn Arc(self, x: Finite<f64>, y: Finite<f64>, r: Finite<f64>,
+ start: Finite<f64>, end: Finite<f64>, ccw: bool) -> Fallible<()> {
let x = *x;
let y = *y;
let r = *r;
let start = *start;
let end = *end;
+ if r < 0.0 {
+ return Err(IndexSize);
+ }
+
self.renderer.send(CanvasMsg::Arc(Point2D(x as f32, y as f32), r as f32,
start as f32, end as f32, ccw)).unwrap();
+ Ok(())
}
// https://html.spec.whatwg.org/#dom-context-2d-imagesmoothingenabled
@@ -493,7 +499,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
fn SetStrokeStyle(self, value: StringOrCanvasGradientOrCanvasPattern) {
match value {
StringOrCanvasGradientOrCanvasPattern::eString(string) => {
- match parse_color(string.as_slice()) {
+ match parse_color(&string) {
Ok(rgba) => {
self.stroke_color.set(rgba);
self.renderer
@@ -521,7 +527,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
fn SetFillStyle(self, value: StringOrCanvasGradientOrCanvasPattern) {
match value {
StringOrCanvasGradientOrCanvasPattern::eString(string) => {
- match parse_color(string.as_slice()) {
+ match parse_color(&string) {
Ok(rgba) => {
self.fill_color.set(rgba);
self.renderer
@@ -640,7 +646,7 @@ impl Drop for CanvasRenderingContext2D {
}
pub fn parse_color(string: &str) -> Result<RGBA,()> {
- match CSSColor::parse(&mut Parser::new(string.as_slice())) {
+ match CSSColor::parse(&mut Parser::new(&string)) {
Ok(CSSColor::RGBA(rgba)) => Ok(rgba),
_ => Err(()),
}
diff --git a/components/script/dom/cssstyledeclaration.rs b/components/script/dom/cssstyledeclaration.rs
index b41adcb8b06..c76ccee38fe 100644
--- a/components/script/dom/cssstyledeclaration.rs
+++ b/components/script/dom/cssstyledeclaration.rs
@@ -4,9 +4,7 @@
use dom::bindings::codegen::Bindings::CSSStyleDeclarationBinding::{self, CSSStyleDeclarationMethods};
use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast};
-use dom::bindings::error::Error;
-use dom::bindings::error::ErrorResult;
-use dom::bindings::error::Fallible;
+use dom::bindings::error::{Error, ErrorResult, Fallible};
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, JSRef, OptionalRootedRootable, Temporary};
use dom::bindings::utils::{Reflector, reflect_dom_object};
@@ -50,20 +48,14 @@ macro_rules! css_properties(
);
fn serialize_list(list: &Vec<PropertyDeclaration>) -> DOMString {
- let mut result = String::new();
- for declaration in list.iter() {
- result.push_str(serialize_value(declaration).as_slice());
- result.push_str(" ");
- }
- result
-}
-
-fn serialize_value(declaration: &PropertyDeclaration) -> DOMString {
- declaration.value()
+ list.iter().fold(String::new(), |accum, ref declaration| {
+ accum + &declaration.value() + " "
+ })
}
impl CSSStyleDeclaration {
- pub fn new_inherited(owner: JSRef<HTMLElement>, modification_access: CSSModificationAccess) -> CSSStyleDeclaration {
+ pub fn new_inherited(owner: JSRef<HTMLElement>,
+ modification_access: CSSModificationAccess) -> CSSStyleDeclaration {
CSSStyleDeclaration {
reflector_: Reflector::new(),
owner: JS::from_rooted(owner),
@@ -71,7 +63,8 @@ impl CSSStyleDeclaration {
}
}
- pub fn new(global: JSRef<Window>, owner: JSRef<HTMLElement>, modification_access: CSSModificationAccess) -> Temporary<CSSStyleDeclaration> {
+ pub fn new(global: JSRef<Window>, owner: JSRef<HTMLElement>,
+ modification_access: CSSModificationAccess) -> Temporary<CSSStyleDeclaration> {
reflect_dom_object(box CSSStyleDeclaration::new_inherited(owner, modification_access),
GlobalRef::Window(global),
CSSStyleDeclarationBinding::Wrap)
@@ -98,6 +91,7 @@ impl<'a> PrivateCSSStyleDeclarationHelpers for JSRef<'a, CSSStyleDeclaration> {
}
impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> {
+ // http://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-length
fn Length(self) -> u32 {
let owner = self.owner.root();
let elem: JSRef<Element> = ElementCast::from_ref(owner.r());
@@ -108,6 +102,7 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> {
len as u32
}
+ // http://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-item
fn Item(self, index: u32) -> DOMString {
let index = index as usize;
let owner = self.owner.root();
@@ -131,10 +126,10 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> {
// http://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertyvalue
fn GetPropertyValue(self, property: DOMString) -> DOMString {
// Step 1
- let property = Atom::from_slice(property.as_slice().to_ascii_lowercase().as_slice());
+ let property = Atom::from_slice(&property.to_ascii_lowercase());
// Step 2
- let longhand_properties = longhands_from_shorthand(property.as_slice());
+ let longhand_properties = longhands_from_shorthand(&property);
if let Some(longhand_properties) = longhand_properties {
// Step 2.1
let mut list = vec!();
@@ -142,7 +137,7 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> {
// Step 2.2
for longhand in longhand_properties.iter() {
// Step 2.2.1
- let declaration = self.get_declaration(&Atom::from_slice(longhand.as_slice()));
+ let declaration = self.get_declaration(&Atom::from_slice(&longhand));
// Step 2.2.2 & 2.2.3
match declaration {
@@ -157,7 +152,7 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> {
// Step 3 & 4
if let Some(ref declaration) = self.get_declaration(&property) {
- serialize_value(declaration)
+ declaration.value()
} else {
"".to_owned()
}
@@ -166,15 +161,15 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> {
// http://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertypriority
fn GetPropertyPriority(self, property: DOMString) -> DOMString {
// Step 1
- let property = Atom::from_slice(property.as_slice().to_ascii_lowercase().as_slice());
+ let property = Atom::from_slice(&property.to_ascii_lowercase());
// Step 2
- let longhand_properties = longhands_from_shorthand(property.as_slice());
+ let longhand_properties = longhands_from_shorthand(&property);
if let Some(longhand_properties) = longhand_properties {
// Step 2.1 & 2.2 & 2.3
if longhand_properties.iter()
.map(|longhand| self.GetPropertyPriority(longhand.clone()))
- .all(|priority| priority.as_slice() == "important") {
+ .all(|priority| priority == "important") {
return "important".to_owned();
}
@@ -196,10 +191,10 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> {
}
// Step 2
- let property = property.as_slice().to_ascii_lowercase();
+ let property = property.to_ascii_lowercase();
// Step 3
- if !is_supported_property(property.as_slice()) {
+ if !is_supported_property(&property) {
return Ok(());
}
@@ -209,20 +204,19 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> {
}
// Step 5
- let priority = priority.as_slice().to_ascii_lowercase();
- if priority.as_slice() != "!important" && !priority.is_empty() {
+ let priority = priority.to_ascii_lowercase();
+ if priority != "!important" && !priority.is_empty() {
return Ok(());
}
// Step 6
- let mut synthesized_declaration = String::from_str(property.as_slice());
+ let mut synthesized_declaration = String::from_str(&property);
synthesized_declaration.push_str(": ");
- synthesized_declaration.push_str(value.as_slice());
+ synthesized_declaration.push_str(&value);
let owner = self.owner.root();
let window = window_from_node(owner.r()).root();
- let decl_block = parse_style_attribute(synthesized_declaration.as_slice(),
- &window.r().get_url());
+ let decl_block = parse_style_attribute(&synthesized_declaration, &window.r().get_url());
// Step 7
if decl_block.normal.len() == 0 {
@@ -235,7 +229,11 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> {
// Step 8
for decl in decl_block.normal.iter() {
// Step 9
- let style_priority = if priority.is_empty() { StylePriority::Normal } else { StylePriority::Important };
+ let style_priority = if priority.is_empty() {
+ StylePriority::Normal
+ } else {
+ StylePriority::Important
+ };
element.update_inline_style(decl.clone(), style_priority);
}
@@ -253,29 +251,32 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> {
}
// Step 2
- let property = property.as_slice().to_ascii_lowercase();
+ let property = property.to_ascii_lowercase();
// Step 3
- if !is_supported_property(property.as_slice()) {
+ if !is_supported_property(&property) {
return Ok(());
}
// Step 4
- let priority = priority.as_slice().to_ascii_lowercase();
- if priority.as_slice() != "important" && !priority.is_empty() {
+ let priority = priority.to_ascii_lowercase();
+ if priority != "important" && !priority.is_empty() {
return Ok(());
}
let owner = self.owner.root();
let window = window_from_node(owner.r()).root();
- let decl_block = parse_style_attribute(property.as_slice(),
- &window.r().get_url());
+ let decl_block = parse_style_attribute(&property, &window.r().get_url());
let element: JSRef<Element> = ElementCast::from_ref(owner.r());
// Step 5
for decl in decl_block.normal.iter() {
// Step 6
- let style_priority = if priority.is_empty() { StylePriority::Normal } else { StylePriority::Important };
+ let style_priority = if priority.is_empty() {
+ StylePriority::Normal
+ } else {
+ StylePriority::Important
+ };
element.update_inline_style(decl.clone(), style_priority);
}
@@ -298,12 +299,12 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> {
}
// Step 2
- let property = property.as_slice().to_ascii_lowercase();
+ let property = property.to_ascii_lowercase();
// Step 3
let value = self.GetPropertyValue(property.clone());
- let longhand_properties = longhands_from_shorthand(property.as_slice());
+ let longhand_properties = longhands_from_shorthand(&property);
match longhand_properties {
Some(longhands) => {
// Step 4
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index 8ceb6ace1f3..debd6c0831a 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -323,7 +323,7 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> {
let node: JSRef<Node> = NodeCast::from_ref(element);
node.is_in_doc()
});
- assert!(!id.as_slice().is_empty());
+ assert!(!id.is_empty());
let mut idmap = self.idmap.borrow_mut();
diff --git a/components/script/dom/domimplementation.rs b/components/script/dom/domimplementation.rs
index 3353e735dfd..2b5bc3870c1 100644
--- a/components/script/dom/domimplementation.rs
+++ b/components/script/dom/domimplementation.rs
@@ -53,7 +53,7 @@ impl DOMImplementation {
impl<'a> DOMImplementationMethods for JSRef<'a, DOMImplementation> {
// http://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype
fn CreateDocumentType(self, qname: DOMString, pubid: DOMString, sysid: DOMString) -> Fallible<Temporary<DocumentType>> {
- match xml_name_type(qname.as_slice()) {
+ match xml_name_type(&qname) {
// Step 1.
InvalidXMLName => Err(InvalidCharacter),
// Step 2.
diff --git a/components/script/dom/domrectlist.rs b/components/script/dom/domrectlist.rs
index 8ef7b8fce52..ec70329e092 100644
--- a/components/script/dom/domrectlist.rs
+++ b/components/script/dom/domrectlist.rs
@@ -6,6 +6,7 @@ use dom::bindings::codegen::Bindings::DOMRectListBinding;
use dom::bindings::codegen::Bindings::DOMRectListBinding::DOMRectListMethods;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, JSRef, Temporary};
+use dom::bindings::trace::RootedVec;
use dom::bindings::utils::{Reflector, reflect_dom_object};
use dom::domrect::DOMRect;
use dom::window::Window;
@@ -19,17 +20,16 @@ pub struct DOMRectList {
impl DOMRectList {
fn new_inherited(window: JSRef<Window>,
- rects: Vec<JSRef<DOMRect>>) -> DOMRectList {
- let rects = rects.iter().map(|rect| JS::from_rooted(*rect)).collect();
+ rects: &RootedVec<JS<DOMRect>>) -> DOMRectList {
DOMRectList {
reflector_: Reflector::new(),
- rects: rects,
+ rects: (**rects).clone(),
window: JS::from_rooted(window),
}
}
pub fn new(window: JSRef<Window>,
- rects: Vec<JSRef<DOMRect>>) -> Temporary<DOMRectList> {
+ rects: &RootedVec<JS<DOMRect>>) -> Temporary<DOMRectList> {
reflect_dom_object(box DOMRectList::new_inherited(window, rects),
GlobalRef::Window(window), DOMRectListBinding::Wrap)
}
diff --git a/components/script/dom/domtokenlist.rs b/components/script/dom/domtokenlist.rs
index 2d0a4338be5..7d28c067acc 100644
--- a/components/script/dom/domtokenlist.rs
+++ b/components/script/dom/domtokenlist.rs
@@ -94,7 +94,7 @@ impl<'a> DOMTokenListMethods for JSRef<'a, DOMTokenList> {
// http://dom.spec.whatwg.org/#dom-domtokenlist-contains
fn Contains(self, token: DOMString) -> Fallible<bool> {
- self.check_token_exceptions(token.as_slice()).map(|token| {
+ self.check_token_exceptions(&token).map(|token| {
self.attribute().root().map(|attr| {
// FIXME(https://github.com/rust-lang/rust/issues/23338)
let attr = attr.r();
@@ -112,7 +112,7 @@ impl<'a> DOMTokenListMethods for JSRef<'a, DOMTokenList> {
let element = self.element.root();
let mut atoms = element.r().get_tokenlist_attribute(&self.local_name);
for token in tokens.iter() {
- let token = try!(self.check_token_exceptions(token.as_slice()));
+ let token = try!(self.check_token_exceptions(&token));
if !atoms.iter().any(|atom| *atom == token) {
atoms.push(token);
}
@@ -126,7 +126,7 @@ impl<'a> DOMTokenListMethods for JSRef<'a, DOMTokenList> {
let element = self.element.root();
let mut atoms = element.r().get_tokenlist_attribute(&self.local_name);
for token in tokens.iter() {
- let token = try!(self.check_token_exceptions(token.as_slice()));
+ let token = try!(self.check_token_exceptions(&token));
atoms.iter().position(|atom| *atom == token).map(|index| {
atoms.remove(index)
});
@@ -139,7 +139,7 @@ impl<'a> DOMTokenListMethods for JSRef<'a, DOMTokenList> {
fn Toggle(self, token: DOMString, force: Option<bool>) -> Fallible<bool> {
let element = self.element.root();
let mut atoms = element.r().get_tokenlist_attribute(&self.local_name);
- let token = try!(self.check_token_exceptions(token.as_slice()));
+ let token = try!(self.check_token_exceptions(&token));
match atoms.iter().position(|atom| *atom == token) {
Some(index) => match force {
Some(true) => Ok(true),
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index 016ba9a87c1..f69392a4126 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -28,7 +28,8 @@ use dom::bindings::codegen::InheritTypes::HTMLFormElementDerived;
use dom::bindings::error::{ErrorResult, Fallible};
use dom::bindings::error::Error::{NamespaceError, InvalidCharacter, Syntax};
use dom::bindings::js::{MutNullableJS, JS, JSRef, LayoutJS, Temporary, TemporaryPushable};
-use dom::bindings::js::{OptionalRootable, Root};
+use dom::bindings::js::OptionalRootable;
+use dom::bindings::trace::RootedVec;
use dom::bindings::utils::xml_name_type;
use dom::bindings::utils::XMLName::{QName, Name, InvalidXMLName};
use dom::create::create_element;
@@ -566,7 +567,7 @@ impl<'a> ElementHelpers<'a> for JSRef<'a, Element> {
declarations.normal
.iter()
.chain(declarations.important.iter())
- .find(|decl| decl.matches(property.as_slice()))
+ .find(|decl| decl.matches(&property))
.map(|decl| decl.clone())
})
}
@@ -576,7 +577,7 @@ impl<'a> ElementHelpers<'a> for JSRef<'a, Element> {
inline_declarations.as_ref().and_then(|declarations| {
declarations.important
.iter()
- .find(|decl| decl.matches(property.as_slice()))
+ .find(|decl| decl.matches(&property))
.map(|decl| decl.clone())
})
}
@@ -679,7 +680,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
None => qname.local.clone(),
Some(ref prefix) => {
let name = format!("{}:{}", *prefix, qname.local.as_slice());
- Atom::from_slice(name.as_slice())
+ Atom::from_slice(&name)
},
};
let value = self.parse_attribute(&qname.ns, &qname.local, value);
@@ -687,8 +688,8 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
}
fn set_attribute(self, name: &Atom, value: AttrValue) {
- assert!(name.as_slice() == name.as_slice().to_ascii_lowercase().as_slice());
- assert!(!name.as_slice().contains(":"));
+ assert!(name.as_slice() == name.to_ascii_lowercase());
+ assert!(!name.contains(":"));
self.do_set_attribute(name.clone(), value, name.clone(),
ns!(""), None, |attr| attr.local_name() == name);
@@ -697,7 +698,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
// https://html.spec.whatwg.org/multipage/dom.html#attr-data-*
fn set_custom_attribute(self, name: DOMString, value: DOMString) -> ErrorResult {
// Step 1.
- match xml_name_type(name.as_slice()) {
+ match xml_name_type(&name) {
InvalidXMLName => return Err(InvalidCharacter),
_ => {}
}
@@ -784,7 +785,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
};
let is_equal = |lhs: &Atom, rhs: &Atom| match quirks_mode {
NoQuirks | LimitedQuirks => lhs == rhs,
- Quirks => lhs.as_slice().eq_ignore_ascii_case(rhs.as_slice())
+ Quirks => lhs.eq_ignore_ascii_case(&rhs)
};
self.get_attribute(ns!(""), &atom!("class")).root().map(|attr| {
// FIXME(https://github.com/rust-lang/rust/issues/23338)
@@ -797,13 +798,13 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
}
fn set_atomic_attribute(self, name: &Atom, value: DOMString) {
- assert!(name.as_slice().eq_ignore_ascii_case(name.as_slice()));
+ assert!(name.as_slice() == name.to_ascii_lowercase());
let value = AttrValue::from_atomic(value);
self.set_attribute(name, value);
}
fn has_attribute(self, name: &Atom) -> bool {
- assert!(name.as_slice().bytes().all(|b| b.to_ascii_lowercase() == b));
+ assert!(name.bytes().all(|b| b.to_ascii_lowercase() == b));
// FIXME(https://github.com/rust-lang/rust/issues/23338)
let attrs = self.attrs.borrow();
attrs.iter().map(|attr| attr.root()).any(|attr| {
@@ -820,12 +821,12 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
if value {
self.set_string_attribute(name, String::new());
} else {
- self.remove_attribute(ns!(""), name.as_slice());
+ self.remove_attribute(ns!(""), &name);
}
}
fn get_url_attribute(self, name: &Atom) -> DOMString {
- assert!(name.as_slice() == name.as_slice().to_ascii_lowercase().as_slice());
+ assert!(name.as_slice() == name.to_ascii_lowercase());
if !self.has_attribute(name) {
return "".to_owned();
}
@@ -834,7 +835,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
let base = doc.r().url();
// https://html.spec.whatwg.org/multipage/infrastructure.html#reflect
// XXXManishearth this doesn't handle `javascript:` urls properly
- match UrlParser::new().base_url(&base).parse(url.as_slice()) {
+ match UrlParser::new().base_url(&base).parse(&url) {
Ok(parsed) => parsed.serialize(),
Err(_) => "".to_owned()
}
@@ -850,7 +851,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
}
}
fn set_string_attribute(self, name: &Atom, value: DOMString) {
- assert!(name.as_slice() == name.as_slice().to_ascii_lowercase().as_slice());
+ assert!(name.as_slice() == name.to_ascii_lowercase());
self.set_attribute(name, AttrValue::String(value));
}
@@ -866,17 +867,17 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
}
fn set_tokenlist_attribute(self, name: &Atom, value: DOMString) {
- assert!(name.as_slice() == name.as_slice().to_ascii_lowercase().as_slice());
+ assert!(name.as_slice() == name.to_ascii_lowercase());
self.set_attribute(name, AttrValue::from_serialized_tokenlist(value));
}
fn set_atomic_tokenlist_attribute(self, name: &Atom, tokens: Vec<Atom>) {
- assert!(name.as_slice() == name.as_slice().to_ascii_lowercase().as_slice());
+ assert!(name.as_slice() == name.to_ascii_lowercase());
self.set_attribute(name, AttrValue::from_atomic_tokens(tokens));
}
fn get_uint_attribute(self, name: &Atom) -> u32 {
- assert!(name.as_slice().chars().all(|ch| {
+ assert!(name.chars().all(|ch| {
!ch.is_ascii() || ch.to_ascii_lowercase() == ch
}));
let attribute = self.get_attribute(ns!(""), name).root();
@@ -892,7 +893,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
}
}
fn set_uint_attribute(self, name: &Atom, value: u32) {
- assert!(name.as_slice() == name.as_slice().to_ascii_lowercase().as_slice());
+ assert!(name.as_slice() == name.to_ascii_lowercase());
self.set_attribute(name, AttrValue::UInt(value.to_string(), value));
}
}
@@ -1114,17 +1115,18 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
fn GetClientRects(self) -> Temporary<DOMRectList> {
let win = window_from_node(self).root();
let node: JSRef<Node> = NodeCast::from_ref(self);
- let rects = node.get_content_boxes();
- let rects: Vec<Root<DOMRect>> = rects.iter().map(|r| {
- DOMRect::new(
- win.r(),
- r.origin.y,
- r.origin.y + r.size.height,
- r.origin.x,
- r.origin.x + r.size.width).root()
- }).collect();
+ let raw_rects = node.get_content_boxes();
+ let mut rects = RootedVec::new();
+ for rect in raw_rects.iter() {
+ let rect = DOMRect::new(win.r(),
+ rect.origin.y,
+ rect.origin.y + rect.size.height,
+ rect.origin.x,
+ rect.origin.x + rect.size.width);
+ rects.push(JS::from_rooted(rect));
+ }
- DOMRectList::new(win.r(), rects.iter().map(|rect| rect.r()).collect())
+ DOMRectList::new(win.r(), &rects)
}
// http://dev.w3.org/csswg/cssom-view/#dom-element-getboundingclientrect
@@ -1380,7 +1382,7 @@ impl<'a> VirtualMethods for JSRef<'a, Element> {
let doc = document_from_node(*self).root();
let value = attr.r().Value();
if !value.is_empty() {
- let value = Atom::from_slice(value.as_slice());
+ let value = Atom::from_slice(&value);
doc.r().register_named_element(*self, value);
}
}
@@ -1397,7 +1399,7 @@ impl<'a> VirtualMethods for JSRef<'a, Element> {
let doc = document_from_node(*self).root();
let value = attr.r().Value();
if !value.is_empty() {
- let value = Atom::from_slice(value.as_slice());
+ let value = Atom::from_slice(&value);
doc.r().unregister_named_element(*self, value);
}
}
diff --git a/components/script/dom/eventdispatcher.rs b/components/script/dom/eventdispatcher.rs
index 3518ff20eb6..029691f702c 100644
--- a/components/script/dom/eventdispatcher.rs
+++ b/components/script/dom/eventdispatcher.rs
@@ -4,8 +4,9 @@
use dom::bindings::callback::ExceptionHandling::Report;
use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
-use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast, NodeDerived};
-use dom::bindings::js::{JS, JSRef, OptionalRootable, Root};
+use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast};
+use dom::bindings::js::{JS, JSRef, OptionalRootable};
+use dom::bindings::trace::RootedVec;
use dom::eventtarget::{EventTarget, ListenerPhase};
use dom::event::{Event, EventPhase};
use dom::node::{Node, NodeHelpers};
@@ -27,15 +28,13 @@ pub fn dispatch_event<'a, 'b>(target: JSRef<'a, EventTarget>,
let type_ = event.Type();
//TODO: no chain if not participating in a tree
- let mut chain: Vec<Root<EventTarget>> = if target.is_node() {
- let target_node: JSRef<Node> = NodeCast::to_ref(target).unwrap();
- target_node.ancestors().map(|ancestor| {
+ let mut chain: RootedVec<JS<EventTarget>> = RootedVec::new();
+ if let Some(target_node) = NodeCast::to_ref(target) {
+ for ancestor in target_node.ancestors() {
let ancestor_target: JSRef<EventTarget> = EventTargetCast::from_ref(ancestor);
- JS::from_rooted(ancestor_target).root()
- }).collect()
- } else {
- vec!()
- };
+ chain.push(JS::from_rooted(ancestor_target))
+ }
+ }
event.set_phase(EventPhase::Capturing);
@@ -43,6 +42,7 @@ pub fn dispatch_event<'a, 'b>(target: JSRef<'a, EventTarget>,
/* capturing */
for cur_target in chain.as_slice().iter().rev() {
+ let cur_target = cur_target.root();
let stopped = match cur_target.r().get_listeners_for(type_.as_slice(), ListenerPhase::Capturing) {
Some(listeners) => {
event.set_current_target(cur_target.r());
@@ -88,6 +88,7 @@ pub fn dispatch_event<'a, 'b>(target: JSRef<'a, EventTarget>,
event.set_phase(EventPhase::Bubbling);
for cur_target in chain.iter() {
+ let cur_target = cur_target.root();
let stopped = match cur_target.r().get_listeners_for(type_.as_slice(), ListenerPhase::Bubbling) {
Some(listeners) => {
event.set_current_target(cur_target.r());
diff --git a/components/script/dom/htmlcollection.rs b/components/script/dom/htmlcollection.rs
index 29cd1dfbb74..a6e216cffdb 100644
--- a/components/script/dom/htmlcollection.rs
+++ b/components/script/dom/htmlcollection.rs
@@ -76,7 +76,7 @@ impl HTMLCollection {
pub fn by_tag_name(window: JSRef<Window>, root: JSRef<Node>, tag: DOMString)
-> Temporary<HTMLCollection> {
- if tag.as_slice() == "*" {
+ if tag == "*" {
return HTMLCollection::all_elements(window, root, None);
}
@@ -95,8 +95,8 @@ impl HTMLCollection {
}
}
let filter = TagNameFilter {
- tag: Atom::from_slice(tag.as_slice()),
- ascii_lower_tag: Atom::from_slice(tag.as_slice().to_ascii_lowercase().as_slice()),
+ tag: Atom::from_slice(&tag),
+ ascii_lower_tag: Atom::from_slice(&tag.to_ascii_lowercase()),
};
HTMLCollection::create(window, root, box filter)
}
@@ -104,11 +104,11 @@ impl HTMLCollection {
pub fn by_tag_name_ns(window: JSRef<Window>, root: JSRef<Node>, tag: DOMString,
maybe_ns: Option<DOMString>) -> Temporary<HTMLCollection> {
let namespace_filter = match maybe_ns {
- Some(ref namespace) if namespace.as_slice() == "*" => None,
+ Some(ref namespace) if namespace == &"*" => None,
ns => Some(namespace::from_domstring(ns)),
};
- if tag.as_slice() == "*" {
+ if tag == "*" {
return HTMLCollection::all_elements(window, root, namespace_filter);
}
#[jstraceable]
@@ -128,7 +128,7 @@ impl HTMLCollection {
}
}
let filter = TagNameNSFilter {
- tag: Atom::from_slice(tag.as_slice()),
+ tag: Atom::from_slice(&tag),
namespace_filter: namespace_filter
};
HTMLCollection::create(window, root, box filter)
@@ -146,7 +146,7 @@ impl HTMLCollection {
}
}
let filter = ClassNameFilter {
- classes: split_html_space_chars(classes.as_slice()).map(|class| {
+ classes: split_html_space_chars(&classes).map(|class| {
Atom::from_slice(class)
}).collect()
};
diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs
index a134b26584a..a0d0adaf82b 100644
--- a/components/script/dom/htmlelement.rs
+++ b/components/script/dom/htmlelement.rs
@@ -146,7 +146,7 @@ pub trait HTMLElementCustomAttributeHelpers {
fn to_snake_case(name: DOMString) -> DOMString {
let mut attr_name = "data-".to_owned();
- for ch in name.as_slice().chars() {
+ for ch in name.chars() {
if ch.is_uppercase() {
attr_name.push('\x2d');
attr_name.push(ch.to_lowercase());
@@ -170,7 +170,7 @@ impl<'a> HTMLElementCustomAttributeHelpers for JSRef<'a, HTMLElement> {
fn get_custom_attr(self, name: DOMString) -> Option<DOMString> {
let element: JSRef<Element> = ElementCast::from_ref(self);
- element.get_attribute(ns!(""), &Atom::from_slice(to_snake_case(name).as_slice())).map(|attr| {
+ element.get_attribute(ns!(""), &Atom::from_slice(&to_snake_case(name))).map(|attr| {
let attr = attr.root();
// FIXME(https://github.com/rust-lang/rust/issues/23338)
let attr = attr.r();
@@ -181,7 +181,7 @@ impl<'a> HTMLElementCustomAttributeHelpers for JSRef<'a, HTMLElement> {
fn delete_custom_attr(self, name: DOMString) {
let element: JSRef<Element> = ElementCast::from_ref(self);
- element.remove_attribute(ns!(""), to_snake_case(name).as_slice())
+ element.remove_attribute(ns!(""), &to_snake_case(name))
}
}
@@ -196,7 +196,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLElement> {
s.after_set_attr(attr);
}
- let name = attr.local_name().as_slice();
+ let name = attr.local_name();
if name.starts_with("on") {
let window = window_from_node(*self).root();
let (cx, url, reflector) = (window.r().get_cx(),
diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs
index 5d8f06c276a..8dca04ec736 100644
--- a/components/script/dom/htmlscriptelement.rs
+++ b/components/script/dom/htmlscriptelement.rs
@@ -202,25 +202,26 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> {
}
// Step 12.
- match element.get_attribute(ns!(""), &atom!("for")).root() {
- Some(for_script) => {
- if for_script.r().Value().to_ascii_lowercase().trim_matches(HTML_SPACE_CHARACTERS) != "window" {
+ let for_attribute = element.get_attribute(ns!(""), &atom!("for")).root();
+ let event_attribute = element.get_attribute(ns!(""), &Atom::from_slice("event")).root();
+ match (for_attribute.r(), event_attribute.r()) {
+ (Some(for_attribute), Some(event_attribute)) => {
+ let for_value = for_attribute.Value()
+ .to_ascii_lowercase();
+ let for_value = for_value.trim_matches(HTML_SPACE_CHARACTERS);
+ if for_value != "window" {
return;
}
- }
- _ => { }
- }
- match element.get_attribute(ns!(""), &Atom::from_slice("event")).root() {
- Some(event) => {
- let event = event.r().Value().to_ascii_lowercase();
- let event = event.trim_matches(HTML_SPACE_CHARACTERS);
- if event != "onload" && event != "onload()" {
+ let event_value = event_attribute.Value().to_ascii_lowercase();
+ let event_value = event_value.trim_matches(HTML_SPACE_CHARACTERS);
+ if event_value != "onload" && event_value != "onload()" {
return;
}
- }
- _ => { }
+ },
+ (_, _) => (),
}
+
// Step 13.
if let Some(charset) = element.get_attribute(ns!(""), &Atom::from_slice("charset")).root() {
if let Some(encodingRef) = encoding_from_whatwg_label(&charset.r().Value()) {
@@ -359,10 +360,10 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> {
} else {
let chan = window.r().script_chan();
let handler = Trusted::new(window.r().get_cx(), self, chan.clone());
- let dispatcher = Box::new(EventDispatcher {
+ let dispatcher = box EventDispatcher {
element: handler,
is_error: false,
- });
+ };
chan.send(ScriptMsg::RunnableMsg(dispatcher)).unwrap();
}
}
@@ -372,10 +373,10 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> {
let window = window.r();
let chan = window.script_chan();
let handler = Trusted::new(window.get_cx(), self, chan.clone());
- let dispatcher = Box::new(EventDispatcher {
+ let dispatcher = box EventDispatcher {
element: handler,
is_error: true,
- });
+ };
chan.send(ScriptMsg::RunnableMsg(dispatcher)).unwrap();
}
diff --git a/components/script/dom/keyboardevent.rs b/components/script/dom/keyboardevent.rs
index bd531cb61f2..d9ca779edc3 100644
--- a/components/script/dom/keyboardevent.rs
+++ b/components/script/dom/keyboardevent.rs
@@ -320,7 +320,7 @@ fn code_value(key: constellation_msg::Key) -> &'static str {
constellation_msg::Key::Num8 => "Digit8",
constellation_msg::Key::Num9 => "Digit9",
constellation_msg::Key::Semicolon => "Semicolon",
- constellation_msg::Key::Equal => "Equals",
+ constellation_msg::Key::Equal => "Equal",
constellation_msg::Key::A => "KeyA",
constellation_msg::Key::B => "KeyB",
constellation_msg::Key::C => "KeyC",
@@ -414,7 +414,7 @@ fn code_value(key: constellation_msg::Key) -> &'static str {
constellation_msg::Key::KpSubtract => "NumpadSubtract",
constellation_msg::Key::KpAdd => "NumpadAdd",
constellation_msg::Key::KpEnter => "NumpadEnter",
- constellation_msg::Key::KpEqual => "NumpadEquals",
+ constellation_msg::Key::KpEqual => "NumpadEqual",
constellation_msg::Key::LeftShift | constellation_msg::Key::RightShift => "Shift",
constellation_msg::Key::LeftControl | constellation_msg::Key::RightControl => "Control",
constellation_msg::Key::LeftAlt | constellation_msg::Key::RightAlt => "Alt",
diff --git a/components/script/dom/macros.rs b/components/script/dom/macros.rs
index 42f23b8c4b2..c29dede570d 100644
--- a/components/script/dom/macros.rs
+++ b/components/script/dom/macros.rs
@@ -227,5 +227,6 @@ macro_rules! global_event_handlers(
event_handler!(click, GetOnclick, SetOnclick);
event_handler!(input, GetOninput, SetOninput);
event_handler!(change, GetOnchange, SetOnchange);
+ event_handler!(submit, GetOnsubmit, SetOnsubmit);
)
);
diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs
index 1e70c1f73b3..f1f9c58fad8 100644
--- a/components/script/dom/mod.rs
+++ b/components/script/dom/mod.rs
@@ -312,6 +312,7 @@ pub mod servohtmlparser;
pub mod storage;
pub mod storageevent;
pub mod text;
+pub mod textencoder;
pub mod treewalker;
pub mod uievent;
pub mod urlhelper;
diff --git a/components/script/dom/navigator.rs b/components/script/dom/navigator.rs
index 257e1d2dfab..0b96e355a2f 100644
--- a/components/script/dom/navigator.rs
+++ b/components/script/dom/navigator.rs
@@ -54,5 +54,9 @@ impl<'a> NavigatorMethods for JSRef<'a, Navigator> {
fn UserAgent(self) -> DOMString {
navigatorinfo::UserAgent()
}
+
+ fn AppVersion(self) -> DOMString {
+ navigatorinfo::AppVersion()
+ }
}
diff --git a/components/script/dom/navigatorinfo.rs b/components/script/dom/navigatorinfo.rs
index 7dc94d85374..d4aec6999ab 100644
--- a/components/script/dom/navigatorinfo.rs
+++ b/components/script/dom/navigatorinfo.rs
@@ -33,3 +33,7 @@ pub fn UserAgent() -> DOMString {
None => "".to_owned(),
}
}
+
+pub fn AppVersion() -> DOMString {
+ "4.0".to_owned()
+}
diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs
index 67bb5279f32..ae79327e7da 100644
--- a/components/script/dom/node.rs
+++ b/components/script/dom/node.rs
@@ -700,14 +700,16 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> {
//
// TODO(cgaebel): This is a very conservative way to account for sibling
// selectors. Maybe we can do something smarter in the future.
- let parent =
- match self.parent_node() {
- None => return,
- Some(parent) => parent,
- };
-
- for sibling in parent.root().r().children() {
- sibling.set_has_dirty_siblings(true);
+ if !self.get_has_dirty_siblings() {
+ let parent =
+ match self.parent_node() {
+ None => return,
+ Some(parent) => parent,
+ };
+
+ for sibling in parent.root().r().children() {
+ sibling.set_has_dirty_siblings(true);
+ }
}
// 4. Dirty ancestors.
diff --git a/components/script/dom/nodelist.rs b/components/script/dom/nodelist.rs
index 319004e4b46..ec1e47caacb 100644
--- a/components/script/dom/nodelist.rs
+++ b/components/script/dom/nodelist.rs
@@ -17,6 +17,7 @@ pub enum NodeListType {
Children(JS<Node>)
}
+// https://dom.spec.whatwg.org/#interface-nodelist
#[dom_struct]
pub struct NodeList {
reflector_: Reflector,
@@ -47,6 +48,7 @@ impl NodeList {
}
impl<'a> NodeListMethods for JSRef<'a, NodeList> {
+ // https://dom.spec.whatwg.org/#dom-nodelist-length
fn Length(self) -> u32 {
match self.list_type {
NodeListType::Simple(ref elems) => elems.len() as u32,
@@ -57,6 +59,7 @@ impl<'a> NodeListMethods for JSRef<'a, NodeList> {
}
}
+ // https://dom.spec.whatwg.org/#dom-nodelist-item
fn Item(self, index: u32) -> Option<Temporary<Node>> {
match self.list_type {
_ if index >= self.Length() => None,
diff --git a/components/script/dom/storage.rs b/components/script/dom/storage.rs
index d15bb12b14a..191482c39c1 100644
--- a/components/script/dom/storage.rs
+++ b/components/script/dom/storage.rs
@@ -5,15 +5,27 @@
use dom::bindings::codegen::Bindings::StorageBinding;
use dom::bindings::codegen::Bindings::StorageBinding::StorageMethods;
use dom::bindings::global::{GlobalRef, GlobalField};
-use dom::bindings::js::{JSRef, Temporary};
+use dom::bindings::js::{JSRef, Temporary, RootedReference};
+use dom::bindings::refcounted::Trusted;
use dom::bindings::utils::{Reflector, reflect_dom_object};
+use dom::bindings::codegen::InheritTypes::{EventCast, EventTargetCast};
+use dom::event::{Event, EventHelpers, EventBubbles, EventCancelable};
+use dom::eventtarget::{EventTarget};
+use dom::storageevent::StorageEvent;
+use dom::urlhelper::UrlHelper;
+use dom::window::WindowHelpers;
use util::str::DOMString;
use net::storage_task::StorageTask;
use net::storage_task::StorageType;
use net::storage_task::StorageTaskMsg;
+use page::IterablePage;
use std::sync::mpsc::channel;
use url::Url;
+use script_task::{ScriptTask, ScriptMsg, MainThreadRunnable};
+
+use collections::borrow::ToOwned;
+
#[dom_struct]
pub struct Storage {
reflector_: Reflector,
@@ -79,9 +91,10 @@ impl<'a> StorageMethods for JSRef<'a, Storage> {
fn SetItem(self, name: DOMString, value: DOMString) {
let (sender, receiver) = channel();
- self.get_storage_task().send(StorageTaskMsg::SetItem(sender, self.get_url(), self.storage_type, name, value)).unwrap();
- if receiver.recv().unwrap() {
- //TODO send notification
+ self.get_storage_task().send(StorageTaskMsg::SetItem(sender, self.get_url(), self.storage_type, name.clone(), value.clone())).unwrap();
+ let (changed, old_value) = receiver.recv().unwrap();
+ if changed {
+ self.broadcast_change_notification(Some(name), old_value, Some(value));
}
}
@@ -96,9 +109,9 @@ impl<'a> StorageMethods for JSRef<'a, Storage> {
fn RemoveItem(self, name: DOMString) {
let (sender, receiver) = channel();
- self.get_storage_task().send(StorageTaskMsg::RemoveItem(sender, self.get_url(), self.storage_type, name)).unwrap();
- if receiver.recv().unwrap() {
- //TODO send notification
+ self.get_storage_task().send(StorageTaskMsg::RemoveItem(sender, self.get_url(), self.storage_type, name.clone())).unwrap();
+ if let Some(old_value) = receiver.recv().unwrap() {
+ self.broadcast_change_notification(Some(name), Some(old_value), None);
}
}
@@ -111,7 +124,76 @@ impl<'a> StorageMethods for JSRef<'a, Storage> {
self.get_storage_task().send(StorageTaskMsg::Clear(sender, self.get_url(), self.storage_type)).unwrap();
if receiver.recv().unwrap() {
- //TODO send notification
+ self.broadcast_change_notification(None, None, None);
+ }
+ }
+}
+
+trait PrivateStorageHelpers {
+ fn broadcast_change_notification(self, key: Option<DOMString>, old_value: Option<DOMString>,
+ new_value: Option<DOMString>);
+}
+
+impl<'a> PrivateStorageHelpers for JSRef<'a, Storage> {
+ /// https://html.spec.whatwg.org/multipage/webstorage.html#send-a-storage-notification
+ fn broadcast_change_notification(self, key: Option<DOMString>, old_value: Option<DOMString>,
+ new_value: Option<DOMString>){
+ let global_root = self.global.root();
+ let global_ref = global_root.r();
+ let script_chan = global_ref.script_chan();
+ let trusted_storage = Trusted::new(global_ref.get_cx(), self,
+ script_chan.clone());
+ script_chan.send(ScriptMsg::MainThreadRunnableMsg(
+ box StorageEventRunnable::new(trusted_storage, key,
+ old_value, new_value))).unwrap();
+ }
+}
+
+pub struct StorageEventRunnable {
+ element: Trusted<Storage>,
+ key: Option<DOMString>,
+ old_value: Option<DOMString>,
+ new_value: Option<DOMString>
+}
+
+impl StorageEventRunnable {
+ fn new(storage: Trusted<Storage>, key: Option<DOMString>, old_value: Option<DOMString>,
+ new_value: Option<DOMString>) -> StorageEventRunnable {
+ StorageEventRunnable { element: storage, key: key, old_value: old_value, new_value: new_value }
+ }
+}
+
+impl MainThreadRunnable for StorageEventRunnable {
+ fn handler(self: Box<StorageEventRunnable>, script_task: &ScriptTask) {
+ let this = *self;
+ let storage_root = this.element.to_temporary().root();
+ let storage = storage_root.r();
+ let global_root = storage.global.root();
+ let global_ref = global_root.r();
+ let ev_window = global_ref.as_window();
+ let ev_url = storage.get_url();
+
+ let storage_event = StorageEvent::new(
+ global_ref,
+ "storage".to_owned(),
+ EventBubbles::DoesNotBubble, EventCancelable::NotCancelable,
+ this.key, this.old_value, this.new_value,
+ ev_url.to_string(),
+ Some(storage)
+ ).root();
+ let event: JSRef<Event> = EventCast::from_ref(storage_event.r());
+
+ let root_page = script_task.root_page();
+ for it_page in root_page.iter() {
+ let it_window_root = it_page.window().root();
+ let it_window = it_window_root.r();
+ assert!(UrlHelper::SameOrigin(&ev_url, &it_window.get_url()));
+ // TODO: Such a Document object is not necessarily fully active, but events fired on such
+ // objects are ignored by the event loop until the Document becomes fully active again.
+ if ev_window.pipeline() != it_window.pipeline() {
+ let target: JSRef<EventTarget> = EventTargetCast::from_ref(it_window);
+ event.fire(target);
+ }
}
}
}
diff --git a/components/script/dom/textencoder.rs b/components/script/dom/textencoder.rs
new file mode 100644
index 00000000000..e568a6dfa75
--- /dev/null
+++ b/components/script/dom/textencoder.rs
@@ -0,0 +1,94 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use dom::bindings::codegen::Bindings::TextEncoderBinding;
+use dom::bindings::codegen::Bindings::TextEncoderBinding::TextEncoderMethods;
+use dom::bindings::global::GlobalRef;
+use dom::bindings::error::Fallible;
+use dom::bindings::error::Error::IndexSize;
+use dom::bindings::js::{JSRef, Temporary};
+use dom::bindings::str::USVString;
+use dom::bindings::utils::{Reflector, reflect_dom_object};
+
+use util::str::DOMString;
+
+use std::borrow::ToOwned;
+use std::ascii::AsciiExt;
+use std::ptr;
+
+use encoding::types::EncodingRef;
+use encoding::{Encoding, EncoderTrap};
+use encoding::label::encoding_from_whatwg_label;
+
+use libc::uint8_t;
+use js::jsapi::{JSContext, JSObject};
+use js::jsfriendapi::bindgen::{JS_NewUint8Array, JS_GetUint8ArrayData};
+
+#[dom_struct]
+pub struct TextEncoder {
+ reflector_: Reflector,
+ encoding: DOMString,
+ encoder: EncodingRef,
+}
+
+impl TextEncoder {
+ fn new_inherited(encoding: DOMString, encoder: EncodingRef) -> TextEncoder {
+ TextEncoder {
+ reflector_: Reflector::new(),
+ encoding: encoding,
+ encoder: encoder,
+ }
+ }
+
+ pub fn new(global: GlobalRef, encoding: DOMString, encoder: EncodingRef) -> Temporary<TextEncoder> {
+ reflect_dom_object(box TextEncoder::new_inherited(encoding, encoder),
+ global,
+ TextEncoderBinding::Wrap)
+ }
+
+ // https://encoding.spec.whatwg.org/#dom-textencoder
+ pub fn Constructor(global: GlobalRef,
+ label: DOMString) -> Fallible<Temporary<TextEncoder>> {
+ let encoding = match encoding_from_whatwg_label(label.trim().as_slice().to_ascii_lowercase().as_slice()) {
+ Some(enc) => enc,
+ None => {
+ debug!("Encoding Label Not Supported");
+ // TODO: should throw RangeError
+ return Err(IndexSize)
+ }
+ };
+
+ match encoding.name() {
+ "utf-8" | "utf-16be" | "utf-16le" => {
+ Ok(TextEncoder::new(global, encoding.name().to_owned(), encoding))
+ }
+ _ => {
+ debug!("Encoding Not UTF");
+ // TODO: should throw RangeError
+ Err(IndexSize)
+ }
+ }
+ }
+}
+
+impl<'a> TextEncoderMethods for JSRef<'a, TextEncoder> {
+ // https://encoding.spec.whatwg.org/#dom-textencoder-encoding
+ fn Encoding(self) -> DOMString {
+ self.encoding.clone()
+ }
+
+ // https://encoding.spec.whatwg.org/#dom-textencoder-encode
+ #[allow(unsafe_code)]
+ fn Encode(self, cx: *mut JSContext, input: USVString) -> *mut JSObject {
+ unsafe {
+ let output = self.encoder.encode(input.0.as_slice(), EncoderTrap::Strict).unwrap();
+ let length = output.len() as u32;
+ let js_object: *mut JSObject = JS_NewUint8Array(cx, length);
+
+ let js_object_data: *mut uint8_t = JS_GetUint8ArrayData(js_object, cx);
+ ptr::copy_nonoverlapping(js_object_data, output.as_ptr(), length as usize);
+ return js_object;
+ }
+ }
+}
diff --git a/components/script/dom/treewalker.rs b/components/script/dom/treewalker.rs
index f74e5f975b0..d13b730af0d 100644
--- a/components/script/dom/treewalker.rs
+++ b/components/script/dom/treewalker.rs
@@ -64,14 +64,17 @@ impl TreeWalker {
}
impl<'a> TreeWalkerMethods for JSRef<'a, TreeWalker> {
+ // https://dom.spec.whatwg.org/#dom-treewalker-root
fn Root(self) -> Temporary<Node> {
Temporary::new(self.root_node)
}
+ // https://dom.spec.whatwg.org/#dom-treewalker-whattoshow
fn WhatToShow(self) -> u32 {
self.what_to_show
}
+ // https://dom.spec.whatwg.org/#dom-treewalker-filter
fn GetFilter(self) -> Option<NodeFilter> {
match self.filter {
Filter::None => None,
@@ -80,38 +83,47 @@ impl<'a> TreeWalkerMethods for JSRef<'a, TreeWalker> {
}
}
+ // https://dom.spec.whatwg.org/#dom-treewalker-currentnode
fn CurrentNode(self) -> Temporary<Node> {
Temporary::new(self.current_node.get())
}
+ // https://dom.spec.whatwg.org/#dom-treewalker-currentnode
fn SetCurrentNode(self, node: JSRef<Node>) {
self.current_node.set(JS::from_rooted(node));
}
+ // https://dom.spec.whatwg.org/#dom-treewalker-parentnode
fn ParentNode(self) -> Fallible<Option<Temporary<Node>>> {
self.parent_node()
}
+ // https://dom.spec.whatwg.org/#dom-treewalker-firstchild
fn FirstChild(self) -> Fallible<Option<Temporary<Node>>> {
self.first_child()
}
+ // https://dom.spec.whatwg.org/#dom-treewalker-lastchild
fn LastChild(self) -> Fallible<Option<Temporary<Node>>> {
self.last_child()
}
+ // https://dom.spec.whatwg.org/#dom-treewalker-previoussibling
fn PreviousSibling(self) -> Fallible<Option<Temporary<Node>>> {
self.prev_sibling()
}
+ // https://dom.spec.whatwg.org/#dom-treewalker-nextsibling
fn NextSibling(self) -> Fallible<Option<Temporary<Node>>> {
self.next_sibling()
}
+ // https://dom.spec.whatwg.org/#dom-treewalker-previousnode
fn PreviousNode(self) -> Fallible<Option<Temporary<Node>>> {
self.prev_node()
}
+ // https://dom.spec.whatwg.org/#dom-treewalker-nextnode
fn NextNode(self) -> Fallible<Option<Temporary<Node>>> {
self.next_node()
}
diff --git a/components/script/dom/uievent.rs b/components/script/dom/uievent.rs
index c0f72600344..24d029cbce7 100644
--- a/components/script/dom/uievent.rs
+++ b/components/script/dom/uievent.rs
@@ -18,6 +18,7 @@ use util::str::DOMString;
use std::cell::Cell;
use std::default::Default;
+// https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#interface-UIEvent
#[dom_struct]
pub struct UIEvent {
event: Event,
@@ -70,10 +71,12 @@ impl UIEvent {
}
impl<'a> UIEventMethods for JSRef<'a, UIEvent> {
+ // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#widl-UIEvent-view
fn GetView(self) -> Option<Temporary<Window>> {
self.view.get()
}
+ // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#widl-UIEvent-detail
fn Detail(self) -> i32 {
self.detail.get()
}
diff --git a/components/script/dom/urlsearchparams.rs b/components/script/dom/urlsearchparams.rs
index 16f015554b0..0158b76a377 100644
--- a/components/script/dom/urlsearchparams.rs
+++ b/components/script/dom/urlsearchparams.rs
@@ -19,9 +19,8 @@ use encoding::types::{EncodingRef, EncoderTrap};
use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};
-use std::fmt::radix;
-use std::ascii::OwnedAsciiExt;
+// https://url.spec.whatwg.org/#interface-urlsearchparams
#[dom_struct]
pub struct URLSearchParams {
reflector_: Reflector,
@@ -41,6 +40,7 @@ impl URLSearchParams {
URLSearchParamsBinding::Wrap)
}
+ // https://url.spec.whatwg.org/#dom-urlsearchparams-urlsearchparams
pub fn Constructor(global: GlobalRef, init: Option<StringOrURLSearchParams>) ->
Fallible<Temporary<URLSearchParams>> {
let usp = URLSearchParams::new(global).root();
@@ -67,6 +67,7 @@ impl URLSearchParams {
}
impl<'a> URLSearchParamsMethods for JSRef<'a, URLSearchParams> {
+ // https://url.spec.whatwg.org/#dom-urlsearchparams-append
fn Append(self, name: DOMString, value: DOMString) {
let mut data = self.data.borrow_mut();
@@ -80,23 +81,27 @@ impl<'a> URLSearchParamsMethods for JSRef<'a, URLSearchParams> {
self.update_steps();
}
+ // https://url.spec.whatwg.org/#dom-urlsearchparams-delete
fn Delete(self, name: DOMString) {
self.data.borrow_mut().remove(&name);
self.update_steps();
}
+ // https://url.spec.whatwg.org/#dom-urlsearchparams-get
fn Get(self, name: DOMString) -> Option<DOMString> {
// FIXME(https://github.com/rust-lang/rust/issues/23338)
let data = self.data.borrow();
data.get(&name).map(|v| v[0].clone())
}
+ // https://url.spec.whatwg.org/#dom-urlsearchparams-has
fn Has(self, name: DOMString) -> bool {
// FIXME(https://github.com/rust-lang/rust/issues/23338)
let data = self.data.borrow();
data.contains_key(&name)
}
+ // https://url.spec.whatwg.org/#dom-urlsearchparams-set
fn Set(self, name: DOMString, value: DOMString) {
self.data.borrow_mut().insert(name, vec!(value));
self.update_steps();
diff --git a/components/script/dom/validitystate.rs b/components/script/dom/validitystate.rs
index 5e87e9de2b1..6088279c980 100644
--- a/components/script/dom/validitystate.rs
+++ b/components/script/dom/validitystate.rs
@@ -8,6 +8,7 @@ use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::utils::{Reflector, reflect_dom_object};
use dom::window::Window;
+// https://html.spec.whatwg.org/#validitystate
#[dom_struct]
pub struct ValidityState {
reflector_: Reflector,
diff --git a/components/script/dom/webidls/CSSStyleDeclaration.webidl b/components/script/dom/webidls/CSSStyleDeclaration.webidl
index 3be5abe1099..1da7946338b 100644
--- a/components/script/dom/webidls/CSSStyleDeclaration.webidl
+++ b/components/script/dom/webidls/CSSStyleDeclaration.webidl
@@ -186,4 +186,10 @@ partial interface CSSStyleDeclaration {
[TreatNullAs=EmptyString] attribute DOMString zIndex;
[TreatNullAs=EmptyString] attribute DOMString imageRendering;
+
+ [TreatNullAs=EmptyString] attribute DOMString transition;
+ [TreatNullAs=EmptyString] attribute DOMString transitionDuration;
+ [TreatNullAs=EmptyString] attribute DOMString transitionTimingFunction;
+ [TreatNullAs=EmptyString] attribute DOMString transitionProperty;
+ [TreatNullAs=EmptyString] attribute DOMString transitionDelay;
};
diff --git a/components/script/dom/webidls/CanvasRenderingContext2D.webidl b/components/script/dom/webidls/CanvasRenderingContext2D.webidl
index a3d40dc7c52..96624deb0fa 100644
--- a/components/script/dom/webidls/CanvasRenderingContext2D.webidl
+++ b/components/script/dom/webidls/CanvasRenderingContext2D.webidl
@@ -150,6 +150,7 @@ interface CanvasPathMethods {
//void rect(double x, double y, double w, double h);
+ [Throws]
void arc(double x, double y, double radius, double startAngle, double endAngle, optional boolean anticlockwise = false);
// NOT IMPLEMENTED [LenientFloat] void ellipse(double x, double y, double radiusX, double radiusY, double rotation, double startAngle, double endAngle, boolean anticlockwise);
};
diff --git a/components/script/dom/webidls/EventHandler.webidl b/components/script/dom/webidls/EventHandler.webidl
index de491455302..0ab01a113d4 100644
--- a/components/script/dom/webidls/EventHandler.webidl
+++ b/components/script/dom/webidls/EventHandler.webidl
@@ -25,6 +25,7 @@ interface GlobalEventHandlers {
attribute EventHandler onload;
attribute EventHandler oninput;
attribute EventHandler onchange;
+ attribute EventHandler onsubmit;
};
[NoInterfaceObject]
diff --git a/components/script/dom/webidls/Navigator.webidl b/components/script/dom/webidls/Navigator.webidl
index 0ce509f4c04..67b5cf95018 100644
--- a/components/script/dom/webidls/Navigator.webidl
+++ b/components/script/dom/webidls/Navigator.webidl
@@ -19,7 +19,7 @@ Navigator implements NavigatorID;
interface NavigatorID {
readonly attribute DOMString appCodeName; // constant "Mozilla"
readonly attribute DOMString appName;
- //readonly attribute DOMString appVersion;
+ readonly attribute DOMString appVersion;
readonly attribute DOMString platform;
readonly attribute DOMString product; // constant "Gecko"
boolean taintEnabled(); // constant false
diff --git a/components/script/dom/webidls/TextEncoder.webidl b/components/script/dom/webidls/TextEncoder.webidl
new file mode 100644
index 00000000000..697f7ca9146
--- /dev/null
+++ b/components/script/dom/webidls/TextEncoder.webidl
@@ -0,0 +1,12 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* https://encoding.spec.whatwg.org/#interface-textencoder */
+[Constructor(optional DOMString utfLabel = "utf-8")/*, Exposed=Window,Worker */]
+interface TextEncoder {
+ readonly attribute DOMString encoding;
+ [NewObject]
+ Uint8Array encode(optional USVString input = "");
+};
diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs
index da09b6bb767..1af70fa5f0b 100644
--- a/components/script/dom/websocket.rs
+++ b/components/script/dom/websocket.rs
@@ -11,6 +11,7 @@ use dom::bindings::utils::reflect_dom_object;
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use util::str::DOMString;
+// https://html.spec.whatwg.org/#the-websocket-interface
#[dom_struct]
pub struct WebSocket {
eventtarget: EventTarget,
@@ -37,6 +38,7 @@ impl WebSocket {
}
impl<'a> WebSocketMethods for JSRef<'a, WebSocket> {
+ // https://html.spec.whatwg.org/#dom-websocket-url
fn Url(self) -> DOMString {
self.url.clone()
}
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index ce7dc34e77d..08e526df282 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -27,7 +27,7 @@ use dom::performance::Performance;
use dom::screen::Screen;
use dom::storage::Storage;
use layout_interface::{ReflowGoal, ReflowQueryType, LayoutRPC, LayoutChan, Reflow, Msg};
-use layout_interface::{ContentBoxResponse, ContentBoxesResponse};
+use layout_interface::{ContentBoxResponse, ContentBoxesResponse, ScriptReflow};
use page::Page;
use script_task::{TimerSource, ScriptChan};
use script_task::ScriptMsg;
@@ -119,7 +119,7 @@ pub struct Window {
parent_info: Option<(PipelineId, SubpageId)>,
/// Unique id for last reflow request; used for confirming completion reply.
- last_reflow_id: Cell<uint>,
+ last_reflow_id: Cell<u32>,
/// Global static data related to the DOM.
dom_static: GlobalStaticData,
@@ -218,8 +218,7 @@ impl Window {
}
// http://www.whatwg.org/html/#atob
-pub fn base64_btoa(btoa: DOMString) -> Fallible<DOMString> {
- let input = btoa.as_slice();
+pub fn base64_btoa(input: DOMString) -> Fallible<DOMString> {
// "The btoa() method must throw an InvalidCharacterError exception if
// the method's first argument contains any character whose code point
// is greater than U+00FF."
@@ -239,10 +238,7 @@ pub fn base64_btoa(btoa: DOMString) -> Fallible<DOMString> {
}
// http://www.whatwg.org/html/#atob
-pub fn base64_atob(atob: DOMString) -> Fallible<DOMString> {
- // "Let input be the string being parsed."
- let input = atob.as_slice();
-
+pub fn base64_atob(input: DOMString) -> Fallible<DOMString> {
// "Remove all space characters from input."
// serialize::base64::from_base64 ignores \r and \n,
// but it treats the other space characters as
@@ -460,7 +456,7 @@ pub trait WindowHelpers {
fn layout(&self) -> &LayoutRPC;
fn content_box_query(self, content_box_request: TrustedNodeAddress) -> Rect<Au>;
fn content_boxes_query(self, content_boxes_request: TrustedNodeAddress) -> Vec<Rect<Au>>;
- fn handle_reflow_complete_msg(self, reflow_id: uint);
+ fn handle_reflow_complete_msg(self, reflow_id: u32);
fn handle_resize_inactive_msg(self, new_size: WindowSizeData);
fn set_fragment_name(self, fragment: Option<String>);
fn steal_fragment_name(self) -> Option<String>;
@@ -568,17 +564,19 @@ impl<'a> WindowHelpers for JSRef<'a, Window> {
}
// Send new document and relevant styles to layout.
- let reflow = box Reflow {
+ let reflow = box ScriptReflow {
+ reflow_info: Reflow {
+ goal: goal,
+ url: self.get_url(),
+ iframe: self.parent_info.is_some(),
+ page_clip_rect: self.page_clip_rect.get(),
+ },
document_root: root.to_trusted_node_address(),
- url: self.get_url(),
- iframe: self.parent_info.is_some(),
- goal: goal,
window_size: window_size,
script_chan: self.control_chan.clone(),
script_join_chan: join_chan,
id: last_reflow_id.get(),
query_type: query_type,
- page_clip_rect: self.page_clip_rect.get(),
};
let LayoutChan(ref chan) = self.layout_chan;
@@ -631,7 +629,7 @@ impl<'a> WindowHelpers for JSRef<'a, Window> {
rects
}
- fn handle_reflow_complete_msg(self, reflow_id: uint) {
+ fn handle_reflow_complete_msg(self, reflow_id: u32) {
let last_reflow_id = self.last_reflow_id.get();
if last_reflow_id == reflow_id {
*self.layout_join_port.borrow_mut() = None;
diff --git a/components/script/dom/worker.rs b/components/script/dom/worker.rs
index 274d4c1d906..5d422edf7e7 100644
--- a/components/script/dom/worker.rs
+++ b/components/script/dom/worker.rs
@@ -36,6 +36,7 @@ use std::sync::mpsc::{channel, Sender};
pub type TrustedWorkerAddress = Trusted<Worker>;
+// https://html.spec.whatwg.org/multipage/workers.html#worker
#[dom_struct]
pub struct Worker {
eventtarget: EventTarget,
diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs
index e0d8ae7aaa0..c24edd5ce36 100644
--- a/components/script/dom/workerglobalscope.rs
+++ b/components/script/dom/workerglobalscope.rs
@@ -39,6 +39,7 @@ pub enum WorkerGlobalScopeTypeId {
DedicatedGlobalScope,
}
+// https://html.spec.whatwg.org/multipage/workers.html#the-workerglobalscope-common-interface
#[dom_struct]
pub struct WorkerGlobalScope {
eventtarget: EventTarget,
@@ -96,16 +97,19 @@ impl WorkerGlobalScope {
}
impl<'a> WorkerGlobalScopeMethods for JSRef<'a, WorkerGlobalScope> {
+ // https://html.spec.whatwg.org/multipage/workers.html#dom-workerglobalscope-self
fn Self_(self) -> Temporary<WorkerGlobalScope> {
Temporary::from_rooted(self)
}
+ // https://html.spec.whatwg.org/multipage/workers.html#dom-workerglobalscope-location
fn Location(self) -> Temporary<WorkerLocation> {
self.location.or_init(|| {
WorkerLocation::new(self, self.worker_url.clone())
})
}
+ // https://html.spec.whatwg.org/multipage/workers.html#dom-workerglobalscope-importscripts
fn ImportScripts(self, url_strings: Vec<DOMString>) -> ErrorResult {
let mut urls = Vec::with_capacity(url_strings.len());
for url in url_strings.into_iter() {
@@ -138,6 +142,7 @@ impl<'a> WorkerGlobalScopeMethods for JSRef<'a, WorkerGlobalScope> {
Ok(())
}
+ // https://html.spec.whatwg.org/multipage/workers.html#dom-worker-navigator
fn Navigator(self) -> Temporary<WorkerNavigator> {
self.navigator.or_init(|| WorkerNavigator::new(self))
}
diff --git a/components/script/dom/workerlocation.rs b/components/script/dom/workerlocation.rs
index 1f176e2c7d9..0d82fc79098 100644
--- a/components/script/dom/workerlocation.rs
+++ b/components/script/dom/workerlocation.rs
@@ -13,6 +13,7 @@ use dom::workerglobalscope::WorkerGlobalScope;
use url::Url;
+// https://html.spec.whatwg.org/multipage/workers.html#worker-locations
#[dom_struct]
pub struct WorkerLocation {
reflector_: Reflector,
diff --git a/components/script/dom/workernavigator.rs b/components/script/dom/workernavigator.rs
index 203e2bd03fa..ea446f986cb 100644
--- a/components/script/dom/workernavigator.rs
+++ b/components/script/dom/workernavigator.rs
@@ -11,6 +11,7 @@ use dom::navigatorinfo;
use dom::workerglobalscope::WorkerGlobalScope;
use util::str::DOMString;
+// https://html.spec.whatwg.org/multipage/workers.html#workernavigator
#[dom_struct]
pub struct WorkerNavigator {
reflector_: Reflector,
@@ -54,5 +55,9 @@ impl<'a> WorkerNavigatorMethods for JSRef<'a, WorkerNavigator> {
fn UserAgent(self) -> DOMString {
navigatorinfo::UserAgent()
}
+
+ fn AppVersion(self) -> DOMString {
+ navigatorinfo::AppVersion()
+ }
}