Make link elements fire a load event.

This commit is contained in:
Josh Matthews 2015-04-22 20:12:24 -04:00
parent 32a89c9455
commit f3cdba6b8b
8 changed files with 78 additions and 10 deletions

View file

@ -8,13 +8,16 @@ use dom::attr::AttrHelpers;
use dom::bindings::codegen::Bindings::HTMLLinkElementBinding;
use dom::bindings::codegen::Bindings::HTMLLinkElementBinding::HTMLLinkElementMethods;
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::codegen::InheritTypes::HTMLLinkElementDerived;
use dom::bindings::codegen::InheritTypes::{EventTargetCast, HTMLLinkElementDerived};
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, NodeCast};
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, JSRef, MutNullableHeap, Rootable, Temporary};
use dom::bindings::js::{OptionalRootable, RootedReference};
use dom::bindings::refcounted::Trusted;
use dom::document::{Document, DocumentHelpers};
use dom::domtokenlist::DOMTokenList;
use dom::element::{AttributeHandlers, Element};
use dom::event::{EventBubbles, EventCancelable, Event, EventHelpers};
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::element::ElementTypeId;
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
@ -22,6 +25,7 @@ use dom::node::{Node, NodeHelpers, NodeTypeId, window_from_node};
use dom::virtualmethods::VirtualMethods;
use dom::window::WindowHelpers;
use layout_interface::{LayoutChan, Msg};
use script_traits::StylesheetLoadResponder;
use util::str::{DOMString, HTML_SPACE_CHARACTERS};
use style::media_queries::parse_media_query_list;
use style::node::TElement;
@ -152,9 +156,12 @@ impl<'a> PrivateHTMLLinkElementHelpers for JSRef<'a, HTMLLinkElement> {
let media = parse_media_query_list(&mut css_parser);
let doc = window.Document().root();
let link_element = Trusted::new(window.get_cx(), self, window.script_chan().clone());
let load_dispatcher = StylesheetLoadDispatcher::new(link_element);
let pending = doc.r().prep_async_load(LoadType::Stylesheet(url.clone()));
let LayoutChan(ref layout_chan) = window.layout_chan();
layout_chan.send(Msg::LoadStylesheet(url, media, pending)).unwrap();
layout_chan.send(Msg::LoadStylesheet(url, media, pending, box load_dispatcher)).unwrap();
}
Err(e) => debug!("Parsing url {} failed: {}", href, e)
}
@ -183,3 +190,27 @@ impl<'a> HTMLLinkElementMethods for JSRef<'a, HTMLLinkElement> {
})
}
}
pub struct StylesheetLoadDispatcher {
elem: Trusted<HTMLLinkElement>,
}
impl StylesheetLoadDispatcher {
pub fn new(elem: Trusted<HTMLLinkElement>) -> StylesheetLoadDispatcher {
StylesheetLoadDispatcher {
elem: elem,
}
}
}
impl StylesheetLoadResponder for StylesheetLoadDispatcher {
fn respond(self: Box<StylesheetLoadDispatcher>) {
let elem = self.elem.to_temporary().root();
let window = window_from_node(elem.r()).root();
let event = Event::new(GlobalRef::Window(window.r()), "load".to_owned(),
EventBubbles::DoesNotBubble,
EventCancelable::NotCancelable).root();
let target = EventTargetCast::from_ref(elem.r());
event.r().fire(target);
}
}

View file

@ -15,6 +15,7 @@ use msg::constellation_msg::{PipelineExitType, WindowSizeData};
use net_traits::PendingAsyncLoad;
use profile_traits::mem::{Reporter, ReportsChan};
use script_traits::{ScriptControlChan, OpaqueScriptLayoutChannel, UntrustedNodeAddress};
use script_traits::StylesheetLoadResponder;
use std::any::Any;
use std::sync::mpsc::{channel, Receiver, Sender};
use style::animation::PropertyAnimation;
@ -31,7 +32,7 @@ pub enum Msg {
AddStylesheet(Stylesheet, MediaQueryList),
/// Adds the given stylesheet to the document.
LoadStylesheet(Url, MediaQueryList, PendingAsyncLoad),
LoadStylesheet(Url, MediaQueryList, PendingAsyncLoad, Box<StylesheetLoadResponder+Send>),
/// Puts a document into quirks mode, causing the quirks mode stylesheet to be loaded.
SetQuirksMode,

View file

@ -731,8 +731,10 @@ impl ScriptTask {
self.handle_webdriver_msg(pipeline_id, msg),
ConstellationControlMsg::TickAllAnimations(pipeline_id) =>
self.handle_tick_all_animations(pipeline_id),
ConstellationControlMsg::StylesheetLoadComplete(id, url) =>
self.handle_resource_loaded(id, LoadType::Stylesheet(url)),
ConstellationControlMsg::StylesheetLoadComplete(id, url, responder) => {
self.handle_resource_loaded(id, LoadType::Stylesheet(url));
responder.respond();
}
}
}