aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom
diff options
context:
space:
mode:
authorGlenn Watson <gw@intuitionlibrary.com>2015-03-13 15:08:02 +1000
committerGlenn Watson <gw@intuitionlibrary.com>2015-03-17 09:35:41 +1000
commit939a89568e9506c2c6ffbd1f49e3acda6acdf370 (patch)
treed760bf3ad5309c910b9f4e0f5518403a2fbf2e8b /components/script/dom
parent0888a3a16d4f5eafe4f8008ec060764645f3bee5 (diff)
downloadservo-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.rs2
-rw-r--r--components/script/dom/htmliframeelement.rs27
-rw-r--r--components/script/dom/window.rs21
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();