aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
Diffstat (limited to 'components/script')
-rw-r--r--components/script/Cargo.toml2
-rw-r--r--components/script/dom/bindings/trace.rs3
-rw-r--r--components/script/dom/document.rs58
-rw-r--r--components/script/dom/htmlbaseelement.rs30
-rw-r--r--components/script/dom/htmltableelement.rs7
-rw-r--r--components/script/dom/htmltablerowelement.rs31
-rw-r--r--components/script/dom/webidls/HTMLBaseElement.webidl4
-rw-r--r--components/script/dom/webidls/HTMLTableRowElement.webidl2
-rw-r--r--components/script/lib.rs1
-rw-r--r--components/script/origin.rs73
10 files changed, 176 insertions, 35 deletions
diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml
index eaf86e3b39f..9fda41e036f 100644
--- a/components/script/Cargo.toml
+++ b/components/script/Cargo.toml
@@ -75,7 +75,7 @@ heapsize = "0.3.0"
heapsize_plugin = "0.1.2"
html5ever = {version = "0.5.1", features = ["heap_size", "unstable"]}
hyper = { version = "0.8", features = [ "serde-serialization" ] }
-image = "0.7"
+image = "0.9"
libc = "0.2"
log = "0.3.5"
num = "0.1.24"
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs
index 16138b33641..50c3fbf682f 100644
--- a/components/script/dom/bindings/trace.rs
+++ b/components/script/dom/bindings/trace.rs
@@ -89,6 +89,7 @@ use style::properties::PropertyDeclarationBlock;
use style::restyle_hints::ElementSnapshot;
use style::selector_impl::PseudoElement;
use style::values::specified::Length;
+use url::Origin as UrlOrigin;
use url::Url;
use util::str::{DOMString, LengthOrPercentageOrAuto};
use uuid::Uuid;
@@ -276,7 +277,7 @@ impl<A: JSTraceable, B: JSTraceable, C: JSTraceable> JSTraceable for (A, B, C) {
}
}
-no_jsmanaged_fields!(bool, f32, f64, String, Url, AtomicBool, AtomicUsize, Uuid);
+no_jsmanaged_fields!(bool, f32, f64, String, Url, AtomicBool, AtomicUsize, UrlOrigin, Uuid);
no_jsmanaged_fields!(usize, u8, u16, u32, u64);
no_jsmanaged_fields!(isize, i8, i16, i32, i64);
no_jsmanaged_fields!(Sender<T>);
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index e38ab86bf29..723e461df30 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -94,6 +94,7 @@ use net_traits::CookieSource::NonHTTP;
use net_traits::response::HttpsState;
use net_traits::{AsyncResponseTarget, PendingAsyncLoad};
use num::ToPrimitive;
+use origin::Origin;
use script_runtime::ScriptChan;
use script_thread::{MainThreadScriptChan, MainThreadScriptMsg, Runnable};
use script_traits::UntrustedNodeAddress;
@@ -223,6 +224,8 @@ pub struct Document {
/// https://html.spec.whatwg.org/multipage/#concept-document-https-state
https_state: Cell<HttpsState>,
touchpad_pressure_phase: Cell<TouchpadPressurePhase>,
+ /// The document's origin.
+ origin: Origin,
}
#[derive(JSTraceable, HeapSizeOf)]
@@ -1544,14 +1547,6 @@ impl Document {
/// https://html.spec.whatwg.org/multipage/#cookie-averse-document-object
fn is_cookie_averse(&self) -> bool {
- /// https://url.spec.whatwg.org/#network-scheme
- fn url_has_network_scheme(url: &Url) -> bool {
- match &*url.scheme {
- "ftp" | "http" | "https" => true,
- _ => false,
- }
- }
-
self.browsing_context.is_none() || !url_has_network_scheme(&self.url)
}
@@ -1590,6 +1585,14 @@ impl LayoutDocumentHelpers for LayoutJS<Document> {
}
}
+/// https://url.spec.whatwg.org/#network-scheme
+fn url_has_network_scheme(url: &Url) -> bool {
+ match &*url.scheme {
+ "ftp" | "http" | "https" => true,
+ _ => false,
+ }
+}
+
impl Document {
pub fn new_inherited(window: &Window,
browsing_context: Option<&BrowsingContext>,
@@ -1608,6 +1611,15 @@ impl Document {
(DocumentReadyState::Complete, true)
};
+ // Incomplete implementation of Document origin specification at
+ // https://html.spec.whatwg.org/multipage/#origin:document
+ let origin = if url_has_network_scheme(&url) {
+ Origin::new(&url)
+ } else {
+ // Default to DOM standard behaviour
+ Origin::opaque_identifier()
+ };
+
Document {
node: Node::new_document_node(),
window: JS::from_ref(window),
@@ -1673,6 +1685,7 @@ impl Document {
css_errors_store: DOMRefCell::new(vec![]),
https_state: Cell::new(HttpsState::None),
touchpad_pressure_phase: Cell::new(TouchpadPressurePhase::BeforeClick),
+ origin: origin,
}
}
@@ -1868,9 +1881,18 @@ impl DocumentMethods for Document {
// https://html.spec.whatwg.org/multipage/#relaxing-the-same-origin-restriction
fn Domain(&self) -> DOMString {
- // TODO: This should use the effective script origin when it exists
- let origin = self.window.get_url();
- DOMString::from(origin.serialize_host().unwrap_or_else(|| "".to_owned()))
+ // Step 1.
+ if self.browsing_context().is_none() {
+ return DOMString::new();
+ }
+
+ if let Some(host) = self.origin.host() {
+ // Step 4.
+ DOMString::from(host.serialize())
+ } else {
+ // Step 3.
+ DOMString::new()
+ }
}
// https://dom.spec.whatwg.org/#dom-document-documenturi
@@ -2497,10 +2519,11 @@ impl DocumentMethods for Document {
return Ok(DOMString::new());
}
- let url = self.url();
- if !is_scheme_host_port_tuple(&url) {
+ if !self.origin.is_scheme_host_port_tuple() {
return Err(Error::Security);
}
+
+ let url = self.url();
let (tx, rx) = ipc::channel().unwrap();
let _ = self.window.resource_thread().send(GetCookiesForUrl((*url).clone(), tx, NonHTTP));
let cookies = rx.recv().unwrap();
@@ -2513,10 +2536,11 @@ impl DocumentMethods for Document {
return Ok(());
}
- let url = self.url();
- if !is_scheme_host_port_tuple(url) {
+ if !self.origin.is_scheme_host_port_tuple() {
return Err(Error::Security);
}
+
+ let url = self.url();
let _ = self.window
.resource_thread()
.send(SetCookiesForUrl((*url).clone(), String::from(cookie), NonHTTP));
@@ -2720,10 +2744,6 @@ impl DocumentMethods for Document {
}
}
-fn is_scheme_host_port_tuple(url: &Url) -> bool {
- url.host().is_some() && url.port_or_default().is_some()
-}
-
fn update_with_current_time_ms(marker: &Cell<u64>) {
if marker.get() == Default::default() {
let time = time::get_time();
diff --git a/components/script/dom/htmlbaseelement.rs b/components/script/dom/htmlbaseelement.rs
index 7f1ce7641d3..241c209c7a8 100644
--- a/components/script/dom/htmlbaseelement.rs
+++ b/components/script/dom/htmlbaseelement.rs
@@ -2,8 +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::attr::Attr;
+use dom::attr::{Attr, AttrValue};
use dom::bindings::codegen::Bindings::HTMLBaseElementBinding;
+use dom::bindings::codegen::Bindings::HTMLBaseElementBinding::HTMLBaseElementMethods;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::Root;
use dom::document::Document;
@@ -60,6 +61,33 @@ impl HTMLBaseElement {
}
}
+impl HTMLBaseElementMethods for HTMLBaseElement {
+ // https://html.spec.whatwg.org/multipage/#dom-base-href
+ fn Href(&self) -> DOMString {
+ let document = document_from_node(self);
+
+ // Step 1.
+ if !self.upcast::<Element>().has_attribute(&atom!("href")) {
+ return DOMString::from(document.base_url().serialize());
+ }
+
+ // Step 2.
+ let fallback_base_url = document.fallback_base_url();
+
+ // Step 3.
+ let url = self.upcast::<Element>().get_url_attribute(&atom!("href"));
+
+ // Step 4.
+ let url_record = fallback_base_url.join(&*url);
+
+ // Step 5, 6.
+ DOMString::from(url_record.ok().map_or("".to_owned(), |record| record.serialize()))
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-base-href
+ make_url_setter!(SetHref, "href");
+}
+
impl VirtualMethods for HTMLBaseElement {
fn super_type(&self) -> Option<&VirtualMethods> {
Some(self.upcast::<HTMLElement>() as &VirtualMethods)
diff --git a/components/script/dom/htmltableelement.rs b/components/script/dom/htmltableelement.rs
index efcc24f4370..4ea908675b1 100644
--- a/components/script/dom/htmltableelement.rs
+++ b/components/script/dom/htmltableelement.rs
@@ -118,13 +118,6 @@ impl HTMLTableElement {
thead.upcast::<Node>().remove_self();
}
}
-
- /// Determine the row index for the given `HTMLTableRowElement`.
- pub fn row_index(&self, row_elem: &HTMLTableRowElement) -> Option<usize> {
- self.Rows()
- .elements_iter()
- .position(|elem| (&elem as &Element) == row_elem.upcast::<Element>())
- }
}
impl HTMLTableElementMethods for HTMLTableElement {
diff --git a/components/script/dom/htmltablerowelement.rs b/components/script/dom/htmltablerowelement.rs
index c6d532a0323..bb83e00b0db 100644
--- a/components/script/dom/htmltablerowelement.rs
+++ b/components/script/dom/htmltablerowelement.rs
@@ -4,7 +4,9 @@
use cssparser::RGBA;
use dom::attr::AttrValue;
+use dom::bindings::codegen::Bindings::HTMLTableElementBinding::HTMLTableElementMethods;
use dom::bindings::codegen::Bindings::HTMLTableRowElementBinding::{self, HTMLTableRowElementMethods};
+use dom::bindings::codegen::Bindings::HTMLTableSectionElementBinding::HTMLTableSectionElementMethods;
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::error::{ErrorResult, Fallible};
use dom::bindings::inheritance::Castable;
@@ -54,6 +56,14 @@ impl HTMLTableRowElement {
document,
HTMLTableRowElementBinding::Wrap)
}
+
+ /// Determine the index for this `HTMLTableRowElement` within the given
+ /// `HTMLCollection`. Returns `-1` if not found within collection.
+ fn row_index(&self, collection: Root<HTMLCollection>) -> i32 {
+ collection.elements_iter()
+ .position(|elem| (&elem as &Element) == self.upcast())
+ .map_or(-1, |i| i as i32)
+ }
}
impl HTMLTableRowElementMethods for HTMLTableRowElement {
@@ -97,7 +107,7 @@ impl HTMLTableRowElementMethods for HTMLTableRowElement {
None => return -1,
};
if let Some(table) = parent.downcast::<HTMLTableElement>() {
- return table.row_index(self).map_or(-1, |i| i as i32);
+ return self.row_index(table.Rows());
}
if !parent.is::<HTMLTableSectionElement>() {
return -1;
@@ -107,8 +117,23 @@ impl HTMLTableRowElementMethods for HTMLTableRowElement {
None => return -1,
};
grandparent.downcast::<HTMLTableElement>()
- .and_then(|table| table.row_index(self))
- .map_or(-1, |i| i as i32)
+ .map_or(-1, |table| self.row_index(table.Rows()))
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-tr-sectionrowindex
+ fn SectionRowIndex(&self) -> i32 {
+ let parent = match self.upcast::<Node>().GetParentNode() {
+ Some(parent) => parent,
+ None => return -1,
+ };
+ let collection = if let Some(table) = parent.downcast::<HTMLTableElement>() {
+ table.Rows()
+ } else if let Some(table_section) = parent.downcast::<HTMLTableSectionElement>() {
+ table_section.Rows()
+ } else {
+ return -1;
+ };
+ self.row_index(collection)
}
}
diff --git a/components/script/dom/webidls/HTMLBaseElement.webidl b/components/script/dom/webidls/HTMLBaseElement.webidl
index 5c59c62f9be..549a6df1004 100644
--- a/components/script/dom/webidls/HTMLBaseElement.webidl
+++ b/components/script/dom/webidls/HTMLBaseElement.webidl
@@ -5,6 +5,6 @@
// https://html.spec.whatwg.org/multipage/#htmlbaseelement
interface HTMLBaseElement : HTMLElement {
- // attribute DOMString href;
- // attribute DOMString target;
+ attribute DOMString href;
+// attribute DOMString target;
};
diff --git a/components/script/dom/webidls/HTMLTableRowElement.webidl b/components/script/dom/webidls/HTMLTableRowElement.webidl
index 05d339aba3f..fe6c93e6be5 100644
--- a/components/script/dom/webidls/HTMLTableRowElement.webidl
+++ b/components/script/dom/webidls/HTMLTableRowElement.webidl
@@ -6,7 +6,7 @@
// https://html.spec.whatwg.org/multipage/#htmltablerowelement
interface HTMLTableRowElement : HTMLElement {
readonly attribute long rowIndex;
- //readonly attribute long sectionRowIndex;
+ readonly attribute long sectionRowIndex;
readonly attribute HTMLCollection cells;
[Throws]
HTMLElement insertCell(optional long index = -1);
diff --git a/components/script/lib.rs b/components/script/lib.rs
index d3913865070..e525a62b70d 100644
--- a/components/script/lib.rs
+++ b/components/script/lib.rs
@@ -90,6 +90,7 @@ pub mod dom;
pub mod layout_interface;
mod mem;
mod network_listener;
+pub mod origin;
pub mod page;
pub mod parse;
pub mod reporter;
diff --git a/components/script/origin.rs b/components/script/origin.rs
new file mode 100644
index 00000000000..096ffbbd6fb
--- /dev/null
+++ b/components/script/origin.rs
@@ -0,0 +1,73 @@
+/* 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 std::cell::RefCell;
+use std::rc::Rc;
+use url::{OpaqueOrigin, Origin as UrlOrigin};
+use url::{Url, Host};
+
+/// A representation of an [origin](https://html.spec.whatwg.org/multipage/#origin-2).
+#[derive(HeapSizeOf)]
+pub struct Origin {
+ #[ignore_heap_size_of = "Rc<T> has unclear ownership semantics"]
+ inner: Rc<RefCell<UrlOrigin>>,
+}
+
+// We can't use RefCell inside JSTraceable, but Origin doesn't contain JS values and
+// DOMRefCell makes it much harder to write unit tests (due to setting up required TLS).
+no_jsmanaged_fields!(Origin);
+
+impl Origin {
+ /// Create a new origin comprising a unique, opaque identifier.
+ pub fn opaque_identifier() -> Origin {
+ let opaque = UrlOrigin::UID(OpaqueOrigin::new());
+ Origin {
+ inner: Rc::new(RefCell::new(opaque)),
+ }
+ }
+
+ /// Create a new origin for the given URL.
+ pub fn new(url: &Url) -> Origin {
+ Origin {
+ inner: Rc::new(RefCell::new(url.origin())),
+ }
+ }
+
+ pub fn set(&self, origin: UrlOrigin) {
+ *self.inner.borrow_mut() = origin;
+ }
+
+ /// Does this origin represent a host/scheme/port tuple?
+ pub fn is_scheme_host_port_tuple(&self) -> bool {
+ match *self.inner.borrow() {
+ UrlOrigin::Tuple(..) => true,
+ UrlOrigin::UID(..) => false,
+ }
+ }
+
+ /// Return the host associated with this origin.
+ pub fn host(&self) -> Option<Host> {
+ match *self.inner.borrow() {
+ UrlOrigin::Tuple(_, ref host, _) => Some(host.clone()),
+ UrlOrigin::UID(..) => None,
+ }
+ }
+
+ /// https://html.spec.whatwg.org/multipage/#same-origin
+ pub fn same_origin(&self, other: &Origin) -> bool {
+ *self.inner.borrow() == *other.inner.borrow()
+ }
+
+ pub fn copy(&self) -> Origin {
+ Origin {
+ inner: Rc::new(RefCell::new(self.inner.borrow().clone())),
+ }
+ }
+
+ pub fn alias(&self) -> Origin {
+ Origin {
+ inner: self.inner.clone(),
+ }
+ }
+}