aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
Diffstat (limited to 'components/script')
-rw-r--r--components/script/dom/document.rs50
-rw-r--r--components/script/dom/element.rs33
-rw-r--r--components/script/dom/htmlhrelement.rs21
-rw-r--r--components/script/dom/htmliframeelement.rs45
-rw-r--r--components/script/dom/htmllinkelement.rs32
-rw-r--r--components/script/dom/performancetiming.rs42
-rw-r--r--components/script/dom/webidls/BrowserElement.webidl6
-rw-r--r--components/script/dom/webidls/HTMLHRElement.webidl2
-rw-r--r--components/script/dom/webidls/PerformanceTiming.webidl4
-rw-r--r--components/script/script_task.rs2
10 files changed, 200 insertions, 37 deletions
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index 6928d6f4977..af1c265a876 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -194,6 +194,13 @@ 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
+ 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>,
}
impl PartialEq for Document {
@@ -507,6 +514,12 @@ impl Document {
// https://html.spec.whatwg.org/multipage/#current-document-readiness
pub fn set_ready_state(&self, state: DocumentReadyState) {
+ match state {
+ DocumentReadyState::Loading => update_with_current_time(&self.dom_loading),
+ DocumentReadyState::Interactive => update_with_current_time(&self.dom_interactive),
+ DocumentReadyState::Complete => update_with_current_time(&self.dom_complete),
+ };
+
self.ready_state.set(state);
let event = Event::new(GlobalRef::Window(&self.window),
@@ -1226,6 +1239,9 @@ impl Document {
return;
}
self.domcontentloaded_dispatched.set(true);
+
+ update_with_current_time(&self.dom_content_loaded_event_start);
+
let event = Event::new(GlobalRef::Window(self.window()),
DOMString::from("DOMContentLoaded"),
EventBubbles::DoesNotBubble,
@@ -1233,6 +1249,8 @@ impl Document {
let doctarget = self.upcast::<EventTarget>();
let _ = doctarget.DispatchEvent(event.r());
self.window().reflow(ReflowGoal::ForDisplay, ReflowQueryType::NoQuery, ReflowReason::DOMContentLoaded);
+
+ update_with_current_time(&self.dom_content_loaded_event_end);
}
pub fn notify_constellation_load(&self) {
@@ -1258,6 +1276,26 @@ impl Document {
.filter_map(Root::downcast::<HTMLIFrameElement>)
.find(|node| node.subpage_id() == Some(subpage_id))
}
+
+ pub fn get_dom_loading(&self) -> u64 {
+ self.dom_loading.get()
+ }
+
+ pub fn get_dom_interactive(&self) -> u64 {
+ self.dom_interactive.get()
+ }
+
+ pub fn get_dom_content_loaded_event_start(&self) -> u64 {
+ self.dom_content_loaded_event_start.get()
+ }
+
+ pub fn get_dom_content_loaded_event_end(&self) -> u64 {
+ self.dom_content_loaded_event_end.get()
+ }
+
+ pub fn get_dom_complete(&self) -> u64 {
+ self.dom_complete.get()
+ }
}
#[derive(HeapSizeOf)]
@@ -1367,6 +1405,11 @@ impl Document {
appropriate_template_contents_owner_document: Default::default(),
modified_elements: DOMRefCell::new(HashMap::new()),
active_touch_points: DOMRefCell::new(Vec::new()),
+ dom_loading: Cell::new(Default::default()),
+ dom_interactive: Cell::new(Default::default()),
+ dom_content_loaded_event_start: Cell::new(Default::default()),
+ dom_content_loaded_event_end: Cell::new(Default::default()),
+ dom_complete: Cell::new(Default::default()),
}
}
@@ -2237,6 +2280,13 @@ 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>) {
+ if marker.get() == Default::default() {
+ let current_time_ms = time::get_time().sec * 1000;
+ marker.set(current_time_ms as u64);
+ }
+}
+
pub struct DocumentProgressHandler {
addr: Trusted<Document>
}
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index 158d9612442..c7e87a1535d 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -75,7 +75,6 @@ use std::default::Default;
use std::mem;
use std::sync::Arc;
use string_cache::{Atom, Namespace, QualName};
-use style::legacy::{UnsignedIntegerAttribute, from_declaration};
use style::properties::DeclaredValue;
use style::properties::longhands::{self, background_image, border_spacing, font_family, font_size};
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, parse_style_attribute};
@@ -225,8 +224,7 @@ pub trait LayoutElementHelpers {
unsafe fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, &mut V)
where V: VecLike<DeclarationBlock<Vec<PropertyDeclaration>>>;
#[allow(unsafe_code)]
- unsafe fn get_unsigned_integer_attribute_for_layout(&self, attribute: UnsignedIntegerAttribute)
- -> Option<u32>;
+ unsafe fn get_colspan(self) -> u32;
#[allow(unsafe_code)]
unsafe fn html_element_in_html_document_for_layout(&self) -> bool;
fn id_attribute(&self) -> *const Option<Atom>;
@@ -260,6 +258,12 @@ impl LayoutElementHelpers for LayoutJS<Element> {
unsafe fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, hints: &mut V)
where V: VecLike<DeclarationBlock<Vec<PropertyDeclaration>>>
{
+ #[inline]
+ fn from_declaration(rule: PropertyDeclaration)
+ -> DeclarationBlock<Vec<PropertyDeclaration>> {
+ DeclarationBlock::from_declarations(Arc::new(vec![rule]))
+ }
+
let bgcolor = if let Some(this) = self.downcast::<HTMLBodyElement>() {
this.get_background_color()
} else if let Some(this) = self.downcast::<HTMLTableElement>() {
@@ -390,6 +394,9 @@ impl LayoutElementHelpers for LayoutJS<Element> {
this.get_width()
} else if let Some(this) = self.downcast::<HTMLTableCellElement>() {
this.get_width()
+ } else if let Some(this) = self.downcast::<HTMLHRElement>() {
+ // https://html.spec.whatwg.org/multipage/#the-hr-element-2:attr-hr-width
+ this.get_width()
} else {
LengthOrPercentageOrAuto::Auto
};
@@ -500,19 +507,13 @@ impl LayoutElementHelpers for LayoutJS<Element> {
}
#[allow(unsafe_code)]
- unsafe fn get_unsigned_integer_attribute_for_layout(&self,
- attribute: UnsignedIntegerAttribute)
- -> Option<u32> {
- match attribute {
- UnsignedIntegerAttribute::ColSpan => {
- if let Some(this) = self.downcast::<HTMLTableCellElement>() {
- this.get_colspan()
- } else {
- // Don't panic since `display` can cause this to be called on arbitrary
- // elements.
- None
- }
- }
+ unsafe fn get_colspan(self) -> u32 {
+ if let Some(this) = self.downcast::<HTMLTableCellElement>() {
+ this.get_colspan().unwrap_or(1)
+ } else {
+ // Don't panic since `display` can cause this to be called on arbitrary
+ // elements.
+ 1
}
}
diff --git a/components/script/dom/htmlhrelement.rs b/components/script/dom/htmlhrelement.rs
index eabd970c6f5..8b6cf338786 100644
--- a/components/script/dom/htmlhrelement.rs
+++ b/components/script/dom/htmlhrelement.rs
@@ -13,7 +13,7 @@ use dom::htmlelement::HTMLElement;
use dom::node::Node;
use dom::virtualmethods::VirtualMethods;
use string_cache::Atom;
-use util::str::DOMString;
+use util::str::{DOMString, LengthOrPercentageOrAuto};
#[dom_struct]
pub struct HTMLHRElement {
@@ -42,10 +42,17 @@ impl HTMLHRElementMethods for HTMLHRElement {
// https://html.spec.whatwg.org/multipage/#dom-hr-color
make_legacy_color_setter!(SetColor, "color");
+
+ // https://html.spec.whatwg.org/multipage/#dom-hr-width
+ make_getter!(Width);
+
+ // https://html.spec.whatwg.org/multipage/#dom-hr-width
+ make_dimension_setter!(SetWidth, "width");
}
pub trait HTMLHRLayoutHelpers {
fn get_color(&self) -> Option<RGBA>;
+ fn get_width(&self) -> LengthOrPercentageOrAuto;
}
impl HTMLHRLayoutHelpers for LayoutJS<HTMLHRElement> {
@@ -58,6 +65,17 @@ impl HTMLHRLayoutHelpers for LayoutJS<HTMLHRElement> {
.cloned()
}
}
+
+ #[allow(unsafe_code)]
+ fn get_width(&self) -> LengthOrPercentageOrAuto {
+ unsafe {
+ (&*self.upcast::<Element>().unsafe_get())
+ .get_attr_for_layout(&ns!(""), &atom!("width"))
+ .map(AttrValue::as_dimension)
+ .cloned()
+ .unwrap_or(LengthOrPercentageOrAuto::Auto)
+ }
+ }
}
@@ -69,6 +87,7 @@ impl VirtualMethods for HTMLHRElement {
fn parse_plain_attribute(&self, name: &Atom, value: DOMString) -> AttrValue {
match name {
&atom!("color") => AttrValue::from_legacy_color(value),
+ &atom!("width") => AttrValue::from_dimension(value),
_ => self.super_type().unwrap().parse_plain_attribute(name, value),
}
}
diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs
index 2281c9e371f..edb45fbb14b 100644
--- a/components/script/dom/htmliframeelement.rs
+++ b/components/script/dom/htmliframeelement.rs
@@ -3,6 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::attr::{Attr, AttrValue};
+use dom::bindings::codegen::Bindings::BrowserElementBinding::BrowserElementIconChangeEventDetail;
use dom::bindings::codegen::Bindings::HTMLIFrameElementBinding;
use dom::bindings::codegen::Bindings::HTMLIFrameElementBinding::HTMLIFrameElementMethods;
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
@@ -21,8 +22,8 @@ use dom::node::{Node, window_from_node};
use dom::urlhelper::UrlHelper;
use dom::virtualmethods::VirtualMethods;
use dom::window::Window;
-use js::jsapi::{JSAutoCompartment, JSAutoRequest, RootedValue};
-use js::jsval::UndefinedValue;
+use js::jsapi::{JSAutoCompartment, JSAutoRequest, RootedValue, JSContext, MutableHandleValue};
+use js::jsval::{UndefinedValue, NullValue};
use msg::constellation_msg::IFrameSandboxState::{IFrameSandboxed, IFrameUnsandboxed};
use msg::constellation_msg::Msg as ConstellationMsg;
use msg::constellation_msg::{ConstellationChan, IframeLoadInfo, MozBrowserEvent};
@@ -143,9 +144,10 @@ impl HTMLIFrameElement {
let _ar = JSAutoRequest::new(cx);
let _ac = JSAutoCompartment::new(cx, window.reflector().get_jsobject().get());
let mut detail = RootedValue::new(cx, UndefinedValue());
- event.detail().to_jsval(cx, detail.handle_mut());
+ let event_name = DOMString::from(event.name().to_owned());
+ self.build_mozbrowser_event_detail(event, cx, detail.handle_mut());
CustomEvent::new(GlobalRef::Window(window.r()),
- DOMString::from(event.name()),
+ event_name,
true,
true,
detail.handle())
@@ -225,6 +227,41 @@ impl HTMLIFrameElementLayoutMethods for LayoutJS<HTMLIFrameElement> {
}
}
+pub trait MozBrowserEventDetailBuilder {
+ #[allow(unsafe_code)]
+ unsafe fn build_mozbrowser_event_detail(&self,
+ event: MozBrowserEvent,
+ cx: *mut JSContext,
+ rval: MutableHandleValue);
+}
+
+impl MozBrowserEventDetailBuilder for HTMLIFrameElement {
+ #[allow(unsafe_code)]
+ unsafe fn build_mozbrowser_event_detail(&self,
+ event: MozBrowserEvent,
+ cx: *mut JSContext,
+ rval: MutableHandleValue) {
+ match event {
+ MozBrowserEvent::AsyncScroll | MozBrowserEvent::Close | MozBrowserEvent::ContextMenu |
+ MozBrowserEvent::Error | MozBrowserEvent::LoadEnd | MozBrowserEvent::LoadStart |
+ MozBrowserEvent::OpenWindow | MozBrowserEvent::SecurityChange | MozBrowserEvent::OpenSearch |
+ MozBrowserEvent::ShowModalPrompt | MozBrowserEvent::UsernameAndPasswordRequired => {
+ rval.set(NullValue());
+ }
+ MozBrowserEvent::LocationChange(ref string) | MozBrowserEvent::TitleChange(ref string) => {
+ string.to_jsval(cx, rval);
+ }
+ MozBrowserEvent::IconChange(rel, href, sizes) => {
+ BrowserElementIconChangeEventDetail {
+ rel: Some(DOMString::from(rel)),
+ href: Some(DOMString::from(href)),
+ sizes: Some(DOMString::from(sizes)),
+ }.to_jsval(cx, rval);
+ }
+ }
+ }
+}
+
pub fn Navigate(iframe: &HTMLIFrameElement, direction: NavigationDirection) -> Fallible<()> {
if iframe.Mozbrowser() {
if iframe.upcast::<Node>().is_in_doc() {
diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs
index 2860c98dd5c..a7365c38a69 100644
--- a/components/script/dom/htmllinkelement.rs
+++ b/components/script/dom/htmllinkelement.rs
@@ -24,8 +24,8 @@ use encoding::all::UTF_8;
use ipc_channel::ipc;
use ipc_channel::router::ROUTER;
use layout_interface::{LayoutChan, Msg};
-use msg::constellation_msg::ConstellationChan;
use msg::constellation_msg::Msg as ConstellationMsg;
+use msg::constellation_msg::{ConstellationChan, MozBrowserEvent};
use net_traits::{AsyncResponseListener, AsyncResponseTarget, Metadata};
use network_listener::{NetworkListener, PreInvoke};
use std::ascii::AsciiExt;
@@ -102,7 +102,7 @@ fn is_favicon(value: &Option<String>) -> bool {
match *value {
Some(ref value) => {
value.split(HTML_SPACE_CHARACTERS)
- .any(|s| s.eq_ignore_ascii_case("icon"))
+ .any(|s| s.eq_ignore_ascii_case("icon") || s.eq_ignore_ascii_case("apple-touch-icon"))
},
None => false,
}
@@ -118,13 +118,22 @@ impl VirtualMethods for HTMLLinkElement {
if !self.upcast::<Node>().is_in_doc() || mutation == AttributeMutation::Removed {
return;
}
+
let rel = get_attr(self.upcast(), &atom!(rel));
match attr.local_name() {
&atom!(href) => {
if string_is_stylesheet(&rel) {
self.handle_stylesheet_url(&attr.value());
} else if is_favicon(&rel) {
- self.handle_favicon_url(&attr.value());
+ let sizes = get_attr(self.upcast(), &atom!("sizes"));
+ self.handle_favicon_url(rel.as_ref().unwrap(), &attr.value(), &sizes);
+ }
+ },
+ &atom!("sizes") => {
+ if is_favicon(&rel) {
+ if let Some(ref href) = get_attr(self.upcast(), &atom!("href")) {
+ self.handle_favicon_url(rel.as_ref().unwrap(), href, &Some(attr.value().to_string()));
+ }
}
},
&atom!(media) => {
@@ -153,13 +162,14 @@ impl VirtualMethods for HTMLLinkElement {
let rel = get_attr(element, &atom!("rel"));
let href = get_attr(element, &atom!("href"));
+ let sizes = get_attr(self.upcast(), &atom!("sizes"));
- match (rel, href) {
- (ref rel, Some(ref href)) if string_is_stylesheet(rel) => {
+ match href {
+ Some(ref href) if string_is_stylesheet(&rel) => {
self.handle_stylesheet_url(href);
}
- (ref rel, Some(ref href)) if is_favicon(rel) => {
- self.handle_favicon_url(href);
+ Some(ref href) if is_favicon(&rel) => {
+ self.handle_favicon_url(rel.as_ref().unwrap(), href, &sizes);
}
_ => {}
}
@@ -219,7 +229,7 @@ impl HTMLLinkElement {
}
}
- fn handle_favicon_url(&self, href: &str) {
+ fn handle_favicon_url(&self, rel: &str, href: &str, sizes: &Option<String>) {
let window = window_from_node(self);
let window = window.r();
match UrlParser::new().base_url(&window.get_url()).parse(href) {
@@ -227,6 +237,12 @@ impl HTMLLinkElement {
let ConstellationChan(ref chan) = window.constellation_chan();
let event = ConstellationMsg::NewFavicon(url.clone());
chan.send(event).unwrap();
+
+ let mozbrowser_event = match *sizes {
+ Some(ref sizes) => MozBrowserEvent::IconChange(rel.to_owned(), url.to_string(), sizes.to_owned()),
+ None => MozBrowserEvent::IconChange(rel.to_owned(), url.to_string(), "".to_owned())
+ };
+ window.Document().trigger_mozbrowser_event(mozbrowser_event);
}
Err(e) => debug!("Parsing url {} failed: {}", href, e)
}
diff --git a/components/script/dom/performancetiming.rs b/components/script/dom/performancetiming.rs
index 1799d6a7f91..c9f2458de3e 100644
--- a/components/script/dom/performancetiming.rs
+++ b/components/script/dom/performancetiming.rs
@@ -4,9 +4,11 @@
use dom::bindings::codegen::Bindings::PerformanceTimingBinding;
use dom::bindings::codegen::Bindings::PerformanceTimingBinding::PerformanceTimingMethods;
+use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::global::GlobalRef;
-use dom::bindings::js::Root;
+use dom::bindings::js::{JS, Root};
use dom::bindings::reflector::{Reflector, reflect_dom_object};
+use dom::document::Document;
use dom::window::Window;
#[dom_struct]
@@ -14,15 +16,19 @@ pub struct PerformanceTiming {
reflector_: Reflector,
navigationStart: u64,
navigationStartPrecise: f64,
+ document: JS<Document>,
}
impl PerformanceTiming {
- fn new_inherited(navStart: u64, navStartPrecise: f64)
+ fn new_inherited(navStart: u64,
+ navStartPrecise: f64,
+ document: &Document)
-> PerformanceTiming {
PerformanceTiming {
reflector_: Reflector::new(),
navigationStart: navStart,
navigationStartPrecise: navStartPrecise,
+ document: JS::from_ref(document),
}
}
@@ -31,19 +37,45 @@ impl PerformanceTiming {
navigation_start: u64,
navigation_start_precise: f64)
-> Root<PerformanceTiming> {
+
let timing = PerformanceTiming::new_inherited(navigation_start,
- navigation_start_precise);
+ navigation_start_precise,
+ window.Document().r());
reflect_dom_object(box timing, GlobalRef::Window(window),
PerformanceTimingBinding::Wrap)
}
}
impl PerformanceTimingMethods for PerformanceTiming {
- // https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/
- // NavigationTiming/Overview.html#dom-performancetiming-navigationstart
+ // https://w3c.github.io/navigation-timing/#widl-PerformanceTiming-navigationStart
fn NavigationStart(&self) -> u64 {
self.navigationStart
}
+
+ // https://w3c.github.io/navigation-timing/#widl-PerformanceTiming-domLoading
+ fn DomLoading(&self) -> u64 {
+ self.document.get_dom_loading()
+ }
+
+ // https://w3c.github.io/navigation-timing/#widl-PerformanceTiming-domInteractive
+ fn DomInteractive(&self) -> u64 {
+ self.document.get_dom_interactive()
+ }
+
+ // https://w3c.github.io/navigation-timing/#widl-PerformanceTiming-domContentLoadedEventStart
+ fn DomContentLoadedEventStart(&self) -> u64 {
+ self.document.get_dom_content_loaded_event_start()
+ }
+
+ // https://w3c.github.io/navigation-timing/#widl-PerformanceTiming-domContentLoadedEventEnd
+ fn DomContentLoadedEventEnd(&self) -> u64 {
+ self.document.get_dom_content_loaded_event_end()
+ }
+
+ // https://w3c.github.io/navigation-timing/#widl-PerformanceTiming-domComplete
+ fn DomComplete(&self) -> u64 {
+ self.document.get_dom_complete()
+ }
}
diff --git a/components/script/dom/webidls/BrowserElement.webidl b/components/script/dom/webidls/BrowserElement.webidl
index 6b4e9a8cf04..2ba6ceb1a01 100644
--- a/components/script/dom/webidls/BrowserElement.webidl
+++ b/components/script/dom/webidls/BrowserElement.webidl
@@ -24,6 +24,12 @@ callback BrowserElementNextPaintEventCallback = void ();
interface BrowserElement {
};
+dictionary BrowserElementIconChangeEventDetail {
+ DOMString rel;
+ DOMString href;
+ DOMString sizes;
+};
+
BrowserElement implements BrowserElementCommon;
BrowserElement implements BrowserElementPrivileged;
diff --git a/components/script/dom/webidls/HTMLHRElement.webidl b/components/script/dom/webidls/HTMLHRElement.webidl
index 185100712f5..f203527b2bf 100644
--- a/components/script/dom/webidls/HTMLHRElement.webidl
+++ b/components/script/dom/webidls/HTMLHRElement.webidl
@@ -14,5 +14,5 @@ partial interface HTMLHRElement {
attribute DOMString color;
// attribute boolean noShade;
// attribute DOMString size;
- // attribute DOMString width;
+ attribute DOMString width;
};
diff --git a/components/script/dom/webidls/PerformanceTiming.webidl b/components/script/dom/webidls/PerformanceTiming.webidl
index b066b4be2dc..a016f2b1616 100644
--- a/components/script/dom/webidls/PerformanceTiming.webidl
+++ b/components/script/dom/webidls/PerformanceTiming.webidl
@@ -21,12 +21,12 @@ interface PerformanceTiming {
readonly attribute unsigned long long secureConnectionStart;
readonly attribute unsigned long long requestStart;
readonly attribute unsigned long long responseStart;
- readonly attribute unsigned long long responseEnd;
+ readonly attribute unsigned long long responseEnd; */
readonly attribute unsigned long long domLoading;
readonly attribute unsigned long long domInteractive;
readonly attribute unsigned long long domContentLoadedEventStart;
readonly attribute unsigned long long domContentLoadedEventEnd;
readonly attribute unsigned long long domComplete;
- readonly attribute unsigned long long loadEventStart;
+ /* readonly attribute unsigned long long loadEventStart;
readonly attribute unsigned long long loadEventEnd; */
};
diff --git a/components/script/script_task.rs b/components/script/script_task.rs
index b0648f6f27c..c3ddfdad6b3 100644
--- a/components/script/script_task.rs
+++ b/components/script/script_task.rs
@@ -1642,6 +1642,8 @@ impl ScriptTask {
let frame_element = frame_element.r().map(Castable::upcast);
window.init_browsing_context(document.r(), frame_element);
+ document.set_ready_state(DocumentReadyState::Loading);
+
// Create the root frame
page.set_frame(Some(Frame {
document: JS::from_rooted(&document),