diff options
author | Glenn Watson <gw@intuitionlibrary.com> | 2015-03-13 15:08:02 +1000 |
---|---|---|
committer | Glenn Watson <gw@intuitionlibrary.com> | 2015-03-17 09:35:41 +1000 |
commit | 939a89568e9506c2c6ffbd1f49e3acda6acdf370 (patch) | |
tree | d760bf3ad5309c910b9f4e0f5518403a2fbf2e8b /components/script/dom | |
parent | 0888a3a16d4f5eafe4f8008ec060764645f3bee5 (diff) | |
download | servo-939a89568e9506c2c6ffbd1f49e3acda6acdf370.tar.gz servo-939a89568e9506c2c6ffbd1f49e3acda6acdf370.zip |
First part of refactoring constellation to support iframe navigation.
The history is now recorded per frame, but needs to be exposed in a followup PR.
Also fixes a race condition that occurs loading iframes under heavy CPU load.
This ensures that iframes never do a reflow / layout until they have a valid
window size set from their parent frame.
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/htmlformelement.rs | 2 | ||||
-rw-r--r-- | components/script/dom/htmliframeelement.rs | 27 | ||||
-rw-r--r-- | components/script/dom/window.rs | 21 |
3 files changed, 29 insertions, 21 deletions
diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs index 9c2148334e2..ebe033cea37 100644 --- a/components/script/dom/htmlformelement.rs +++ b/components/script/dom/htmlformelement.rs @@ -215,7 +215,7 @@ impl<'a> HTMLFormElementHelpers for JSRef<'a, HTMLFormElement> { } // This is wrong. https://html.spec.whatwg.org/multipage/forms.html#planned-navigation - win.r().script_chan().send(ScriptMsg::TriggerLoad(win.r().pipeline(), load_data)).unwrap(); + win.r().script_chan().send(ScriptMsg::Navigate(win.r().pipeline(), load_data)).unwrap(); } fn get_form_dataset<'b>(self, submitter: Option<FormSubmitter<'b>>) -> Vec<FormDatum> { diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index 1bd9071be01..61ce736bb7e 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -63,6 +63,7 @@ pub trait HTMLIFrameElementHelpers { /// http://www.whatwg.org/html/#process-the-iframe-attributes fn process_the_iframe_attributes(self); fn generate_new_subpage_id(self) -> (SubpageId, Option<SubpageId>); + fn navigate_child_browsing_context(self, url: Url); } impl<'a> HTMLIFrameElementHelpers for JSRef<'a, HTMLIFrameElement> { @@ -92,12 +93,7 @@ impl<'a> HTMLIFrameElementHelpers for JSRef<'a, HTMLIFrameElement> { (subpage_id, old_subpage_id) } - fn process_the_iframe_attributes(self) { - let url = match self.get_url() { - Some(url) => url.clone(), - None => Url::parse("about:blank").unwrap(), - }; - + fn navigate_child_browsing_context(self, url: Url) { let sandboxed = if self.is_sandboxed() { IFrameSandboxed } else { @@ -111,11 +107,20 @@ impl<'a> HTMLIFrameElementHelpers for JSRef<'a, HTMLIFrameElement> { self.containing_page_pipeline_id.set(Some(window.pipeline())); let ConstellationChan(ref chan) = window.constellation_chan(); - chan.send(ConstellationMsg::ScriptLoadedURLInIFrame(url, - window.pipeline(), - new_subpage_id, - old_subpage_id, - sandboxed)).unwrap(); + chan.send(ConstellationMsg::ScriptLoadedURLInIFrame(url, + window.pipeline(), + new_subpage_id, + old_subpage_id, + sandboxed)).unwrap(); + } + + fn process_the_iframe_attributes(self) { + let url = match self.get_url() { + Some(url) => url.clone(), + None => Url::parse("about:blank").unwrap(), + }; + + self.navigate_child_browsing_context(url); } } diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 1e67ebaaa60..70c12abc9f3 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -135,7 +135,7 @@ pub struct Window { layout_join_port: DOMRefCell<Option<Receiver<()>>>, /// The current size of the window, in pixels. - window_size: Cell<WindowSizeData>, + window_size: Cell<Option<WindowSizeData>>, /// Associated resource task for use by DOM objects like XMLHttpRequest resource_task: ResourceTask, @@ -428,7 +428,7 @@ pub trait WindowHelpers { fn set_fragment_name(self, fragment: Option<String>); fn steal_fragment_name(self) -> Option<String>; fn set_window_size(self, size: WindowSizeData); - fn window_size(self) -> WindowSizeData; + fn window_size(self) -> Option<WindowSizeData>; fn get_url(self) -> Url; fn resource_task(self) -> ResourceTask; fn devtools_chan(self) -> Option<DevtoolsControlChan>; @@ -517,6 +517,11 @@ impl<'a> WindowHelpers for JSRef<'a, Window> { return } + let window_size = match self.window_size.get() { + Some(window_size) => window_size, + None => return, + }; + // Layout will let us know when it's done. let (join_chan, join_port) = channel(); @@ -528,8 +533,6 @@ impl<'a> WindowHelpers for JSRef<'a, Window> { let last_reflow_id = &self.last_reflow_id; last_reflow_id.set(last_reflow_id.get() + 1); - let window_size = self.window_size.get(); - // On debug mode, print the reflow event information. if opts::get().relayout_event { debug_reflow_events(&goal, &query_type, &reason); @@ -607,7 +610,7 @@ impl<'a> WindowHelpers for JSRef<'a, Window> { } fn handle_resize_inactive_msg(self, new_size: WindowSizeData) { - self.window_size.set(new_size); + self.window_size.set(Some(new_size)); } fn init_browser_context(self, doc: JSRef<Document>, frame_element: Option<JSRef<Element>>) { @@ -626,7 +629,7 @@ impl<'a> WindowHelpers for JSRef<'a, Window> { self.script_chan.send(ScriptMsg::TriggerFragment(self.id, fragment)).unwrap(); }, None => { - self.script_chan.send(ScriptMsg::TriggerLoad(self.id, LoadData::new(url))).unwrap(); + self.script_chan.send(ScriptMsg::Navigate(self.id, LoadData::new(url))).unwrap(); } } } @@ -645,10 +648,10 @@ impl<'a> WindowHelpers for JSRef<'a, Window> { } fn set_window_size(self, size: WindowSizeData) { - self.window_size.set(size); + self.window_size.set(Some(size)); } - fn window_size(self) -> WindowSizeData { + fn window_size(self) -> Option<WindowSizeData> { self.window_size.get() } @@ -755,7 +758,7 @@ impl Window { layout_chan: LayoutChan, id: PipelineId, subpage_id: Option<SubpageId>, - window_size: WindowSizeData) + window_size: Option<WindowSizeData>) -> Temporary<Window> { let layout_rpc: Box<LayoutRPC> = { let (rpc_send, rpc_recv) = channel(); |