diff options
Diffstat (limited to 'components/script/dom')
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() + } } |