diff options
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/document.rs | 50 | ||||
-rw-r--r-- | components/script/dom/element.rs | 33 | ||||
-rw-r--r-- | components/script/dom/htmlhrelement.rs | 21 | ||||
-rw-r--r-- | components/script/dom/htmliframeelement.rs | 45 | ||||
-rw-r--r-- | components/script/dom/htmllinkelement.rs | 32 | ||||
-rw-r--r-- | components/script/dom/performancetiming.rs | 42 | ||||
-rw-r--r-- | components/script/dom/webidls/BrowserElement.webidl | 6 | ||||
-rw-r--r-- | components/script/dom/webidls/HTMLHRElement.webidl | 2 | ||||
-rw-r--r-- | components/script/dom/webidls/PerformanceTiming.webidl | 4 | ||||
-rw-r--r-- | components/script/script_task.rs | 2 |
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), |