mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Add support for fullscreen #10102
This commit is contained in:
parent
c3c086e521
commit
55f0e56224
33 changed files with 454 additions and 30 deletions
18
Cargo.lock
generated
18
Cargo.lock
generated
|
@ -1075,7 +1075,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"html5ever-atoms 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"html5ever-atoms 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"mac 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mac 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"phf 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
"phf 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1088,7 +1088,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "html5ever-atoms"
|
name = "html5ever-atoms"
|
||||||
version = "0.1.1"
|
version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1272,7 +1272,7 @@ dependencies = [
|
||||||
"gfx_traits 0.0.1",
|
"gfx_traits 0.0.1",
|
||||||
"heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"html5ever-atoms 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"html5ever-atoms 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -2189,7 +2189,7 @@ dependencies = [
|
||||||
"heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"html5ever 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"html5ever 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"html5ever-atoms 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"html5ever-atoms 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hyper 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hyper 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hyper_serde 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hyper_serde 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"image 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"image 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -2247,7 +2247,7 @@ dependencies = [
|
||||||
"gfx_traits 0.0.1",
|
"gfx_traits 0.0.1",
|
||||||
"heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"html5ever-atoms 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"html5ever-atoms 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -2598,7 +2598,7 @@ dependencies = [
|
||||||
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"heapsize 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"html5ever-atoms 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"html5ever-atoms 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -2635,7 +2635,7 @@ dependencies = [
|
||||||
"app_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"app_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cssparser 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cssparser 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"html5ever-atoms 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"html5ever-atoms 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"owning_ref 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"owning_ref 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parking_lot 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -3192,7 +3192,7 @@ name = "xml5ever"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"html5ever-atoms 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"html5ever-atoms 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"mac 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mac 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"phf 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
"phf 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -3290,7 +3290,7 @@ dependencies = [
|
||||||
"checksum heartbeats-simple-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53c4b67617665d7f4172f381f9843c1bec6a4fccc9a9226529e5b1be40dc1301"
|
"checksum heartbeats-simple-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53c4b67617665d7f4172f381f9843c1bec6a4fccc9a9226529e5b1be40dc1301"
|
||||||
"checksum hpack 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d2da7d3a34cf6406d9d700111b8eafafe9a251de41ae71d8052748259343b58"
|
"checksum hpack 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d2da7d3a34cf6406d9d700111b8eafafe9a251de41ae71d8052748259343b58"
|
||||||
"checksum html5ever 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)" = "45815593feb142cf01121b9f413d8630c9902192d160e494a579c50628eef498"
|
"checksum html5ever 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)" = "45815593feb142cf01121b9f413d8630c9902192d160e494a579c50628eef498"
|
||||||
"checksum html5ever-atoms 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "daefa106438c66af58309c84842b5db1df2733fe35849f39adde6fdf63583d40"
|
"checksum html5ever-atoms 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fd3fc831590ee7fcf693c673e4e3cbe14fbda44dc0f26d9bdc79cfc9f551dc05"
|
||||||
"checksum httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "46534074dbb80b070d60a5cb8ecadd8963a00a438ae1a95268850a7ef73b67ae"
|
"checksum httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "46534074dbb80b070d60a5cb8ecadd8963a00a438ae1a95268850a7ef73b67ae"
|
||||||
"checksum hyper 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)" = "edd47c66782933e546a32ae89ca3c49263b2ba9bc29f3a0d5c52fff48e0ac67c"
|
"checksum hyper 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)" = "edd47c66782933e546a32ae89ca3c49263b2ba9bc29f3a0d5c52fff48e0ac67c"
|
||||||
"checksum hyper_serde 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "572d2168173019de312a050a24f2ad33ac2ac7895a2139fbf21ee6b6f470a24e"
|
"checksum hyper_serde 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "572d2168173019de312a050a24f2ad33ac2ac7895a2139fbf21ee6b6f470a24e"
|
||||||
|
|
|
@ -78,3 +78,5 @@ statechange
|
||||||
controllerchange
|
controllerchange
|
||||||
fetch
|
fetch
|
||||||
characteristicvaluechanged
|
characteristicvaluechanged
|
||||||
|
fullscreenchange
|
||||||
|
fullscreenerror
|
||||||
|
|
|
@ -633,6 +633,10 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||||
func();
|
func();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(Msg::SetFullscreenState(state), ShutdownState::NotShuttingDown) => {
|
||||||
|
self.window.set_fullscreen_state(state);
|
||||||
|
}
|
||||||
|
|
||||||
// When we are shutting_down, we need to avoid performing operations
|
// When we are shutting_down, we need to avoid performing operations
|
||||||
// such as Paint that may crash because we have begun tearing down
|
// such as Paint that may crash because we have begun tearing down
|
||||||
// the rest of our resources.
|
// the rest of our resources.
|
||||||
|
|
|
@ -128,7 +128,9 @@ pub enum Msg {
|
||||||
/// Runs a closure in the compositor thread.
|
/// Runs a closure in the compositor thread.
|
||||||
/// It's used to dispatch functions from webrender to the main thread's event loop.
|
/// It's used to dispatch functions from webrender to the main thread's event loop.
|
||||||
/// Required to allow WGL GLContext sharing in Windows.
|
/// Required to allow WGL GLContext sharing in Windows.
|
||||||
Dispatch(Box<Fn() + Send>)
|
Dispatch(Box<Fn() + Send>),
|
||||||
|
/// Enter or exit fullscreen
|
||||||
|
SetFullscreenState(bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for Msg {
|
impl Debug for Msg {
|
||||||
|
@ -161,6 +163,7 @@ impl Debug for Msg {
|
||||||
Msg::PipelineExited(..) => write!(f, "PipelineExited"),
|
Msg::PipelineExited(..) => write!(f, "PipelineExited"),
|
||||||
Msg::NewScrollFrameReady(..) => write!(f, "NewScrollFrameReady"),
|
Msg::NewScrollFrameReady(..) => write!(f, "NewScrollFrameReady"),
|
||||||
Msg::Dispatch(..) => write!(f, "Dispatch"),
|
Msg::Dispatch(..) => write!(f, "Dispatch"),
|
||||||
|
Msg::SetFullscreenState(..) => write!(f, "SetFullscreenState"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,6 +119,8 @@ pub trait WindowMethods {
|
||||||
fn set_inner_size(&self, size: Size2D<u32>);
|
fn set_inner_size(&self, size: Size2D<u32>);
|
||||||
/// Set the window position
|
/// Set the window position
|
||||||
fn set_position(&self, point: Point2D<i32>);
|
fn set_position(&self, point: Point2D<i32>);
|
||||||
|
/// Set fullscreen state
|
||||||
|
fn set_fullscreen_state(&self, state: bool);
|
||||||
|
|
||||||
/// Sets the page title for the current page.
|
/// Sets the page title for the current page.
|
||||||
fn set_page_title(&self, title: Option<String>);
|
fn set_page_title(&self, title: Option<String>);
|
||||||
|
|
|
@ -1090,6 +1090,9 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
FromScriptMsg::BroadcastStorageEvent(pipeline_id, storage, url, key, old_value, new_value) => {
|
FromScriptMsg::BroadcastStorageEvent(pipeline_id, storage, url, key, old_value, new_value) => {
|
||||||
self.handle_broadcast_storage_event(pipeline_id, storage, url, key, old_value, new_value);
|
self.handle_broadcast_storage_event(pipeline_id, storage, url, key, old_value, new_value);
|
||||||
}
|
}
|
||||||
|
FromScriptMsg::SetFullscreenState(state) => {
|
||||||
|
self.compositor_proxy.send(ToCompositorMsg::SetFullscreenState(state));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,6 +150,8 @@ impl Formattable for ProfilerCategory {
|
||||||
ProfilerCategory::ScriptWebSocketEvent => "Script Web Socket Event",
|
ProfilerCategory::ScriptWebSocketEvent => "Script Web Socket Event",
|
||||||
ProfilerCategory::ScriptWorkerEvent => "Script Worker Event",
|
ProfilerCategory::ScriptWorkerEvent => "Script Worker Event",
|
||||||
ProfilerCategory::ScriptServiceWorkerEvent => "Script Service Worker Event",
|
ProfilerCategory::ScriptServiceWorkerEvent => "Script Service Worker Event",
|
||||||
|
ProfilerCategory::ScriptEnterFullscreen => "Script Enter Fullscreen",
|
||||||
|
ProfilerCategory::ScriptExitFullscreen => "Script Exit Fullscreen",
|
||||||
ProfilerCategory::ApplicationHeartbeat => "Application Heartbeat",
|
ProfilerCategory::ApplicationHeartbeat => "Application Heartbeat",
|
||||||
};
|
};
|
||||||
format!("{}{}", padding, name)
|
format!("{}{}", padding, name)
|
||||||
|
|
|
@ -86,6 +86,8 @@ pub enum ProfilerCategory {
|
||||||
ScriptWorkerEvent = 0x74,
|
ScriptWorkerEvent = 0x74,
|
||||||
ScriptServiceWorkerEvent = 0x75,
|
ScriptServiceWorkerEvent = 0x75,
|
||||||
ScriptParseXML = 0x76,
|
ScriptParseXML = 0x76,
|
||||||
|
ScriptEnterFullscreen = 0x77,
|
||||||
|
ScriptExitFullscreen = 0x78,
|
||||||
ApplicationHeartbeat = 0x90,
|
ApplicationHeartbeat = 0x90,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ use dom::bindings::inheritance::{Castable, ElementTypeId, HTMLElementTypeId, Nod
|
||||||
use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root};
|
use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root};
|
||||||
use dom::bindings::js::RootedReference;
|
use dom::bindings::js::RootedReference;
|
||||||
use dom::bindings::num::Finite;
|
use dom::bindings::num::Finite;
|
||||||
use dom::bindings::refcounted::Trusted;
|
use dom::bindings::refcounted::{Trusted, TrustedPromise};
|
||||||
use dom::bindings::reflector::{DomObject, reflect_dom_object};
|
use dom::bindings::reflector::{DomObject, reflect_dom_object};
|
||||||
use dom::bindings::str::{DOMString, USVString};
|
use dom::bindings::str::{DOMString, USVString};
|
||||||
use dom::bindings::xmlname::{namespace_from_domstring, validate_and_extract, xml_name_type};
|
use dom::bindings::xmlname::{namespace_from_domstring, validate_and_extract, xml_name_type};
|
||||||
|
@ -39,7 +39,7 @@ use dom::customevent::CustomEvent;
|
||||||
use dom::documentfragment::DocumentFragment;
|
use dom::documentfragment::DocumentFragment;
|
||||||
use dom::documenttype::DocumentType;
|
use dom::documenttype::DocumentType;
|
||||||
use dom::domimplementation::DOMImplementation;
|
use dom::domimplementation::DOMImplementation;
|
||||||
use dom::element::{Element, ElementCreator};
|
use dom::element::{Element, ElementCreator, ElementPerformFullscreenEnter, ElementPerformFullscreenExit};
|
||||||
use dom::errorevent::ErrorEvent;
|
use dom::errorevent::ErrorEvent;
|
||||||
use dom::event::{Event, EventBubbles, EventCancelable};
|
use dom::event::{Event, EventBubbles, EventCancelable};
|
||||||
use dom::eventdispatcher::EventStatus;
|
use dom::eventdispatcher::EventStatus;
|
||||||
|
@ -74,6 +74,7 @@ use dom::pagetransitionevent::PageTransitionEvent;
|
||||||
use dom::popstateevent::PopStateEvent;
|
use dom::popstateevent::PopStateEvent;
|
||||||
use dom::processinginstruction::ProcessingInstruction;
|
use dom::processinginstruction::ProcessingInstruction;
|
||||||
use dom::progressevent::ProgressEvent;
|
use dom::progressevent::ProgressEvent;
|
||||||
|
use dom::promise::Promise;
|
||||||
use dom::range::Range;
|
use dom::range::Range;
|
||||||
use dom::servoparser::ServoParser;
|
use dom::servoparser::ServoParser;
|
||||||
use dom::storageevent::StorageEvent;
|
use dom::storageevent::StorageEvent;
|
||||||
|
@ -105,6 +106,7 @@ use net_traits::response::HttpsState;
|
||||||
use num_traits::ToPrimitive;
|
use num_traits::ToPrimitive;
|
||||||
use origin::Origin;
|
use origin::Origin;
|
||||||
use script_layout_interface::message::{Msg, ReflowQueryType};
|
use script_layout_interface::message::{Msg, ReflowQueryType};
|
||||||
|
use script_runtime::{CommonScriptMsg, ScriptThreadEventCategory};
|
||||||
use script_thread::{MainThreadScriptMsg, Runnable};
|
use script_thread::{MainThreadScriptMsg, Runnable};
|
||||||
use script_traits::{AnimationState, CompositorEvent, MouseButton, MouseEventType, MozBrowserEvent};
|
use script_traits::{AnimationState, CompositorEvent, MouseButton, MouseEventType, MozBrowserEvent};
|
||||||
use script_traits::{ScriptMsg as ConstellationMsg, TouchpadPressurePhase};
|
use script_traits::{ScriptMsg as ConstellationMsg, TouchpadPressurePhase};
|
||||||
|
@ -290,6 +292,8 @@ pub struct Document {
|
||||||
///
|
///
|
||||||
/// See also: https://github.com/servo/servo/issues/10110
|
/// See also: https://github.com/servo/servo/issues/10110
|
||||||
dom_count: Cell<u32>,
|
dom_count: Cell<u32>,
|
||||||
|
/// Entry node for fullscreen.
|
||||||
|
fullscreen_element: MutNullableHeap<JS<Element>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(JSTraceable, HeapSizeOf)]
|
#[derive(JSTraceable, HeapSizeOf)]
|
||||||
|
@ -1907,6 +1911,7 @@ impl Document {
|
||||||
last_click_info: DOMRefCell::new(None),
|
last_click_info: DOMRefCell::new(None),
|
||||||
ignore_destructive_writes_counter: Default::default(),
|
ignore_destructive_writes_counter: Default::default(),
|
||||||
dom_count: Cell::new(1),
|
dom_count: Cell::new(1),
|
||||||
|
fullscreen_element: MutNullableHeap::new(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2092,6 +2097,110 @@ impl Document {
|
||||||
self.ignore_destructive_writes_counter.set(
|
self.ignore_destructive_writes_counter.set(
|
||||||
self.ignore_destructive_writes_counter.get() - 1);
|
self.ignore_destructive_writes_counter.get() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://fullscreen.spec.whatwg.org/#dom-element-requestfullscreen
|
||||||
|
#[allow(unrooted_must_root)]
|
||||||
|
pub fn enter_fullscreen(&self, pending: &Element) -> Rc<Promise> {
|
||||||
|
// Step 1
|
||||||
|
let promise = Promise::new(self.global().r());
|
||||||
|
let mut error = false;
|
||||||
|
|
||||||
|
// Step 4
|
||||||
|
// check namespace
|
||||||
|
match *pending.namespace() {
|
||||||
|
ns!(mathml) => {
|
||||||
|
if pending.local_name().as_ref() != "math" {
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ns!(svg) => {
|
||||||
|
if pending.local_name().as_ref() != "svg" {
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ns!(html) => (),
|
||||||
|
_ => error = true,
|
||||||
|
}
|
||||||
|
// fullscreen element ready check
|
||||||
|
if !pending.fullscreen_element_ready_check() {
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
// TODO fullscreen is supported
|
||||||
|
// TODO This algorithm is allowed to request fullscreen.
|
||||||
|
|
||||||
|
// Step 5 Parallel start
|
||||||
|
|
||||||
|
let window = self.window();
|
||||||
|
// Step 6
|
||||||
|
if !error {
|
||||||
|
let event = ConstellationMsg::SetFullscreenState(true);
|
||||||
|
window.upcast::<GlobalScope>().constellation_chan().send(event).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 7
|
||||||
|
let trusted_pending = Trusted::new(pending);
|
||||||
|
let trusted_promise = TrustedPromise::new(promise.clone());
|
||||||
|
let handler = ElementPerformFullscreenEnter::new(trusted_pending, trusted_promise, error);
|
||||||
|
let script_msg = CommonScriptMsg::RunnableMsg(ScriptThreadEventCategory::EnterFullscreen, handler);
|
||||||
|
let msg = MainThreadScriptMsg::Common(script_msg);
|
||||||
|
window.main_thread_script_chan().send(msg).unwrap();
|
||||||
|
|
||||||
|
promise
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://fullscreen.spec.whatwg.org/#exit-fullscreen
|
||||||
|
#[allow(unrooted_must_root)]
|
||||||
|
pub fn exit_fullscreen(&self) -> Rc<Promise> {
|
||||||
|
let global = self.global();
|
||||||
|
// Step 1
|
||||||
|
let promise = Promise::new(global.r());
|
||||||
|
// Step 2
|
||||||
|
if self.fullscreen_element.get().is_none() {
|
||||||
|
promise.reject_error(global.get_cx(), Error::Type(String::from("fullscreen is null")));
|
||||||
|
return promise
|
||||||
|
}
|
||||||
|
// TODO Step 3-6
|
||||||
|
let element = self.fullscreen_element.get().unwrap();
|
||||||
|
|
||||||
|
// Step 7 Parallel start
|
||||||
|
|
||||||
|
let window = self.window();
|
||||||
|
// Step 8
|
||||||
|
let event = ConstellationMsg::SetFullscreenState(false);
|
||||||
|
window.upcast::<GlobalScope>().constellation_chan().send(event).unwrap();
|
||||||
|
|
||||||
|
// Step 9
|
||||||
|
let trusted_element = Trusted::new(element.r());
|
||||||
|
let trusted_promise = TrustedPromise::new(promise.clone());
|
||||||
|
let handler = ElementPerformFullscreenExit::new(trusted_element, trusted_promise);
|
||||||
|
let script_msg = CommonScriptMsg::RunnableMsg(ScriptThreadEventCategory::ExitFullscreen, handler);
|
||||||
|
let msg = MainThreadScriptMsg::Common(script_msg);
|
||||||
|
window.main_thread_script_chan().send(msg).unwrap();
|
||||||
|
|
||||||
|
promise
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_fullscreen_element(&self, element: Option<&Element>) {
|
||||||
|
self.fullscreen_element.set(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_allow_fullscreen(&self) -> bool {
|
||||||
|
// https://html.spec.whatwg.org/multipage/#allowed-to-use
|
||||||
|
match self.browsing_context() {
|
||||||
|
// Step 1
|
||||||
|
None => false,
|
||||||
|
Some(_) => {
|
||||||
|
// Step 2
|
||||||
|
let window = self.window();
|
||||||
|
if window.is_top_level() {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
// Step 3
|
||||||
|
window.GetFrameElement().map_or(false, |el| el.has_attribute(&local_name!("allowfullscreen")))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3109,6 +3218,34 @@ impl DocumentMethods for Document {
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#documentandelementeventhandlers
|
// https://html.spec.whatwg.org/multipage/#documentandelementeventhandlers
|
||||||
document_and_element_event_handlers!();
|
document_and_element_event_handlers!();
|
||||||
|
|
||||||
|
// https://fullscreen.spec.whatwg.org/#handler-document-onfullscreenerror
|
||||||
|
event_handler!(fullscreenerror, GetOnfullscreenerror, SetOnfullscreenerror);
|
||||||
|
|
||||||
|
// https://fullscreen.spec.whatwg.org/#handler-document-onfullscreenchange
|
||||||
|
event_handler!(fullscreenchange, GetOnfullscreenchange, SetOnfullscreenchange);
|
||||||
|
|
||||||
|
// https://fullscreen.spec.whatwg.org/#dom-document-fullscreenenabled
|
||||||
|
fn FullscreenEnabled(&self) -> bool {
|
||||||
|
self.get_allow_fullscreen()
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://fullscreen.spec.whatwg.org/#dom-document-fullscreen
|
||||||
|
fn Fullscreen(&self) -> bool {
|
||||||
|
self.fullscreen_element.get().is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://fullscreen.spec.whatwg.org/#dom-document-fullscreenelement
|
||||||
|
fn GetFullscreenElement(&self) -> Option<Root<Element>> {
|
||||||
|
// TODO ShadowRoot
|
||||||
|
self.fullscreen_element.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unrooted_must_root)]
|
||||||
|
// https://fullscreen.spec.whatwg.org/#dom-document-exitfullscreen
|
||||||
|
fn ExitFullscreen(&self) -> Rc<Promise> {
|
||||||
|
self.exit_fullscreen()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_with_current_time_ms(marker: &Cell<u64>) {
|
fn update_with_current_time_ms(marker: &Cell<u64>) {
|
||||||
|
|
|
@ -24,6 +24,8 @@ use dom::bindings::error::{Error, ErrorResult, Fallible};
|
||||||
use dom::bindings::inheritance::{Castable, ElementTypeId, HTMLElementTypeId, NodeTypeId};
|
use dom::bindings::inheritance::{Castable, ElementTypeId, HTMLElementTypeId, NodeTypeId};
|
||||||
use dom::bindings::js::{JS, LayoutJS, MutNullableHeap};
|
use dom::bindings::js::{JS, LayoutJS, MutNullableHeap};
|
||||||
use dom::bindings::js::{Root, RootedReference};
|
use dom::bindings::js::{Root, RootedReference};
|
||||||
|
use dom::bindings::refcounted::{Trusted, TrustedPromise};
|
||||||
|
use dom::bindings::reflector::DomObject;
|
||||||
use dom::bindings::str::DOMString;
|
use dom::bindings::str::DOMString;
|
||||||
use dom::bindings::xmlname::{namespace_from_domstring, validate_and_extract, xml_name_type};
|
use dom::bindings::xmlname::{namespace_from_domstring, validate_and_extract, xml_name_type};
|
||||||
use dom::bindings::xmlname::XMLName::InvalidXMLName;
|
use dom::bindings::xmlname::XMLName::InvalidXMLName;
|
||||||
|
@ -35,6 +37,7 @@ use dom::domrect::DOMRect;
|
||||||
use dom::domrectlist::DOMRectList;
|
use dom::domrectlist::DOMRectList;
|
||||||
use dom::domtokenlist::DOMTokenList;
|
use dom::domtokenlist::DOMTokenList;
|
||||||
use dom::event::Event;
|
use dom::event::Event;
|
||||||
|
use dom::eventtarget::EventTarget;
|
||||||
use dom::htmlanchorelement::HTMLAnchorElement;
|
use dom::htmlanchorelement::HTMLAnchorElement;
|
||||||
use dom::htmlbodyelement::{HTMLBodyElement, HTMLBodyElementLayoutHelpers};
|
use dom::htmlbodyelement::{HTMLBodyElement, HTMLBodyElementLayoutHelpers};
|
||||||
use dom::htmlbuttonelement::HTMLButtonElement;
|
use dom::htmlbuttonelement::HTMLButtonElement;
|
||||||
|
@ -62,18 +65,23 @@ use dom::node::{CLICK_IN_PROGRESS, ChildrenMutation, LayoutNodeHelpers, Node};
|
||||||
use dom::node::{NodeDamage, SEQUENTIALLY_FOCUSABLE, UnbindContext};
|
use dom::node::{NodeDamage, SEQUENTIALLY_FOCUSABLE, UnbindContext};
|
||||||
use dom::node::{document_from_node, window_from_node};
|
use dom::node::{document_from_node, window_from_node};
|
||||||
use dom::nodelist::NodeList;
|
use dom::nodelist::NodeList;
|
||||||
|
use dom::promise::Promise;
|
||||||
use dom::servoparser::ServoParser;
|
use dom::servoparser::ServoParser;
|
||||||
use dom::text::Text;
|
use dom::text::Text;
|
||||||
use dom::validation::Validatable;
|
use dom::validation::Validatable;
|
||||||
use dom::virtualmethods::{VirtualMethods, vtable_for};
|
use dom::virtualmethods::{VirtualMethods, vtable_for};
|
||||||
|
use dom::window::ReflowReason;
|
||||||
use html5ever::serialize;
|
use html5ever::serialize;
|
||||||
use html5ever::serialize::SerializeOpts;
|
use html5ever::serialize::SerializeOpts;
|
||||||
use html5ever::serialize::TraversalScope;
|
use html5ever::serialize::TraversalScope;
|
||||||
use html5ever::serialize::TraversalScope::{ChildrenOnly, IncludeNode};
|
use html5ever::serialize::TraversalScope::{ChildrenOnly, IncludeNode};
|
||||||
use html5ever::tree_builder::{LimitedQuirks, NoQuirks, Quirks};
|
use html5ever::tree_builder::{LimitedQuirks, NoQuirks, Quirks};
|
||||||
use html5ever_atoms::{Prefix, LocalName, Namespace, QualName};
|
use html5ever_atoms::{Prefix, LocalName, Namespace, QualName};
|
||||||
|
use js::jsapi::{HandleValue, JSAutoCompartment};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use ref_filter_map::ref_filter_map;
|
use ref_filter_map::ref_filter_map;
|
||||||
|
use script_layout_interface::message::ReflowQueryType;
|
||||||
|
use script_thread::Runnable;
|
||||||
use selectors::matching::{ElementFlags, MatchingReason, matches};
|
use selectors::matching::{ElementFlags, MatchingReason, matches};
|
||||||
use selectors::matching::{HAS_EDGE_CHILD_SELECTOR, HAS_SLOW_SELECTOR, HAS_SLOW_SELECTOR_LATER_SIBLINGS};
|
use selectors::matching::{HAS_EDGE_CHILD_SELECTOR, HAS_SLOW_SELECTOR, HAS_SLOW_SELECTOR_LATER_SIBLINGS};
|
||||||
use selectors::parser::{AttrSelector, NamespaceConstraint};
|
use selectors::parser::{AttrSelector, NamespaceConstraint};
|
||||||
|
@ -84,9 +92,11 @@ use std::cell::{Cell, Ref};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
use style::attr::{AttrValue, LengthOrPercentageOrAuto};
|
use style::attr::{AttrValue, LengthOrPercentageOrAuto};
|
||||||
|
use style::context::ReflowGoal;
|
||||||
use style::dom::TRestyleDamage;
|
use style::dom::TRestyleDamage;
|
||||||
use style::element_state::*;
|
use style::element_state::*;
|
||||||
use style::matching::{common_style_affecting_attributes, rare_style_affecting_attributes};
|
use style::matching::{common_style_affecting_attributes, rare_style_affecting_attributes};
|
||||||
|
@ -1300,6 +1310,15 @@ impl Element {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://fullscreen.spec.whatwg.org/#fullscreen-element-ready-check
|
||||||
|
pub fn fullscreen_element_ready_check(&self) -> bool {
|
||||||
|
if !self.is_connected() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
let document = document_from_node(self);
|
||||||
|
document.get_allow_fullscreen()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ElementMethods for Element {
|
impl ElementMethods for Element {
|
||||||
|
@ -2056,6 +2075,13 @@ impl ElementMethods for Element {
|
||||||
None => return Err(Error::NotSupported)
|
None => return Err(Error::NotSupported)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://fullscreen.spec.whatwg.org/#dom-element-requestfullscreen
|
||||||
|
#[allow(unrooted_must_root)]
|
||||||
|
fn RequestFullscreen(&self) -> Rc<Promise> {
|
||||||
|
let doc = document_from_node(self);
|
||||||
|
doc.enter_fullscreen(self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fragment_affecting_attributes() -> [LocalName; 3] {
|
pub fn fragment_affecting_attributes() -> [LocalName; 3] {
|
||||||
|
@ -2167,6 +2193,10 @@ impl VirtualMethods for Element {
|
||||||
}
|
}
|
||||||
|
|
||||||
let doc = document_from_node(self);
|
let doc = document_from_node(self);
|
||||||
|
let fullscreen = doc.GetFullscreenElement();
|
||||||
|
if fullscreen.r() == Some(self) {
|
||||||
|
doc.exit_fullscreen();
|
||||||
|
}
|
||||||
if let Some(ref value) = *self.id_attribute.borrow() {
|
if let Some(ref value) = *self.id_attribute.borrow() {
|
||||||
doc.unregister_named_element(self, value.clone());
|
doc.unregister_named_element(self, value.clone());
|
||||||
}
|
}
|
||||||
|
@ -2307,6 +2337,7 @@ impl<'a> ::selectors::Element for Root<Element> {
|
||||||
|
|
||||||
NonTSPseudoClass::Active |
|
NonTSPseudoClass::Active |
|
||||||
NonTSPseudoClass::Focus |
|
NonTSPseudoClass::Focus |
|
||||||
|
NonTSPseudoClass::Fullscreen |
|
||||||
NonTSPseudoClass::Hover |
|
NonTSPseudoClass::Hover |
|
||||||
NonTSPseudoClass::Enabled |
|
NonTSPseudoClass::Enabled |
|
||||||
NonTSPseudoClass::Disabled |
|
NonTSPseudoClass::Disabled |
|
||||||
|
@ -2584,6 +2615,21 @@ impl Element {
|
||||||
pub fn set_target_state(&self, value: bool) {
|
pub fn set_target_state(&self, value: bool) {
|
||||||
self.set_state(IN_TARGET_STATE, value)
|
self.set_state(IN_TARGET_STATE, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn fullscreen_state(&self) -> bool {
|
||||||
|
self.state.get().contains(IN_FULLSCREEN_STATE)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_fullscreen_state(&self, value: bool) {
|
||||||
|
self.set_state(IN_FULLSCREEN_STATE, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://dom.spec.whatwg.org/#connected
|
||||||
|
pub fn is_connected(&self) -> bool {
|
||||||
|
let node = self.upcast::<Node>();
|
||||||
|
let root = node.GetRootNode();
|
||||||
|
root.is::<Document>()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Element {
|
impl Element {
|
||||||
|
@ -2713,3 +2759,104 @@ impl TagName {
|
||||||
*self.ptr.borrow_mut() = None;
|
*self.ptr.borrow_mut() = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ElementPerformFullscreenEnter {
|
||||||
|
element: Trusted<Element>,
|
||||||
|
promise: TrustedPromise,
|
||||||
|
error: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ElementPerformFullscreenEnter {
|
||||||
|
pub fn new(element: Trusted<Element>, promise: TrustedPromise, error: bool) -> Box<ElementPerformFullscreenEnter> {
|
||||||
|
box ElementPerformFullscreenEnter {
|
||||||
|
element: element,
|
||||||
|
promise: promise,
|
||||||
|
error: error,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Runnable for ElementPerformFullscreenEnter {
|
||||||
|
fn name(&self) -> &'static str { "ElementPerformFullscreenEnter" }
|
||||||
|
|
||||||
|
#[allow(unrooted_must_root)]
|
||||||
|
fn handler(self: Box<ElementPerformFullscreenEnter>) {
|
||||||
|
let element = self.element.root();
|
||||||
|
let document = document_from_node(element.r());
|
||||||
|
|
||||||
|
// Step 7.1
|
||||||
|
if self.error || !element.fullscreen_element_ready_check() {
|
||||||
|
// JSAutoCompartment needs to be manually made.
|
||||||
|
// Otherwise, Servo will crash.
|
||||||
|
let promise = self.promise.root();
|
||||||
|
let promise_cx = promise.global().get_cx();
|
||||||
|
let _ac = JSAutoCompartment::new(promise_cx, promise.reflector().get_jsobject().get());
|
||||||
|
document.upcast::<EventTarget>().fire_event(atom!("fullscreenerror"));
|
||||||
|
promise.reject_error(promise.global().get_cx(), Error::Type(String::from("fullscreen is not connected")));
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Step 7.2-4
|
||||||
|
// Step 7.5
|
||||||
|
element.set_fullscreen_state(true);
|
||||||
|
document.set_fullscreen_element(Some(&element));
|
||||||
|
document.window().reflow(ReflowGoal::ForDisplay,
|
||||||
|
ReflowQueryType::NoQuery,
|
||||||
|
ReflowReason::ElementStateChanged);
|
||||||
|
|
||||||
|
// Step 7.6
|
||||||
|
document.upcast::<EventTarget>().fire_event(atom!("fullscreenchange"));
|
||||||
|
|
||||||
|
// Step 7.7
|
||||||
|
// JSAutoCompartment needs to be manually made.
|
||||||
|
// Otherwise, Servo will crash.
|
||||||
|
let promise = self.promise.root();
|
||||||
|
let promise_cx = promise.global().get_cx();
|
||||||
|
let _ac = JSAutoCompartment::new(promise_cx, promise.reflector().get_jsobject().get());
|
||||||
|
promise.resolve(promise.global().get_cx(), HandleValue::undefined());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ElementPerformFullscreenExit {
|
||||||
|
element: Trusted<Element>,
|
||||||
|
promise: TrustedPromise,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ElementPerformFullscreenExit {
|
||||||
|
pub fn new(element: Trusted<Element>, promise: TrustedPromise) -> Box<ElementPerformFullscreenExit> {
|
||||||
|
box ElementPerformFullscreenExit {
|
||||||
|
element: element,
|
||||||
|
promise: promise,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Runnable for ElementPerformFullscreenExit {
|
||||||
|
fn name(&self) -> &'static str { "ElementPerformFullscreenExit" }
|
||||||
|
|
||||||
|
#[allow(unrooted_must_root)]
|
||||||
|
fn handler(self: Box<ElementPerformFullscreenExit>) {
|
||||||
|
let element = self.element.root();
|
||||||
|
let document = document_from_node(element.r());
|
||||||
|
// TODO Step 9.1-5
|
||||||
|
// Step 9.6
|
||||||
|
element.set_fullscreen_state(false);
|
||||||
|
|
||||||
|
document.window().reflow(ReflowGoal::ForDisplay,
|
||||||
|
ReflowQueryType::NoQuery,
|
||||||
|
ReflowReason::ElementStateChanged);
|
||||||
|
|
||||||
|
document.set_fullscreen_element(None);
|
||||||
|
|
||||||
|
// Step 9.8
|
||||||
|
document.upcast::<EventTarget>().fire_event(atom!("fullscreenchange"));
|
||||||
|
|
||||||
|
// Step 9.10
|
||||||
|
let promise = self.promise.root();
|
||||||
|
// JSAutoCompartment needs to be manually made.
|
||||||
|
// Otherwise, Servo will crash.
|
||||||
|
let promise_cx = promise.global().get_cx();
|
||||||
|
let _ac = JSAutoCompartment::new(promise_cx, promise.reflector().get_jsobject().get());
|
||||||
|
promise.resolve(promise.global().get_cx(), HandleValue::undefined());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ use dom::bindings::codegen::Bindings::BrowserElementBinding::BrowserElementVisib
|
||||||
use dom::bindings::codegen::Bindings::BrowserElementBinding::BrowserShowModalPromptEventDetail;
|
use dom::bindings::codegen::Bindings::BrowserElementBinding::BrowserShowModalPromptEventDetail;
|
||||||
use dom::bindings::codegen::Bindings::HTMLIFrameElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLIFrameElementBinding;
|
||||||
use dom::bindings::codegen::Bindings::HTMLIFrameElementBinding::HTMLIFrameElementMethods;
|
use dom::bindings::codegen::Bindings::HTMLIFrameElementBinding::HTMLIFrameElementMethods;
|
||||||
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
|
use dom::bindings::codegen::Bindings::WindowBinding::WindowBinding::WindowMethods;
|
||||||
use dom::bindings::conversions::ToJSValConvertible;
|
use dom::bindings::conversions::ToJSValConvertible;
|
||||||
use dom::bindings::error::{Error, ErrorResult, Fallible};
|
use dom::bindings::error::{Error, ErrorResult, Fallible};
|
||||||
use dom::bindings::inheritance::Castable;
|
use dom::bindings::inheritance::Castable;
|
||||||
|
@ -544,6 +544,11 @@ impl HTMLIFrameElementMethods for HTMLIFrameElement {
|
||||||
element.set_bool_attribute(&local_name!("mozbrowser"), value);
|
element.set_bool_attribute(&local_name!("mozbrowser"), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#attr-iframe-allowfullscreen
|
||||||
|
make_bool_getter!(AllowFullscreen, "allowfullscreen");
|
||||||
|
// https://html.spec.whatwg.org/multipage/#attr-iframe-allowfullscreen
|
||||||
|
make_bool_setter!(SetAllowFullscreen, "allowfullscreen");
|
||||||
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/goBack
|
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/goBack
|
||||||
fn GoBack(&self) -> ErrorResult {
|
fn GoBack(&self) -> ErrorResult {
|
||||||
Navigate(self, TraversalDirection::Back(1))
|
Navigate(self, TraversalDirection::Back(1))
|
||||||
|
|
|
@ -190,3 +190,15 @@ partial interface Document {
|
||||||
partial interface Document {
|
partial interface Document {
|
||||||
[SameObject] readonly attribute StyleSheetList styleSheets;
|
[SameObject] readonly attribute StyleSheetList styleSheets;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// https://fullscreen.spec.whatwg.org/#api
|
||||||
|
partial interface Document {
|
||||||
|
[LenientSetter] readonly attribute boolean fullscreenEnabled;
|
||||||
|
[LenientSetter] readonly attribute Element? fullscreenElement;
|
||||||
|
[LenientSetter] readonly attribute boolean fullscreen; // historical
|
||||||
|
|
||||||
|
Promise<void> exitFullscreen();
|
||||||
|
|
||||||
|
attribute EventHandler onfullscreenchange;
|
||||||
|
attribute EventHandler onfullscreenerror;
|
||||||
|
};
|
||||||
|
|
|
@ -110,6 +110,11 @@ partial interface Element {
|
||||||
attribute DOMString outerHTML;
|
attribute DOMString outerHTML;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// https://fullscreen.spec.whatwg.org/#api
|
||||||
|
partial interface Element {
|
||||||
|
Promise<void> requestFullscreen();
|
||||||
|
};
|
||||||
|
|
||||||
Element implements ChildNode;
|
Element implements ChildNode;
|
||||||
Element implements NonDocumentTypeChildNode;
|
Element implements NonDocumentTypeChildNode;
|
||||||
Element implements ParentNode;
|
Element implements ParentNode;
|
||||||
|
|
|
@ -13,7 +13,7 @@ interface HTMLIFrameElement : HTMLElement {
|
||||||
[SameObject, PutForwards=value]
|
[SameObject, PutForwards=value]
|
||||||
readonly attribute DOMTokenList sandbox;
|
readonly attribute DOMTokenList sandbox;
|
||||||
// attribute boolean seamless;
|
// attribute boolean seamless;
|
||||||
// attribute boolean allowFullscreen;
|
attribute boolean allowFullscreen;
|
||||||
attribute DOMString width;
|
attribute DOMString width;
|
||||||
attribute DOMString height;
|
attribute DOMString height;
|
||||||
readonly attribute Document? contentDocument;
|
readonly attribute Document? contentDocument;
|
||||||
|
|
|
@ -666,6 +666,7 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
|
||||||
|
|
||||||
NonTSPseudoClass::Active |
|
NonTSPseudoClass::Active |
|
||||||
NonTSPseudoClass::Focus |
|
NonTSPseudoClass::Focus |
|
||||||
|
NonTSPseudoClass::Fullscreen |
|
||||||
NonTSPseudoClass::Hover |
|
NonTSPseudoClass::Hover |
|
||||||
NonTSPseudoClass::Enabled |
|
NonTSPseudoClass::Enabled |
|
||||||
NonTSPseudoClass::Disabled |
|
NonTSPseudoClass::Disabled |
|
||||||
|
|
|
@ -76,7 +76,9 @@ pub enum ScriptThreadEventCategory {
|
||||||
UpdateReplacedElement,
|
UpdateReplacedElement,
|
||||||
WebSocketEvent,
|
WebSocketEvent,
|
||||||
WorkerEvent,
|
WorkerEvent,
|
||||||
ServiceWorkerEvent
|
ServiceWorkerEvent,
|
||||||
|
EnterFullscreen,
|
||||||
|
ExitFullscreen,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An interface for receiving ScriptMsg values in an event loop. Used for synchronous DOM
|
/// An interface for receiving ScriptMsg values in an event loop. Used for synchronous DOM
|
||||||
|
|
|
@ -946,7 +946,9 @@ impl ScriptThread {
|
||||||
ScriptThreadEventCategory::TimerEvent => ProfilerCategory::ScriptTimerEvent,
|
ScriptThreadEventCategory::TimerEvent => ProfilerCategory::ScriptTimerEvent,
|
||||||
ScriptThreadEventCategory::WebSocketEvent => ProfilerCategory::ScriptWebSocketEvent,
|
ScriptThreadEventCategory::WebSocketEvent => ProfilerCategory::ScriptWebSocketEvent,
|
||||||
ScriptThreadEventCategory::WorkerEvent => ProfilerCategory::ScriptWorkerEvent,
|
ScriptThreadEventCategory::WorkerEvent => ProfilerCategory::ScriptWorkerEvent,
|
||||||
ScriptThreadEventCategory::ServiceWorkerEvent => ProfilerCategory::ScriptServiceWorkerEvent
|
ScriptThreadEventCategory::ServiceWorkerEvent => ProfilerCategory::ScriptServiceWorkerEvent,
|
||||||
|
ScriptThreadEventCategory::EnterFullscreen => ProfilerCategory::ScriptEnterFullscreen,
|
||||||
|
ScriptThreadEventCategory::ExitFullscreen => ProfilerCategory::ScriptExitFullscreen,
|
||||||
};
|
};
|
||||||
profile(profiler_cat, None, self.time_profiler_chan.clone(), f)
|
profile(profiler_cat, None, self.time_profiler_chan.clone(), f)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -145,6 +145,8 @@ pub enum ScriptMsg {
|
||||||
ForwardDOMMessage(DOMMessage, ServoUrl),
|
ForwardDOMMessage(DOMMessage, ServoUrl),
|
||||||
/// Store the data required to activate a service worker for the given scope
|
/// Store the data required to activate a service worker for the given scope
|
||||||
RegisterServiceWorker(ScopeThings, ServoUrl),
|
RegisterServiceWorker(ScopeThings, ServoUrl),
|
||||||
|
/// Enter or exit fullscreen
|
||||||
|
SetFullscreenState(bool),
|
||||||
/// Requests that the compositor shut down.
|
/// Requests that the compositor shut down.
|
||||||
Exit
|
Exit
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,5 +35,7 @@ bitflags! {
|
||||||
const IN_PLACEHOLDER_SHOWN_STATE = 0x0100,
|
const IN_PLACEHOLDER_SHOWN_STATE = 0x0100,
|
||||||
#[doc = "https://html.spec.whatwg.org/multipage/#selector-target"]
|
#[doc = "https://html.spec.whatwg.org/multipage/#selector-target"]
|
||||||
const IN_TARGET_STATE = 0x0200,
|
const IN_TARGET_STATE = 0x0200,
|
||||||
|
#[doc = "https://fullscreen.spec.whatwg.org/#%3Afullscreen-pseudo-class"]
|
||||||
|
const IN_FULLSCREEN_STATE = 0x0400,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,6 +109,7 @@ pub enum NonTSPseudoClass {
|
||||||
Visited,
|
Visited,
|
||||||
Active,
|
Active,
|
||||||
Focus,
|
Focus,
|
||||||
|
Fullscreen,
|
||||||
Hover,
|
Hover,
|
||||||
Enabled,
|
Enabled,
|
||||||
Disabled,
|
Disabled,
|
||||||
|
@ -127,6 +128,7 @@ impl ToCss for NonTSPseudoClass {
|
||||||
Visited => ":visited",
|
Visited => ":visited",
|
||||||
Active => ":active",
|
Active => ":active",
|
||||||
Focus => ":focus",
|
Focus => ":focus",
|
||||||
|
Fullscreen => ":fullscreen",
|
||||||
Hover => ":hover",
|
Hover => ":hover",
|
||||||
Enabled => ":enabled",
|
Enabled => ":enabled",
|
||||||
Disabled => ":disabled",
|
Disabled => ":disabled",
|
||||||
|
@ -145,6 +147,7 @@ impl NonTSPseudoClass {
|
||||||
match *self {
|
match *self {
|
||||||
Active => IN_ACTIVE_STATE,
|
Active => IN_ACTIVE_STATE,
|
||||||
Focus => IN_FOCUS_STATE,
|
Focus => IN_FOCUS_STATE,
|
||||||
|
Fullscreen => IN_FULLSCREEN_STATE,
|
||||||
Hover => IN_HOVER_STATE,
|
Hover => IN_HOVER_STATE,
|
||||||
Enabled => IN_ENABLED_STATE,
|
Enabled => IN_ENABLED_STATE,
|
||||||
Disabled => IN_DISABLED_STATE,
|
Disabled => IN_DISABLED_STATE,
|
||||||
|
@ -196,6 +199,7 @@ impl<'a> ::selectors::Parser for SelectorParser<'a> {
|
||||||
"visited" => Visited,
|
"visited" => Visited,
|
||||||
"active" => Active,
|
"active" => Active,
|
||||||
"focus" => Focus,
|
"focus" => Focus,
|
||||||
|
"fullscreen" => Fullscreen,
|
||||||
"hover" => Hover,
|
"hover" => Hover,
|
||||||
"enabled" => Enabled,
|
"enabled" => Enabled,
|
||||||
"disabled" => Disabled,
|
"disabled" => Disabled,
|
||||||
|
|
|
@ -481,6 +481,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
|
||||||
NonTSPseudoClass::Disabled |
|
NonTSPseudoClass::Disabled |
|
||||||
NonTSPseudoClass::Checked |
|
NonTSPseudoClass::Checked |
|
||||||
NonTSPseudoClass::ReadWrite |
|
NonTSPseudoClass::ReadWrite |
|
||||||
|
NonTSPseudoClass::Fullscreen |
|
||||||
NonTSPseudoClass::Indeterminate => {
|
NonTSPseudoClass::Indeterminate => {
|
||||||
self.get_state().contains(pseudo_class.state_flag())
|
self.get_state().contains(pseudo_class.state_flag())
|
||||||
},
|
},
|
||||||
|
|
|
@ -90,6 +90,7 @@ pub enum NonTSPseudoClass {
|
||||||
Visited,
|
Visited,
|
||||||
Active,
|
Active,
|
||||||
Focus,
|
Focus,
|
||||||
|
Fullscreen,
|
||||||
Hover,
|
Hover,
|
||||||
Enabled,
|
Enabled,
|
||||||
Disabled,
|
Disabled,
|
||||||
|
@ -111,6 +112,7 @@ impl ToCss for NonTSPseudoClass {
|
||||||
Visited => ":visited",
|
Visited => ":visited",
|
||||||
Active => ":active",
|
Active => ":active",
|
||||||
Focus => ":focus",
|
Focus => ":focus",
|
||||||
|
Fullscreen => ":fullscreen",
|
||||||
Hover => ":hover",
|
Hover => ":hover",
|
||||||
Enabled => ":enabled",
|
Enabled => ":enabled",
|
||||||
Disabled => ":disabled",
|
Disabled => ":disabled",
|
||||||
|
@ -132,6 +134,7 @@ impl NonTSPseudoClass {
|
||||||
match *self {
|
match *self {
|
||||||
Active => IN_ACTIVE_STATE,
|
Active => IN_ACTIVE_STATE,
|
||||||
Focus => IN_FOCUS_STATE,
|
Focus => IN_FOCUS_STATE,
|
||||||
|
Fullscreen => IN_FULLSCREEN_STATE,
|
||||||
Hover => IN_HOVER_STATE,
|
Hover => IN_HOVER_STATE,
|
||||||
Enabled => IN_ENABLED_STATE,
|
Enabled => IN_ENABLED_STATE,
|
||||||
Disabled => IN_DISABLED_STATE,
|
Disabled => IN_DISABLED_STATE,
|
||||||
|
@ -187,6 +190,7 @@ impl<'a> ::selectors::Parser for SelectorParser<'a> {
|
||||||
"visited" => Visited,
|
"visited" => Visited,
|
||||||
"active" => Active,
|
"active" => Active,
|
||||||
"focus" => Focus,
|
"focus" => Focus,
|
||||||
|
"fullscreen" => Fullscreen,
|
||||||
"hover" => Hover,
|
"hover" => Hover,
|
||||||
"enabled" => Enabled,
|
"enabled" => Enabled,
|
||||||
"disabled" => Disabled,
|
"disabled" => Disabled,
|
||||||
|
|
|
@ -238,6 +238,9 @@ impl WindowMethods for Window {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_fullscreen_state(&self, _state: bool) {
|
||||||
|
}
|
||||||
|
|
||||||
fn present(&self) {
|
fn present(&self) {
|
||||||
let browser = self.cef_browser.borrow();
|
let browser = self.cef_browser.borrow();
|
||||||
match *browser {
|
match *browser {
|
||||||
|
|
|
@ -841,6 +841,15 @@ impl WindowMethods for Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_fullscreen_state(&self, _state: bool) {
|
||||||
|
match self.kind {
|
||||||
|
WindowKind::Window(..) => {
|
||||||
|
warn!("Fullscreen is not implemented!")
|
||||||
|
},
|
||||||
|
WindowKind::Headless(..) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn present(&self) {
|
fn present(&self) {
|
||||||
match self.kind {
|
match self.kind {
|
||||||
WindowKind::Window(ref window) => {
|
WindowKind::Window(ref window) => {
|
||||||
|
|
|
@ -286,3 +286,25 @@ video { object-fit: contain; }
|
||||||
|
|
||||||
|
|
||||||
textarea { white-space: pre-wrap; }
|
textarea { white-space: pre-wrap; }
|
||||||
|
|
||||||
|
*|*:not(:root):fullscreen {
|
||||||
|
position:fixed !important;
|
||||||
|
top:0 !important; right:0 !important; bottom:0 !important; left:0 !important;
|
||||||
|
margin:0 !important;
|
||||||
|
box-sizing:border-box !important;
|
||||||
|
min-width:0 !important;
|
||||||
|
max-width:none !important;
|
||||||
|
min-height:0 !important;
|
||||||
|
max-height:none !important;
|
||||||
|
width:100% !important;
|
||||||
|
height:100% !important;
|
||||||
|
transform:none !important;
|
||||||
|
|
||||||
|
/* intentionally not !important */
|
||||||
|
object-fit:contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
iframe:fullscreen {
|
||||||
|
border:none !important;
|
||||||
|
padding:0 !important;
|
||||||
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@ skip: true
|
||||||
skip: false
|
skip: false
|
||||||
[FileAPI]
|
[FileAPI]
|
||||||
skip: false
|
skip: false
|
||||||
|
[fullscreen]
|
||||||
|
skip: false
|
||||||
[hr-time]
|
[hr-time]
|
||||||
skip: false
|
skip: false
|
||||||
[html]
|
[html]
|
||||||
|
|
|
@ -1305,9 +1305,6 @@
|
||||||
[HTMLIFrameElement interface: attribute seamless]
|
[HTMLIFrameElement interface: attribute seamless]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[HTMLIFrameElement interface: attribute allowFullscreen]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[HTMLIFrameElement interface: attribute align]
|
[HTMLIFrameElement interface: attribute align]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
[iframe-allowfullscreen.html]
|
[iframe-allowfullscreen.html]
|
||||||
type: testharness
|
type: testharness
|
||||||
[iframe-allowfullscreen]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[iframe-sandbox-allowfullscreen]
|
[iframe-sandbox-allowfullscreen]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -8132,6 +8132,12 @@
|
||||||
"url": "/_mozilla/mozilla/form_tab_keyevent.html"
|
"url": "/_mozilla/mozilla/form_tab_keyevent.html"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"mozilla/fullscreen-remove-single.html": [
|
||||||
|
{
|
||||||
|
"path": "mozilla/fullscreen-remove-single.html",
|
||||||
|
"url": "/_mozilla/mozilla/fullscreen-remove-single.html"
|
||||||
|
}
|
||||||
|
],
|
||||||
"mozilla/getBoundingClientRect.html": [
|
"mozilla/getBoundingClientRect.html": [
|
||||||
{
|
{
|
||||||
"path": "mozilla/getBoundingClientRect.html",
|
"path": "mozilla/getBoundingClientRect.html",
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<title>Remove the single element on the fullscreen element stack</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<div id="log"></div>
|
||||||
|
<div id="single"></div>
|
||||||
|
<script>
|
||||||
|
async_test(function(t)
|
||||||
|
{
|
||||||
|
var single = document.getElementById("single");
|
||||||
|
document.onfullscreenchange = t.step_func(function()
|
||||||
|
{
|
||||||
|
assert_equals(document.fullscreenElement, single);
|
||||||
|
document.onfullscreenchange = t.step_func(function()
|
||||||
|
{
|
||||||
|
assert_equals(document.fullscreenElement, null);
|
||||||
|
t.done();
|
||||||
|
});
|
||||||
|
single.remove();
|
||||||
|
});
|
||||||
|
single.requestFullscreen();
|
||||||
|
});
|
||||||
|
</script>
|
10
tests/wpt/web-platform-tests/fullscreen/api/blank.html
Normal file
10
tests/wpt/web-platform-tests/fullscreen/api/blank.html
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Title</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -3,15 +3,23 @@
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<div id="log"></div>
|
<div id="log"></div>
|
||||||
<iframe></iframe>
|
<iframe src="blank.html"></iframe>
|
||||||
<iframe allowfullscreen></iframe>
|
<iframe allowfullscreen src="blank.html"></iframe>
|
||||||
<script>
|
<script>
|
||||||
test(function()
|
async_test(function(t)
|
||||||
{
|
{
|
||||||
assert_true(document.fullscreenEnabled, "top-level document");
|
assert_true(document.fullscreenEnabled, "top-level document");
|
||||||
|
|
||||||
var iframes = document.getElementsByTagName("iframe");
|
var iframes = document.getElementsByTagName("iframe");
|
||||||
|
|
||||||
|
var loaded = 0;
|
||||||
|
iframes[0].onload = t.step_func(function() {
|
||||||
assert_false(iframes[0].contentDocument.fullscreenEnabled, "iframe without allowfullscreen");
|
assert_false(iframes[0].contentDocument.fullscreenEnabled, "iframe without allowfullscreen");
|
||||||
|
if (++loaded == 2) t.done();
|
||||||
|
});
|
||||||
|
iframes[1].onload = t.step_func(function() {
|
||||||
assert_true(iframes[1].contentDocument.fullscreenEnabled, "iframe with allowfullscreen");
|
assert_true(iframes[1].contentDocument.fullscreenEnabled, "iframe with allowfullscreen");
|
||||||
|
if (++loaded == 2) t.done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -6,8 +6,13 @@
|
||||||
<script>
|
<script>
|
||||||
async_test(function(t)
|
async_test(function(t)
|
||||||
{
|
{
|
||||||
|
var sync = true;
|
||||||
assert_equals(document.onfullscreenerror, null, "initial onfullscreenerror");
|
assert_equals(document.onfullscreenerror, null, "initial onfullscreenerror");
|
||||||
document.onfullscreenerror = t.step_func_done();
|
document.onfullscreenerror = t.step_func_done(function(event) {
|
||||||
document.createElement("a").requestFullscreen();
|
assert_false(sync);
|
||||||
|
});
|
||||||
|
var e = document.createElement('span');
|
||||||
|
e.requestFullscreen();
|
||||||
|
sync = false;
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue