aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/document.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/document.rs')
-rw-r--r--components/script/dom/document.rs96
1 files changed, 68 insertions, 28 deletions
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index ad68be7175f..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;
@@ -209,18 +210,22 @@ pub struct Document {
modified_elements: DOMRefCell<HashMap<JS<Element>, ElementSnapshot>>,
/// http://w3c.github.io/touch-events/#dfn-active-touch-point
active_touch_points: DOMRefCell<Vec<JS<Touch>>>,
- /// DOM-Related Navigation Timing properties:
- /// http://w3c.github.io/navigation-timing/#widl-PerformanceTiming-domLoading
+ /// Navigation Timing properties:
+ /// https://w3c.github.io/navigation-timing/#sec-PerformanceNavigationTiming
dom_loading: Cell<u64>,
dom_interactive: Cell<u64>,
dom_content_loaded_event_start: Cell<u64>,
dom_content_loaded_event_end: Cell<u64>,
dom_complete: Cell<u64>,
+ load_event_start: Cell<u64>,
+ load_event_end: Cell<u64>,
/// Vector to store CSS errors
css_errors_store: DOMRefCell<Vec<CSSError>>,
/// 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)]
@@ -544,14 +549,14 @@ impl Document {
DocumentReadyState::Loading => {
// https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowserconnected
self.trigger_mozbrowser_event(MozBrowserEvent::Connected);
- update_with_current_time(&self.dom_loading);
+ update_with_current_time_ms(&self.dom_loading);
},
DocumentReadyState::Complete => {
// https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowserloadend
self.trigger_mozbrowser_event(MozBrowserEvent::LoadEnd);
- update_with_current_time(&self.dom_complete);
+ update_with_current_time_ms(&self.dom_complete);
},
- DocumentReadyState::Interactive => update_with_current_time(&self.dom_interactive),
+ DocumentReadyState::Interactive => update_with_current_time_ms(&self.dom_interactive),
};
self.ready_state.set(state);
@@ -1447,7 +1452,7 @@ impl Document {
}
self.domcontentloaded_dispatched.set(true);
- update_with_current_time(&self.dom_content_loaded_event_start);
+ update_with_current_time_ms(&self.dom_content_loaded_event_start);
let chan = MainThreadScriptChan(self.window().main_thread_script_chan().clone()).clone();
let doctarget = Trusted::new(self.upcast::<EventTarget>(), chan);
@@ -1458,7 +1463,7 @@ impl Document {
ReflowQueryType::NoQuery,
ReflowReason::DOMContentLoaded);
- update_with_current_time(&self.dom_content_loaded_event_end);
+ update_with_current_time_ms(&self.dom_content_loaded_event_end);
}
pub fn notify_constellation_load(&self) {
@@ -1513,6 +1518,14 @@ impl Document {
self.dom_complete.get()
}
+ pub fn get_load_event_start(&self) -> u64 {
+ self.load_event_start.get()
+ }
+
+ pub fn get_load_event_end(&self) -> u64 {
+ self.load_event_end.get()
+ }
+
// https://html.spec.whatwg.org/multipage/#fire-a-focus-event
fn fire_focus_event(&self, focus_event_type: FocusEventType, node: &Node, relatedTarget: Option<&EventTarget>) {
let (event_name, does_bubble) = match focus_event_type {
@@ -1534,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)
}
@@ -1580,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>,
@@ -1598,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),
@@ -1658,9 +1680,12 @@ impl Document {
dom_content_loaded_event_start: Cell::new(Default::default()),
dom_content_loaded_event_end: Cell::new(Default::default()),
dom_complete: Cell::new(Default::default()),
+ load_event_start: Cell::new(Default::default()),
+ load_event_end: Cell::new(Default::default()),
css_errors_store: DOMRefCell::new(vec![]),
https_state: Cell::new(HttpsState::None),
touchpad_pressure_phase: Cell::new(TouchpadPressurePhase::BeforeClick),
+ origin: origin,
}
}
@@ -1856,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
@@ -2485,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();
@@ -2501,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));
@@ -2708,13 +2744,10 @@ 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(marker: &Cell<u64>) {
+fn update_with_current_time_ms(marker: &Cell<u64>) {
if marker.get() == Default::default() {
- let current_time_ms = time::get_time().sec * 1000;
+ let time = time::get_time();
+ let current_time_ms = time.sec * 1000 + time.nsec as i64 / 1000000;
marker.set(current_time_ms as u64);
}
}
@@ -2744,8 +2777,15 @@ impl DocumentProgressHandler {
EventCancelable::NotCancelable);
let wintarget = window.upcast::<EventTarget>();
event.set_trusted(true);
+
+ // http://w3c.github.io/navigation-timing/#widl-PerformanceNavigationTiming-loadEventStart
+ update_with_current_time_ms(&document.load_event_start);
+
let _ = wintarget.dispatch_event_with_target(document.upcast(), &event);
+ // http://w3c.github.io/navigation-timing/#widl-PerformanceNavigationTiming-loadEventEnd
+ update_with_current_time_ms(&document.load_event_end);
+
document.notify_constellation_load();
window.reflow(ReflowGoal::ForDisplay,