aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom')
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py4
-rw-r--r--components/script/dom/bindings/conversions.rs31
-rw-r--r--components/script/dom/bindings/js.rs10
-rw-r--r--components/script/dom/bindings/utils.rs19
-rw-r--r--components/script/dom/browsercontext.rs17
-rw-r--r--components/script/dom/document.rs239
-rw-r--r--components/script/dom/domimplementation.rs21
-rw-r--r--components/script/dom/domparser.rs9
-rw-r--r--components/script/dom/domrect.rs83
-rw-r--r--components/script/dom/domrectreadonly.rs102
-rw-r--r--components/script/dom/domstringmap.rs9
-rw-r--r--components/script/dom/domtokenlist.rs22
-rw-r--r--components/script/dom/element.rs202
-rw-r--r--components/script/dom/htmlbodyelement.rs12
-rw-r--r--components/script/dom/htmlbuttonelement.rs44
-rw-r--r--components/script/dom/htmlelement.rs14
-rw-r--r--components/script/dom/htmlfieldsetelement.rs23
-rw-r--r--components/script/dom/htmlformelement.rs6
-rw-r--r--components/script/dom/htmlimageelement.rs1
-rw-r--r--components/script/dom/htmlinputelement.rs111
-rw-r--r--components/script/dom/htmloptgroupelement.rs24
-rw-r--r--components/script/dom/htmloptionelement.rs27
-rw-r--r--components/script/dom/htmlscriptelement.rs2
-rw-r--r--components/script/dom/htmlselectelement.rs29
-rw-r--r--components/script/dom/htmltablerowelement.rs20
-rw-r--r--components/script/dom/htmltablesectionelement.rs61
-rw-r--r--components/script/dom/htmltextareaelement.rs31
-rw-r--r--components/script/dom/location.rs83
-rw-r--r--components/script/dom/mod.rs1
-rw-r--r--components/script/dom/namednodemap.rs35
-rw-r--r--components/script/dom/node.rs250
-rw-r--r--components/script/dom/nodeiterator.rs7
-rw-r--r--components/script/dom/nodelist.rs12
-rw-r--r--components/script/dom/performance.rs2
-rw-r--r--components/script/dom/range.rs3
-rw-r--r--components/script/dom/servohtmlparser.rs29
-rw-r--r--components/script/dom/treewalker.rs3
-rw-r--r--components/script/dom/url.rs42
-rw-r--r--components/script/dom/urlhelper.rs19
-rw-r--r--components/script/dom/webidls/DOMRect.webidl17
-rw-r--r--components/script/dom/webidls/DOMRectReadOnly.webidl29
-rw-r--r--components/script/dom/webidls/Element.webidl4
-rw-r--r--components/script/dom/webidls/EventHandler.webidl1
-rw-r--r--components/script/dom/webidls/HTMLAnchorElement.webidl2
-rw-r--r--components/script/dom/webidls/HTMLAreaElement.webidl7
-rw-r--r--components/script/dom/webidls/HTMLHyperlinkElementUtils.webidl20
-rw-r--r--components/script/dom/webidls/HTMLTableRowElement.webidl6
-rw-r--r--components/script/dom/webidls/Location.webidl22
-rw-r--r--components/script/dom/webidls/URL.webidl20
-rw-r--r--components/script/dom/webidls/URLSearchParams.webidl4
-rw-r--r--components/script/dom/webidls/URLUtils.webidl28
-rw-r--r--components/script/dom/webidls/URLUtilsReadOnly.webidl26
-rw-r--r--components/script/dom/webidls/WebSocket.webidl2
-rw-r--r--components/script/dom/webidls/WorkerLocation.webidl18
-rw-r--r--components/script/dom/websocket.rs45
-rw-r--r--components/script/dom/window.rs11
-rw-r--r--components/script/dom/workerlocation.rs18
-rw-r--r--components/script/dom/xmlhttprequest.rs6
58 files changed, 1045 insertions, 900 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index 1d054d03f14..c71e0f354dc 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -5907,8 +5907,8 @@ pub trait %(derivedTrait)s: Sized {
impl %(name)sCast {
#[inline]
- /// Downcast an instance of a base class of `${name}` to an instance of
- /// `${name}`, if it internally is an instance of `${name}`
+ /// Downcast an instance of a base class of `%(name)s` to an instance of
+ /// `%(name)s`, if it internally is an instance of `%(name)s`
pub fn to_ref<T: %(derivedTrait)s + Reflectable>(base: &T) -> Option<&%(name)s> {
match base.%(methodName)s() {
true => Some(unsafe { mem::transmute(base) }),
diff --git a/components/script/dom/bindings/conversions.rs b/components/script/dom/bindings/conversions.rs
index 3805a0e76d3..eb9c1c81305 100644
--- a/components/script/dom/bindings/conversions.rs
+++ b/components/script/dom/bindings/conversions.rs
@@ -177,6 +177,7 @@ fn clamp_to<D>(d: f64) -> D
}
}
+//http://heycam.github.io/webidl/#es-void
impl ToJSValConvertible for () {
fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
rval.set(UndefinedValue());
@@ -217,12 +218,14 @@ fn convert_int_from_jsval<T, M>(cx: *mut JSContext, value: HandleValue,
}
}
+//http://heycam.github.io/webidl/#es-boolean
impl ToJSValConvertible for bool {
fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
rval.set(BooleanValue(*self));
}
}
+//http://heycam.github.io/webidl/#es-boolean
impl FromJSValConvertible for bool {
type Config = ();
fn from_jsval(_cx: *mut JSContext, val: HandleValue, _option: ()) -> Result<bool, ()> {
@@ -230,12 +233,14 @@ impl FromJSValConvertible for bool {
}
}
+//http://heycam.github.io/webidl/#es-byte
impl ToJSValConvertible for i8 {
fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
rval.set(Int32Value(*self as i32));
}
}
+//http://heycam.github.io/webidl/#es-byte
impl FromJSValConvertible for i8 {
type Config = ConversionBehavior;
fn from_jsval(cx: *mut JSContext, val: HandleValue, option: ConversionBehavior) -> Result<i8, ()> {
@@ -243,12 +248,14 @@ impl FromJSValConvertible for i8 {
}
}
+//http://heycam.github.io/webidl/#es-octet
impl ToJSValConvertible for u8 {
fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
rval.set(Int32Value(*self as i32));
}
}
+//http://heycam.github.io/webidl/#es-octet
impl FromJSValConvertible for u8 {
type Config = ConversionBehavior;
fn from_jsval(cx: *mut JSContext, val: HandleValue, option: ConversionBehavior) -> Result<u8, ()> {
@@ -256,12 +263,14 @@ impl FromJSValConvertible for u8 {
}
}
+//http://heycam.github.io/webidl/#es-short
impl ToJSValConvertible for i16 {
fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
rval.set(Int32Value(*self as i32));
}
}
+//http://heycam.github.io/webidl/#es-short
impl FromJSValConvertible for i16 {
type Config = ConversionBehavior;
fn from_jsval(cx: *mut JSContext, val: HandleValue, option: ConversionBehavior) -> Result<i16, ()> {
@@ -269,12 +278,14 @@ impl FromJSValConvertible for i16 {
}
}
+//http://heycam.github.io/webidl/#es-unsigned-short
impl ToJSValConvertible for u16 {
fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
rval.set(Int32Value(*self as i32));
}
}
+//http://heycam.github.io/webidl/#es-unsigned-short
impl FromJSValConvertible for u16 {
type Config = ConversionBehavior;
fn from_jsval(cx: *mut JSContext, val: HandleValue, option: ConversionBehavior) -> Result<u16, ()> {
@@ -282,12 +293,14 @@ impl FromJSValConvertible for u16 {
}
}
+//http://heycam.github.io/webidl/#es-long
impl ToJSValConvertible for i32 {
fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
rval.set(Int32Value(*self));
}
}
+//http://heycam.github.io/webidl/#es-long
impl FromJSValConvertible for i32 {
type Config = ConversionBehavior;
fn from_jsval(cx: *mut JSContext, val: HandleValue, option: ConversionBehavior) -> Result<i32, ()> {
@@ -295,12 +308,14 @@ impl FromJSValConvertible for i32 {
}
}
+//http://heycam.github.io/webidl/#es-unsigned-long
impl ToJSValConvertible for u32 {
fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
rval.set(UInt32Value(*self));
}
}
+//http://heycam.github.io/webidl/#es-unsigned-long
impl FromJSValConvertible for u32 {
type Config = ConversionBehavior;
fn from_jsval(cx: *mut JSContext, val: HandleValue, option: ConversionBehavior) -> Result<u32, ()> {
@@ -308,6 +323,7 @@ impl FromJSValConvertible for u32 {
}
}
+//http://heycam.github.io/webidl/#es-long-long
impl ToJSValConvertible for i64 {
fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
unsafe {
@@ -316,6 +332,7 @@ impl ToJSValConvertible for i64 {
}
}
+//http://heycam.github.io/webidl/#es-long-long
impl FromJSValConvertible for i64 {
type Config = ConversionBehavior;
fn from_jsval(cx: *mut JSContext, val: HandleValue, option: ConversionBehavior) -> Result<i64, ()> {
@@ -323,6 +340,7 @@ impl FromJSValConvertible for i64 {
}
}
+//http://heycam.github.io/webidl/#es-unsigned-long-long
impl ToJSValConvertible for u64 {
fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
unsafe {
@@ -331,6 +349,7 @@ impl ToJSValConvertible for u64 {
}
}
+//http://heycam.github.io/webidl/#es-unsigned-long-long
impl FromJSValConvertible for u64 {
type Config = ConversionBehavior;
fn from_jsval(cx: *mut JSContext, val: HandleValue, option: ConversionBehavior) -> Result<u64, ()> {
@@ -338,6 +357,7 @@ impl FromJSValConvertible for u64 {
}
}
+//http://heycam.github.io/webidl/#es-float
impl ToJSValConvertible for f32 {
fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
unsafe {
@@ -346,6 +366,7 @@ impl ToJSValConvertible for f32 {
}
}
+//http://heycam.github.io/webidl/#es-float
impl FromJSValConvertible for f32 {
type Config = ();
fn from_jsval(cx: *mut JSContext, val: HandleValue, _option: ()) -> Result<f32, ()> {
@@ -354,6 +375,7 @@ impl FromJSValConvertible for f32 {
}
}
+//http://heycam.github.io/webidl/#es-double
impl ToJSValConvertible for f64 {
fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
unsafe {
@@ -362,6 +384,7 @@ impl ToJSValConvertible for f64 {
}
}
+//http://heycam.github.io/webidl/#es-double
impl FromJSValConvertible for f64 {
type Config = ();
fn from_jsval(cx: *mut JSContext, val: HandleValue, _option: ()) -> Result<f64, ()> {
@@ -407,6 +430,7 @@ impl ToJSValConvertible for str {
}
}
+//http://heycam.github.io/webidl/#es-DOMString
impl ToJSValConvertible for DOMString {
fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
(**self).to_jsval(cx, rval);
@@ -484,6 +508,7 @@ pub fn jsid_to_str(cx: *mut JSContext, id: HandleId) -> DOMString {
}
}
+//http://heycam.github.io/webidl/#es-DOMString
impl FromJSValConvertible for DOMString {
type Config = StringificationBehavior;
fn from_jsval(cx: *mut JSContext, value: HandleValue,
@@ -504,12 +529,14 @@ impl FromJSValConvertible for DOMString {
}
}
+//http://heycam.github.io/webidl/#es-USVString
impl ToJSValConvertible for USVString {
fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
self.0.to_jsval(cx, rval);
}
}
+//http://heycam.github.io/webidl/#es-USVString
impl FromJSValConvertible for USVString {
type Config = ();
fn from_jsval(cx: *mut JSContext, value: HandleValue, _: ())
@@ -533,6 +560,7 @@ impl FromJSValConvertible for USVString {
}
}
+//http://heycam.github.io/webidl/#es-ByteString
impl ToJSValConvertible for ByteString {
fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
unsafe {
@@ -546,6 +574,7 @@ impl ToJSValConvertible for ByteString {
}
}
+//http://heycam.github.io/webidl/#es-ByteString
impl FromJSValConvertible for ByteString {
type Config = ();
fn from_jsval(cx: *mut JSContext, value: HandleValue, _option: ()) -> Result<ByteString, ()> {
@@ -586,6 +615,7 @@ impl FromJSValConvertible for ByteString {
}
}
+
impl ToJSValConvertible for Reflector {
fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
let obj = self.get_jsobject().get();
@@ -770,6 +800,7 @@ impl<T: FromJSValConvertible> FromJSValConvertible for Option<T> {
}
}
+//http://heycam.github.io/webidl/#es-object
impl ToJSValConvertible for *mut JSObject {
fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
rval.set(ObjectOrNullValue(*self));
diff --git a/components/script/dom/bindings/js.rs b/components/script/dom/bindings/js.rs
index aea80d88431..1ef1d93a86d 100644
--- a/components/script/dom/bindings/js.rs
+++ b/components/script/dom/bindings/js.rs
@@ -96,6 +96,16 @@ impl<T: Reflectable> JS<T> {
}
}
+impl<T: Reflectable> Deref for JS<T> {
+ type Target = T;
+
+ fn deref(&self) -> &T {
+ // We can only have &JS<T> from a rooted thing, so it's safe to deref
+ // it to &T.
+ unsafe { &**self.ptr }
+ }
+}
+
impl<T: Reflectable> JSTraceable for JS<T> {
fn trace(&self, trc: *mut JSTracer) {
trace_reflector(trc, "", unsafe { (**self.ptr).reflector() });
diff --git a/components/script/dom/bindings/utils.rs b/components/script/dom/bindings/utils.rs
index 7b430f1340e..af028ebfcbc 100644
--- a/components/script/dom/bindings/utils.rs
+++ b/components/script/dom/bindings/utils.rs
@@ -222,20 +222,21 @@ pub fn do_create_interface_objects(cx: *mut JSContext,
dom_class: Option<&'static DOMClass>,
members: &'static NativeProperties,
rval: MutableHandleObject) {
+ assert!(rval.get().is_null());
if let Some(proto_class) = proto_class {
create_interface_prototype_object(cx, proto_proto,
proto_class, members, rval);
- }
- if !rval.get().is_null() {
- let dom_class_ptr = match dom_class {
- Some(dom_class) => dom_class as *const DOMClass as *const libc::c_void,
- None => ptr::null() as *const libc::c_void,
- };
+ if !rval.get().is_null() {
+ let dom_class_ptr = match dom_class {
+ Some(dom_class) => dom_class as *const DOMClass as *const libc::c_void,
+ None => ptr::null() as *const libc::c_void,
+ };
- unsafe {
- JS_SetReservedSlot(rval.get(), DOM_PROTO_INSTANCE_CLASS_SLOT,
- PrivateValue(dom_class_ptr));
+ unsafe {
+ JS_SetReservedSlot(rval.get(), DOM_PROTO_INSTANCE_CLASS_SLOT,
+ PrivateValue(dom_class_ptr));
+ }
}
}
diff --git a/components/script/dom/browsercontext.rs b/components/script/dom/browsercontext.rs
index af2bfbdc81e..60dbdc5523e 100644
--- a/components/script/dom/browsercontext.rs
+++ b/components/script/dom/browsercontext.rs
@@ -44,17 +44,16 @@ impl BrowsingContext {
}
}
- pub fn active_document(&self) -> Root<Document> {
- self.history[self.active_index].document.root()
+ pub fn active_document(&self) -> &Document {
+ &*self.history[self.active_index].document
}
- pub fn active_window(&self) -> Root<Window> {
- let doc = self.active_document();
- doc.r().window()
+ pub fn active_window(&self) -> &Window {
+ self.active_document().window()
}
- pub fn frame_element(&self) -> Option<Root<Element>> {
- self.frame_element.as_ref().map(JS::root)
+ pub fn frame_element(&self) -> Option<&Element> {
+ self.frame_element.as_ref().map(|element| &**element)
}
pub fn window_proxy(&self) -> *mut JSObject {
@@ -64,8 +63,8 @@ impl BrowsingContext {
#[allow(unsafe_code)]
pub fn create_window_proxy(&mut self) {
- let win = self.active_window();
- let win = win.r();
+ // We inline self.active_window() because we can't borrow *self here.
+ let win = self.history[self.active_index].document.window();
let WindowProxyHandler(handler) = win.windowproxy_handler();
assert!(!handler.is_null());
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index 175cc68ea9d..8fe2fee79c5 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -232,8 +232,8 @@ impl Document {
}
#[inline]
- pub fn window(&self) -> Root<Window> {
- self.window.root()
+ pub fn window(&self) -> &Window {
+ &*self.window
}
#[inline]
@@ -248,13 +248,11 @@ impl Document {
// https://html.spec.whatwg.org/multipage/#fully-active
pub fn is_fully_active(&self) -> bool {
- let window = self.window.root();
- let window = window.r();
- let browsing_context = window.browsing_context();
+ let browsing_context = self.window.browsing_context();
let browsing_context = browsing_context.as_ref().unwrap();
let active_document = browsing_context.active_document();
- if self != active_document.r() {
+ if self != active_document {
return false;
}
// FIXME: It should also check whether the browser context is top-level or not
@@ -308,9 +306,7 @@ impl Document {
self.quirks_mode.set(mode);
if mode == Quirks {
- let window = self.window.root();
- let window = window.r();
- let LayoutChan(ref layout_chan) = window.layout_chan();
+ let LayoutChan(ref layout_chan) = self.window.layout_chan();
layout_chan.send(Msg::SetQuirksMode).unwrap();
}
}
@@ -336,10 +332,9 @@ impl Document {
}
self.reflow_timeout.set(None);
- let window = self.window.root();
- window.r().reflow(ReflowGoal::ForDisplay,
- ReflowQueryType::NoQuery,
- ReflowReason::RefreshTick);
+ self.window.reflow(ReflowGoal::ForDisplay,
+ ReflowQueryType::NoQuery,
+ ReflowReason::RefreshTick);
}
}
@@ -449,8 +444,7 @@ impl Document {
None => return None,
};
let root = NodeCast::from_ref(root);
- let win = self.window.root();
- let address = match win.r().layout().hit_test(root.to_trusted_node_address(), *point) {
+ let address = match self.window.layout().hit_test(root.to_trusted_node_address(), *point) {
Ok(HitTestResponse(node_address)) => Some(node_address),
Err(()) => {
debug!("layout query error");
@@ -467,8 +461,7 @@ impl Document {
None => return vec!(),
};
let root = NodeCast::from_ref(root);
- let win = self.window.root();
- match win.r().layout().mouse_over(root.to_trusted_node_address(), *point) {
+ match self.window.layout().mouse_over(root.to_trusted_node_address(), *point) {
Ok(MouseOverResponse(node_address)) => node_address,
Err(()) => vec!(),
}
@@ -478,8 +471,7 @@ impl Document {
pub fn set_ready_state(&self, state: DocumentReadyState) {
self.ready_state.set(state);
- let window = self.window.root();
- let event = Event::new(GlobalRef::Window(window.r()), "readystatechange".to_owned(),
+ let event = Event::new(GlobalRef::Window(&self.window), "readystatechange".to_owned(),
EventBubbles::DoesNotBubble,
EventCancelable::NotCancelable);
let target = EventTargetCast::from_ref(self);
@@ -516,22 +508,19 @@ impl Document {
//TODO: dispatch blur, focus, focusout, and focusin events
if let Some(ref elem) = self.focused.get_rooted() {
- let node = NodeCast::from_ref(elem.r());
- node.set_focus_state(false);
+ elem.set_focus_state(false);
}
self.focused.set(self.possibly_focused.get().r());
if let Some(ref elem) = self.focused.get_rooted() {
- let node = NodeCast::from_ref(elem.r());
- node.set_focus_state(true);
+ elem.set_focus_state(true);
// Update the focus state for all elements in the focus chain.
// https://html.spec.whatwg.org/multipage/#focus-chain
if focus_type == FocusType::Element {
- let window = self.window.root();
- let ConstellationChan(ref chan) = window.r().constellation_chan();
- let event = ConstellationMsg::Focus(window.r().pipeline());
+ let ConstellationChan(ref chan) = self.window.constellation_chan();
+ let event = ConstellationMsg::Focus(self.window.pipeline());
chan.send(event).unwrap();
}
}
@@ -548,8 +537,6 @@ impl Document {
/// Sends this document's title to the compositor.
pub fn send_title_to_compositor(&self) {
let window = self.window();
- // FIXME(https://github.com/rust-lang/rust/issues/23338)
- let window = window.r();
let compositor = window.compositor();
compositor.send(ScriptToCompositorMsg::SetTitle(window.pipeline(), Some(self.Title()))).unwrap();
}
@@ -593,24 +580,22 @@ impl Document {
debug!("{} on {:?}", mouse_event_type_string, node.debug_str());
// Prevent click event if form control element is disabled.
if let MouseEventType::Click = mouse_event_type {
- if node.click_event_filter_by_disabled_state() {
+ if el.click_event_filter_by_disabled_state() {
return;
}
self.begin_focus_transaction();
}
- let window = self.window.root();
-
// https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#event-type-click
let x = point.x as i32;
let y = point.y as i32;
let clickCount = 1;
- let event = MouseEvent::new(window.r(),
+ let event = MouseEvent::new(&self.window,
mouse_event_type_string,
EventBubbles::Bubbles,
EventCancelable::Cancelable,
- Some(window.r()),
+ Some(&self.window),
clickCount,
x, y, x, y,
false, false, false, false,
@@ -632,7 +617,9 @@ impl Document {
if let MouseEventType::Click = mouse_event_type {
self.commit_focus_transaction(FocusType::Element);
}
- window.r().reflow(ReflowGoal::ForDisplay, ReflowQueryType::NoQuery, ReflowReason::MouseEvent);
+ self.window.reflow(ReflowGoal::ForDisplay,
+ ReflowQueryType::NoQuery,
+ ReflowReason::MouseEvent);
}
pub fn fire_mouse_event(&self,
@@ -642,13 +629,11 @@ impl Document {
let x = point.x.to_i32().unwrap_or(0);
let y = point.y.to_i32().unwrap_or(0);
- let window = self.window.root();
-
- let mouse_event = MouseEvent::new(window.r(),
+ let mouse_event = MouseEvent::new(&self.window,
event_name,
EventBubbles::Bubbles,
EventCancelable::Cancelable,
- Some(window.r()),
+ Some(&self.window),
0i32,
x, y, x, y,
false, false, false, false,
@@ -661,15 +646,16 @@ impl Document {
pub fn handle_mouse_move_event(&self,
js_runtime: *mut JSRuntime,
point: Point2D<f32>,
- prev_mouse_over_targets: &mut RootedVec<JS<Node>>) {
+ prev_mouse_over_targets: &mut RootedVec<JS<Element>>) {
// Build a list of elements that are currently under the mouse.
let mouse_over_addresses = self.get_nodes_under_mouse(&point);
- let mut mouse_over_targets: RootedVec<JS<Node>> = RootedVec::new();
+ let mut mouse_over_targets: RootedVec<JS<Element>> = RootedVec::new();
for node_address in &mouse_over_addresses {
let node = node::from_untrusted_node_address(js_runtime, *node_address);
mouse_over_targets.push(node.r().inclusive_ancestors()
.find(|node| node.r().is_element())
- .map(|node| JS::from_rooted(&node)).unwrap());
+ .map(|node| JS::from_ref(ElementCast::to_ref(node.r()).unwrap()))
+ .unwrap());
};
// Remove hover from any elements in the previous list that are no longer
@@ -715,10 +701,9 @@ impl Document {
prev_mouse_over_targets.clear();
prev_mouse_over_targets.append(&mut *mouse_over_targets);
- let window = self.window.root();
- window.r().reflow(ReflowGoal::ForDisplay,
- ReflowQueryType::NoQuery,
- ReflowReason::MouseEvent);
+ self.window.reflow(ReflowGoal::ForDisplay,
+ ReflowQueryType::NoQuery,
+ ReflowReason::MouseEvent);
}
/// The entry point for all key processing for web content
@@ -727,14 +712,13 @@ impl Document {
state: KeyState,
modifiers: KeyModifiers,
compositor: &mut IpcSender<ScriptToCompositorMsg>) {
- let window = self.window.root();
let focused = self.get_focused_element();
let body = self.GetBody();
let target = match (&focused, &body) {
(&Some(ref focused), _) => EventTargetCast::from_ref(focused.r()),
(&None, &Some(ref body)) => EventTargetCast::from_ref(body.r()),
- (&None, &None) => EventTargetCast::from_ref(window.r()),
+ (&None, &None) => EventTargetCast::from_ref(&*self.window),
};
let ctrl = modifiers.contains(CONTROL);
@@ -751,8 +735,8 @@ impl Document {
let props = KeyboardEvent::key_properties(key, modifiers);
- let keyevent = KeyboardEvent::new(window.r(), ev_type, true, true,
- Some(window.r()), 0, Some(key),
+ let keyevent = KeyboardEvent::new(&self.window, ev_type, true, true,
+ Some(&self.window), 0, Some(key),
props.key_string.to_owned(), props.code.to_owned(),
props.location, is_repeating, is_composing,
ctrl, alt, shift, meta,
@@ -764,8 +748,8 @@ impl Document {
// https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#keys-cancelable-keys
if state != KeyState::Released && props.is_printable() && !prevented {
// https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#keypress-event-order
- let event = KeyboardEvent::new(window.r(), "keypress".to_owned(),
- true, true, Some(window.r()), 0, Some(key),
+ let event = KeyboardEvent::new(&self.window, "keypress".to_owned(),
+ true, true, Some(&self.window), 0, Some(key),
props.key_string.to_owned(), props.code.to_owned(),
props.location, is_repeating, is_composing,
ctrl, alt, shift, meta,
@@ -805,7 +789,9 @@ impl Document {
_ => ()
}
- window.r().reflow(ReflowGoal::ForDisplay, ReflowQueryType::NoQuery, ReflowReason::KeyEvent);
+ self.window.reflow(ReflowGoal::ForDisplay,
+ ReflowQueryType::NoQuery,
+ ReflowReason::KeyEvent);
}
pub fn node_from_nodes_and_strings(&self, nodes: Vec<NodeOrString>)
@@ -857,10 +843,8 @@ impl Document {
pub fn trigger_mozbrowser_event(&self, event: MozBrowserEvent) {
if htmliframeelement::mozbrowser_enabled() {
- let window = self.window.root();
-
- if let Some((containing_pipeline_id, subpage_id)) = window.r().parent_info() {
- let ConstellationChan(ref chan) = window.r().constellation_chan();
+ if let Some((containing_pipeline_id, subpage_id)) = self.window.parent_info() {
+ let ConstellationChan(ref chan) = self.window.constellation_chan();
let event = ConstellationMsg::MozBrowserEvent(containing_pipeline_id,
subpage_id,
event);
@@ -871,16 +855,14 @@ impl Document {
/// https://html.spec.whatwg.org/multipage/#dom-window-requestanimationframe
pub fn request_animation_frame(&self, callback: Box<FnBox(f64)>) -> u32 {
- let window = self.window.root();
- let window = window.r();
let ident = self.animation_frame_ident.get() + 1;
self.animation_frame_ident.set(ident);
self.animation_frame_list.borrow_mut().insert(ident, callback);
// TODO: Should tick animation only when document is visible
- let ConstellationChan(ref chan) = window.constellation_chan();
- let event = ConstellationMsg::ChangeRunningAnimationsState(window.pipeline(),
+ let ConstellationChan(ref chan) = self.window.constellation_chan();
+ let event = ConstellationMsg::ChangeRunningAnimationsState(self.window.pipeline(),
AnimationState::AnimationCallbacksPresent);
chan.send(event).unwrap();
@@ -891,10 +873,8 @@ impl Document {
pub fn cancel_animation_frame(&self, ident: u32) {
self.animation_frame_list.borrow_mut().remove(&ident);
if self.animation_frame_list.borrow().is_empty() {
- let window = self.window.root();
- let window = window.r();
- let ConstellationChan(ref chan) = window.constellation_chan();
- let event = ConstellationMsg::ChangeRunningAnimationsState(window.pipeline(),
+ let ConstellationChan(ref chan) = self.window.constellation_chan();
+ let event = ConstellationMsg::ChangeRunningAnimationsState(self.window.pipeline(),
AnimationState::NoAnimationCallbacksPresent);
chan.send(event).unwrap();
}
@@ -907,16 +887,12 @@ impl Document {
let mut list = self.animation_frame_list.borrow_mut();
animation_frame_list = Vec::from_iter(list.drain());
- let window = self.window.root();
- let window = window.r();
- let ConstellationChan(ref chan) = window.constellation_chan();
- let event = ConstellationMsg::ChangeRunningAnimationsState(window.pipeline(),
+ let ConstellationChan(ref chan) = self.window.constellation_chan();
+ let event = ConstellationMsg::ChangeRunningAnimationsState(self.window.pipeline(),
AnimationState::NoAnimationCallbacksPresent);
chan.send(event).unwrap();
}
- let window = self.window.root();
- let window = window.r();
- let performance = window.Performance();
+ let performance = self.window.Performance();
let performance = performance.r();
let timing = performance.Now();
@@ -924,9 +900,9 @@ impl Document {
callback(*timing);
}
- window.reflow(ReflowGoal::ForDisplay,
- ReflowQueryType::NoQuery,
- ReflowReason::RequestAnimationFrame);
+ self.window.reflow(ReflowGoal::ForDisplay,
+ ReflowQueryType::NoQuery,
+ ReflowReason::RequestAnimationFrame);
}
pub fn prepare_async_load(&self, load: LoadType) -> PendingAsyncLoad {
@@ -950,9 +926,8 @@ impl Document {
}
pub fn notify_constellation_load(&self) {
- let window = self.window.root();
- let pipeline_id = window.r().pipeline();
- let ConstellationChan(ref chan) = window.r().constellation_chan();
+ let pipeline_id = self.window.pipeline();
+ let ConstellationChan(ref chan) = self.window.constellation_chan();
let event = ConstellationMsg::DOMLoad(pipeline_id);
chan.send(event).unwrap();
@@ -1093,12 +1068,11 @@ impl Document {
}
fn create_node_list<F: Fn(&Node) -> bool>(&self, callback: F) -> Root<NodeList> {
- let window = self.window.root();
let doc = self.GetDocumentElement();
let maybe_node = doc.r().map(NodeCast::from_ref);
let iter = maybe_node.iter().flat_map(|node| node.traverse_preorder())
.filter(|node| callback(node.r()));
- NodeList::new_simple_list(window.r(), iter)
+ NodeList::new_simple_list(&self.window, iter)
}
fn get_html_element(&self) -> Option<Root<HTMLHtmlElement>> {
@@ -1117,7 +1091,7 @@ impl Document {
IsHTMLDocument::NonHTMLDocument
};
let new_doc = Document::new(
- &*self.window(), None, doctype, None, None,
+ self.window(), None, doctype, None, None,
DocumentSource::NotFromParser, DocumentLoader::new(&self.loader()));
new_doc.appropriate_template_contents_owner_document.set(Some(&new_doc));
new_doc
@@ -1126,9 +1100,10 @@ impl Document {
}
-impl Node {
+impl Element {
fn click_event_filter_by_disabled_state(&self) -> bool {
- match self.type_id() {
+ let node = NodeCast::from_ref(self);
+ match node.type_id() {
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLButtonElement)) |
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement)) |
// NodeTypeId::Element(ElementTypeId::HTMLKeygenElement) |
@@ -1168,9 +1143,7 @@ impl DocumentMethods for Document {
// https://html.spec.whatwg.org/multipage/#dom-document-hasfocus
fn HasFocus(&self) -> bool {
let target = self; // Step 1.
- let window = self.window.root();
- let window = window.r();
- let browsing_context = window.browsing_context();
+ let browsing_context = self.window.browsing_context();
let browsing_context = browsing_context.as_ref();
match browsing_context {
@@ -1230,22 +1203,18 @@ impl DocumentMethods for Document {
// https://dom.spec.whatwg.org/#dom-document-getelementsbytagname
fn GetElementsByTagName(&self, tag_name: DOMString) -> Root<HTMLCollection> {
- let window = self.window.root();
- HTMLCollection::by_tag_name(window.r(), NodeCast::from_ref(self), tag_name)
+ HTMLCollection::by_tag_name(&self.window, NodeCast::from_ref(self), tag_name)
}
// https://dom.spec.whatwg.org/#dom-document-getelementsbytagnamens
fn GetElementsByTagNameNS(&self, maybe_ns: Option<DOMString>, tag_name: DOMString)
-> Root<HTMLCollection> {
- let window = self.window.root();
- HTMLCollection::by_tag_name_ns(window.r(), NodeCast::from_ref(self), tag_name, maybe_ns)
+ HTMLCollection::by_tag_name_ns(&self.window, NodeCast::from_ref(self), tag_name, maybe_ns)
}
// https://dom.spec.whatwg.org/#dom-document-getelementsbyclassname
fn GetElementsByClassName(&self, classes: DOMString) -> Root<HTMLCollection> {
- let window = self.window.root();
-
- HTMLCollection::by_class_name(window.r(), NodeCast::from_ref(self), classes)
+ HTMLCollection::by_class_name(&self.window, NodeCast::from_ref(self), classes)
}
// https://dom.spec.whatwg.org/#dom-nonelementparentnode-getelementbyid
@@ -1284,13 +1253,12 @@ impl DocumentMethods for Document {
return Err(Error::InvalidCharacter);
}
- let window = self.window.root();
let name = Atom::from_slice(&local_name);
// repetition used because string_cache::atom::Atom is non-copyable
let l_name = Atom::from_slice(&local_name);
let value = AttrValue::String("".to_owned());
- Ok(Attr::new(window.r(), name, value, l_name, ns!(""), None, None))
+ Ok(Attr::new(&self.window, name, value, l_name, ns!(""), None, None))
}
// https://dom.spec.whatwg.org/#dom-document-createattributens
@@ -1298,10 +1266,9 @@ impl DocumentMethods for Document {
-> Fallible<Root<Attr>> {
let (namespace, prefix, local_name) =
try!(validate_and_extract(namespace, &qualified_name));
- let window = self.window.root();
let value = AttrValue::String("".to_owned());
let qualified_name = Atom::from_slice(&qualified_name);
- Ok(Attr::new(window.r(), local_name, value, qualified_name,
+ Ok(Attr::new(&self.window, local_name, value, qualified_name,
namespace, prefix, None))
}
@@ -1369,22 +1336,20 @@ impl DocumentMethods for Document {
// https://dom.spec.whatwg.org/#dom-document-createevent
fn CreateEvent(&self, mut interface: DOMString) -> Fallible<Root<Event>> {
- let window = self.window.root();
-
interface.make_ascii_lowercase();
match &*interface {
"uievents" | "uievent" => Ok(EventCast::from_root(
- UIEvent::new_uninitialized(window.r()))),
+ UIEvent::new_uninitialized(&self.window))),
"mouseevents" | "mouseevent" => Ok(EventCast::from_root(
- MouseEvent::new_uninitialized(window.r()))),
+ MouseEvent::new_uninitialized(&self.window))),
"customevent" => Ok(EventCast::from_root(
- CustomEvent::new_uninitialized(GlobalRef::Window(window.r())))),
+ CustomEvent::new_uninitialized(GlobalRef::Window(&self.window)))),
"htmlevents" | "events" | "event" => Ok(Event::new_uninitialized(
- GlobalRef::Window(window.r()))),
+ GlobalRef::Window(&self.window))),
"keyboardevent" | "keyevents" => Ok(EventCast::from_root(
- KeyboardEvent::new_uninitialized(window.r()))),
+ KeyboardEvent::new_uninitialized(&self.window))),
"messageevent" => Ok(EventCast::from_root(
- MessageEvent::new_uninitialized(GlobalRef::Window(window.r())))),
+ MessageEvent::new_uninitialized(GlobalRef::Window(&self.window)))),
_ => Err(Error::NotSupported)
}
}
@@ -1585,20 +1550,18 @@ impl DocumentMethods for Document {
// https://html.spec.whatwg.org/multipage/#dom-document-images
fn Images(&self) -> Root<HTMLCollection> {
self.images.or_init(|| {
- let window = self.window.root();
let root = NodeCast::from_ref(self);
let filter = box ImagesFilter;
- HTMLCollection::create(window.r(), root, filter)
+ HTMLCollection::create(&self.window, root, filter)
})
}
// https://html.spec.whatwg.org/multipage/#dom-document-embeds
fn Embeds(&self) -> Root<HTMLCollection> {
self.embeds.or_init(|| {
- let window = self.window.root();
let root = NodeCast::from_ref(self);
let filter = box EmbedsFilter;
- HTMLCollection::create(window.r(), root, filter)
+ HTMLCollection::create(&self.window, root, filter)
})
}
@@ -1610,40 +1573,36 @@ impl DocumentMethods for Document {
// https://html.spec.whatwg.org/multipage/#dom-document-links
fn Links(&self) -> Root<HTMLCollection> {
self.links.or_init(|| {
- let window = self.window.root();
let root = NodeCast::from_ref(self);
let filter = box LinksFilter;
- HTMLCollection::create(window.r(), root, filter)
+ HTMLCollection::create(&self.window, root, filter)
})
}
// https://html.spec.whatwg.org/multipage/#dom-document-forms
fn Forms(&self) -> Root<HTMLCollection> {
self.forms.or_init(|| {
- let window = self.window.root();
let root = NodeCast::from_ref(self);
let filter = box FormsFilter;
- HTMLCollection::create(window.r(), root, filter)
+ HTMLCollection::create(&self.window, root, filter)
})
}
// https://html.spec.whatwg.org/multipage/#dom-document-scripts
fn Scripts(&self) -> Root<HTMLCollection> {
self.scripts.or_init(|| {
- let window = self.window.root();
let root = NodeCast::from_ref(self);
let filter = box ScriptsFilter;
- HTMLCollection::create(window.r(), root, filter)
+ HTMLCollection::create(&self.window, root, filter)
})
}
// https://html.spec.whatwg.org/multipage/#dom-document-anchors
fn Anchors(&self) -> Root<HTMLCollection> {
self.anchors.or_init(|| {
- let window = self.window.root();
let root = NodeCast::from_ref(self);
let filter = box AnchorsFilter;
- HTMLCollection::create(window.r(), root, filter)
+ HTMLCollection::create(&self.window, root, filter)
})
}
@@ -1651,24 +1610,20 @@ impl DocumentMethods for Document {
fn Applets(&self) -> Root<HTMLCollection> {
// FIXME: This should be return OBJECT elements containing applets.
self.applets.or_init(|| {
- let window = self.window.root();
let root = NodeCast::from_ref(self);
let filter = box AppletsFilter;
- HTMLCollection::create(window.r(), root, filter)
+ HTMLCollection::create(&self.window, root, filter)
})
}
// https://html.spec.whatwg.org/multipage/#dom-document-location
fn Location(&self) -> Root<Location> {
- let window = self.window.root();
- let window = window.r();
- self.location.or_init(|| Location::new(window))
+ self.location.or_init(|| Location::new(&self.window))
}
// https://dom.spec.whatwg.org/#dom-parentnode-children
fn Children(&self) -> Root<HTMLCollection> {
- let window = self.window.root();
- HTMLCollection::children(window.r(), NodeCast::from_ref(self))
+ HTMLCollection::children(&self.window, NodeCast::from_ref(self))
}
// https://dom.spec.whatwg.org/#dom-parentnode-firstelementchild
@@ -1725,9 +1680,8 @@ impl DocumentMethods for Document {
if !is_scheme_host_port_tuple(&url) {
return Err(Error::Security);
}
- let window = self.window.root();
let (tx, rx) = ipc::channel().unwrap();
- let _ = window.r().resource_task().send(GetCookiesForUrl((*url).clone(), tx, NonHTTP));
+ let _ = self.window.resource_task().send(GetCookiesForUrl((*url).clone(), tx, NonHTTP));
let cookies = rx.recv().unwrap();
Ok(cookies.unwrap_or("".to_owned()))
}
@@ -1739,8 +1693,7 @@ impl DocumentMethods for Document {
if !is_scheme_host_port_tuple(url) {
return Err(Error::Security);
}
- let window = self.window.root();
- let _ = window.r().resource_task().send(SetCookiesForUrl((*url).clone(), cookie, NonHTTP));
+ let _ = self.window.resource_task().send(SetCookiesForUrl((*url).clone(), cookie, NonHTTP));
Ok(())
}
@@ -1834,9 +1787,8 @@ impl DocumentMethods for Document {
}
// Step 4.
*found = true;
- let window = self.window();
let filter = NamedElementFilter { name: name };
- let collection = HTMLCollection::create(window.r(), root, box filter);
+ let collection = HTMLCollection::create(self.window(), root, box filter);
collection.r().reflector().get_jsobject().get()
}
@@ -1894,13 +1846,15 @@ impl DocumentProgressHandler {
fn dispatch_dom_content_loaded(&self) {
let document = self.addr.root();
let window = document.r().window();
- let event = Event::new(GlobalRef::Window(window.r()), "DOMContentLoaded".to_owned(),
+ let event = Event::new(GlobalRef::Window(window), "DOMContentLoaded".to_owned(),
EventBubbles::DoesNotBubble,
EventCancelable::NotCancelable);
let doctarget = EventTargetCast::from_ref(document.r());
let _ = doctarget.DispatchEvent(event.r());
- window.r().reflow(ReflowGoal::ForDisplay, ReflowQueryType::NoQuery, ReflowReason::DOMContentLoaded);
+ window.reflow(ReflowGoal::ForDisplay,
+ ReflowQueryType::NoQuery,
+ ReflowReason::DOMContentLoaded);
}
fn set_ready_state_complete(&self) {
@@ -1911,35 +1865,34 @@ impl DocumentProgressHandler {
fn dispatch_load(&self) {
let document = self.addr.root();
let window = document.r().window();
- let event = Event::new(GlobalRef::Window(window.r()), "load".to_owned(),
+ let event = Event::new(GlobalRef::Window(window), "load".to_owned(),
EventBubbles::DoesNotBubble,
EventCancelable::NotCancelable);
- let wintarget = EventTargetCast::from_ref(window.r());
+ let wintarget = EventTargetCast::from_ref(window);
let doctarget = EventTargetCast::from_ref(document.r());
event.r().set_trusted(true);
let _ = wintarget.dispatch_event_with_target(doctarget, event.r());
- let window_ref = window.r();
- let browsing_context = window_ref.browsing_context();
+ let browsing_context = window.browsing_context();
let browsing_context = browsing_context.as_ref().unwrap();
- browsing_context.frame_element().map(|frame_element| {
- let frame_window = window_from_node(frame_element.r());
+ if let Some(frame_element) = browsing_context.frame_element() {
+ let frame_window = window_from_node(frame_element);
let event = Event::new(GlobalRef::Window(frame_window.r()), "load".to_owned(),
EventBubbles::DoesNotBubble,
EventCancelable::NotCancelable);
- let target = EventTargetCast::from_ref(frame_element.r());
+ let target = EventTargetCast::from_ref(frame_element);
event.r().fire(target);
- });
+ };
document.r().notify_constellation_load();
// https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowserloadend
document.r().trigger_mozbrowser_event(MozBrowserEvent::LoadEnd);
- window_ref.reflow(ReflowGoal::ForDisplay,
- ReflowQueryType::NoQuery,
- ReflowReason::DocumentLoaded);
+ window.reflow(ReflowGoal::ForDisplay,
+ ReflowQueryType::NoQuery,
+ ReflowReason::DocumentLoaded);
}
}
@@ -1947,7 +1900,7 @@ impl Runnable for DocumentProgressHandler {
fn handler(self: Box<DocumentProgressHandler>) {
let document = self.addr.root();
let window = document.r().window();
- if window.r().is_alive() {
+ if window.is_alive() {
match self.task {
DocumentProgressTask::DOMContentLoaded => {
self.dispatch_dom_content_loaded();
diff --git a/components/script/dom/domimplementation.rs b/components/script/dom/domimplementation.rs
index d66cba67bc0..93eb8cf8e0a 100644
--- a/components/script/dom/domimplementation.rs
+++ b/components/script/dom/domimplementation.rs
@@ -42,7 +42,7 @@ impl DOMImplementation {
pub fn new(document: &Document) -> Root<DOMImplementation> {
let window = document.window();
reflect_dom_object(box DOMImplementation::new_inherited(document),
- GlobalRef::Window(window.r()),
+ GlobalRef::Window(window),
DOMImplementationBinding::Wrap)
}
}
@@ -53,20 +53,17 @@ impl DOMImplementationMethods for DOMImplementation {
fn CreateDocumentType(&self, qualified_name: DOMString, pubid: DOMString, sysid: DOMString)
-> Fallible<Root<DocumentType>> {
try!(validate_qualified_name(&qualified_name));
- let document = self.document.root();
- Ok(DocumentType::new(qualified_name, Some(pubid), Some(sysid), document.r()))
+ Ok(DocumentType::new(qualified_name, Some(pubid), Some(sysid), &self.document))
}
// https://dom.spec.whatwg.org/#dom-domimplementation-createdocument
fn CreateDocument(&self, namespace: Option<DOMString>, qname: DOMString,
maybe_doctype: Option<&DocumentType>) -> Fallible<Root<Document>> {
- let doc = self.document.root();
- let doc = doc.r();
- let win = doc.window();
- let loader = DocumentLoader::new(&*doc.loader());
+ let win = self.document.window();
+ let loader = DocumentLoader::new(&self.document.loader());
// Step 1.
- let doc = Document::new(win.r(), None, IsHTMLDocument::NonHTMLDocument,
+ let doc = Document::new(win, None, IsHTMLDocument::NonHTMLDocument,
None, None, DocumentSource::NotFromParser, loader);
// Step 2-3.
let maybe_elem = if qname.is_empty() {
@@ -108,13 +105,11 @@ impl DOMImplementationMethods for DOMImplementation {
// https://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument
fn CreateHTMLDocument(&self, title: Option<DOMString>) -> Root<Document> {
- let document = self.document.root();
- let document = document.r();
- let win = document.window();
- let loader = DocumentLoader::new(&*document.loader());
+ let win = self.document.window();
+ let loader = DocumentLoader::new(&self.document.loader());
// Step 1-2.
- let doc = Document::new(win.r(), None, IsHTMLDocument::HTMLDocument, None, None,
+ let doc = Document::new(win, None, IsHTMLDocument::HTMLDocument, None, None,
DocumentSource::NotFromParser, loader);
{
diff --git a/components/script/dom/domparser.rs b/components/script/dom/domparser.rs
index 8ad9bfa507b..a66b8ea3962 100644
--- a/components/script/dom/domparser.rs
+++ b/components/script/dom/domparser.rs
@@ -49,15 +49,14 @@ impl DOMParserMethods for DOMParser {
s: DOMString,
ty: DOMParserBinding::SupportedType)
-> Fallible<Root<Document>> {
- let window = self.window.root();
- let url = window.r().get_url();
+ let url = self.window.get_url();
let content_type = DOMParserBinding::SupportedTypeValues::strings[ty as usize].to_owned();
- let doc = window.r().Document();
+ let doc = self.window.Document();
let doc = doc.r();
let loader = DocumentLoader::new(&*doc.loader());
match ty {
Text_html => {
- let document = Document::new(window.r(), Some(url.clone()),
+ let document = Document::new(&self.window, Some(url.clone()),
IsHTMLDocument::HTMLDocument,
Some(content_type),
None,
@@ -69,7 +68,7 @@ impl DOMParserMethods for DOMParser {
}
Text_xml => {
//FIXME: this should probably be FromParser when we actually parse the string (#3756).
- Ok(Document::new(window.r(), Some(url.clone()),
+ Ok(Document::new(&self.window, Some(url.clone()),
IsHTMLDocument::NonHTMLDocument,
Some(content_type),
None,
diff --git a/components/script/dom/domrect.rs b/components/script/dom/domrect.rs
index 6706642b5c5..fa1dcc1b165 100644
--- a/components/script/dom/domrect.rs
+++ b/components/script/dom/domrect.rs
@@ -2,74 +2,75 @@
* 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 app_units::Au;
use dom::bindings::codegen::Bindings::DOMRectBinding;
use dom::bindings::codegen::Bindings::DOMRectBinding::DOMRectMethods;
+use dom::bindings::codegen::Bindings::DOMRectReadOnlyBinding::DOMRectReadOnlyMethods;
+use dom::bindings::error::Fallible;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::Root;
-use dom::bindings::num::Finite;
-use dom::bindings::utils::{Reflector, reflect_dom_object};
-use dom::window::Window;
+use dom::bindings::utils::reflect_dom_object;
+use dom::domrectreadonly::DOMRectReadOnly;
#[dom_struct]
pub struct DOMRect {
- reflector_: Reflector,
- top: f32,
- bottom: f32,
- left: f32,
- right: f32,
+ rect: DOMRectReadOnly,
}
impl DOMRect {
- fn new_inherited(top: Au, bottom: Au,
- left: Au, right: Au) -> DOMRect {
+ fn new_inherited(x: f64, y: f64, width: f64, height: f64) -> DOMRect {
DOMRect {
- top: top.to_nearest_px() as f32,
- bottom: bottom.to_nearest_px() as f32,
- left: left.to_nearest_px() as f32,
- right: right.to_nearest_px() as f32,
- reflector_: Reflector::new(),
+ rect: DOMRectReadOnly::new_inherited(x, y, width, height),
}
}
- pub fn new(window: &Window,
- top: Au, bottom: Au,
- left: Au, right: Au) -> Root<DOMRect> {
- reflect_dom_object(box DOMRect::new_inherited(top, bottom, left, right),
- GlobalRef::Window(window), DOMRectBinding::Wrap)
+ pub fn new(global: GlobalRef, x: f64, y: f64, width: f64, height: f64) -> Root<DOMRect> {
+ reflect_dom_object(box DOMRect::new_inherited(x, y, width, height), global, DOMRectBinding::Wrap)
+ }
+
+ pub fn Constructor(global: GlobalRef,
+ x: f64, y: f64, width: f64, height: f64) -> Fallible<Root<DOMRect>> {
+ Ok(DOMRect::new(global, x, y, width, height))
}
}
impl DOMRectMethods for DOMRect {
- // https://drafts.fxtf.org/geometry/#dom-domrectreadonly-top
- fn Top(&self) -> Finite<f32> {
- Finite::wrap(self.top)
+ // https://drafts.fxtf.org/geometry/#dom-domrect-x
+ fn X(&self) -> f64 {
+ self.rect.X()
+ }
+
+ // https://drafts.fxtf.org/geometry/#dom-domrect-x
+ fn SetX(&self, value: f64) {
+ self.rect.set_x(value);
+ }
+
+ // https://drafts.fxtf.org/geometry/#dom-domrect-y
+ fn Y(&self) -> f64 {
+ self.rect.Y()
}
- // https://drafts.fxtf.org/geometry/#dom-domrectreadonly-bottom
- fn Bottom(&self) -> Finite<f32> {
- Finite::wrap(self.bottom)
+ // https://drafts.fxtf.org/geometry/#dom-domrect-y
+ fn SetY(&self, value: f64) {
+ self.rect.set_y(value);
}
- // https://drafts.fxtf.org/geometry/#dom-domrectreadonly-left
- fn Left(&self) -> Finite<f32> {
- Finite::wrap(self.left)
+ // https://drafts.fxtf.org/geometry/#dom-domrect-width
+ fn Width(&self) -> f64 {
+ self.rect.Width()
}
- // https://drafts.fxtf.org/geometry/#dom-domrectreadonly-right
- fn Right(&self) -> Finite<f32> {
- Finite::wrap(self.right)
+ // https://drafts.fxtf.org/geometry/#dom-domrect-width
+ fn SetWidth(&self, value: f64) {
+ self.rect.set_width(value);
}
- // https://drafts.fxtf.org/geometry/#dom-domrectreadonly-width
- fn Width(&self) -> Finite<f32> {
- let result = (self.right - self.left).abs();
- Finite::wrap(result)
+ // https://drafts.fxtf.org/geometry/#dom-domrect-height
+ fn Height(&self) -> f64 {
+ self.rect.Height()
}
- // https://drafts.fxtf.org/geometry/#dom-domrectreadonly-height
- fn Height(&self) -> Finite<f32> {
- let result = (self.bottom - self.top).abs();
- Finite::wrap(result)
+ // https://drafts.fxtf.org/geometry/#dom-domrect-height
+ fn SetHeight(&self, value: f64) {
+ self.rect.set_height(value);
}
}
diff --git a/components/script/dom/domrectreadonly.rs b/components/script/dom/domrectreadonly.rs
new file mode 100644
index 00000000000..a6ba99ead2a
--- /dev/null
+++ b/components/script/dom/domrectreadonly.rs
@@ -0,0 +1,102 @@
+/* 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::DOMRectReadOnlyBinding::{DOMRectReadOnlyMethods, Wrap};
+use dom::bindings::error::Fallible;
+use dom::bindings::global::GlobalRef;
+use dom::bindings::js::Root;
+use dom::bindings::utils::{Reflector, reflect_dom_object};
+use std::cell::Cell;
+
+#[dom_struct]
+pub struct DOMRectReadOnly {
+ reflector_: Reflector,
+ x: Cell<f64>,
+ y: Cell<f64>,
+ width: Cell<f64>,
+ height: Cell<f64>,
+}
+
+impl DOMRectReadOnly {
+ pub fn new_inherited(x: f64, y: f64, width: f64, height: f64) -> DOMRectReadOnly {
+ DOMRectReadOnly {
+ x: Cell::new(x),
+ y: Cell::new(y),
+ width: Cell::new(width),
+ height: Cell::new(height),
+ reflector_: Reflector::new(),
+ }
+ }
+
+ pub fn new(global: GlobalRef, x: f64, y: f64, width: f64, height: f64) -> Root<DOMRectReadOnly> {
+ reflect_dom_object(box DOMRectReadOnly::new_inherited(x, y, width, height), global, Wrap)
+ }
+
+ pub fn Constructor(global: GlobalRef,
+ x: f64, y: f64, width: f64, height: f64) -> Fallible<Root<DOMRectReadOnly>> {
+ Ok(DOMRectReadOnly::new(global, x, y, width, height))
+ }
+
+ pub fn set_x(&self, value: f64) {
+ self.x.set(value);
+ }
+
+ pub fn set_y(&self, value: f64) {
+ self.y.set(value);
+ }
+
+ pub fn set_width(&self, value: f64) {
+ self.width.set(value);
+ }
+
+ pub fn set_height(&self, value: f64) {
+ self.height.set(value);
+ }
+}
+
+impl DOMRectReadOnlyMethods for DOMRectReadOnly {
+ // https://drafts.fxtf.org/geometry/#dom-domrectreadonly-x
+ fn X(&self) -> f64 {
+ self.x.get()
+ }
+
+ // https://drafts.fxtf.org/geometry/#dom-domrectreadonly-y
+ fn Y(&self) -> f64 {
+ self.y.get()
+ }
+
+ // https://drafts.fxtf.org/geometry/#dom-domrectreadonly-width
+ fn Width(&self) -> f64 {
+ self.width.get()
+ }
+
+ // https://drafts.fxtf.org/geometry/#dom-domrectreadonly-height
+ fn Height(&self) -> f64 {
+ self.height.get()
+ }
+
+ // https://drafts.fxtf.org/geometry/#dom-domrectreadonly-top
+ fn Top(&self) -> f64 {
+ let height = self.height.get();
+ if height >= 0f64 { self.y.get() } else { self.y.get() + height }
+ }
+
+ // https://drafts.fxtf.org/geometry/#dom-domrectreadonly-right
+ fn Right(&self) -> f64 {
+ let width = self.width.get();
+ if width < 0f64 { self.x.get() } else { self.x.get() + width }
+ }
+
+ // https://drafts.fxtf.org/geometry/#dom-domrectreadonly-bottom
+ fn Bottom(&self) -> f64 {
+ let height = self.height.get();
+ if height < 0f64 { self.y.get() } else { self.y.get() + height }
+ }
+
+ // https://drafts.fxtf.org/geometry/#dom-domrectreadonly-left
+ fn Left(&self) -> f64 {
+ let width = self.width.get();
+ if width >= 0f64 { self.x.get() } else { self.x.get() + width }
+ }
+}
diff --git a/components/script/dom/domstringmap.rs b/components/script/dom/domstringmap.rs
index cfa5a8e0a1c..95f727c93cb 100644
--- a/components/script/dom/domstringmap.rs
+++ b/components/script/dom/domstringmap.rs
@@ -37,20 +37,17 @@ impl DOMStringMap {
impl DOMStringMapMethods for DOMStringMap {
// https://html.spec.whatwg.org/multipage/#dom-domstringmap-removeitem
fn NamedDeleter(&self, name: DOMString) {
- let element = self.element.root();
- element.r().delete_custom_attr(name)
+ self.element.delete_custom_attr(name)
}
// https://html.spec.whatwg.org/multipage/#dom-domstringmap-setitem
fn NamedSetter(&self, name: DOMString, value: DOMString) -> ErrorResult {
- let element = self.element.root();
- element.r().set_custom_attr(name, value)
+ self.element.set_custom_attr(name, value)
}
// https://html.spec.whatwg.org/multipage/#dom-domstringmap-nameditem
fn NamedGetter(&self, name: DOMString, found: &mut bool) -> DOMString {
- let element = self.element.root();
- match element.r().get_custom_attr(name) {
+ match self.element.get_custom_attr(name) {
Some(value) => {
*found = true;
value.clone()
diff --git a/components/script/dom/domtokenlist.rs b/components/script/dom/domtokenlist.rs
index e13c1448d70..c3944b7627c 100644
--- a/components/script/dom/domtokenlist.rs
+++ b/components/script/dom/domtokenlist.rs
@@ -39,8 +39,7 @@ impl DOMTokenList {
}
fn attribute(&self) -> Option<Root<Attr>> {
- let element = self.element.root();
- element.r().get_attribute(&ns!(""), &self.local_name)
+ self.element.get_attribute(&ns!(""), &self.local_name)
}
fn check_token_exceptions(&self, token: &str) -> Fallible<Atom> {
@@ -87,43 +86,40 @@ impl DOMTokenListMethods for DOMTokenList {
// https://dom.spec.whatwg.org/#dom-domtokenlist-add
fn Add(&self, tokens: Vec<DOMString>) -> ErrorResult {
- let element = self.element.root();
- let mut atoms = element.r().get_tokenlist_attribute(&self.local_name);
+ let mut atoms = self.element.get_tokenlist_attribute(&self.local_name);
for token in &tokens {
let token = try!(self.check_token_exceptions(&token));
if !atoms.iter().any(|atom| *atom == token) {
atoms.push(token);
}
}
- element.r().set_atomic_tokenlist_attribute(&self.local_name, atoms);
+ self.element.set_atomic_tokenlist_attribute(&self.local_name, atoms);
Ok(())
}
// https://dom.spec.whatwg.org/#dom-domtokenlist-remove
fn Remove(&self, tokens: Vec<DOMString>) -> ErrorResult {
- let element = self.element.root();
- let mut atoms = element.r().get_tokenlist_attribute(&self.local_name);
+ let mut atoms = self.element.get_tokenlist_attribute(&self.local_name);
for token in &tokens {
let token = try!(self.check_token_exceptions(&token));
atoms.iter().position(|atom| *atom == token).map(|index| {
atoms.remove(index)
});
}
- element.r().set_atomic_tokenlist_attribute(&self.local_name, atoms);
+ self.element.set_atomic_tokenlist_attribute(&self.local_name, atoms);
Ok(())
}
// https://dom.spec.whatwg.org/#dom-domtokenlist-toggle
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 mut atoms = self.element.get_tokenlist_attribute(&self.local_name);
let token = try!(self.check_token_exceptions(&token));
match atoms.iter().position(|atom| *atom == token) {
Some(index) => match force {
Some(true) => Ok(true),
_ => {
atoms.remove(index);
- element.r().set_atomic_tokenlist_attribute(&self.local_name, atoms);
+ self.element.set_atomic_tokenlist_attribute(&self.local_name, atoms);
Ok(false)
}
},
@@ -131,7 +127,7 @@ impl DOMTokenListMethods for DOMTokenList {
Some(false) => Ok(false),
_ => {
atoms.push(token);
- element.r().set_atomic_tokenlist_attribute(&self.local_name, atoms);
+ self.element.set_atomic_tokenlist_attribute(&self.local_name, atoms);
Ok(true)
}
}
@@ -140,7 +136,7 @@ impl DOMTokenListMethods for DOMTokenList {
// https://dom.spec.whatwg.org/#stringification-behavior
fn Stringifier(&self) -> DOMString {
- let tokenlist = self.element.root().r().get_tokenlist_attribute(&self.local_name);
+ let tokenlist = self.element.get_tokenlist_attribute(&self.local_name);
str_join(&tokenlist, "\x20")
}
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index 651142df713..a2970ffff1f 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -22,14 +22,16 @@ use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::codegen::InheritTypes::{CharacterDataCast, DocumentDerived, ElementCast};
use dom::bindings::codegen::InheritTypes::{ElementDerived, ElementTypeId, EventTargetCast};
use dom::bindings::codegen::InheritTypes::{HTMLAnchorElementCast, HTMLBodyElementCast};
-use dom::bindings::codegen::InheritTypes::{HTMLElementTypeId, HTMLFontElementCast};
+use dom::bindings::codegen::InheritTypes::{HTMLElementTypeId, HTMLFieldSetElementDerived, HTMLFontElementCast};
use dom::bindings::codegen::InheritTypes::{HTMLIFrameElementCast, HTMLInputElementCast};
+use dom::bindings::codegen::InheritTypes::{HTMLLegendElementDerived, HTMLOptGroupElementDerived};
use dom::bindings::codegen::InheritTypes::{HTMLTableCellElementCast, HTMLTableElementCast};
use dom::bindings::codegen::InheritTypes::{HTMLTableRowElementCast, HTMLTableSectionElementCast};
use dom::bindings::codegen::InheritTypes::{HTMLTemplateElementCast, HTMLTextAreaElementCast};
use dom::bindings::codegen::InheritTypes::{NodeCast, NodeTypeId, TextCast};
use dom::bindings::codegen::UnionTypes::NodeOrString;
use dom::bindings::error::{Error, ErrorResult, Fallible};
+use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, LayoutJS, MutNullableHeap};
use dom::bindings::js::{Root, RootedReference};
use dom::bindings::utils::XMLName::InvalidXMLName;
@@ -47,7 +49,7 @@ use dom::htmltableelement::HTMLTableElement;
use dom::htmltextareaelement::RawLayoutHTMLTextAreaElementHelpers;
use dom::namednodemap::NamedNodeMap;
use dom::node::{CLICK_IN_PROGRESS, LayoutNodeHelpers, Node};
-use dom::node::{NodeDamage, NodeFlags, SEQUENTIALLY_FOCUSABLE};
+use dom::node::{NodeDamage, SEQUENTIALLY_FOCUSABLE};
use dom::node::{document_from_node, window_from_node};
use dom::nodelist::NodeList;
use dom::virtualmethods::{VirtualMethods, vtable_for};
@@ -62,7 +64,7 @@ use selectors::parser::{AttrSelector, NamespaceConstraint};
use smallvec::VecLike;
use std::ascii::AsciiExt;
use std::borrow::{Cow, ToOwned};
-use std::cell::Ref;
+use std::cell::{Cell, Ref};
use std::default::Default;
use std::mem;
use std::sync::Arc;
@@ -76,6 +78,25 @@ use style::values::specified::{self, CSSColor, CSSRGBA};
use url::UrlParser;
use util::str::{DOMString, LengthOrPercentageOrAuto};
+bitflags! {
+ #[doc = "Element Event States."]
+ #[derive(JSTraceable, HeapSizeOf)]
+ flags EventState: u8 {
+ #[doc = "The mouse is down on this element. \
+ (https://html.spec.whatwg.org/multipage/#selector-active). \
+ FIXME(#7333): set/unset this when appropriate"]
+ const IN_ACTIVE_STATE = 0x01,
+ #[doc = "This element has focus."]
+ const IN_FOCUS_STATE = 0x02,
+ #[doc = "The mouse is hovering over this element."]
+ const IN_HOVER_STATE = 0x04,
+ #[doc = "Content is enabled (and can be disabled)."]
+ const IN_ENABLED_STATE = 0x08,
+ #[doc = "Content is disabled."]
+ const IN_DISABLED_STATE = 0x10,
+ }
+}
+
#[dom_struct]
pub struct Element {
node: Node,
@@ -87,6 +108,7 @@ pub struct Element {
style_attribute: DOMRefCell<Option<PropertyDeclarationBlock>>,
attr_list: MutNullableHeap<JS<NamedNodeMap>>,
class_list: MutNullableHeap<JS<DOMTokenList>>,
+ event_state: Cell<EventState>,
}
impl PartialEq for Element {
@@ -115,16 +137,16 @@ impl Element {
pub fn new_inherited(local_name: DOMString,
namespace: Namespace, prefix: Option<DOMString>,
document: &Document) -> Element {
- Element::new_inherited_with_flags(NodeFlags::new(), local_name,
+ Element::new_inherited_with_state(EventState::empty(), local_name,
namespace, prefix, document)
}
- pub fn new_inherited_with_flags(flags: NodeFlags, local_name: DOMString,
+ pub fn new_inherited_with_state(state: EventState, local_name: DOMString,
namespace: Namespace, prefix: Option<DOMString>,
document: &Document)
-> Element {
Element {
- node: Node::new_inherited_with_flags(flags, document),
+ node: Node::new_inherited(document),
local_name: Atom::from_slice(&local_name),
namespace: namespace,
prefix: prefix,
@@ -133,6 +155,7 @@ impl Element {
class_list: Default::default(),
id_attribute: DOMRefCell::new(None),
style_attribute: DOMRefCell::new(None),
+ event_state: Cell::new(state),
}
}
@@ -224,6 +247,8 @@ pub trait LayoutElementHelpers {
fn namespace(&self) -> &Namespace;
fn get_checked_state_for_layout(&self) -> bool;
fn get_indeterminate_state_for_layout(&self) -> bool;
+
+ fn get_event_state_for_layout(&self) -> EventState;
}
impl LayoutElementHelpers for LayoutJS<Element> {
@@ -574,6 +599,14 @@ impl LayoutElementHelpers for LayoutJS<Element> {
None => false,
}
}
+
+ #[inline]
+ #[allow(unsafe_code)]
+ fn get_event_state_for_layout(&self) -> EventState {
+ unsafe {
+ (*self.unsafe_get()).event_state.get()
+ }
+ }
}
#[derive(PartialEq, Eq, Copy, Clone, HeapSizeOf)]
@@ -827,7 +860,7 @@ impl Element {
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLSelectElement)) |
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTextAreaElement)) |
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLOptionElement)) => {
- node.get_disabled_state()
+ self.get_disabled_state()
}
// TODO:
// an optgroup element that has a disabled attribute
@@ -1143,13 +1176,13 @@ impl ElementMethods for Element {
node.owner_doc()
};
let window = doc.r().window();
- NamedNodeMap::new(window.r(), self)
+ NamedNodeMap::new(window, self)
})
}
// https://dom.spec.whatwg.org/#dom-element-getattribute
fn GetAttribute(&self, name: DOMString) -> Option<DOMString> {
- self.get_attribute_by_name(name)
+ self.GetAttributeNode(name)
.map(|s| s.r().Value())
}
@@ -1157,9 +1190,21 @@ impl ElementMethods for Element {
fn GetAttributeNS(&self,
namespace: Option<DOMString>,
local_name: DOMString) -> Option<DOMString> {
+ self.GetAttributeNodeNS(namespace, local_name)
+ .map(|attr| attr.r().Value())
+ }
+
+ // https://dom.spec.whatwg.org/#dom-element-getattributenode
+ fn GetAttributeNode(&self, name: DOMString) -> Option<Root<Attr>> {
+ self.get_attribute_by_name(name)
+ }
+
+ // https://dom.spec.whatwg.org/#dom-element-getattributenodens
+ fn GetAttributeNodeNS(&self,
+ namespace: Option<DOMString>,
+ local_name: DOMString) -> Option<Root<Attr>> {
let namespace = &namespace_from_domstring(namespace);
self.get_attribute(namespace, &Atom::from_slice(&local_name))
- .map(|attr| attr.r().Value())
}
// https://dom.spec.whatwg.org/#dom-element-setattribute
@@ -1249,9 +1294,11 @@ impl ElementMethods for Element {
let node = NodeCast::from_ref(self);
let raw_rects = node.get_content_boxes();
let rects = raw_rects.iter().map(|rect| {
- DOMRect::new(win.r(),
- rect.origin.y, rect.origin.y + rect.size.height,
- rect.origin.x, rect.origin.x + rect.size.width)
+ DOMRect::new(GlobalRef::Window(win.r()),
+ rect.origin.x.to_f64_px(),
+ rect.origin.y.to_f64_px(),
+ rect.size.width.to_f64_px(),
+ rect.size.height.to_f64_px())
});
DOMRectList::new(win.r(), rects)
}
@@ -1261,12 +1308,11 @@ impl ElementMethods for Element {
let win = window_from_node(self);
let node = NodeCast::from_ref(self);
let rect = node.get_bounding_content_box();
- DOMRect::new(
- win.r(),
- rect.origin.y,
- rect.origin.y + rect.size.height,
- rect.origin.x,
- rect.origin.x + rect.size.width)
+ DOMRect::new(GlobalRef::Window(win.r()),
+ rect.origin.x.to_f64_px(),
+ rect.origin.y.to_f64_px(),
+ rect.size.width.to_f64_px(),
+ rect.size.height.to_f64_px())
}
// https://drafts.csswg.org/cssom-view/#dom-element-clienttop
@@ -1624,31 +1670,30 @@ impl<'a> ::selectors::Element for Root<Element> {
fn get_namespace<'b>(&'b self) -> &'b Namespace {
self.namespace()
}
+
fn get_hover_state(&self) -> bool {
- let node = NodeCast::from_ref(&**self);
- node.get_hover_state()
+ Element::get_hover_state(self)
}
+
fn get_active_state(&self) -> bool {
- let node = NodeCast::from_ref(&**self);
- node.get_active_state()
+ Element::get_active_state(self)
}
+
fn get_focus_state(&self) -> bool {
// TODO: Also check whether the top-level browsing context has the system focus,
// and whether this element is a browsing context container.
// https://html.spec.whatwg.org/multipage/#selector-focus
- let node = NodeCast::from_ref(&**self);
- node.get_focus_state()
+ Element::get_focus_state(self)
}
+
fn get_id(&self) -> Option<Atom> {
self.id_attribute.borrow().clone()
}
fn get_disabled_state(&self) -> bool {
- let node = NodeCast::from_ref(&**self);
- node.get_disabled_state()
+ Element::get_disabled_state(self)
}
fn get_enabled_state(&self) -> bool {
- let node = NodeCast::from_ref(&**self);
- node.get_enabled_state()
+ Element::get_enabled_state(self)
}
fn get_checked_state(&self) -> bool {
let input_element: Option<&HTMLInputElement> = HTMLInputElementCast::to_ref(&**self);
@@ -1816,6 +1861,105 @@ impl Element {
// Step 7
self.set_click_in_progress(false);
}
+
+ fn set_state(&self, which: EventState, value: bool) {
+ let mut state = self.event_state.get();
+ match value {
+ true => state.insert(which),
+ false => state.remove(which),
+ };
+ self.event_state.set(state);
+
+ let node = NodeCast::from_ref(self);
+ node.dirty(NodeDamage::NodeStyleDamaged);
+ }
+
+ pub fn get_active_state(&self) -> bool {
+ self.event_state.get().contains(IN_ACTIVE_STATE)
+ }
+
+ pub fn set_active_state(&self, value: bool) {
+ self.set_state(IN_ACTIVE_STATE, value)
+ }
+
+ pub fn get_focus_state(&self) -> bool {
+ self.event_state.get().contains(IN_FOCUS_STATE)
+ }
+
+ pub fn set_focus_state(&self, value: bool) {
+ self.set_state(IN_FOCUS_STATE, value)
+ }
+
+ pub fn get_hover_state(&self) -> bool {
+ self.event_state.get().contains(IN_HOVER_STATE)
+ }
+
+ pub fn set_hover_state(&self, value: bool) {
+ self.set_state(IN_HOVER_STATE, value)
+ }
+
+ pub fn get_enabled_state(&self) -> bool {
+ self.event_state.get().contains(IN_ENABLED_STATE)
+ }
+
+ pub fn set_enabled_state(&self, value: bool) {
+ self.set_state(IN_ENABLED_STATE, value)
+ }
+
+ pub fn get_disabled_state(&self) -> bool {
+ self.event_state.get().contains(IN_DISABLED_STATE)
+ }
+
+ pub fn set_disabled_state(&self, value: bool) {
+ self.set_state(IN_DISABLED_STATE, value)
+ }
+}
+
+impl Element {
+ pub fn check_ancestors_disabled_state_for_form_control(&self) {
+ let node = NodeCast::from_ref(self);
+ if self.get_disabled_state() { return; }
+ for ancestor in node.ancestors() {
+ let ancestor = ancestor;
+ let ancestor = ancestor.r();
+ if !ancestor.is_htmlfieldsetelement() { continue; }
+ if !ElementCast::to_ref(ancestor).unwrap().get_disabled_state() { continue; }
+ if ancestor.is_parent_of(node) {
+ self.set_disabled_state(true);
+ self.set_enabled_state(false);
+ return;
+ }
+ match ancestor.children()
+ .find(|child| child.r().is_htmllegendelement())
+ {
+ Some(ref legend) => {
+ // XXXabinader: should we save previous ancestor to avoid this iteration?
+ if node.ancestors().any(|ancestor| ancestor == *legend) { continue; }
+ },
+ None => ()
+ }
+ self.set_disabled_state(true);
+ self.set_enabled_state(false);
+ return;
+ }
+ }
+
+ pub fn check_parent_disabled_state_for_option(&self) {
+ if self.get_disabled_state() { return; }
+ let node = NodeCast::from_ref(self);
+ if let Some(ref parent) = node.GetParentNode() {
+ if parent.r().is_htmloptgroupelement() && ElementCast::to_ref(parent.r()).unwrap().get_disabled_state() {
+ self.set_disabled_state(true);
+ self.set_enabled_state(false);
+ }
+ }
+ }
+
+ pub fn check_disabled_attribute(&self) {
+ let has_disabled_attrib = self.has_attribute(&atom!("disabled"));
+ self.set_disabled_state(has_disabled_attrib);
+ self.set_enabled_state(!has_disabled_attrib);
+ }
}
#[derive(Clone, Copy, PartialEq)]
diff --git a/components/script/dom/htmlbodyelement.rs b/components/script/dom/htmlbodyelement.rs
index 806086a6b03..438aa79ec74 100644
--- a/components/script/dom/htmlbodyelement.rs
+++ b/components/script/dom/htmlbodyelement.rs
@@ -83,6 +83,18 @@ impl HTMLBodyElementMethods for HTMLBodyElement {
let win = window_from_node(self);
win.r().SetOnunload(listener)
}
+
+ // https://html.spec.whatwg.org/multipage/#the-body-element
+ fn GetOnstorage(&self) -> Option<Rc<EventHandlerNonNull>> {
+ let win = window_from_node(self);
+ win.r().GetOnstorage()
+ }
+
+ // https://html.spec.whatwg.org/multipage/#the-body-element
+ fn SetOnstorage(&self, listener: Option<Rc<EventHandlerNonNull>>) {
+ let win = window_from_node(self);
+ win.r().SetOnstorage(listener)
+ }
}
diff --git a/components/script/dom/htmlbuttonelement.rs b/components/script/dom/htmlbuttonelement.rs
index 104619aecbb..93f7f9b292a 100644
--- a/components/script/dom/htmlbuttonelement.rs
+++ b/components/script/dom/htmlbuttonelement.rs
@@ -10,14 +10,13 @@ use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLButtonElementCast, H
use dom::bindings::codegen::InheritTypes::{HTMLFieldSetElementDerived, NodeCast};
use dom::bindings::js::Root;
use dom::document::Document;
-use dom::element::{AttributeMutation, Element};
+use dom::element::{AttributeMutation, Element, IN_ENABLED_STATE};
use dom::event::Event;
use dom::eventtarget::EventTarget;
use dom::htmlelement::HTMLElement;
use dom::htmlformelement::{FormControl, FormSubmitter};
use dom::htmlformelement::{SubmittedFrom, HTMLFormElement};
-use dom::node::{IN_ENABLED_STATE, Node, NodeFlags};
-use dom::node::{document_from_node, window_from_node};
+use dom::node::{Node, document_from_node, window_from_node};
use dom::validitystate::ValidityState;
use dom::virtualmethods::VirtualMethods;
use std::ascii::AsciiExt;
@@ -47,7 +46,7 @@ impl HTMLButtonElement {
document: &Document) -> HTMLButtonElement {
HTMLButtonElement {
htmlelement:
- HTMLElement::new_inherited_with_flags(NodeFlags::new() | IN_ENABLED_STATE,
+ HTMLElement::new_inherited_with_state(IN_ENABLED_STATE,
localName, prefix, document),
//TODO: implement button_type in attribute_mutated
button_type: Cell::new(ButtonType::ButtonSubmit)
@@ -144,17 +143,17 @@ impl VirtualMethods for HTMLButtonElement {
self.super_type().unwrap().attribute_mutated(attr, mutation);
match attr.local_name() {
&atom!(disabled) => {
- let node = NodeCast::from_ref(self);
+ let el = ElementCast::from_ref(self);
match mutation {
AttributeMutation::Set(Some(_)) => {}
AttributeMutation::Set(None) => {
- node.set_disabled_state(true);
- node.set_enabled_state(false);
+ el.set_disabled_state(true);
+ el.set_enabled_state(false);
},
AttributeMutation::Removed => {
- node.set_disabled_state(false);
- node.set_enabled_state(true);
- node.check_ancestors_disabled_state_for_form_control();
+ el.set_disabled_state(false);
+ el.set_enabled_state(true);
+ el.check_ancestors_disabled_state_for_form_control();
}
}
},
@@ -167,8 +166,8 @@ impl VirtualMethods for HTMLButtonElement {
s.bind_to_tree(tree_in_doc);
}
- let node = NodeCast::from_ref(self);
- node.check_ancestors_disabled_state_for_form_control();
+ let el = ElementCast::from_ref(self);
+ el.check_ancestors_disabled_state_for_form_control();
}
fn unbind_from_tree(&self, tree_in_doc: bool) {
@@ -177,10 +176,11 @@ impl VirtualMethods for HTMLButtonElement {
}
let node = NodeCast::from_ref(self);
+ let el = ElementCast::from_ref(self);
if node.ancestors().any(|ancestor| ancestor.r().is_htmlfieldsetelement()) {
- node.check_ancestors_disabled_state_for_form_control();
+ el.check_ancestors_disabled_state_for_form_control();
} else {
- node.check_disabled_attribute();
+ el.check_disabled_attribute();
}
}
}
@@ -194,8 +194,8 @@ impl<'a> Activatable for &'a HTMLButtonElement {
fn is_instance_activatable(&self) -> bool {
//https://html.spec.whatwg.org/multipage/#the-button-element
- let node = NodeCast::from_ref(*self);
- !(node.get_disabled_state())
+ let el = ElementCast::from_ref(*self);
+ !(el.get_disabled_state())
}
// https://html.spec.whatwg.org/multipage/#run-pre-click-activation-steps
@@ -232,13 +232,9 @@ impl<'a> Activatable for &'a HTMLButtonElement {
if owner.is_none() || elem.click_in_progress() {
return;
}
- // This is safe because we are stopping after finding the first element
- // and only then performing actions which may modify the DOM tree
- unsafe {
- node.query_selector_iter("button[type=submit]".to_owned()).unwrap()
- .filter_map(HTMLButtonElementCast::to_root)
- .find(|r| r.r().form_owner() == owner)
- .map(|s| s.r().synthetic_click_activation(ctrlKey, shiftKey, altKey, metaKey));
- }
+ node.query_selector_iter("button[type=submit]".to_owned()).unwrap()
+ .filter_map(HTMLButtonElementCast::to_root)
+ .find(|r| r.r().form_owner() == owner)
+ .map(|s| s.r().synthetic_click_activation(ctrlKey, shiftKey, altKey, metaKey));
}
}
diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs
index 48154d25042..ae25eb3dc17 100644
--- a/components/script/dom/htmlelement.rs
+++ b/components/script/dom/htmlelement.rs
@@ -20,9 +20,9 @@ use dom::bindings::utils::Reflectable;
use dom::cssstyledeclaration::{CSSModificationAccess, CSSStyleDeclaration};
use dom::document::Document;
use dom::domstringmap::DOMStringMap;
-use dom::element::{AttributeMutation, Element};
+use dom::element::{AttributeMutation, Element, EventState};
use dom::htmlinputelement::HTMLInputElement;
-use dom::node::{Node, NodeFlags, SEQUENTIALLY_FOCUSABLE};
+use dom::node::{Node, SEQUENTIALLY_FOCUSABLE};
use dom::node::{document_from_node, window_from_node};
use dom::virtualmethods::VirtualMethods;
use msg::constellation_msg::FocusType;
@@ -49,15 +49,15 @@ impl PartialEq for HTMLElement {
impl HTMLElement {
pub fn new_inherited(tag_name: DOMString, prefix: Option<DOMString>,
document: &Document) -> HTMLElement {
- HTMLElement::new_inherited_with_flags(NodeFlags::new(), tag_name, prefix, document)
+ HTMLElement::new_inherited_with_state(EventState::empty(), tag_name, prefix, document)
}
- pub fn new_inherited_with_flags(flags: NodeFlags, tag_name: DOMString,
+ pub fn new_inherited_with_state(state: EventState, tag_name: DOMString,
prefix: Option<DOMString>, document: &Document)
-> HTMLElement {
HTMLElement {
element:
- Element::new_inherited_with_flags(flags, tag_name, ns!(HTML), prefix, document),
+ Element::new_inherited_with_state(state, tag_name, ns!(HTML), prefix, document),
style_decl: Default::default(),
dataset: Default::default(),
}
@@ -194,8 +194,8 @@ impl HTMLElementMethods for HTMLElement {
// https://html.spec.whatwg.org/multipage/#dom-blur
fn Blur(&self) {
// TODO: Run the unfocusing steps.
- let node = NodeCast::from_ref(self);
- if !node.get_focus_state() {
+ let el = ElementCast::from_ref(self);
+ if !el.get_focus_state() {
return;
}
// https://html.spec.whatwg.org/multipage/#unfocusing-steps
diff --git a/components/script/dom/htmlfieldsetelement.rs b/components/script/dom/htmlfieldsetelement.rs
index c50f3bf6756..2eb696affb8 100644
--- a/components/script/dom/htmlfieldsetelement.rs
+++ b/components/script/dom/htmlfieldsetelement.rs
@@ -5,16 +5,16 @@
use dom::attr::Attr;
use dom::bindings::codegen::Bindings::HTMLFieldSetElementBinding;
use dom::bindings::codegen::Bindings::HTMLFieldSetElementBinding::HTMLFieldSetElementMethods;
-use dom::bindings::codegen::InheritTypes::{ElementTypeId, HTMLElementCast};
+use dom::bindings::codegen::InheritTypes::{ElementCast, ElementTypeId, HTMLElementCast};
use dom::bindings::codegen::InheritTypes::{HTMLElementTypeId, HTMLLegendElementDerived};
use dom::bindings::codegen::InheritTypes::{NodeCast, NodeTypeId};
use dom::bindings::js::{Root, RootedReference};
use dom::document::Document;
-use dom::element::{AttributeMutation, Element};
+use dom::element::{AttributeMutation, Element, IN_ENABLED_STATE};
use dom::htmlcollection::{CollectionFilter, HTMLCollection};
use dom::htmlelement::HTMLElement;
use dom::htmlformelement::{FormControl, HTMLFormElement};
-use dom::node::{IN_ENABLED_STATE, Node, NodeFlags, window_from_node};
+use dom::node::{Node, window_from_node};
use dom::validitystate::ValidityState;
use dom::virtualmethods::VirtualMethods;
use util::str::{DOMString, StaticStringVec};
@@ -30,7 +30,7 @@ impl HTMLFieldSetElement {
document: &Document) -> HTMLFieldSetElement {
HTMLFieldSetElement {
htmlelement:
- HTMLElement::new_inherited_with_flags(NodeFlags::new() | IN_ENABLED_STATE,
+ HTMLElement::new_inherited_with_state(IN_ENABLED_STATE,
localName, prefix, document)
}
}
@@ -99,8 +99,9 @@ impl VirtualMethods for HTMLFieldSetElement {
AttributeMutation::Removed => false,
};
let node = NodeCast::from_ref(self);
- node.set_disabled_state(disabled_state);
- node.set_enabled_state(!disabled_state);
+ let el = ElementCast::from_ref(self);
+ el.set_disabled_state(disabled_state);
+ el.set_enabled_state(!disabled_state);
let mut found_legend = false;
let children = node.children().filter(|node| {
if found_legend {
@@ -135,13 +136,15 @@ impl VirtualMethods for HTMLFieldSetElement {
});
if disabled_state {
for field in fields {
- field.set_disabled_state(true);
- field.set_enabled_state(false);
+ let el = ElementCast::to_ref(field.r()).unwrap();
+ el.set_disabled_state(true);
+ el.set_enabled_state(false);
}
} else {
for field in fields {
- field.check_disabled_attribute();
- field.check_ancestors_disabled_state_for_form_control();
+ let el = ElementCast::to_ref(field.r()).unwrap();
+ el.check_disabled_attribute();
+ el.check_ancestors_disabled_state_for_form_control();
}
}
},
diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs
index 46caced7d45..8fa12c02c6c 100644
--- a/components/script/dom/htmlformelement.rs
+++ b/components/script/dom/htmlformelement.rs
@@ -223,9 +223,11 @@ impl HTMLFormElement {
// TODO: This is an incorrect way of getting controls owned
// by the form, but good enough until html5ever lands
node.traverse_preorder().filter_map(|child| {
- if child.r().get_disabled_state() {
- return None;
+ match ElementCast::to_ref(child.r()) {
+ Some(el) if !el.get_disabled_state() => (),
+ _ => return None,
}
+
if child.r().ancestors()
.any(|a| HTMLDataListElementCast::to_root(a).is_some()) {
return None;
diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs
index c07022306d6..9e58d68a4e2 100644
--- a/components/script/dom/htmlimageelement.rs
+++ b/components/script/dom/htmlimageelement.rs
@@ -100,7 +100,6 @@ impl HTMLImageElement {
let node = NodeCast::from_ref(self);
let document = node.owner_doc();
let window = document.r().window();
- let window = window.r();
let image_cache = window.image_cache_task();
match value {
None => {
diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs
index cdfe8716775..78ca2e3e726 100644
--- a/components/script/dom/htmlinputelement.rs
+++ b/components/script/dom/htmlinputelement.rs
@@ -17,14 +17,14 @@ use dom::bindings::codegen::InheritTypes::{KeyboardEventCast, NodeCast};
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, LayoutJS, Root, RootedReference};
use dom::document::Document;
-use dom::element::{AttributeMutation, Element, RawLayoutElementHelpers};
+use dom::element::{AttributeMutation, Element, IN_ENABLED_STATE, RawLayoutElementHelpers};
use dom::event::{Event, EventBubbles, EventCancelable};
use dom::eventtarget::EventTarget;
use dom::htmlelement::HTMLElement;
use dom::htmlformelement::{FormControl, FormDatum, FormSubmitter, HTMLFormElement};
use dom::htmlformelement::{ResetFrom, SubmittedFrom};
use dom::keyboardevent::KeyboardEvent;
-use dom::node::{IN_ENABLED_STATE, Node, NodeDamage, NodeFlags};
+use dom::node::{Node, NodeDamage};
use dom::node::{document_from_node, window_from_node};
use dom::virtualmethods::VirtualMethods;
use msg::constellation_msg::ConstellationChan;
@@ -106,10 +106,10 @@ static DEFAULT_INPUT_SIZE: u32 = 20;
impl HTMLInputElement {
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLInputElement {
- let chan = document.window().r().constellation_chan();
+ let chan = document.window().constellation_chan();
HTMLInputElement {
htmlelement:
- HTMLElement::new_inherited_with_flags(NodeFlags::new() | IN_ENABLED_STATE,
+ HTMLElement::new_inherited_with_state(IN_ENABLED_STATE,
localName, prefix, document),
input_type: Cell::new(InputType::InputText),
checked: Cell::new(false),
@@ -359,12 +359,9 @@ fn broadcast_radio_checked(broadcaster: &HTMLInputElement, group: Option<&Atom>)
// This function is a workaround for lifetime constraint difficulties.
fn do_broadcast(doc_node: &Node, broadcaster: &HTMLInputElement,
owner: Option<&HTMLFormElement>, group: Option<&Atom>) {
- // There is no DOM tree manipulation here, so this is safe
- let iter = unsafe {
- doc_node.query_selector_iter("input[type=radio]".to_owned()).unwrap()
- .filter_map(HTMLInputElementCast::to_root)
- .filter(|r| in_same_group(r.r(), owner, group) && broadcaster != r.r())
- };
+ let iter = doc_node.query_selector_iter("input[type=radio]".to_owned())
+ .unwrap().filter_map(HTMLInputElementCast::to_root)
+ .filter(|r| in_same_group(r.r(), owner, group) && broadcaster != r.r());
for ref r in iter {
if r.r().Checked() {
r.r().SetChecked(false);
@@ -472,8 +469,8 @@ impl HTMLInputElement {
fn mutable(&self) -> bool {
// https://html.spec.whatwg.org/multipage/#the-input-element:concept-fe-mutable
// https://html.spec.whatwg.org/multipage/#the-readonly-attribute:concept-fe-mutable
- let node = NodeCast::from_ref(self);
- !(node.get_disabled_state() || self.ReadOnly())
+ let el = ElementCast::from_ref(self);
+ !(el.get_disabled_state() || self.ReadOnly())
}
// https://html.spec.whatwg.org/multipage/#the-input-element:concept-form-reset-control
@@ -511,10 +508,10 @@ impl VirtualMethods for HTMLInputElement {
},
AttributeMutation::Removed => false,
};
- let node = NodeCast::from_ref(self);
- node.set_disabled_state(disabled_state);
- node.set_enabled_state(!disabled_state);
- node.check_ancestors_disabled_state_for_form_control();
+ let el = ElementCast::from_ref(self);
+ el.set_disabled_state(disabled_state);
+ el.set_enabled_state(!disabled_state);
+ el.check_ancestors_disabled_state_for_form_control();
},
&atom!(checked) if !self.checked_changed.get() => {
let checked_state = match mutation {
@@ -596,8 +593,8 @@ impl VirtualMethods for HTMLInputElement {
s.bind_to_tree(tree_in_doc);
}
- let node = NodeCast::from_ref(self);
- node.check_ancestors_disabled_state_for_form_control();
+ let el = ElementCast::from_ref(self);
+ el.check_ancestors_disabled_state_for_form_control();
}
fn unbind_from_tree(&self, tree_in_doc: bool) {
@@ -606,10 +603,11 @@ impl VirtualMethods for HTMLInputElement {
}
let node = NodeCast::from_ref(self);
+ let el = ElementCast::from_ref(self);
if node.ancestors().any(|ancestor| ancestor.r().is_htmlfieldsetelement()) {
- node.check_ancestors_disabled_state_for_form_control();
+ el.check_ancestors_disabled_state_for_form_control();
} else {
- node.check_disabled_attribute();
+ el.check_disabled_attribute();
}
}
@@ -713,15 +711,12 @@ impl Activatable for HTMLInputElement {
let doc_node = NodeCast::from_ref(doc.r());
let group = self.get_radio_group_name();;
- // Safe since we only manipulate the DOM tree after finding an element
- let checked_member = unsafe {
- doc_node.query_selector_iter("input[type=radio]".to_owned()).unwrap()
- .filter_map(HTMLInputElementCast::to_root)
- .find(|r| {
- in_same_group(r.r(), owner.r(), group.as_ref()) &&
- r.r().Checked()
- })
- };
+ let checked_member = doc_node.query_selector_iter("input[type=radio]".to_owned()).unwrap()
+ .filter_map(HTMLInputElementCast::to_root)
+ .find(|r| {
+ in_same_group(r.r(), owner.r(), group.as_ref()) &&
+ r.r().Checked()
+ });
cache.checked_radio = checked_member.r().map(JS::from_ref);
cache.checked_changed = self.checked_changed.get();
self.SetChecked(true);
@@ -758,17 +753,16 @@ impl Activatable for HTMLInputElement {
InputType::InputRadio => {
// We want to restore state only if the element had been changed in the first place
if cache.was_mutable {
- let old_checked = cache.checked_radio.as_ref().map(|t| t.root());
let name = self.get_radio_group_name();
- match old_checked {
- Some(ref o) => {
+ match cache.checked_radio.as_ref().map(|t| &*t) {
+ Some(o) => {
// Avoiding iterating through the whole tree here, instead
// we can check if the conditions for radio group siblings apply
- if name == o.r().get_radio_group_name() && // TODO should be compatibility caseless
- self.form_owner() == o.r().form_owner() &&
+ if name == o.get_radio_group_name() && // TODO should be compatibility caseless
+ self.form_owner() == o.form_owner() &&
// TODO Both a and b are in the same home subtree
- o.r().input_type.get() == InputType::InputRadio {
- o.r().SetChecked(true);
+ o.input_type.get() == InputType::InputRadio {
+ o.SetChecked(true);
} else {
self.SetChecked(false);
}
@@ -849,14 +843,10 @@ impl Activatable for HTMLInputElement {
if elem.click_in_progress() {
return;
}
- // This is safe because we are stopping after finding the first element
- // and only then performing actions which may modify the DOM tree
let submit_button;
- unsafe {
- submit_button = node.query_selector_iter("input[type=submit]".to_owned()).unwrap()
- .filter_map(HTMLInputElementCast::to_root)
- .find(|r| r.r().form_owner() == owner);
- }
+ submit_button = node.query_selector_iter("input[type=submit]".to_owned()).unwrap()
+ .filter_map(HTMLInputElementCast::to_root)
+ .find(|r| r.r().form_owner() == owner);
match submit_button {
Some(ref button) => {
if button.r().is_instance_activatable() {
@@ -864,28 +854,23 @@ impl Activatable for HTMLInputElement {
}
}
None => {
- unsafe {
- // Safe because we don't perform any DOM modification
- // until we're done with the iterator.
- let inputs = node.query_selector_iter("input".to_owned()).unwrap()
- .filter_map(HTMLInputElementCast::to_root)
- .filter(|input| {
- input.r().form_owner() == owner && match &*input.r().Type() {
- "text" | "search" | "url" | "tel" |
- "email" | "password" | "datetime" |
- "date" | "month" | "week" | "time" |
- "datetime-local" | "number"
- => true,
- _ => false
- }
- });
+ let inputs = node.query_selector_iter("input".to_owned()).unwrap()
+ .filter_map(HTMLInputElementCast::to_root)
+ .filter(|input| {
+ input.r().form_owner() == owner && match &*input.r().Type() {
+ "text" | "search" | "url" | "tel" |
+ "email" | "password" | "datetime" |
+ "date" | "month" | "week" | "time" |
+ "datetime-local" | "number"
+ => true,
+ _ => false
+ }
+ });
- if inputs.skip(1).next().is_some() {
- // lazily test for > 1 submission-blocking inputs
- return;
- }
+ if inputs.skip(1).next().is_some() {
+ // lazily test for > 1 submission-blocking inputs
+ return;
}
-
form.r().submit(SubmittedFrom::NotFromFormSubmitMethod,
FormSubmitter::FormElement(form.r()));
}
diff --git a/components/script/dom/htmloptgroupelement.rs b/components/script/dom/htmloptgroupelement.rs
index b90eacff87f..cabb19936ab 100644
--- a/components/script/dom/htmloptgroupelement.rs
+++ b/components/script/dom/htmloptgroupelement.rs
@@ -5,12 +5,13 @@
use dom::attr::Attr;
use dom::bindings::codegen::Bindings::HTMLOptGroupElementBinding;
use dom::bindings::codegen::Bindings::HTMLOptGroupElementBinding::HTMLOptGroupElementMethods;
-use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLOptionElementDerived, NodeCast};
+use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, HTMLOptionElementCast};
+use dom::bindings::codegen::InheritTypes::{HTMLOptionElementDerived, NodeCast};
use dom::bindings::js::Root;
use dom::document::Document;
-use dom::element::AttributeMutation;
+use dom::element::{AttributeMutation, IN_ENABLED_STATE};
use dom::htmlelement::HTMLElement;
-use dom::node::{IN_ENABLED_STATE, Node, NodeFlags};
+use dom::node::{Node};
use dom::virtualmethods::VirtualMethods;
use util::str::DOMString;
@@ -25,7 +26,7 @@ impl HTMLOptGroupElement {
document: &Document) -> HTMLOptGroupElement {
HTMLOptGroupElement {
htmlelement:
- HTMLElement::new_inherited_with_flags(NodeFlags::new() | IN_ENABLED_STATE,
+ HTMLElement::new_inherited_with_state(IN_ENABLED_STATE,
localName, prefix, document)
}
}
@@ -66,19 +67,22 @@ impl VirtualMethods for HTMLOptGroupElement {
AttributeMutation::Removed => false,
};
let node = NodeCast::from_ref(self);
- node.set_disabled_state(disabled_state);
- node.set_enabled_state(!disabled_state);
+ let el = ElementCast::from_ref(self);
+ el.set_disabled_state(disabled_state);
+ el.set_enabled_state(!disabled_state);
let options = node.children().filter(|child| {
child.is_htmloptionelement()
- });
+ }).map(|child| Root::from_ref(HTMLOptionElementCast::to_ref(child.r()).unwrap()));
if disabled_state {
for option in options {
- option.set_disabled_state(true);
- option.set_enabled_state(false);
+ let el = ElementCast::from_ref(option.r());
+ el.set_disabled_state(true);
+ el.set_enabled_state(false);
}
} else {
for option in options {
- option.check_disabled_attribute();
+ let el = ElementCast::from_ref(option.r());
+ el.check_disabled_attribute();
}
}
},
diff --git a/components/script/dom/htmloptionelement.rs b/components/script/dom/htmloptionelement.rs
index 74454c14355..b84fc43af34 100644
--- a/components/script/dom/htmloptionelement.rs
+++ b/components/script/dom/htmloptionelement.rs
@@ -12,9 +12,9 @@ use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLScriptElementDer
use dom::bindings::codegen::InheritTypes::{NodeCast, TextDerived};
use dom::bindings::js::Root;
use dom::document::Document;
-use dom::element::{AttributeMutation, Element};
+use dom::element::{AttributeMutation, Element, IN_ENABLED_STATE};
use dom::htmlelement::HTMLElement;
-use dom::node::{IN_ENABLED_STATE, Node, NodeFlags};
+use dom::node::{Node};
use dom::virtualmethods::VirtualMethods;
use std::cell::Cell;
use util::str::{DOMString, split_html_space_chars, str_join};
@@ -36,7 +36,7 @@ impl HTMLOptionElement {
document: &Document) -> HTMLOptionElement {
HTMLOptionElement {
htmlelement:
- HTMLElement::new_inherited_with_flags(NodeFlags::new() | IN_ENABLED_STATE,
+ HTMLElement::new_inherited_with_state(IN_ENABLED_STATE,
localName, prefix, document),
selectedness: Cell::new(false),
dirtiness: Cell::new(false),
@@ -151,16 +151,16 @@ impl VirtualMethods for HTMLOptionElement {
self.super_type().unwrap().attribute_mutated(attr, mutation);
match attr.local_name() {
&atom!(disabled) => {
- let node = NodeCast::from_ref(self);
+ let el = ElementCast::from_ref(self);
match mutation {
AttributeMutation::Set(_) => {
- node.set_disabled_state(true);
- node.set_enabled_state(false);
+ el.set_disabled_state(true);
+ el.set_enabled_state(false);
},
AttributeMutation::Removed => {
- node.set_disabled_state(false);
- node.set_enabled_state(true);
- node.check_parent_disabled_state_for_option();
+ el.set_disabled_state(false);
+ el.set_enabled_state(true);
+ el.check_parent_disabled_state_for_option();
}
}
},
@@ -189,8 +189,8 @@ impl VirtualMethods for HTMLOptionElement {
s.bind_to_tree(tree_in_doc);
}
- let node = NodeCast::from_ref(self);
- node.check_parent_disabled_state_for_option();
+ let el = ElementCast::from_ref(self);
+ el.check_parent_disabled_state_for_option();
}
fn unbind_from_tree(&self, tree_in_doc: bool) {
@@ -199,10 +199,11 @@ impl VirtualMethods for HTMLOptionElement {
}
let node = NodeCast::from_ref(self);
+ let el = ElementCast::from_ref(self);
if node.GetParentNode().is_some() {
- node.check_parent_disabled_state_for_option();
+ el.check_parent_disabled_state_for_option();
} else {
- node.check_disabled_attribute();
+ el.check_disabled_attribute();
}
}
}
diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs
index b6f9e97e712..579fe0c7c1b 100644
--- a/components/script/dom/htmlscriptelement.rs
+++ b/components/script/dom/htmlscriptelement.rs
@@ -209,7 +209,7 @@ impl HTMLScriptElement {
// Step 10.
let document_from_node_ref = document_from_node(self);
let document_from_node_ref = document_from_node_ref.r();
- if self.parser_inserted.get() && self.parser_document.root().r() != document_from_node_ref {
+ if self.parser_inserted.get() && &*self.parser_document != document_from_node_ref {
return NextParserState::Continue;
}
diff --git a/components/script/dom/htmlselectelement.rs b/components/script/dom/htmlselectelement.rs
index 33a46acace1..878bfe2538c 100644
--- a/components/script/dom/htmlselectelement.rs
+++ b/components/script/dom/htmlselectelement.rs
@@ -5,15 +5,15 @@
use dom::attr::{Attr, AttrValue};
use dom::bindings::codegen::Bindings::HTMLSelectElementBinding;
use dom::bindings::codegen::Bindings::HTMLSelectElementBinding::HTMLSelectElementMethods;
-use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLFieldSetElementDerived, NodeCast};
+use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, HTMLFieldSetElementDerived, NodeCast};
use dom::bindings::codegen::UnionTypes::HTMLElementOrLong;
use dom::bindings::codegen::UnionTypes::HTMLOptionElementOrHTMLOptGroupElement;
use dom::bindings::js::Root;
use dom::document::Document;
-use dom::element::AttributeMutation;
+use dom::element::{AttributeMutation, IN_ENABLED_STATE};
use dom::htmlelement::HTMLElement;
use dom::htmlformelement::{FormControl, HTMLFormElement};
-use dom::node::{IN_ENABLED_STATE, Node, NodeFlags, window_from_node};
+use dom::node::{Node, window_from_node};
use dom::validitystate::ValidityState;
use dom::virtualmethods::VirtualMethods;
use std::borrow::ToOwned;
@@ -33,7 +33,7 @@ impl HTMLSelectElement {
document: &Document) -> HTMLSelectElement {
HTMLSelectElement {
htmlelement:
- HTMLElement::new_inherited_with_flags(NodeFlags::new() | IN_ENABLED_STATE,
+ HTMLElement::new_inherited_with_state(IN_ENABLED_STATE,
localName, prefix, document)
}
}
@@ -107,16 +107,16 @@ impl VirtualMethods for HTMLSelectElement {
fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) {
self.super_type().unwrap().attribute_mutated(attr, mutation);
if attr.local_name() == &atom!(disabled) {
- let node = NodeCast::from_ref(self);
+ let el = ElementCast::from_ref(self);
match mutation {
AttributeMutation::Set(_) => {
- node.set_disabled_state(true);
- node.set_enabled_state(false);
+ el.set_disabled_state(true);
+ el.set_enabled_state(false);
},
AttributeMutation::Removed => {
- node.set_disabled_state(false);
- node.set_enabled_state(true);
- node.check_ancestors_disabled_state_for_form_control();
+ el.set_disabled_state(false);
+ el.set_enabled_state(true);
+ el.check_ancestors_disabled_state_for_form_control();
}
}
}
@@ -127,8 +127,8 @@ impl VirtualMethods for HTMLSelectElement {
s.bind_to_tree(tree_in_doc);
}
- let node = NodeCast::from_ref(self);
- node.check_ancestors_disabled_state_for_form_control();
+ let el = ElementCast::from_ref(self);
+ el.check_ancestors_disabled_state_for_form_control();
}
fn unbind_from_tree(&self, tree_in_doc: bool) {
@@ -137,10 +137,11 @@ impl VirtualMethods for HTMLSelectElement {
}
let node = NodeCast::from_ref(self);
+ let el = ElementCast::from_ref(self);
if node.ancestors().any(|ancestor| ancestor.r().is_htmlfieldsetelement()) {
- node.check_ancestors_disabled_state_for_form_control();
+ el.check_ancestors_disabled_state_for_form_control();
} else {
- node.check_disabled_attribute();
+ el.check_disabled_attribute();
}
}
diff --git a/components/script/dom/htmltablerowelement.rs b/components/script/dom/htmltablerowelement.rs
index a485048b240..a35d5d79d66 100644
--- a/components/script/dom/htmltablerowelement.rs
+++ b/components/script/dom/htmltablerowelement.rs
@@ -8,11 +8,13 @@ use dom::bindings::codegen::Bindings::HTMLTableRowElementBinding::{self, HTMLTab
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLTableDataCellElementDerived};
use dom::bindings::codegen::InheritTypes::{HTMLTableHeaderCellElementDerived, NodeCast};
+use dom::bindings::error::{ErrorResult, Fallible};
use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference};
use dom::document::Document;
use dom::element::{AttributeMutation, Element};
use dom::htmlcollection::{CollectionFilter, HTMLCollection};
use dom::htmlelement::HTMLElement;
+use dom::htmltabledatacellelement::HTMLTableDataCellElement;
use dom::node::{Node, window_from_node};
use dom::virtualmethods::VirtualMethods;
use std::cell::Cell;
@@ -73,6 +75,24 @@ impl HTMLTableRowElementMethods for HTMLTableRowElement {
HTMLCollection::create(window.r(), NodeCast::from_ref(self), filter)
})
}
+
+ // https://html.spec.whatwg.org/multipage/#dom-tr-insertcell
+ fn InsertCell(&self, index: i32) -> Fallible<Root<HTMLElement>> {
+ let node = NodeCast::from_ref(self);
+ node.insert_cell_or_row(
+ index,
+ || self.Cells(),
+ || HTMLTableDataCellElement::new("td".to_owned(), None, node.owner_doc().r()))
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-tr-deletecell
+ fn DeleteCell(&self, index: i32) -> ErrorResult {
+ let node = NodeCast::from_ref(self);
+ node.delete_cell_or_row(
+ index,
+ || self.Cells(),
+ |n| n.is_htmltabledatacellelement())
+ }
}
impl VirtualMethods for HTMLTableRowElement {
diff --git a/components/script/dom/htmltablesectionelement.rs b/components/script/dom/htmltablesectionelement.rs
index a384afcaae7..dfc2ceb5900 100644
--- a/components/script/dom/htmltablesectionelement.rs
+++ b/components/script/dom/htmltablesectionelement.rs
@@ -4,12 +4,9 @@
use cssparser::RGBA;
use dom::attr::Attr;
-use dom::bindings::codegen::Bindings::HTMLCollectionBinding::HTMLCollectionMethods;
use dom::bindings::codegen::Bindings::HTMLTableSectionElementBinding::{self, HTMLTableSectionElementMethods};
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
-use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast};
-use dom::bindings::codegen::InheritTypes::{HTMLTableRowElementDerived, NodeCast};
-use dom::bindings::error::Error;
+use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLTableRowElementDerived, NodeCast};
use dom::bindings::error::{ErrorResult, Fallible};
use dom::bindings::js::{Root, RootedReference};
use dom::document::Document;
@@ -20,7 +17,6 @@ use dom::htmltablerowelement::HTMLTableRowElement;
use dom::node::{Node, window_from_node};
use dom::virtualmethods::VirtualMethods;
use std::cell::Cell;
-use std::iter;
use util::str::{self, DOMString};
#[dom_struct]
@@ -67,57 +63,20 @@ impl HTMLTableSectionElementMethods for HTMLTableSectionElement {
// https://html.spec.whatwg.org/multipage/#dom-tbody-insertrow
fn InsertRow(&self, index: i32) -> Fallible<Root<HTMLElement>> {
- if index < -1 {
- return Err(Error::IndexSize);
- }
-
let node = NodeCast::from_ref(self);
- let tr = HTMLTableRowElement::new("tr".to_owned(), None, node.owner_doc().r());
-
- let after_node = if index == -1 {
- None
- } else {
- match self.Rows()
- .elements_iter()
- .map(NodeCast::from_root)
- .map(Some)
- .chain(iter::once(None))
- .nth(index as usize) {
- None => return Err(Error::IndexSize),
- Some(node) => node,
- }
- };
-
- {
- let tr_node = NodeCast::from_ref(tr.r());
- try!(node.InsertBefore(tr_node, after_node.r()));
- }
-
- Ok(HTMLElementCast::from_root(tr))
+ node.insert_cell_or_row(
+ index,
+ || self.Rows(),
+ || HTMLTableRowElement::new("tr".to_owned(), None, node.owner_doc().r()))
}
// https://html.spec.whatwg.org/multipage/#dom-tbody-deleterow
fn DeleteRow(&self, index: i32) -> ErrorResult {
- let element = match index {
- index if index < -1 => return Err(Error::IndexSize),
- -1 => {
- let last_child = NodeCast::from_ref(self).GetLastChild();
- match last_child.and_then(|node| node.inclusively_preceding_siblings()
- .filter_map(ElementCast::to_root)
- .filter(|n| n.is_htmltablerowelement())
- .next()) {
- Some(element) => element,
- None => return Ok(()),
- }
- },
- index => match self.Rows().Item(index as u32) {
- Some(element) => element,
- None => return Err(Error::IndexSize),
- },
- };
-
- NodeCast::from_ref(element.r()).remove_self();
- Ok(())
+ let node = NodeCast::from_ref(self);
+ node.delete_cell_or_row(
+ index,
+ || self.Rows(),
+ |n| n.is_htmltablerowelement())
}
}
diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs
index 19cd81e6519..ba46c064762 100644
--- a/components/script/dom/htmltextareaelement.rs
+++ b/components/script/dom/htmltextareaelement.rs
@@ -15,13 +15,13 @@ use dom::bindings::global::GlobalRef;
use dom::bindings::js::{LayoutJS, Root};
use dom::bindings::refcounted::Trusted;
use dom::document::Document;
-use dom::element::AttributeMutation;
+use dom::element::{AttributeMutation, IN_ENABLED_STATE};
use dom::event::{Event, EventBubbles, EventCancelable};
use dom::htmlelement::HTMLElement;
use dom::htmlformelement::{FormControl, HTMLFormElement};
use dom::keyboardevent::KeyboardEvent;
-use dom::node::{ChildrenMutation, IN_ENABLED_STATE, Node, NodeDamage};
-use dom::node::{NodeFlags, document_from_node, window_from_node};
+use dom::node::{ChildrenMutation, Node, NodeDamage};
+use dom::node::{document_from_node, window_from_node};
use dom::virtualmethods::VirtualMethods;
use msg::constellation_msg::ConstellationChan;
use script_task::ScriptTaskEventCategory::InputEvent;
@@ -84,10 +84,10 @@ impl HTMLTextAreaElement {
fn new_inherited(localName: DOMString,
prefix: Option<DOMString>,
document: &Document) -> HTMLTextAreaElement {
- let chan = document.window().r().constellation_chan();
+ let chan = document.window().constellation_chan();
HTMLTextAreaElement {
htmlelement:
- HTMLElement::new_inherited_with_flags(NodeFlags::new() | IN_ENABLED_STATE,
+ HTMLElement::new_inherited_with_state(IN_ENABLED_STATE,
localName, prefix, document),
textinput: DOMRefCell::new(TextInput::new(Lines::Multiple, "".to_owned(), chan)),
cols: Cell::new(DEFAULT_COLS),
@@ -245,16 +245,16 @@ impl VirtualMethods for HTMLTextAreaElement {
self.super_type().unwrap().attribute_mutated(attr, mutation);
match attr.local_name() {
&atom!(disabled) => {
- let node = NodeCast::from_ref(self);
+ let el = ElementCast::from_ref(self);
match mutation {
AttributeMutation::Set(_) => {
- node.set_disabled_state(true);
- node.set_enabled_state(false);
+ el.set_disabled_state(true);
+ el.set_enabled_state(false);
},
AttributeMutation::Removed => {
- node.set_disabled_state(false);
- node.set_enabled_state(true);
- node.check_ancestors_disabled_state_for_form_control();
+ el.set_disabled_state(false);
+ el.set_enabled_state(true);
+ el.check_ancestors_disabled_state_for_form_control();
}
}
},
@@ -279,8 +279,8 @@ impl VirtualMethods for HTMLTextAreaElement {
s.bind_to_tree(tree_in_doc);
}
- let node = NodeCast::from_ref(self);
- node.check_ancestors_disabled_state_for_form_control();
+ let el = ElementCast::from_ref(self);
+ el.check_ancestors_disabled_state_for_form_control();
}
fn parse_plain_attribute(&self, name: &Atom, value: DOMString) -> AttrValue {
@@ -297,10 +297,11 @@ impl VirtualMethods for HTMLTextAreaElement {
}
let node = NodeCast::from_ref(self);
+ let el = ElementCast::from_ref(self);
if node.ancestors().any(|ancestor| ancestor.r().is_htmlfieldsetelement()) {
- node.check_ancestors_disabled_state_for_form_control();
+ el.check_ancestors_disabled_state_for_form_control();
} else {
- node.check_disabled_attribute();
+ el.check_disabled_attribute();
}
}
diff --git a/components/script/dom/location.rs b/components/script/dom/location.rs
index c366139649b..a9e788a7b04 100644
--- a/components/script/dom/location.rs
+++ b/components/script/dom/location.rs
@@ -4,7 +4,6 @@
use dom::bindings::codegen::Bindings::LocationBinding;
use dom::bindings::codegen::Bindings::LocationBinding::LocationMethods;
-use dom::bindings::error::ErrorResult;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, Root};
use dom::bindings::str::USVString;
@@ -35,141 +34,117 @@ impl Location {
}
fn get_url(&self) -> Url {
- self.window.root().get_url()
+ self.window.get_url()
}
fn set_url_component(&self, value: USVString,
setter: fn(&mut Url, USVString)) {
- let window = self.window.root();
- let mut url = window.get_url();
+ let mut url = self.window.get_url();
setter(&mut url, value);
- window.load_url(url);
+ self.window.load_url(url);
}
}
impl LocationMethods for Location {
// https://html.spec.whatwg.org/multipage/#dom-location-assign
- fn Assign(&self, url: DOMString) {
- let window = self.window.root();
+ fn Assign(&self, url: USVString) {
// TODO: per spec, we should use the _API base URL_ specified by the
// _entry settings object_.
- let base_url = window.get_url();
- if let Ok(url) = UrlParser::new().base_url(&base_url).parse(&url) {
- window.load_url(url);
+ let base_url = self.window.get_url();
+ if let Ok(url) = UrlParser::new().base_url(&base_url).parse(&url.0) {
+ self.window.load_url(url);
}
}
// https://html.spec.whatwg.org/multipage/#dom-location-reload
fn Reload(&self) {
- self.window.root().load_url(self.get_url());
+ self.window.load_url(self.get_url());
}
- // https://url.spec.whatwg.org/#dom-urlutils-hash
+ // https://html.spec.whatwg.org/multipage/#dom-location-hash
fn Hash(&self) -> USVString {
UrlHelper::Hash(&self.get_url())
}
- // https://url.spec.whatwg.org/#dom-urlutils-hash
+ // https://html.spec.whatwg.org/multipage/#dom-location-hash
fn SetHash(&self, value: USVString) {
self.set_url_component(value, UrlHelper::SetHash);
}
- // https://url.spec.whatwg.org/#dom-urlutils-host
+ // https://html.spec.whatwg.org/multipage/#dom-location-host
fn Host(&self) -> USVString {
UrlHelper::Host(&self.get_url())
}
- // https://url.spec.whatwg.org/#dom-urlutils-host
+ // https://html.spec.whatwg.org/multipage/#dom-location-host
fn SetHost(&self, value: USVString) {
self.set_url_component(value, UrlHelper::SetHost);
}
- // https://url.spec.whatwg.org/#dom-urlutils-hostname
+ // https://html.spec.whatwg.org/multipage/#dom-location-hostname
fn Hostname(&self) -> USVString {
UrlHelper::Hostname(&self.get_url())
}
- // https://url.spec.whatwg.org/#dom-urlutils-hostname
+ // https://html.spec.whatwg.org/multipage/#dom-location-hostname
fn SetHostname(&self, value: USVString) {
self.set_url_component(value, UrlHelper::SetHostname);
}
- // https://url.spec.whatwg.org/#dom-urlutils-href
+ // https://html.spec.whatwg.org/multipage/#dom-location-href
fn Href(&self) -> USVString {
UrlHelper::Href(&self.get_url())
}
- // https://url.spec.whatwg.org/#dom-urlutils-href
- fn SetHref(&self, value: USVString) -> ErrorResult {
- let window = self.window.root();
- if let Ok(url) = UrlParser::new().base_url(&window.get_url()).parse(&value.0) {
- window.load_url(url);
- };
- Ok(())
- }
-
- // https://url.spec.whatwg.org/#dom-urlutils-password
- fn Password(&self) -> USVString {
- UrlHelper::Password(&self.get_url())
- }
-
- // https://url.spec.whatwg.org/#dom-urlutils-password
- fn SetPassword(&self, value: USVString) {
- self.set_url_component(value, UrlHelper::SetPassword);
+ // https://html.spec.whatwg.org/multipage/#dom-location-href
+ fn SetHref(&self, value: USVString) {
+ if let Ok(url) = UrlParser::new().base_url(&self.window.get_url()).parse(&value.0) {
+ self.window.load_url(url);
+ }
}
- // https://url.spec.whatwg.org/#dom-urlutils-pathname
+ // https://html.spec.whatwg.org/multipage/#dom-location-pathname
fn Pathname(&self) -> USVString {
UrlHelper::Pathname(&self.get_url())
}
- // https://url.spec.whatwg.org/#dom-urlutils-pathname
+ // https://html.spec.whatwg.org/multipage/#dom-location-pathname
fn SetPathname(&self, value: USVString) {
self.set_url_component(value, UrlHelper::SetPathname);
}
- // https://url.spec.whatwg.org/#dom-urlutils-port
+ // https://html.spec.whatwg.org/multipage/#dom-location-port
fn Port(&self) -> USVString {
UrlHelper::Port(&self.get_url())
}
- // https://url.spec.whatwg.org/#dom-urlutils-port
+ // https://html.spec.whatwg.org/multipage/#dom-location-port
fn SetPort(&self, value: USVString) {
self.set_url_component(value, UrlHelper::SetPort);
}
- // https://url.spec.whatwg.org/#dom-urlutils-protocol
+ // https://html.spec.whatwg.org/multipage/#dom-location-protocol
fn Protocol(&self) -> USVString {
UrlHelper::Protocol(&self.get_url())
}
- // https://url.spec.whatwg.org/#dom-urlutils-protocol
+ // https://html.spec.whatwg.org/multipage/#dom-location-protocol
fn SetProtocol(&self, value: USVString) {
self.set_url_component(value, UrlHelper::SetProtocol);
}
- // https://url.spec.whatwg.org/#URLUtils-stringification-behavior
+ // https://html.spec.whatwg.org/multipage/#dom-location-href
fn Stringifier(&self) -> DOMString {
self.Href().0
}
- // https://url.spec.whatwg.org/#dom-urlutils-search
+ // https://html.spec.whatwg.org/multipage/#dom-location-search
fn Search(&self) -> USVString {
UrlHelper::Search(&self.get_url())
}
- // https://url.spec.whatwg.org/#dom-urlutils-search
+ // https://html.spec.whatwg.org/multipage/#dom-location-search
fn SetSearch(&self, value: USVString) {
self.set_url_component(value, UrlHelper::SetSearch);
}
-
- // https://url.spec.whatwg.org/#dom-urlutils-username
- fn Username(&self) -> USVString {
- UrlHelper::Username(&self.get_url())
- }
-
- // https://url.spec.whatwg.org/#dom-urlutils-username
- fn SetUsername(&self, value: USVString) {
- self.set_url_component(value, UrlHelper::SetUsername);
- }
}
diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs
index 05d89c232df..c8179c3f0e3 100644
--- a/components/script/dom/mod.rs
+++ b/components/script/dom/mod.rs
@@ -220,6 +220,7 @@ pub mod dompoint;
pub mod dompointreadonly;
pub mod domrect;
pub mod domrectlist;
+pub mod domrectreadonly;
pub mod domstringmap;
pub mod domtokenlist;
pub mod element;
diff --git a/components/script/dom/namednodemap.rs b/components/script/dom/namednodemap.rs
index 078ddcc0d84..6070c0bb0c2 100644
--- a/components/script/dom/namednodemap.rs
+++ b/components/script/dom/namednodemap.rs
@@ -37,57 +37,38 @@ impl NamedNodeMap {
impl NamedNodeMapMethods for NamedNodeMap {
// https://dom.spec.whatwg.org/#dom-namednodemap-length
fn Length(&self) -> u32 {
- let owner = self.owner.root();
- // FIXME(https://github.com/rust-lang/rust/issues/23338)
- let owner = owner.r();
- let attrs = owner.attrs();
- attrs.len() as u32
+ self.owner.attrs().len() as u32
}
// https://dom.spec.whatwg.org/#dom-namednodemap-item
fn Item(&self, index: u32) -> Option<Root<Attr>> {
- let owner = self.owner.root();
- // FIXME(https://github.com/rust-lang/rust/issues/23338)
- let owner = owner.r();
- let attrs = owner.attrs();
- attrs.get(index as usize).map(|t| t.root())
+ self.owner.attrs().get(index as usize).map(JS::root)
}
// https://dom.spec.whatwg.org/#dom-namednodemap-getnameditem
fn GetNamedItem(&self, name: DOMString) -> Option<Root<Attr>> {
- let owner = self.owner.root();
- // FIXME(https://github.com/rust-lang/rust/issues/23338)
- let owner = owner.r();
- owner.get_attribute_by_name(name)
+ self.owner.get_attribute_by_name(name)
}
// https://dom.spec.whatwg.org/#dom-namednodemap-getnameditemns
fn GetNamedItemNS(&self, namespace: Option<DOMString>, local_name: DOMString)
-> Option<Root<Attr>> {
- let owner = self.owner.root();
- // FIXME(https://github.com/rust-lang/rust/issues/23338)
- let owner = owner.r();
let ns = namespace_from_domstring(namespace);
- owner.get_attribute(&ns, &Atom::from_slice(&local_name))
+ self.owner.get_attribute(&ns, &Atom::from_slice(&local_name))
}
// https://dom.spec.whatwg.org/#dom-namednodemap-removenameditem
fn RemoveNamedItem(&self, name: DOMString) -> Fallible<Root<Attr>> {
- let owner = self.owner.root();
- // FIXME(https://github.com/rust-lang/rust/issues/23338)
- let owner = owner.r();
- let name = owner.parsed_name(name);
- owner.remove_attribute_by_name(&name).ok_or(Error::NotFound)
+ let name = self.owner.parsed_name(name);
+ self.owner.remove_attribute_by_name(&name).ok_or(Error::NotFound)
}
// https://dom.spec.whatwg.org/#dom-namednodemap-removenameditemns
fn RemoveNamedItemNS(&self, namespace: Option<DOMString>, local_name: DOMString)
-> Fallible<Root<Attr>> {
- let owner = self.owner.root();
- // FIXME(https://github.com/rust-lang/rust/issues/23338)
- let owner = owner.r();
let ns = namespace_from_domstring(namespace);
- owner.remove_attribute(&ns, &Atom::from_slice(&local_name)).ok_or(Error::NotFound)
+ self.owner.remove_attribute(&ns, &Atom::from_slice(&local_name))
+ .ok_or(Error::NotFound)
}
// https://dom.spec.whatwg.org/#dom-namednodemap-item
diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs
index daacdd09fa0..b50d71ccd10 100644
--- a/components/script/dom/node.rs
+++ b/components/script/dom/node.rs
@@ -14,16 +14,18 @@ use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
use dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods;
use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods;
+use dom::bindings::codegen::Bindings::HTMLCollectionBinding::HTMLCollectionMethods;
use dom::bindings::codegen::Bindings::NamedNodeMapBinding::NamedNodeMapMethods;
use dom::bindings::codegen::Bindings::NodeBinding::{NodeConstants, NodeMethods};
use dom::bindings::codegen::Bindings::NodeListBinding::NodeListMethods;
use dom::bindings::codegen::Bindings::ProcessingInstructionBinding::ProcessingInstructionMethods;
+use dom::bindings::codegen::InheritTypes::HTMLElementBase;
+use dom::bindings::codegen::InheritTypes::HTMLElementCast;
use dom::bindings::codegen::InheritTypes::{CharacterDataCast, CharacterDataTypeId};
use dom::bindings::codegen::InheritTypes::{DocumentCast, DocumentDerived, DocumentTypeCast};
use dom::bindings::codegen::InheritTypes::{ElementCast, ElementDerived, ElementTypeId};
use dom::bindings::codegen::InheritTypes::{EventTargetCast, EventTargetTypeId};
-use dom::bindings::codegen::InheritTypes::{HTMLElementTypeId, HTMLFieldSetElementDerived};
-use dom::bindings::codegen::InheritTypes::{HTMLLegendElementDerived, HTMLOptGroupElementDerived};
+use dom::bindings::codegen::InheritTypes::{HTMLElementTypeId};
use dom::bindings::codegen::InheritTypes::{NodeBase, NodeCast, NodeTypeId};
use dom::bindings::codegen::InheritTypes::{ProcessingInstructionCast, TextCast, TextDerived};
use dom::bindings::codegen::UnionTypes::NodeOrString;
@@ -43,6 +45,8 @@ use dom::documentfragment::DocumentFragment;
use dom::documenttype::DocumentType;
use dom::element::{Element, ElementCreator};
use dom::eventtarget::EventTarget;
+use dom::htmlcollection::HTMLCollection;
+use dom::htmlelement::HTMLElement;
use dom::nodelist::NodeList;
use dom::processinginstruction::ProcessingInstruction;
use dom::text::Text;
@@ -60,7 +64,7 @@ use selectors::parser::parse_author_origin_selector_list_from_str;
use std::borrow::ToOwned;
use std::cell::{Cell, Ref, RefCell, RefMut};
use std::default::Default;
-use std::iter::{FilterMap, Peekable};
+use std::iter::{self, FilterMap, Peekable};
use std::mem;
use std::slice::ref_slice;
use std::sync::Arc;
@@ -125,40 +129,28 @@ impl PartialEq for Node {
bitflags! {
#[doc = "Flags for node items."]
#[derive(JSTraceable, HeapSizeOf)]
- flags NodeFlags: u16 {
+ flags NodeFlags: u8 {
#[doc = "Specifies whether this node is in a document."]
const IS_IN_DOC = 0x01,
- #[doc = "Specifies whether this node is in hover state."]
- const IN_HOVER_STATE = 0x02,
- #[doc = "Specifies whether this node is in disabled state."]
- const IN_DISABLED_STATE = 0x04,
- #[doc = "Specifies whether this node is in enabled state."]
- const IN_ENABLED_STATE = 0x08,
#[doc = "Specifies whether this node _must_ be reflowed regardless of style differences."]
- const HAS_CHANGED = 0x10,
+ const HAS_CHANGED = 0x02,
#[doc = "Specifies whether this node needs style recalc on next reflow."]
- const IS_DIRTY = 0x20,
+ const IS_DIRTY = 0x04,
#[doc = "Specifies whether this node has siblings (inclusive of itself) which \
changed since the last reflow."]
- const HAS_DIRTY_SIBLINGS = 0x40,
+ const HAS_DIRTY_SIBLINGS = 0x08,
#[doc = "Specifies whether this node has descendants (inclusive of itself) which \
have changed since the last reflow."]
- const HAS_DIRTY_DESCENDANTS = 0x80,
+ const HAS_DIRTY_DESCENDANTS = 0x10,
// TODO: find a better place to keep this (#4105)
// https://critic.hoppipolla.co.uk/showcomment?chain=8873
// Perhaps using a Set in Document?
#[doc = "Specifies whether or not there is an authentic click in progress on \
this element."]
- const CLICK_IN_PROGRESS = 0x100,
- #[doc = "Specifies whether this node has the focus."]
- const IN_FOCUS_STATE = 0x200,
+ const CLICK_IN_PROGRESS = 0x20,
#[doc = "Specifies whether this node is focusable and whether it is supposed \
to be reachable with using sequential focus navigation."]
- const SEQUENTIALLY_FOCUSABLE = 0x400,
- #[doc = "Specifies whether this node is [being activated]\
- (https://html.spec.whatwg.org/multipage/#selector-active). \
- FIXME(#7333): set/unset this when appropriate"]
- const IN_ACTIVE_STATE = 0x800,
+ const SEQUENTIALLY_FOCUSABLE = 0x40,
}
}
@@ -353,8 +345,7 @@ pub struct QuerySelectorIterator {
}
impl<'a> QuerySelectorIterator {
- #[allow(unsafe_code)]
- unsafe fn new(iter: TreeIterator, selectors: Vec<Selector>)
+ fn new(iter: TreeIterator, selectors: Vec<Selector>)
-> QuerySelectorIterator {
QuerySelectorIterator {
selectors: selectors,
@@ -474,49 +465,6 @@ impl Node {
self.flags.set(flags);
}
- pub fn get_hover_state(&self) -> bool {
- self.get_flag(IN_HOVER_STATE)
- }
-
- pub fn set_hover_state(&self, state: bool) {
- self.set_flag(IN_HOVER_STATE, state);
- self.dirty(NodeDamage::NodeStyleDamaged);
- }
-
- pub fn get_focus_state(&self) -> bool {
- self.get_flag(IN_FOCUS_STATE)
- }
-
- pub fn set_focus_state(&self, state: bool) {
- self.set_flag(IN_FOCUS_STATE, state);
- self.dirty(NodeDamage::NodeStyleDamaged);
- }
-
- pub fn get_active_state(&self) -> bool {
- self.get_flag(IN_ACTIVE_STATE)
- }
-
- pub fn set_active_state(&self, state: bool) {
- self.set_flag(IN_ACTIVE_STATE, state);
- self.dirty(NodeDamage::NodeStyleDamaged);
- }
-
- pub fn get_disabled_state(&self) -> bool {
- self.get_flag(IN_DISABLED_STATE)
- }
-
- pub fn set_disabled_state(&self, state: bool) {
- self.set_flag(IN_DISABLED_STATE, state)
- }
-
- pub fn get_enabled_state(&self) -> bool {
- self.get_flag(IN_ENABLED_STATE)
- }
-
- pub fn set_enabled_state(&self, state: bool) {
- self.set_flag(IN_ENABLED_STATE, state)
- }
-
pub fn get_has_changed(&self) -> bool {
self.get_flag(HAS_CHANGED)
}
@@ -788,8 +736,7 @@ impl Node {
/// Get an iterator over all nodes which match a set of selectors
/// Be careful not to do anything which may manipulate the DOM tree
/// whilst iterating, otherwise the iterator may be invalidated.
- #[allow(unsafe_code)]
- pub unsafe fn query_selector_iter(&self, selectors: DOMString)
+ pub fn query_selector_iter(&self, selectors: DOMString)
-> Fallible<QuerySelectorIterator> {
// Step 1.
match parse_author_origin_selector_list_from_str(&selectors) {
@@ -806,7 +753,7 @@ impl Node {
#[allow(unsafe_code)]
pub fn query_selector_all(&self, selectors: DOMString) -> Fallible<Root<NodeList>> {
let window = window_from_node(self);
- let iter = try!(unsafe { self.query_selector_iter(selectors) });
+ let iter = try!(self.query_selector_iter(selectors));
Ok(NodeList::new_simple_list(window.r(), iter))
}
@@ -918,6 +865,66 @@ impl Node {
}
Ok(fragment)
}
+
+ /// Used by `HTMLTableSectionElement::InsertRow` and `HTMLTableRowElement::InsertCell`
+ pub fn insert_cell_or_row<F, G, I>(&self, index: i32, get_items: F, new_child: G) -> Fallible<Root<HTMLElement>>
+ where F: Fn() -> Root<HTMLCollection>,
+ G: Fn() -> Root<I>,
+ I: NodeBase + HTMLElementBase + Reflectable,
+ {
+ if index < -1 {
+ return Err(Error::IndexSize);
+ }
+
+ let tr = new_child();
+
+ let after_node = if index == -1 {
+ None
+ } else {
+ match get_items().elements_iter()
+ .map(NodeCast::from_root)
+ .map(Some)
+ .chain(iter::once(None))
+ .nth(index as usize) {
+ None => return Err(Error::IndexSize),
+ Some(node) => node,
+ }
+ };
+
+ {
+ let tr_node = NodeCast::from_ref(tr.r());
+ try!(self.InsertBefore(tr_node, after_node.r()));
+ }
+
+ Ok(HTMLElementCast::from_root(tr))
+ }
+
+ /// Used by `HTMLTableSectionElement::DeleteRow` and `HTMLTableRowElement::DeleteCell`
+ pub fn delete_cell_or_row<F, G>(&self, index: i32, get_items: F, is_delete_type: G) -> ErrorResult
+ where F: Fn() -> Root<HTMLCollection>,
+ G: Fn(&Element) -> bool
+ {
+ let element = match index {
+ index if index < -1 => return Err(Error::IndexSize),
+ -1 => {
+ let last_child = NodeCast::from_ref(self).GetLastChild();
+ match last_child.and_then(|node| node.inclusively_preceding_siblings()
+ .filter_map(ElementCast::to_root)
+ .filter(|elem| is_delete_type(elem))
+ .next()) {
+ Some(element) => element,
+ None => return Ok(()),
+ }
+ },
+ index => match get_items().Item(index as u32) {
+ Some(element) => element,
+ None => return Err(Error::IndexSize),
+ },
+ };
+
+ NodeCast::from_ref(element.r()).remove_self();
+ Ok(())
+ }
}
@@ -975,12 +982,6 @@ pub trait LayoutNodeHelpers {
unsafe fn layout_data(&self) -> Ref<Option<LayoutData>>;
unsafe fn layout_data_mut(&self) -> RefMut<Option<LayoutData>>;
unsafe fn layout_data_unchecked(&self) -> *const Option<LayoutData>;
-
- fn get_hover_state_for_layout(&self) -> bool;
- fn get_focus_state_for_layout(&self) -> bool;
- fn get_active_state_for_layout(&self) -> bool;
- fn get_disabled_state_for_layout(&self) -> bool;
- fn get_enabled_state_for_layout(&self) -> bool;
}
impl LayoutNodeHelpers for LayoutJS<Node> {
@@ -1076,42 +1077,6 @@ impl LayoutNodeHelpers for LayoutJS<Node> {
unsafe fn layout_data_unchecked(&self) -> *const Option<LayoutData> {
(*self.unsafe_get()).layout_data.borrow_unchecked()
}
-
- #[inline]
- #[allow(unsafe_code)]
- fn get_hover_state_for_layout(&self) -> bool {
- unsafe {
- self.get_flag(IN_HOVER_STATE)
- }
- }
- #[inline]
- #[allow(unsafe_code)]
- fn get_focus_state_for_layout(&self) -> bool {
- unsafe {
- self.get_flag(IN_FOCUS_STATE)
- }
- }
- #[inline]
- #[allow(unsafe_code)]
- fn get_active_state_for_layout(&self) -> bool {
- unsafe {
- self.get_flag(IN_ACTIVE_STATE)
- }
- }
- #[inline]
- #[allow(unsafe_code)]
- fn get_disabled_state_for_layout(&self) -> bool {
- unsafe {
- self.get_flag(IN_DISABLED_STATE)
- }
- }
- #[inline]
- #[allow(unsafe_code)]
- fn get_enabled_state_for_layout(&self) -> bool {
- unsafe {
- self.get_flag(IN_ENABLED_STATE)
- }
- }
}
@@ -1341,15 +1306,11 @@ impl Node {
wrap_fn: extern "Rust" fn(*mut JSContext, GlobalRef, Box<N>) -> Root<N>)
-> Root<N> {
let window = document.window();
- reflect_dom_object(node, GlobalRef::Window(window.r()), wrap_fn)
+ reflect_dom_object(node, GlobalRef::Window(window), wrap_fn)
}
pub fn new_inherited(doc: &Document) -> Node {
- Node::new_inherited_with_flags(NodeFlags::new(), doc)
- }
-
- pub fn new_inherited_with_flags(flags: NodeFlags, doc: &Document) -> Node {
- Node::new_(flags, Some(doc))
+ Node::new_(NodeFlags::new(), Some(doc))
}
#[allow(unrooted_must_root)]
@@ -1688,7 +1649,7 @@ impl Node {
};
let window = document.window();
let loader = DocumentLoader::new(&*document.loader());
- let document = Document::new(window.r(), Some((*document.url()).clone()),
+ let document = Document::new(window, Some((*document.url()).clone()),
is_html_doc, None,
None, DocumentSource::NotFromParser, loader);
NodeCast::from_root(document)
@@ -1929,7 +1890,7 @@ impl NodeMethods for Node {
self.child_list.or_init(|| {
let doc = self.owner_doc();
let window = doc.r().window();
- NodeList::new_child_list(window.r(), self)
+ NodeList::new_child_list(window, self)
})
}
@@ -2428,7 +2389,7 @@ pub fn document_from_node<T: NodeBase + Reflectable>(derived: &T) -> Root<Docume
pub fn window_from_node<T: NodeBase + Reflectable>(derived: &T) -> Root<Window> {
let document = document_from_node(derived);
- document.r().window()
+ Root::from_ref(document.r().window())
}
impl VirtualMethods for Node {
@@ -2462,53 +2423,6 @@ impl VirtualMethods for Node {
}
}
-
-impl Node {
- pub fn check_ancestors_disabled_state_for_form_control(&self) {
- if self.get_disabled_state() { return; }
- for ancestor in self.ancestors() {
- let ancestor = ancestor;
- let ancestor = ancestor.r();
- if !ancestor.is_htmlfieldsetelement() { continue; }
- if !ancestor.get_disabled_state() { continue; }
- if ancestor.is_parent_of(self) {
- self.set_disabled_state(true);
- self.set_enabled_state(false);
- return;
- }
- match ancestor.children()
- .find(|child| child.r().is_htmllegendelement())
- {
- Some(ref legend) => {
- // XXXabinader: should we save previous ancestor to avoid this iteration?
- if self.ancestors().any(|ancestor| ancestor == *legend) { continue; }
- },
- None => ()
- }
- self.set_disabled_state(true);
- self.set_enabled_state(false);
- return;
- }
- }
-
- pub fn check_parent_disabled_state_for_option(&self) {
- if self.get_disabled_state() { return; }
- if let Some(ref parent) = self.GetParentNode() {
- if parent.r().is_htmloptgroupelement() && parent.r().get_disabled_state() {
- self.set_disabled_state(true);
- self.set_enabled_state(false);
- }
- }
- }
-
- pub fn check_disabled_attribute(&self) {
- let elem = ElementCast::to_ref(self).unwrap();
- let has_disabled_attrib = elem.has_attribute(&atom!("disabled"));
- self.set_disabled_state(has_disabled_attrib);
- self.set_enabled_state(!has_disabled_attrib);
- }
-}
-
/// A summary of the changes that happened to a node.
#[derive(Copy, Clone, PartialEq, HeapSizeOf)]
pub enum NodeDamage {
diff --git a/components/script/dom/nodeiterator.rs b/components/script/dom/nodeiterator.rs
index c7152231776..27a99ec3b55 100644
--- a/components/script/dom/nodeiterator.rs
+++ b/components/script/dom/nodeiterator.rs
@@ -47,9 +47,8 @@ impl NodeIterator {
root_node: &Node,
what_to_show: u32,
filter: Filter) -> Root<NodeIterator> {
- let window = document.window();
reflect_dom_object(box NodeIterator::new_inherited(root_node, what_to_show, filter),
- GlobalRef::Window(window.r()),
+ GlobalRef::Window(document.window()),
NodeIteratorBinding::Wrap)
}
@@ -122,7 +121,7 @@ impl NodeIteratorMethods for NodeIterator {
}
// Step 3-1.
- for following_node in node.r().following_nodes(self.root_node.root().r()) {
+ for following_node in node.r().following_nodes(&self.root_node) {
// Step 3-2.
let result = try!(self.accept_node(following_node.r()));
@@ -166,7 +165,7 @@ impl NodeIteratorMethods for NodeIterator {
}
// Step 3-1.
- for preceding_node in node.r().preceding_nodes(self.root_node.root().r()) {
+ for preceding_node in node.r().preceding_nodes(&self.root_node) {
// Step 3-2.
let result = try!(self.accept_node(preceding_node.r()));
diff --git a/components/script/dom/nodelist.rs b/components/script/dom/nodelist.rs
index b5db05945ca..2ed127dd2dc 100644
--- a/components/script/dom/nodelist.rs
+++ b/components/script/dom/nodelist.rs
@@ -109,7 +109,7 @@ impl ChildrenList {
}
pub fn len(&self) -> u32 {
- self.node.root().children_count()
+ self.node.children_count()
}
pub fn item(&self, index: u32) -> Option<Root<Node>> {
@@ -121,7 +121,7 @@ impl ChildrenList {
}
if index == 0u32 {
// Item is first child if any, not worth updating last visited.
- return self.node.root().GetFirstChild();
+ return self.node.GetFirstChild();
}
let last_index = self.last_index.get();
if index == last_index {
@@ -137,7 +137,7 @@ impl ChildrenList {
} else if index > last_index {
if index == len - 1u32 {
// Item is parent's last child, not worth updating last visited.
- return Some(self.node.root().GetLastChild().unwrap());
+ return Some(self.node.GetLastChild().unwrap());
}
if index <= last_index + (len - last_index) / 2u32 {
// Item is closer to the last visited child and follows it.
@@ -147,7 +147,7 @@ impl ChildrenList {
} else {
// Item is closer to parent's last child and obviously
// precedes it.
- self.node.root().GetLastChild().unwrap()
+ self.node.GetLastChild().unwrap()
.inclusively_preceding_siblings()
.nth((len - index - 1u32) as usize).unwrap()
}
@@ -159,7 +159,7 @@ impl ChildrenList {
} else {
// Item is closer to parent's first child and obviously follows it.
debug_assert!(index < last_index / 2u32);
- self.node.root().GetFirstChild().unwrap()
+ self.node.GetFirstChild().unwrap()
.inclusively_following_siblings()
.nth(index as usize)
.unwrap()
@@ -263,7 +263,7 @@ impl ChildrenList {
}
fn reset(&self) {
- self.last_visited.set(self.node.root().GetFirstChild().as_ref().map(Root::r));
+ self.last_visited.set(self.node.GetFirstChild().r());
self.last_index.set(0u32);
}
}
diff --git a/components/script/dom/performance.rs b/components/script/dom/performance.rs
index 2d0a5990cdc..b8b6c17ef09 100644
--- a/components/script/dom/performance.rs
+++ b/components/script/dom/performance.rs
@@ -51,7 +51,7 @@ impl PerformanceMethods for Performance {
// https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/HighResolutionTime/Overview.html#dom-performance-now
fn Now(&self) -> DOMHighResTimeStamp {
- let navStart = self.timing.root().r().NavigationStartPrecise();
+ let navStart = self.timing.NavigationStartPrecise();
let now = (time::precise_time_ns() as f64 - navStart) / 1000000 as f64;
Finite::wrap(now)
}
diff --git a/components/script/dom/range.rs b/components/script/dom/range.rs
index 0b9a5cc0dbf..52ab9d24d66 100644
--- a/components/script/dom/range.rs
+++ b/components/script/dom/range.rs
@@ -49,10 +49,9 @@ impl Range {
start_container: &Node, start_offset: u32,
end_container: &Node, end_offset: u32)
-> Root<Range> {
- let window = document.window();
reflect_dom_object(box Range::new_inherited(start_container, start_offset,
end_container, end_offset),
- GlobalRef::Window(window.r()),
+ GlobalRef::Window(document.window()),
RangeBinding::Wrap)
}
diff --git a/components/script/dom/servohtmlparser.rs b/components/script/dom/servohtmlparser.rs
index 9b319e66a9a..2cf4bac0a4c 100644
--- a/components/script/dom/servohtmlparser.rs
+++ b/components/script/dom/servohtmlparser.rs
@@ -15,7 +15,7 @@ use dom::bindings::refcounted::Trusted;
use dom::bindings::trace::JSTraceable;
use dom::bindings::utils::{Reflector, reflect_dom_object};
use dom::document::Document;
-use dom::node::{Node, window_from_node};
+use dom::node::Node;
use dom::text::Text;
use dom::window::Window;
use encoding::all::UTF_8;
@@ -48,8 +48,7 @@ impl Sink {
match child {
NodeOrText::AppendNode(n) => n.root(),
NodeOrText::AppendText(t) => {
- let doc = self.document.root();
- let text = Text::new(t.into(), &doc);
+ let text = Text::new(t.into(), &self.document);
NodeCast::from_root(text)
}
}
@@ -109,7 +108,7 @@ impl AsyncResponseListener for ParserContext {
let parser = parser.r();
let win = parser.window();
- self.parser = Some(Trusted::new(win.r().get_cx(), parser, self.script_chan.clone()));
+ self.parser = Some(Trusted::new(win.get_cx(), parser, self.script_chan.clone()));
match content_type {
Some(ContentType(Mime(TopLevel::Image, _, _))) => {
@@ -153,8 +152,7 @@ impl AsyncResponseListener for ParserContext {
Some(parser) => parser.root(),
None => return,
};
- let doc = parser.r().document.root();
- doc.r().finish_load(LoadType::PageSource(self.url.clone()));
+ parser.document.finish_load(LoadType::PageSource(self.url.clone()));
if let Err(err) = status {
debug!("Failed to load page URL {}, error: {}", self.url.serialize(), err);
@@ -189,7 +187,7 @@ pub struct ServoHTMLParser {
impl<'a> Parser for &'a ServoHTMLParser {
fn parse_chunk(self, input: String) {
- self.document.root().r().set_current_parser(Some(self));
+ self.document.set_current_parser(Some(self));
self.pending_input.borrow_mut().push(input);
self.parse_sync();
}
@@ -201,8 +199,7 @@ impl<'a> Parser for &'a ServoHTMLParser {
self.tokenizer().borrow_mut().end();
debug!("finished parsing");
- let document = self.document.root();
- document.r().set_current_parser(None);
+ self.document.set_current_parser(None);
if let Some(pipeline) = self.pipeline {
ScriptTask::parsing_complete(pipeline);
@@ -214,7 +211,6 @@ impl ServoHTMLParser {
#[allow(unrooted_must_root)]
pub fn new(base_url: Option<Url>, document: &Document, pipeline: Option<PipelineId>)
-> Root<ServoHTMLParser> {
- let window = document.window();
let sink = Sink {
base_url: base_url,
document: JS::from_ref(document),
@@ -237,14 +233,13 @@ impl ServoHTMLParser {
pipeline: pipeline,
};
- reflect_dom_object(box parser, GlobalRef::Window(window.r()),
+ reflect_dom_object(box parser, GlobalRef::Window(document.window()),
ServoHTMLParserBinding::Wrap)
}
#[allow(unrooted_must_root)]
pub fn new_for_fragment(base_url: Option<Url>, document: &Document,
fragment_context: FragmentContext) -> Root<ServoHTMLParser> {
- let window = document.window();
let sink = Sink {
base_url: base_url,
document: JS::from_ref(document),
@@ -275,7 +270,7 @@ impl ServoHTMLParser {
pipeline: None,
};
- reflect_dom_object(box parser, GlobalRef::Window(window.r()),
+ reflect_dom_object(box parser, GlobalRef::Window(document.window()),
ServoHTMLParserBinding::Wrap)
}
@@ -301,8 +296,7 @@ impl ServoHTMLParser {
break;
}
- let document = self.document.root();
- document.r().reflow_if_reflow_timer_expired();
+ self.document.reflow_if_reflow_timer_expired();
let mut pending_input = self.pending_input.borrow_mut();
if !pending_input.is_empty() {
@@ -320,9 +314,8 @@ impl ServoHTMLParser {
}
}
- fn window(&self) -> Root<Window> {
- let doc = self.document.root();
- window_from_node(doc.r())
+ fn window(&self) -> &Window {
+ self.document.window()
}
}
diff --git a/components/script/dom/treewalker.rs b/components/script/dom/treewalker.rs
index 7f4646a1618..f19e8383ddf 100644
--- a/components/script/dom/treewalker.rs
+++ b/components/script/dom/treewalker.rs
@@ -45,9 +45,8 @@ impl TreeWalker {
root_node: &Node,
what_to_show: u32,
filter: Filter) -> Root<TreeWalker> {
- let window = document.window();
reflect_dom_object(box TreeWalker::new_inherited(root_node, what_to_show, filter),
- GlobalRef::Window(window.r()),
+ GlobalRef::Window(document.window()),
TreeWalkerBinding::Wrap)
}
diff --git a/components/script/dom/url.rs b/components/script/dom/url.rs
index 4a3bb19a776..9ff22b53597 100644
--- a/components/script/dom/url.rs
+++ b/components/script/dom/url.rs
@@ -88,42 +88,42 @@ impl URL {
}
impl URLMethods for URL {
- // https://url.spec.whatwg.org/#dom-urlutils-hash
+ // https://url.spec.whatwg.org/#dom-url-hash
fn Hash(&self) -> USVString {
UrlHelper::Hash(&self.url.borrow())
}
- // https://url.spec.whatwg.org/#dom-urlutils-hash
+ // https://url.spec.whatwg.org/#dom-url-hash
fn SetHash(&self, value: USVString) {
UrlHelper::SetHash(&mut self.url.borrow_mut(), value);
}
- // https://url.spec.whatwg.org/#dom-urlutils-host
+ // https://url.spec.whatwg.org/#dom-url-host
fn Host(&self) -> USVString {
UrlHelper::Host(&self.url.borrow())
}
- // https://url.spec.whatwg.org/#dom-urlutils-host
+ // https://url.spec.whatwg.org/#dom-url-host
fn SetHost(&self, value: USVString) {
UrlHelper::SetHost(&mut self.url.borrow_mut(), value);
}
- // https://url.spec.whatwg.org/#dom-urlutils-hostname
+ // https://url.spec.whatwg.org/#dom-url-hostname
fn Hostname(&self) -> USVString {
UrlHelper::Hostname(&self.url.borrow())
}
- // https://url.spec.whatwg.org/#dom-urlutils-hostname
+ // https://url.spec.whatwg.org/#dom-url-hostname
fn SetHostname(&self, value: USVString) {
UrlHelper::SetHostname(&mut self.url.borrow_mut(), value);
}
- // https://url.spec.whatwg.org/#dom-urlutils-href
+ // https://url.spec.whatwg.org/#dom-url-href
fn Href(&self) -> USVString {
UrlHelper::Href(&self.url.borrow())
}
- // https://url.spec.whatwg.org/#dom-urlutils-href
+ // https://url.spec.whatwg.org/#dom-url-href
fn SetHref(&self, value: USVString) -> ErrorResult {
match parse_with_base(value, self.base.as_ref()) {
Ok(url) => {
@@ -136,67 +136,67 @@ impl URLMethods for URL {
}
}
- // https://url.spec.whatwg.org/#dom-urlutils-password
+ // https://url.spec.whatwg.org/#dom-url-password
fn Password(&self) -> USVString {
UrlHelper::Password(&self.url.borrow())
}
- // https://url.spec.whatwg.org/#dom-urlutils-password
+ // https://url.spec.whatwg.org/#dom-url-password
fn SetPassword(&self, value: USVString) {
UrlHelper::SetPassword(&mut self.url.borrow_mut(), value);
}
- // https://url.spec.whatwg.org/#dom-urlutils-pathname
+ // https://url.spec.whatwg.org/#dom-url-pathname
fn Pathname(&self) -> USVString {
UrlHelper::Pathname(&self.url.borrow())
}
- // https://url.spec.whatwg.org/#dom-urlutils-pathname
+ // https://url.spec.whatwg.org/#dom-url-pathname
fn SetPathname(&self, value: USVString) {
UrlHelper::SetPathname(&mut self.url.borrow_mut(), value);
}
- // https://url.spec.whatwg.org/#dom-urlutils-port
+ // https://url.spec.whatwg.org/#dom-url-port
fn Port(&self) -> USVString {
UrlHelper::Port(&self.url.borrow())
}
- // https://url.spec.whatwg.org/#dom-urlutils-port
+ // https://url.spec.whatwg.org/#dom-url-port
fn SetPort(&self, value: USVString) {
UrlHelper::SetPort(&mut self.url.borrow_mut(), value);
}
- // https://url.spec.whatwg.org/#dom-urlutils-protocol
+ // https://url.spec.whatwg.org/#dom-url-protocol
fn Protocol(&self) -> USVString {
UrlHelper::Protocol(&self.url.borrow())
}
- // https://url.spec.whatwg.org/#dom-urlutils-protocol
+ // https://url.spec.whatwg.org/#dom-url-protocol
fn SetProtocol(&self, value: USVString) {
UrlHelper::SetProtocol(&mut self.url.borrow_mut(), value);
}
- // https://url.spec.whatwg.org/#dom-urlutils-search
+ // https://url.spec.whatwg.org/#dom-url-search
fn Search(&self) -> USVString {
UrlHelper::Search(&self.url.borrow())
}
- // https://url.spec.whatwg.org/#dom-urlutils-search
+ // https://url.spec.whatwg.org/#dom-url-search
fn SetSearch(&self, value: USVString) {
UrlHelper::SetSearch(&mut self.url.borrow_mut(), value);
}
- // https://url.spec.whatwg.org/#URLUtils-stringification-behavior
+ // https://url.spec.whatwg.org/#dom-url-href
fn Stringifier(&self) -> DOMString {
self.Href().0
}
- // https://url.spec.whatwg.org/#dom-urlutils-username
+ // https://url.spec.whatwg.org/#dom-url-username
fn Username(&self) -> USVString {
UrlHelper::Username(&self.url.borrow())
}
- // https://url.spec.whatwg.org/#dom-urlutils-username
+ // https://url.spec.whatwg.org/#dom-url-username
fn SetUsername(&self, value: USVString) {
UrlHelper::SetUsername(&mut self.url.borrow_mut(), value);
}
diff --git a/components/script/dom/urlhelper.rs b/components/script/dom/urlhelper.rs
index 8d6916c0551..d9e26e84263 100644
--- a/components/script/dom/urlhelper.rs
+++ b/components/script/dom/urlhelper.rs
@@ -12,7 +12,6 @@ use url::{SchemeData, Url, UrlParser};
pub struct UrlHelper;
impl UrlHelper {
- // https://url.spec.whatwg.org/#dom-urlutils-hash
pub fn Hash(url: &Url) -> USVString {
USVString(match url.fragment {
None => "".to_owned(),
@@ -21,13 +20,11 @@ impl UrlHelper {
})
}
- // https://url.spec.whatwg.org/#dom-urlutils-hash
pub fn SetHash(url: &mut Url, value: USVString) {
let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() };
let _ = wrapper.set_fragment(&value.0);
}
- // https://url.spec.whatwg.org/#dom-urlutils-host
pub fn Host(url: &Url) -> USVString {
USVString(match url.scheme_data {
SchemeData::NonRelative(..) => "".to_owned(),
@@ -41,40 +38,33 @@ impl UrlHelper {
})
}
- // https://url.spec.whatwg.org/#dom-urlutils-host
pub fn SetHost(url: &mut Url, value: USVString) {
let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() };
let _ = wrapper.set_host(&value.0);
}
- // https://url.spec.whatwg.org/#dom-urlutils-hostname
pub fn Hostname(url: &Url) -> USVString {
USVString(url.serialize_host().unwrap_or_else(|| "".to_owned()))
}
- // https://url.spec.whatwg.org/#dom-urlutils-hostname
pub fn SetHostname(url: &mut Url, value: USVString) {
let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() };
let _ = wrapper.set_host_and_port(&value.0);
}
- // https://url.spec.whatwg.org/#dom-urlutils-href
pub fn Href(url: &Url) -> USVString {
USVString(url.serialize())
}
- // https://url.spec.whatwg.org/#dom-urlutils-password
pub fn Password(url: &Url) -> USVString {
USVString(url.password().unwrap_or("").to_owned())
}
- // https://url.spec.whatwg.org/#dom-urlutils-password
pub fn SetPassword(url: &mut Url, value: USVString) {
let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() };
let _ = wrapper.set_password(&value.0);
}
- // https://url.spec.whatwg.org/#dom-urlutils-pathname
pub fn Pathname(url: &Url) -> USVString {
USVString(match url.scheme_data {
SchemeData::NonRelative(ref scheme_data) => scheme_data.clone(),
@@ -82,13 +72,11 @@ impl UrlHelper {
})
}
- // https://url.spec.whatwg.org/#dom-urlutils-pathname
pub fn SetPathname(url: &mut Url, value: USVString) {
let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() };
let _ = wrapper.set_path(&value.0);
}
- // https://url.spec.whatwg.org/#dom-urlutils-port
pub fn Port(url: &Url) -> USVString {
USVString(match url.port() {
None => "".to_owned(),
@@ -96,18 +84,15 @@ impl UrlHelper {
})
}
- // https://url.spec.whatwg.org/#dom-urlutils-port
pub fn SetPort(url: &mut Url, value: USVString) {
let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() };
let _ = wrapper.set_port(&value.0);
}
- // https://url.spec.whatwg.org/#dom-urlutils-protocol
pub fn Protocol(url: &Url) -> USVString {
USVString(format!("{}:", url.scheme.clone()))
}
- // https://url.spec.whatwg.org/#dom-urlutils-protocol
pub fn SetProtocol(url: &mut Url, value: USVString) {
let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() };
let _ = wrapper.set_scheme(&value.0);
@@ -127,7 +112,6 @@ impl UrlHelper {
true
}
- // https://url.spec.whatwg.org/#dom-urlutils-search
pub fn Search(url: &Url) -> USVString {
USVString(match url.query {
None => "".to_owned(),
@@ -136,18 +120,15 @@ impl UrlHelper {
})
}
- // https://url.spec.whatwg.org/#dom-urlutils-search
pub fn SetSearch(url: &mut Url, value: USVString) {
let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() };
let _ = wrapper.set_query(&value.0);
}
- // https://url.spec.whatwg.org/#dom-urlutils-username
pub fn Username(url: &Url) -> USVString {
USVString(url.username().unwrap_or("").to_owned())
}
- // https://url.spec.whatwg.org/#dom-urlutils-username
pub fn SetUsername(url: &mut Url, value: USVString) {
let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() };
let _ = wrapper.set_username(&value.0);
diff --git a/components/script/dom/webidls/DOMRect.webidl b/components/script/dom/webidls/DOMRect.webidl
index 6e0fe24b57d..9ea5933c3f9 100644
--- a/components/script/dom/webidls/DOMRect.webidl
+++ b/components/script/dom/webidls/DOMRect.webidl
@@ -3,12 +3,13 @@
* 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/. */
-// http://dev.w3.org/fxtf/geometry/#DOMRect
-interface DOMRect {
- readonly attribute float top;
- readonly attribute float right;
- readonly attribute float bottom;
- readonly attribute float left;
- readonly attribute float width;
- readonly attribute float height;
+[Constructor(optional unrestricted double x = 0, optional unrestricted double y = 0,
+ optional unrestricted double width = 0, optional unrestricted double height = 0),
+ /*Exposed=(Window,Worker)*/]
+// https://drafts.fxtf.org/geometry/#domrect
+interface DOMRect : DOMRectReadOnly {
+ inherit attribute unrestricted double x;
+ inherit attribute unrestricted double y;
+ inherit attribute unrestricted double width;
+ inherit attribute unrestricted double height;
};
diff --git a/components/script/dom/webidls/DOMRectReadOnly.webidl b/components/script/dom/webidls/DOMRectReadOnly.webidl
new file mode 100644
index 00000000000..937ed4eb478
--- /dev/null
+++ b/components/script/dom/webidls/DOMRectReadOnly.webidl
@@ -0,0 +1,29 @@
+/* -*- 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/. */
+
+[Constructor(optional unrestricted double x = 0, optional unrestricted double y = 0,
+ optional unrestricted double width = 0, optional unrestricted double height = 0),
+ /*Exposed=(Window,Worker)*/]
+// https://drafts.fxtf.org/geometry/#domrect
+interface DOMRectReadOnly {
+ // [NewObject] static DOMRectReadOnly fromRect(optional DOMRectInit other);
+
+ readonly attribute unrestricted double x;
+ readonly attribute unrestricted double y;
+ readonly attribute unrestricted double width;
+ readonly attribute unrestricted double height;
+ readonly attribute unrestricted double top;
+ readonly attribute unrestricted double right;
+ readonly attribute unrestricted double bottom;
+ readonly attribute unrestricted double left;
+};
+
+// https://drafts.fxtf.org/geometry/#dictdef-domrectinit
+dictionary DOMRectInit {
+ unrestricted double x = 0;
+ unrestricted double y = 0;
+ unrestricted double width = 0;
+ unrestricted double height = 0;
+};
diff --git a/components/script/dom/webidls/Element.webidl b/components/script/dom/webidls/Element.webidl
index dde5b978890..b5b35f8e802 100644
--- a/components/script/dom/webidls/Element.webidl
+++ b/components/script/dom/webidls/Element.webidl
@@ -37,6 +37,10 @@ interface Element : Node {
DOMString? getAttribute(DOMString name);
[Pure]
DOMString? getAttributeNS(DOMString? namespace, DOMString localName);
+ [Pure]
+ Attr? getAttributeNode(DOMString name);
+ [Pure]
+ Attr? getAttributeNodeNS(DOMString? namespace, DOMString localName);
[Throws]
void setAttribute(DOMString name, DOMString value);
[Throws]
diff --git a/components/script/dom/webidls/EventHandler.webidl b/components/script/dom/webidls/EventHandler.webidl
index 8848c3aafbb..7ff237f2ceb 100644
--- a/components/script/dom/webidls/EventHandler.webidl
+++ b/components/script/dom/webidls/EventHandler.webidl
@@ -36,6 +36,7 @@ interface GlobalEventHandlers {
[NoInterfaceObject]
interface WindowEventHandlers {
attribute EventHandler onunload;
+ attribute EventHandler onstorage;
};
// The spec has |attribute OnErrorEventHandler onerror;| on
diff --git a/components/script/dom/webidls/HTMLAnchorElement.webidl b/components/script/dom/webidls/HTMLAnchorElement.webidl
index f21e3dc6af7..6585e1ccc56 100644
--- a/components/script/dom/webidls/HTMLAnchorElement.webidl
+++ b/components/script/dom/webidls/HTMLAnchorElement.webidl
@@ -26,7 +26,7 @@ interface HTMLAnchorElement : HTMLElement {
// also has obsolete members
};
-//HTMLAnchorElement implements URLUtils;
+//HTMLAnchorElement implements HTMLHyperlinkElementUtils;
// https://html.spec.whatwg.org/multipage/#HTMLAnchorElement-partial
partial interface HTMLAnchorElement {
diff --git a/components/script/dom/webidls/HTMLAreaElement.webidl b/components/script/dom/webidls/HTMLAreaElement.webidl
index 860e9af008a..a6568bd0b6b 100644
--- a/components/script/dom/webidls/HTMLAreaElement.webidl
+++ b/components/script/dom/webidls/HTMLAreaElement.webidl
@@ -13,12 +13,9 @@ interface HTMLAreaElement : HTMLElement {
//[PutForwards=value] attribute DOMSettableTokenList ping;
// attribute DOMString rel;
readonly attribute DOMTokenList relList;
- // attribute DOMString hreflang;
- // attribute DOMString type;
-
- // also has obsolete members
+ // hreflang and type are not reflected
};
-//HTMLAreaElement implements URLUtils;
+//HTMLAreaElement implements HTMLHyperlinkElementUtils;
// https://html.spec.whatwg.org/multipage/#HTMLAreaElement-partial
partial interface HTMLAreaElement {
diff --git a/components/script/dom/webidls/HTMLHyperlinkElementUtils.webidl b/components/script/dom/webidls/HTMLHyperlinkElementUtils.webidl
new file mode 100644
index 00000000000..c8d7a35493d
--- /dev/null
+++ b/components/script/dom/webidls/HTMLHyperlinkElementUtils.webidl
@@ -0,0 +1,20 @@
+/* -*- 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://html.spec.whatwg.org/multipage/#htmlhyperlinkelementutils
+//[NoInterfaceObject/*, Exposed=Window*/]
+//interface HTMLHyperlinkElementUtils {
+// stringifier attribute USVString href;
+// attribute USVString origin;
+// attribute USVString protocol;
+// attribute USVString username;
+// attribute USVString password;
+// attribute USVString host;
+// attribute USVString hostname;
+// attribute USVString port;
+// attribute USVString pathname;
+// attribute USVString search;
+// attribute USVString hash;
+//};
diff --git a/components/script/dom/webidls/HTMLTableRowElement.webidl b/components/script/dom/webidls/HTMLTableRowElement.webidl
index 9ddf710653f..66538630c9d 100644
--- a/components/script/dom/webidls/HTMLTableRowElement.webidl
+++ b/components/script/dom/webidls/HTMLTableRowElement.webidl
@@ -8,8 +8,10 @@ interface HTMLTableRowElement : HTMLElement {
//readonly attribute long rowIndex;
//readonly attribute long sectionRowIndex;
readonly attribute HTMLCollection cells;
- //HTMLElement insertCell(optional long index = -1);
- //void deleteCell(long index);
+ [Throws]
+ HTMLElement insertCell(optional long index = -1);
+ [Throws]
+ void deleteCell(long index);
// also has obsolete members
};
diff --git a/components/script/dom/webidls/Location.webidl b/components/script/dom/webidls/Location.webidl
index 70b496b00ec..f82031ac74b 100644
--- a/components/script/dom/webidls/Location.webidl
+++ b/components/script/dom/webidls/Location.webidl
@@ -5,8 +5,24 @@
// https://html.spec.whatwg.org/multipage/#location
/*[Unforgeable]*/ interface Location {
- void assign(DOMString url);
- //void replace(DOMString url);
+ /*stringifier*/ attribute USVString href;
+ // attribute USVString origin;
+ attribute USVString protocol;
+ attribute USVString host;
+ attribute USVString hostname;
+ attribute USVString port;
+ attribute USVString pathname;
+ attribute USVString search;
+ attribute USVString hash;
+
+ void assign(USVString url);
+ //void replace(USVString url);
void reload();
+
+ //[SameObject] readonly attribute USVString[] ancestorOrigins;
+
+ // This is only doing as well as gecko right now.
+ // https://github.com/servo/servo/issues/7590 is on file for
+ // adding attribute stringifier support.
+ stringifier;
};
-Location implements URLUtils;
diff --git a/components/script/dom/webidls/URL.webidl b/components/script/dom/webidls/URL.webidl
index 2e03ea9b858..57ae34a3eba 100644
--- a/components/script/dom/webidls/URL.webidl
+++ b/components/script/dom/webidls/URL.webidl
@@ -8,5 +8,23 @@
interface URL {
static USVString domainToASCII(USVString domain);
// static USVString domainToUnicode(USVString domain);
+
+ [SetterThrows]
+ /*stringifier*/ attribute USVString href;
+ // readonly attribute USVString origin;
+ attribute USVString protocol;
+ attribute USVString username;
+ attribute USVString password;
+ attribute USVString host;
+ attribute USVString hostname;
+ attribute USVString port;
+ attribute USVString pathname;
+ attribute USVString search;
+ // readonly attribute URLSearchParams searchParams;
+ attribute USVString hash;
+
+ // This is only doing as well as gecko right now.
+ // https://github.com/servo/servo/issues/7590 is on file for
+ // adding attribute stringifier support.
+ stringifier;
};
-URL implements URLUtils;
diff --git a/components/script/dom/webidls/URLSearchParams.webidl b/components/script/dom/webidls/URLSearchParams.webidl
index 1afdc30a352..4ab1cd43019 100644
--- a/components/script/dom/webidls/URLSearchParams.webidl
+++ b/components/script/dom/webidls/URLSearchParams.webidl
@@ -7,7 +7,7 @@
* https://url.spec.whatwg.org/#interface-urlsearchparams
*/
-[Constructor(optional (DOMString or URLSearchParams) init)]
+[Constructor(optional (DOMString or URLSearchParams) init/* = ""*/)]
interface URLSearchParams {
void append(DOMString name, DOMString value);
void delete(DOMString name);
@@ -15,5 +15,7 @@ interface URLSearchParams {
// sequence<DOMString> getAll(DOMString name);
boolean has(DOMString name);
void set(DOMString name, DOMString value);
+ // iterable<USVString, USVString>;
stringifier;
};
+
diff --git a/components/script/dom/webidls/URLUtils.webidl b/components/script/dom/webidls/URLUtils.webidl
deleted file mode 100644
index bb32fb82e5e..00000000000
--- a/components/script/dom/webidls/URLUtils.webidl
+++ /dev/null
@@ -1,28 +0,0 @@
-/* -*- 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://url.spec.whatwg.org/#urlutils
-[NoInterfaceObject]
-interface URLUtils {
- //stringifier attribute USVString href;
- [SetterThrows]
- attribute USVString href;
- //readonly attribute USVString origin;
- attribute USVString protocol;
- attribute USVString username;
- attribute USVString password;
- attribute USVString host;
- attribute USVString hostname;
- attribute USVString port;
- attribute USVString pathname;
- attribute USVString search;
- // attribute URLSearchParams searchParams;
- attribute USVString hash;
-
- // This is only doing as well as gecko right now.
- // https://github.com/servo/servo/issues/7590 is on file for
- // adding attribute stringifier support.
- stringifier;
-};
diff --git a/components/script/dom/webidls/URLUtilsReadOnly.webidl b/components/script/dom/webidls/URLUtilsReadOnly.webidl
deleted file mode 100644
index a919986bbbe..00000000000
--- a/components/script/dom/webidls/URLUtilsReadOnly.webidl
+++ /dev/null
@@ -1,26 +0,0 @@
-/* -*- 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://url.spec.whatwg.org/#urlutilsreadonly
-[NoInterfaceObject/*,
- Exposed=(Window,Worker)*/]
-interface URLUtilsReadOnly {
- //stringifier readonly attribute USVString href;
- readonly attribute USVString href;
- //readonly attribute USVString origin;
-
- readonly attribute USVString protocol;
- readonly attribute USVString host;
- readonly attribute USVString hostname;
- readonly attribute USVString port;
- readonly attribute USVString pathname;
- readonly attribute USVString search;
- readonly attribute USVString hash;
-
- // This is only doing as well as gecko right now.
- // https://github.com/servo/servo/issues/7590 is on file for
- // adding attribute stringifier support.
- stringifier;
-};
diff --git a/components/script/dom/webidls/WebSocket.webidl b/components/script/dom/webidls/WebSocket.webidl
index e2652a3716f..bf19ff6e78f 100644
--- a/components/script/dom/webidls/WebSocket.webidl
+++ b/components/script/dom/webidls/WebSocket.webidl
@@ -15,7 +15,7 @@ interface WebSocket : EventTarget {
const unsigned short CLOSING = 2;
const unsigned short CLOSED = 3;
readonly attribute unsigned short readyState;
- //readonly attribute unsigned long bufferedAmount;
+ readonly attribute unsigned long bufferedAmount;
//networking
attribute EventHandler onopen;
diff --git a/components/script/dom/webidls/WorkerLocation.webidl b/components/script/dom/webidls/WorkerLocation.webidl
index 7d624118271..598e210de44 100644
--- a/components/script/dom/webidls/WorkerLocation.webidl
+++ b/components/script/dom/webidls/WorkerLocation.webidl
@@ -5,5 +5,19 @@
// https://html.spec.whatwg.org/multipage/#worker-locations
//[Exposed=Worker]
-interface WorkerLocation { };
-WorkerLocation implements URLUtilsReadOnly;
+interface WorkerLocation {
+ /*stringifier*/ readonly attribute USVString href;
+ // readonly attribute USVString origin;
+ readonly attribute USVString protocol;
+ readonly attribute USVString host;
+ readonly attribute USVString hostname;
+ readonly attribute USVString port;
+ readonly attribute USVString pathname;
+ readonly attribute USVString search;
+ readonly attribute USVString hash;
+
+ // This is only doing as well as gecko right now.
+ // https://github.com/servo/servo/issues/7590 is on file for
+ // adding attribute stringifier support.
+ stringifier;
+};
diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs
index c348efc88d0..4b2797248fa 100644
--- a/components/script/dom/websocket.rs
+++ b/components/script/dom/websocket.rs
@@ -132,6 +132,8 @@ pub struct WebSocket {
url: Url,
global: GlobalField,
ready_state: Cell<WebSocketRequestState>,
+ buffered_amount: Cell<u32>,
+ clearing_buffer: Cell<bool>, //Flag to tell if there is a running task to clear buffered_amount
#[ignore_heap_size_of = "Defined in std"]
sender: RefCell<Option<Arc<Mutex<Sender<WebSocketStream>>>>>,
failed: Cell<bool>, //Flag to tell if websocket was closed due to failure
@@ -172,6 +174,8 @@ impl WebSocket {
url: url,
global: GlobalField::from_rooted(&global),
ready_state: Cell::new(WebSocketRequestState::Connecting),
+ buffered_amount: Cell::new(0),
+ clearing_buffer: Cell::new(false),
failed: Cell::new(false),
sender: RefCell::new(None),
full: Cell::new(false),
@@ -314,6 +318,11 @@ impl WebSocketMethods for WebSocket {
self.ready_state.get() as u16
}
+ // https://html.spec.whatwg.org/multipage/#dom-websocket-bufferedamount
+ fn BufferedAmount(&self) -> u32 {
+ self.buffered_amount.get()
+ }
+
// https://html.spec.whatwg.org/multipage/#dom-websocket-binarytype
fn BinaryType(&self) -> BinaryType {
self.binary_type.get()
@@ -340,14 +349,28 @@ impl WebSocketMethods for WebSocket {
/*TODO: This is not up to spec see http://html.spec.whatwg.org/multipage/comms.html search for
"If argument is a string"
TODO: Need to buffer data
- TODO: bufferedAmount attribute returns the size of the buffer in bytes -
- this is a required attribute defined in the websocket.webidl file
TODO: The send function needs to flag when full by using the following
self.full.set(true). This needs to be done when the buffer is full
*/
let mut other_sender = self.sender.borrow_mut();
let my_sender = other_sender.as_mut().unwrap();
+
+ self.buffered_amount.set(self.buffered_amount.get() + (data.0.as_bytes().len() as u32));
+
let _ = my_sender.lock().unwrap().send_message(Message::Text(data.0));
+
+ if !self.clearing_buffer.get() && self.ready_state.get() == WebSocketRequestState::Open {
+ self.clearing_buffer.set(true);
+
+ let global = self.global.root();
+ let task = box BufferedAmountTask {
+ addr: Trusted::new(global.r().get_cx(), self, global.r().script_chan()),
+ };
+ let chan = global.r().script_chan();
+
+ chan.send(CommonScriptMsg::RunnableMsg(WebSocketEvent, task)).unwrap();
+ }
+
Ok(())
}
@@ -437,6 +460,24 @@ impl Runnable for ConnectionEstablishedTask {
}
}
+struct BufferedAmountTask {
+ addr: Trusted<WebSocket>,
+}
+
+impl Runnable for BufferedAmountTask {
+ // See https://html.spec.whatwg.org/multipage/#dom-websocket-bufferedamount
+ //
+ // To be compliant with standards, we need to reset bufferedAmount only when the event loop
+ // reaches step 1. In our implementation, the bytes will already have been sent on a background
+ // thread.
+ fn handler(self: Box<Self>) {
+ let ws = self.addr.root();
+
+ ws.buffered_amount.set(0);
+ ws.clearing_buffer.set(false);
+ }
+}
+
struct CloseTask {
addr: Trusted<WebSocket>,
}
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index 4ada66c36cc..b3968a9205d 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -381,7 +381,7 @@ impl WindowMethods for Window {
// https://html.spec.whatwg.org/multipage/#dom-document-0
fn Document(&self) -> Root<Document> {
- self.browsing_context().as_ref().unwrap().active_document()
+ Root::from_ref(self.browsing_context().as_ref().unwrap().active_document())
}
// https://html.spec.whatwg.org/multipage/#dom-location
@@ -411,7 +411,7 @@ impl WindowMethods for Window {
// https://html.spec.whatwg.org/multipage/#dom-frameelement
fn GetFrameElement(&self) -> Option<Root<Element>> {
- self.browsing_context().as_ref().unwrap().frame_element()
+ self.browsing_context().as_ref().unwrap().frame_element().map(Root::from_ref)
}
// https://html.spec.whatwg.org/multipage/#dom-navigator
@@ -513,6 +513,9 @@ impl WindowMethods for Window {
// https://html.spec.whatwg.org/multipage/#handler-window-onunload
event_handler!(unload, GetOnunload, SetOnunload);
+ // https://html.spec.whatwg.org/multipage/#handler-window-onstorage
+ event_handler!(storage, GetOnstorage, SetOnstorage);
+
// https://html.spec.whatwg.org/multipage/#handler-onerror
error_event_handler!(error, GetOnerror, SetOnerror);
@@ -1245,11 +1248,11 @@ impl Window {
let browsing_context = browsing_context.as_ref().unwrap();
browsing_context.frame_element().map(|frame_element| {
- let window = window_from_node(frame_element.r());
+ let window = window_from_node(frame_element);
// FIXME(https://github.com/rust-lang/rust/issues/23338)
let r = window.r();
let context = r.browsing_context();
- context.as_ref().unwrap().active_window()
+ Root::from_ref(context.as_ref().unwrap().active_window())
})
}
}
diff --git a/components/script/dom/workerlocation.rs b/components/script/dom/workerlocation.rs
index 467d2fef7ee..477c329cf75 100644
--- a/components/script/dom/workerlocation.rs
+++ b/components/script/dom/workerlocation.rs
@@ -36,47 +36,47 @@ impl WorkerLocation {
}
impl WorkerLocationMethods for WorkerLocation {
- // https://url.spec.whatwg.org/#dom-urlutils-hash
+ // https://html.spec.whatwg.org/multipage/#dom-workerlocation-hash
fn Hash(&self) -> USVString {
UrlHelper::Hash(&self.url)
}
- // https://url.spec.whatwg.org/#dom-urlutils-host
+ // https://html.spec.whatwg.org/multipage/#dom-workerlocation-host
fn Host(&self) -> USVString {
UrlHelper::Host(&self.url)
}
- // https://url.spec.whatwg.org/#dom-urlutils-hostname
+ // https://html.spec.whatwg.org/multipage/#dom-workerlocation-hostname
fn Hostname(&self) -> USVString {
UrlHelper::Hostname(&self.url)
}
- // https://url.spec.whatwg.org/#dom-urlutils-href
+ // https://html.spec.whatwg.org/multipage/#dom-workerlocation-href
fn Href(&self) -> USVString {
UrlHelper::Href(&self.url)
}
- // https://url.spec.whatwg.org/#dom-urlutils-pathname
+ // https://html.spec.whatwg.org/multipage/#dom-workerlocation-pathname
fn Pathname(&self) -> USVString {
UrlHelper::Pathname(&self.url)
}
- // https://url.spec.whatwg.org/#dom-urlutils-port
+ // https://html.spec.whatwg.org/multipage/#dom-workerlocation-port
fn Port(&self) -> USVString {
UrlHelper::Port(&self.url)
}
- // https://url.spec.whatwg.org/#dom-urlutils-protocol
+ // https://html.spec.whatwg.org/multipage/#dom-workerlocation-protocol
fn Protocol(&self) -> USVString {
UrlHelper::Protocol(&self.url)
}
- // https://url.spec.whatwg.org/#dom-urlutils-search
+ // https://html.spec.whatwg.org/multipage/#dom-workerlocation-search
fn Search(&self) -> USVString {
UrlHelper::Search(&self.url)
}
- // https://url.spec.whatwg.org/#URLUtils-stringification-behavior
+ // https://html.spec.whatwg.org/multipage/#dom-workerlocation-href
fn Stringifier(&self) -> DOMString {
self.Href().0
}
diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs
index 3373865fa5f..400b06ca95f 100644
--- a/components/script/dom/xmlhttprequest.rs
+++ b/components/script/dom/xmlhttprequest.rs
@@ -493,8 +493,7 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
if !self.sync.get() {
// Step 8
- let upload_target = self.upload.root();
- let event_target = EventTargetCast::from_ref(upload_target.r());
+ let event_target = EventTargetCast::from_ref(&*self.upload);
if event_target.has_handlers() {
self.upload_events.set(true);
}
@@ -917,13 +916,12 @@ impl XMLHttpRequest {
fn dispatch_progress_event(&self, upload: bool, type_: DOMString, loaded: u64, total: Option<u64>) {
let global = self.global.root();
- let upload_target = self.upload.root();
let progressevent = ProgressEvent::new(global.r(),
type_, EventBubbles::DoesNotBubble, EventCancelable::NotCancelable,
total.is_some(), loaded,
total.unwrap_or(0));
let target = if upload {
- EventTargetCast::from_ref(upload_target.r())
+ EventTargetCast::from_ref(&*self.upload)
} else {
EventTargetCast::from_ref(self)
};