Browser API: implement iframe.reload()

This commit is contained in:
Paul Rouget 2015-12-08 04:39:37 +01:00
parent 9cccd34bc4
commit 2a86f9d165
6 changed files with 67 additions and 13 deletions

View file

@ -790,6 +790,17 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
// containing_page_pipeline_id's frame tree's children. This message is never the result of a
// page navigation.
fn handle_script_loaded_url_in_iframe_msg(&mut self, load_info: IframeLoadInfo) {
let old_pipeline_id = load_info.old_subpage_id.map(|old_subpage_id| {
self.find_subpage(load_info.containing_pipeline_id, old_subpage_id).id
});
// If no url is specified, reload.
let new_url = match (old_pipeline_id, load_info.url) {
(_, Some(ref url)) => url.clone(),
(Some(old_pipeline_id), None) => self.pipeline(old_pipeline_id).url.clone(),
(None, None) => url!("about:blank"),
};
// Compare the pipeline's url to the new url. If the origin is the same,
// then reuse the script task in creating the new pipeline
let script_chan = {
@ -797,27 +808,24 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
let source_url = source_pipeline.url.clone();
let same_script = (source_url.host() == load_info.url.host() &&
source_url.port() == load_info.url.port()) &&
let same_script = (source_url.host() == new_url.host() &&
source_url.port() == new_url.port()) &&
load_info.sandbox == IFrameSandboxState::IFrameUnsandboxed;
// FIXME(tkuehn): Need to follow the standardized spec for checking same-origin
// Reuse the script task if the URL is same-origin
if same_script {
debug!("Constellation: loading same-origin iframe, \
parent url {:?}, iframe url {:?}", source_url, load_info.url);
parent url {:?}, iframe url {:?}", source_url, new_url);
Some(source_pipeline.script_chan.clone())
} else {
debug!("Constellation: loading cross-origin iframe, \
parent url {:?}, iframe url {:?}", source_url, load_info.url);
parent url {:?}, iframe url {:?}", source_url, new_url);
None
}
};
// Create the new pipeline, attached to the parent and push to pending frames
let old_pipeline_id = load_info.old_subpage_id.map(|old_subpage_id| {
self.find_subpage(load_info.containing_pipeline_id, old_subpage_id).id
});
let window_size = old_pipeline_id.and_then(|old_pipeline_id| {
self.pipeline(old_pipeline_id).size
});
@ -825,7 +833,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
Some((load_info.containing_pipeline_id, load_info.new_subpage_id)),
window_size,
script_chan,
LoadData::new(load_info.url));
LoadData::new(new_url));
self.subpage_map.insert((load_info.containing_pipeline_id, load_info.new_subpage_id),
load_info.new_pipeline_id);

View file

@ -217,7 +217,7 @@ bitflags! {
#[derive(Deserialize, Serialize)]
pub struct IframeLoadInfo {
/// Url to load
pub url: Url,
pub url: Option<Url>,
/// Pipeline ID of the parent of this iframe
pub containing_pipeline_id: PipelineId,
/// The new subpage ID for this load

View file

@ -90,7 +90,7 @@ impl HTMLIFrameElement {
(subpage_id, old_subpage_id)
}
pub fn navigate_child_browsing_context(&self, url: Url) {
pub fn navigate_or_reload_child_browsing_context(&self, url: Option<Url>) {
let sandboxed = if self.is_sandboxed() {
IFrameSandboxed
} else {
@ -127,7 +127,7 @@ impl HTMLIFrameElement {
None => url!("about:blank"),
};
self.navigate_child_browsing_context(url);
self.navigate_or_reload_child_browsing_context(Some(url));
}
#[allow(unsafe_code)]
@ -399,7 +399,12 @@ impl HTMLIFrameElementMethods for HTMLIFrameElement {
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/reload
fn Reload(&self, _hardReload: bool) -> Fallible<()> {
Err(Error::NotSupported)
if mozbrowser_enabled() {
if self.upcast::<Node>().is_in_doc() {
self.navigate_or_reload_child_browsing_context(None);
}
}
Ok(())
}
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/stop

View file

@ -1943,7 +1943,7 @@ impl ScriptTask {
doc.find_iframe(subpage_id)
});
if let Some(iframe) = iframe.r() {
iframe.navigate_child_browsing_context(load_data.url);
iframe.navigate_or_reload_child_browsing_context(Some(load_data.url));
}
}
None => {

View file

@ -5643,6 +5643,12 @@
"url": "/_mozilla/mozilla/mozbrowser/mozbrowsericonchange_event.html"
}
],
"mozilla/mozbrowser/reload.html": [
{
"path": "mozilla/mozbrowser/reload.html",
"url": "/_mozilla/mozilla/mozbrowser/reload.html"
}
],
"mozilla/navigator.html": [
{
"path": "mozilla/navigator.html",

View file

@ -0,0 +1,35 @@
<head>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<script>
async_test(function(t) {
const SRC = "data:,foobar";
const RELOAD_MAX_COUNT = 5;
var iframe = document.createElement("iframe");
iframe.mozbrowser = "true";
iframe.src = SRC;
var reload_count = 0;
iframe.addEventListener("mozbrowserloadend", t.step_func(e => {
reload_count++;
assert_equals(SRC, e.target.src);
if (reload_count == RELOAD_MAX_COUNT) {
t.done();
} else {
iframe.reload();
}
}));
document.body.appendChild(iframe);
});
</script>
</body>