aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/htmliframeelement.rs
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2016-06-16 08:53:56 -0500
committerGitHub <noreply@github.com>2016-06-16 08:53:56 -0500
commitd620ab71c41431c3fb040162f554faefb9abfbd7 (patch)
tree902c90598821bee9998194bb14f65c7b3e9bbab9 /components/script/dom/htmliframeelement.rs
parentff67f80f36106cba4a89c48d8c8d59c9880856c7 (diff)
parent2bff131535987da0330737f78fb23291593db30d (diff)
downloadservo-d620ab71c41431c3fb040162f554faefb9abfbd7.tar.gz
servo-d620ab71c41431c3fb040162f554faefb9abfbd7.zip
Auto merge of #10225 - jmr0:visibility_api, r=jdm
Implement non-visible pipeline and iframe visibility methods This addresses #9566 and a good part of #9751, specifically: * Pipeline has a notion of visibility * IFrame setVisible/getVisible interface with IFrame's pipeline visibility * IFrame mozbrowservisibilitychange responds to changes in visibility * Pipeline visibility is used to limit animations (requestAnimationFrame does not tick animations when hidden) and to increase timer intervals (currently set to a minimum of 1 second while hidden) Absent for now are any changes to the Document API and general implementation of the Page Visibility API, since the more interesting parts require knowledge of whether the user agent is minimized, OS screen locked, etc. cc @paulrouget @jdm <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/10225) <!-- Reviewable:end -->
Diffstat (limited to 'components/script/dom/htmliframeelement.rs')
-rw-r--r--components/script/dom/htmliframeelement.rs54
1 files changed, 53 insertions, 1 deletions
diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs
index 57248c03e97..86146b8e915 100644
--- a/components/script/dom/htmliframeelement.rs
+++ b/components/script/dom/htmliframeelement.rs
@@ -11,12 +11,13 @@ use dom::bindings::codegen::Bindings::BrowserElementBinding::BrowserElementLocat
use dom::bindings::codegen::Bindings::BrowserElementBinding::BrowserElementOpenTabEventDetail;
use dom::bindings::codegen::Bindings::BrowserElementBinding::BrowserElementOpenWindowEventDetail;
use dom::bindings::codegen::Bindings::BrowserElementBinding::BrowserElementSecurityChangeDetail;
+use dom::bindings::codegen::Bindings::BrowserElementBinding::BrowserElementVisibilityChangeEventDetail;
use dom::bindings::codegen::Bindings::BrowserElementBinding::BrowserShowModalPromptEventDetail;
use dom::bindings::codegen::Bindings::HTMLIFrameElementBinding;
use dom::bindings::codegen::Bindings::HTMLIFrameElementBinding::HTMLIFrameElementMethods;
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::conversions::ToJSValConvertible;
-use dom::bindings::error::{Error, ErrorResult};
+use dom::bindings::error::{Error, ErrorResult, Fallible};
use dom::bindings::global::GlobalRef;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, MutNullableHeap, Root, LayoutJS};
@@ -68,6 +69,7 @@ pub struct HTMLIFrameElement {
sandbox: MutNullableHeap<JS<DOMTokenList>>,
sandbox_allowance: Cell<Option<u8>>,
load_blocker: DOMRefCell<Option<LoadBlocker>>,
+ visibility: Cell<bool>,
}
impl HTMLIFrameElement {
@@ -199,6 +201,7 @@ impl HTMLIFrameElement {
sandbox: Default::default(),
sandbox_allowance: Cell::new(None),
load_blocker: DOMRefCell::new(None),
+ visibility: Cell::new(true),
}
}
@@ -224,6 +227,26 @@ impl HTMLIFrameElement {
self.pipeline_id.get()
}
+ pub fn change_visibility_status(&self, visibility: bool) {
+ if self.visibility.get() != visibility {
+ self.visibility.set(visibility);
+
+ // Visibility changes are only exposed to Mozbrowser iframes
+ if self.Mozbrowser() {
+ self.dispatch_mozbrowser_event(MozBrowserEvent::VisibilityChange(visibility));
+ }
+ }
+ }
+
+ pub fn set_visible(&self, visible: bool) {
+ if let Some(pipeline_id) = self.pipeline_id.get() {
+ let window = window_from_node(self);
+ let window = window.r();
+ let msg = ConstellationMsg::SetVisible(pipeline_id, visible);
+ window.constellation_chan().send(msg).unwrap();
+ }
+ }
+
/// https://html.spec.whatwg.org/multipage/#iframe-load-event-steps steps 1-4
pub fn iframe_load_event_steps(&self, loaded_pipeline: PipelineId) {
// TODO(#9592): assert that the load blocker is present at all times when we
@@ -390,6 +413,11 @@ impl MozBrowserEventDetailBuilder for HTMLIFrameElement {
returnValue: Some(DOMString::from(return_value)),
}.to_jsval(cx, rval)
}
+ MozBrowserEvent::VisibilityChange(visibility) => {
+ BrowserElementVisibilityChangeEventDetail {
+ visible: Some(visibility),
+ }.to_jsval(cx, rval);
+ }
}
}
}
@@ -496,6 +524,30 @@ impl HTMLIFrameElementMethods for HTMLIFrameElement {
}
}
+ // https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/setVisible
+ fn SetVisible(&self, visible: bool) -> ErrorResult {
+ if self.Mozbrowser() {
+ self.set_visible(visible);
+ Ok(())
+ } else {
+ debug!("this frame is not mozbrowser: mozbrowser attribute missing, or not a top
+ level window, or mozbrowser preference not set (use --pref dom.mozbrowser.enabled)");
+ Err(Error::NotSupported)
+ }
+ }
+
+ // https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/getVisible
+ fn GetVisible(&self) -> Fallible<bool> {
+ if self.Mozbrowser() {
+ Ok(self.visibility.get())
+ } else {
+ debug!("this frame is not mozbrowser: mozbrowser attribute missing, or not a top
+ level window, or mozbrowser preference not set (use --pref dom.mozbrowser.enabled)");
+ Err(Error::NotSupported)
+ }
+ }
+
+
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/stop
fn Stop(&self) -> ErrorResult {
Err(Error::NotSupported)