aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
Diffstat (limited to 'components/script')
-rw-r--r--components/script/Cargo.toml3
-rw-r--r--components/script/dom/abstractworker.rs6
-rw-r--r--components/script/dom/attr.rs7
-rw-r--r--components/script/dom/beforeunloadevent.rs2
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py6
-rw-r--r--components/script/dom/bindings/constant.rs1
-rw-r--r--components/script/dom/bindings/conversions.rs2
-rw-r--r--components/script/dom/bindings/guard.rs2
-rw-r--r--components/script/dom/bindings/js.rs62
-rw-r--r--components/script/dom/bindings/mod.rs6
-rw-r--r--components/script/dom/bindings/str.rs6
-rw-r--r--components/script/dom/bindings/trace.rs86
-rw-r--r--components/script/dom/bluetooth.rs109
-rw-r--r--components/script/dom/bluetoothadvertisingdata.rs61
-rw-r--r--components/script/dom/bluetoothadvertisingevent.rs126
-rw-r--r--components/script/dom/bluetoothdevice.rs156
-rw-r--r--components/script/dom/bluetoothremotegattcharacteristic.rs124
-rw-r--r--components/script/dom/bluetoothremotegattdescriptor.rs18
-rw-r--r--components/script/dom/bluetoothremotegattserver.rs148
-rw-r--r--components/script/dom/bluetoothremotegattservice.rs219
-rw-r--r--components/script/dom/browsingcontext.rs4
-rw-r--r--components/script/dom/characterdata.rs2
-rw-r--r--components/script/dom/client.rs4
-rw-r--r--components/script/dom/create.rs4
-rw-r--r--components/script/dom/crypto.rs8
-rw-r--r--components/script/dom/cssgroupingrule.rs18
-rw-r--r--components/script/dom/cssimportrule.rs53
-rw-r--r--components/script/dom/csskeyframesrule.rs29
-rw-r--r--components/script/dom/cssmediarule.rs6
-rw-r--r--components/script/dom/cssrule.rs14
-rw-r--r--components/script/dom/cssrulelist.rs12
-rw-r--r--components/script/dom/cssstyledeclaration.rs370
-rw-r--r--components/script/dom/cssstylerule.rs22
-rw-r--r--components/script/dom/cssstylesheet.rs6
-rw-r--r--components/script/dom/dedicatedworkerglobalscope.rs6
-rw-r--r--components/script/dom/document.rs94
-rw-r--r--components/script/dom/domexception.rs10
-rw-r--r--components/script/dom/domimplementation.rs25
-rw-r--r--components/script/dom/element.rs65
-rw-r--r--components/script/dom/event.rs6
-rw-r--r--components/script/dom/eventdispatcher.rs12
-rw-r--r--components/script/dom/filereader.rs13
-rw-r--r--components/script/dom/focusevent.rs4
-rw-r--r--components/script/dom/globalscope.rs4
-rw-r--r--components/script/dom/htmlanchorelement.rs6
-rw-r--r--components/script/dom/htmlareaelement.rs4
-rw-r--r--components/script/dom/htmlcanvaselement.rs4
-rw-r--r--components/script/dom/htmlcollection.rs6
-rw-r--r--components/script/dom/htmlelement.rs13
-rwxr-xr-xcomponents/script/dom/htmlformelement.rs10
-rw-r--r--components/script/dom/htmliframeelement.rs8
-rwxr-xr-xcomponents/script/dom/htmlinputelement.rs6
-rw-r--r--components/script/dom/htmllinkelement.rs200
-rw-r--r--components/script/dom/htmlmediaelement.rs12
-rw-r--r--components/script/dom/htmlmetaelement.rs9
-rw-r--r--components/script/dom/htmlscriptelement.rs2
-rwxr-xr-xcomponents/script/dom/htmlselectelement.rs69
-rw-r--r--components/script/dom/htmlstyleelement.rs69
-rw-r--r--components/script/dom/htmltablecellelement.rs5
-rw-r--r--components/script/dom/htmltableelement.rs4
-rw-r--r--components/script/dom/htmltablerowelement.rs4
-rw-r--r--components/script/dom/htmltemplateelement.rs6
-rwxr-xr-xcomponents/script/dom/htmltextareaelement.rs38
-rw-r--r--components/script/dom/htmltimeelement.rs16
-rw-r--r--components/script/dom/htmltitleelement.rs10
-rw-r--r--components/script/dom/macros.rs11
-rw-r--r--components/script/dom/mediaquerylist.rs13
-rw-r--r--components/script/dom/mediaquerylistevent.rs76
-rw-r--r--components/script/dom/mod.rs12
-rw-r--r--components/script/dom/mouseevent.rs6
-rw-r--r--components/script/dom/navigator.rs10
-rw-r--r--components/script/dom/navigatorinfo.rs2
-rw-r--r--components/script/dom/node.rs34
-rw-r--r--components/script/dom/nodeiterator.rs9
-rw-r--r--components/script/dom/nodelist.rs6
-rw-r--r--components/script/dom/radionodelist.rs4
-rw-r--r--components/script/dom/range.rs6
-rw-r--r--components/script/dom/request.rs7
-rw-r--r--components/script/dom/response.rs7
-rw-r--r--components/script/dom/serviceworkercontainer.rs4
-rw-r--r--components/script/dom/serviceworkerglobalscope.rs11
-rw-r--r--components/script/dom/servoparser/html.rs6
-rw-r--r--components/script/dom/servoparser/mod.rs2
-rw-r--r--components/script/dom/servoparser/xml.rs4
-rw-r--r--components/script/dom/storageevent.rs6
-rw-r--r--components/script/dom/svgelement.rs15
-rw-r--r--components/script/dom/svggraphicselement.rs10
-rw-r--r--components/script/dom/testbinding.rs2
-rw-r--r--components/script/dom/touch.rs6
-rw-r--r--components/script/dom/touchevent.rs14
-rw-r--r--components/script/dom/treewalker.rs9
-rw-r--r--components/script/dom/uievent.rs5
-rw-r--r--components/script/dom/url.rs4
-rw-r--r--components/script/dom/userscripts.rs4
-rwxr-xr-xcomponents/script/dom/validitystate.rs4
-rw-r--r--components/script/dom/webglframebuffer.rs4
-rw-r--r--components/script/dom/webglobject.rs9
-rw-r--r--components/script/dom/webglprogram.rs6
-rw-r--r--components/script/dom/webglrenderingcontext.rs65
-rw-r--r--components/script/dom/webglshaderprecisionformat.rs2
-rw-r--r--components/script/dom/webidls/BluetoothAdvertisingEvent.webidl (renamed from components/script/dom/webidls/BluetoothAdvertisingData.webidl)21
-rw-r--r--components/script/dom/webidls/BluetoothDevice.webidl8
-rw-r--r--components/script/dom/webidls/CSSGroupingRule.webidl2
-rw-r--r--components/script/dom/webidls/CSSImportRule.webidl11
-rw-r--r--components/script/dom/webidls/CSSKeyframesRule.webidl3
-rw-r--r--components/script/dom/webidls/CSSRule.webidl2
-rw-r--r--components/script/dom/webidls/CSSStyleDeclaration.webidl4
-rw-r--r--components/script/dom/webidls/CSSStyleRule.webidl2
-rw-r--r--components/script/dom/webidls/MediaQueryListEvent.webidl15
-rw-r--r--components/script/dom/webidls/SVGElement.webidl2
-rw-r--r--components/script/dom/webidls/SVGGraphicsElement.webidl2
-rw-r--r--components/script/dom/webidls/WebGLObject.webidl2
-rw-r--r--components/script/dom/websocket.rs13
-rw-r--r--components/script/dom/window.rs50
-rw-r--r--components/script/dom/workerglobalscope.rs6
-rw-r--r--components/script/dom/xmlhttprequest.rs8
-rw-r--r--components/script/layout_wrapper.rs71
-rw-r--r--components/script/lib.rs7
-rw-r--r--components/script/network_listener.rs8
-rw-r--r--components/script/script_runtime.rs4
-rw-r--r--components/script/script_thread.rs159
-rw-r--r--components/script/serviceworker_manager.rs8
-rw-r--r--components/script/stylesheet_loader.rs245
-rw-r--r--components/script/test.rs68
-rw-r--r--components/script/timers.rs2
-rw-r--r--components/script/webdriver_handlers.rs10
126 files changed, 1971 insertions, 1599 deletions
diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml
index 293c2aefe02..05af21f1dc1 100644
--- a/components/script/Cargo.toml
+++ b/components/script/Cargo.toml
@@ -70,13 +70,14 @@ script_traits = {path = "../script_traits"}
selectors = "0.15"
serde = "0.8"
servo_atoms = {path = "../atoms"}
+servo_config = {path = "../config", features = ["servo"] }
+servo_geometry = {path = "../geometry" }
servo_url = {path = "../url", features = ["servo"] }
smallvec = "0.1"
style = {path = "../style"}
style_traits = {path = "../style_traits"}
time = "0.1.12"
url = {version = "1.2", features = ["heap_size", "query_encoding"]}
-util = {path = "../util"}
uuid = {version = "0.3.1", features = ["v4"]}
websocket = "0.17"
xml5ever = {version = "0.2", features = ["unstable"]}
diff --git a/components/script/dom/abstractworker.rs b/components/script/dom/abstractworker.rs
index ee8ee31abc0..8d92680fbed 100644
--- a/components/script/dom/abstractworker.rs
+++ b/components/script/dom/abstractworker.rs
@@ -31,7 +31,7 @@ impl<T: DomObject> SimpleWorkerErrorHandler<T> {
#[derive(Copy, Clone)]
pub struct SharedRt {
- pub rt: *mut JSRuntime
+ rt: *mut JSRuntime
}
impl SharedRt {
@@ -47,10 +47,6 @@ impl SharedRt {
JS_RequestInterruptCallback(self.rt);
}
}
-
- pub fn rt(&self) -> *mut JSRuntime {
- self.rt
- }
}
#[allow(unsafe_code)]
unsafe impl Send for SharedRt {}
diff --git a/components/script/dom/attr.rs b/components/script/dom/attr.rs
index 8b9587c9151..c44cfd4367d 100644
--- a/components/script/dom/attr.rs
+++ b/components/script/dom/attr.rs
@@ -6,8 +6,7 @@ use devtools_traits::AttrInfo;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::AttrBinding::{self, AttrMethods};
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, MutNullableHeap};
-use dom::bindings::js::{LayoutJS, Root, RootedReference};
+use dom::bindings::js::{LayoutJS, MutNullableJS, Root, RootedReference};
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::bindings::str::DOMString;
use dom::element::{AttributeMutation, Element};
@@ -28,7 +27,7 @@ pub struct Attr {
value: DOMRefCell<AttrValue>,
/// the element that owns this attribute.
- owner: MutNullableHeap<JS<Element>>,
+ owner: MutNullableJS<Element>,
}
impl Attr {
@@ -48,7 +47,7 @@ impl Attr {
prefix: prefix,
},
value: DOMRefCell::new(value),
- owner: MutNullableHeap::new(owner),
+ owner: MutNullableJS::new(owner),
}
}
diff --git a/components/script/dom/beforeunloadevent.rs b/components/script/dom/beforeunloadevent.rs
index c79ca70c28e..d9162002016 100644
--- a/components/script/dom/beforeunloadevent.rs
+++ b/components/script/dom/beforeunloadevent.rs
@@ -2,6 +2,8 @@
* 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/. */
+#![allow(dead_code)]
+
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::BeforeUnloadEventBinding;
use dom::bindings::codegen::Bindings::BeforeUnloadEventBinding::BeforeUnloadEventMethods;
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index dc39048ab40..d68b1adf33e 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -4260,7 +4260,9 @@ class CGUnionConversionStruct(CGThing):
return CGWrapper(
CGIndenter(jsConversion, 4),
- pre="unsafe fn TryConvertTo%s(cx: *mut JSContext, value: HandleValue) -> %s {\n" % (t.name, returnType),
+ # TryConvertToObject is unused, but not generating it while generating others is tricky.
+ pre="#[allow(dead_code)] unsafe fn TryConvertTo%s(cx: *mut JSContext, value: HandleValue) -> %s {\n"
+ % (t.name, returnType),
post="\n}")
def define(self):
@@ -5603,7 +5605,7 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries
'dom::globalscope::GlobalScope',
'mem::heap_size_of_raw_self_and_children',
'libc',
- 'util::prefs::PREFS',
+ 'servo_config::prefs::PREFS',
'std::borrow::ToOwned',
'std::cmp',
'std::mem',
diff --git a/components/script/dom/bindings/constant.rs b/components/script/dom/bindings/constant.rs
index 7d453a1fd09..42f10055080 100644
--- a/components/script/dom/bindings/constant.rs
+++ b/components/script/dom/bindings/constant.rs
@@ -20,6 +20,7 @@ pub struct ConstantSpec {
/// Representation of an IDL constant value.
#[derive(Clone)]
+#[allow(dead_code)]
pub enum ConstantVal {
/// `long` constant.
IntVal(i32),
diff --git a/components/script/dom/bindings/conversions.rs b/components/script/dom/bindings/conversions.rs
index adfe242b5f8..18a2deb8f0f 100644
--- a/components/script/dom/bindings/conversions.rs
+++ b/components/script/dom/bindings/conversions.rs
@@ -56,8 +56,8 @@ use js::jsval::{ObjectValue, StringValue};
use js::rust::{ToString, get_object_class, is_dom_class, is_dom_object, maybe_wrap_value};
use libc;
use num_traits::Float;
+use servo_config::opts;
use std::{char, mem, ptr, slice};
-use util::opts;
/// A trait to check whether a given `JSObject` implements an IDL interface.
pub trait IDLInterface {
diff --git a/components/script/dom/bindings/guard.rs b/components/script/dom/bindings/guard.rs
index 114045a62e8..25a52fbe84c 100644
--- a/components/script/dom/bindings/guard.rs
+++ b/components/script/dom/bindings/guard.rs
@@ -5,7 +5,7 @@
//! Machinery to conditionally expose things.
use js::jsapi::{HandleObject, JSContext};
-use util::prefs::PREFS;
+use servo_config::prefs::PREFS;
/// A container with a condition.
pub struct Guard<T: Clone + Copy> {
diff --git a/components/script/dom/bindings/js.rs b/components/script/dom/bindings/js.rs
index fa7999ebcb1..bdd2b81ce37 100644
--- a/components/script/dom/bindings/js.rs
+++ b/components/script/dom/bindings/js.rs
@@ -229,20 +229,6 @@ impl LayoutJS<Node> {
}
}
-
-/// A trait to be implemented for JS-managed types that can be stored in
-/// mutable member fields.
-///
-/// Do not implement this trait yourself.
-pub trait HeapGCValue: JSTraceable {
-}
-
-impl HeapGCValue for Heap<JSVal> {
-}
-
-impl<T: DomObject> HeapGCValue for JS<T> {
-}
-
/// A holder that provides interior mutability for GC-managed JSVals.
///
/// Must be used in place of traditional interior mutability to ensure proper
@@ -293,20 +279,20 @@ impl MutHeapJSVal {
/// on `JS<T>`.
#[must_root]
#[derive(JSTraceable)]
-pub struct MutHeap<T: HeapGCValue> {
- val: UnsafeCell<T>,
+pub struct MutJS<T: DomObject> {
+ val: UnsafeCell<JS<T>>,
}
-impl<T: DomObject> MutHeap<JS<T>> {
- /// Create a new `MutHeap`.
- pub fn new(initial: &T) -> MutHeap<JS<T>> {
+impl<T: DomObject> MutJS<T> {
+ /// Create a new `MutJS`.
+ pub fn new(initial: &T) -> MutJS<T> {
debug_assert!(thread_state::get().is_script());
- MutHeap {
+ MutJS {
val: UnsafeCell::new(JS::from_ref(initial)),
}
}
- /// Set this `MutHeap` to the given value.
+ /// Set this `MutJS` to the given value.
pub fn set(&self, val: &T) {
debug_assert!(thread_state::get().is_script());
unsafe {
@@ -314,7 +300,7 @@ impl<T: DomObject> MutHeap<JS<T>> {
}
}
- /// Get the value in this `MutHeap`.
+ /// Get the value in this `MutJS`.
pub fn get(&self) -> Root<T> {
debug_assert!(thread_state::get().is_script());
unsafe {
@@ -323,14 +309,14 @@ impl<T: DomObject> MutHeap<JS<T>> {
}
}
-impl<T: HeapGCValue> HeapSizeOf for MutHeap<T> {
+impl<T: DomObject> HeapSizeOf for MutJS<T> {
fn heap_size_of_children(&self) -> usize {
// See comment on HeapSizeOf for JS<T>.
0
}
}
-impl<T: DomObject> PartialEq for MutHeap<JS<T>> {
+impl<T: DomObject> PartialEq for MutJS<T> {
fn eq(&self, other: &Self) -> bool {
unsafe {
*self.val.get() == *other.val.get()
@@ -338,7 +324,7 @@ impl<T: DomObject> PartialEq for MutHeap<JS<T>> {
}
}
-impl<T: DomObject + PartialEq> PartialEq<T> for MutHeap<JS<T>> {
+impl<T: DomObject + PartialEq> PartialEq<T> for MutJS<T> {
fn eq(&self, other: &T) -> bool {
unsafe {
**self.val.get() == *other
@@ -354,15 +340,15 @@ impl<T: DomObject + PartialEq> PartialEq<T> for MutHeap<JS<T>> {
/// on `JS<T>`.
#[must_root]
#[derive(JSTraceable)]
-pub struct MutNullableHeap<T: HeapGCValue> {
- ptr: UnsafeCell<Option<T>>,
+pub struct MutNullableJS<T: DomObject> {
+ ptr: UnsafeCell<Option<JS<T>>>,
}
-impl<T: DomObject> MutNullableHeap<JS<T>> {
- /// Create a new `MutNullableHeap`.
- pub fn new(initial: Option<&T>) -> MutNullableHeap<JS<T>> {
+impl<T: DomObject> MutNullableJS<T> {
+ /// Create a new `MutNullableJS`.
+ pub fn new(initial: Option<&T>) -> MutNullableJS<T> {
debug_assert!(thread_state::get().is_script());
- MutNullableHeap {
+ MutNullableJS {
ptr: UnsafeCell::new(initial.map(JS::from_ref)),
}
}
@@ -400,7 +386,7 @@ impl<T: DomObject> MutNullableHeap<JS<T>> {
}
}
- /// Set this `MutNullableHeap` to the given value.
+ /// Set this `MutNullableJS` to the given value.
pub fn set(&self, val: Option<&T>) {
debug_assert!(thread_state::get().is_script());
unsafe {
@@ -416,7 +402,7 @@ impl<T: DomObject> MutNullableHeap<JS<T>> {
}
}
-impl<T: DomObject> PartialEq for MutNullableHeap<JS<T>> {
+impl<T: DomObject> PartialEq for MutNullableJS<T> {
fn eq(&self, other: &Self) -> bool {
unsafe {
*self.ptr.get() == *other.ptr.get()
@@ -424,7 +410,7 @@ impl<T: DomObject> PartialEq for MutNullableHeap<JS<T>> {
}
}
-impl<'a, T: DomObject> PartialEq<Option<&'a T>> for MutNullableHeap<JS<T>> {
+impl<'a, T: DomObject> PartialEq<Option<&'a T>> for MutNullableJS<T> {
fn eq(&self, other: &Option<&T>) -> bool {
unsafe {
*self.ptr.get() == other.map(JS::from_ref)
@@ -432,17 +418,17 @@ impl<'a, T: DomObject> PartialEq<Option<&'a T>> for MutNullableHeap<JS<T>> {
}
}
-impl<T: HeapGCValue> Default for MutNullableHeap<T> {
+impl<T: DomObject> Default for MutNullableJS<T> {
#[allow(unrooted_must_root)]
- fn default() -> MutNullableHeap<T> {
+ fn default() -> MutNullableJS<T> {
debug_assert!(thread_state::get().is_script());
- MutNullableHeap {
+ MutNullableJS {
ptr: UnsafeCell::new(None),
}
}
}
-impl<T: HeapGCValue> HeapSizeOf for MutNullableHeap<T> {
+impl<T: DomObject> HeapSizeOf for MutNullableJS<T> {
fn heap_size_of_children(&self) -> usize {
// See comment on HeapSizeOf for JS<T>.
0
diff --git a/components/script/dom/bindings/mod.rs b/components/script/dom/bindings/mod.rs
index 27504efda7c..4e7920828dd 100644
--- a/components/script/dom/bindings/mod.rs
+++ b/components/script/dom/bindings/mod.rs
@@ -129,6 +129,10 @@
//! return `Err()` from the method with the appropriate [error value]
//! (error/enum.Error.html).
+#![allow(unsafe_code)]
+#![deny(missing_docs)]
+#![deny(non_snake_case)]
+
pub mod callback;
pub mod cell;
pub mod constant;
@@ -153,7 +157,7 @@ pub mod weakref;
pub mod xmlname;
/// Generated JS-Rust bindings.
-#[allow(missing_docs, non_snake_case)]
+#[allow(dead_code, missing_docs, non_snake_case)]
pub mod codegen {
#[allow(unrooted_must_root)]
pub mod Bindings {
diff --git a/components/script/dom/bindings/str.rs b/components/script/dom/bindings/str.rs
index d7984939e28..896c2af5b24 100644
--- a/components/script/dom/bindings/str.rs
+++ b/components/script/dom/bindings/str.rs
@@ -286,6 +286,12 @@ impl Into<Vec<u8>> for DOMString {
}
}
+impl<'a> Into<Cow<'a, str>> for DOMString {
+ fn into(self) -> Cow<'a, str> {
+ self.0.into()
+ }
+}
+
impl Extend<char> for DOMString {
fn extend<I>(&mut self, iterable: I) where I: IntoIterator<Item=char> {
self.0.extend(iterable)
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs
index 4c650719bff..850bef189c7 100644
--- a/components/script/dom/bindings/trace.rs
+++ b/components/script/dom/bindings/trace.rs
@@ -48,7 +48,6 @@ use euclid::length::Length as EuclidLength;
use euclid::rect::Rect;
use euclid::size::Size2D;
use html5ever::tokenizer::buffer_queue::BufferQueue;
-use html5ever::tree_builder::QuirksMode;
use html5ever_atoms::{Prefix, LocalName, Namespace, QualName};
use hyper::header::Headers;
use hyper::method::Method;
@@ -59,7 +58,6 @@ use js::glue::{CallObjectTracer, CallUnbarrieredObjectTracer, CallValueTracer};
use js::jsapi::{GCTraceKindToAscii, Heap, JSObject, JSTracer, TraceKind};
use js::jsval::JSVal;
use js::rust::Runtime;
-use libc;
use msg::constellation_msg::{FrameId, FrameType, PipelineId};
use net_traits::{Metadata, NetworkError, ReferrerPolicy, ResourceThreads};
use net_traits::filemanager_thread::RelativePos;
@@ -82,7 +80,7 @@ use serde::{Deserialize, Serialize};
use servo_atoms::Atom;
use servo_url::ServoUrl;
use smallvec::SmallVec;
-use std::cell::{Cell, UnsafeCell};
+use std::cell::{Cell, RefCell, UnsafeCell};
use std::collections::{BTreeMap, HashMap, HashSet, VecDeque};
use std::hash::{BuildHasher, Hash};
use std::ops::{Deref, DerefMut};
@@ -93,13 +91,14 @@ use std::sync::atomic::{AtomicBool, AtomicUsize};
use std::sync::mpsc::{Receiver, Sender};
use std::time::{SystemTime, Instant};
use style::attr::{AttrIdentifier, AttrValue, LengthOrPercentageOrAuto};
+use style::context::QuirksMode;
use style::element_state::*;
use style::font_face::FontFaceRule;
use style::keyframes::Keyframe;
use style::media_queries::MediaList;
use style::properties::PropertyDeclarationBlock;
use style::selector_parser::{PseudoElement, Snapshot};
-use style::stylesheets::{CssRules, KeyframesRule, MediaRule, NamespaceRule, StyleRule};
+use style::stylesheets::{CssRules, KeyframesRule, MediaRule, NamespaceRule, StyleRule, ImportRule};
use style::values::specified::Length;
use style::viewport::ViewportRule;
use time::Duration;
@@ -526,6 +525,12 @@ unsafe impl JSTraceable for RwLock<KeyframesRule> {
}
}
+unsafe impl JSTraceable for RwLock<ImportRule> {
+ unsafe fn trace(&self, _trc: *mut JSTracer) {
+ // Do nothing.
+ }
+}
+
unsafe impl JSTraceable for RwLock<MediaRule> {
unsafe fn trace(&self, _trc: *mut JSTracer) {
// Do nothing.
@@ -568,27 +573,16 @@ unsafe impl JSTraceable for RwLock<MediaList> {
}
}
-/// Homemade trait object for JSTraceable things
-struct TraceableInfo {
- pub ptr: *const libc::c_void,
- pub trace: unsafe fn(obj: *const libc::c_void, tracer: *mut JSTracer),
-}
-
/// Holds a set of JSTraceables that need to be rooted
pub struct RootedTraceableSet {
- set: Vec<TraceableInfo>,
+ set: Vec<*const JSTraceable>,
}
-#[allow(missing_docs)] // FIXME
-mod dummy { // Attributes don’t apply through the macro.
- use std::cell::RefCell;
- use std::rc::Rc;
- use super::RootedTraceableSet;
+thread_local!(
/// TLV Holds a set of JSTraceables that need to be rooted
- thread_local!(pub static ROOTED_TRACEABLES: Rc<RefCell<RootedTraceableSet>> =
- Rc::new(RefCell::new(RootedTraceableSet::new())));
-}
-pub use self::dummy::ROOTED_TRACEABLES;
+ static ROOTED_TRACEABLES: RefCell<RootedTraceableSet> =
+ RefCell::new(RootedTraceableSet::new());
+);
impl RootedTraceableSet {
fn new() -> RootedTraceableSet {
@@ -597,12 +591,12 @@ impl RootedTraceableSet {
}
}
- unsafe fn remove<T: JSTraceable>(traceable: &T) {
+ unsafe fn remove(traceable: *const JSTraceable) {
ROOTED_TRACEABLES.with(|ref traceables| {
let mut traceables = traceables.borrow_mut();
let idx =
match traceables.set.iter()
- .rposition(|x| x.ptr == traceable as *const T as *const _) {
+ .rposition(|x| *x == traceable) {
Some(idx) => idx,
None => unreachable!(),
};
@@ -610,25 +604,15 @@ impl RootedTraceableSet {
});
}
- unsafe fn add<T: JSTraceable>(traceable: &T) {
+ unsafe fn add(traceable: *const JSTraceable) {
ROOTED_TRACEABLES.with(|ref traceables| {
- unsafe fn trace<T: JSTraceable>(obj: *const libc::c_void, tracer: *mut JSTracer) {
- let obj: &T = &*(obj as *const T);
- obj.trace(tracer);
- }
-
- let mut traceables = traceables.borrow_mut();
- let info = TraceableInfo {
- ptr: traceable as *const T as *const libc::c_void,
- trace: trace::<T>,
- };
- traceables.set.push(info);
+ traceables.borrow_mut().set.push(traceable);
})
}
unsafe fn trace(&self, tracer: *mut JSTracer) {
- for info in &self.set {
- (info.trace)(info.ptr, tracer);
+ for traceable in &self.set {
+ (**traceable).trace(tracer);
}
}
}
@@ -640,11 +624,11 @@ impl RootedTraceableSet {
/// If you have an arbitrary number of DomObjects to root, use rooted_vec!.
/// If you know what you're doing, use this.
#[derive(JSTraceable)]
-pub struct RootedTraceable<'a, T: 'a + JSTraceable> {
+pub struct RootedTraceable<'a, T: 'static + JSTraceable> {
ptr: &'a T,
}
-impl<'a, T: JSTraceable> RootedTraceable<'a, T> {
+impl<'a, T: JSTraceable + 'static> RootedTraceable<'a, T> {
/// Root a JSTraceable thing for the life of this RootedTraceable
pub fn new(traceable: &'a T) -> RootedTraceable<'a, T> {
unsafe {
@@ -656,7 +640,7 @@ impl<'a, T: JSTraceable> RootedTraceable<'a, T> {
}
}
-impl<'a, T: JSTraceable> Drop for RootedTraceable<'a, T> {
+impl<'a, T: JSTraceable + 'static> Drop for RootedTraceable<'a, T> {
fn drop(&mut self) {
unsafe {
RootedTraceableSet::remove(self.ptr);
@@ -686,15 +670,29 @@ impl<T: JSTraceable> RootableVec<T> {
/// A vector of items that are rooted for the lifetime 'a.
#[allow_unrooted_interior]
-pub struct RootedVec<'a, T: 'a + JSTraceable> {
+pub struct RootedVec<'a, T: 'static + JSTraceable> {
root: &'a mut RootableVec<T>,
}
-impl<'a, T: JSTraceable + DomObject> RootedVec<'a, JS<T>> {
+impl<'a, T: 'static + JSTraceable> RootedVec<'a, T> {
/// Create a vector of items of type T that is rooted for
/// the lifetime of this struct
- pub fn new<I: Iterator<Item = Root<T>>>(root: &'a mut RootableVec<JS<T>>, iter: I)
- -> RootedVec<'a, JS<T>> {
+ pub fn new(root: &'a mut RootableVec<T>) -> Self {
+ unsafe {
+ RootedTraceableSet::add(root);
+ }
+ RootedVec {
+ root: root,
+ }
+ }
+}
+
+impl<'a, T: 'static + JSTraceable + DomObject> RootedVec<'a, JS<T>> {
+ /// Create a vector of items of type JS<T> that is rooted for
+ /// the lifetime of this struct
+ pub fn from_iter<I>(root: &'a mut RootableVec<JS<T>>, iter: I) -> Self
+ where I: Iterator<Item = Root<T>>
+ {
unsafe {
RootedTraceableSet::add(root);
}
@@ -705,7 +703,7 @@ impl<'a, T: JSTraceable + DomObject> RootedVec<'a, JS<T>> {
}
}
-impl<'a, T: JSTraceable> Drop for RootedVec<'a, T> {
+impl<'a, T: JSTraceable + 'static> Drop for RootedVec<'a, T> {
fn drop(&mut self) {
self.clear();
unsafe {
diff --git a/components/script/dom/bluetooth.rs b/components/script/dom/bluetooth.rs
index 5a657eb6459..dcbb398a4ee 100644
--- a/components/script/dom/bluetooth.rs
+++ b/components/script/dom/bluetooth.rs
@@ -2,8 +2,8 @@
* 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 bluetooth_traits::{BluetoothError, BluetoothRequest};
-use bluetooth_traits::{BluetoothResponse, BluetoothResponseListener, BluetoothResponseResult};
+use bluetooth_traits::{BluetoothError, BluetoothRequest, GATTType};
+use bluetooth_traits::{BluetoothResponse, BluetoothResponseResult};
use bluetooth_traits::blocklist::{Blocklist, uuid_is_blocklisted};
use bluetooth_traits::scanfilter::{BluetoothScanfilter, BluetoothScanfilterSequence};
use bluetooth_traits::scanfilter::{RequestDeviceoptions, ServiceUUIDSequence};
@@ -13,22 +13,21 @@ use dom::bindings::codegen::Bindings::BluetoothBinding::{self, BluetoothDataFilt
use dom::bindings::codegen::Bindings::BluetoothBinding::{BluetoothMethods, RequestDeviceOptions};
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::codegen::UnionTypes::StringOrUnsignedLong;
-use dom::bindings::error::Error::{self, NotFound, Security, Type};
+use dom::bindings::error::Error::{self, Network, NotFound, Security, Type};
use dom::bindings::error::Fallible;
-use dom::bindings::js::{JS, MutHeap, Root};
+use dom::bindings::js::{MutJS, Root};
use dom::bindings::refcounted::{Trusted, TrustedPromise};
use dom::bindings::reflector::{DomObject, reflect_dom_object};
use dom::bindings::str::DOMString;
-use dom::bluetoothadvertisingdata::BluetoothAdvertisingData;
use dom::bluetoothdevice::BluetoothDevice;
-use dom::bluetoothuuid::{BluetoothServiceUUID, BluetoothUUID};
+use dom::bluetoothuuid::{BluetoothServiceUUID, BluetoothUUID, UUID};
use dom::eventtarget::EventTarget;
use dom::globalscope::GlobalScope;
use dom::promise::Promise;
use ipc_channel::ipc::{self, IpcSender};
use ipc_channel::router::ROUTER;
use js::jsapi::{JSAutoCompartment, JSContext};
-use network_listener::{NetworkListener, PreInvoke};
+use script_thread::Runnable;
use std::collections::HashMap;
use std::rc::Rc;
use std::str::FromStr;
@@ -62,9 +61,7 @@ pub trait AsyncBluetoothListener {
fn handle_response(&self, result: BluetoothResponse, cx: *mut JSContext, promise: &Rc<Promise>);
}
-impl<Listener: AsyncBluetoothListener + DomObject> PreInvoke for BluetoothContext<Listener> {}
-
-impl<Listener: AsyncBluetoothListener + DomObject> BluetoothResponseListener for BluetoothContext<Listener> {
+impl<T: AsyncBluetoothListener + DomObject> BluetoothContext<T> {
#[allow(unrooted_must_root)]
fn response(&mut self, response: BluetoothResponseResult) {
let promise = self.promise.take().expect("bt promise is missing").root();
@@ -86,7 +83,7 @@ impl<Listener: AsyncBluetoothListener + DomObject> BluetoothResponseListener for
#[dom_struct]
pub struct Bluetooth {
eventtarget: EventTarget,
- device_instance_map: DOMRefCell<HashMap<String, MutHeap<JS<BluetoothDevice>>>>,
+ device_instance_map: DOMRefCell<HashMap<String, MutJS<BluetoothDevice>>>,
}
impl Bluetooth {
@@ -107,6 +104,10 @@ impl Bluetooth {
self.global().as_window().bluetooth_thread()
}
+ pub fn get_device_map(&self) -> &DOMRefCell<HashMap<String, MutJS<BluetoothDevice>>> {
+ &self.device_instance_map
+ }
+
// https://webbluetoothcg.github.io/web-bluetooth/#request-bluetooth-devices
fn request_bluetooth_devices(&self,
p: &Rc<Promise>,
@@ -183,17 +184,84 @@ pub fn response_async<T: AsyncBluetoothListener + DomObject + 'static>(
promise: Some(TrustedPromise::new(promise.clone())),
receiver: Trusted::new(receiver),
}));
- let listener = NetworkListener {
- context: context,
- task_source: task_source,
- wrapper: None,
- };
ROUTER.add_route(action_receiver.to_opaque(), box move |message| {
- listener.notify_response(message.to().unwrap());
+ struct ListenerRunnable<T: AsyncBluetoothListener + DomObject> {
+ context: Arc<Mutex<BluetoothContext<T>>>,
+ action: BluetoothResponseResult,
+ }
+
+ impl<T: AsyncBluetoothListener + DomObject> Runnable for ListenerRunnable<T> {
+ fn handler(self: Box<Self>) {
+ let this = *self;
+ let mut context = this.context.lock().unwrap();
+ context.response(this.action);
+ }
+ }
+
+ let runnable = box ListenerRunnable {
+ context: context.clone(),
+ action: message.to().unwrap(),
+ };
+
+ let result = task_source.queue_wrapperless(runnable);
+ if let Err(err) = result {
+ warn!("failed to deliver network data: {:?}", err);
+ }
});
action_sender
}
+#[allow(unrooted_must_root)]
+// https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren
+pub fn get_gatt_children<T, F> (
+ attribute: &T,
+ single: bool,
+ uuid_canonicalizer: F,
+ uuid: Option<StringOrUnsignedLong>,
+ instance_id: String,
+ connected: bool,
+ child_type: GATTType)
+ -> Rc<Promise>
+ where T: AsyncBluetoothListener + DomObject + 'static,
+ F: FnOnce(StringOrUnsignedLong) -> Fallible<UUID> {
+ let p = Promise::new(&attribute.global());
+ let p_cx = p.global().get_cx();
+
+ let result_uuid = if let Some(u) = uuid {
+ // Step 1.
+ let canonicalized = match uuid_canonicalizer(u) {
+ Ok(canonicalized_uuid) => canonicalized_uuid.to_string(),
+ Err(e) => {
+ p.reject_error(p_cx, e);
+ return p;
+ }
+ };
+ // Step 2.
+ if uuid_is_blocklisted(canonicalized.as_ref(), Blocklist::All) {
+ p.reject_error(p_cx, Security);
+ return p;
+ }
+ Some(canonicalized)
+ } else {
+ None
+ };
+
+ // Step 3 - 4.
+ if !connected {
+ p.reject_error(p_cx, Network);
+ return p;
+ }
+
+ // TODO: Step 5: Implement representedDevice internal slot for BluetoothDevice.
+
+ // Note: Steps 6 - 7 are implemented in components/bluetooth/lib.rs in get_descriptor function
+ // and in handle_response function.
+ let sender = response_async(&p, attribute);
+ attribute.global().as_window().bluetooth_thread().send(
+ BluetoothRequest::GetGATTChildren(instance_id, result_uuid, single, child_type, sender)).unwrap();
+ return p;
+}
+
// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothlescanfilterinit-canonicalizing
fn canonicalize_filter(filter: &BluetoothLEScanFilterInit) -> Fallible<BluetoothScanfilter> {
// Step 1.
@@ -400,16 +468,11 @@ impl AsyncBluetoothListener for Bluetooth {
if let Some(existing_device) = device_instance_map.get(&device.id.clone()) {
return promise.resolve_native(promise_cx, &existing_device.get());
}
- let ad_data = BluetoothAdvertisingData::new(&self.global(),
- device.appearance,
- device.tx_power,
- device.rssi);
let bt_device = BluetoothDevice::new(&self.global(),
DOMString::from(device.id.clone()),
device.name.map(DOMString::from),
- &ad_data,
&self);
- device_instance_map.insert(device.id, MutHeap::new(&bt_device));
+ device_instance_map.insert(device.id, MutJS::new(&bt_device));
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-requestdevice
// Step 5.
promise.resolve_native(promise_cx, &bt_device);
diff --git a/components/script/dom/bluetoothadvertisingdata.rs b/components/script/dom/bluetoothadvertisingdata.rs
deleted file mode 100644
index 878f4fe82ec..00000000000
--- a/components/script/dom/bluetoothadvertisingdata.rs
+++ /dev/null
@@ -1,61 +0,0 @@
-/* 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::BluetoothAdvertisingDataBinding;
-use dom::bindings::codegen::Bindings::BluetoothAdvertisingDataBinding::BluetoothAdvertisingDataMethods;
-use dom::bindings::js::Root;
-use dom::bindings::reflector::{Reflector, reflect_dom_object};
-use dom::globalscope::GlobalScope;
-
-// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothadvertisingdata
-#[dom_struct]
-pub struct BluetoothAdvertisingData {
- reflector_: Reflector,
- appearance: Option<u16>,
- tx_power: Option<i8>,
- rssi: Option<i8>,
-}
-
-impl BluetoothAdvertisingData {
- pub fn new_inherited(appearance: Option<u16>,
- tx_power: Option<i8>,
- rssi: Option<i8>)
- -> BluetoothAdvertisingData {
- BluetoothAdvertisingData {
- reflector_: Reflector::new(),
- appearance: appearance,
- tx_power: tx_power,
- rssi: rssi,
- }
- }
-
- pub fn new(global: &GlobalScope,
- appearance: Option<u16>,
- txPower: Option<i8>,
- rssi: Option<i8>)
- -> Root<BluetoothAdvertisingData> {
- reflect_dom_object(box BluetoothAdvertisingData::new_inherited(appearance,
- txPower,
- rssi),
- global,
- BluetoothAdvertisingDataBinding::Wrap)
- }
-}
-
-impl BluetoothAdvertisingDataMethods for BluetoothAdvertisingData {
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothadvertisingdata-appearance
- fn GetAppearance(&self) -> Option<u16> {
- self.appearance
- }
-
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothadvertisingdata-txpower
- fn GetTxPower(&self) -> Option<i8> {
- self.tx_power
- }
-
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothadvertisingdata-rssi
- fn GetRssi(&self) -> Option<i8> {
- self.rssi
- }
-}
diff --git a/components/script/dom/bluetoothadvertisingevent.rs b/components/script/dom/bluetoothadvertisingevent.rs
new file mode 100644
index 00000000000..cc65aa4cd96
--- /dev/null
+++ b/components/script/dom/bluetoothadvertisingevent.rs
@@ -0,0 +1,126 @@
+/* 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::BluetoothAdvertisingEventBinding::{self, BluetoothAdvertisingEventInit};
+use dom::bindings::codegen::Bindings::BluetoothAdvertisingEventBinding::BluetoothAdvertisingEventMethods;
+use dom::bindings::codegen::Bindings::EventBinding::EventBinding::EventMethods;
+use dom::bindings::error::Fallible;
+use dom::bindings::inheritance::Castable;
+use dom::bindings::js::{JS, Root, RootedReference};
+use dom::bindings::reflector::reflect_dom_object;
+use dom::bindings::str::DOMString;
+use dom::bluetoothdevice::BluetoothDevice;
+use dom::event::{Event, EventBubbles, EventCancelable};
+use dom::globalscope::GlobalScope;
+use dom::window::Window;
+use servo_atoms::Atom;
+
+// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothadvertisingevent
+#[dom_struct]
+pub struct BluetoothAdvertisingEvent {
+ event: Event,
+ device: JS<BluetoothDevice>,
+ name: Option<DOMString>,
+ appearance: Option<u16>,
+ tx_power: Option<i8>,
+ rssi: Option<i8>,
+}
+
+impl BluetoothAdvertisingEvent {
+ pub fn new_inherited(device: &BluetoothDevice,
+ name: Option<DOMString>,
+ appearance: Option<u16>,
+ tx_power: Option<i8>,
+ rssi: Option<i8>)
+ -> BluetoothAdvertisingEvent {
+ BluetoothAdvertisingEvent {
+ event: Event::new_inherited(),
+ device: JS::from_ref(device),
+ name: name,
+ appearance: appearance,
+ tx_power: tx_power,
+ rssi: rssi,
+ }
+ }
+
+ pub fn new(global: &GlobalScope,
+ type_: Atom,
+ bubbles: EventBubbles,
+ cancelable: EventCancelable,
+ device: &BluetoothDevice,
+ name: Option<DOMString>,
+ appearance: Option<u16>,
+ txPower: Option<i8>,
+ rssi: Option<i8>)
+ -> Root<BluetoothAdvertisingEvent> {
+ let ev = reflect_dom_object(box BluetoothAdvertisingEvent::new_inherited(device,
+ name,
+ appearance,
+ txPower,
+ rssi),
+ global,
+ BluetoothAdvertisingEventBinding::Wrap);
+ {
+ let event = ev.upcast::<Event>();
+ event.init_event(type_, bool::from(bubbles), bool::from(cancelable));
+ }
+ ev
+ }
+
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothadvertisingevent-bluetoothadvertisingevent
+ pub fn Constructor(window: &Window,
+ type_: DOMString,
+ init: &BluetoothAdvertisingEventInit)
+ -> Fallible<Root<BluetoothAdvertisingEvent>> {
+ let global = window.upcast::<GlobalScope>();
+ let device = init.device.r();
+ let name = init.name.clone();
+ let appearance = init.appearance.clone();
+ let txPower = init.txPower.clone();
+ let rssi = init.rssi.clone();
+ let bubbles = EventBubbles::from(init.parent.bubbles);
+ let cancelable = EventCancelable::from(init.parent.cancelable);
+ Ok(BluetoothAdvertisingEvent::new(global,
+ Atom::from(type_),
+ bubbles,
+ cancelable,
+ device,
+ name,
+ appearance,
+ txPower,
+ rssi))
+ }
+}
+
+impl BluetoothAdvertisingEventMethods for BluetoothAdvertisingEvent {
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothadvertisingevent-device
+ fn Device(&self) -> Root<BluetoothDevice> {
+ Root::from_ref(&*self.device)
+ }
+
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothadvertisingevent-name
+ fn GetName(&self) -> Option<DOMString> {
+ self.name.clone()
+ }
+
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothadvertisingevent-appearance
+ fn GetAppearance(&self) -> Option<u16> {
+ self.appearance
+ }
+
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothadvertisingevent-txpower
+ fn GetTxPower(&self) -> Option<i8> {
+ self.tx_power
+ }
+
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothadvertisingevent-rssi
+ fn GetRssi(&self) -> Option<i8> {
+ self.rssi
+ }
+
+ // https://dom.spec.whatwg.org/#dom-event-istrusted
+ fn IsTrusted(&self) -> bool {
+ self.event.IsTrusted()
+ }
+}
diff --git a/components/script/dom/bluetoothdevice.rs b/components/script/dom/bluetoothdevice.rs
index b257b82f343..d56970c0d98 100644
--- a/components/script/dom/bluetoothdevice.rs
+++ b/components/script/dom/bluetoothdevice.rs
@@ -2,17 +2,20 @@
* 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 bluetooth_traits::{BluetoothCharacteristicMsg, BluetoothDescriptorMsg, BluetoothServiceMsg};
+use bluetooth_traits::{BluetoothCharacteristicMsg, BluetoothDescriptorMsg};
+use bluetooth_traits::{BluetoothRequest, BluetoothResponse, BluetoothServiceMsg};
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::BluetoothDeviceBinding;
use dom::bindings::codegen::Bindings::BluetoothDeviceBinding::BluetoothDeviceMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods;
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
-use dom::bindings::js::{JS, Root, MutHeap, MutNullableHeap};
+use dom::bindings::error::Error;
+use dom::bindings::error::ErrorResult;
+use dom::bindings::inheritance::Castable;
+use dom::bindings::js::{MutJS, MutNullableJS, Root};
use dom::bindings::reflector::{DomObject, reflect_dom_object};
use dom::bindings::str::DOMString;
-use dom::bluetooth::Bluetooth;
-use dom::bluetoothadvertisingdata::BluetoothAdvertisingData;
+use dom::bluetooth::{AsyncBluetoothListener, Bluetooth, response_async};
use dom::bluetoothcharacteristicproperties::BluetoothCharacteristicProperties;
use dom::bluetoothremotegattcharacteristic::BluetoothRemoteGATTCharacteristic;
use dom::bluetoothremotegattdescriptor::BluetoothRemoteGATTDescriptor;
@@ -20,8 +23,12 @@ use dom::bluetoothremotegattserver::BluetoothRemoteGATTServer;
use dom::bluetoothremotegattservice::BluetoothRemoteGATTService;
use dom::eventtarget::EventTarget;
use dom::globalscope::GlobalScope;
+use dom::promise::Promise;
+use ipc_channel::ipc::{self, IpcSender};
+use js::jsapi::JSContext;
+use std::cell::Cell;
use std::collections::HashMap;
-
+use std::rc::Rc;
// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothdevice
#[dom_struct]
@@ -29,47 +36,48 @@ pub struct BluetoothDevice {
eventtarget: EventTarget,
id: DOMString,
name: Option<DOMString>,
- ad_data: MutHeap<JS<BluetoothAdvertisingData>>,
- gatt: MutNullableHeap<JS<BluetoothRemoteGATTServer>>,
- context: MutHeap<JS<Bluetooth>>,
- attribute_instance_map: (DOMRefCell<HashMap<String, MutHeap<JS<BluetoothRemoteGATTService>>>>,
- DOMRefCell<HashMap<String, MutHeap<JS<BluetoothRemoteGATTCharacteristic>>>>,
- DOMRefCell<HashMap<String, MutHeap<JS<BluetoothRemoteGATTDescriptor>>>>),
+ gatt: MutNullableJS<BluetoothRemoteGATTServer>,
+ context: MutJS<Bluetooth>,
+ attribute_instance_map: (DOMRefCell<HashMap<String, MutJS<BluetoothRemoteGATTService>>>,
+ DOMRefCell<HashMap<String, MutJS<BluetoothRemoteGATTCharacteristic>>>,
+ DOMRefCell<HashMap<String, MutJS<BluetoothRemoteGATTDescriptor>>>),
+ watching_advertisements: Cell<bool>,
}
impl BluetoothDevice {
pub fn new_inherited(id: DOMString,
name: Option<DOMString>,
- ad_data: &BluetoothAdvertisingData,
context: &Bluetooth)
-> BluetoothDevice {
BluetoothDevice {
eventtarget: EventTarget::new_inherited(),
id: id,
name: name,
- ad_data: MutHeap::new(ad_data),
gatt: Default::default(),
- context: MutHeap::new(context),
+ context: MutJS::new(context),
attribute_instance_map: (DOMRefCell::new(HashMap::new()),
DOMRefCell::new(HashMap::new()),
DOMRefCell::new(HashMap::new())),
+ watching_advertisements: Cell::new(false),
}
}
pub fn new(global: &GlobalScope,
id: DOMString,
name: Option<DOMString>,
- adData: &BluetoothAdvertisingData,
context: &Bluetooth)
-> Root<BluetoothDevice> {
reflect_dom_object(box BluetoothDevice::new_inherited(id,
name,
- adData,
context),
global,
BluetoothDeviceBinding::Wrap)
}
+ fn get_context(&self) -> Root<Bluetooth> {
+ self.context.get()
+ }
+
pub fn get_or_create_service(&self,
service: &BluetoothServiceMsg,
server: &BluetoothRemoteGATTServer)
@@ -84,7 +92,7 @@ impl BluetoothDevice {
DOMString::from(service.uuid.clone()),
service.is_primary,
service.instance_id.clone());
- service_map.insert(service.instance_id.clone(), MutHeap::new(&bt_service));
+ service_map.insert(service.instance_id.clone(), MutJS::new(&bt_service));
return bt_service;
}
@@ -113,10 +121,17 @@ impl BluetoothDevice {
DOMString::from(characteristic.uuid.clone()),
&properties,
characteristic.instance_id.clone());
- characteristic_map.insert(characteristic.instance_id.clone(), MutHeap::new(&bt_characteristic));
+ characteristic_map.insert(characteristic.instance_id.clone(), MutJS::new(&bt_characteristic));
return bt_characteristic;
}
+ pub fn is_represented_device_null(&self) -> bool {
+ let (sender, receiver) = ipc::channel().unwrap();
+ self.get_bluetooth_thread().send(
+ BluetoothRequest::IsRepresentedDeviceNull(self.Id().to_string(), sender)).unwrap();
+ receiver.recv().unwrap()
+ }
+
pub fn get_or_create_descriptor(&self,
descriptor: &BluetoothDescriptorMsg,
characteristic: &BluetoothRemoteGATTCharacteristic)
@@ -130,9 +145,67 @@ impl BluetoothDevice {
characteristic,
DOMString::from(descriptor.uuid.clone()),
descriptor.instance_id.clone());
- descriptor_map.insert(descriptor.instance_id.clone(), MutHeap::new(&bt_descriptor));
+ descriptor_map.insert(descriptor.instance_id.clone(), MutJS::new(&bt_descriptor));
return bt_descriptor;
}
+
+ fn get_bluetooth_thread(&self) -> IpcSender<BluetoothRequest> {
+ self.global().as_window().bluetooth_thread()
+ }
+
+ // https://webbluetoothcg.github.io/web-bluetooth/#clean-up-the-disconnected-device
+ #[allow(unrooted_must_root)]
+ pub fn clean_up_disconnected_device(&self) {
+ // Step 1.
+ self.Gatt().set_connected(false);
+
+ // TODO: Step 2: Implement activeAlgorithms internal slot for BluetoothRemoteGATTServer.
+
+ // Step 3: We don't need `context`, we get the attributeInstanceMap from the device.
+ // https://github.com/WebBluetoothCG/web-bluetooth/issues/330
+
+ // Step 4.
+ let mut service_map = self.attribute_instance_map.0.borrow_mut();
+ let service_ids = service_map.drain().map(|(id, _)| id).collect();
+
+ let mut characteristic_map = self.attribute_instance_map.1.borrow_mut();
+ let characteristic_ids = characteristic_map.drain().map(|(id, _)| id).collect();
+
+ let mut descriptor_map = self.attribute_instance_map.2.borrow_mut();
+ let descriptor_ids = descriptor_map.drain().map(|(id, _)| id).collect();
+
+ // Step 5, 6.4, 7.
+ // TODO: Step 6: Implement `active notification context set` for BluetoothRemoteGATTCharacteristic.
+ let _ = self.get_bluetooth_thread().send(
+ BluetoothRequest::SetRepresentedToNull(service_ids, characteristic_ids, descriptor_ids));
+
+ // Step 8.
+ self.upcast::<EventTarget>().fire_bubbling_event(atom!("gattserverdisconnected"));
+ }
+
+ // https://webbluetoothcg.github.io/web-bluetooth/#garbage-collect-the-connection
+ #[allow(unrooted_must_root)]
+ pub fn garbage_collect_the_connection(&self) -> ErrorResult {
+ // Step 1: TODO: Check if other systems using this device.
+
+ // Step 2.
+ let context = self.get_context();
+ for (id, device) in context.get_device_map().borrow().iter() {
+ // Step 2.1 - 2.2.
+ if id == &self.Id().to_string() {
+ if device.get().Gatt().Connected() {
+ return Ok(());
+ }
+ // TODO: Step 2.3: Implement activeAlgorithms internal slot for BluetoothRemoteGATTServer.
+ }
+ }
+
+ // Step 3.
+ let (sender, receiver) = ipc::channel().unwrap();
+ self.get_bluetooth_thread().send(
+ BluetoothRequest::GATTServerDisconnect(String::from(self.Id()), sender)).unwrap();
+ receiver.recv().unwrap().map_err(Error::from)
+ }
}
impl BluetoothDeviceMethods for BluetoothDevice {
@@ -146,11 +219,6 @@ impl BluetoothDeviceMethods for BluetoothDevice {
self.name.clone()
}
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-addata
- fn AdData(&self) -> Root<BluetoothAdvertisingData> {
- self.ad_data.get()
- }
-
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-gatt
fn Gatt(&self) -> Root<BluetoothRemoteGATTServer> {
// TODO: Step 1 - 2: Implement the Permission API.
@@ -159,6 +227,46 @@ impl BluetoothDeviceMethods for BluetoothDevice {
})
}
+ #[allow(unrooted_must_root)]
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-watchadvertisements
+ fn WatchAdvertisements(&self) -> Rc<Promise> {
+ let p = Promise::new(&self.global());
+ let sender = response_async(&p, self);
+ // TODO: Step 1.
+ // Note: Steps 2 - 3 are implemented in components/bluetooth/lib.rs in watch_advertisements function
+ // and in handle_response function.
+ self.get_bluetooth_thread().send(
+ BluetoothRequest::WatchAdvertisements(String::from(self.Id()), sender)).unwrap();
+ return p;
+ }
+
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-unwatchadvertisements
+ fn UnwatchAdvertisements(&self) -> () {
+ // Step 1.
+ self.watching_advertisements.set(false)
+ // TODO: Step 2.
+ }
+
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-watchingadvertisements
+ fn WatchingAdvertisements(&self) -> bool {
+ self.watching_advertisements.get()
+ }
+
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdeviceeventhandlers-ongattserverdisconnected
event_handler!(gattserverdisconnected, GetOngattserverdisconnected, SetOngattserverdisconnected);
}
+
+impl AsyncBluetoothListener for BluetoothDevice {
+ fn handle_response(&self, response: BluetoothResponse, promise_cx: *mut JSContext, promise: &Rc<Promise>) {
+ match response {
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-unwatchadvertisements
+ BluetoothResponse::WatchAdvertisements(_result) => {
+ // Step 3.1.
+ self.watching_advertisements.set(true);
+ // Step 3.2.
+ promise.resolve_native(promise_cx, &());
+ },
+ _ => promise.reject_error(promise_cx, Error::Type("Something went wrong...".to_owned())),
+ }
+ }
+}
diff --git a/components/script/dom/bluetoothremotegattcharacteristic.rs b/components/script/dom/bluetoothremotegattcharacteristic.rs
index eb41e6ec1db..b4b9941343b 100644
--- a/components/script/dom/bluetoothremotegattcharacteristic.rs
+++ b/components/script/dom/bluetoothremotegattcharacteristic.rs
@@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use bluetooth_traits::{BluetoothRequest, BluetoothResponse};
+use bluetooth_traits::{BluetoothRequest, BluetoothResponse, GATTType};
use bluetooth_traits::blocklist::{Blocklist, uuid_is_blocklisted};
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::BluetoothCharacteristicPropertiesBinding::
@@ -16,10 +16,10 @@ use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding::Bluetoo
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::error::Error::{self, InvalidModification, Network, NotSupported, Security};
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, MutHeap, Root};
+use dom::bindings::js::{MutJS, Root};
use dom::bindings::reflector::{DomObject, reflect_dom_object};
use dom::bindings::str::{ByteString, DOMString};
-use dom::bluetooth::{AsyncBluetoothListener, response_async};
+use dom::bluetooth::{AsyncBluetoothListener, get_gatt_children, response_async};
use dom::bluetoothcharacteristicproperties::BluetoothCharacteristicProperties;
use dom::bluetoothremotegattservice::BluetoothRemoteGATTService;
use dom::bluetoothuuid::{BluetoothDescriptorUUID, BluetoothUUID};
@@ -38,9 +38,9 @@ pub const MAXIMUM_ATTRIBUTE_LENGTH: usize = 512;
#[dom_struct]
pub struct BluetoothRemoteGATTCharacteristic {
eventtarget: EventTarget,
- service: MutHeap<JS<BluetoothRemoteGATTService>>,
+ service: MutJS<BluetoothRemoteGATTService>,
uuid: DOMString,
- properties: MutHeap<JS<BluetoothCharacteristicProperties>>,
+ properties: MutJS<BluetoothCharacteristicProperties>,
value: DOMRefCell<Option<ByteString>>,
instance_id: String,
}
@@ -53,9 +53,9 @@ impl BluetoothRemoteGATTCharacteristic {
-> BluetoothRemoteGATTCharacteristic {
BluetoothRemoteGATTCharacteristic {
eventtarget: EventTarget::new_inherited(),
- service: MutHeap::new(service),
+ service: MutJS::new(service),
uuid: uuid,
- properties: MutHeap::new(properties),
+ properties: MutJS::new(properties),
value: DOMRefCell::new(None),
instance_id: instance_id,
}
@@ -102,83 +102,18 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
#[allow(unrooted_must_root)]
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-getdescriptor
- // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren
fn GetDescriptor(&self, descriptor: BluetoothDescriptorUUID) -> Rc<Promise> {
- let p = Promise::new(&self.global());
- let p_cx = p.global().get_cx();
-
- // Step 1.
- let uuid = match BluetoothUUID::descriptor(descriptor) {
- Ok(uuid) => uuid.to_string(),
- Err(e) => {
- p.reject_error(p_cx, e);
- return p;
- }
- };
-
- // Step 2.
- if uuid_is_blocklisted(uuid.as_ref(), Blocklist::All) {
- p.reject_error(p_cx, Security);
- return p;
- }
-
- // Step 3 - 4.
- if !self.Service().Device().Gatt().Connected() {
- p.reject_error(p_cx, Network);
- return p;
- }
-
- // TODO: Step 5: Implement representedService internal slot for BluetoothRemoteGATTService.
-
- // Note: Steps 6 - 7 are implemented in components/bluetooth/lib.rs in get_descriptor function
- // and in handle_response function.
- let sender = response_async(&p, self);
- self.get_bluetooth_thread().send(
- BluetoothRequest::GetDescriptor(self.get_instance_id(), uuid, sender)).unwrap();
- return p;
+ get_gatt_children(self, true, BluetoothUUID::descriptor, Some(descriptor), self.get_instance_id(),
+ self.Service().Device().Gatt().Connected(), GATTType::Descriptor)
}
#[allow(unrooted_must_root)]
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-getdescriptors
- // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren
fn GetDescriptors(&self,
descriptor: Option<BluetoothDescriptorUUID>)
-> Rc<Promise> {
- let p = Promise::new(&self.global());
- let p_cx = p.global().get_cx();
- let mut uuid: Option<String> = None;
- if let Some(d) = descriptor {
- // Step 1.
- uuid = match BluetoothUUID::descriptor(d) {
- Ok(uuid) => Some(uuid.to_string()),
- Err(e) => {
- p.reject_error(p_cx, e);
- return p;
- }
- };
- if let Some(ref uuid) = uuid {
- // Step 2.
- if uuid_is_blocklisted(uuid.as_ref(), Blocklist::All) {
- p.reject_error(p_cx, Security);
- return p;
- }
- }
- };
-
- // Step 3 - 4.
- if !self.Service().Device().Gatt().Connected() {
- p.reject_error(p_cx, Network);
- return p;
- }
-
- // TODO: Step 5: Implement representedService internal slot for BluetoothRemoteGATTService.
-
- // Note: Steps 6 - 7 are implemented in components/bluetooth/lib.rs in get_descriptors function
- // and in handle_response function.
- let sender = response_async(&p, self);
- self.get_bluetooth_thread().send(
- BluetoothRequest::GetDescriptors(self.get_instance_id(), uuid, sender)).unwrap();
- return p;
+ get_gatt_children(self, false, BluetoothUUID::descriptor, descriptor, self.get_instance_id(),
+ self.Service().Device().Gatt().Connected(), GATTType::Descriptor)
}
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-value
@@ -204,8 +139,6 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
return p;
}
- // TODO: Step 3 - 4: Implement representedCharacteristic internal slot for BluetoothRemoteGATTCharacteristic.
-
// TODO: Step 5: Implement the `connection-checking-wrapper` algorithm for BluetoothRemoteGATTServer.
// Step 5.1.
@@ -214,8 +147,8 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
return p;
}
- // Note: Remaining substeps of Step 5 are implemented in components/bluetooth/lib.rs in readValue function
- // and in handle_response function.
+ // Note: Steps 3 - 4 and the remaining substeps of Step 5 are implemented in components/bluetooth/lib.rs
+ // in readValue function and in handle_response function.
let sender = response_async(&p, self);
self.get_bluetooth_thread().send(
BluetoothRequest::ReadValue(self.get_instance_id(), sender)).unwrap();
@@ -246,8 +179,6 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
return p;
}
- // TODO: Step 5 - 6: Implement representedCharacteristic internal slot for BluetoothRemoteGATTCharacteristic.
-
// TODO: Step 7: Implement the `connection-checking-wrapper` algorithm for BluetoothRemoteGATTServer.
// Step 7.1.
@@ -258,8 +189,8 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
return p;
}
- // Note: Remaining substeps of Step 7 are implemented in components/bluetooth/lib.rs in writeValue function
- // and in handle_response function.
+ // Note: Steps 5 - 6 and the remaining substeps of Step 7 are implemented in components/bluetooth/lib.rs
+ // in writeValue function and in handle_response function.
let sender = response_async(&p, self);
self.get_bluetooth_thread().send(
BluetoothRequest::WriteValue(self.get_instance_id(), value, sender)).unwrap();
@@ -278,8 +209,6 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
return p;
}
- // TODO: Step 2 - 3: Implement representedCharacteristic internal slot for BluetoothRemoteGATTCharacteristic.
-
// Step 4.
if !(self.Properties().Notify() ||
self.Properties().Indicate()) {
@@ -295,7 +224,7 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
return p;
}
- // Note: Steps 7 - 11 are implemented in components/bluetooth/lib.rs in enable_notification function
+ // Note: Steps 2 - 3, 7 - 11 are implemented in components/bluetooth/lib.rs in enable_notification function
// and in handle_response function.
let sender = response_async(&p, self);
self.get_bluetooth_thread().send(
@@ -311,11 +240,10 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
let p = Promise::new(&self.global());
let sender = response_async(&p, self);
- // TODO: Step 1 - 4: Implement representedCharacteristic internal slot and
- // `active notification context set` for BluetoothRemoteGATTCharacteristic,
+ // TODO: Step 3 - 4: Implement `active notification context set` for BluetoothRemoteGATTCharacteristic,
- // Note: Part of Step 4 and Step 5 are implemented in components/bluetooth/lib.rs in enable_notification
- // function and in handle_response function.
+ // Note: Steps 1 - 2, and part of Step 4 and Step 5 are implemented in components/bluetooth/lib.rs
+ // in enable_notification function and in handle_response function.
self.get_bluetooth_thread().send(
BluetoothRequest::EnableNotification(self.get_instance_id(),
false,
@@ -331,17 +259,13 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic {
fn handle_response(&self, response: BluetoothResponse, promise_cx: *mut JSContext, promise: &Rc<Promise>) {
let device = self.Service().Device();
match response {
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-getdescriptor
// https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren
// Step 7.
- BluetoothResponse::GetDescriptor(descriptor) => {
- let bt_descriptor = device.get_or_create_descriptor(&descriptor, &self);
- promise.resolve_native(promise_cx, &bt_descriptor);
- },
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-getdescriptors
- // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren
- // Step 7.
- BluetoothResponse::GetDescriptors(descriptors_vec) => {
+ BluetoothResponse::GetDescriptors(descriptors_vec, single) => {
+ if single {
+ promise.resolve_native(promise_cx, &device.get_or_create_descriptor(&descriptors_vec[0], &self));
+ return;
+ }
let mut descriptors = vec!();
for descriptor in descriptors_vec {
let bt_descriptor = device.get_or_create_descriptor(&descriptor, &self);
diff --git a/components/script/dom/bluetoothremotegattdescriptor.rs b/components/script/dom/bluetoothremotegattdescriptor.rs
index c31fae99070..b96a20c4a21 100644
--- a/components/script/dom/bluetoothremotegattdescriptor.rs
+++ b/components/script/dom/bluetoothremotegattdescriptor.rs
@@ -13,7 +13,7 @@ use dom::bindings::codegen::Bindings::BluetoothRemoteGATTDescriptorBinding::Blue
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding::BluetoothRemoteGATTServiceMethods;
use dom::bindings::error::Error::{self, InvalidModification, Network, Security};
-use dom::bindings::js::{JS, MutHeap, Root};
+use dom::bindings::js::{MutJS, Root};
use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object};
use dom::bindings::str::{ByteString, DOMString};
use dom::bluetooth::{AsyncBluetoothListener, response_async};
@@ -28,7 +28,7 @@ use std::rc::Rc;
#[dom_struct]
pub struct BluetoothRemoteGATTDescriptor {
reflector_: Reflector,
- characteristic: MutHeap<JS<BluetoothRemoteGATTCharacteristic>>,
+ characteristic: MutJS<BluetoothRemoteGATTCharacteristic>,
uuid: DOMString,
value: DOMRefCell<Option<ByteString>>,
instance_id: String,
@@ -41,7 +41,7 @@ impl BluetoothRemoteGATTDescriptor {
-> BluetoothRemoteGATTDescriptor {
BluetoothRemoteGATTDescriptor {
reflector_: Reflector::new(),
- characteristic: MutHeap::new(characteristic),
+ characteristic: MutJS::new(characteristic),
uuid: uuid,
value: DOMRefCell::new(None),
instance_id: instance_id,
@@ -103,11 +103,9 @@ impl BluetoothRemoteGATTDescriptorMethods for BluetoothRemoteGATTDescriptor {
return p;
}
- // TODO: Step 3 - 4: Implement representedDescriptor internal slot for BluetoothRemoteGATTDescriptor.
-
// TODO: Step 5: Implement the `connection-checking-wrapper` algorithm for BluetoothRemoteGATTServer.
- // Note: Substeps of Step 5 are implemented in components/bluetooth/lib.rs in readValue function
- // and in handle_response function.
+ // Note: Steps 3 - 4 and substeps of Step 5 are implemented in components/bluetooth/lib.rs
+ // in readValue function and in handle_response function.
let sender = response_async(&p, self);
self.get_bluetooth_thread().send(
BluetoothRequest::ReadValue(self.get_instance_id(), sender)).unwrap();
@@ -138,11 +136,9 @@ impl BluetoothRemoteGATTDescriptorMethods for BluetoothRemoteGATTDescriptor {
return p;
}
- // TODO: Step 5 - 6: Implement representedCharacteristic internal slot for BluetoothRemoteGATTCharacteristic.
-
// TODO: Step 7: Implement the `connection-checking-wrapper` algorithm for BluetoothRemoteGATTServer.
- // Note: Substeps of Step 7 are implemented in components/bluetooth/lib.rs in writeValue function
- // and in handle_response function.
+ // Note: Steps 5 - 6 and substeps of Step 7 are implemented in components/bluetooth/lib.rs
+ // in writeValue function and in handle_response function.
let sender = response_async(&p, self);
self.get_bluetooth_thread().send(
BluetoothRequest::WriteValue(self.get_instance_id(), value, sender)).unwrap();
diff --git a/components/script/dom/bluetoothremotegattserver.rs b/components/script/dom/bluetoothremotegattserver.rs
index d9d57ae51f1..e81aae08abe 100644
--- a/components/script/dom/bluetoothremotegattserver.rs
+++ b/components/script/dom/bluetoothremotegattserver.rs
@@ -2,21 +2,20 @@
* 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 bluetooth_traits::{BluetoothRequest, BluetoothResponse};
-use bluetooth_traits::blocklist::{Blocklist, uuid_is_blocklisted};
+use bluetooth_traits::{BluetoothRequest, BluetoothResponse, GATTType};
use dom::bindings::codegen::Bindings::BluetoothDeviceBinding::BluetoothDeviceMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods;
-use dom::bindings::error::Error::{self, Network, Security};
+use dom::bindings::error::Error;
use dom::bindings::error::ErrorResult;
-use dom::bindings::js::{JS, MutHeap, Root};
+use dom::bindings::js::{MutJS, Root};
use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object};
-use dom::bluetooth::{AsyncBluetoothListener, response_async};
+use dom::bluetooth::{AsyncBluetoothListener, get_gatt_children, response_async};
use dom::bluetoothdevice::BluetoothDevice;
use dom::bluetoothuuid::{BluetoothServiceUUID, BluetoothUUID};
use dom::globalscope::GlobalScope;
use dom::promise::Promise;
-use ipc_channel::ipc::{self, IpcSender};
+use ipc_channel::ipc::IpcSender;
use js::jsapi::JSContext;
use std::cell::Cell;
use std::rc::Rc;
@@ -25,7 +24,7 @@ use std::rc::Rc;
#[dom_struct]
pub struct BluetoothRemoteGATTServer {
reflector_: Reflector,
- device: MutHeap<JS<BluetoothDevice>>,
+ device: MutJS<BluetoothDevice>,
connected: Cell<bool>,
}
@@ -33,7 +32,7 @@ impl BluetoothRemoteGATTServer {
pub fn new_inherited(device: &BluetoothDevice) -> BluetoothRemoteGATTServer {
BluetoothRemoteGATTServer {
reflector_: Reflector::new(),
- device: MutHeap::new(device),
+ device: MutJS::new(device),
connected: Cell::new(false),
}
}
@@ -47,6 +46,10 @@ impl BluetoothRemoteGATTServer {
fn get_bluetooth_thread(&self) -> IpcSender<BluetoothRequest> {
self.global().as_window().bluetooth_thread()
}
+
+ pub fn set_connected(&self, connected: bool) {
+ self.connected.set(connected);
+ }
}
impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer {
@@ -67,17 +70,14 @@ impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer {
let p = Promise::new(&self.global());
let sender = response_async(&p, self);
- // TODO: Step 2: Implement representedDevice internal slot for BluetoothDevice.
-
// TODO: Step 3: Check if the UA is currently using the Bluetooth system.
// TODO: Step 4: Implement activeAlgorithms internal slot for BluetoothRemoteGATTServer.
- // TODO: Step 5.1 - 5.2: Implement activeAlgorithms, representedDevice internal slots
- // and the` garbage-collect the connection` algorithm.
+ // TODO: Step 5.1 - 5.2: Implement activeAlgorithms internal slot for BluetoothRemoteGATTServer.
- // Note: Steps 5.1.1 and 5.1.3 are in components/bluetooth/lib.rs in the gatt_server_connect function.
- // Steps 5.2.4 - 5.2.5 are in response function.
+ // Note: Steps 2, 5.1.1 and 5.1.3 are in components/bluetooth/lib.rs in the gatt_server_connect function.
+ // Steps 5.2.3 - 5.2.5 are in response function.
self.get_bluetooth_thread().send(
BluetoothRequest::GATTServerConnect(String::from(self.Device().Id()), sender)).unwrap();
// Step 5: return promise.
@@ -90,135 +90,63 @@ impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer {
// Step 2.
if !self.Connected() {
- return Ok(());
+ return Ok(())
}
- let (sender, receiver) = ipc::channel().unwrap();
- self.get_bluetooth_thread().send(
- BluetoothRequest::GATTServerDisconnect(String::from(self.Device().Id()), sender)).unwrap();
- let server = receiver.recv().unwrap();
-
- // TODO: Step 3: Implement the `clean up the disconnected device` algorithm.
- // TODO: Step 4: Implement representedDevice internal slot for BluetoothDevice.
+ // Step 3.
+ self.Device().clean_up_disconnected_device();
- // TODO: Step 5: Implement the `garbage-collect the connection` algorithm.
- match server {
- Ok(connected) => {
- self.connected.set(connected);
- Ok(())
- },
- Err(error) => {
- Err(Error::from(error))
- },
- }
+ // Step 4 - 5:
+ self.Device().garbage_collect_the_connection()
}
#[allow(unrooted_must_root)]
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservice
fn GetPrimaryService(&self, service: BluetoothServiceUUID) -> Rc<Promise> {
// TODO: Step 1: Implement the Permission API and the allowedServices BluetoothDevice internal slot.
- // Subsequent steps are relative to https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren
- let p = Promise::new(&self.global());
- let p_cx = p.global().get_cx();
-
- // Step 1.
- let uuid = match BluetoothUUID::service(service) {
- Ok(uuid) => uuid.to_string(),
- Err(e) => {
- p.reject_error(p_cx, e);
- return p;
- }
- };
-
// Step 2.
- if uuid_is_blocklisted(uuid.as_ref(), Blocklist::All) {
- p.reject_error(p_cx, Security);
- return p;
- }
-
- // Step 3 - 4.
- if !self.Device().Gatt().Connected() {
- p.reject_error(p_cx, Network);
- return p;
- }
-
- // TODO: Step 5: Implement representedDevice internal slot for BluetoothDevice.
-
- // Note: Steps 6 - 7 are implemented in components/bluetooth/lib.rs in get_primary_service function
- // and in handle_response function.
- let sender = response_async(&p, self);
- self.get_bluetooth_thread().send(
- BluetoothRequest::GetPrimaryService(String::from(self.Device().Id()), uuid, sender)).unwrap();
- return p;
+ get_gatt_children(self, true, BluetoothUUID::service, Some(service), String::from(self.Device().Id()),
+ self.Device().Gatt().Connected(), GATTType::PrimaryService)
}
#[allow(unrooted_must_root)]
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservices
fn GetPrimaryServices(&self, service: Option<BluetoothServiceUUID>) -> Rc<Promise> {
// TODO: Step 1: Implement the Permission API and the allowedServices BluetoothDevice internal slot.
- // Subsequent steps are relative to https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren
- let p = Promise::new(&self.global());
- let p_cx = p.global().get_cx();
-
- let mut uuid: Option<String> = None;
- if let Some(s) = service {
- // Step 1.
- uuid = match BluetoothUUID::service(s) {
- Ok(uuid) => Some(uuid.to_string()),
- Err(e) => {
- p.reject_error(p_cx, e);
- return p;
- }
- };
- if let Some(ref uuid) = uuid {
- // Step 2.
- if uuid_is_blocklisted(uuid.as_ref(), Blocklist::All) {
- p.reject_error(p_cx, Security);
- return p;
- }
- }
- };
-
- // Step 3 - 4.
- if !self.Device().Gatt().Connected() {
- p.reject_error(p_cx, Network);
- return p;
- }
-
- // TODO: Step 5: Implement representedDevice internal slot for BluetoothDevice.
+ // Step 2.
+ get_gatt_children(self, false, BluetoothUUID::service, service, String::from(self.Device().Id()),
+ self.Connected(), GATTType::PrimaryService)
- // Note: Steps 6 - 7 are implemented in components/bluetooth/lib.rs in get_primary_services function
- // and in handle_response function.
- let sender = response_async(&p, self);
- self.get_bluetooth_thread().send(
- BluetoothRequest::GetPrimaryServices(String::from(self.Device().Id()), uuid, sender)).unwrap();
- return p;
}
}
impl AsyncBluetoothListener for BluetoothRemoteGATTServer {
fn handle_response(&self, response: BluetoothResponse, promise_cx: *mut JSContext, promise: &Rc<Promise>) {
- let device = self.Device();
match response {
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-connect
BluetoothResponse::GATTServerConnect(connected) => {
+ // Step 5.2.3
+ if self.Device().is_represented_device_null() {
+ if let Err(e) = self.Device().garbage_collect_the_connection() {
+ return promise.reject_error(promise_cx, Error::from(e));
+ }
+ return promise.reject_error(promise_cx, Error::Network);
+ }
+
// Step 5.2.4.
self.connected.set(connected);
// Step 5.2.5.
promise.resolve_native(promise_cx, self);
},
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservice
// https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren
// Step 7.
- BluetoothResponse::GetPrimaryService(service) => {
- let bt_service = device.get_or_create_service(&service, &self);
- promise.resolve_native(promise_cx, &bt_service);
- },
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservices
- // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren
- // Step 7.
- BluetoothResponse::GetPrimaryServices(services_vec) => {
+ BluetoothResponse::GetPrimaryServices(services_vec, single) => {
+ let device = self.Device();
+ if single {
+ promise.resolve_native(promise_cx, &device.get_or_create_service(&services_vec[0], &self));
+ return;
+ }
let mut services = vec!();
for service in services_vec {
let bt_service = device.get_or_create_service(&service, &self);
diff --git a/components/script/dom/bluetoothremotegattservice.rs b/components/script/dom/bluetoothremotegattservice.rs
index f4aed154c7c..304cbb7d5b9 100644
--- a/components/script/dom/bluetoothremotegattservice.rs
+++ b/components/script/dom/bluetoothremotegattservice.rs
@@ -2,24 +2,22 @@
* 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 bluetooth_traits::{BluetoothRequest, BluetoothResponse};
-use bluetooth_traits::blocklist::{Blocklist, uuid_is_blocklisted};
+use bluetooth_traits::{BluetoothResponse, GATTType};
use dom::bindings::codegen::Bindings::BluetoothDeviceBinding::BluetoothDeviceMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding::BluetoothRemoteGATTServiceMethods;
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
-use dom::bindings::error::Error::{self, Network, Security};
-use dom::bindings::js::{JS, MutHeap, Root};
-use dom::bindings::reflector::{DomObject, reflect_dom_object};
+use dom::bindings::error::Error;
+use dom::bindings::js::{MutJS, Root};
+use dom::bindings::reflector::reflect_dom_object;
use dom::bindings::str::DOMString;
-use dom::bluetooth::{AsyncBluetoothListener, response_async};
+use dom::bluetooth::{AsyncBluetoothListener, get_gatt_children};
use dom::bluetoothdevice::BluetoothDevice;
use dom::bluetoothuuid::{BluetoothCharacteristicUUID, BluetoothServiceUUID, BluetoothUUID};
use dom::eventtarget::EventTarget;
use dom::globalscope::GlobalScope;
use dom::promise::Promise;
-use ipc_channel::ipc::IpcSender;
use js::jsapi::JSContext;
use std::rc::Rc;
@@ -27,7 +25,7 @@ use std::rc::Rc;
#[dom_struct]
pub struct BluetoothRemoteGATTService {
eventtarget: EventTarget,
- device: MutHeap<JS<BluetoothDevice>>,
+ device: MutJS<BluetoothDevice>,
uuid: DOMString,
is_primary: bool,
instance_id: String,
@@ -41,7 +39,7 @@ impl BluetoothRemoteGATTService {
-> BluetoothRemoteGATTService {
BluetoothRemoteGATTService {
eventtarget: EventTarget::new_inherited(),
- device: MutHeap::new(device),
+ device: MutJS::new(device),
uuid: uuid,
is_primary: is_primary,
instance_id: instance_id,
@@ -62,10 +60,6 @@ impl BluetoothRemoteGATTService {
BluetoothRemoteGATTServiceBinding::Wrap)
}
- fn get_bluetooth_thread(&self) -> IpcSender<BluetoothRequest> {
- self.global().as_window().bluetooth_thread()
- }
-
fn get_instance_id(&self) -> String {
self.instance_id.clone()
}
@@ -89,173 +83,39 @@ impl BluetoothRemoteGATTServiceMethods for BluetoothRemoteGATTService {
#[allow(unrooted_must_root)]
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getcharacteristic
- // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren
fn GetCharacteristic(&self,
characteristic: BluetoothCharacteristicUUID)
-> Rc<Promise> {
- let p = Promise::new(&self.global());
- let p_cx = p.global().get_cx();
-
- // Step 1.
- let uuid = match BluetoothUUID::characteristic(characteristic) {
- Ok(uuid) => uuid.to_string(),
- Err(e) => {
- p.reject_error(p_cx, e);
- return p;
- }
- };
-
- // Step 2.
- if uuid_is_blocklisted(uuid.as_ref(), Blocklist::All) {
- p.reject_error(p_cx, Security);
- return p;
- }
-
- // Step 3 - 4.
- if !self.Device().Gatt().Connected() {
- p.reject_error(p_cx, Network);
- return p;
- }
-
- // TODO: Step 5: Implement representedService internal slot for BluetootRemoteGATTService.
-
- // Note: Steps 6 - 7 are implemented is components/bluetooth/lib.rs in get_characteristic function
- // and in handle_response function.
- let sender = response_async(&p, self);
- self.get_bluetooth_thread().send(
- BluetoothRequest::GetCharacteristic(self.get_instance_id(), uuid, sender)).unwrap();
- return p;
+ get_gatt_children(self, true, BluetoothUUID::characteristic, Some(characteristic), self.get_instance_id(),
+ self.Device().Gatt().Connected(), GATTType::Characteristic)
}
#[allow(unrooted_must_root)]
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getcharacteristics
- // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren
fn GetCharacteristics(&self,
characteristic: Option<BluetoothCharacteristicUUID>)
-> Rc<Promise> {
- let p = Promise::new(&self.global());
- let p_cx = p.global().get_cx();
- let mut uuid: Option<String> = None;
- if let Some(c) = characteristic {
- // Step 1.
- uuid = match BluetoothUUID::characteristic(c) {
- Ok(uuid) => Some(uuid.to_string()),
- Err(e) => {
- p.reject_error(p_cx, e);
- return p;
- }
- };
- if let Some(ref uuid) = uuid {
- // Step 2.
- if uuid_is_blocklisted(uuid.as_ref(), Blocklist::All) {
- p.reject_error(p_cx, Security);
- return p;
- }
- }
- };
-
- // Step 3 - 4.
- if !self.Device().Gatt().Connected() {
- p.reject_error(p_cx, Network);
- return p;
- }
-
- // TODO: Step 5: Implement representedService internal slot for BluetootRemoteGATTService.
-
- // Note: Steps 6 - 7 are implemented is components/bluetooth/lib.rs in get_characteristics function
- // and in handle_response function.
- let sender = response_async(&p, self);
- self.get_bluetooth_thread().send(
- BluetoothRequest::GetCharacteristics(self.get_instance_id(), uuid, sender)).unwrap();
- return p;
+ get_gatt_children(self, false, BluetoothUUID::characteristic, characteristic, self.get_instance_id(),
+ self.Device().Gatt().Connected(), GATTType::Characteristic)
}
#[allow(unrooted_must_root)]
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getincludedservice
- // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren
fn GetIncludedService(&self,
service: BluetoothServiceUUID)
-> Rc<Promise> {
- let p = Promise::new(&self.global());
- let p_cx = p.global().get_cx();
-
- // Step 1.
- let uuid = match BluetoothUUID::service(service) {
- Ok(uuid) => uuid.to_string(),
- Err(e) => {
- p.reject_error(p_cx, e);
- return p;
- }
- };
-
- // Step 2.
- if uuid_is_blocklisted(uuid.as_ref(), Blocklist::All) {
- p.reject_error(p_cx, Security);
- return p;
- }
-
- // Step 3 - 4.
- if !self.Device().Gatt().Connected() {
- p.reject_error(p_cx, Network);
- return p;
- }
-
- // TODO: Step 5: Implement representedService internal slot for BluetootRemoteGATTService.
-
- // Note: Steps 6 - 7 are implemented is components/bluetooth/lib.rs in get_included_service function
- // and in handle_response function.
- let sender = response_async(&p, self);
- self.get_bluetooth_thread().send(
- BluetoothRequest::GetIncludedService(self.get_instance_id(),
- uuid,
- sender)).unwrap();
- return p;
+ get_gatt_children(self, false, BluetoothUUID::service, Some(service), self.get_instance_id(),
+ self.Device().Gatt().Connected(), GATTType::IncludedService)
}
#[allow(unrooted_must_root)]
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getincludedservices
- // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren
fn GetIncludedServices(&self,
service: Option<BluetoothServiceUUID>)
-> Rc<Promise> {
- let p = Promise::new(&self.global());
- let p_cx = p.global().get_cx();
- let mut uuid: Option<String> = None;
- if let Some(s) = service {
- // Step 1.
- uuid = match BluetoothUUID::service(s) {
- Ok(uuid) => Some(uuid.to_string()),
- Err(e) => {
- p.reject_error(p_cx, e);
- return p;
- }
- };
- if let Some(ref uuid) = uuid {
- // Step 2.
- if uuid_is_blocklisted(uuid.as_ref(), Blocklist::All) {
- p.reject_error(p_cx, Security);
- return p;
- }
- }
- };
-
- // Step 3 - 4.
- if !self.Device().Gatt().Connected() {
- p.reject_error(p_cx, Network);
- return p;
- }
-
- // TODO: Step 5: Implement representedService internal slot for BluetootRemoteGATTService.
-
- // Note: Steps 6 - 7 are implemented is components/bluetooth/lib.rs in get_included_services function
- // and in handle_response function.
- let sender = response_async(&p, self);
- self.get_bluetooth_thread().send(
- BluetoothRequest::GetIncludedServices(self.get_instance_id(),
- uuid,
- sender)).unwrap();
- return p;
+ get_gatt_children(self, false, BluetoothUUID::service, service, self.get_instance_id(),
+ self.Device().Gatt().Connected(), GATTType::IncludedService)
}
// https://webbluetoothcg.github.io/web-bluetooth/#dom-serviceeventhandlers-onserviceadded
@@ -272,17 +132,14 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTService {
fn handle_response(&self, response: BluetoothResponse, promise_cx: *mut JSContext, promise: &Rc<Promise>) {
let device = self.Device();
match response {
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getcharacteristic
// https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren
// Step 7.
- BluetoothResponse::GetCharacteristic(characteristic) => {
- let bt_characteristic = device.get_or_create_characteristic(&characteristic, &self);
- promise.resolve_native(promise_cx, &bt_characteristic);
- },
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getcharacteristics
- // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren
- // Step 7.
- BluetoothResponse::GetCharacteristics(characteristics_vec) => {
+ BluetoothResponse::GetCharacteristics(characteristics_vec, single) => {
+ if single {
+ promise.resolve_native(promise_cx,
+ &device.get_or_create_characteristic(&characteristics_vec[0], &self));
+ return;
+ }
let mut characteristics = vec!();
for characteristic in characteristics_vec {
let bt_characteristic = device.get_or_create_characteristic(&characteristic, &self);
@@ -290,31 +147,19 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTService {
}
promise.resolve_native(promise_cx, &characteristics);
},
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getincludedservice
// https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren
// Step 7.
- BluetoothResponse::GetIncludedService(service) => {
- let s =
- BluetoothRemoteGATTService::new(&self.global(),
- &self.device.get(),
- DOMString::from(service.uuid),
- service.is_primary,
- service.instance_id);
- promise.resolve_native(promise_cx, &s);
- },
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getincludedservices
- // https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren
- // Step 7.
- BluetoothResponse::GetIncludedServices(services_vec) => {
- let s: Vec<Root<BluetoothRemoteGATTService>> =
- services_vec.into_iter()
- .map(|service| BluetoothRemoteGATTService::new(&self.global(),
- &self.device.get(),
- DOMString::from(service.uuid),
- service.is_primary,
- service.instance_id))
- .collect();
- promise.resolve_native(promise_cx, &s);
+ BluetoothResponse::GetIncludedServices(services_vec, single) => {
+ if single {
+ promise.resolve_native(promise_cx, &device.get_or_create_service(&services_vec[0], &device.Gatt()));
+ return;
+ }
+ let mut services = vec!();
+ for service in services_vec {
+ let bt_service = device.get_or_create_service(&service, &device.Gatt());
+ services.push(bt_service);
+ }
+ promise.resolve_native(promise_cx, &services);
},
_ => promise.reject_error(promise_cx, Error::Type("Something went wrong...".to_owned())),
}
diff --git a/components/script/dom/browsingcontext.rs b/components/script/dom/browsingcontext.rs
index 76b8badbe76..1a7f26253a0 100644
--- a/components/script/dom/browsingcontext.rs
+++ b/components/script/dom/browsingcontext.rs
@@ -4,7 +4,7 @@
use dom::bindings::conversions::{ToJSValConvertible, root_from_handleobject};
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference};
+use dom::bindings::js::{JS, MutNullableJS, Root, RootedReference};
use dom::bindings::proxyhandler::{fill_property_descriptor, get_property_descriptor};
use dom::bindings::reflector::{DomObject, MutDomObject, Reflector};
use dom::bindings::trace::JSTraceable;
@@ -43,7 +43,7 @@ pub struct BrowsingContext {
/// The current active document.
/// Note that the session history is stored in the constellation,
/// in the script thread we just track the current active document.
- active_document: MutNullableHeap<JS<Document>>,
+ active_document: MutNullableJS<Document>,
/// The containing iframe element, if this is a same-origin iframe
frame_element: Option<JS<Element>>,
diff --git a/components/script/dom/characterdata.rs b/components/script/dom/characterdata.rs
index 01f11e3ac50..a2c456317dc 100644
--- a/components/script/dom/characterdata.rs
+++ b/components/script/dom/characterdata.rs
@@ -19,8 +19,8 @@ use dom::element::Element;
use dom::node::{Node, NodeDamage};
use dom::processinginstruction::ProcessingInstruction;
use dom::text::Text;
+use servo_config::opts;
use std::cell::Ref;
-use util::opts;
// https://dom.spec.whatwg.org/#characterdata
#[dom_struct]
diff --git a/components/script/dom/client.rs b/components/script/dom/client.rs
index 496a13d32dc..d9d43ce7e01 100644
--- a/components/script/dom/client.rs
+++ b/components/script/dom/client.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::Bindings::ClientBinding::{ClientMethods, Wrap};
use dom::bindings::codegen::Bindings::ClientBinding::FrameType;
-use dom::bindings::js::{JS, Root, MutNullableHeap};
+use dom::bindings::js::{Root, MutNullableJS};
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::bindings::str::{DOMString, USVString};
use dom::serviceworker::ServiceWorker;
@@ -16,7 +16,7 @@ use uuid::Uuid;
#[dom_struct]
pub struct Client {
reflector_: Reflector,
- active_worker: MutNullableHeap<JS<ServiceWorker>>,
+ active_worker: MutNullableJS<ServiceWorker>,
url: ServoUrl,
frame_type: FrameType,
#[ignore_heap_size_of = "Defined in uuid"]
diff --git a/components/script/dom/create.rs b/components/script/dom/create.rs
index 42a3c8158a1..7c9a9eeea9c 100644
--- a/components/script/dom/create.rs
+++ b/components/script/dom/create.rs
@@ -78,7 +78,7 @@ use dom::htmlunknownelement::HTMLUnknownElement;
use dom::htmlvideoelement::HTMLVideoElement;
use dom::svgsvgelement::SVGSVGElement;
use html5ever_atoms::{Prefix, QualName};
-use util::prefs::PREFS;
+use servo_config::prefs::PREFS;
fn create_svg_element(name: QualName,
prefix: Option<DOMString>,
@@ -244,7 +244,7 @@ fn create_html_element(name: QualName,
local_name!("span") => make!(HTMLSpanElement),
local_name!("strike") => make!(HTMLElement),
local_name!("strong") => make!(HTMLElement),
- local_name!("style") => make!(HTMLStyleElement),
+ local_name!("style") => make!(HTMLStyleElement, creator),
local_name!("sub") => make!(HTMLElement),
local_name!("summary") => make!(HTMLElement),
local_name!("sup") => make!(HTMLElement),
diff --git a/components/script/dom/crypto.rs b/components/script/dom/crypto.rs
index 4120456c77c..57b561e8a58 100644
--- a/components/script/dom/crypto.rs
+++ b/components/script/dom/crypto.rs
@@ -6,7 +6,6 @@ use core::nonzero::NonZero;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::CryptoBinding;
use dom::bindings::codegen::Bindings::CryptoBinding::CryptoMethods;
-use dom::bindings::conversions::array_buffer_view_data;
use dom::bindings::error::{Error, Fallible};
use dom::bindings::js::Root;
use dom::bindings::reflector::{Reflector, reflect_dom_object};
@@ -46,9 +45,10 @@ impl CryptoMethods for Crypto {
input: *mut JSObject)
-> Fallible<NonZero<*mut JSObject>> {
assert!(!input.is_null());
- let mut data = match array_buffer_view_data::<u8>(input) {
- Some(data) => data,
- None => {
+ typedarray!(in(_cx) let mut array_buffer_view: ArrayBufferView = input);
+ let mut data = match array_buffer_view.as_mut() {
+ Ok(x) => x.as_mut_slice(),
+ Err(_) => {
return Err(Error::Type("Argument to Crypto.getRandomValues is not an ArrayBufferView"
.to_owned()));
}
diff --git a/components/script/dom/cssgroupingrule.rs b/components/script/dom/cssgroupingrule.rs
index e8651c551d3..b793b04b28c 100644
--- a/components/script/dom/cssgroupingrule.rs
+++ b/components/script/dom/cssgroupingrule.rs
@@ -2,17 +2,15 @@
* 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::CSSGroupingRuleBinding;
use dom::bindings::codegen::Bindings::CSSGroupingRuleBinding::CSSGroupingRuleMethods;
use dom::bindings::error::{ErrorResult, Fallible};
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, MutNullableHeap, Root};
-use dom::bindings::reflector::{DomObject, reflect_dom_object};
+use dom::bindings::js::{MutNullableJS, Root};
+use dom::bindings::reflector::DomObject;
use dom::bindings::str::DOMString;
use dom::cssrule::CSSRule;
use dom::cssrulelist::{CSSRuleList, RulesSource};
use dom::cssstylesheet::CSSStyleSheet;
-use dom::window::Window;
use parking_lot::RwLock;
use std::sync::Arc;
use style::stylesheets::CssRules as StyleCssRules;
@@ -22,7 +20,7 @@ pub struct CSSGroupingRule {
cssrule: CSSRule,
#[ignore_heap_size_of = "Arc"]
rules: Arc<RwLock<StyleCssRules>>,
- rulelist: MutNullableHeap<JS<CSSRuleList>>,
+ rulelist: MutNullableJS<CSSRuleList>,
}
impl CSSGroupingRule {
@@ -31,18 +29,10 @@ impl CSSGroupingRule {
CSSGroupingRule {
cssrule: CSSRule::new_inherited(parent_stylesheet),
rules: rules,
- rulelist: MutNullableHeap::new(None),
+ rulelist: MutNullableJS::new(None),
}
}
- #[allow(unrooted_must_root)]
- pub fn new(window: &Window, parent_stylesheet: &CSSStyleSheet,
- rules: Arc<RwLock<StyleCssRules>>) -> Root<CSSGroupingRule> {
- reflect_dom_object(box CSSGroupingRule::new_inherited(parent_stylesheet, rules),
- window,
- CSSGroupingRuleBinding::Wrap)
- }
-
fn rulelist(&self) -> Root<CSSRuleList> {
let parent_stylesheet = self.upcast::<CSSRule>().parent_stylesheet();
self.rulelist.or_init(|| CSSRuleList::new(self.global().as_window(),
diff --git a/components/script/dom/cssimportrule.rs b/components/script/dom/cssimportrule.rs
new file mode 100644
index 00000000000..582a6f597f9
--- /dev/null
+++ b/components/script/dom/cssimportrule.rs
@@ -0,0 +1,53 @@
+/* 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::CSSImportRuleBinding;
+use dom::bindings::js::Root;
+use dom::bindings::reflector::reflect_dom_object;
+use dom::bindings::str::DOMString;
+use dom::cssrule::{CSSRule, SpecificCSSRule};
+use dom::cssstylesheet::CSSStyleSheet;
+use dom::window::Window;
+use parking_lot::RwLock;
+use std::sync::Arc;
+use style::stylesheets::ImportRule;
+use style_traits::ToCss;
+
+#[dom_struct]
+pub struct CSSImportRule {
+ cssrule: CSSRule,
+ #[ignore_heap_size_of = "Arc"]
+ import_rule: Arc<RwLock<ImportRule>>,
+}
+
+impl CSSImportRule {
+ fn new_inherited(parent_stylesheet: &CSSStyleSheet,
+ import_rule: Arc<RwLock<ImportRule>>)
+ -> Self {
+ CSSImportRule {
+ cssrule: CSSRule::new_inherited(parent_stylesheet),
+ import_rule: import_rule,
+ }
+ }
+
+ #[allow(unrooted_must_root)]
+ pub fn new(window: &Window,
+ parent_stylesheet: &CSSStyleSheet,
+ import_rule: Arc<RwLock<ImportRule>>) -> Root<Self> {
+ reflect_dom_object(box Self::new_inherited(parent_stylesheet, import_rule),
+ window,
+ CSSImportRuleBinding::Wrap)
+ }
+}
+
+impl SpecificCSSRule for CSSImportRule {
+ fn ty(&self) -> u16 {
+ use dom::bindings::codegen::Bindings::CSSRuleBinding::CSSRuleConstants;
+ CSSRuleConstants::IMPORT_RULE
+ }
+
+ fn get_css(&self) -> DOMString {
+ self.import_rule.read().to_css_string().into()
+ }
+}
diff --git a/components/script/dom/csskeyframesrule.rs b/components/script/dom/csskeyframesrule.rs
index 46ed79435c1..1c94e0e99fb 100644
--- a/components/script/dom/csskeyframesrule.rs
+++ b/components/script/dom/csskeyframesrule.rs
@@ -5,8 +5,9 @@
use cssparser::Parser;
use dom::bindings::codegen::Bindings::CSSKeyframesRuleBinding;
use dom::bindings::codegen::Bindings::CSSKeyframesRuleBinding::CSSKeyframesRuleMethods;
+use dom::bindings::error::{Error, ErrorResult};
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, MutNullableHeap, Root};
+use dom::bindings::js::{MutNullableJS, Root};
use dom::bindings::reflector::{DomObject, reflect_dom_object};
use dom::bindings::str::DOMString;
use dom::csskeyframerule::CSSKeyframeRule;
@@ -15,6 +16,7 @@ use dom::cssrulelist::{CSSRuleList, RulesSource};
use dom::cssstylesheet::CSSStyleSheet;
use dom::window::Window;
use parking_lot::RwLock;
+use servo_atoms::Atom;
use std::sync::Arc;
use style::keyframes::{Keyframe, KeyframeSelector};
use style::parser::ParserContextExtraData;
@@ -26,7 +28,7 @@ pub struct CSSKeyframesRule {
cssrule: CSSRule,
#[ignore_heap_size_of = "Arc"]
keyframesrule: Arc<RwLock<KeyframesRule>>,
- rulelist: MutNullableHeap<JS<CSSRuleList>>,
+ rulelist: MutNullableJS<CSSRuleList>,
}
impl CSSKeyframesRule {
@@ -35,7 +37,7 @@ impl CSSKeyframesRule {
CSSKeyframesRule {
cssrule: CSSRule::new_inherited(parent_stylesheet),
keyframesrule: keyframesrule,
- rulelist: MutNullableHeap::new(None),
+ rulelist: MutNullableJS::new(None),
}
}
@@ -101,6 +103,27 @@ impl CSSKeyframesRuleMethods for CSSKeyframesRule {
self.rulelist().item(idx as u32)
}).and_then(Root::downcast)
}
+
+ // https://drafts.csswg.org/css-animations/#dom-csskeyframesrule-name
+ fn Name(&self) -> DOMString {
+ DOMString::from(&*self.keyframesrule.read().name)
+ }
+
+ // https://drafts.csswg.org/css-animations/#dom-csskeyframesrule-name
+ fn SetName(&self, value: DOMString) -> ErrorResult {
+ // https://github.com/w3c/csswg-drafts/issues/801
+ // Setting this property to a CSS-wide keyword or `none` will
+ // throw a Syntax Error.
+ match_ignore_ascii_case! { value,
+ "initial" => return Err(Error::Syntax),
+ "inherit" => return Err(Error::Syntax),
+ "unset" => return Err(Error::Syntax),
+ "none" => return Err(Error::Syntax),
+ _ => ()
+ }
+ self.keyframesrule.write().name = Atom::from(value);
+ Ok(())
+ }
}
impl SpecificCSSRule for CSSKeyframesRule {
diff --git a/components/script/dom/cssmediarule.rs b/components/script/dom/cssmediarule.rs
index 0e1fc145e7d..b6b04dde9d8 100644
--- a/components/script/dom/cssmediarule.rs
+++ b/components/script/dom/cssmediarule.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::Bindings::CSSMediaRuleBinding;
use dom::bindings::codegen::Bindings::CSSMediaRuleBinding::CSSMediaRuleMethods;
-use dom::bindings::js::{JS, MutNullableHeap, Root};
+use dom::bindings::js::{MutNullableJS, Root};
use dom::bindings::reflector::{DomObject, reflect_dom_object};
use dom::bindings::str::DOMString;
use dom::cssgroupingrule::CSSGroupingRule;
@@ -22,7 +22,7 @@ pub struct CSSMediaRule {
cssrule: CSSGroupingRule,
#[ignore_heap_size_of = "Arc"]
mediarule: Arc<RwLock<MediaRule>>,
- medialist: MutNullableHeap<JS<MediaList>>,
+ medialist: MutNullableJS<MediaList>,
}
impl CSSMediaRule {
@@ -32,7 +32,7 @@ impl CSSMediaRule {
CSSMediaRule {
cssrule: CSSGroupingRule::new_inherited(parent_stylesheet, list),
mediarule: mediarule,
- medialist: MutNullableHeap::new(None),
+ medialist: MutNullableJS::new(None),
}
}
diff --git a/components/script/dom/cssrule.rs b/components/script/dom/cssrule.rs
index 603354c8621..8323d7e22b0 100644
--- a/components/script/dom/cssrule.rs
+++ b/components/script/dom/cssrule.rs
@@ -2,13 +2,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/. */
-use dom::bindings::codegen::Bindings::CSSRuleBinding;
use dom::bindings::codegen::Bindings::CSSRuleBinding::CSSRuleMethods;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, Root};
-use dom::bindings::reflector::{Reflector, reflect_dom_object};
+use dom::bindings::reflector::Reflector;
use dom::bindings::str::DOMString;
use dom::cssfontfacerule::CSSFontFaceRule;
+use dom::cssimportrule::CSSImportRule;
use dom::csskeyframerule::CSSKeyframeRule;
use dom::csskeyframesrule::CSSKeyframesRule;
use dom::cssmediarule::CSSMediaRule;
@@ -42,13 +42,6 @@ impl CSSRule {
}
}
- #[allow(unrooted_must_root)]
- pub fn new(window: &Window, parent_stylesheet: &CSSStyleSheet) -> Root<CSSRule> {
- reflect_dom_object(box CSSRule::new_inherited(parent_stylesheet),
- window,
- CSSRuleBinding::Wrap)
- }
-
pub fn as_specific(&self) -> &SpecificCSSRule {
if let Some(rule) = self.downcast::<CSSStyleRule>() {
rule as &SpecificCSSRule
@@ -64,6 +57,8 @@ impl CSSRule {
rule as &SpecificCSSRule
} else if let Some(rule) = self.downcast::<CSSKeyframeRule>() {
rule as &SpecificCSSRule
+ } else if let Some(rule) = self.downcast::<CSSImportRule>() {
+ rule as &SpecificCSSRule
} else {
unreachable!()
}
@@ -75,6 +70,7 @@ impl CSSRule {
rule: StyleCssRule) -> Root<CSSRule> {
// be sure to update the match in as_specific when this is updated
match rule {
+ StyleCssRule::Import(s) => Root::upcast(CSSImportRule::new(window, parent_stylesheet, s)),
StyleCssRule::Style(s) => Root::upcast(CSSStyleRule::new(window, parent_stylesheet, s)),
StyleCssRule::FontFace(s) => Root::upcast(CSSFontFaceRule::new(window, parent_stylesheet, s)),
StyleCssRule::Keyframes(s) => Root::upcast(CSSKeyframesRule::new(window, parent_stylesheet, s)),
diff --git a/components/script/dom/cssrulelist.rs b/components/script/dom/cssrulelist.rs
index 988f839a87a..f667638b022 100644
--- a/components/script/dom/cssrulelist.rs
+++ b/components/script/dom/cssrulelist.rs
@@ -6,7 +6,7 @@ use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::CSSRuleListBinding;
use dom::bindings::codegen::Bindings::CSSRuleListBinding::CSSRuleListMethods;
use dom::bindings::error::{Error, ErrorResult, Fallible};
-use dom::bindings::js::{JS, MutNullableHeap, Root};
+use dom::bindings::js::{JS, MutNullableJS, Root};
use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object};
use dom::csskeyframerule::CSSKeyframeRule;
use dom::cssrule::CSSRule;
@@ -38,7 +38,7 @@ pub struct CSSRuleList {
parent_stylesheet: JS<CSSStyleSheet>,
#[ignore_heap_size_of = "Arc"]
rules: RulesSource,
- dom_rules: DOMRefCell<Vec<MutNullableHeap<JS<CSSRule>>>>
+ dom_rules: DOMRefCell<Vec<MutNullableJS<CSSRule>>>
}
pub enum RulesSource {
@@ -51,10 +51,10 @@ impl CSSRuleList {
pub fn new_inherited(parent_stylesheet: &CSSStyleSheet, rules: RulesSource) -> CSSRuleList {
let dom_rules = match rules {
RulesSource::Rules(ref rules) => {
- rules.read().0.iter().map(|_| MutNullableHeap::new(None)).collect()
+ rules.read().0.iter().map(|_| MutNullableJS::new(None)).collect()
}
RulesSource::Keyframes(ref rules) => {
- rules.read().keyframes.iter().map(|_| MutNullableHeap::new(None)).collect()
+ rules.read().keyframes.iter().map(|_| MutNullableJS::new(None)).collect()
}
};
@@ -92,7 +92,7 @@ impl CSSRuleList {
let parent_stylesheet = &*self.parent_stylesheet;
let dom_rule = CSSRule::new_specific(&window, parent_stylesheet, new_rule);
- self.dom_rules.borrow_mut().insert(index, MutNullableHeap::new(Some(&*dom_rule)));
+ self.dom_rules.borrow_mut().insert(index, MutNullableJS::new(Some(&*dom_rule)));
Ok((idx))
}
@@ -158,7 +158,7 @@ impl CSSRuleList {
if let RulesSource::Rules(..) = self.rules {
panic!("Can only call append_lazy_rule with keyframes-backed CSSRules");
}
- self.dom_rules.borrow_mut().push(MutNullableHeap::new(None));
+ self.dom_rules.borrow_mut().push(MutNullableJS::new(None));
}
}
diff --git a/components/script/dom/cssstyledeclaration.rs b/components/script/dom/cssstyledeclaration.rs
index c6280597b17..7cd63aa12b0 100644
--- a/components/script/dom/cssstyledeclaration.rs
+++ b/components/script/dom/cssstyledeclaration.rs
@@ -3,6 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::Bindings::CSSStyleDeclarationBinding::{self, CSSStyleDeclarationMethods};
+use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::error::{Error, ErrorResult, Fallible};
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, Root};
@@ -12,12 +13,11 @@ use dom::element::Element;
use dom::node::{Node, NodeDamage, window_from_node};
use dom::window::Window;
use parking_lot::RwLock;
-use servo_atoms::Atom;
use std::ascii::AsciiExt;
use std::sync::Arc;
use style::parser::ParserContextExtraData;
-use style::properties::{Shorthand, Importance, PropertyDeclarationBlock};
-use style::properties::{is_supported_property, parse_one_declaration, parse_style_attribute};
+use style::properties::{Importance, PropertyDeclarationBlock, PropertyId, LonghandId, ShorthandId};
+use style::properties::{parse_one_declaration, parse_style_attribute};
use style::selector_parser::PseudoElement;
use style_traits::ToCss;
@@ -25,11 +25,59 @@ use style_traits::ToCss;
#[dom_struct]
pub struct CSSStyleDeclaration {
reflector_: Reflector,
- owner: JS<Element>,
+ owner: CSSStyleOwner,
readonly: bool,
pseudo: Option<PseudoElement>,
}
+#[derive(HeapSizeOf, JSTraceable)]
+#[must_root]
+pub enum CSSStyleOwner {
+ Element(JS<Element>),
+ CSSStyleRule(JS<Window>,
+ #[ignore_heap_size_of = "Arc"]
+ Arc<RwLock<PropertyDeclarationBlock>>),
+}
+
+impl CSSStyleOwner {
+ fn style_attribute(&self) -> Option<Arc<RwLock<PropertyDeclarationBlock>>> {
+ match *self {
+ CSSStyleOwner::Element(ref el) => {
+ if let Some(ref pdb) = *el.style_attribute().borrow() {
+ Some(pdb.clone())
+ } else {
+ None
+ }
+ }
+ CSSStyleOwner::CSSStyleRule(_, ref pdb) => {
+ Some(pdb.clone())
+ }
+ }
+ }
+
+ fn window(&self) -> Root<Window> {
+ match *self {
+ CSSStyleOwner::Element(ref el) => window_from_node(&**el),
+ CSSStyleOwner::CSSStyleRule(ref window, _) => Root::from_ref(&**window),
+ }
+ }
+
+ fn flush_style(&self, pdb: &PropertyDeclarationBlock) {
+ if let CSSStyleOwner::Element(ref el) = *self {
+ el.set_style_attr(pdb.to_css_string());
+ }
+ }
+
+ fn dirty(&self) {
+ match *self {
+ CSSStyleOwner::Element(ref el) =>
+ el.upcast::<Node>().dirty(NodeDamage::NodeStyleDamaged),
+ CSSStyleOwner::CSSStyleRule(ref window, _) =>
+ window.Document().invalidate_stylesheets(),
+ }
+ }
+}
+
#[derive(PartialEq, HeapSizeOf)]
pub enum CSSModificationAccess {
ReadWrite,
@@ -37,33 +85,35 @@ pub enum CSSModificationAccess {
}
macro_rules! css_properties(
- ( $([$getter:ident, $setter:ident, $cssprop:expr]),* ) => (
+ ( $([$getter:ident, $setter:ident, $id:expr],)* ) => (
$(
fn $getter(&self) -> DOMString {
- self.GetPropertyValue(DOMString::from($cssprop))
+ self.get_property_value($id)
}
fn $setter(&self, value: DOMString) -> ErrorResult {
- self.SetPropertyValue(DOMString::from($cssprop), value)
+ self.set_property($id, value, DOMString::new())
}
)*
);
);
impl CSSStyleDeclaration {
- pub fn new_inherited(owner: &Element,
+ #[allow(unrooted_must_root)]
+ pub fn new_inherited(owner: CSSStyleOwner,
pseudo: Option<PseudoElement>,
modification_access: CSSModificationAccess)
-> CSSStyleDeclaration {
CSSStyleDeclaration {
reflector_: Reflector::new(),
- owner: JS::from_ref(owner),
+ owner: owner,
readonly: modification_access == CSSModificationAccess::Readonly,
pseudo: pseudo,
}
}
+ #[allow(unrooted_must_root)]
pub fn new(global: &Window,
- owner: &Element,
+ owner: CSSStyleOwner,
pseudo: Option<PseudoElement>,
modification_access: CSSModificationAccess)
-> Root<CSSStyleDeclaration> {
@@ -74,108 +124,59 @@ impl CSSStyleDeclaration {
CSSStyleDeclarationBinding::Wrap)
}
- fn get_computed_style(&self, property: &Atom) -> Option<DOMString> {
- let node = self.owner.upcast::<Node>();
- if !node.is_in_doc() {
- // TODO: Node should be matched against the style rules of this window.
- // Firefox is currently the only browser to implement this.
- return None;
+ fn get_computed_style(&self, property: PropertyId) -> DOMString {
+ match self.owner {
+ CSSStyleOwner::CSSStyleRule(..) =>
+ panic!("get_computed_style called on CSSStyleDeclaration with a CSSStyleRule owner"),
+ CSSStyleOwner::Element(ref el) => {
+ let node = el.upcast::<Node>();
+ if !node.is_in_doc() {
+ // TODO: Node should be matched against the style rules of this window.
+ // Firefox is currently the only browser to implement this.
+ return DOMString::new();
+ }
+ let addr = node.to_trusted_node_address();
+ window_from_node(node).resolved_style_query(addr, self.pseudo.clone(), property)
+ }
}
- let addr = node.to_trusted_node_address();
- window_from_node(&*self.owner).resolved_style_query(addr, self.pseudo.clone(), property)
- }
-}
-
-impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
- // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-length
- fn Length(&self) -> u32 {
- let elem = self.owner.upcast::<Element>();
- let len = match *elem.style_attribute().borrow() {
- Some(ref lock) => lock.read().declarations.len(),
- None => 0,
- };
- len as u32
- }
-
- // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-item
- fn Item(&self, index: u32) -> DOMString {
- self.IndexedGetter(index).unwrap_or_default()
}
- // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertyvalue
- fn GetPropertyValue(&self, mut property: DOMString) -> DOMString {
+ fn get_property_value(&self, id: PropertyId) -> DOMString {
if self.readonly {
// Readonly style declarations are used for getComputedStyle.
- property.make_ascii_lowercase();
- let property = Atom::from(property);
- return self.get_computed_style(&property).unwrap_or(DOMString::new());
+ return self.get_computed_style(id);
}
- let style_attribute = self.owner.style_attribute().borrow();
- let style_attribute = if let Some(ref lock) = *style_attribute {
- lock.read()
+ if let Some(ref lock) = self.owner.style_attribute() {
+ let mut string = String::new();
+ lock.read().property_value_to_css(&id, &mut string).unwrap();
+ DOMString::from(string)
} else {
// No style attribute is like an empty style attribute: no matching declaration.
- return DOMString::new()
- };
-
- let mut string = String::new();
- style_attribute.property_value_to_css(&property, &mut string).unwrap();
- DOMString::from(string)
- }
-
- // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertypriority
- fn GetPropertyPriority(&self, property: DOMString) -> DOMString {
- let style_attribute = self.owner.style_attribute().borrow();
- let style_attribute = if let Some(ref lock) = *style_attribute {
- lock.read()
- } else {
- // No style attribute is like an empty style attribute: no matching declaration.
- return DOMString::new()
- };
-
- if style_attribute.property_priority(&property).important() {
- DOMString::from("important")
- } else {
- // Step 4
DOMString::new()
}
}
- // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-setproperty
- fn SetProperty(&self,
- property: DOMString,
- value: DOMString,
- priority: DOMString)
- -> ErrorResult {
+ fn set_property(&self, id: PropertyId, value: DOMString, priority: DOMString) -> ErrorResult {
// Step 1
if self.readonly {
return Err(Error::NoModificationAllowed);
}
- // Step 3
- if !is_supported_property(&property) {
- return Ok(());
- }
-
- let mut style_attribute = self.owner.style_attribute().borrow_mut();
-
if value.is_empty() {
// Step 4
- let empty;
- {
- let mut style_attribute = if let Some(ref lock) = *style_attribute {
- lock.write()
+ let empty = {
+ if let Some(ref lock) = self.owner.style_attribute() {
+ let mut style_attribute = lock.write();
+ style_attribute.remove_property(&id);
+ style_attribute.declarations.is_empty()
} else {
// No style attribute is like an empty style attribute: nothing to remove.
return Ok(())
- };
-
- style_attribute.remove_property(&property);
- empty = style_attribute.declarations.is_empty()
- }
- if empty {
- *style_attribute = None;
+ }
+ };
+ if let (&CSSStyleOwner::Element(ref el), true) = (&self.owner, empty) {
+ *el.style_attribute().borrow_mut() = None;
}
} else {
// Step 5
@@ -186,29 +187,28 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
};
// Step 6
- let window = window_from_node(&*self.owner);
+ let window = self.owner.window();
let declarations =
- parse_one_declaration(&property, &value, &window.get_url(), window.css_error_reporter(),
+ parse_one_declaration(id, &value, &window.get_url(), window.css_error_reporter(),
ParserContextExtraData::default());
// Step 7
- let declarations = if let Ok(declarations) = declarations {
- declarations
- } else {
- return Ok(());
+ let declarations = match declarations {
+ Ok(declarations) => declarations,
+ Err(_) => return Ok(())
};
// Step 8
// Step 9
- match *style_attribute {
+ match self.owner.style_attribute() {
Some(ref lock) => {
let mut style_attribute = lock.write();
for declaration in declarations {
style_attribute.set_parsed_declaration(declaration, importance);
}
- self.owner.set_style_attr(style_attribute.to_css_string());
+ self.owner.flush_style(&style_attribute);
}
- ref mut option @ None => {
+ None => {
let important_count = if importance.important() {
declarations.len() as u32
} else {
@@ -218,16 +218,80 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
declarations: declarations.into_iter().map(|d| (d, importance)).collect(),
important_count: important_count,
};
- self.owner.set_style_attr(block.to_css_string());
- *option = Some(Arc::new(RwLock::new(block)));
+ if let CSSStyleOwner::Element(ref el) = self.owner {
+ el.set_style_attr(block.to_css_string());
+ *el.style_attribute().borrow_mut() = Some(Arc::new(RwLock::new(block)));
+ } else {
+ panic!("set_property called on a CSSStyleDeclaration with a non-Element owner");
+ }
}
}
}
- let node = self.owner.upcast::<Node>();
- node.dirty(NodeDamage::NodeStyleDamaged);
+ self.owner.dirty();
Ok(())
}
+}
+
+impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
+ // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-length
+ fn Length(&self) -> u32 {
+ self.owner.style_attribute().as_ref().map_or(0, |lock| lock.read().declarations.len() as u32)
+ }
+
+ // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-item
+ fn Item(&self, index: u32) -> DOMString {
+ self.IndexedGetter(index).unwrap_or_default()
+ }
+
+ // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertyvalue
+ fn GetPropertyValue(&self, property: DOMString) -> DOMString {
+ let id = if let Ok(id) = PropertyId::parse(property.into()) {
+ id
+ } else {
+ // Unkwown property
+ return DOMString::new()
+ };
+ self.get_property_value(id)
+ }
+
+ // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertypriority
+ fn GetPropertyPriority(&self, property: DOMString) -> DOMString {
+ let id = if let Ok(id) = PropertyId::parse(property.into()) {
+ id
+ } else {
+ // Unkwown property
+ return DOMString::new()
+ };
+
+ if let Some(ref lock) = self.owner.style_attribute() {
+ if lock.read().property_priority(&id).important() {
+ DOMString::from("important")
+ } else {
+ // Step 4
+ DOMString::new()
+ }
+ } else {
+ // No style attribute is like an empty style attribute: no matching declaration.
+ DOMString::new()
+ }
+ }
+
+ // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-setproperty
+ fn SetProperty(&self,
+ property: DOMString,
+ value: DOMString,
+ priority: DOMString)
+ -> ErrorResult {
+ // Step 3
+ let id = if let Ok(id) = PropertyId::parse(property.into()) {
+ id
+ } else {
+ // Unknown property
+ return Ok(())
+ };
+ self.set_property(id, value, priority)
+ }
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-setpropertypriority
fn SetPropertyPriority(&self, property: DOMString, priority: DOMString) -> ErrorResult {
@@ -237,9 +301,12 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
}
// Step 2 & 3
- if !is_supported_property(&property) {
- return Ok(());
- }
+ let id = if let Ok(id) = PropertyId::parse(property.into()) {
+ id
+ } else {
+ // Unkwown property
+ return Ok(())
+ };
// Step 4
let importance = match &*priority {
@@ -248,19 +315,14 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
_ => return Ok(()),
};
- let style_attribute = self.owner.style_attribute().borrow();
- if let Some(ref lock) = *style_attribute {
+ if let Some(ref lock) = self.owner.style_attribute() {
let mut style_attribute = lock.write();
// Step 5 & 6
- match Shorthand::from_name(&property) {
- Some(shorthand) => style_attribute.set_importance(shorthand.longhands(), importance),
- None => style_attribute.set_importance(&[&*property], importance),
- }
+ style_attribute.set_importance(&id, importance);
- self.owner.set_style_attr(style_attribute.to_css_string());
- let node = self.owner.upcast::<Node>();
- node.dirty(NodeDamage::NodeStyleDamaged);
+ self.owner.flush_style(&style_attribute);
+ self.owner.dirty();
}
Ok(())
}
@@ -277,31 +339,33 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
return Err(Error::NoModificationAllowed);
}
- let mut style_attribute = self.owner.style_attribute().borrow_mut();
+ let id = if let Ok(id) = PropertyId::parse(property.into()) {
+ id
+ } else {
+ // Unkwown property, cannot be there to remove.
+ return Ok(DOMString::new())
+ };
+
let mut string = String::new();
- let empty;
- {
- let mut style_attribute = if let Some(ref lock) = *style_attribute {
- lock.write()
+ let empty = {
+ if let Some(ref lock) = self.owner.style_attribute() {
+ let mut style_attribute = lock.write();
+ // Step 3
+ style_attribute.property_value_to_css(&id, &mut string).unwrap();
+
+ // Step 4 & 5
+ style_attribute.remove_property(&id);
+ self.owner.flush_style(&style_attribute);
+ style_attribute.declarations.is_empty()
} else {
// No style attribute is like an empty style attribute: nothing to remove.
return Ok(DOMString::new())
- };
-
- // Step 3
- style_attribute.property_value_to_css(&property, &mut string).unwrap();
-
- // Step 4 & 5
- style_attribute.remove_property(&property);
- self.owner.set_style_attr(style_attribute.to_css_string());
- empty = style_attribute.declarations.is_empty()
- }
- if empty {
- *style_attribute = None;
+ }
+ };
+ if let (&CSSStyleOwner::Element(ref el), true) = (&self.owner, empty) {
+ *el.style_attribute().borrow_mut() = None;
}
-
- let node = self.owner.upcast::<Node>();
- node.dirty(NodeDamage::NodeStyleDamaged);
+ self.owner.dirty();
// Step 6
Ok(DOMString::from(string))
@@ -319,11 +383,8 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
// https://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface
fn IndexedGetter(&self, index: u32) -> Option<DOMString> {
- let index = index as usize;
- let elem = self.owner.upcast::<Element>();
- let style_attribute = elem.style_attribute().borrow();
- style_attribute.as_ref().and_then(|lock| {
- lock.read().declarations.get(index).map(|entry| {
+ self.owner.style_attribute().as_ref().and_then(|lock| {
+ lock.read().declarations.get(index as usize).map(|entry| {
let (ref declaration, importance) = *entry;
let mut css = declaration.to_css_string();
if importance.important() {
@@ -336,19 +397,13 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-csstext
fn CssText(&self) -> DOMString {
- let elem = self.owner.upcast::<Element>();
- let style_attribute = elem.style_attribute().borrow();
-
- if let Some(lock) = style_attribute.as_ref() {
- DOMString::from(lock.read().to_css_string())
- } else {
- DOMString::new()
- }
+ self.owner.style_attribute().as_ref().map_or(DOMString::new(), |lock|
+ DOMString::from(lock.read().to_css_string()))
}
// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-csstext
fn SetCssText(&self, value: DOMString) -> ErrorResult {
- let window = window_from_node(self.owner.upcast::<Node>());
+ let window = self.owner.window();
// Step 1
if self.readonly {
@@ -358,15 +413,16 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
// Step 3
let decl_block = parse_style_attribute(&value, &window.get_url(), window.css_error_reporter(),
ParserContextExtraData::default());
- *self.owner.style_attribute().borrow_mut() = if decl_block.declarations.is_empty() {
- self.owner.set_style_attr(String::new());
- None // Step 2
- } else {
- self.owner.set_style_attr(decl_block.to_css_string());
- Some(Arc::new(RwLock::new(decl_block)))
- };
- let node = self.owner.upcast::<Node>();
- node.dirty(NodeDamage::NodeStyleDamaged);
+ if let CSSStyleOwner::Element(ref el) = self.owner {
+ *el.style_attribute().borrow_mut() = if decl_block.declarations.is_empty() {
+ el.set_style_attr(String::new());
+ None // Step 2
+ } else {
+ el.set_style_attr(decl_block.to_css_string());
+ Some(Arc::new(RwLock::new(decl_block)))
+ };
+ }
+ self.owner.dirty();
Ok(())
}
diff --git a/components/script/dom/cssstylerule.rs b/components/script/dom/cssstylerule.rs
index 091704f42d5..3e23864ae61 100644
--- a/components/script/dom/cssstylerule.rs
+++ b/components/script/dom/cssstylerule.rs
@@ -2,11 +2,12 @@
* 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::CSSStyleRuleBinding;
-use dom::bindings::js::Root;
-use dom::bindings::reflector::reflect_dom_object;
+use dom::bindings::codegen::Bindings::CSSStyleRuleBinding::{self, CSSStyleRuleMethods};
+use dom::bindings::js::{JS, MutNullableJS, Root};
+use dom::bindings::reflector::{DomObject, reflect_dom_object};
use dom::bindings::str::DOMString;
use dom::cssrule::{CSSRule, SpecificCSSRule};
+use dom::cssstyledeclaration::{CSSModificationAccess, CSSStyleDeclaration, CSSStyleOwner};
use dom::cssstylesheet::CSSStyleSheet;
use dom::window::Window;
use parking_lot::RwLock;
@@ -19,6 +20,7 @@ pub struct CSSStyleRule {
cssrule: CSSRule,
#[ignore_heap_size_of = "Arc"]
stylerule: Arc<RwLock<StyleRule>>,
+ style_decl: MutNullableJS<CSSStyleDeclaration>,
}
impl CSSStyleRule {
@@ -27,6 +29,7 @@ impl CSSStyleRule {
CSSStyleRule {
cssrule: CSSRule::new_inherited(parent_stylesheet),
stylerule: stylerule,
+ style_decl: Default::default(),
}
}
@@ -49,3 +52,16 @@ impl SpecificCSSRule for CSSStyleRule {
self.stylerule.read().to_css_string().into()
}
}
+
+impl CSSStyleRuleMethods for CSSStyleRule {
+ // https://drafts.csswg.org/cssom/#dom-cssstylerule-style
+ fn Style(&self) -> Root<CSSStyleDeclaration> {
+ self.style_decl.or_init(|| {
+ CSSStyleDeclaration::new(self.global().as_window(),
+ CSSStyleOwner::CSSStyleRule(JS::from_ref(self.global().as_window()),
+ self.stylerule.read().block.clone()),
+ None,
+ CSSModificationAccess::ReadWrite)
+ })
+ }
+}
diff --git a/components/script/dom/cssstylesheet.rs b/components/script/dom/cssstylesheet.rs
index 106b9b5805d..908cfad2cd5 100644
--- a/components/script/dom/cssstylesheet.rs
+++ b/components/script/dom/cssstylesheet.rs
@@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::CSSStyleSheetBinding;
use dom::bindings::codegen::Bindings::CSSStyleSheetBinding::CSSStyleSheetMethods;
use dom::bindings::codegen::Bindings::WindowBinding::WindowBinding::WindowMethods;
use dom::bindings::error::{ErrorResult, Fallible};
-use dom::bindings::js::{JS, Root, MutNullableHeap};
+use dom::bindings::js::{JS, MutNullableJS, Root};
use dom::bindings::reflector::{reflect_dom_object, DomObject};
use dom::bindings::str::DOMString;
use dom::cssrulelist::{CSSRuleList, RulesSource};
@@ -20,7 +20,7 @@ use style::stylesheets::Stylesheet as StyleStyleSheet;
pub struct CSSStyleSheet {
stylesheet: StyleSheet,
owner: JS<Element>,
- rulelist: MutNullableHeap<JS<CSSRuleList>>,
+ rulelist: MutNullableJS<CSSRuleList>,
#[ignore_heap_size_of = "Arc"]
style_stylesheet: Arc<StyleStyleSheet>,
}
@@ -34,7 +34,7 @@ impl CSSStyleSheet {
CSSStyleSheet {
stylesheet: StyleSheet::new_inherited(type_, href, title),
owner: JS::from_ref(owner),
- rulelist: MutNullableHeap::new(None),
+ rulelist: MutNullableJS::new(None),
style_stylesheet: stylesheet,
}
}
diff --git a/components/script/dom/dedicatedworkerglobalscope.rs b/components/script/dom/dedicatedworkerglobalscope.rs
index 96ee1f871eb..911847aadb8 100644
--- a/components/script/dom/dedicatedworkerglobalscope.rs
+++ b/components/script/dom/dedicatedworkerglobalscope.rs
@@ -38,8 +38,8 @@ use std::mem::replace;
use std::sync::{Arc, Mutex};
use std::sync::atomic::AtomicBool;
use std::sync::mpsc::{Receiver, RecvError, Select, Sender, channel};
+use std::thread;
use style::thread_state;
-use util::thread::spawn_named;
/// Set the `worker` field of a related DedicatedWorkerGlobalScope object to a particular
/// value for the duration of this object's lifetime. This ensures that the related Worker
@@ -160,7 +160,7 @@ impl DedicatedWorkerGlobalScope {
let name = format!("WebWorker for {}", serialized_worker_url);
let top_level_frame_id = FrameId::installed();
- spawn_named(name, move || {
+ thread::Builder::new().name(name).spawn(move || {
thread_state::initialize(thread_state::SCRIPT | thread_state::IN_WORKER);
if let Some(top_level_frame_id) = top_level_frame_id {
@@ -243,7 +243,7 @@ impl DedicatedWorkerGlobalScope {
global.handle_event(event);
}
}, reporter_name, parent_sender, CommonScriptMsg::CollectReports);
- });
+ }).expect("Thread spawning failed");
}
pub fn script_chan(&self) -> Box<ScriptChan + Send> {
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index 9704b4ba0ab..6f8f2435311 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -24,7 +24,7 @@ use dom::bindings::codegen::Bindings::WindowBinding::{FrameRequestCallback, Scro
use dom::bindings::codegen::UnionTypes::NodeOrString;
use dom::bindings::error::{Error, ErrorResult, Fallible};
use dom::bindings::inheritance::{Castable, ElementTypeId, HTMLElementTypeId, NodeTypeId};
-use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root};
+use dom::bindings::js::{JS, LayoutJS, MutNullableJS, Root};
use dom::bindings::js::RootedReference;
use dom::bindings::num::Finite;
use dom::bindings::refcounted::{Trusted, TrustedPromise};
@@ -91,8 +91,9 @@ use encoding::EncodingRef;
use encoding::all::UTF_8;
use euclid::point::Point2D;
use gfx_traits::ScrollRootId;
-use html5ever::tree_builder::{LimitedQuirks, NoQuirks, Quirks, QuirksMode};
use html5ever_atoms::{LocalName, QualName};
+use hyper::header::{Header, SetCookie};
+use hyper_serde::Serde;
use ipc_channel::ipc::{self, IpcSender};
use js::jsapi::{JSContext, JSObject, JSRuntime};
use js::jsapi::JS_GetRuntime;
@@ -113,6 +114,7 @@ use script_traits::{ScriptMsg as ConstellationMsg, TouchpadPressurePhase};
use script_traits::{TouchEventType, TouchId};
use script_traits::UntrustedNodeAddress;
use servo_atoms::Atom;
+use servo_config::prefs::PREFS;
use servo_url::ServoUrl;
use std::ascii::AsciiExt;
use std::borrow::ToOwned;
@@ -126,14 +128,13 @@ use std::rc::Rc;
use std::sync::Arc;
use std::time::{Duration, Instant};
use style::attr::AttrValue;
-use style::context::ReflowGoal;
+use style::context::{QuirksMode, ReflowGoal};
use style::restyle_hints::RestyleHint;
use style::selector_parser::{RestyleDamage, Snapshot};
use style::str::{split_html_space_chars, str_join};
use style::stylesheets::Stylesheet;
use time;
use url::percent_encoding::percent_decode;
-use util::prefs::PREFS;
pub enum TouchEventResult {
Processed(bool),
@@ -184,8 +185,8 @@ pub struct Document {
window: JS<Window>,
/// https://html.spec.whatwg.org/multipage/#concept-document-bc
browsing_context: Option<JS<BrowsingContext>>,
- implementation: MutNullableHeap<JS<DOMImplementation>>,
- location: MutNullableHeap<JS<Location>>,
+ implementation: MutNullableJS<DOMImplementation>,
+ location: MutNullableJS<Location>,
content_type: DOMString,
last_modified: Option<String>,
encoding: Cell<EncodingRef>,
@@ -197,29 +198,29 @@ pub struct Document {
tag_map: DOMRefCell<HashMap<LocalName, JS<HTMLCollection>>>,
tagns_map: DOMRefCell<HashMap<QualName, JS<HTMLCollection>>>,
classes_map: DOMRefCell<HashMap<Vec<Atom>, JS<HTMLCollection>>>,
- images: MutNullableHeap<JS<HTMLCollection>>,
- embeds: MutNullableHeap<JS<HTMLCollection>>,
- links: MutNullableHeap<JS<HTMLCollection>>,
- forms: MutNullableHeap<JS<HTMLCollection>>,
- scripts: MutNullableHeap<JS<HTMLCollection>>,
- anchors: MutNullableHeap<JS<HTMLCollection>>,
- applets: MutNullableHeap<JS<HTMLCollection>>,
+ images: MutNullableJS<HTMLCollection>,
+ embeds: MutNullableJS<HTMLCollection>,
+ links: MutNullableJS<HTMLCollection>,
+ forms: MutNullableJS<HTMLCollection>,
+ scripts: MutNullableJS<HTMLCollection>,
+ anchors: MutNullableJS<HTMLCollection>,
+ applets: MutNullableJS<HTMLCollection>,
/// List of stylesheets associated with nodes in this document. |None| if the list needs to be refreshed.
stylesheets: DOMRefCell<Option<Vec<StylesheetInDocument>>>,
/// Whether the list of stylesheets has changed since the last reflow was triggered.
stylesheets_changed_since_reflow: Cell<bool>,
- stylesheet_list: MutNullableHeap<JS<StyleSheetList>>,
+ stylesheet_list: MutNullableJS<StyleSheetList>,
ready_state: Cell<DocumentReadyState>,
/// Whether the DOMContentLoaded event has already been dispatched.
domcontentloaded_dispatched: Cell<bool>,
/// The element that has most recently requested focus for itself.
- possibly_focused: MutNullableHeap<JS<Element>>,
+ possibly_focused: MutNullableJS<Element>,
/// The element that currently has the document focus context.
- focused: MutNullableHeap<JS<Element>>,
+ focused: MutNullableJS<Element>,
/// The script element that is currently executing.
- current_script: MutNullableHeap<JS<HTMLScriptElement>>,
+ current_script: MutNullableJS<HTMLScriptElement>,
/// https://html.spec.whatwg.org/multipage/#pending-parsing-blocking-script
- pending_parsing_blocking_script: MutNullableHeap<JS<HTMLScriptElement>>,
+ pending_parsing_blocking_script: MutNullableJS<HTMLScriptElement>,
/// Number of stylesheets that block executing the next parser-inserted script
script_blocking_stylesheets_count: Cell<u32>,
/// https://html.spec.whatwg.org/multipage/#list-of-scripts-that-will-execute-when-the-document-has-finished-parsing
@@ -245,14 +246,14 @@ pub struct Document {
/// Tracks all outstanding loads related to this document.
loader: DOMRefCell<DocumentLoader>,
/// The current active HTML parser, to allow resuming after interruptions.
- current_parser: MutNullableHeap<JS<ServoParser>>,
+ current_parser: MutNullableJS<ServoParser>,
/// When we should kick off a reflow. This happens during parsing.
reflow_timeout: Cell<Option<u64>>,
/// The cached first `base` element with an `href` attribute.
- base_element: MutNullableHeap<JS<HTMLBaseElement>>,
+ base_element: MutNullableJS<HTMLBaseElement>,
/// This field is set to the document itself for inert documents.
/// https://html.spec.whatwg.org/multipage/#appropriate-template-contents-owner-document
- appropriate_template_contents_owner_document: MutNullableHeap<JS<Document>>,
+ appropriate_template_contents_owner_document: MutNullableJS<Document>,
/// Information on elements needing restyle to ship over to the layout thread when the
/// time comes.
pending_restyles: DOMRefCell<HashMap<JS<Element>, PendingRestyle>>,
@@ -280,7 +281,7 @@ pub struct Document {
/// https://html.spec.whatwg.org/multipage/#dom-document-referrer
referrer: Option<String>,
/// https://html.spec.whatwg.org/multipage/#target-element
- target_element: MutNullableHeap<JS<Element>>,
+ target_element: MutNullableJS<Element>,
/// https://w3c.github.io/uievents/#event-type-dblclick
#[ignore_heap_size_of = "Defined in std"]
last_click_info: DOMRefCell<Option<(Instant, Point2D<f32>)>>,
@@ -293,7 +294,7 @@ pub struct Document {
/// See also: https://github.com/servo/servo/issues/10110
dom_count: Cell<u32>,
/// Entry node for fullscreen.
- fullscreen_element: MutNullableHeap<JS<Element>>,
+ fullscreen_element: MutNullableJS<Element>,
}
#[derive(JSTraceable, HeapSizeOf)]
@@ -488,7 +489,7 @@ impl Document {
pub fn set_quirks_mode(&self, mode: QuirksMode) {
self.quirks_mode.set(mode);
- if mode == Quirks {
+ if mode == QuirksMode::Quirks {
self.window.layout_chan().send(Msg::SetQuirksMode).unwrap();
}
}
@@ -1036,7 +1037,7 @@ impl Document {
pub fn handle_mouse_move_event(&self,
js_runtime: *mut JSRuntime,
client_point: Option<Point2D<f32>>,
- prev_mouse_over_target: &MutNullableHeap<JS<Element>>) {
+ prev_mouse_over_target: &MutNullableJS<Element>) {
let client_point = match client_point {
None => {
// If there's no point, there's no target under the mouse
@@ -1521,8 +1522,11 @@ impl Document {
/// https://html.spec.whatwg.org/multipage/#run-the-animation-frame-callbacks
pub fn run_the_animation_frame_callbacks(&self) {
- let mut animation_frame_list =
- mem::replace(&mut *self.animation_frame_list.borrow_mut(), vec![]);
+ rooted_vec!(let mut animation_frame_list);
+ mem::swap(
+ &mut *animation_frame_list,
+ &mut *self.animation_frame_list.borrow_mut());
+
self.running_animation_callbacks.set(true);
let timing = self.window.Performance().Now();
@@ -1538,7 +1542,7 @@ impl Document {
// message quickly followed by an AnimationCallbacksPresent message.
if self.animation_frame_list.borrow().is_empty() {
mem::swap(&mut *self.animation_frame_list.borrow_mut(),
- &mut animation_frame_list);
+ &mut *animation_frame_list);
let global_scope = self.window.upcast::<GlobalScope>();
let event = ConstellationMsg::ChangeRunningAnimationsState(global_scope.pipeline_id(),
AnimationState::NoAnimationCallbacksPresent);
@@ -1772,6 +1776,7 @@ pub trait LayoutDocumentHelpers {
unsafe fn drain_pending_restyles(&self) -> Vec<(LayoutJS<Element>, PendingRestyle)>;
unsafe fn needs_paint_from_layout(&self);
unsafe fn will_paint(&self);
+ unsafe fn quirks_mode(&self) -> QuirksMode;
}
#[allow(unsafe_code)]
@@ -1798,6 +1803,11 @@ impl LayoutDocumentHelpers for LayoutJS<Document> {
unsafe fn will_paint(&self) {
(*self.unsafe_get()).needs_paint.set(false)
}
+
+ #[inline]
+ unsafe fn quirks_mode(&self) -> QuirksMode {
+ (*self.unsafe_get()).quirks_mode()
+ }
}
/// https://url.spec.whatwg.org/#network-scheme
@@ -1855,7 +1865,7 @@ impl Document {
last_modified: last_modified,
url: DOMRefCell::new(url),
// https://dom.spec.whatwg.org/#concept-document-quirks
- quirks_mode: Cell::new(NoQuirks),
+ quirks_mode: Cell::new(QuirksMode::NoQuirks),
// https://dom.spec.whatwg.org/#concept-document-encoding
encoding: Cell::new(UTF_8),
is_html_document: is_html_document == IsHTMLDocument::HTMLDocument,
@@ -1872,7 +1882,7 @@ impl Document {
applets: Default::default(),
stylesheets: DOMRefCell::new(None),
stylesheets_changed_since_reflow: Cell::new(false),
- stylesheet_list: MutNullableHeap::new(None),
+ stylesheet_list: MutNullableJS::new(None),
ready_state: Cell::new(ready_state),
domcontentloaded_dispatched: Cell::new(domcontentloaded_dispatched),
possibly_focused: Default::default(),
@@ -1907,11 +1917,11 @@ impl Document {
origin: origin,
referrer: referrer,
referrer_policy: Cell::new(referrer_policy),
- target_element: MutNullableHeap::new(None),
+ target_element: MutNullableJS::new(None),
last_click_info: DOMRefCell::new(None),
ignore_destructive_writes_counter: Default::default(),
dom_count: Cell::new(1),
- fullscreen_element: MutNullableHeap::new(None),
+ fullscreen_element: MutNullableJS::new(None),
}
}
@@ -2298,8 +2308,8 @@ impl DocumentMethods for Document {
// https://dom.spec.whatwg.org/#dom-document-compatmode
fn CompatMode(&self) -> DOMString {
DOMString::from(match self.quirks_mode.get() {
- LimitedQuirks | NoQuirks => "CSS1Compat",
- Quirks => "BackCompat",
+ QuirksMode::LimitedQuirks | QuirksMode::NoQuirks => "CSS1Compat",
+ QuirksMode::Quirks => "BackCompat",
})
}
@@ -2667,7 +2677,7 @@ impl DocumentMethods for Document {
None => DOMString::new(),
Some(ref title) => {
// Steps 3-4.
- let value = Node::collect_text_contents(title.children());
+ let value = title.child_text_content();
DOMString::from(str_join(split_html_space_chars(&value), " "))
},
}
@@ -2957,11 +2967,15 @@ impl DocumentMethods for Document {
return Err(Error::Security);
}
- let url = self.url();
- let _ = self.window
- .upcast::<GlobalScope>()
- .resource_threads()
- .send(SetCookiesForUrl(url, String::from(cookie), NonHTTP));
+ let header = Header::parse_header(&[cookie.into()]);
+ if let Ok(SetCookie(cookies)) = header {
+ let cookies = cookies.into_iter().map(Serde).collect();
+ let _ = self.window
+ .upcast::<GlobalScope>()
+ .resource_threads()
+ .send(SetCookiesForUrl(self.url(), cookies, NonHTTP));
+ }
+
Ok(())
}
diff --git a/components/script/dom/domexception.rs b/components/script/dom/domexception.rs
index 2a5946193b6..7428a986c48 100644
--- a/components/script/dom/domexception.rs
+++ b/components/script/dom/domexception.rs
@@ -29,13 +29,11 @@ pub enum DOMErrorName {
SecurityError = DOMExceptionConstants::SECURITY_ERR,
NetworkError = DOMExceptionConstants::NETWORK_ERR,
AbortError = DOMExceptionConstants::ABORT_ERR,
- URLMismatchError = DOMExceptionConstants::URL_MISMATCH_ERR,
TypeMismatchError = DOMExceptionConstants::TYPE_MISMATCH_ERR,
QuotaExceededError = DOMExceptionConstants::QUOTA_EXCEEDED_ERR,
TimeoutError = DOMExceptionConstants::TIMEOUT_ERR,
InvalidNodeTypeError = DOMExceptionConstants::INVALID_NODE_TYPE_ERR,
DataCloneError = DOMExceptionConstants::DATA_CLONE_ERR,
- EncodingError,
}
#[dom_struct]
@@ -62,11 +60,7 @@ impl DOMException {
impl DOMExceptionMethods for DOMException {
// https://heycam.github.io/webidl/#dfn-DOMException
fn Code(&self) -> u16 {
- match self.code {
- // https://heycam.github.io/webidl/#dfn-throw
- DOMErrorName::EncodingError => 0,
- code => code as u16,
- }
+ self.code as u16
}
// https://heycam.github.io/webidl/#idl-DOMException-error-names
@@ -93,14 +87,12 @@ impl DOMExceptionMethods for DOMException {
DOMErrorName::SecurityError => "The operation is insecure.",
DOMErrorName::NetworkError => "A network error occurred.",
DOMErrorName::AbortError => "The operation was aborted.",
- DOMErrorName::URLMismatchError => "The given URL does not match another URL.",
DOMErrorName::TypeMismatchError => "The given type does not match any expected type.",
DOMErrorName::QuotaExceededError => "The quota has been exceeded.",
DOMErrorName::TimeoutError => "The operation timed out.",
DOMErrorName::InvalidNodeTypeError =>
"The supplied node is incorrect or has an incorrect ancestor for this operation.",
DOMErrorName::DataCloneError => "The object can not be cloned.",
- DOMErrorName::EncodingError => "The encoding operation (either encoded or decoding) failed."
};
DOMString::from(message)
diff --git a/components/script/dom/domimplementation.rs b/components/script/dom/domimplementation.rs
index 7556e64d0a7..cbc69b318df 100644
--- a/components/script/dom/domimplementation.rs
+++ b/components/script/dom/domimplementation.rs
@@ -155,20 +155,17 @@ impl DOMImplementationMethods for DOMImplementation {
doc_html.AppendChild(&doc_head).unwrap();
// Step 6.
- match title {
- None => (),
- Some(title_str) => {
- // Step 6.1.
- let doc_title =
- Root::upcast::<Node>(HTMLTitleElement::new(local_name!("title"),
- None,
- &doc));
- doc_head.AppendChild(&doc_title).unwrap();
-
- // Step 6.2.
- let title_text = Text::new(title_str, &doc);
- doc_title.AppendChild(title_text.upcast()).unwrap();
- }
+ if let Some(title_str) = title {
+ // Step 6.1.
+ let doc_title =
+ Root::upcast::<Node>(HTMLTitleElement::new(local_name!("title"),
+ None,
+ &doc));
+ doc_head.AppendChild(&doc_title).unwrap();
+
+ // Step 6.2.
+ let title_text = Text::new(title_str, &doc);
+ doc_title.AppendChild(title_text.upcast()).unwrap();
}
}
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index 4a94f345b02..d9c2f6907e7 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -22,7 +22,7 @@ use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::codegen::UnionTypes::NodeOrString;
use dom::bindings::error::{Error, ErrorResult, Fallible};
use dom::bindings::inheritance::{Castable, ElementTypeId, HTMLElementTypeId, NodeTypeId};
-use dom::bindings::js::{JS, LayoutJS, MutNullableHeap};
+use dom::bindings::js::{JS, LayoutJS, MutNullableJS};
use dom::bindings::js::{Root, RootedReference};
use dom::bindings::refcounted::{Trusted, TrustedPromise};
use dom::bindings::reflector::DomObject;
@@ -51,9 +51,11 @@ use dom::htmlimageelement::{HTMLImageElement, LayoutHTMLImageElementHelpers};
use dom::htmlinputelement::{HTMLInputElement, LayoutHTMLInputElementHelpers};
use dom::htmllabelelement::HTMLLabelElement;
use dom::htmllegendelement::HTMLLegendElement;
+use dom::htmllinkelement::HTMLLinkElement;
use dom::htmlobjectelement::HTMLObjectElement;
use dom::htmloptgroupelement::HTMLOptGroupElement;
use dom::htmlselectelement::HTMLSelectElement;
+use dom::htmlstyleelement::HTMLStyleElement;
use dom::htmltablecellelement::{HTMLTableCellElement, HTMLTableCellElementLayoutHelpers};
use dom::htmltableelement::{HTMLTableElement, HTMLTableElementLayoutHelpers};
use dom::htmltablerowelement::{HTMLTableRowElement, HTMLTableRowElementLayoutHelpers};
@@ -75,7 +77,6 @@ use html5ever::serialize;
use html5ever::serialize::SerializeOpts;
use html5ever::serialize::TraversalScope;
use html5ever::serialize::TraversalScope::{ChildrenOnly, IncludeNode};
-use html5ever::tree_builder::{LimitedQuirks, NoQuirks, Quirks};
use html5ever_atoms::{Prefix, LocalName, Namespace, QualName};
use js::jsapi::{HandleValue, JSAutoCompartment};
use parking_lot::RwLock;
@@ -96,8 +97,7 @@ use std::rc::Rc;
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
use style::attr::{AttrValue, LengthOrPercentageOrAuto};
-use style::context::ReflowGoal;
-use style::dom::TRestyleDamage;
+use style::context::{QuirksMode, ReflowGoal};
use style::element_state::*;
use style::matching::{common_style_affecting_attributes, rare_style_affecting_attributes};
use style::parser::ParserContextExtraData;
@@ -110,6 +110,7 @@ use style::sink::Push;
use style::stylist::ApplicableDeclarationBlock;
use style::values::CSSFloat;
use style::values::specified::{self, CSSColor, CSSRGBA, LengthOrPercentage};
+use stylesheet_loader::StylesheetOwner;
// TODO: Update focus state when the top-level browsing context gains or loses system focus,
// and when the element enters or leaves a browsing context container.
@@ -126,8 +127,8 @@ pub struct Element {
id_attribute: DOMRefCell<Option<Atom>>,
#[ignore_heap_size_of = "Arc"]
style_attribute: DOMRefCell<Option<Arc<RwLock<PropertyDeclarationBlock>>>>,
- attr_list: MutNullableHeap<JS<NamedNodeMap>>,
- class_list: MutNullableHeap<JS<DOMTokenList>>,
+ attr_list: MutNullableJS<NamedNodeMap>,
+ class_list: MutNullableJS<DOMTokenList>,
state: Cell<ElementState>,
atomic_flags: AtomicElementFlags,
}
@@ -398,7 +399,7 @@ impl LayoutElementHelpers for LayoutJS<Element> {
PropertyDeclaration::BackgroundImage(DeclaredValue::Value(
background_image::SpecifiedValue(vec![
background_image::single_value::SpecifiedValue(Some(
- specified::Image::for_cascade(Some(url.into()), specified::url::UrlExtraData { })
+ specified::Image::for_cascade(url.into(), specified::url::UrlExtraData { })
))
])))));
}
@@ -1095,8 +1096,8 @@ impl Element {
let quirks_mode = document_from_node(self).quirks_mode();
let is_equal = |lhs: &Atom, rhs: &Atom| {
match quirks_mode {
- NoQuirks | LimitedQuirks => lhs == rhs,
- Quirks => lhs.eq_ignore_ascii_case(&rhs),
+ QuirksMode::NoQuirks | QuirksMode::LimitedQuirks => lhs == rhs,
+ QuirksMode::Quirks => lhs.eq_ignore_ascii_case(&rhs),
}
};
self.get_attribute(&ns!(), &local_name!("class"))
@@ -1276,7 +1277,7 @@ impl Element {
// Step 7
if *self.root_element() == *self {
- if doc.quirks_mode() != Quirks {
+ if doc.quirks_mode() != QuirksMode::Quirks {
win.scroll(x, y, behavior);
}
@@ -1285,7 +1286,7 @@ impl Element {
// Step 9
if doc.GetBody().r() == self.downcast::<HTMLElement>() &&
- doc.quirks_mode() == Quirks &&
+ doc.quirks_mode() == QuirksMode::Quirks &&
!self.potentially_scrollable() {
win.scroll(x, y, behavior);
return;
@@ -1656,7 +1657,7 @@ impl ElementMethods for Element {
// Step 5
if *self.root_element() == *self {
- if doc.quirks_mode() == Quirks {
+ if doc.quirks_mode() == QuirksMode::Quirks {
return 0.0;
}
@@ -1666,7 +1667,7 @@ impl ElementMethods for Element {
// Step 7
if doc.GetBody().r() == self.downcast::<HTMLElement>() &&
- doc.quirks_mode() == Quirks &&
+ doc.quirks_mode() == QuirksMode::Quirks &&
!self.potentially_scrollable() {
return win.ScrollY() as f64;
}
@@ -1707,7 +1708,7 @@ impl ElementMethods for Element {
// Step 7
if *self.root_element() == *self {
- if doc.quirks_mode() != Quirks {
+ if doc.quirks_mode() != QuirksMode::Quirks {
win.scroll(win.ScrollX() as f64, y, behavior);
}
@@ -1716,7 +1717,7 @@ impl ElementMethods for Element {
// Step 9
if doc.GetBody().r() == self.downcast::<HTMLElement>() &&
- doc.quirks_mode() == Quirks &&
+ doc.quirks_mode() == QuirksMode::Quirks &&
!self.potentially_scrollable() {
win.scroll(win.ScrollX() as f64, y, behavior);
return;
@@ -1748,7 +1749,7 @@ impl ElementMethods for Element {
// Step 5
if *self.root_element() == *self {
- if doc.quirks_mode() != Quirks {
+ if doc.quirks_mode() != QuirksMode::Quirks {
// Step 6
return win.ScrollX() as f64;
}
@@ -1758,7 +1759,7 @@ impl ElementMethods for Element {
// Step 7
if doc.GetBody().r() == self.downcast::<HTMLElement>() &&
- doc.quirks_mode() == Quirks &&
+ doc.quirks_mode() == QuirksMode::Quirks &&
!self.potentially_scrollable() {
return win.ScrollX() as f64;
}
@@ -1799,7 +1800,7 @@ impl ElementMethods for Element {
// Step 7
if *self.root_element() == *self {
- if doc.quirks_mode() == Quirks {
+ if doc.quirks_mode() == QuirksMode::Quirks {
return;
}
@@ -1809,7 +1810,7 @@ impl ElementMethods for Element {
// Step 9
if doc.GetBody().r() == self.downcast::<HTMLElement>() &&
- doc.quirks_mode() == Quirks &&
+ doc.quirks_mode() == QuirksMode::Quirks &&
!self.potentially_scrollable() {
win.scroll(x, win.ScrollY() as f64, behavior);
return;
@@ -2421,6 +2422,18 @@ impl Element {
})
}
+ pub fn as_stylesheet_owner(&self) -> Option<&StylesheetOwner> {
+ if let Some(s) = self.downcast::<HTMLStyleElement>() {
+ return Some(s as &StylesheetOwner)
+ }
+
+ if let Some(l) = self.downcast::<HTMLLinkElement>() {
+ return Some(l as &StylesheetOwner)
+ }
+
+ None
+ }
+
// https://html.spec.whatwg.org/multipage/#category-submit
pub fn as_maybe_validatable(&self) -> Option<&Validatable> {
let element = match self.upcast::<Node>().type_id() {
@@ -2663,15 +2676,11 @@ impl Element {
self.set_enabled_state(false);
return;
}
- match ancestor.children()
- .find(|child| child.is::<HTMLLegendElement>()) {
- Some(ref legend) => {
- // XXXabinader: should we save previous ancestor to avoid this iteration?
- if node.ancestors().any(|ancestor| ancestor == *legend) {
- continue;
- }
- },
- None => (),
+ if let Some(ref legend) = ancestor.children().find(|n| n.is::<HTMLLegendElement>()) {
+ // XXXabinader: should we save previous ancestor to avoid this iteration?
+ if node.ancestors().any(|ancestor| ancestor == *legend) {
+ continue;
+ }
}
self.set_disabled_state(true);
self.set_enabled_state(false);
diff --git a/components/script/dom/event.rs b/components/script/dom/event.rs
index d67d1f64e78..d471c25d873 100644
--- a/components/script/dom/event.rs
+++ b/components/script/dom/event.rs
@@ -6,7 +6,7 @@ use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::EventBinding;
use dom::bindings::codegen::Bindings::EventBinding::{EventConstants, EventMethods};
use dom::bindings::error::Fallible;
-use dom::bindings::js::{JS, MutNullableHeap, Root};
+use dom::bindings::js::{MutNullableJS, Root};
use dom::bindings::refcounted::Trusted;
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::bindings::str::DOMString;
@@ -80,8 +80,8 @@ impl From<bool> for EventCancelable {
#[dom_struct]
pub struct Event {
reflector_: Reflector,
- current_target: MutNullableHeap<JS<EventTarget>>,
- target: MutNullableHeap<JS<EventTarget>>,
+ current_target: MutNullableJS<EventTarget>,
+ target: MutNullableJS<EventTarget>,
type_: DOMRefCell<Atom>,
phase: Cell<EventPhase>,
canceled: Cell<bool>,
diff --git a/components/script/dom/eventdispatcher.rs b/components/script/dom/eventdispatcher.rs
index d5e4bf51338..bdec56532dc 100644
--- a/components/script/dom/eventdispatcher.rs
+++ b/components/script/dom/eventdispatcher.rs
@@ -156,15 +156,11 @@ pub fn dispatch_event(target: &EventTarget,
dispatch_to_listeners(event, target, event_path.r());
// Default action.
- let target = event.GetTarget();
- match target {
- Some(ref target) => {
- if let Some(node) = target.downcast::<Node>() {
- let vtable = vtable_for(&node);
- vtable.handle_event(event);
- }
+ if let Some(target) = event.GetTarget() {
+ if let Some(node) = target.downcast::<Node>() {
+ let vtable = vtable_for(&node);
+ vtable.handle_event(event);
}
- None => {}
}
// Step 10-12.
diff --git a/components/script/dom/filereader.rs b/components/script/dom/filereader.rs
index bb57ad5d9de..9b5c39b013c 100644
--- a/components/script/dom/filereader.rs
+++ b/components/script/dom/filereader.rs
@@ -9,7 +9,7 @@ use dom::bindings::codegen::Bindings::FileReaderBinding::{self, FileReaderConsta
use dom::bindings::codegen::UnionTypes::StringOrObject;
use dom::bindings::error::{Error, ErrorResult, Fallible};
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, MutNullableHeap, Root};
+use dom::bindings::js::{MutNullableJS, Root};
use dom::bindings::refcounted::Trusted;
use dom::bindings::reflector::{DomObject, reflect_dom_object};
use dom::bindings::str::DOMString;
@@ -34,9 +34,9 @@ use servo_atoms::Atom;
use std::cell::Cell;
use std::ptr;
use std::sync::Arc;
+use std::thread;
use task_source::TaskSource;
use task_source::file_reading::{FileReadingTaskSource, FileReadingRunnable, FileReadingTask};
-use util::thread::spawn_named;
#[derive(PartialEq, Clone, Copy, JSTraceable, HeapSizeOf)]
pub enum FileReaderFunction {
@@ -86,7 +86,7 @@ pub enum FileReaderResult {
pub struct FileReader {
eventtarget: EventTarget,
ready_state: Cell<FileReaderReadyState>,
- error: MutNullableHeap<JS<DOMException>>,
+ error: MutNullableJS<DOMException>,
result: DOMRefCell<Option<FileReaderResult>>,
generation_id: Cell<GenerationId>,
}
@@ -96,7 +96,7 @@ impl FileReader {
FileReader {
eventtarget: EventTarget::new_inherited(),
ready_state: Cell::new(FileReaderReadyState::Empty),
- error: MutNullableHeap::new(None),
+ error: MutNullableJS::new(None),
result: DOMRefCell::new(None),
generation_id: Cell::new(GenerationId(0)),
}
@@ -401,9 +401,10 @@ impl FileReader {
let wrapper = global.get_runnable_wrapper();
let task_source = global.file_reading_task_source();
- spawn_named("file reader async operation".to_owned(), move || {
+ thread::Builder::new().name("file reader async operation".to_owned()).spawn(move || {
perform_annotated_read_operation(gen_id, load_data, blob_contents, fr, task_source, wrapper)
- });
+ }).expect("Thread spawning failed");
+
Ok(())
}
diff --git a/components/script/dom/focusevent.rs b/components/script/dom/focusevent.rs
index 1eb3983737d..c7e48531479 100644
--- a/components/script/dom/focusevent.rs
+++ b/components/script/dom/focusevent.rs
@@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::FocusEventBinding::FocusEventMethods;
use dom::bindings::codegen::Bindings::UIEventBinding::UIEventMethods;
use dom::bindings::error::Fallible;
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference};
+use dom::bindings::js::{MutNullableJS, Root, RootedReference};
use dom::bindings::reflector::reflect_dom_object;
use dom::bindings::str::DOMString;
use dom::event::{EventBubbles, EventCancelable};
@@ -20,7 +20,7 @@ use std::default::Default;
#[dom_struct]
pub struct FocusEvent {
uievent: UIEvent,
- related_target: MutNullableHeap<JS<EventTarget>>,
+ related_target: MutNullableJS<EventTarget>,
}
impl FocusEvent {
diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs
index 19436804b19..ae08bc0e5fd 100644
--- a/components/script/dom/globalscope.rs
+++ b/components/script/dom/globalscope.rs
@@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::conversions::root_from_object;
use dom::bindings::error::{ErrorInfo, report_pending_exception};
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, MutNullableHeap, Root};
+use dom::bindings::js::{MutNullableJS, Root};
use dom::bindings::reflector::DomObject;
use dom::bindings::str::DOMString;
use dom::crypto::Crypto;
@@ -50,7 +50,7 @@ use timers::{OneshotTimers, TimerCallback};
#[dom_struct]
pub struct GlobalScope {
eventtarget: EventTarget,
- crypto: MutNullableHeap<JS<Crypto>>,
+ crypto: MutNullableJS<Crypto>,
next_worker_id: Cell<WorkerId>,
/// Pipeline id associated with this global.
diff --git a/components/script/dom/htmlanchorelement.rs b/components/script/dom/htmlanchorelement.rs
index f92290b2c97..52c355f2bab 100644
--- a/components/script/dom/htmlanchorelement.rs
+++ b/components/script/dom/htmlanchorelement.rs
@@ -11,7 +11,7 @@ use dom::bindings::codegen::Bindings::HTMLAnchorElementBinding::HTMLAnchorElemen
use dom::bindings::codegen::Bindings::MouseEventBinding::MouseEventMethods;
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, MutNullableHeap, Root};
+use dom::bindings::js::{MutNullableJS, Root};
use dom::bindings::str::{DOMString, USVString};
use dom::document::Document;
use dom::domtokenlist::DOMTokenList;
@@ -28,15 +28,15 @@ use html5ever_atoms::LocalName;
use net_traits::ReferrerPolicy;
use num_traits::ToPrimitive;
use script_traits::MozBrowserEvent;
+use servo_config::prefs::PREFS;
use servo_url::ServoUrl;
use std::default::Default;
use style::attr::AttrValue;
-use util::prefs::PREFS;
#[dom_struct]
pub struct HTMLAnchorElement {
htmlelement: HTMLElement,
- rel_list: MutNullableHeap<JS<DOMTokenList>>,
+ rel_list: MutNullableJS<DOMTokenList>,
url: DOMRefCell<Option<ServoUrl>>,
}
diff --git a/components/script/dom/htmlareaelement.rs b/components/script/dom/htmlareaelement.rs
index b8df3806a3f..79240885167 100644
--- a/components/script/dom/htmlareaelement.rs
+++ b/components/script/dom/htmlareaelement.rs
@@ -5,7 +5,7 @@
use dom::bindings::codegen::Bindings::HTMLAreaElementBinding;
use dom::bindings::codegen::Bindings::HTMLAreaElementBinding::HTMLAreaElementMethods;
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, MutNullableHeap, Root};
+use dom::bindings::js::{MutNullableJS, Root};
use dom::bindings::str::DOMString;
use dom::document::Document;
use dom::domtokenlist::DOMTokenList;
@@ -19,7 +19,7 @@ use style::attr::AttrValue;
#[dom_struct]
pub struct HTMLAreaElement {
htmlelement: HTMLElement,
- rel_list: MutNullableHeap<JS<DOMTokenList>>,
+ rel_list: MutNullableJS<DOMTokenList>,
}
impl HTMLAreaElement {
diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs
index b9d7731d652..b174d2ec9a8 100644
--- a/components/script/dom/htmlcanvaselement.rs
+++ b/components/script/dom/htmlcanvaselement.rs
@@ -13,7 +13,7 @@ use dom::bindings::codegen::UnionTypes::CanvasRenderingContext2DOrWebGLRendering
use dom::bindings::conversions::ConversionResult;
use dom::bindings::error::{Error, Fallible};
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{HeapGCValue, JS, LayoutJS, Root};
+use dom::bindings::js::{JS, LayoutJS, Root};
use dom::bindings::num::Finite;
use dom::bindings::str::DOMString;
use dom::canvasrenderingcontext2d::{CanvasRenderingContext2D, LayoutCanvasRenderingContext2DHelpers};
@@ -47,8 +47,6 @@ pub enum CanvasContext {
WebGL(JS<WebGLRenderingContext>),
}
-impl HeapGCValue for CanvasContext {}
-
#[dom_struct]
pub struct HTMLCanvasElement {
htmlelement: HTMLElement,
diff --git a/components/script/dom/htmlcollection.rs b/components/script/dom/htmlcollection.rs
index 959265e82e0..eacffd6cded 100644
--- a/components/script/dom/htmlcollection.rs
+++ b/components/script/dom/htmlcollection.rs
@@ -5,7 +5,7 @@
use dom::bindings::codegen::Bindings::HTMLCollectionBinding;
use dom::bindings::codegen::Bindings::HTMLCollectionBinding::HTMLCollectionMethods;
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, Root, MutNullableHeap};
+use dom::bindings::js::{JS, Root, MutNullableJS};
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::bindings::str::DOMString;
use dom::bindings::trace::JSTraceable;
@@ -59,7 +59,7 @@ pub struct HTMLCollection {
// the length of the collection, and a cursor into the collection.
// FIXME: make the cached cursor element a weak pointer
cached_version: Cell<u64>,
- cached_cursor_element: MutNullableHeap<JS<Element>>,
+ cached_cursor_element: MutNullableJS<Element>,
cached_cursor_index: Cell<OptionU32>,
cached_length: Cell<OptionU32>,
}
@@ -73,7 +73,7 @@ impl HTMLCollection {
filter: filter,
// Default values for the cache
cached_version: Cell::new(root.inclusive_descendants_version()),
- cached_cursor_element: MutNullableHeap::new(None),
+ cached_cursor_element: MutNullableJS::new(None),
cached_cursor_index: Cell::new(OptionU32::none()),
cached_length: Cell::new(OptionU32::none()),
}
diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs
index d4490357650..6725fdb5dfb 100644
--- a/components/script/dom/htmlelement.rs
+++ b/components/script/dom/htmlelement.rs
@@ -13,9 +13,9 @@ use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::error::{Error, ErrorResult};
use dom::bindings::inheritance::{ElementTypeId, HTMLElementTypeId, NodeTypeId};
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference};
+use dom::bindings::js::{JS, MutNullableJS, Root, RootedReference};
use dom::bindings::str::DOMString;
-use dom::cssstyledeclaration::{CSSModificationAccess, CSSStyleDeclaration};
+use dom::cssstyledeclaration::{CSSModificationAccess, CSSStyleDeclaration, CSSStyleOwner};
use dom::document::{Document, FocusType};
use dom::domstringmap::DOMStringMap;
use dom::element::{AttributeMutation, Element};
@@ -40,8 +40,8 @@ use style::element_state::*;
#[dom_struct]
pub struct HTMLElement {
element: Element,
- style_decl: MutNullableHeap<JS<CSSStyleDeclaration>>,
- dataset: MutNullableHeap<JS<DOMStringMap>>,
+ style_decl: MutNullableJS<CSSStyleDeclaration>,
+ dataset: MutNullableJS<DOMStringMap>,
}
impl HTMLElement {
@@ -115,7 +115,10 @@ impl HTMLElementMethods for HTMLElement {
fn Style(&self) -> Root<CSSStyleDeclaration> {
self.style_decl.or_init(|| {
let global = window_from_node(self);
- CSSStyleDeclaration::new(&global, self.upcast::<Element>(), None, CSSModificationAccess::ReadWrite)
+ CSSStyleDeclaration::new(&global,
+ CSSStyleOwner::Element(JS::from_ref(self.upcast())),
+ None,
+ CSSModificationAccess::ReadWrite)
})
}
diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs
index 90abdbafefd..a0a34b081c8 100755
--- a/components/script/dom/htmlformelement.rs
+++ b/components/script/dom/htmlformelement.rs
@@ -13,7 +13,7 @@ use dom::bindings::codegen::Bindings::HTMLInputElementBinding::HTMLInputElementM
use dom::bindings::codegen::Bindings::HTMLTextAreaElementBinding::HTMLTextAreaElementMethods;
use dom::bindings::conversions::DerivedFrom;
use dom::bindings::inheritance::{Castable, ElementTypeId, HTMLElementTypeId, NodeTypeId};
-use dom::bindings::js::{JS, MutNullableHeap, Root};
+use dom::bindings::js::{MutNullableJS, Root};
use dom::bindings::refcounted::Trusted;
use dom::bindings::reflector::DomObject;
use dom::bindings::str::DOMString;
@@ -61,7 +61,7 @@ pub struct GenerationId(u32);
pub struct HTMLFormElement {
htmlelement: HTMLElement,
marked_for_reset: Cell<bool>,
- elements: MutNullableHeap<JS<HTMLFormControlsCollection>>,
+ elements: MutNullableJS<HTMLFormControlsCollection>,
generation_id: Cell<GenerationId>
}
@@ -85,10 +85,6 @@ impl HTMLFormElement {
document,
HTMLFormElementBinding::Wrap)
}
-
- pub fn generation_id(&self) -> GenerationId {
- self.generation_id.get()
- }
}
impl HTMLFormElementMethods for HTMLFormElement {
@@ -662,6 +658,7 @@ impl HTMLFormElement {
#[derive(JSTraceable, HeapSizeOf, Clone)]
pub enum FormDatumValue {
+ #[allow(dead_code)]
File(Root<File>),
String(DOMString)
}
@@ -701,6 +698,7 @@ pub enum FormMethod {
}
#[derive(HeapSizeOf)]
+#[allow(dead_code)]
pub enum FormSubmittableElement {
ButtonElement(Root<HTMLButtonElement>),
InputElement(Root<HTMLInputElement>),
diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs
index 44323e1c1ef..53c7e34f94f 100644
--- a/components/script/dom/htmliframeelement.rs
+++ b/components/script/dom/htmliframeelement.rs
@@ -19,7 +19,7 @@ use dom::bindings::codegen::Bindings::WindowBinding::WindowBinding::WindowMethod
use dom::bindings::conversions::ToJSValConvertible;
use dom::bindings::error::{Error, ErrorResult, Fallible};
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root};
+use dom::bindings::js::{LayoutJS, MutNullableJS, Root};
use dom::bindings::refcounted::Trusted;
use dom::bindings::reflector::DomObject;
use dom::bindings::str::DOMString;
@@ -48,13 +48,13 @@ use script_traits::{IFrameLoadInfo, IFrameLoadInfoWithData, LoadData};
use script_traits::{MozBrowserEvent, NewLayoutInfo, ScriptMsg as ConstellationMsg};
use script_traits::IFrameSandboxState::{IFrameSandboxed, IFrameUnsandboxed};
use servo_atoms::Atom;
+use servo_config::prefs::PREFS;
+use servo_config::servo_version;
use servo_url::ServoUrl;
use std::cell::Cell;
use style::attr::{AttrValue, LengthOrPercentageOrAuto};
use style::context::ReflowGoal;
use task_source::TaskSource;
-use util::prefs::PREFS;
-use util::servo_version;
bitflags! {
#[derive(JSTraceable, HeapSizeOf)]
@@ -80,7 +80,7 @@ pub struct HTMLIFrameElement {
htmlelement: HTMLElement,
frame_id: FrameId,
pipeline_id: Cell<Option<PipelineId>>,
- sandbox: MutNullableHeap<JS<DOMTokenList>>,
+ sandbox: MutNullableJS<DOMTokenList>,
sandbox_allowance: Cell<Option<SandboxAllowance>>,
load_blocker: DOMRefCell<Option<LoadBlocker>>,
visibility: Cell<bool>,
diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs
index 90cf630e9fe..eb344ef0a79 100755
--- a/components/script/dom/htmlinputelement.rs
+++ b/components/script/dom/htmlinputelement.rs
@@ -13,7 +13,7 @@ use dom::bindings::codegen::Bindings::HTMLInputElementBinding::HTMLInputElementM
use dom::bindings::codegen::Bindings::KeyboardEventBinding::KeyboardEventMethods;
use dom::bindings::error::{Error, ErrorResult};
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root, RootedReference};
+use dom::bindings::js::{JS, LayoutJS, MutNullableJS, Root, RootedReference};
use dom::bindings::str::DOMString;
use dom::document::Document;
use dom::element::{AttributeMutation, Element, LayoutElementHelpers, RawLayoutElementHelpers};
@@ -94,7 +94,7 @@ pub struct HTMLInputElement {
// https://html.spec.whatwg.org/multipage/#concept-input-value-dirty-flag
value_dirty: Cell<bool>,
- filelist: MutNullableHeap<JS<FileList>>,
+ filelist: MutNullableJS<FileList>,
}
#[derive(JSTraceable)]
@@ -150,7 +150,7 @@ impl HTMLInputElement {
SelectionDirection::None)),
activation_state: DOMRefCell::new(InputActivationState::new()),
value_dirty: Cell::new(false),
- filelist: MutNullableHeap::new(None),
+ filelist: MutNullableJS::new(None),
}
}
diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs
index 1985e511c4d..ee4ee4718cf 100644
--- a/components/script/dom/htmllinkelement.rs
+++ b/components/script/dom/htmllinkelement.rs
@@ -3,65 +3,54 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use cssparser::Parser as CssParser;
-use document_loader::LoadType;
use dom::attr::Attr;
use dom::bindings::cell::DOMRefCell;
-use dom::bindings::codegen::Bindings::DOMTokenListBinding::DOMTokenListMethods;
+use dom::bindings::codegen::Bindings::DOMTokenListBinding::DOMTokenListBinding::DOMTokenListMethods;
use dom::bindings::codegen::Bindings::HTMLLinkElementBinding;
use dom::bindings::codegen::Bindings::HTMLLinkElementBinding::HTMLLinkElementMethods;
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference};
-use dom::bindings::refcounted::Trusted;
-use dom::bindings::reflector::DomObject;
+use dom::bindings::js::{MutNullableJS, Root, RootedReference};
use dom::bindings::str::DOMString;
use dom::cssstylesheet::CSSStyleSheet;
use dom::document::Document;
use dom::domtokenlist::DOMTokenList;
use dom::element::{AttributeMutation, Element, ElementCreator};
-use dom::eventtarget::EventTarget;
use dom::globalscope::GlobalScope;
use dom::htmlelement::HTMLElement;
use dom::node::{Node, document_from_node, window_from_node};
use dom::stylesheet::StyleSheet as DOMStyleSheet;
use dom::virtualmethods::VirtualMethods;
-use encoding::EncodingRef;
-use encoding::all::UTF_8;
use html5ever_atoms::LocalName;
-use hyper::header::ContentType;
-use hyper::mime::{Mime, TopLevel, SubLevel};
-use hyper_serde::Serde;
-use ipc_channel::ipc;
-use ipc_channel::router::ROUTER;
-use net_traits::{FetchResponseListener, FetchMetadata, Metadata, NetworkError, ReferrerPolicy};
-use net_traits::request::{CredentialsMode, Destination, RequestInit, Type as RequestType};
-use network_listener::{NetworkListener, PreInvoke};
-use script_layout_interface::message::Msg;
+use net_traits::ReferrerPolicy;
use script_traits::{MozBrowserEvent, ScriptMsg as ConstellationMsg};
-use servo_url::ServoUrl;
use std::ascii::AsciiExt;
use std::borrow::ToOwned;
use std::cell::Cell;
use std::default::Default;
-use std::mem;
-use std::sync::{Arc, Mutex};
+use std::sync::Arc;
use style::attr::AttrValue;
-use style::media_queries::{MediaList, parse_media_query_list};
-use style::parser::ParserContextExtraData;
+use style::media_queries::parse_media_query_list;
use style::str::HTML_SPACE_CHARACTERS;
-use style::stylesheets::{Stylesheet, Origin};
+use style::stylesheets::Stylesheet;
+use stylesheet_loader::{StylesheetLoader, StylesheetContextSource, StylesheetOwner};
unsafe_no_jsmanaged_fields!(Stylesheet);
#[dom_struct]
pub struct HTMLLinkElement {
htmlelement: HTMLElement,
- rel_list: MutNullableHeap<JS<DOMTokenList>>,
+ rel_list: MutNullableJS<DOMTokenList>,
#[ignore_heap_size_of = "Arc"]
stylesheet: DOMRefCell<Option<Arc<Stylesheet>>>,
- cssom_stylesheet: MutNullableHeap<JS<CSSStyleSheet>>,
+ cssom_stylesheet: MutNullableJS<CSSStyleSheet>,
/// https://html.spec.whatwg.org/multipage/#a-style-sheet-that-is-blocking-scripts
parser_inserted: Cell<bool>,
+ /// The number of loads that this link element has triggered (could be more
+ /// than one because of imports) and have not yet finished.
+ pending_loads: Cell<u32>,
+ /// Whether any of the loads have failed.
+ any_failed_load: Cell<bool>,
}
impl HTMLLinkElement {
@@ -72,7 +61,9 @@ impl HTMLLinkElement {
rel_list: Default::default(),
parser_inserted: Cell::new(creator == ElementCreator::ParserCreated),
stylesheet: DOMRefCell::new(None),
- cssom_stylesheet: MutNullableHeap::new(None),
+ cssom_stylesheet: MutNullableJS::new(None),
+ pending_loads: Cell::new(0),
+ any_failed_load: Cell::new(false),
}
}
@@ -86,6 +77,12 @@ impl HTMLLinkElement {
HTMLLinkElementBinding::Wrap)
}
+ pub fn set_stylesheet(&self, s: Arc<Stylesheet>) {
+ assert!(self.stylesheet.borrow().is_none());
+ *self.stylesheet.borrow_mut() = Some(s);
+ }
+
+
pub fn get_stylesheet(&self) -> Option<Arc<Stylesheet>> {
self.stylesheet.borrow().clone()
}
@@ -231,8 +228,11 @@ impl HTMLLinkElement {
// Step 2.
let url = match document.base_url().join(href) {
- Err(e) => return debug!("Parsing url {} failed: {}", href, e),
Ok(url) => url,
+ Err(e) => {
+ debug!("Parsing url {} failed: {}", href, e);
+ return;
+ }
};
let element = self.upcast::<Element>();
@@ -246,50 +246,13 @@ impl HTMLLinkElement {
let mut css_parser = CssParser::new(&mq_str);
let media = parse_media_query_list(&mut css_parser);
- // TODO: #8085 - Don't load external stylesheets if the node's mq doesn't match.
- let elem = Trusted::new(self);
-
- let context = Arc::new(Mutex::new(StylesheetContext {
- elem: elem,
+ // TODO: #8085 - Don't load external stylesheets if the node's mq
+ // doesn't match.
+ let loader = StylesheetLoader::for_element(self.upcast());
+ loader.load(StylesheetContextSource::LinkElement {
+ url: url,
media: Some(media),
- data: vec!(),
- metadata: None,
- url: url.clone(),
- }));
-
- let (action_sender, action_receiver) = ipc::channel().unwrap();
- let listener = NetworkListener {
- context: context,
- task_source: document.window().networking_task_source(),
- wrapper: Some(document.window().get_runnable_wrapper())
- };
- ROUTER.add_route(action_receiver.to_opaque(), box move |message| {
- listener.notify_fetch(message.to().unwrap());
});
-
- if self.parser_inserted.get() {
- document.increment_script_blocking_stylesheet_count();
- }
-
- let referrer_policy = match self.RelList().Contains("noreferrer".into()) {
- true => Some(ReferrerPolicy::NoReferrer),
- false => document.get_referrer_policy(),
- };
-
- let request = RequestInit {
- url: url.clone(),
- type_: RequestType::Style,
- destination: Destination::Style,
- credentials_mode: CredentialsMode::Include,
- use_url_credentials: true,
- origin: document.url(),
- pipeline_id: Some(self.global().pipeline_id()),
- referrer_url: Some(document.url()),
- referrer_policy: referrer_policy,
- .. RequestInit::default()
- };
-
- document.fetch_async(LoadType::Stylesheet(url), request, action_sender);
}
fn handle_favicon_url(&self, rel: &str, href: &str, sizes: &Option<String>) {
@@ -310,92 +273,37 @@ impl HTMLLinkElement {
}
}
-/// The context required for asynchronously loading an external stylesheet.
-struct StylesheetContext {
- /// The element that initiated the request.
- elem: Trusted<HTMLLinkElement>,
- media: Option<MediaList>,
- /// The response body received to date.
- data: Vec<u8>,
- /// The response metadata received to date.
- metadata: Option<Metadata>,
- /// The initial URL requested.
- url: ServoUrl,
-}
-
-impl PreInvoke for StylesheetContext {}
-
-impl FetchResponseListener for StylesheetContext {
- fn process_request_body(&mut self) {}
+impl StylesheetOwner for HTMLLinkElement {
+ fn increment_pending_loads_count(&self) {
+ self.pending_loads.set(self.pending_loads.get() + 1)
+ }
- fn process_request_eof(&mut self) {}
+ fn load_finished(&self, succeeded: bool) -> Option<bool> {
+ assert!(self.pending_loads.get() > 0, "What finished?");
+ if !succeeded {
+ self.any_failed_load.set(true);
+ }
- fn process_response(&mut self,
- metadata: Result<FetchMetadata, NetworkError>) {
- self.metadata = metadata.ok().map(|m| {
- match m {
- FetchMetadata::Unfiltered(m) => m,
- FetchMetadata::Filtered { unsafe_, .. } => unsafe_
- }
- });
- if let Some(ref meta) = self.metadata {
- if let Some(Serde(ContentType(Mime(TopLevel::Text, SubLevel::Css, _)))) = meta.content_type {
- } else {
- self.elem.root().upcast::<EventTarget>().fire_event(atom!("error"));
- }
+ self.pending_loads.set(self.pending_loads.get() - 1);
+ if self.pending_loads.get() != 0 {
+ return None;
}
- }
- fn process_response_chunk(&mut self, mut payload: Vec<u8>) {
- self.data.append(&mut payload);
+ let any_failed = self.any_failed_load.get();
+ self.any_failed_load.set(false);
+ Some(any_failed)
}
- fn process_response_eof(&mut self, status: Result<(), NetworkError>) {
- let elem = self.elem.root();
- let document = document_from_node(&*elem);
- let mut successful = false;
-
- if status.is_ok() {
- let metadata = match self.metadata.take() {
- Some(meta) => meta,
- None => return,
- };
- let is_css = metadata.content_type.map_or(false, |Serde(ContentType(Mime(top, sub, _)))|
- top == TopLevel::Text && sub == SubLevel::Css);
-
- let data = if is_css { mem::replace(&mut self.data, vec!()) } else { vec!() };
-
- // TODO: Get the actual value. http://dev.w3.org/csswg/css-syntax/#environment-encoding
- let environment_encoding = UTF_8 as EncodingRef;
- let protocol_encoding_label = metadata.charset.as_ref().map(|s| &**s);
- let final_url = metadata.final_url;
-
- let win = window_from_node(&*elem);
-
- let sheet = Arc::new(Stylesheet::from_bytes(
- &data, final_url, protocol_encoding_label, Some(environment_encoding),
- Origin::Author, self.media.take().unwrap(), win.css_error_reporter(),
- ParserContextExtraData::default()));
-
- let win = window_from_node(&*elem);
- win.layout_chan().send(Msg::AddStylesheet(sheet.clone())).unwrap();
-
- *elem.stylesheet.borrow_mut() = Some(sheet);
- document.invalidate_stylesheets();
-
- // FIXME: Revisit once consensus is reached at: https://github.com/whatwg/html/issues/1142
- successful = metadata.status.map_or(false, |(code, _)| code == 200);
- }
+ fn parser_inserted(&self) -> bool {
+ self.parser_inserted.get()
+ }
- if elem.parser_inserted.get() {
- document.decrement_script_blocking_stylesheet_count();
+ fn referrer_policy(&self) -> Option<ReferrerPolicy> {
+ if self.RelList().Contains("noreferrer".into()) {
+ return Some(ReferrerPolicy::NoReferrer)
}
- document.finish_load(LoadType::Stylesheet(self.url.clone()));
-
- let event = if successful { atom!("load") } else { atom!("error") };
-
- elem.upcast::<EventTarget>().fire_event(event);
+ None
}
}
diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs
index 778c0d6b560..fd327404b4d 100644
--- a/components/script/dom/htmlmediaelement.rs
+++ b/components/script/dom/htmlmediaelement.rs
@@ -13,7 +13,7 @@ use dom::bindings::codegen::Bindings::HTMLMediaElementBinding::HTMLMediaElementM
use dom::bindings::codegen::Bindings::MediaErrorBinding::MediaErrorConstants::*;
use dom::bindings::codegen::Bindings::MediaErrorBinding::MediaErrorMethods;
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{Root, MutNullableHeap, JS};
+use dom::bindings::js::{MutNullableJS, Root};
use dom::bindings::refcounted::Trusted;
use dom::bindings::reflector::DomObject;
use dom::bindings::str::DOMString;
@@ -218,7 +218,7 @@ pub struct HTMLMediaElement {
current_src: DOMRefCell<String>,
generation_id: Cell<u32>,
first_data_load: Cell<bool>,
- error: MutNullableHeap<JS<MediaError>>,
+ error: MutNullableJS<MediaError>,
paused: Cell<bool>,
autoplaying: Cell<bool>,
video: DOMRefCell<Option<VideoMedia>>,
@@ -243,11 +243,6 @@ impl HTMLMediaElement {
}
}
- #[inline]
- pub fn htmlelement(&self) -> &HTMLElement {
- &self.htmlelement
- }
-
// https://html.spec.whatwg.org/multipage/#internal-pause-steps
fn internal_pause_steps(&self) {
// Step 1
@@ -437,6 +432,7 @@ impl HTMLMediaElement {
}
// https://html.spec.whatwg.org/multipage/#concept-media-load-algorithm
+ #[allow(unreachable_code)]
fn resource_selection_algorithm_sync(&self, base_url: ServoUrl) {
// TODO step 5 (populate pending text tracks)
@@ -446,7 +442,7 @@ impl HTMLMediaElement {
ResourceSelectionMode::Object
} else if let Some(attr) = self.upcast::<Element>().get_attribute(&ns!(), &local_name!("src")) {
ResourceSelectionMode::Attribute(attr.Value().to_string())
- } else if false {
+ } else if false { // TODO: when implementing this remove #[allow(unreachable_code)] above.
// TODO <source> child
ResourceSelectionMode::Children(panic!())
} else {
diff --git a/components/script/dom/htmlmetaelement.rs b/components/script/dom/htmlmetaelement.rs
index bcf112cce94..cf9d078e39f 100644
--- a/components/script/dom/htmlmetaelement.rs
+++ b/components/script/dom/htmlmetaelement.rs
@@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::HTMLMetaElementBinding;
use dom::bindings::codegen::Bindings::HTMLMetaElementBinding::HTMLMetaElementMethods;
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference};
+use dom::bindings::js::{MutNullableJS, Root, RootedReference};
use dom::bindings::str::DOMString;
use dom::cssstylesheet::CSSStyleSheet;
use dom::document::Document;
@@ -19,6 +19,7 @@ use dom::node::{Node, UnbindContext, document_from_node, window_from_node};
use dom::virtualmethods::VirtualMethods;
use html5ever_atoms::LocalName;
use parking_lot::RwLock;
+use servo_config::prefs::PREFS;
use std::ascii::AsciiExt;
use std::sync::Arc;
use std::sync::atomic::AtomicBool;
@@ -32,7 +33,7 @@ pub struct HTMLMetaElement {
htmlelement: HTMLElement,
#[ignore_heap_size_of = "Arc"]
stylesheet: DOMRefCell<Option<Arc<Stylesheet>>>,
- cssom_stylesheet: MutNullableHeap<JS<CSSStyleSheet>>,
+ cssom_stylesheet: MutNullableJS<CSSStyleSheet>,
}
impl HTMLMetaElement {
@@ -42,7 +43,7 @@ impl HTMLMetaElement {
HTMLMetaElement {
htmlelement: HTMLElement::new_inherited(local_name, prefix, document),
stylesheet: DOMRefCell::new(None),
- cssom_stylesheet: MutNullableHeap::new(None),
+ cssom_stylesheet: MutNullableJS::new(None),
}
}
@@ -89,7 +90,7 @@ impl HTMLMetaElement {
}
fn apply_viewport(&self) {
- if !::util::prefs::PREFS.get("layout.viewport.enabled").as_boolean().unwrap_or(false) {
+ if !PREFS.get("layout.viewport.enabled").as_boolean().unwrap_or(false) {
return;
}
let element = self.upcast::<Element>();
diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs
index bccde70bb88..9558d9c4b41 100644
--- a/components/script/dom/htmlscriptelement.rs
+++ b/components/script/dom/htmlscriptelement.rs
@@ -713,7 +713,7 @@ impl HTMLScriptElementMethods for HTMLScriptElement {
// https://html.spec.whatwg.org/multipage/#dom-script-text
fn Text(&self) -> DOMString {
- Node::collect_text_contents(self.upcast::<Node>().children())
+ self.upcast::<Node>().child_text_content()
}
// https://html.spec.whatwg.org/multipage/#dom-script-text
diff --git a/components/script/dom/htmlselectelement.rs b/components/script/dom/htmlselectelement.rs
index ad66f2b05f3..25977da8095 100755
--- a/components/script/dom/htmlselectelement.rs
+++ b/components/script/dom/htmlselectelement.rs
@@ -14,7 +14,7 @@ use dom::bindings::codegen::UnionTypes::HTMLElementOrLong;
use dom::bindings::codegen::UnionTypes::HTMLOptionElementOrHTMLOptGroupElement;
//use dom::bindings::error::ErrorResult;
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, MutNullableHeap, Root};
+use dom::bindings::js::{MutNullableJS, Root};
use dom::bindings::str::DOMString;
use dom::document::Document;
use dom::element::{AttributeMutation, Element};
@@ -31,6 +31,7 @@ use dom::validation::Validatable;
use dom::validitystate::{ValidityState, ValidationFlags};
use dom::virtualmethods::VirtualMethods;
use html5ever_atoms::LocalName;
+use std::iter;
use style::attr::AttrValue;
use style::element_state::*;
@@ -58,7 +59,7 @@ impl CollectionFilter for OptionsFilter {
#[dom_struct]
pub struct HTMLSelectElement {
htmlelement: HTMLElement,
- options: MutNullableHeap<JS<HTMLOptionsCollection>>,
+ options: MutNullableJS<HTMLOptionsCollection>,
}
static DEFAULT_SELECT_SIZE: u32 = 0;
@@ -84,10 +85,25 @@ impl HTMLSelectElement {
HTMLSelectElementBinding::Wrap)
}
+ // https://html.spec.whatwg.org/multipage/#concept-select-option-list
+ fn list_of_options(&self) -> impl Iterator<Item=Root<HTMLOptionElement>> {
+ self.upcast::<Node>()
+ .children()
+ .flat_map(|node| {
+ if node.is::<HTMLOptionElement>() {
+ let node = Root::downcast::<HTMLOptionElement>(node).unwrap();
+ Choice3::First(iter::once(node))
+ } else if node.is::<HTMLOptGroupElement>() {
+ Choice3::Second(node.children().filter_map(Root::downcast))
+ } else {
+ Choice3::Third(iter::empty())
+ }
+ })
+ }
+
// https://html.spec.whatwg.org/multipage/#the-select-element:concept-form-reset-control
pub fn reset(&self) {
- let node = self.upcast::<Node>();
- for opt in node.traverse_preorder().filter_map(Root::downcast::<HTMLOptionElement>) {
+ for opt in self.list_of_options() {
opt.set_selectedness(opt.DefaultSelected());
opt.set_dirtiness(false);
}
@@ -103,8 +119,7 @@ impl HTMLSelectElement {
let mut first_enabled: Option<Root<HTMLOptionElement>> = None;
let mut last_selected: Option<Root<HTMLOptionElement>> = None;
- let node = self.upcast::<Node>();
- for opt in node.traverse_preorder().filter_map(Root::downcast::<HTMLOptionElement>) {
+ for opt in self.list_of_options() {
if opt.Selected() {
opt.set_selectedness(false);
last_selected = Some(Root::from_ref(&opt));
@@ -127,11 +142,10 @@ impl HTMLSelectElement {
}
pub fn push_form_data(&self, data_set: &mut Vec<FormDatum>) {
- let node = self.upcast::<Node>();
if self.Name().is_empty() {
return;
}
- for opt in node.traverse_preorder().filter_map(Root::downcast::<HTMLOptionElement>) {
+ for opt in self.list_of_options() {
let element = opt.upcast::<Element>();
if opt.Selected() && element.enabled_state() {
data_set.push(FormDatum {
@@ -146,9 +160,8 @@ impl HTMLSelectElement {
// https://html.spec.whatwg.org/multipage/#concept-select-pick
pub fn pick_option(&self, picked: &HTMLOptionElement) {
if !self.Multiple() {
- let node = self.upcast::<Node>();
let picked = picked.upcast();
- for opt in node.traverse_preorder().filter_map(Root::downcast::<HTMLOptionElement>) {
+ for opt in self.list_of_options() {
if opt.upcast::<HTMLElement>() != picked {
opt.set_selectedness(false);
}
@@ -271,9 +284,7 @@ impl HTMLSelectElementMethods for HTMLSelectElement {
// https://html.spec.whatwg.org/multipage/#dom-select-value
fn Value(&self) -> DOMString {
- self.upcast::<Node>()
- .traverse_preorder()
- .filter_map(Root::downcast::<HTMLOptionElement>)
+ self.list_of_options()
.filter(|opt_elem| opt_elem.Selected())
.map(|opt_elem| opt_elem.Value())
.next()
@@ -282,9 +293,7 @@ impl HTMLSelectElementMethods for HTMLSelectElement {
// https://html.spec.whatwg.org/multipage/#dom-select-value
fn SetValue(&self, value: DOMString) {
- let mut opt_iter = self.upcast::<Node>()
- .traverse_preorder()
- .filter_map(Root::downcast::<HTMLOptionElement>);
+ let mut opt_iter = self.list_of_options();
// Reset until we find an <option> with a matching value
for opt in opt_iter.by_ref() {
if opt.Value() == value {
@@ -302,9 +311,7 @@ impl HTMLSelectElementMethods for HTMLSelectElement {
// https://html.spec.whatwg.org/multipage/#dom-select-selectedindex
fn SelectedIndex(&self) -> i32 {
- self.upcast::<Node>()
- .traverse_preorder()
- .filter_map(Root::downcast::<HTMLOptionElement>)
+ self.list_of_options()
.enumerate()
.filter(|&(_, ref opt_elem)| opt_elem.Selected())
.map(|(i, _)| i as i32)
@@ -314,9 +321,7 @@ impl HTMLSelectElementMethods for HTMLSelectElement {
// https://html.spec.whatwg.org/multipage/#dom-select-selectedindex
fn SetSelectedIndex(&self, index: i32) {
- let mut opt_iter = self.upcast::<Node>()
- .traverse_preorder()
- .filter_map(Root::downcast::<HTMLOptionElement>);
+ let mut opt_iter = self.list_of_options();
for opt in opt_iter.by_ref().take(index as usize) {
opt.set_selectedness(false);
}
@@ -394,3 +399,23 @@ impl Validatable for HTMLSelectElement {
true
}
}
+
+enum Choice3<I, J, K> {
+ First(I),
+ Second(J),
+ Third(K),
+}
+
+impl<I, J, K, T> Iterator for Choice3<I, J, K>
+ where I: Iterator<Item=T>, J: Iterator<Item=T>, K: Iterator<Item=T>
+{
+ type Item = T;
+
+ fn next(&mut self) -> Option<T> {
+ match *self {
+ Choice3::First(ref mut i) => i.next(),
+ Choice3::Second(ref mut j) => j.next(),
+ Choice3::Third(ref mut k) => k.next(),
+ }
+ }
+}
diff --git a/components/script/dom/htmlstyleelement.rs b/components/script/dom/htmlstyleelement.rs
index 5a61d6f5b3a..2507f7bee35 100644
--- a/components/script/dom/htmlstyleelement.rs
+++ b/components/script/dom/htmlstyleelement.rs
@@ -8,46 +8,59 @@ use dom::bindings::codegen::Bindings::HTMLStyleElementBinding;
use dom::bindings::codegen::Bindings::HTMLStyleElementBinding::HTMLStyleElementMethods;
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, MutNullableHeap, Root};
+use dom::bindings::js::{MutNullableJS, Root};
use dom::bindings::str::DOMString;
use dom::cssstylesheet::CSSStyleSheet;
use dom::document::Document;
-use dom::element::Element;
+use dom::element::{Element, ElementCreator};
+use dom::eventtarget::EventTarget;
use dom::htmlelement::HTMLElement;
use dom::node::{ChildrenMutation, Node, document_from_node, window_from_node};
use dom::stylesheet::StyleSheet as DOMStyleSheet;
use dom::virtualmethods::VirtualMethods;
use html5ever_atoms::LocalName;
+use net_traits::ReferrerPolicy;
use script_layout_interface::message::Msg;
+use std::cell::Cell;
use std::sync::Arc;
use style::media_queries::parse_media_query_list;
use style::parser::ParserContextExtraData;
use style::stylesheets::{Stylesheet, Origin};
+use stylesheet_loader::{StylesheetLoader, StylesheetOwner};
#[dom_struct]
pub struct HTMLStyleElement {
htmlelement: HTMLElement,
#[ignore_heap_size_of = "Arc"]
stylesheet: DOMRefCell<Option<Arc<Stylesheet>>>,
- cssom_stylesheet: MutNullableHeap<JS<CSSStyleSheet>>,
+ cssom_stylesheet: MutNullableJS<CSSStyleSheet>,
+ /// https://html.spec.whatwg.org/multipage/#a-style-sheet-that-is-blocking-scripts
+ parser_inserted: Cell<bool>,
+ pending_loads: Cell<u32>,
+ any_failed_load: Cell<bool>,
}
impl HTMLStyleElement {
fn new_inherited(local_name: LocalName,
prefix: Option<DOMString>,
- document: &Document) -> HTMLStyleElement {
+ document: &Document,
+ creator: ElementCreator) -> HTMLStyleElement {
HTMLStyleElement {
htmlelement: HTMLElement::new_inherited(local_name, prefix, document),
stylesheet: DOMRefCell::new(None),
- cssom_stylesheet: MutNullableHeap::new(None),
+ cssom_stylesheet: MutNullableJS::new(None),
+ parser_inserted: Cell::new(creator == ElementCreator::ParserCreated),
+ pending_loads: Cell::new(0),
+ any_failed_load: Cell::new(false),
}
}
#[allow(unrooted_must_root)]
pub fn new(local_name: LocalName,
prefix: Option<DOMString>,
- document: &Document) -> Root<HTMLStyleElement> {
- Node::reflect_node(box HTMLStyleElement::new_inherited(local_name, prefix, document),
+ document: &Document,
+ creator: ElementCreator) -> Root<HTMLStyleElement> {
+ Node::reflect_node(box HTMLStyleElement::new_inherited(local_name, prefix, document, creator),
document,
HTMLStyleElementBinding::Wrap)
}
@@ -68,10 +81,19 @@ impl HTMLStyleElement {
let data = node.GetTextContent().expect("Element.textContent must be a string");
let mq = parse_media_query_list(&mut CssParser::new(&mq_str));
- let sheet = Stylesheet::from_str(&data, url, Origin::Author, mq, win.css_error_reporter(),
+ let loader = StylesheetLoader::for_element(self.upcast());
+ let sheet = Stylesheet::from_str(&data, url, Origin::Author, mq,
+ Some(&loader),
+ win.css_error_reporter(),
ParserContextExtraData::default());
+
let sheet = Arc::new(sheet);
+ // No subresource loads were triggered, just fire the load event now.
+ if self.pending_loads.get() == 0 {
+ self.upcast::<EventTarget>().fire_event(atom!("load"));
+ }
+
win.layout_chan().send(Msg::AddStylesheet(sheet.clone())).unwrap();
*self.stylesheet.borrow_mut() = Some(sheet);
let doc = document_from_node(self);
@@ -121,6 +143,37 @@ impl VirtualMethods for HTMLStyleElement {
}
}
+impl StylesheetOwner for HTMLStyleElement {
+ fn increment_pending_loads_count(&self) {
+ self.pending_loads.set(self.pending_loads.get() + 1)
+ }
+
+ fn load_finished(&self, succeeded: bool) -> Option<bool> {
+ assert!(self.pending_loads.get() > 0, "What finished?");
+ if !succeeded {
+ self.any_failed_load.set(true);
+ }
+
+ self.pending_loads.set(self.pending_loads.get() - 1);
+ if self.pending_loads.get() != 0 {
+ return None;
+ }
+
+ let any_failed = self.any_failed_load.get();
+ self.any_failed_load.set(false);
+ Some(any_failed)
+ }
+
+ fn parser_inserted(&self) -> bool {
+ self.parser_inserted.get()
+ }
+
+ fn referrer_policy(&self) -> Option<ReferrerPolicy> {
+ None
+ }
+}
+
+
impl HTMLStyleElementMethods for HTMLStyleElement {
// https://drafts.csswg.org/cssom/#dom-linkstyle-sheet
fn GetSheet(&self) -> Option<Root<DOMStyleSheet>> {
diff --git a/components/script/dom/htmltablecellelement.rs b/components/script/dom/htmltablecellelement.rs
index b4bd885d4ed..4a6ca5ca9b1 100644
--- a/components/script/dom/htmltablecellelement.rs
+++ b/components/script/dom/htmltablecellelement.rs
@@ -34,11 +34,6 @@ impl HTMLTableCellElement {
htmlelement: HTMLElement::new_inherited(tag_name, prefix, document),
}
}
-
- #[inline]
- pub fn htmlelement(&self) -> &HTMLElement {
- &self.htmlelement
- }
}
impl HTMLTableCellElementMethods for HTMLTableCellElement {
diff --git a/components/script/dom/htmltableelement.rs b/components/script/dom/htmltableelement.rs
index e533c9acdcd..741b53c38ac 100644
--- a/components/script/dom/htmltableelement.rs
+++ b/components/script/dom/htmltableelement.rs
@@ -10,7 +10,7 @@ use dom::bindings::codegen::Bindings::HTMLTableElementBinding::HTMLTableElementM
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::error::{Error, ErrorResult, Fallible};
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root, RootedReference};
+use dom::bindings::js::{JS, LayoutJS, MutNullableJS, Root, RootedReference};
use dom::bindings::str::DOMString;
use dom::document::Document;
use dom::element::{AttributeMutation, Element, RawLayoutElementHelpers};
@@ -31,7 +31,7 @@ pub struct HTMLTableElement {
htmlelement: HTMLElement,
border: Cell<Option<u32>>,
cellspacing: Cell<Option<u32>>,
- tbodies: MutNullableHeap<JS<HTMLCollection>>,
+ tbodies: MutNullableJS<HTMLCollection>,
}
#[allow(unrooted_must_root)]
diff --git a/components/script/dom/htmltablerowelement.rs b/components/script/dom/htmltablerowelement.rs
index b95aba1c3e0..c6b04648dc2 100644
--- a/components/script/dom/htmltablerowelement.rs
+++ b/components/script/dom/htmltablerowelement.rs
@@ -9,7 +9,7 @@ use dom::bindings::codegen::Bindings::HTMLTableSectionElementBinding::HTMLTableS
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::error::{ErrorResult, Fallible};
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root, RootedReference};
+use dom::bindings::js::{LayoutJS, MutNullableJS, Root, RootedReference};
use dom::bindings::str::DOMString;
use dom::document::Document;
use dom::element::{Element, RawLayoutElementHelpers};
@@ -36,7 +36,7 @@ impl CollectionFilter for CellsFilter {
#[dom_struct]
pub struct HTMLTableRowElement {
htmlelement: HTMLElement,
- cells: MutNullableHeap<JS<HTMLCollection>>,
+ cells: MutNullableJS<HTMLCollection>,
}
impl HTMLTableRowElement {
diff --git a/components/script/dom/htmltemplateelement.rs b/components/script/dom/htmltemplateelement.rs
index 7ee8d03b163..1c9b2c0aacd 100644
--- a/components/script/dom/htmltemplateelement.rs
+++ b/components/script/dom/htmltemplateelement.rs
@@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::HTMLTemplateElementBinding;
use dom::bindings::codegen::Bindings::HTMLTemplateElementBinding::HTMLTemplateElementMethods;
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, MutNullableHeap, Root};
+use dom::bindings::js::{MutNullableJS, Root};
use dom::bindings::str::DOMString;
use dom::document::Document;
use dom::documentfragment::DocumentFragment;
@@ -21,7 +21,7 @@ pub struct HTMLTemplateElement {
htmlelement: HTMLElement,
/// https://html.spec.whatwg.org/multipage/#template-contents
- contents: MutNullableHeap<JS<DocumentFragment>>,
+ contents: MutNullableJS<DocumentFragment>,
}
impl HTMLTemplateElement {
@@ -31,7 +31,7 @@ impl HTMLTemplateElement {
HTMLTemplateElement {
htmlelement:
HTMLElement::new_inherited(local_name, prefix, document),
- contents: MutNullableHeap::new(None),
+ contents: MutNullableJS::new(None),
}
}
diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs
index 47b9bb6ee0b..fd5b42fa25c 100755
--- a/components/script/dom/htmltextareaelement.rs
+++ b/components/script/dom/htmltextareaelement.rs
@@ -39,6 +39,7 @@ pub struct HTMLTextAreaElement {
htmlelement: HTMLElement,
#[ignore_heap_size_of = "#7193"]
textinput: DOMRefCell<TextInput<IpcSender<ConstellationMsg>>>,
+ placeholder: DOMRefCell<DOMString>,
// https://html.spec.whatwg.org/multipage/#concept-textarea-dirty
value_changed: Cell<bool>,
}
@@ -58,7 +59,12 @@ impl LayoutHTMLTextAreaElementHelpers for LayoutJS<HTMLTextAreaElement> {
#[allow(unrooted_must_root)]
#[allow(unsafe_code)]
unsafe fn get_value_for_layout(self) -> String {
- String::from((*self.unsafe_get()).textinput.borrow_for_layout().get_content())
+ let text = (*self.unsafe_get()).textinput.borrow_for_layout().get_content();
+ String::from(if text.is_empty() {
+ (*self.unsafe_get()).placeholder.borrow_for_layout().clone()
+ } else {
+ text
+ })
}
#[allow(unrooted_must_root)]
@@ -105,6 +111,7 @@ impl HTMLTextAreaElement {
htmlelement:
HTMLElement::new_inherited_with_state(IN_ENABLED_STATE | IN_READ_WRITE_STATE,
local_name, prefix, document),
+ placeholder: DOMRefCell::new(DOMString::new()),
textinput: DOMRefCell::new(TextInput::new(
Lines::Multiple, DOMString::new(), chan, None, None, SelectionDirection::None)),
value_changed: Cell::new(false),
@@ -119,6 +126,14 @@ impl HTMLTextAreaElement {
document,
HTMLTextAreaElementBinding::Wrap)
}
+
+ fn update_placeholder_shown_state(&self) {
+ let has_placeholder = !self.placeholder.borrow().is_empty();
+ let has_value = !self.textinput.borrow().is_empty();
+ let el = self.upcast::<Element>();
+ el.set_placeholder_shown_state(has_placeholder && !has_value);
+ el.set_placeholder_shown_state(has_placeholder);
+ }
}
impl HTMLTextAreaElementMethods for HTMLTextAreaElement {
@@ -270,11 +285,6 @@ impl HTMLTextAreaElementMethods for HTMLTextAreaElement {
impl HTMLTextAreaElement {
- // https://html.spec.whatwg.org/multipage/#concept-fe-mutable
- pub fn mutable(&self) -> bool {
- // https://html.spec.whatwg.org/multipage/#the-textarea-element:concept-fe-mutable
- !(self.Disabled() || self.ReadOnly())
- }
pub fn reset(&self) {
// https://html.spec.whatwg.org/multipage/#the-textarea-element:concept-form-reset-control
self.SetValue(self.DefaultValue());
@@ -311,6 +321,16 @@ impl VirtualMethods for HTMLTextAreaElement {
}
}
},
+ local_name!("placeholder") => {
+ {
+ let mut placeholder = self.placeholder.borrow_mut();
+ placeholder.clear();
+ if let AttributeMutation::Set(_) = mutation {
+ placeholder.push_str(&attr.value());
+ }
+ }
+ self.update_placeholder_shown_state();
+ },
local_name!("readonly") => {
let el = self.upcast::<Element>();
match mutation {
@@ -375,10 +395,14 @@ impl VirtualMethods for HTMLTextAreaElement {
document_from_node(self).request_focus(self.upcast());
} else if event.type_() == atom!("keydown") && !event.DefaultPrevented() {
if let Some(kevent) = event.downcast::<KeyboardEvent>() {
- match self.textinput.borrow_mut().handle_keydown(kevent) {
+ // This can't be inlined, as holding on to textinput.borrow_mut()
+ // during self.implicit_submission will cause a panic.
+ let action = self.textinput.borrow_mut().handle_keydown(kevent);
+ match action {
KeyReaction::TriggerDefaultAction => (),
KeyReaction::DispatchInput => {
self.value_changed.set(true);
+ self.update_placeholder_shown_state();
if event.IsTrusted() {
let window = window_from_node(self);
diff --git a/components/script/dom/htmltimeelement.rs b/components/script/dom/htmltimeelement.rs
index 84794443e02..c5286dd685f 100644
--- a/components/script/dom/htmltimeelement.rs
+++ b/components/script/dom/htmltimeelement.rs
@@ -2,14 +2,11 @@
* 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::ElementBinding::ElementBinding::ElementMethods;
use dom::bindings::codegen::Bindings::HTMLTimeElementBinding;
use dom::bindings::codegen::Bindings::HTMLTimeElementBinding::HTMLTimeElementMethods;
-use dom::bindings::inheritance::Castable;
use dom::bindings::js::Root;
use dom::bindings::str::DOMString;
use dom::document::Document;
-use dom::element::Element;
use dom::htmlelement::HTMLElement;
use dom::node::Node;
use html5ever_atoms::LocalName;
@@ -38,18 +35,7 @@ impl HTMLTimeElement {
impl HTMLTimeElementMethods for HTMLTimeElement {
// https://html.spec.whatwg.org/multipage/#dom-time-datetime
- //make_getter!(DateTime, "datetime");
- fn DateTime(&self) -> DOMString {
- let element = self.upcast::<Element>();
- if element.has_attribute(&local_name!("datetime")) {
- return element.get_string_attribute(&local_name!("datetime"))
- } else {
- match element.GetInnerHTML() {
- Ok(x) => x,
- _ => DOMString::new(),
- }
- }
- }
+ make_getter!(DateTime, "datetime");
// https://html.spec.whatwg.org/multipage/#dom-time-datetime
make_setter!(SetDateTime, "datetime");
diff --git a/components/script/dom/htmltitleelement.rs b/components/script/dom/htmltitleelement.rs
index f3ec357cb56..6dde6a6203b 100644
--- a/components/script/dom/htmltitleelement.rs
+++ b/components/script/dom/htmltitleelement.rs
@@ -8,11 +8,9 @@ use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::Root;
use dom::bindings::str::DOMString;
-use dom::characterdata::CharacterData;
use dom::document::Document;
use dom::htmlelement::HTMLElement;
use dom::node::{ChildrenMutation, Node};
-use dom::text::Text;
use dom::virtualmethods::VirtualMethods;
use html5ever_atoms::LocalName;
@@ -41,13 +39,7 @@ impl HTMLTitleElement {
impl HTMLTitleElementMethods for HTMLTitleElement {
// https://html.spec.whatwg.org/multipage/#dom-title-text
fn Text(&self) -> DOMString {
- let mut content = String::new();
- for child in self.upcast::<Node>().children() {
- if let Some(text) = child.downcast::<Text>() {
- content.push_str(&text.upcast::<CharacterData>().data());
- }
- }
- DOMString::from(content)
+ self.upcast::<Node>().child_text_content()
}
// https://html.spec.whatwg.org/multipage/#dom-title-text
diff --git a/components/script/dom/macros.rs b/components/script/dom/macros.rs
index 99b06bae39d..f2174bdd552 100644
--- a/components/script/dom/macros.rs
+++ b/components/script/dom/macros.rs
@@ -537,14 +537,15 @@ macro_rules! document_and_element_event_handlers(
#[macro_export]
macro_rules! rooted_vec {
(let mut $name:ident) => {
- rooted_vec!(let mut $name <- ::std::iter::empty())
+ let mut root = $crate::dom::bindings::trace::RootableVec::new_unrooted();
+ let mut $name = $crate::dom::bindings::trace::RootedVec::new(&mut root);
};
(let $name:ident <- $iter:expr) => {
- let mut __root = $crate::dom::bindings::trace::RootableVec::new_unrooted();
- let $name = $crate::dom::bindings::trace::RootedVec::new(&mut __root, $iter);
+ let mut root = $crate::dom::bindings::trace::RootableVec::new_unrooted();
+ let $name = $crate::dom::bindings::trace::RootedVec::from_iter(&mut root, $iter);
};
(let mut $name:ident <- $iter:expr) => {
- let mut __root = $crate::dom::bindings::trace::RootableVec::new_unrooted();
- let mut $name = $crate::dom::bindings::trace::RootedVec::new(&mut __root, $iter);
+ let mut root = $crate::dom::bindings::trace::RootableVec::new_unrooted();
+ let mut $name = $crate::dom::bindings::trace::RootedVec::from_iter(&mut root, $iter);
}
}
diff --git a/components/script/dom/mediaquerylist.rs b/components/script/dom/mediaquerylist.rs
index 86f67cdd8a1..db96a4760cd 100644
--- a/components/script/dom/mediaquerylist.rs
+++ b/components/script/dom/mediaquerylist.rs
@@ -9,12 +9,15 @@ use dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods;
use dom::bindings::codegen::Bindings::MediaQueryListBinding::{self, MediaQueryListMethods};
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, Root};
+use dom::bindings::reflector::DomObject;
use dom::bindings::reflector::reflect_dom_object;
use dom::bindings::str::DOMString;
use dom::bindings::trace::JSTraceable;
use dom::bindings::weakref::{WeakRef, WeakRefVec};
use dom::document::Document;
+use dom::event::Event;
use dom::eventtarget::EventTarget;
+use dom::mediaquerylistevent::MediaQueryListEvent;
use euclid::scale_factor::ScaleFactor;
use js::jsapi::JSTracer;
use std::cell::Cell;
@@ -136,8 +139,14 @@ impl WeakMediaQueryListVec {
/// https://drafts.csswg.org/cssom-view/#evaluate-media-queries-and-report-changes
pub fn evaluate_and_report_changes(&self) {
for mql in self.cell.borrow().iter() {
- if let MediaQueryListMatchState::Changed(_) = mql.root().unwrap().evaluate_changes() {
- mql.root().unwrap().upcast::<EventTarget>().fire_event(atom!("change"));
+ let mql = mql.root().unwrap();
+ if let MediaQueryListMatchState::Changed(_) = mql.evaluate_changes() {
+ let event = MediaQueryListEvent::new(&mql.global(),
+ atom!("change"),
+ false, false,
+ mql.Media(),
+ mql.Matches());
+ event.upcast::<Event>().fire(mql.upcast::<EventTarget>());
}
}
}
diff --git a/components/script/dom/mediaquerylistevent.rs b/components/script/dom/mediaquerylistevent.rs
new file mode 100644
index 00000000000..8edd2fa3ab2
--- /dev/null
+++ b/components/script/dom/mediaquerylistevent.rs
@@ -0,0 +1,76 @@
+/* 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::EventBinding::EventMethods;
+use dom::bindings::codegen::Bindings::MediaQueryListEventBinding;
+use dom::bindings::codegen::Bindings::MediaQueryListEventBinding::MediaQueryListEventInit;
+use dom::bindings::codegen::Bindings::MediaQueryListEventBinding::MediaQueryListEventMethods;
+use dom::bindings::error::Fallible;
+use dom::bindings::inheritance::Castable;
+use dom::bindings::js::Root;
+use dom::bindings::reflector::reflect_dom_object;
+use dom::bindings::str::DOMString;
+use dom::event::Event;
+use dom::globalscope::GlobalScope;
+use dom::window::Window;
+use servo_atoms::Atom;
+use std::cell::Cell;
+
+// https://drafts.csswg.org/cssom-view/#dom-mediaquerylistevent-mediaquerylistevent
+#[dom_struct]
+pub struct MediaQueryListEvent {
+ event: Event,
+ media: DOMString,
+ matches: Cell<bool>
+}
+
+impl MediaQueryListEvent {
+ pub fn new_initialized(global: &GlobalScope,
+ media: DOMString,
+ matches: bool) -> Root<MediaQueryListEvent> {
+ let ev = box MediaQueryListEvent {
+ event: Event::new_inherited(),
+ media: media,
+ matches: Cell::new(matches)
+ };
+ reflect_dom_object(ev, global, MediaQueryListEventBinding::Wrap)
+ }
+
+ pub fn new(global: &GlobalScope, type_: Atom,
+ bubbles: bool, cancelable: bool,
+ media: DOMString, matches: bool) -> Root<MediaQueryListEvent> {
+ let ev = MediaQueryListEvent::new_initialized(global, media, matches);
+ {
+ let event = ev.upcast::<Event>();
+ event.init_event(type_, bubbles, cancelable);
+ }
+ ev
+ }
+
+ pub fn Constructor(window: &Window, type_: DOMString,
+ init: &MediaQueryListEventInit)
+ -> Fallible<Root<MediaQueryListEvent>> {
+ let global = window.upcast::<GlobalScope>();
+ Ok(MediaQueryListEvent::new(global, Atom::from(type_),
+ init.parent.bubbles, init.parent.cancelable,
+ init.media.clone(), init.matches))
+ }
+}
+
+impl MediaQueryListEventMethods for MediaQueryListEvent {
+ // https://drafts.csswg.org/cssom-view/#dom-mediaquerylistevent-media
+ fn Media(&self) -> DOMString {
+ self.media.clone()
+ }
+
+ // https://drafts.csswg.org/cssom-view/#dom-mediaquerylistevent-matches
+ fn Matches(&self) -> bool {
+ self.matches.get()
+ }
+
+ // https://dom.spec.whatwg.org/#dom-event-istrusted
+ fn IsTrusted(&self) -> bool {
+ self.upcast::<Event>().IsTrusted()
+ }
+}
diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs
index 5bc19eab627..4f94ac8309f 100644
--- a/components/script/dom/mod.rs
+++ b/components/script/dom/mod.rs
@@ -32,8 +32,8 @@
//! * rooting pointers on the stack:
//! the [`Root`](bindings/js/struct.Root.html) smart pointer;
//! * tracing pointers in member fields: the [`JS`](bindings/js/struct.JS.html),
-//! [`MutNullableHeap`](bindings/js/struct.MutNullableHeap.html) and
-//! [`MutHeap`](bindings/js/struct.MutHeap.html) smart pointers and
+//! [`MutNullableJS`](bindings/js/struct.MutNullableJS.html) and
+//! [`MutJS`](bindings/js/struct.MutJS.html) smart pointers and
//! [the tracing implementation](bindings/trace/index.html);
//! * rooting pointers from across thread boundaries or in channels: the
//! [`Trusted`](bindings/refcounted/struct.Trusted.html) smart pointer;
@@ -217,13 +217,10 @@ pub mod abstractworkerglobalscope;
pub mod activation;
pub mod attr;
pub mod beforeunloadevent;
-mod create;
-#[allow(unsafe_code)]
-#[deny(missing_docs, non_snake_case)]
pub mod bindings;
pub mod blob;
pub mod bluetooth;
-pub mod bluetoothadvertisingdata;
+pub mod bluetoothadvertisingevent;
pub mod bluetoothcharacteristicproperties;
pub mod bluetoothdevice;
pub mod bluetoothremotegattcharacteristic;
@@ -240,10 +237,12 @@ pub mod client;
pub mod closeevent;
pub mod comment;
pub mod console;
+mod create;
pub mod crypto;
pub mod css;
pub mod cssfontfacerule;
pub mod cssgroupingrule;
+pub mod cssimportrule;
pub mod csskeyframerule;
pub mod csskeyframesrule;
pub mod cssmediarule;
@@ -370,6 +369,7 @@ pub mod location;
pub mod mediaerror;
pub mod medialist;
pub mod mediaquerylist;
+pub mod mediaquerylistevent;
pub mod messageevent;
pub mod mimetype;
pub mod mimetypearray;
diff --git a/components/script/dom/mouseevent.rs b/components/script/dom/mouseevent.rs
index 2b39d555204..3b0e3fb1710 100644
--- a/components/script/dom/mouseevent.rs
+++ b/components/script/dom/mouseevent.rs
@@ -7,16 +7,16 @@ use dom::bindings::codegen::Bindings::MouseEventBinding::MouseEventMethods;
use dom::bindings::codegen::Bindings::UIEventBinding::UIEventMethods;
use dom::bindings::error::Fallible;
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference};
+use dom::bindings::js::{MutNullableJS, Root, RootedReference};
use dom::bindings::reflector::reflect_dom_object;
use dom::bindings::str::DOMString;
use dom::event::{Event, EventBubbles, EventCancelable};
use dom::eventtarget::EventTarget;
use dom::uievent::UIEvent;
use dom::window::Window;
+use servo_config::prefs::PREFS;
use std::cell::Cell;
use std::default::Default;
-use util::prefs::PREFS;
#[dom_struct]
pub struct MouseEvent {
@@ -30,7 +30,7 @@ pub struct MouseEvent {
alt_key: Cell<bool>,
meta_key: Cell<bool>,
button: Cell<i16>,
- related_target: MutNullableHeap<JS<EventTarget>>,
+ related_target: MutNullableJS<EventTarget>,
}
impl MouseEvent {
diff --git a/components/script/dom/navigator.rs b/components/script/dom/navigator.rs
index 9318e437ad5..b7d781f5eb0 100644
--- a/components/script/dom/navigator.rs
+++ b/components/script/dom/navigator.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::Bindings::NavigatorBinding;
use dom::bindings::codegen::Bindings::NavigatorBinding::NavigatorMethods;
-use dom::bindings::js::{JS, MutNullableHeap, Root};
+use dom::bindings::js::{MutNullableJS, Root};
use dom::bindings::reflector::{Reflector, DomObject, reflect_dom_object};
use dom::bindings::str::DOMString;
use dom::bluetooth::Bluetooth;
@@ -17,10 +17,10 @@ use dom::window::Window;
#[dom_struct]
pub struct Navigator {
reflector_: Reflector,
- bluetooth: MutNullableHeap<JS<Bluetooth>>,
- plugins: MutNullableHeap<JS<PluginArray>>,
- mime_types: MutNullableHeap<JS<MimeTypeArray>>,
- service_worker: MutNullableHeap<JS<ServiceWorkerContainer>>,
+ bluetooth: MutNullableJS<Bluetooth>,
+ plugins: MutNullableJS<PluginArray>,
+ mime_types: MutNullableJS<MimeTypeArray>,
+ service_worker: MutNullableJS<ServiceWorkerContainer>,
}
impl Navigator {
diff --git a/components/script/dom/navigatorinfo.rs b/components/script/dom/navigatorinfo.rs
index 54200e7be20..f0b331c49e6 100644
--- a/components/script/dom/navigatorinfo.rs
+++ b/components/script/dom/navigatorinfo.rs
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::str::DOMString;
-use util::opts;
+use servo_config::opts;
pub fn Product() -> DOMString {
DOMString::from("Gecko")
diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs
index 983f11f478c..d6bc301955d 100644
--- a/components/script/dom/node.rs
+++ b/components/script/dom/node.rs
@@ -21,7 +21,7 @@ use dom::bindings::error::{Error, ErrorResult, Fallible};
use dom::bindings::inheritance::{Castable, CharacterDataTypeId, ElementTypeId};
use dom::bindings::inheritance::{EventTargetTypeId, HTMLElementTypeId, NodeTypeId};
use dom::bindings::inheritance::{SVGElementTypeId, SVGGraphicsElementTypeId};
-use dom::bindings::js::{JS, LayoutJS, MutNullableHeap};
+use dom::bindings::js::{JS, LayoutJS, MutNullableJS};
use dom::bindings::js::Root;
use dom::bindings::js::RootedReference;
use dom::bindings::reflector::{DomObject, reflect_dom_object};
@@ -57,7 +57,6 @@ use euclid::point::Point2D;
use euclid::rect::Rect;
use euclid::size::Size2D;
use heapsize::{HeapSizeOf, heap_size_of};
-use html5ever::tree_builder::QuirksMode;
use html5ever_atoms::{Prefix, Namespace, QualName};
use js::jsapi::{JSContext, JSObject, JSRuntime};
use libc::{self, c_void, uintptr_t};
@@ -78,6 +77,7 @@ use std::iter;
use std::mem;
use std::ops::Range;
use std::sync::Arc;
+use style::context::QuirksMode;
use style::dom::OpaqueNode;
use style::selector_parser::{SelectorImpl, SelectorParser};
use style::stylesheets::Stylesheet;
@@ -95,25 +95,25 @@ pub struct Node {
eventtarget: EventTarget,
/// The parent of this node.
- parent_node: MutNullableHeap<JS<Node>>,
+ parent_node: MutNullableJS<Node>,
/// The first child of this node.
- first_child: MutNullableHeap<JS<Node>>,
+ first_child: MutNullableJS<Node>,
/// The last child of this node.
- last_child: MutNullableHeap<JS<Node>>,
+ last_child: MutNullableJS<Node>,
/// The next sibling of this node.
- next_sibling: MutNullableHeap<JS<Node>>,
+ next_sibling: MutNullableJS<Node>,
/// The previous sibling of this node.
- prev_sibling: MutNullableHeap<JS<Node>>,
+ prev_sibling: MutNullableJS<Node>,
/// The document that this node belongs to.
- owner_doc: MutNullableHeap<JS<Document>>,
+ owner_doc: MutNullableJS<Document>,
/// The live list of children return by .childNodes.
- child_list: MutNullableHeap<JS<NodeList>>,
+ child_list: MutNullableJS<NodeList>,
/// The live count of children of this node.
children_count: Cell<u32>,
@@ -426,10 +426,6 @@ impl Node {
self.get_flag(HAS_DIRTY_DESCENDANTS)
}
- pub fn set_has_dirty_descendants(&self, state: bool) {
- self.set_flag(HAS_DIRTY_DESCENDANTS, state)
- }
-
pub fn rev_version(&self) {
// The new version counter is 1 plus the max of the node's current version counter,
// its descendants version, and the document's version. Normally, this will just be
@@ -1370,7 +1366,7 @@ impl Node {
last_child: Default::default(),
next_sibling: Default::default(),
prev_sibling: Default::default(),
- owner_doc: MutNullableHeap::new(doc),
+ owner_doc: MutNullableJS::new(doc),
child_list: Default::default(),
children_count: Cell::new(0u32),
flags: Cell::new(flags),
@@ -1788,12 +1784,16 @@ impl Node {
copy
}
+ /// https://html.spec.whatwg.org/multipage/#child-text-content
+ pub fn child_text_content(&self) -> DOMString {
+ Node::collect_text_contents(self.children())
+ }
+
pub fn collect_text_contents<T: Iterator<Item=Root<Node>>>(iterator: T) -> DOMString {
let mut content = String::new();
for node in iterator {
- match node.downcast::<Text>() {
- Some(ref text) => content.push_str(&text.upcast::<CharacterData>().data()),
- None => (),
+ if let Some(ref text) = node.downcast::<Text>() {
+ content.push_str(&text.upcast::<CharacterData>().data());
}
}
DOMString::from(content)
diff --git a/components/script/dom/nodeiterator.rs b/components/script/dom/nodeiterator.rs
index d9e46a5ea44..920d94d635c 100644
--- a/components/script/dom/nodeiterator.rs
+++ b/components/script/dom/nodeiterator.rs
@@ -9,7 +9,7 @@ use dom::bindings::codegen::Bindings::NodeFilterBinding::NodeFilterConstants;
use dom::bindings::codegen::Bindings::NodeIteratorBinding;
use dom::bindings::codegen::Bindings::NodeIteratorBinding::NodeIteratorMethods;
use dom::bindings::error::Fallible;
-use dom::bindings::js::{JS, MutHeap, Root};
+use dom::bindings::js::{JS, MutJS, Root};
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::document::Document;
use dom::node::Node;
@@ -21,7 +21,7 @@ pub struct NodeIterator {
reflector_: Reflector,
root_node: JS<Node>,
#[ignore_heap_size_of = "Defined in rust-mozjs"]
- reference_node: MutHeap<JS<Node>>,
+ reference_node: MutJS<Node>,
pointer_before_reference_node: Cell<bool>,
what_to_show: u32,
#[ignore_heap_size_of = "Can't measure due to #6870"]
@@ -35,7 +35,7 @@ impl NodeIterator {
NodeIterator {
reflector_: Reflector::new(),
root_node: JS::from_ref(root_node),
- reference_node: MutHeap::new(root_node),
+ reference_node: MutJS::new(root_node),
pointer_before_reference_node: Cell::new(true),
what_to_show: what_to_show,
filter: filter
@@ -79,7 +79,6 @@ impl NodeIteratorMethods for NodeIterator {
match self.filter {
Filter::None => None,
Filter::Callback(ref nf) => Some((*nf).clone()),
- Filter::Native(_) => panic!("Cannot convert native node filter to DOM NodeFilter")
}
}
@@ -200,7 +199,6 @@ impl NodeIterator {
// Step 3-5.
match self.filter {
Filter::None => Ok(NodeFilterConstants::FILTER_ACCEPT),
- Filter::Native(f) => Ok((f)(node)),
Filter::Callback(ref callback) => callback.AcceptNode_(self, node, Rethrow)
}
}
@@ -210,6 +208,5 @@ impl NodeIterator {
#[derive(JSTraceable)]
pub enum Filter {
None,
- Native(fn (node: &Node) -> u16),
Callback(Rc<NodeFilter>)
}
diff --git a/components/script/dom/nodelist.rs b/components/script/dom/nodelist.rs
index 391d21d5865..21e05fc7dcc 100644
--- a/components/script/dom/nodelist.rs
+++ b/components/script/dom/nodelist.rs
@@ -5,7 +5,7 @@
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::codegen::Bindings::NodeListBinding;
use dom::bindings::codegen::Bindings::NodeListBinding::NodeListMethods;
-use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference};
+use dom::bindings::js::{JS, MutNullableJS, Root, RootedReference};
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::node::{ChildrenMutation, Node};
use dom::window::Window;
@@ -111,7 +111,7 @@ impl NodeList {
pub struct ChildrenList {
node: JS<Node>,
#[ignore_heap_size_of = "Defined in rust-mozjs"]
- last_visited: MutNullableHeap<JS<Node>>,
+ last_visited: MutNullableJS<Node>,
last_index: Cell<u32>,
}
@@ -120,7 +120,7 @@ impl ChildrenList {
let last_visited = node.GetFirstChild();
ChildrenList {
node: JS::from_ref(node),
- last_visited: MutNullableHeap::new(last_visited.r()),
+ last_visited: MutNullableJS::new(last_visited.r()),
last_index: Cell::new(0u32),
}
}
diff --git a/components/script/dom/radionodelist.rs b/components/script/dom/radionodelist.rs
index 5cf05cb872a..b8078aa6670 100644
--- a/components/script/dom/radionodelist.rs
+++ b/components/script/dom/radionodelist.rs
@@ -40,10 +40,6 @@ impl RadioNodeList {
RadioNodeList::new(window, NodeListType::Simple(iter.map(|r| JS::from_ref(&*r)).collect()))
}
- pub fn empty(window: &Window) -> Root<RadioNodeList> {
- RadioNodeList::new(window, NodeListType::Simple(vec![]))
- }
-
// FIXME: This shouldn't need to be implemented here since NodeList (the parent of
// RadioNodeList) implements Length
// https://github.com/servo/servo/issues/5875
diff --git a/components/script/dom/range.rs b/components/script/dom/range.rs
index 723239ea3d3..e9e3a484d41 100644
--- a/components/script/dom/range.rs
+++ b/components/script/dom/range.rs
@@ -13,7 +13,7 @@ use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::error::{Error, ErrorResult, Fallible};
use dom::bindings::inheritance::{CharacterDataTypeId, NodeTypeId};
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, MutHeap, Root, RootedReference};
+use dom::bindings::js::{JS, MutJS, Root, RootedReference};
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::bindings::str::DOMString;
use dom::bindings::trace::JSTraceable;
@@ -934,7 +934,7 @@ impl RangeMethods for Range {
#[privatize]
#[derive(HeapSizeOf)]
pub struct BoundaryPoint {
- node: MutHeap<JS<Node>>,
+ node: MutJS<Node>,
offset: Cell<u32>,
}
@@ -943,7 +943,7 @@ impl BoundaryPoint {
debug_assert!(!node.is_doctype());
debug_assert!(offset <= node.len());
BoundaryPoint {
- node: MutHeap::new(node),
+ node: MutJS::new(node),
offset: Cell::new(offset),
}
}
diff --git a/components/script/dom/request.rs b/components/script/dom/request.rs
index cb338d65b29..8ca9104b945 100644
--- a/components/script/dom/request.rs
+++ b/components/script/dom/request.rs
@@ -17,7 +17,7 @@ use dom::bindings::codegen::Bindings::RequestBinding::RequestMode;
use dom::bindings::codegen::Bindings::RequestBinding::RequestRedirect;
use dom::bindings::codegen::Bindings::RequestBinding::RequestType;
use dom::bindings::error::{Error, Fallible};
-use dom::bindings::js::{JS, MutNullableHeap, Root};
+use dom::bindings::js::{MutNullableJS, Root};
use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object};
use dom::bindings::str::{ByteString, DOMString, USVString};
use dom::globalscope::GlobalScope;
@@ -45,7 +45,7 @@ pub struct Request {
reflector_: Reflector,
request: DOMRefCell<NetTraitsRequest>,
body_used: Cell<bool>,
- headers: MutNullableHeap<JS<Headers>>,
+ headers: MutNullableJS<Headers>,
mime_type: DOMRefCell<Vec<u8>>,
#[ignore_heap_size_of = "Rc"]
body_promise: DOMRefCell<Option<(Rc<Promise>, BodyType)>>,
@@ -92,8 +92,7 @@ impl Request {
let mut fallback_credentials: Option<NetTraitsRequestCredentials> = None;
// Step 4
- // TODO: `entry settings object` is not implemented in Servo yet.
- let base_url = global.get_url();
+ let base_url = global.api_base_url();
match input {
// Step 5
diff --git a/components/script/dom/response.rs b/components/script/dom/response.rs
index 278ead3c36d..1d9d62c079a 100644
--- a/components/script/dom/response.rs
+++ b/components/script/dom/response.rs
@@ -10,7 +10,7 @@ use dom::bindings::codegen::Bindings::ResponseBinding;
use dom::bindings::codegen::Bindings::ResponseBinding::{ResponseMethods, ResponseType as DOMResponseType};
use dom::bindings::codegen::Bindings::XMLHttpRequestBinding::BodyInit;
use dom::bindings::error::{Error, Fallible};
-use dom::bindings::js::{JS, MutNullableHeap, Root};
+use dom::bindings::js::{MutNullableJS, Root};
use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object};
use dom::bindings::str::{ByteString, USVString};
use dom::globalscope::GlobalScope;
@@ -32,7 +32,7 @@ use url::Position;
#[dom_struct]
pub struct Response {
reflector_: Reflector,
- headers_reflector: MutNullableHeap<JS<Headers>>,
+ headers_reflector: MutNullableJS<Headers>,
mime_type: DOMRefCell<Vec<u8>>,
body_used: Cell<bool>,
/// `None` can be considered a StatusCode of `0`.
@@ -149,8 +149,7 @@ impl Response {
// https://fetch.spec.whatwg.org/#dom-response-redirect
pub fn Redirect(global: &GlobalScope, url: USVString, status: u16) -> Fallible<Root<Response>> {
// Step 1
- // TODO: `entry settings object` is not implemented in Servo yet.
- let base_url = global.get_url();
+ let base_url = global.api_base_url();
let parsed_url = base_url.join(&url.0);
// Step 2
diff --git a/components/script/dom/serviceworkercontainer.rs b/components/script/dom/serviceworkercontainer.rs
index e5662f56dee..6757fc0179d 100644
--- a/components/script/dom/serviceworkercontainer.rs
+++ b/components/script/dom/serviceworkercontainer.rs
@@ -5,7 +5,7 @@
use dom::bindings::codegen::Bindings::ServiceWorkerContainerBinding::{ServiceWorkerContainerMethods, Wrap};
use dom::bindings::codegen::Bindings::ServiceWorkerContainerBinding::RegistrationOptions;
use dom::bindings::error::Error;
-use dom::bindings::js::{JS, MutNullableHeap, Root};
+use dom::bindings::js::{JS, MutNullableJS, Root};
use dom::bindings::reflector::{DomObject, reflect_dom_object};
use dom::bindings::str::USVString;
use dom::client::Client;
@@ -22,7 +22,7 @@ use std::rc::Rc;
#[dom_struct]
pub struct ServiceWorkerContainer {
eventtarget: EventTarget,
- controller: MutNullableHeap<JS<ServiceWorker>>,
+ controller: MutNullableJS<ServiceWorker>,
client: JS<Client>
}
diff --git a/components/script/dom/serviceworkerglobalscope.rs b/components/script/dom/serviceworkerglobalscope.rs
index 4daf07fff20..8dd3da01671 100644
--- a/components/script/dom/serviceworkerglobalscope.rs
+++ b/components/script/dom/serviceworkerglobalscope.rs
@@ -28,13 +28,12 @@ use net_traits::request::{CredentialsMode, Destination, RequestInit, Type as Req
use rand::random;
use script_runtime::{CommonScriptMsg, StackRootTLS, get_reports, new_rt_and_cx, ScriptChan};
use script_traits::{TimerEvent, WorkerGlobalScopeInit, ScopeThings, ServiceWorkerMsg, WorkerScriptLoadOrigin};
+use servo_config::prefs::PREFS;
use servo_url::ServoUrl;
use std::sync::mpsc::{Receiver, RecvError, Select, Sender, channel};
use std::thread;
use std::time::Duration;
use style::thread_state::{self, IN_WORKER, SCRIPT};
-use util::prefs::PREFS;
-use util::thread::spawn_named;
/// Messages used to control service worker event loop
pub enum ServiceWorkerScriptMsg {
@@ -151,7 +150,7 @@ impl ServiceWorkerGlobalScope {
.. } = scope_things;
let serialized_worker_url = script_url.to_string();
- spawn_named(format!("ServiceWorker for {}", serialized_worker_url), move || {
+ thread::Builder::new().name(format!("ServiceWorker for {}", serialized_worker_url)).spawn(move || {
thread_state::initialize(SCRIPT | IN_WORKER);
let roots = RootCollection::new();
let _stack_roots_tls = StackRootTLS::new(&roots);
@@ -202,11 +201,11 @@ impl ServiceWorkerGlobalScope {
scope.execute_script(DOMString::from(source));
// Service workers are time limited
- spawn_named("SWTimeoutThread".to_owned(), move || {
+ thread::Builder::new().name("SWTimeoutThread".to_owned()).spawn(move || {
let sw_lifetime_timeout = PREFS.get("dom.serviceworker.timeout_seconds").as_u64().unwrap();
thread::sleep(Duration::new(sw_lifetime_timeout, 0));
let _ = timer_chan.send(());
- });
+ }).expect("Thread spawning failed");
global.dispatch_activate();
let reporter_name = format!("service-worker-reporter-{}", random::<u64>());
@@ -217,7 +216,7 @@ impl ServiceWorkerGlobalScope {
}
}
}, reporter_name, scope.script_chan(), CommonScriptMsg::CollectReports);
- });
+ }).expect("Thread spawning failed");
}
fn handle_event(&self, event: MixedMessage) -> bool {
diff --git a/components/script/dom/servoparser/html.rs b/components/script/dom/servoparser/html.rs
index ac6330c3ca2..28f8735891e 100644
--- a/components/script/dom/servoparser/html.rs
+++ b/components/script/dom/servoparser/html.rs
@@ -34,6 +34,7 @@ use js::jsapi::JSTracer;
use servo_url::ServoUrl;
use std::borrow::Cow;
use std::io::{self, Write};
+use style::context::QuirksMode as ServoQuirksMode;
#[derive(HeapSizeOf, JSTraceable)]
#[must_root]
@@ -187,6 +188,11 @@ impl<'a> TreeSink for Sink {
}
fn set_quirks_mode(&mut self, mode: QuirksMode) {
+ let mode = match mode {
+ QuirksMode::Quirks => ServoQuirksMode::Quirks,
+ QuirksMode::LimitedQuirks => ServoQuirksMode::LimitedQuirks,
+ QuirksMode::NoQuirks => ServoQuirksMode::NoQuirks,
+ };
self.document.set_quirks_mode(mode);
}
diff --git a/components/script/dom/servoparser/mod.rs b/components/script/dom/servoparser/mod.rs
index c6f4364925b..2f4f485be12 100644
--- a/components/script/dom/servoparser/mod.rs
+++ b/components/script/dom/servoparser/mod.rs
@@ -32,10 +32,10 @@ use network_listener::PreInvoke;
use profile_traits::time::{TimerMetadata, TimerMetadataFrameType};
use profile_traits::time::{TimerMetadataReflowType, ProfilerCategory, profile};
use script_thread::ScriptThread;
+use servo_config::resource_files::read_resource_file;
use servo_url::ServoUrl;
use std::cell::Cell;
use std::mem;
-use util::resource_files::read_resource_file;
mod html;
mod xml;
diff --git a/components/script/dom/servoparser/xml.rs b/components/script/dom/servoparser/xml.rs
index bcbfa6c4169..616263651c3 100644
--- a/components/script/dom/servoparser/xml.rs
+++ b/components/script/dom/servoparser/xml.rs
@@ -6,7 +6,7 @@
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, MutNullableHeap, Root};
+use dom::bindings::js::{JS, MutNullableJS, Root};
use dom::bindings::str::DOMString;
use dom::bindings::trace::JSTraceable;
use dom::comment::Comment;
@@ -97,7 +97,7 @@ unsafe impl JSTraceable for XmlTokenizer<XmlTreeBuilder<JS<Node>, Sink>> {
struct Sink {
base_url: ServoUrl,
document: JS<Document>,
- script: MutNullableHeap<JS<HTMLScriptElement>>,
+ script: MutNullableJS<HTMLScriptElement>,
}
impl<'a> TreeSink for Sink {
diff --git a/components/script/dom/storageevent.rs b/components/script/dom/storageevent.rs
index 172a7be9ed8..9778976dc0f 100644
--- a/components/script/dom/storageevent.rs
+++ b/components/script/dom/storageevent.rs
@@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::StorageEventBinding;
use dom::bindings::codegen::Bindings::StorageEventBinding::StorageEventMethods;
use dom::bindings::error::Fallible;
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference};
+use dom::bindings::js::{MutNullableJS, Root, RootedReference};
use dom::bindings::reflector::reflect_dom_object;
use dom::bindings::str::DOMString;
use dom::event::{Event, EventBubbles, EventCancelable};
@@ -23,7 +23,7 @@ pub struct StorageEvent {
old_value: Option<DOMString>,
new_value: Option<DOMString>,
url: DOMString,
- storage_area: MutNullableHeap<JS<Storage>>
+ storage_area: MutNullableJS<Storage>
}
@@ -39,7 +39,7 @@ impl StorageEvent {
old_value: old_value,
new_value: new_value,
url: url,
- storage_area: MutNullableHeap::new(storage_area)
+ storage_area: MutNullableJS::new(storage_area)
}
}
diff --git a/components/script/dom/svgelement.rs b/components/script/dom/svgelement.rs
index c89bab166ee..3a18f965ecc 100644
--- a/components/script/dom/svgelement.rs
+++ b/components/script/dom/svgelement.rs
@@ -2,13 +2,10 @@
* 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::SVGElementBinding;
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::Root;
use dom::bindings::str::DOMString;
use dom::document::Document;
use dom::element::Element;
-use dom::node::Node;
use dom::virtualmethods::VirtualMethods;
use html5ever_atoms::LocalName;
use style::element_state::ElementState;
@@ -19,11 +16,6 @@ pub struct SVGElement {
}
impl SVGElement {
- pub fn new_inherited(tag_name: LocalName, prefix: Option<DOMString>,
- document: &Document) -> SVGElement {
- SVGElement::new_inherited_with_state(ElementState::empty(), tag_name, prefix, document)
- }
-
pub fn new_inherited_with_state(state: ElementState, tag_name: LocalName,
prefix: Option<DOMString>, document: &Document)
-> SVGElement {
@@ -32,13 +24,6 @@ impl SVGElement {
Element::new_inherited_with_state(state, tag_name, ns!(svg), prefix, document),
}
}
-
- #[allow(unrooted_must_root)]
- pub fn new(local_name: LocalName, prefix: Option<DOMString>, document: &Document) -> Root<SVGElement> {
- Node::reflect_node(box SVGElement::new_inherited(local_name, prefix, document),
- document,
- SVGElementBinding::Wrap)
- }
}
impl VirtualMethods for SVGElement {
diff --git a/components/script/dom/svggraphicselement.rs b/components/script/dom/svggraphicselement.rs
index 9435cc6d6b7..b8e8aced371 100644
--- a/components/script/dom/svggraphicselement.rs
+++ b/components/script/dom/svggraphicselement.rs
@@ -2,12 +2,9 @@
* 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::SVGGraphicsElementBinding;
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::Root;
use dom::bindings::str::DOMString;
use dom::document::Document;
-use dom::node::Node;
use dom::svgelement::SVGElement;
use dom::virtualmethods::VirtualMethods;
use html5ever_atoms::LocalName;
@@ -32,13 +29,6 @@ impl SVGGraphicsElement {
SVGElement::new_inherited_with_state(state, tag_name, prefix, document),
}
}
-
- #[allow(unrooted_must_root)]
- pub fn new(local_name: LocalName, prefix: Option<DOMString>, document: &Document) -> Root<SVGGraphicsElement> {
- Node::reflect_node(box SVGGraphicsElement::new_inherited(local_name, prefix, document),
- document,
- SVGGraphicsElementBinding::Wrap)
- }
}
impl VirtualMethods for SVGGraphicsElement {
diff --git a/components/script/dom/testbinding.rs b/components/script/dom/testbinding.rs
index 6b0c619749a..9f65d04bbfa 100644
--- a/components/script/dom/testbinding.rs
+++ b/components/script/dom/testbinding.rs
@@ -37,11 +37,11 @@ use js::jsapi::{HandleObject, HandleValue, JSContext, JSObject, JSAutoCompartmen
use js::jsapi::{JS_NewPlainObject, JS_NewUint8ClampedArray};
use js::jsval::{JSVal, NullValue};
use script_traits::MsDuration;
+use servo_config::prefs::PREFS;
use std::borrow::ToOwned;
use std::ptr;
use std::rc::Rc;
use timers::OneshotTimerCallback;
-use util::prefs::PREFS;
#[dom_struct]
pub struct TestBinding {
diff --git a/components/script/dom/touch.rs b/components/script/dom/touch.rs
index 32eeb24b6e1..9b4e61788d3 100644
--- a/components/script/dom/touch.rs
+++ b/components/script/dom/touch.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::Bindings::TouchBinding;
use dom::bindings::codegen::Bindings::TouchBinding::TouchMethods;
-use dom::bindings::js::{JS, MutHeap, Root};
+use dom::bindings::js::{MutJS, Root};
use dom::bindings::num::Finite;
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::eventtarget::EventTarget;
@@ -14,7 +14,7 @@ use dom::window::Window;
pub struct Touch {
reflector_: Reflector,
identifier: i32,
- target: MutHeap<JS<EventTarget>>,
+ target: MutJS<EventTarget>,
screen_x: f64,
screen_y: f64,
client_x: f64,
@@ -31,7 +31,7 @@ impl Touch {
Touch {
reflector_: Reflector::new(),
identifier: identifier,
- target: MutHeap::new(target),
+ target: MutJS::new(target),
screen_x: *screen_x,
screen_y: *screen_y,
client_x: *client_x,
diff --git a/components/script/dom/touchevent.rs b/components/script/dom/touchevent.rs
index 9b4b3a250d5..f20dc4dc012 100644
--- a/components/script/dom/touchevent.rs
+++ b/components/script/dom/touchevent.rs
@@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::TouchEventBinding;
use dom::bindings::codegen::Bindings::TouchEventBinding::TouchEventMethods;
use dom::bindings::codegen::Bindings::UIEventBinding::UIEventMethods;
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, MutHeap, Root};
+use dom::bindings::js::{MutJS, Root};
use dom::bindings::reflector::reflect_dom_object;
use dom::bindings::str::DOMString;
use dom::event::{EventBubbles, EventCancelable};
@@ -18,9 +18,9 @@ use std::cell::Cell;
#[dom_struct]
pub struct TouchEvent {
uievent: UIEvent,
- touches: MutHeap<JS<TouchList>>,
- target_touches: MutHeap<JS<TouchList>>,
- changed_touches: MutHeap<JS<TouchList>>,
+ touches: MutJS<TouchList>,
+ target_touches: MutJS<TouchList>,
+ changed_touches: MutJS<TouchList>,
alt_key: Cell<bool>,
meta_key: Cell<bool>,
ctrl_key: Cell<bool>,
@@ -33,9 +33,9 @@ impl TouchEvent {
target_touches: &TouchList) -> TouchEvent {
TouchEvent {
uievent: UIEvent::new_inherited(),
- touches: MutHeap::new(touches),
- target_touches: MutHeap::new(target_touches),
- changed_touches: MutHeap::new(changed_touches),
+ touches: MutJS::new(touches),
+ target_touches: MutJS::new(target_touches),
+ changed_touches: MutJS::new(changed_touches),
ctrl_key: Cell::new(false),
shift_key: Cell::new(false),
alt_key: Cell::new(false),
diff --git a/components/script/dom/treewalker.rs b/components/script/dom/treewalker.rs
index 1dc3d22f1cf..2a3367b3393 100644
--- a/components/script/dom/treewalker.rs
+++ b/components/script/dom/treewalker.rs
@@ -9,7 +9,7 @@ use dom::bindings::codegen::Bindings::NodeFilterBinding::NodeFilterConstants;
use dom::bindings::codegen::Bindings::TreeWalkerBinding;
use dom::bindings::codegen::Bindings::TreeWalkerBinding::TreeWalkerMethods;
use dom::bindings::error::Fallible;
-use dom::bindings::js::{JS, MutHeap};
+use dom::bindings::js::{JS, MutJS};
use dom::bindings::js::Root;
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::document::Document;
@@ -21,7 +21,7 @@ use std::rc::Rc;
pub struct TreeWalker {
reflector_: Reflector,
root_node: JS<Node>,
- current_node: MutHeap<JS<Node>>,
+ current_node: MutJS<Node>,
what_to_show: u32,
#[ignore_heap_size_of = "function pointers and Rc<T> are hard"]
filter: Filter
@@ -34,7 +34,7 @@ impl TreeWalker {
TreeWalker {
reflector_: Reflector::new(),
root_node: JS::from_ref(root_node),
- current_node: MutHeap::new(root_node),
+ current_node: MutJS::new(root_node),
what_to_show: what_to_show,
filter: filter
}
@@ -251,9 +251,6 @@ impl TreeWalkerMethods for TreeWalker {
}
}
-type NodeAdvancer<'a> = Fn(&Node) -> Option<Root<Node>> + 'a;
-
-
impl TreeWalker {
// https://dom.spec.whatwg.org/#concept-traverse-children
fn traverse_children<F, G>(&self,
diff --git a/components/script/dom/uievent.rs b/components/script/dom/uievent.rs
index 289088b2977..b8c09a48994 100644
--- a/components/script/dom/uievent.rs
+++ b/components/script/dom/uievent.rs
@@ -7,8 +7,7 @@ use dom::bindings::codegen::Bindings::UIEventBinding;
use dom::bindings::codegen::Bindings::UIEventBinding::UIEventMethods;
use dom::bindings::error::Fallible;
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, MutNullableHeap, RootedReference};
-use dom::bindings::js::Root;
+use dom::bindings::js::{MutNullableJS, Root, RootedReference};
use dom::bindings::reflector::reflect_dom_object;
use dom::bindings::str::DOMString;
use dom::event::{Event, EventBubbles, EventCancelable};
@@ -21,7 +20,7 @@ use std::default::Default;
#[dom_struct]
pub struct UIEvent {
event: Event,
- view: MutNullableHeap<JS<Window>>,
+ view: MutNullableJS<Window>,
detail: Cell<i32>
}
diff --git a/components/script/dom/url.rs b/components/script/dom/url.rs
index 2f3e3c3f923..cea4c898119 100644
--- a/components/script/dom/url.rs
+++ b/components/script/dom/url.rs
@@ -6,7 +6,7 @@ use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::BlobBinding::BlobMethods;
use dom::bindings::codegen::Bindings::URLBinding::{self, URLMethods};
use dom::bindings::error::{Error, ErrorResult, Fallible};
-use dom::bindings::js::{JS, MutNullableHeap, Root};
+use dom::bindings::js::{MutNullableJS, Root};
use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object};
use dom::bindings::str::{DOMString, USVString};
use dom::blob::Blob;
@@ -30,7 +30,7 @@ pub struct URL {
url: DOMRefCell<ServoUrl>,
// https://url.spec.whatwg.org/#dom-url-searchparams
- search_params: MutNullableHeap<JS<URLSearchParams>>,
+ search_params: MutNullableJS<URLSearchParams>,
}
impl URL {
diff --git a/components/script/dom/userscripts.rs b/components/script/dom/userscripts.rs
index a4051f44581..66758afaa98 100644
--- a/components/script/dom/userscripts.rs
+++ b/components/script/dom/userscripts.rs
@@ -9,11 +9,11 @@ use dom::bindings::js::RootedReference;
use dom::bindings::str::DOMString;
use dom::htmlheadelement::HTMLHeadElement;
use dom::node::Node;
+use servo_config::opts;
+use servo_config::resource_files::resources_dir_path;
use std::borrow::ToOwned;
use std::fs::read_dir;
use std::path::PathBuf;
-use util::opts;
-use util::resource_files::resources_dir_path;
pub fn load_script(head: &HTMLHeadElement) {
diff --git a/components/script/dom/validitystate.rs b/components/script/dom/validitystate.rs
index 10801120871..f5b6501a82d 100755
--- a/components/script/dom/validitystate.rs
+++ b/components/script/dom/validitystate.rs
@@ -10,8 +10,8 @@ use dom::element::Element;
use dom::window::Window;
// https://html.spec.whatwg.org/multipage/#validity-states
-#[derive(JSTraceable)]
-#[derive(HeapSizeOf)]
+#[derive(JSTraceable, HeapSizeOf)]
+#[allow(dead_code)]
pub enum ValidityStatus {
ValueMissing,
TypeMismatch,
diff --git a/components/script/dom/webglframebuffer.rs b/components/script/dom/webglframebuffer.rs
index 02a767958e2..2f18362122d 100644
--- a/components/script/dom/webglframebuffer.rs
+++ b/components/script/dom/webglframebuffer.rs
@@ -7,7 +7,7 @@ use canvas_traits::CanvasMsg;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::WebGLFramebufferBinding;
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
-use dom::bindings::js::{HeapGCValue, JS, Root};
+use dom::bindings::js::{JS, Root};
use dom::bindings::reflector::reflect_dom_object;
use dom::webglobject::WebGLObject;
use dom::webglrenderbuffer::WebGLRenderbuffer;
@@ -25,8 +25,6 @@ enum WebGLFramebufferAttachment {
Texture { texture: JS<WebGLTexture>, level: i32 },
}
-impl HeapGCValue for WebGLFramebufferAttachment {}
-
#[dom_struct]
pub struct WebGLFramebuffer {
webgl_object: WebGLObject,
diff --git a/components/script/dom/webglobject.rs b/components/script/dom/webglobject.rs
index 9c7382ce5b5..3ebbf8fb017 100644
--- a/components/script/dom/webglobject.rs
+++ b/components/script/dom/webglobject.rs
@@ -3,10 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
-use dom::bindings::codegen::Bindings::WebGLObjectBinding;
-use dom::bindings::js::Root;
-use dom::bindings::reflector::{Reflector, reflect_dom_object};
-use dom::window::Window;
+use dom::bindings::reflector::Reflector;
#[dom_struct]
pub struct WebGLObject {
@@ -19,8 +16,4 @@ impl WebGLObject {
reflector_: Reflector::new(),
}
}
-
- pub fn new(window: &Window) -> Root<WebGLObject> {
- reflect_dom_object(box WebGLObject::new_inherited(), window, WebGLObjectBinding::Wrap)
- }
}
diff --git a/components/script/dom/webglprogram.rs b/components/script/dom/webglprogram.rs
index 3f18c0e313b..ad33fc2f22f 100644
--- a/components/script/dom/webglprogram.rs
+++ b/components/script/dom/webglprogram.rs
@@ -6,7 +6,7 @@
use canvas_traits::CanvasMsg;
use dom::bindings::codegen::Bindings::WebGLProgramBinding;
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
-use dom::bindings::js::{JS, MutNullableHeap, Root};
+use dom::bindings::js::{MutNullableJS, Root};
use dom::bindings::reflector::{DomObject, reflect_dom_object};
use dom::bindings::str::DOMString;
use dom::webglactiveinfo::WebGLActiveInfo;
@@ -27,8 +27,8 @@ pub struct WebGLProgram {
is_deleted: Cell<bool>,
link_called: Cell<bool>,
linked: Cell<bool>,
- fragment_shader: MutNullableHeap<JS<WebGLShader>>,
- vertex_shader: MutNullableHeap<JS<WebGLShader>>,
+ fragment_shader: MutNullableJS<WebGLShader>,
+ vertex_shader: MutNullableJS<WebGLShader>,
#[ignore_heap_size_of = "Defined in ipc-channel"]
renderer: IpcSender<CanvasMsg>,
}
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs
index 98b160095d5..81dfe804278 100644
--- a/components/script/dom/webglrenderingcontext.rs
+++ b/components/script/dom/webglrenderingcontext.rs
@@ -13,7 +13,7 @@ use dom::bindings::conversions::{array_buffer_to_vec, array_buffer_view_data, ar
use dom::bindings::conversions::{array_buffer_view_to_vec, array_buffer_view_to_vec_checked};
use dom::bindings::error::{Error, Fallible};
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root};
+use dom::bindings::js::{JS, LayoutJS, MutNullableJS, Root};
use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object};
use dom::bindings::str::DOMString;
use dom::event::{Event, EventBubbles, EventCancelable};
@@ -124,13 +124,13 @@ pub struct WebGLRenderingContext {
#[ignore_heap_size_of = "Defined in webrender_traits"]
last_error: Cell<Option<WebGLError>>,
texture_unpacking_settings: Cell<TextureUnpacking>,
- bound_framebuffer: MutNullableHeap<JS<WebGLFramebuffer>>,
- bound_renderbuffer: MutNullableHeap<JS<WebGLRenderbuffer>>,
- bound_texture_2d: MutNullableHeap<JS<WebGLTexture>>,
- bound_texture_cube_map: MutNullableHeap<JS<WebGLTexture>>,
- bound_buffer_array: MutNullableHeap<JS<WebGLBuffer>>,
- bound_buffer_element_array: MutNullableHeap<JS<WebGLBuffer>>,
- current_program: MutNullableHeap<JS<WebGLProgram>>,
+ bound_framebuffer: MutNullableJS<WebGLFramebuffer>,
+ bound_renderbuffer: MutNullableJS<WebGLRenderbuffer>,
+ bound_texture_2d: MutNullableJS<WebGLTexture>,
+ bound_texture_cube_map: MutNullableJS<WebGLTexture>,
+ bound_buffer_array: MutNullableJS<WebGLBuffer>,
+ bound_buffer_element_array: MutNullableJS<WebGLBuffer>,
+ current_program: MutNullableJS<WebGLProgram>,
#[ignore_heap_size_of = "Because it's small"]
current_vertex_attrib_0: Cell<(f32, f32, f32, f32)>,
#[ignore_heap_size_of = "Because it's small"]
@@ -159,13 +159,13 @@ impl WebGLRenderingContext {
canvas: JS::from_ref(canvas),
last_error: Cell::new(None),
texture_unpacking_settings: Cell::new(CONVERT_COLORSPACE),
- bound_framebuffer: MutNullableHeap::new(None),
- bound_texture_2d: MutNullableHeap::new(None),
- bound_texture_cube_map: MutNullableHeap::new(None),
- bound_buffer_array: MutNullableHeap::new(None),
- bound_buffer_element_array: MutNullableHeap::new(None),
- bound_renderbuffer: MutNullableHeap::new(None),
- current_program: MutNullableHeap::new(None),
+ bound_framebuffer: MutNullableJS::new(None),
+ bound_texture_2d: MutNullableJS::new(None),
+ bound_texture_cube_map: MutNullableJS::new(None),
+ bound_buffer_array: MutNullableJS::new(None),
+ bound_buffer_element_array: MutNullableJS::new(None),
+ bound_renderbuffer: MutNullableJS::new(None),
+ current_program: MutNullableJS::new(None),
current_vertex_attrib_0: Cell::new((0f32, 0f32, 0f32, 1f32)),
current_scissor: Cell::new((0, 0, size.width, size.height)),
current_clear_color: Cell::new((0.0, 0.0, 0.0, 0.0))
@@ -2829,39 +2829,4 @@ impl UniformSetterType {
UniformSetterType::FloatMat4 => 16,
}
}
-
- pub fn is_compatible_with(&self, gl_type: u32) -> bool {
- gl_type == self.as_gl_constant() || match *self {
- // Sampler uniform variables have an index value (the index of the
- // texture), and as such they have to be set as ints
- UniformSetterType::Int => gl_type == constants::SAMPLER_2D ||
- gl_type == constants::SAMPLER_CUBE,
- // Don't ask me why, but it seems we must allow setting bool
- // uniforms with uniform1f.
- //
- // See the WebGL conformance test
- // conformance/uniforms/gl-uniform-bool.html
- UniformSetterType::Float => gl_type == constants::BOOL,
- UniformSetterType::FloatVec2 => gl_type == constants::BOOL_VEC2,
- UniformSetterType::FloatVec3 => gl_type == constants::BOOL_VEC3,
- UniformSetterType::FloatVec4 => gl_type == constants::BOOL_VEC4,
- _ => false,
- }
- }
-
- fn as_gl_constant(&self) -> u32 {
- match *self {
- UniformSetterType::Int => constants::INT,
- UniformSetterType::IntVec2 => constants::INT_VEC2,
- UniformSetterType::IntVec3 => constants::INT_VEC3,
- UniformSetterType::IntVec4 => constants::INT_VEC4,
- UniformSetterType::Float => constants::FLOAT,
- UniformSetterType::FloatVec2 => constants::FLOAT_VEC2,
- UniformSetterType::FloatVec3 => constants::FLOAT_VEC3,
- UniformSetterType::FloatVec4 => constants::FLOAT_VEC4,
- UniformSetterType::FloatMat2 => constants::FLOAT_MAT2,
- UniformSetterType::FloatMat3 => constants::FLOAT_MAT3,
- UniformSetterType::FloatMat4 => constants::FLOAT_MAT4,
- }
- }
}
diff --git a/components/script/dom/webglshaderprecisionformat.rs b/components/script/dom/webglshaderprecisionformat.rs
index c0f954c8d4d..87ab7490e3a 100644
--- a/components/script/dom/webglshaderprecisionformat.rs
+++ b/components/script/dom/webglshaderprecisionformat.rs
@@ -2,6 +2,8 @@
* 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/. */
+#![allow(dead_code)]
+
// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
use dom::bindings::codegen::Bindings::WebGLShaderPrecisionFormatBinding;
use dom::bindings::codegen::Bindings::WebGLShaderPrecisionFormatBinding::WebGLShaderPrecisionFormatMethods;
diff --git a/components/script/dom/webidls/BluetoothAdvertisingData.webidl b/components/script/dom/webidls/BluetoothAdvertisingEvent.webidl
index 27583a95e4e..2bb88b6f9de 100644
--- a/components/script/dom/webidls/BluetoothAdvertisingData.webidl
+++ b/components/script/dom/webidls/BluetoothAdvertisingEvent.webidl
@@ -2,21 +2,32 @@
* 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://webbluetoothcg.github.io/web-bluetooth/#bluetoothadvertisingdata
+// https://webbluetoothcg.github.io/web-bluetooth/#advertising-events
/*interface BluetoothManufacturerDataMap {
readonly maplike<unsigned short, DataView>;
};
-
interface BluetoothServiceDataMap {
readonly maplike<UUID, DataView>;
};*/
-
-[Pref="dom.bluetooth.enabled"]
-interface BluetoothAdvertisingData {
+[Pref="dom.bluetooth.enabled", Constructor(DOMString type, BluetoothAdvertisingEventInit init)]
+interface BluetoothAdvertisingEvent : Event {
+ readonly attribute BluetoothDevice device;
+ // readonly attribute FrozenArray<UUID> uuids;
+ readonly attribute DOMString? name;
readonly attribute unsigned short? appearance;
readonly attribute byte? txPower;
readonly attribute byte? rssi;
// readonly attribute BluetoothManufacturerDataMap manufacturerData;
// readonly attribute BluetoothServiceDataMap serviceData;
};
+dictionary BluetoothAdvertisingEventInit : EventInit {
+ required BluetoothDevice device;
+ // sequence<(DOMString or unsigned long)> uuids;
+ DOMString name;
+ unsigned short appearance;
+ byte txPower;
+ byte rssi;
+ // Map manufacturerData;
+ // Map serviceData;
+};
diff --git a/components/script/dom/webidls/BluetoothDevice.webidl b/components/script/dom/webidls/BluetoothDevice.webidl
index 0e7843db109..a68049dd08b 100644
--- a/components/script/dom/webidls/BluetoothDevice.webidl
+++ b/components/script/dom/webidls/BluetoothDevice.webidl
@@ -8,13 +8,11 @@
interface BluetoothDevice : EventTarget {
readonly attribute DOMString id;
readonly attribute DOMString? name;
- // TODO: remove this after BluetoothAdvertisingEvent implemented.
- readonly attribute BluetoothAdvertisingData adData;
readonly attribute BluetoothRemoteGATTServer gatt;
- // Promise<void> watchAdvertisements();
- // void unwatchAdvertisements();
- // readonly attribute boolean watchingAdvertisements;
+ Promise<void> watchAdvertisements();
+ void unwatchAdvertisements();
+ readonly attribute boolean watchingAdvertisements;
};
[NoInterfaceObject]
diff --git a/components/script/dom/webidls/CSSGroupingRule.webidl b/components/script/dom/webidls/CSSGroupingRule.webidl
index 9f8347a17d5..41ac5e8dd57 100644
--- a/components/script/dom/webidls/CSSGroupingRule.webidl
+++ b/components/script/dom/webidls/CSSGroupingRule.webidl
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://drafts.csswg.org/cssom/#the-cssgroupingrule-interface
-[Exposed=Window]
+[Abstract, Exposed=Window]
interface CSSGroupingRule : CSSRule {
[SameObject] readonly attribute CSSRuleList cssRules;
[Throws] unsigned long insertRule(DOMString rule, unsigned long index);
diff --git a/components/script/dom/webidls/CSSImportRule.webidl b/components/script/dom/webidls/CSSImportRule.webidl
new file mode 100644
index 00000000000..b8131a7bb87
--- /dev/null
+++ b/components/script/dom/webidls/CSSImportRule.webidl
@@ -0,0 +1,11 @@
+/* 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://drafts.csswg.org/cssom/#cssimportrule
+[Exposed=Window]
+interface CSSImportRule : CSSRule {
+ // readonly attribute DOMString href;
+ // [SameObject, PutForwards=mediaText] readonly attribute MediaList media;
+ // [SameObject] readonly attribute CSSStyleSheet styleSheet;
+};
diff --git a/components/script/dom/webidls/CSSKeyframesRule.webidl b/components/script/dom/webidls/CSSKeyframesRule.webidl
index 34d45e1a357..fc31fc62406 100644
--- a/components/script/dom/webidls/CSSKeyframesRule.webidl
+++ b/components/script/dom/webidls/CSSKeyframesRule.webidl
@@ -5,7 +5,8 @@
// https://drafts.csswg.org/css-animations/#interface-csskeyframesrule
[Exposed=Window]
interface CSSKeyframesRule : CSSRule {
- // attribute DOMString name;
+ [SetterThrows]
+ attribute DOMString name;
readonly attribute CSSRuleList cssRules;
void appendRule(DOMString rule);
diff --git a/components/script/dom/webidls/CSSRule.webidl b/components/script/dom/webidls/CSSRule.webidl
index 462943430e6..cda06ab1254 100644
--- a/components/script/dom/webidls/CSSRule.webidl
+++ b/components/script/dom/webidls/CSSRule.webidl
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://drafts.csswg.org/cssom/#the-cssrule-interface
-[Exposed=Window]
+[Abstract, Exposed=Window]
interface CSSRule {
const unsigned short STYLE_RULE = 1;
const unsigned short CHARSET_RULE = 2; // historical
diff --git a/components/script/dom/webidls/CSSStyleDeclaration.webidl b/components/script/dom/webidls/CSSStyleDeclaration.webidl
index 4314eca74f9..c32e9afddfc 100644
--- a/components/script/dom/webidls/CSSStyleDeclaration.webidl
+++ b/components/script/dom/webidls/CSSStyleDeclaration.webidl
@@ -38,6 +38,10 @@ partial interface CSSStyleDeclaration {
[SetterThrows, TreatNullAs=EmptyString] attribute DOMString background-color;
[SetterThrows, TreatNullAs=EmptyString] attribute DOMString backgroundPosition;
[SetterThrows, TreatNullAs=EmptyString] attribute DOMString background-position;
+ [SetterThrows, TreatNullAs=EmptyString] attribute DOMString backgroundPositionX;
+ [SetterThrows, TreatNullAs=EmptyString] attribute DOMString background-position-x;
+ [SetterThrows, TreatNullAs=EmptyString] attribute DOMString backgroundPositionY;
+ [SetterThrows, TreatNullAs=EmptyString] attribute DOMString background-position-y;
[SetterThrows, TreatNullAs=EmptyString] attribute DOMString backgroundRepeat;
[SetterThrows, TreatNullAs=EmptyString] attribute DOMString background-repeat;
[SetterThrows, TreatNullAs=EmptyString] attribute DOMString backgroundImage;
diff --git a/components/script/dom/webidls/CSSStyleRule.webidl b/components/script/dom/webidls/CSSStyleRule.webidl
index faee525e7ff..145650a916c 100644
--- a/components/script/dom/webidls/CSSStyleRule.webidl
+++ b/components/script/dom/webidls/CSSStyleRule.webidl
@@ -6,5 +6,5 @@
[Exposed=Window]
interface CSSStyleRule : CSSRule {
// attribute DOMString selectorText;
- // [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style;
+ [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style;
};
diff --git a/components/script/dom/webidls/MediaQueryListEvent.webidl b/components/script/dom/webidls/MediaQueryListEvent.webidl
new file mode 100644
index 00000000000..877ca17b60b
--- /dev/null
+++ b/components/script/dom/webidls/MediaQueryListEvent.webidl
@@ -0,0 +1,15 @@
+/* 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://drafts.csswg.org/cssom-view/#dom-mediaquerylistevent-mediaquerylistevent
+[Constructor(DOMString type, optional MediaQueryListEventInit eventInitDict), Exposed=(Window)]
+interface MediaQueryListEvent : Event {
+ readonly attribute DOMString media;
+ readonly attribute boolean matches;
+};
+
+dictionary MediaQueryListEventInit : EventInit {
+ DOMString media = "";
+ boolean matches = false;
+};
diff --git a/components/script/dom/webidls/SVGElement.webidl b/components/script/dom/webidls/SVGElement.webidl
index 02f673a420e..529e9e67f06 100644
--- a/components/script/dom/webidls/SVGElement.webidl
+++ b/components/script/dom/webidls/SVGElement.webidl
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://svgwg.org/svg2-draft/types.html#InterfaceSVGElement
-[Pref="dom.svg.enabled"]
+[Abstract, Pref="dom.svg.enabled"]
interface SVGElement : Element {
//[SameObject] readonly attribute SVGAnimatedString className;
diff --git a/components/script/dom/webidls/SVGGraphicsElement.webidl b/components/script/dom/webidls/SVGGraphicsElement.webidl
index d8f90e639ea..cf6c315d917 100644
--- a/components/script/dom/webidls/SVGGraphicsElement.webidl
+++ b/components/script/dom/webidls/SVGGraphicsElement.webidl
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://svgwg.org/svg2-draft/types.html#InterfaceSVGGraphicsElement
-[Pref="dom.svg.enabled"]
//dictionary SVGBoundingBoxOptions {
// boolean fill = true;
// boolean stroke = false;
@@ -11,6 +10,7 @@
// boolean clipped = false;
//};
+[Abstract, Pref="dom.svg.enabled"]
interface SVGGraphicsElement : SVGElement {
//[SameObject] readonly attribute SVGAnimatedTransformList transform;
diff --git a/components/script/dom/webidls/WebGLObject.webidl b/components/script/dom/webidls/WebGLObject.webidl
index 3ac7514830a..3e8f1f54cca 100644
--- a/components/script/dom/webidls/WebGLObject.webidl
+++ b/components/script/dom/webidls/WebGLObject.webidl
@@ -6,6 +6,6 @@
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.3
//
-[Exposed=Window]
+[Abstract, Exposed=Window]
interface WebGLObject {
};
diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs
index 0953f7898a2..b2057e7effe 100644
--- a/components/script/dom/websocket.rs
+++ b/components/script/dom/websocket.rs
@@ -22,6 +22,8 @@ use dom::eventtarget::EventTarget;
use dom::globalscope::GlobalScope;
use dom::messageevent::MessageEvent;
use dom::urlhelper::UrlHelper;
+use hyper;
+use hyper_serde::Serde;
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use js::jsapi::{JS_GetArrayBufferData, JS_NewArrayBuffer};
use js::jsapi::JSAutoCompartment;
@@ -496,13 +498,10 @@ impl Runnable for ConnectionEstablishedTask {
};
// Step 5: Cookies.
- if let Some(cookies) = self.headers.get_raw("set-cookie") {
- for cookie in cookies.iter() {
- if let Ok(cookie_value) = String::from_utf8(cookie.clone()) {
- let _ = ws.global().core_resource_thread().send(
- SetCookiesForUrl(ws.url.clone(), cookie_value, HTTP));
- }
- }
+ if let Some(cookies) = self.headers.get::<hyper::header::SetCookie>() {
+ let cookies = cookies.iter().map(|c| Serde(c.clone())).collect();
+ let _ = ws.global().core_resource_thread().send(
+ SetCookiesForUrl(ws.url.clone(), cookies, HTTP));
}
// Step 6.
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index 282979dc7bf..7dd8d71e9c8 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -19,7 +19,7 @@ use dom::bindings::codegen::Bindings::WindowBinding::{ScrollBehavior, ScrollToOp
use dom::bindings::codegen::UnionTypes::RequestOrUSVString;
use dom::bindings::error::{Error, ErrorResult, Fallible};
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, MutNullableHeap, Root};
+use dom::bindings::js::{JS, MutNullableJS, Root};
use dom::bindings::num::Finite;
use dom::bindings::refcounted::Trusted;
use dom::bindings::reflector::DomObject;
@@ -28,7 +28,7 @@ use dom::bindings::structuredclone::StructuredCloneData;
use dom::bindings::utils::{GlobalStaticData, WindowProxyHandler};
use dom::browsingcontext::BrowsingContext;
use dom::crypto::Crypto;
-use dom::cssstyledeclaration::{CSSModificationAccess, CSSStyleDeclaration};
+use dom::cssstyledeclaration::{CSSModificationAccess, CSSStyleDeclaration, CSSStyleOwner};
use dom::document::{AnimationFrameCallback, Document};
use dom::element::Element;
use dom::event::Event;
@@ -77,6 +77,9 @@ use script_traits::{DocumentState, TimerEvent, TimerEventId};
use script_traits::{ScriptMsg as ConstellationMsg, TimerEventRequest, WindowSizeData, WindowSizeType};
use script_traits::webdriver_msg::{WebDriverJSError, WebDriverJSResult};
use servo_atoms::Atom;
+use servo_config::opts;
+use servo_config::prefs::PREFS;
+use servo_geometry::{f32_rect_to_au_rect, max_rect};
use servo_url::ServoUrl;
use std::ascii::AsciiExt;
use std::borrow::ToOwned;
@@ -92,6 +95,7 @@ use std::sync::mpsc::TryRecvError::{Disconnected, Empty};
use style::context::ReflowGoal;
use style::error_reporting::ParseErrorReporter;
use style::media_queries;
+use style::properties::PropertyId;
use style::properties::longhands::overflow_x;
use style::selector_parser::PseudoElement;
use style::str::HTML_SPACE_CHARACTERS;
@@ -105,9 +109,6 @@ use timers::{IsInterval, TimerCallback};
#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
use tinyfiledialogs::{self, MessageBoxIcon};
use url::Position;
-use util::geometry::{self, max_rect};
-use util::opts;
-use util::prefs::PREFS;
use webdriver_handlers::jsval_to_webdriver;
/// Current state of the window object
@@ -141,8 +142,6 @@ pub enum ReflowReason {
ElementStateChanged,
}
-pub type ScrollPoint = Point2D<Au>;
-
#[dom_struct]
pub struct Window {
globalscope: GlobalScope,
@@ -158,19 +157,19 @@ pub struct Window {
history_traversal_task_source: HistoryTraversalTaskSource,
#[ignore_heap_size_of = "task sources are hard"]
file_reading_task_source: FileReadingTaskSource,
- navigator: MutNullableHeap<JS<Navigator>>,
+ navigator: MutNullableJS<Navigator>,
#[ignore_heap_size_of = "channels are hard"]
image_cache_thread: ImageCacheThread,
#[ignore_heap_size_of = "channels are hard"]
image_cache_chan: ImageCacheChan,
- browsing_context: MutNullableHeap<JS<BrowsingContext>>,
- history: MutNullableHeap<JS<History>>,
- performance: MutNullableHeap<JS<Performance>>,
+ browsing_context: MutNullableJS<BrowsingContext>,
+ history: MutNullableJS<History>,
+ performance: MutNullableJS<Performance>,
navigation_start: u64,
navigation_start_precise: f64,
- screen: MutNullableHeap<JS<Screen>>,
- session_storage: MutNullableHeap<JS<Storage>>,
- local_storage: MutNullableHeap<JS<Storage>>,
+ screen: MutNullableJS<Screen>,
+ session_storage: MutNullableJS<Storage>,
+ local_storage: MutNullableJS<Storage>,
status: DOMRefCell<DOMString>,
/// For sending timeline markers. Will be ignored if
@@ -240,7 +239,7 @@ pub struct Window {
/// All the MediaQueryLists we need to update
media_query_lists: WeakMediaQueryListVec,
- test_runner: MutNullableHeap<JS<TestRunner>>,
+ test_runner: MutNullableJS<TestRunner>,
}
impl Window {
@@ -700,7 +699,10 @@ impl WindowMethods for Window {
};
// Step 5.
- CSSStyleDeclaration::new(self, element, pseudo, CSSModificationAccess::Readonly)
+ CSSStyleDeclaration::new(self,
+ CSSStyleOwner::Element(JS::from_ref(element)),
+ pseudo,
+ CSSModificationAccess::Readonly)
}
// https://drafts.csswg.org/cssom-view/#dom-window-innerheight
@@ -1295,16 +1297,16 @@ impl Window {
}
pub fn resolved_style_query(&self,
- element: TrustedNodeAddress,
- pseudo: Option<PseudoElement>,
- property: &Atom) -> Option<DOMString> {
+ element: TrustedNodeAddress,
+ pseudo: Option<PseudoElement>,
+ property: PropertyId) -> DOMString {
if !self.reflow(ReflowGoal::ForScriptQuery,
- ReflowQueryType::ResolvedStyleQuery(element, pseudo, property.clone()),
+ ReflowQueryType::ResolvedStyleQuery(element, pseudo, property),
ReflowReason::Query) {
- return None;
+ return DOMString::new();
}
let ResolvedStyleResponse(resolved) = self.layout_rpc.resolved_style();
- resolved.map(DOMString::from)
+ DOMString::from(resolved)
}
pub fn offset_parent_query(&self, node: TrustedNodeAddress) -> (Option<Root<Element>>, Rect<Au>) {
@@ -1412,13 +1414,13 @@ impl Window {
}
pub fn set_page_clip_rect_with_new_viewport(&self, viewport: Rect<f32>) -> bool {
- let rect = geometry::f32_rect_to_au_rect(viewport.clone());
+ let rect = f32_rect_to_au_rect(viewport.clone());
self.current_viewport.set(rect);
// We use a clipping rectangle that is five times the size of the of the viewport,
// so that we don't collect display list items for areas too far outside the viewport,
// but also don't trigger reflows every time the viewport changes.
static VIEWPORT_EXPANSION: f32 = 2.0; // 2 lengths on each side plus original length is 5 total.
- let proposed_clip_rect = geometry::f32_rect_to_au_rect(
+ let proposed_clip_rect = f32_rect_to_au_rect(
viewport.inflate(viewport.size.width * VIEWPORT_EXPANSION,
viewport.size.height * VIEWPORT_EXPANSION));
let clip_rect = self.page_clip_rect.get();
diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs
index 430757bce53..221d60c1570 100644
--- a/components/script/dom/workerglobalscope.rs
+++ b/components/script/dom/workerglobalscope.rs
@@ -10,7 +10,7 @@ use dom::bindings::codegen::Bindings::WorkerGlobalScopeBinding::WorkerGlobalScop
use dom::bindings::codegen::UnionTypes::RequestOrUSVString;
use dom::bindings::error::{Error, ErrorResult, Fallible, report_pending_exception};
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, MutNullableHeap, Root};
+use dom::bindings::js::{MutNullableJS, Root};
use dom::bindings::refcounted::Trusted;
use dom::bindings::reflector::DomObject;
use dom::bindings::str::DOMString;
@@ -73,8 +73,8 @@ pub struct WorkerGlobalScope {
closing: Option<Arc<AtomicBool>>,
#[ignore_heap_size_of = "Defined in js"]
runtime: Runtime,
- location: MutNullableHeap<JS<WorkerLocation>>,
- navigator: MutNullableHeap<JS<WorkerNavigator>>,
+ location: MutNullableJS<WorkerLocation>,
+ navigator: MutNullableJS<WorkerNavigator>,
#[ignore_heap_size_of = "Defined in ipc-channel"]
/// Optional `IpcSender` for sending the `DevtoolScriptControlMsg`
diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs
index 2e1fcd465e8..f676eac3b64 100644
--- a/components/script/dom/xmlhttprequest.rs
+++ b/components/script/dom/xmlhttprequest.rs
@@ -14,7 +14,7 @@ use dom::bindings::codegen::Bindings::XMLHttpRequestBinding::XMLHttpRequestRespo
use dom::bindings::conversions::ToJSValConvertible;
use dom::bindings::error::{Error, ErrorResult, Fallible};
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, MutHeapJSVal, MutNullableHeap, Root};
+use dom::bindings::js::{JS, MutHeapJSVal, MutNullableJS, Root};
use dom::bindings::refcounted::Trusted;
use dom::bindings::reflector::{DomObject, reflect_dom_object};
use dom::bindings::str::{ByteString, DOMString, USVString, is_token};
@@ -53,6 +53,7 @@ use net_traits::request::{CredentialsMode, Destination, RequestInit, RequestMode
use net_traits::trim_http_whitespace;
use network_listener::{NetworkListener, PreInvoke};
use servo_atoms::Atom;
+use servo_config::prefs::PREFS;
use servo_url::ServoUrl;
use std::ascii::AsciiExt;
use std::borrow::ToOwned;
@@ -64,7 +65,6 @@ use task_source::networking::NetworkingTaskSource;
use time;
use timers::{OneshotTimerCallback, OneshotTimerHandle};
use url::Position;
-use util::prefs::PREFS;
#[derive(JSTraceable, PartialEq, Copy, Clone, HeapSizeOf)]
enum XMLHttpRequestState {
@@ -122,8 +122,8 @@ pub struct XMLHttpRequest {
status_text: DOMRefCell<ByteString>,
response: DOMRefCell<ByteString>,
response_type: Cell<XMLHttpRequestResponseType>,
- response_xml: MutNullableHeap<JS<Document>>,
- response_blob: MutNullableHeap<JS<Blob>>,
+ response_xml: MutNullableJS<Document>,
+ response_blob: MutNullableJS<Blob>,
#[ignore_heap_size_of = "Defined in rust-mozjs"]
response_json: MutHeapJSVal,
#[ignore_heap_size_of = "Defined in hyper"]
diff --git a/components/script/layout_wrapper.rs b/components/script/layout_wrapper.rs
index 290ebeb2312..e6c38aa1fb3 100644
--- a/components/script/layout_wrapper.rs
+++ b/components/script/layout_wrapper.rs
@@ -61,7 +61,7 @@ use std::sync::atomic::Ordering;
use style::atomic_refcell::AtomicRefCell;
use style::attr::AttrValue;
use style::computed_values::display;
-use style::context::SharedStyleContext;
+use style::context::{QuirksMode, SharedStyleContext};
use style::data::ElementData;
use style::dom::{LayoutIterator, NodeInfo, OpaqueNode, PresentationalHintsSynthetizer, TElement, TNode};
use style::dom::UnsafeNode;
@@ -86,7 +86,11 @@ impl<'ln> Debug for ServoLayoutNode<'ln> {
if let Some(el) = self.as_element() {
el.fmt(f)
} else {
- write!(f, "{:?} ({:#x})", self.type_id(), self.opaque().0)
+ if self.is_text_node() {
+ write!(f, "<text node> ({:#x})", self.opaque().0)
+ } else {
+ write!(f, "<non-text node> ({:#x})", self.opaque().0)
+ }
}
}
}
@@ -156,15 +160,6 @@ impl<'ln> TNode for ServoLayoutNode<'ln> {
transmute(node)
}
- fn dump(self) {
- self.dump_indent(0);
- }
-
- fn dump_style(self) {
- println!("\nDOM with computed styles:");
- self.dump_style_indent(0);
- }
-
fn children(self) -> LayoutIterator<ServoChildrenIterator<'ln>> {
LayoutIterator(ServoChildrenIterator {
current: self.first_child(),
@@ -290,54 +285,6 @@ impl<'le> GetLayoutData for ServoThreadSafeLayoutElement<'le> {
}
impl<'ln> ServoLayoutNode<'ln> {
- fn dump_indent(self, indent: u32) {
- let mut s = String::new();
- for _ in 0..indent {
- s.push_str(" ");
- }
-
- s.push_str(&self.debug_str());
- println!("{}", s);
-
- for kid in self.children() {
- kid.dump_indent(indent + 1);
- }
- }
-
- fn dump_style_indent(self, indent: u32) {
- if self.is_element() {
- let mut s = String::new();
- for _ in 0..indent {
- s.push_str(" ");
- }
- s.push_str(&self.debug_style_str());
- println!("{}", s);
- }
-
- for kid in self.children() {
- kid.dump_style_indent(indent + 1);
- }
- }
-
- fn debug_str(self) -> String {
- format!("{:?}: dirty_descendants={}",
- self.script_type_id(),
- self.as_element().map_or(false, |el| el.has_dirty_descendants()))
- }
-
- fn debug_style_str(self) -> String {
- let maybe_element = self.as_element();
- let maybe_data = match maybe_element {
- Some(ref el) => el.borrow_data(),
- None => None,
- };
- if let Some(data) = maybe_data {
- format!("{:?}: {:?}", self.script_type_id(), &*data)
- } else {
- format!("{:?}: style_data=None", self.script_type_id())
- }
- }
-
/// Returns the interior of this node as a `LayoutJS`. This is highly unsafe for layout to
/// call and as such is marked `unsafe`.
pub unsafe fn get_jsmanaged(&self) -> &LayoutJS<Node> {
@@ -374,6 +321,10 @@ impl<'ld> ServoLayoutDocument<'ld> {
unsafe { self.document.will_paint(); }
}
+ pub fn quirks_mode(&self) -> QuirksMode {
+ unsafe { self.document.quirks_mode() }
+ }
+
pub fn from_layout_js(doc: LayoutJS<Document>) -> ServoLayoutDocument<'ld> {
ServoLayoutDocument {
document: doc,
@@ -816,7 +767,7 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> {
debug_assert!(self.is_text_node());
let parent = self.node.parent_node().unwrap().as_element().unwrap();
let parent_data = parent.get_data().unwrap().borrow();
- parent_data.current_styles().primary.values.clone()
+ parent_data.styles().primary.values.clone()
}
fn debug_id(self) -> usize {
diff --git a/components/script/lib.rs b/components/script/lib.rs
index e80e9553956..52c0cd6f358 100644
--- a/components/script/lib.rs
+++ b/components/script/lib.rs
@@ -83,6 +83,8 @@ extern crate script_traits;
extern crate selectors;
extern crate serde;
#[macro_use] extern crate servo_atoms;
+#[macro_use] extern crate servo_config;
+extern crate servo_geometry;
extern crate servo_url;
extern crate smallvec;
#[macro_use]
@@ -93,7 +95,6 @@ extern crate time;
extern crate tinyfiledialogs;
extern crate url;
#[macro_use]
-extern crate util;
extern crate uuid;
extern crate webrender_traits;
extern crate websocket;
@@ -104,7 +105,7 @@ pub mod clipboard_provider;
mod devtools;
pub mod document_loader;
#[macro_use]
-pub mod dom;
+mod dom;
pub mod fetch;
pub mod layout_wrapper;
mod mem;
@@ -115,7 +116,9 @@ pub mod script_runtime;
pub mod script_thread;
mod serviceworker_manager;
mod serviceworkerjob;
+mod stylesheet_loader;
mod task_source;
+pub mod test;
pub mod textinput;
mod timers;
mod unpremultiplytable;
diff --git a/components/script/network_listener.rs b/components/script/network_listener.rs
index 5a96317fb18..fc7b4635756 100644
--- a/components/script/network_listener.rs
+++ b/components/script/network_listener.rs
@@ -2,7 +2,6 @@
* 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 bluetooth_traits::{BluetoothResponseListener, BluetoothResponseResult};
use net_traits::{Action, FetchResponseListener, FetchResponseMsg};
use script_thread::{Runnable, RunnableWrapper};
use std::sync::{Arc, Mutex};
@@ -41,13 +40,6 @@ impl<Listener: FetchResponseListener + PreInvoke + Send + 'static> NetworkListen
}
}
-// helps type inference
-impl<Listener: BluetoothResponseListener + PreInvoke + Send + 'static> NetworkListener<Listener> {
- pub fn notify_response(&self, action: BluetoothResponseResult) {
- self.notify(action);
- }
-}
-
/// A gating mechanism that runs before invoking the runnable on the target thread.
/// If the `should_invoke` method returns false, the runnable is discarded without
/// being invoked.
diff --git a/components/script/script_runtime.rs b/components/script/script_runtime.rs
index 00e7d3a198e..a21f96c5890 100644
--- a/components/script/script_runtime.rs
+++ b/components/script/script_runtime.rs
@@ -25,6 +25,8 @@ use js::rust::Runtime;
use msg::constellation_msg::PipelineId;
use profile_traits::mem::{Report, ReportKind, ReportsChan};
use script_thread::{Runnable, STACK_ROOTS, trace_thread};
+use servo_config::opts;
+use servo_config::prefs::PREFS;
use std::cell::Cell;
use std::io::{Write, stdout};
use std::marker::PhantomData;
@@ -35,8 +37,6 @@ use std::ptr;
use std::rc::Rc;
use style::thread_state;
use time::{Tm, now};
-use util::opts;
-use util::prefs::PREFS;
/// Common messages used to control the event loops in both the script and the worker
pub enum CommonScriptMsg {
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index f55d9279138..447b6775bdc 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -32,7 +32,7 @@ use dom::bindings::codegen::Bindings::TransitionEventBinding::TransitionEventIni
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::conversions::{ConversionResult, FromJSValConvertible, StringificationBehavior};
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, MutNullableHeap, Root, RootCollection};
+use dom::bindings::js::{JS, MutNullableJS, Root, RootCollection};
use dom::bindings::js::{RootCollectionPtr, RootedReference};
use dom::bindings::num::Finite;
use dom::bindings::refcounted::Trusted;
@@ -91,6 +91,7 @@ use script_traits::CompositorEvent::{KeyEvent, MouseButtonEvent, MouseMoveEvent,
use script_traits::CompositorEvent::{TouchEvent, TouchpadPressureEvent};
use script_traits::webdriver_msg::WebDriverScriptCommand;
use serviceworkerjob::{Job, JobQueue, AsyncJobHandler, FinishJobHandler, InvokeType, SettleType};
+use servo_config::opts;
use servo_url::ServoUrl;
use std::cell::Cell;
use std::collections::{hash_map, HashMap, HashSet};
@@ -101,6 +102,7 @@ use std::result::Result;
use std::sync::{Arc, Mutex};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::{Receiver, Select, Sender, channel};
+use std::thread;
use style::context::ReflowGoal;
use style::dom::{TNode, UnsafeNode};
use style::thread_state;
@@ -112,8 +114,6 @@ use task_source::networking::NetworkingTaskSource;
use task_source::user_interaction::{UserInteractionTask, UserInteractionTaskSource};
use time::Tm;
use url::Position;
-use util::opts;
-use util::thread;
use webdriver_handlers;
thread_local!(pub static STACK_ROOTS: Cell<Option<RootCollectionPtr>> = Cell::new(None));
@@ -461,7 +461,7 @@ pub struct ScriptThread {
js_runtime: Rc<Runtime>,
/// The topmost element over the mouse.
- topmost_mouse_over_target: MutNullableHeap<JS<Element>>,
+ topmost_mouse_over_target: MutNullableJS<Element>,
/// List of pipelines that have been owned and closed by this script thread.
closed_pipelines: DOMRefCell<HashSet<PipelineId>>,
@@ -498,13 +498,10 @@ impl<'a> ScriptMemoryFailsafe<'a> {
impl<'a> Drop for ScriptMemoryFailsafe<'a> {
#[allow(unrooted_must_root)]
fn drop(&mut self) {
- match self.owner {
- Some(owner) => {
- for (_, document) in owner.documents.borrow().iter() {
- document.window().clear_js_runtime_for_script_deallocation();
- }
+ if let Some(owner) = self.owner {
+ for (_, document) in owner.documents.borrow().iter() {
+ document.window().clear_js_runtime_for_script_deallocation();
}
- None => (),
}
}
}
@@ -519,8 +516,7 @@ impl ScriptThreadFactory for ScriptThread {
let (sender, receiver) = channel();
let layout_chan = sender.clone();
- thread::spawn_named(format!("ScriptThread {:?}", state.id),
- move || {
+ thread::Builder::new().name(format!("ScriptThread {:?}", state.id)).spawn(move || {
thread_state::initialize(thread_state::SCRIPT);
PipelineNamespace::install(state.pipeline_namespace_id);
FrameId::install(state.top_level_frame_id);
@@ -553,7 +549,7 @@ impl ScriptThreadFactory for ScriptThread {
// This must always be the very last operation performed before the thread completes
failsafe.neuter();
- });
+ }).expect("Thread spawning failed");
(sender, receiver)
}
@@ -686,7 +682,7 @@ impl ScriptThread {
devtools_sender: ipc_devtools_sender,
js_runtime: Rc::new(runtime),
- topmost_mouse_over_target: MutNullableHeap::new(Default::default()),
+ topmost_mouse_over_target: MutNullableJS::new(Default::default()),
closed_pipelines: DOMRefCell::new(HashSet::new()),
scheduler_chan: state.scheduler_chan,
@@ -726,10 +722,8 @@ impl ScriptThread {
for (id, document) in self.documents.borrow().iter() {
// Only process a resize if layout is idle.
- let resize_event = document.window().steal_resize_event();
- match resize_event {
- Some((size, size_type)) => resizes.push((id, size, size_type)),
- None => ()
+ if let Some((size, size_type)) = document.window().steal_resize_event() {
+ resizes.push((id, size, size_type));
}
}
@@ -1050,8 +1044,11 @@ impl ScriptThread {
TimerSource::FromWorker => panic!("Worker timeouts must not be sent to script thread"),
};
- let window = self.documents.borrow().find_window(pipeline_id)
- .expect("ScriptThread: received fire timer msg for a pipeline not in this script thread. This is a bug.");
+ let window = self.documents.borrow().find_window(pipeline_id);
+ let window = match window {
+ Some(w) => w,
+ None => return warn!("Received fire timer msg for a closed pipeline {}.", pipeline_id),
+ };
window.handle_fire_timer(id);
}
@@ -1143,7 +1140,8 @@ impl ScriptThread {
}
fn handle_resize(&self, id: PipelineId, size: WindowSizeData, size_type: WindowSizeType) {
- if let Some(ref window) = self.documents.borrow().find_window(id) {
+ let window = self.documents.borrow().find_window(id);
+ if let Some(ref window) = window {
window.set_resize_event(size, size_type);
return;
}
@@ -1156,7 +1154,8 @@ impl ScriptThread {
}
fn handle_viewport(&self, id: PipelineId, rect: Rect<f32>) {
- if let Some(document) = self.documents.borrow().find_document(id) {
+ let document = self.documents.borrow().find_document(id);
+ if let Some(document) = document {
if document.window().set_page_clip_rect_with_new_viewport(rect) {
self.rebuild_and_force_reflow(&document, ReflowReason::Viewport);
}
@@ -1173,7 +1172,7 @@ impl ScriptThread {
fn handle_set_scroll_state(&self,
id: PipelineId,
scroll_states: &[(UntrustedNodeAddress, Point2D<f32>)]) {
- let window = match self.documents.borrow().find_window(id) {
+ let window = match { self.documents.borrow().find_window(id) } {
Some(window) => window,
None => return warn!("Set scroll state message sent to nonexistent pipeline: {:?}", id),
};
@@ -1241,7 +1240,7 @@ impl ScriptThread {
}
fn handle_loads_complete(&self, pipeline: PipelineId) {
- let doc = match self.documents.borrow().find_document(pipeline) {
+ let doc = match { self.documents.borrow().find_document(pipeline) } {
Some(doc) => doc,
None => return warn!("Message sent to closed pipeline {}.", pipeline),
};
@@ -1296,7 +1295,8 @@ impl ScriptThread {
/// To slow/speed up timers and manage any other script thread resource based on visibility.
/// Returns true if successful.
fn alter_resource_utilization(&self, id: PipelineId, visible: bool) -> bool {
- if let Some(window) = self.documents.borrow().find_window(id) {
+ let window = self.documents.borrow().find_window(id);
+ if let Some(window) = window {
if visible {
window.upcast::<GlobalScope>().speed_up_timers();
} else {
@@ -1309,7 +1309,8 @@ impl ScriptThread {
/// Updates iframe element after a change in visibility
fn handle_visibility_change_complete_msg(&self, parent_pipeline_id: PipelineId, id: FrameId, visible: bool) {
- if let Some(iframe) = self.documents.borrow().find_iframe(parent_pipeline_id, id) {
+ let iframe = self.documents.borrow().find_iframe(parent_pipeline_id, id);
+ if let Some(iframe) = iframe {
iframe.change_visibility_status(visible);
}
}
@@ -1337,7 +1338,8 @@ impl ScriptThread {
/// Handles freeze message
fn handle_freeze_msg(&self, id: PipelineId) {
- if let Some(window) = self.documents.borrow().find_window(id) {
+ let window = self.documents.borrow().find_window(id);
+ if let Some(window) = window {
window.upcast::<GlobalScope>().suspend();
return;
}
@@ -1351,7 +1353,8 @@ impl ScriptThread {
/// Handles thaw message
fn handle_thaw_msg(&self, id: PipelineId) {
- if let Some(document) = self.documents.borrow().find_document(id) {
+ let document = self.documents.borrow().find_document(id);
+ if let Some(document) = document {
if let Some(context) = document.browsing_context() {
let needed_reflow = context.set_reflow_status(false);
if needed_reflow {
@@ -1402,14 +1405,16 @@ impl ScriptThread {
parent_pipeline_id: PipelineId,
frame_id: Option<FrameId>,
event: MozBrowserEvent) {
- match self.documents.borrow().find_document(parent_pipeline_id) {
- None => warn!("Mozbrowser event after pipeline {:?} closed.", parent_pipeline_id),
- Some(doc) => match frame_id {
- None => doc.window().dispatch_mozbrowser_event(event),
- Some(frame_id) => match doc.find_iframe(frame_id) {
- None => warn!("Mozbrowser event after iframe {:?}/{:?} closed.", parent_pipeline_id, frame_id),
- Some(frame_element) => frame_element.dispatch_mozbrowser_event(event),
- },
+ let doc = match { self.documents.borrow().find_document(parent_pipeline_id) } {
+ None => return warn!("Mozbrowser event after pipeline {:?} closed.", parent_pipeline_id),
+ Some(doc) => doc,
+ };
+
+ match frame_id {
+ None => doc.window().dispatch_mozbrowser_event(event),
+ Some(frame_id) => match doc.find_iframe(frame_id) {
+ None => warn!("Mozbrowser event after iframe {:?}/{:?} closed.", parent_pipeline_id, frame_id),
+ Some(frame_element) => frame_element.dispatch_mozbrowser_event(event),
},
}
}
@@ -1418,7 +1423,8 @@ impl ScriptThread {
parent_pipeline_id: PipelineId,
frame_id: FrameId,
new_pipeline_id: PipelineId) {
- if let Some(frame_element) = self.documents.borrow().find_iframe(parent_pipeline_id, frame_id) {
+ let frame_element = self.documents.borrow().find_iframe(parent_pipeline_id, frame_id);
+ if let Some(frame_element) = frame_element {
frame_element.update_pipeline_id(new_pipeline_id);
}
}
@@ -1487,13 +1493,14 @@ impl ScriptThread {
Some(r) => r,
None => return
};
- if let Some(window) = self.documents.borrow().find_window(pipeline_id) {
- let script_url = maybe_registration.get_installed().get_script_url();
- let scope_things = ServiceWorkerRegistration::create_scope_things(window.upcast(), script_url);
- let _ = self.constellation_chan.send(ConstellationMsg::RegisterServiceWorker(scope_things, scope.clone()));
- } else {
- warn!("Registration failed for {}", scope);
- }
+ let window = match { self.documents.borrow().find_window(pipeline_id) } {
+ Some(window) => window,
+ None => return warn!("Registration failed for {}", scope),
+ };
+
+ let script_url = maybe_registration.get_installed().get_script_url();
+ let scope_things = ServiceWorkerRegistration::create_scope_things(window.upcast(), script_url);
+ let _ = self.constellation_chan.send(ConstellationMsg::RegisterServiceWorker(scope_things, scope.clone()));
}
pub fn dispatch_job_queue(&self, job_handler: Box<AsyncJobHandler>) {
@@ -1544,7 +1551,7 @@ impl ScriptThread {
/// Handles a request for the window title.
fn handle_get_title_msg(&self, pipeline_id: PipelineId) {
- let document = match self.documents.borrow().find_document(pipeline_id) {
+ let document = match { self.documents.borrow().find_document(pipeline_id) } {
Some(document) => document,
None => return warn!("Message sent to closed pipeline {}.", pipeline_id),
};
@@ -1601,7 +1608,7 @@ impl ScriptThread {
/// Handles when layout thread finishes all animation in one tick
fn handle_tick_all_animations(&self, id: PipelineId) {
- let document = match self.documents.borrow().find_document(id) {
+ let document = match { self.documents.borrow().find_document(id) } {
Some(document) => document,
None => return warn!("Message sent to closed pipeline {}.", id),
};
@@ -1642,7 +1649,8 @@ impl ScriptThread {
/// Handles a Web font being loaded. Does nothing if the page no longer exists.
fn handle_web_font_loaded(&self, pipeline_id: PipelineId) {
- if let Some(document) = self.documents.borrow().find_document(pipeline_id) {
+ let document = self.documents.borrow().find_document(pipeline_id);
+ if let Some(document) = document {
self.rebuild_and_force_reflow(&document, ReflowReason::WebFontLoaded);
}
}
@@ -1650,12 +1658,14 @@ impl ScriptThread {
/// Notify a window of a storage event
fn handle_storage_event(&self, pipeline_id: PipelineId, storage_type: StorageType, url: ServoUrl,
key: Option<String>, old_value: Option<String>, new_value: Option<String>) {
- let storage = match self.documents.borrow().find_window(pipeline_id) {
+ let window = match { self.documents.borrow().find_window(pipeline_id) } {
None => return warn!("Storage event sent to closed pipeline {}.", pipeline_id),
- Some(window) => match storage_type {
- StorageType::Local => window.LocalStorage(),
- StorageType::Session => window.SessionStorage(),
- },
+ Some(window) => window,
+ };
+
+ let storage = match storage_type {
+ StorageType::Local => window.LocalStorage(),
+ StorageType::Session => window.SessionStorage(),
};
storage.queue_storage_event(url, key, old_value, new_value);
@@ -1908,7 +1918,7 @@ impl ScriptThread {
}
MouseMoveEvent(point) => {
- let document = match self.documents.borrow().find_document(pipeline_id) {
+ let document = match { self.documents.borrow().find_document(pipeline_id) } {
Some(document) => document,
None => return warn!("Message sent to closed pipeline {}.", pipeline_id),
};
@@ -1980,17 +1990,19 @@ impl ScriptThread {
}
TouchpadPressureEvent(point, pressure, phase) => {
- match self.documents.borrow().find_document(pipeline_id) {
- Some(doc) => doc.handle_touchpad_pressure_event(self.js_runtime.rt(), point, pressure, phase),
- None => warn!("Message sent to closed pipeline {}.", pipeline_id),
- }
+ let doc = match { self.documents.borrow().find_document(pipeline_id) } {
+ Some(doc) => doc,
+ None => return warn!("Message sent to closed pipeline {}.", pipeline_id),
+ };
+ doc.handle_touchpad_pressure_event(self.js_runtime.rt(), point, pressure, phase);
}
KeyEvent(ch, key, state, modifiers) => {
- match self.documents.borrow().find_document(pipeline_id) {
- Some(document) => document.dispatch_key_event(ch, key, state, modifiers, &self.constellation_chan),
- None => warn!("Message sent to closed pipeline {}.", pipeline_id),
- }
+ let document = match { self.documents.borrow().find_document(pipeline_id) } {
+ Some(document) => document,
+ None => return warn!("Message sent to closed pipeline {}.", pipeline_id),
+ };
+ document.dispatch_key_event(ch, key, state, modifiers, &self.constellation_chan);
}
}
}
@@ -2000,10 +2012,11 @@ impl ScriptThread {
mouse_event_type: MouseEventType,
button: MouseButton,
point: Point2D<f32>) {
- match self.documents.borrow().find_document(pipeline_id) {
- Some(document) => document.handle_mouse_event(self.js_runtime.rt(), button, point, mouse_event_type),
- None => warn!("Message sent to closed pipeline {}.", pipeline_id),
- }
+ let document = match { self.documents.borrow().find_document(pipeline_id) } {
+ Some(document) => document,
+ None => return warn!("Message sent to closed pipeline {}.", pipeline_id),
+ };
+ document.handle_mouse_event(self.js_runtime.rt(), button, point, mouse_event_type);
}
fn handle_touch_event(&self,
@@ -2012,13 +2025,14 @@ impl ScriptThread {
identifier: TouchId,
point: Point2D<f32>)
-> TouchEventResult {
- match self.documents.borrow().find_document(pipeline_id) {
- Some(document) => document.handle_touch_event(self.js_runtime.rt(), event_type, identifier, point),
+ let document = match { self.documents.borrow().find_document(pipeline_id) } {
+ Some(document) => document,
None => {
warn!("Message sent to closed pipeline {}.", pipeline_id);
- TouchEventResult::Processed(true)
+ return TouchEventResult::Processed(true);
},
- }
+ };
+ document.handle_touch_event(self.js_runtime.rt(), event_type, identifier, point)
}
/// https://html.spec.whatwg.org/multipage/#navigating-across-documents
@@ -2044,7 +2058,7 @@ impl ScriptThread {
}
fn handle_resize_event(&self, pipeline_id: PipelineId, new_size: WindowSizeData, size_type: WindowSizeType) {
- let document = match self.documents.borrow().find_document(pipeline_id) {
+ let document = match { self.documents.borrow().find_document(pipeline_id) } {
Some(document) => document,
None => return warn!("Message sent to closed pipeline {}.", pipeline_id),
};
@@ -2127,7 +2141,7 @@ impl ScriptThread {
}
fn handle_parsing_complete(&self, id: PipelineId) {
- let document = match self.documents.borrow().find_document(id) {
+ let document = match { self.documents.borrow().find_document(id) } {
Some(document) => document,
None => return,
};
@@ -2175,7 +2189,8 @@ impl ScriptThread {
}
fn handle_reload(&self, pipeline_id: PipelineId) {
- if let Some(window) = self.documents.borrow().find_window(pipeline_id) {
+ let window = self.documents.borrow().find_window(pipeline_id);
+ if let Some(window) = window {
window.Location().Reload();
}
}
diff --git a/components/script/serviceworker_manager.rs b/components/script/serviceworker_manager.rs
index ac3c2ab4109..793d7ccf370 100644
--- a/components/script/serviceworker_manager.rs
+++ b/components/script/serviceworker_manager.rs
@@ -16,11 +16,11 @@ use ipc_channel::ipc::{self, IpcSender};
use ipc_channel::router::ROUTER;
use net_traits::{CustomResponseMediator, CoreResourceMsg};
use script_traits::{ServiceWorkerMsg, ScopeThings, SWManagerMsg, SWManagerSenders, DOMMessage};
+use servo_config::prefs::PREFS;
use servo_url::ServoUrl;
use std::collections::HashMap;
use std::sync::mpsc::{channel, Sender, Receiver, RecvError};
-use util::prefs::PREFS;
-use util::thread::spawn_named;
+use std::thread;
enum Message {
FromResource(CustomResponseMediator),
@@ -60,11 +60,11 @@ impl ServiceWorkerManager {
let resource_port = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(resource_port);
let _ = sw_senders.resource_sender.send(CoreResourceMsg::NetworkMediator(resource_chan));
let _ = sw_senders.swmanager_sender.send(SWManagerMsg::OwnSender(own_sender.clone()));
- spawn_named("ServiceWorkerManager".to_owned(), move || {
+ thread::Builder::new().name("ServiceWorkerManager".to_owned()).spawn(move || {
ServiceWorkerManager::new(own_sender,
from_constellation,
resource_port).handle_message();
- });
+ }).expect("Thread spawning failed");
}
pub fn get_matching_scope(&self, load_url: &ServoUrl) -> Option<ServoUrl> {
diff --git a/components/script/stylesheet_loader.rs b/components/script/stylesheet_loader.rs
new file mode 100644
index 00000000000..427593c8500
--- /dev/null
+++ b/components/script/stylesheet_loader.rs
@@ -0,0 +1,245 @@
+/* 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 document_loader::LoadType;
+use dom::bindings::inheritance::Castable;
+use dom::bindings::refcounted::Trusted;
+use dom::bindings::reflector::DomObject;
+use dom::element::Element;
+use dom::eventtarget::EventTarget;
+use dom::htmlelement::HTMLElement;
+use dom::htmllinkelement::HTMLLinkElement;
+use dom::node::{document_from_node, window_from_node};
+use encoding::EncodingRef;
+use encoding::all::UTF_8;
+use hyper::header::ContentType;
+use hyper::mime::{Mime, TopLevel, SubLevel};
+use hyper_serde::Serde;
+use ipc_channel::ipc;
+use ipc_channel::router::ROUTER;
+use net_traits::{FetchResponseListener, FetchMetadata, Metadata, NetworkError, ReferrerPolicy};
+use net_traits::request::{CredentialsMode, Destination, RequestInit, Type as RequestType};
+use network_listener::{NetworkListener, PreInvoke};
+use parking_lot::RwLock;
+use script_layout_interface::message::Msg;
+use servo_url::ServoUrl;
+use std::mem;
+use std::sync::{Arc, Mutex};
+use style::media_queries::MediaList;
+use style::parser::ParserContextExtraData;
+use style::stylesheets::{ImportRule, Stylesheet, Origin};
+use style::stylesheets::StylesheetLoader as StyleStylesheetLoader;
+
+pub trait StylesheetOwner {
+ /// Returns whether this element was inserted by the parser (i.e., it should
+ /// trigger a document-load-blocking load).
+ fn parser_inserted(&self) -> bool;
+
+ /// Which referrer policy should loads triggered by this owner follow, or
+ /// `None` for the default.
+ fn referrer_policy(&self) -> Option<ReferrerPolicy>;
+
+ /// Notes that a new load is pending to finish.
+ fn increment_pending_loads_count(&self);
+
+ /// Returns None if there are still pending loads, or whether any load has
+ /// failed since the loads started.
+ fn load_finished(&self, successful: bool) -> Option<bool>;
+}
+
+pub enum StylesheetContextSource {
+ // NB: `media` is just an option so we avoid cloning it.
+ LinkElement { media: Option<MediaList>, url: ServoUrl },
+ Import(Arc<RwLock<ImportRule>>),
+}
+
+impl StylesheetContextSource {
+ fn url(&self) -> ServoUrl {
+ match *self {
+ StylesheetContextSource::LinkElement { ref url, .. } => url.clone(),
+ StylesheetContextSource::Import(ref import) => {
+ let import = import.read();
+ // Look at the parser in style::stylesheets, where we don't
+ // trigger a load if the url is invalid.
+ import.url.url()
+ .expect("Invalid urls shouldn't enter the loader")
+ .clone()
+ }
+ }
+ }
+}
+
+/// The context required for asynchronously loading an external stylesheet.
+pub struct StylesheetContext {
+ /// The element that initiated the request.
+ elem: Trusted<HTMLElement>,
+ source: StylesheetContextSource,
+ metadata: Option<Metadata>,
+ /// The response body received to date.
+ data: Vec<u8>,
+}
+
+impl PreInvoke for StylesheetContext {}
+
+impl FetchResponseListener for StylesheetContext {
+ fn process_request_body(&mut self) {}
+
+ fn process_request_eof(&mut self) {}
+
+ fn process_response(&mut self,
+ metadata: Result<FetchMetadata, NetworkError>) {
+ self.metadata = metadata.ok().map(|m| {
+ match m {
+ FetchMetadata::Unfiltered(m) => m,
+ FetchMetadata::Filtered { unsafe_, .. } => unsafe_
+ }
+ });
+ }
+
+ fn process_response_chunk(&mut self, mut payload: Vec<u8>) {
+ self.data.append(&mut payload);
+ }
+
+ fn process_response_eof(&mut self, status: Result<(), NetworkError>) {
+ let elem = self.elem.root();
+ let document = document_from_node(&*elem);
+ let mut successful = false;
+
+ if status.is_ok() {
+ let metadata = match self.metadata.take() {
+ Some(meta) => meta,
+ None => return,
+ };
+ let is_css = metadata.content_type.map_or(false, |Serde(ContentType(Mime(top, sub, _)))|
+ top == TopLevel::Text && sub == SubLevel::Css);
+
+ let data = if is_css { mem::replace(&mut self.data, vec![]) } else { vec![] };
+
+ // TODO: Get the actual value. http://dev.w3.org/csswg/css-syntax/#environment-encoding
+ let environment_encoding = UTF_8 as EncodingRef;
+ let protocol_encoding_label = metadata.charset.as_ref().map(|s| &**s);
+ let final_url = metadata.final_url;
+
+ let win = window_from_node(&*elem);
+
+ let loader = StylesheetLoader::for_element(&elem);
+ match self.source {
+ StylesheetContextSource::LinkElement { ref mut media, .. } => {
+ let sheet =
+ Arc::new(Stylesheet::from_bytes(&data, final_url,
+ protocol_encoding_label,
+ Some(environment_encoding),
+ Origin::Author,
+ media.take().unwrap(),
+ Some(&loader),
+ win.css_error_reporter(),
+ ParserContextExtraData::default()));
+ elem.downcast::<HTMLLinkElement>()
+ .unwrap()
+ .set_stylesheet(sheet.clone());
+
+ let win = window_from_node(&*elem);
+ win.layout_chan().send(Msg::AddStylesheet(sheet)).unwrap();
+ }
+ StylesheetContextSource::Import(ref import) => {
+ let import = import.read();
+ Stylesheet::update_from_bytes(&import.stylesheet,
+ &data,
+ protocol_encoding_label,
+ Some(environment_encoding),
+ Some(&loader),
+ win.css_error_reporter(),
+ ParserContextExtraData::default());
+ }
+ }
+
+ document.invalidate_stylesheets();
+
+ // FIXME: Revisit once consensus is reached at:
+ // https://github.com/whatwg/html/issues/1142
+ successful = metadata.status.map_or(false, |(code, _)| code == 200);
+ }
+
+ let owner = elem.upcast::<Element>().as_stylesheet_owner()
+ .expect("Stylesheet not loaded by <style> or <link> element!");
+ if owner.parser_inserted() {
+ document.decrement_script_blocking_stylesheet_count();
+ }
+
+ let url = self.source.url();
+ document.finish_load(LoadType::Stylesheet(url));
+
+ if let Some(any_failed) = owner.load_finished(successful) {
+ let event = if any_failed { atom!("error") } else { atom!("load") };
+ elem.upcast::<EventTarget>().fire_event(event);
+ }
+ }
+}
+
+pub struct StylesheetLoader<'a> {
+ elem: &'a HTMLElement,
+}
+
+impl<'a> StylesheetLoader<'a> {
+ pub fn for_element(element: &'a HTMLElement) -> Self {
+ StylesheetLoader {
+ elem: element,
+ }
+ }
+}
+
+impl<'a> StylesheetLoader<'a> {
+ pub fn load(&self, source: StylesheetContextSource) {
+ let url = source.url();
+ let context = Arc::new(Mutex::new(StylesheetContext {
+ elem: Trusted::new(&*self.elem),
+ source: source,
+ metadata: None,
+ data: vec![],
+ }));
+
+ let document = document_from_node(self.elem);
+
+ let (action_sender, action_receiver) = ipc::channel().unwrap();
+ let listener = NetworkListener {
+ context: context,
+ task_source: document.window().networking_task_source(),
+ wrapper: Some(document.window().get_runnable_wrapper())
+ };
+ ROUTER.add_route(action_receiver.to_opaque(), box move |message| {
+ listener.notify_fetch(message.to().unwrap());
+ });
+
+
+ let owner = self.elem.upcast::<Element>().as_stylesheet_owner()
+ .expect("Stylesheet not loaded by <style> or <link> element!");
+ let referrer_policy = owner.referrer_policy()
+ .or_else(|| document.get_referrer_policy());
+ owner.increment_pending_loads_count();
+ if owner.parser_inserted() {
+ document.increment_script_blocking_stylesheet_count();
+ }
+
+ let request = RequestInit {
+ url: url.clone(),
+ type_: RequestType::Style,
+ destination: Destination::Style,
+ credentials_mode: CredentialsMode::Include,
+ use_url_credentials: true,
+ origin: document.url(),
+ pipeline_id: Some(self.elem.global().pipeline_id()),
+ referrer_url: Some(document.url()),
+ referrer_policy: referrer_policy,
+ .. RequestInit::default()
+ };
+
+ document.fetch_async(LoadType::Stylesheet(url), request, action_sender);
+ }
+}
+
+impl<'a> StyleStylesheetLoader for StylesheetLoader<'a> {
+ fn request_stylesheet(&self, import: &Arc<RwLock<ImportRule>>) {
+ self.load(StylesheetContextSource::Import(import.clone()))
+ }
+}
diff --git a/components/script/test.rs b/components/script/test.rs
new file mode 100644
index 00000000000..31353b5ffa3
--- /dev/null
+++ b/components/script/test.rs
@@ -0,0 +1,68 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+pub use dom::bindings::str::{ByteString, DOMString};
+pub use dom::headers::normalize_value;
+
+// For compile-fail tests only.
+pub use dom::bindings::cell::DOMRefCell;
+pub use dom::bindings::js::JS;
+pub use dom::node::Node;
+
+pub mod size_of {
+ use dom::characterdata::CharacterData;
+ use dom::element::Element;
+ use dom::eventtarget::EventTarget;
+ use dom::htmldivelement::HTMLDivElement;
+ use dom::htmlelement::HTMLElement;
+ use dom::htmlspanelement::HTMLSpanElement;
+ use dom::node::Node;
+ use dom::text::Text;
+ use layout_wrapper::{ServoLayoutElement, ServoLayoutNode, ServoThreadSafeLayoutNode};
+ use std::mem::size_of;
+
+ pub fn CharacterData() -> usize {
+ size_of::<CharacterData>()
+ }
+
+ pub fn Element() -> usize {
+ size_of::<Element>()
+ }
+
+ pub fn EventTarget() -> usize {
+ size_of::<EventTarget>()
+ }
+
+ pub fn HTMLDivElement() -> usize {
+ size_of::<HTMLDivElement>()
+ }
+
+ pub fn HTMLElement() -> usize {
+ size_of::<HTMLElement>()
+ }
+
+ pub fn HTMLSpanElement() -> usize {
+ size_of::<HTMLSpanElement>()
+ }
+
+ pub fn Node() -> usize {
+ size_of::<Node>()
+ }
+
+ pub fn SendElement() -> usize {
+ size_of::<::style::dom::SendElement<ServoLayoutElement>>()
+ }
+
+ pub fn SendNode() -> usize {
+ size_of::<::style::dom::SendNode<ServoLayoutNode>>()
+ }
+
+ pub fn ServoThreadSafeLayoutNode() -> usize {
+ size_of::<ServoThreadSafeLayoutNode>()
+ }
+
+ pub fn Text() -> usize {
+ size_of::<Text>()
+ }
+}
diff --git a/components/script/timers.rs b/components/script/timers.rs
index db0adfa9557..14c4eb89c13 100644
--- a/components/script/timers.rs
+++ b/components/script/timers.rs
@@ -18,12 +18,12 @@ use js::jsapi::{HandleValue, Heap};
use js::jsval::{JSVal, UndefinedValue};
use script_traits::{MsDuration, precise_time_ms};
use script_traits::{TimerEvent, TimerEventId, TimerEventRequest, TimerSource};
+use servo_config::prefs::PREFS;
use std::cell::Cell;
use std::cmp::{self, Ord, Ordering};
use std::collections::HashMap;
use std::default::Default;
use std::rc::Rc;
-use util::prefs::PREFS;
#[derive(JSTraceable, PartialEq, Eq, Copy, Clone, HeapSizeOf, Hash, PartialOrd, Ord, Debug)]
pub struct OneshotTimerHandle(i32);
diff --git a/components/script/webdriver_handlers.rs b/components/script/webdriver_handlers.rs
index e0818347c56..e1599d7caef 100644
--- a/components/script/webdriver_handlers.rs
+++ b/components/script/webdriver_handlers.rs
@@ -31,7 +31,7 @@ use js::jsapi::{HandleValue, JSContext};
use js::jsval::UndefinedValue;
use msg::constellation_msg::PipelineId;
use net_traits::CookieSource::{HTTP, NonHTTP};
-use net_traits::CoreResourceMsg::{GetCookiesDataForUrl, SetCookiesForUrlWithData};
+use net_traits::CoreResourceMsg::{GetCookiesDataForUrl, SetCookieForUrl};
use net_traits::IpcSend;
use script_thread::Documents;
use script_traits::webdriver_msg::{WebDriverFrameId, WebDriverJSError, WebDriverJSResult, WebDriverJSValue};
@@ -243,14 +243,14 @@ pub fn handle_add_cookie(documents: &Documents,
(true, _) => Err(WebDriverCookieError::InvalidDomain),
(false, Some(ref domain)) if url.host_str().map(|x| { x == &**domain }).unwrap_or(false) => {
let _ = document.window().upcast::<GlobalScope>().resource_threads().send(
- SetCookiesForUrlWithData(url, cookie, method)
- );
+ SetCookieForUrl(url, cookie, method)
+ );
Ok(())
},
(false, None) => {
let _ = document.window().upcast::<GlobalScope>().resource_threads().send(
- SetCookiesForUrlWithData(url, cookie, method)
- );
+ SetCookieForUrl(url, cookie, method)
+ );
Ok(())
},
(_, _) => {