зеркало из https://github.com/mozilla/gecko-dev.git
Bug 453063 - Support for fullscreen video playback. r=dolske, ui-r=boriss
This commit is contained in:
Родитель
433e3fc3b0
Коммит
84cda3dcc6
|
@ -102,6 +102,10 @@
|
|||
label="&mediaHideControls.label;"
|
||||
accesskey="&mediaHideControls.accesskey;"
|
||||
oncommand="gContextMenu.mediaCommand('hidecontrols');"/>
|
||||
<menuitem id="context-video-fullscreen"
|
||||
accesskey="&videoFullScreen.accesskey;"
|
||||
label="&videoFullScreen.label;"
|
||||
oncommand="gContextMenu.fullScreenVideo();"/>
|
||||
<menuseparator id="context-media-sep-commands"/>
|
||||
<menuitem id="context-reloadimage"
|
||||
label="&reloadImageCmd.label;"
|
||||
|
|
|
@ -0,0 +1,203 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is the Mozilla Foundation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2008
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Dão Gottwald <dao@mozilla.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
-->
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<style type="text/css"><![CDATA[
|
||||
|
||||
html,
|
||||
body,
|
||||
video {
|
||||
height: 100%;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
background: black;
|
||||
overflow: -moz-hidden-unscrollable;
|
||||
}
|
||||
body.userIdle {
|
||||
cursor: none;
|
||||
}
|
||||
video {
|
||||
width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
body.loadingdata > video,
|
||||
body.loadingdata > #close,
|
||||
body.userIdle > #close {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
]]></style>
|
||||
<link href="chrome://browser/skin/fullscreen-video.css"
|
||||
rel="stylesheet" type="text/css"/>
|
||||
<script type="application/javascript"><![CDATA[
|
||||
|
||||
var contentVideo = window.arguments[0];
|
||||
var video;
|
||||
|
||||
var title = (contentVideo.currentSrc || contentVideo.src).replace(/^.*\//, "");
|
||||
try {
|
||||
title = decodeURI(title);
|
||||
} catch (e) {}
|
||||
document.title = title;
|
||||
|
||||
window.addEventListener("focus", function () {
|
||||
window.removeEventListener("focus", arguments.callee, false);
|
||||
|
||||
window.fullScreen = true;
|
||||
|
||||
video = document.querySelector("video");
|
||||
|
||||
video.addEventListener("loadeddata", function () {
|
||||
video.removeEventListener("loadeddata", arguments.callee, false);
|
||||
video.volume = contentVideo.volume;
|
||||
video.muted = contentVideo.muted;
|
||||
video.poster = contentVideo.poster;
|
||||
|
||||
if (contentVideo.currentTime && !contentVideo.ended) {
|
||||
video.addEventListener("seeked", function () {
|
||||
video.removeEventListener("seeked", arguments.callee, false);
|
||||
playbackStarts();
|
||||
}, false);
|
||||
|
||||
video.currentTime = contentVideo.currentTime;
|
||||
} else {
|
||||
playbackStarts();
|
||||
}
|
||||
|
||||
video.controls = true;
|
||||
video.play();
|
||||
}, false);
|
||||
|
||||
// Automatically close this window when the playback ended, unless the user
|
||||
// interacted with it.
|
||||
video.addEventListener("ended", autoClose, false);
|
||||
window.addEventListener("click", cancelAutoClose, false);
|
||||
window.addEventListener("keypress", cancelAutoClose, false);
|
||||
|
||||
video.addEventListener("playing", hideUI, false);
|
||||
video.addEventListener("seeked", hideUI, false);
|
||||
video.addEventListener("seeking", showUI, false);
|
||||
video.addEventListener("pause", showUI, false);
|
||||
video.addEventListener("ended", showUI, false);
|
||||
|
||||
window.addEventListener("mousemove", function () {
|
||||
showUI();
|
||||
resetIdleTimer();
|
||||
}, false);
|
||||
|
||||
video.mozLoadFrom(contentVideo);
|
||||
}, false);
|
||||
|
||||
window.addEventListener("unload", function () {
|
||||
if (video.currentSrc) {
|
||||
contentVideo.currentTime = video.currentTime;
|
||||
contentVideo.volume = video.volume;
|
||||
contentVideo.muted = video.muted;
|
||||
if (!video.paused && !video.ended) {
|
||||
video.pause();
|
||||
contentVideo.play();
|
||||
}
|
||||
}
|
||||
}, false);
|
||||
|
||||
window.addEventListener("keypress", function (event) {
|
||||
if (event.keyCode == event.DOM_VK_ESCAPE) {
|
||||
window.close();
|
||||
return;
|
||||
}
|
||||
|
||||
resetIdleTimer();
|
||||
|
||||
if (!video.controls &&
|
||||
String.fromCharCode(event.charCode) == " ")
|
||||
video.pause();
|
||||
}, false);
|
||||
|
||||
function playbackStarts() {
|
||||
// Loading the data from the content video may take a second or two. We hide
|
||||
// the video during that period.
|
||||
document.body.classList.remove("loadingdata");
|
||||
video.focus();
|
||||
}
|
||||
|
||||
function autoClose() {
|
||||
window.close();
|
||||
}
|
||||
|
||||
function cancelAutoClose() {
|
||||
video.removeEventListener("ended", autoClose, false);
|
||||
window.removeEventListener("click", cancelAutoClose, false);
|
||||
window.removeEventListener("keypress", cancelAutoClose, false);
|
||||
}
|
||||
|
||||
var idleTimer;
|
||||
function resetIdleTimer() {
|
||||
if (idleTimer) {
|
||||
clearTimeout(idleTimer);
|
||||
idleTimer = 0;
|
||||
}
|
||||
idleTimer = setTimeout(function () {
|
||||
idleTimer = 0;
|
||||
hideUI();
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
function showUI() {
|
||||
if (!video.controls) {
|
||||
document.body.classList.remove("userIdle");
|
||||
video.controls = true;
|
||||
}
|
||||
}
|
||||
|
||||
function hideUI() {
|
||||
if (!video.paused && !video.ended && !video.seeking && !video.error) {
|
||||
document.body.classList.add("userIdle");
|
||||
video.controls = false;
|
||||
}
|
||||
}
|
||||
|
||||
]]></script>
|
||||
</head>
|
||||
<body class="loadingdata">
|
||||
<span id="close" onclick="window.close();"/>
|
||||
<video/>
|
||||
</body>
|
||||
</html>
|
|
@ -414,8 +414,9 @@ nsContextMenu.prototype = {
|
|||
this.showItem("context-media-pause", onMedia && !this.target.paused && !this.target.ended);
|
||||
this.showItem("context-media-mute", onMedia && !this.target.muted);
|
||||
this.showItem("context-media-unmute", onMedia && this.target.muted);
|
||||
this.showItem("context-media-showcontrols", onMedia && !this.target.controls)
|
||||
this.showItem("context-media-hidecontrols", onMedia && this.target.controls)
|
||||
this.showItem("context-media-showcontrols", onMedia && !this.target.controls);
|
||||
this.showItem("context-media-hidecontrols", onMedia && this.target.controls);
|
||||
this.showItem("context-video-fullscreen", this.onVideo);
|
||||
// Disable them when there isn't a valid media source loaded.
|
||||
if (onMedia) {
|
||||
var hasError = (this.target.error != null);
|
||||
|
@ -425,6 +426,8 @@ nsContextMenu.prototype = {
|
|||
this.setItemAttr("context-media-unmute", "disabled", hasError);
|
||||
this.setItemAttr("context-media-showcontrols", "disabled", hasError);
|
||||
this.setItemAttr("context-media-hidecontrols", "disabled", hasError);
|
||||
if (this.onVideo)
|
||||
this.setItemAttr("context-video-fullscreen", "disabled", hasError);
|
||||
}
|
||||
this.showItem("context-media-sep-commands", onMedia);
|
||||
},
|
||||
|
@ -803,6 +806,13 @@ nsContextMenu.prototype = {
|
|||
openUILink(viewURL, e, null, null, null, null, doc.documentURIObject );
|
||||
},
|
||||
|
||||
fullScreenVideo: function () {
|
||||
this.target.pause();
|
||||
|
||||
openDialog("chrome://browser/content/fullscreen-video.xhtml",
|
||||
"", "chrome,dialog=no", this.target);
|
||||
},
|
||||
|
||||
// Change current window to the URL of the background image.
|
||||
viewBGImage: function(e) {
|
||||
urlSecurityCheck(this.bgImageURL,
|
||||
|
|
|
@ -230,6 +230,7 @@ function runTest(testNum) {
|
|||
checkContextMenu(["context-media-play", true,
|
||||
"context-media-mute", true,
|
||||
"context-media-showcontrols", true,
|
||||
"context-video-fullscreen", true,
|
||||
"---", null,
|
||||
"context-viewvideo", true,
|
||||
"context-copyvideourl", true,
|
||||
|
@ -245,6 +246,7 @@ function runTest(testNum) {
|
|||
checkContextMenu(["context-media-play", false,
|
||||
"context-media-mute", false,
|
||||
"context-media-showcontrols", false,
|
||||
"context-video-fullscreen", false,
|
||||
"---", null,
|
||||
"context-viewvideo", true,
|
||||
"context-copyvideourl", true,
|
||||
|
@ -260,6 +262,7 @@ function runTest(testNum) {
|
|||
checkContextMenu(["context-media-play", false,
|
||||
"context-media-mute", false,
|
||||
"context-media-showcontrols", false,
|
||||
"context-video-fullscreen", false,
|
||||
"---", null,
|
||||
"context-viewvideo", false,
|
||||
"context-copyvideourl", false,
|
||||
|
|
|
@ -24,6 +24,7 @@ browser.jar:
|
|||
* content/browser/browser.xul (content/browser.xul)
|
||||
* content/browser/browser-tabPreviews.xml (content/browser-tabPreviews.xml)
|
||||
* content/browser/credits.xhtml (content/credits.xhtml)
|
||||
* content/browser/fullscreen-video.xhtml (content/fullscreen-video.xhtml)
|
||||
* content/browser/pageinfo/pageInfo.xul (content/pageinfo/pageInfo.xul)
|
||||
* content/browser/pageinfo/pageInfo.js (content/pageinfo/pageInfo.js)
|
||||
* content/browser/pageinfo/pageInfo.css (content/pageinfo/pageInfo.css)
|
||||
|
|
|
@ -335,6 +335,8 @@
|
|||
<!ENTITY mediaShowControls.accesskey "C">
|
||||
<!ENTITY mediaHideControls.label "Hide Controls">
|
||||
<!ENTITY mediaHideControls.accesskey "C">
|
||||
<!ENTITY videoFullScreen.label "Full Screen">
|
||||
<!ENTITY videoFullScreen.accesskey "F">
|
||||
|
||||
|
||||
<!-- LOCALIZATION NOTE :
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
#close {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background: url(KUI-close.png) center center no-repeat;
|
||||
}
|
|
@ -8,6 +8,7 @@ browser.jar:
|
|||
skin/classic/browser/aboutCertError.css (aboutCertError.css)
|
||||
* skin/classic/browser/browser.css (browser.css)
|
||||
* skin/classic/browser/engineManager.css (engineManager.css)
|
||||
skin/classic/browser/fullscreen-video.css
|
||||
skin/classic/browser/Geo.png
|
||||
skin/classic/browser/Go-arrow.png
|
||||
skin/classic/browser/identity.png
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
#close {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background: url(KUI-close.png) center center no-repeat;
|
||||
}
|
|
@ -12,6 +12,7 @@ browser.jar:
|
|||
* skin/classic/browser/browser.css (browser.css)
|
||||
* skin/classic/browser/engineManager.css (engineManager.css)
|
||||
skin/classic/browser/feed-icons.png
|
||||
skin/classic/browser/fullscreen-video.css
|
||||
skin/classic/browser/Geo.png
|
||||
skin/classic/browser/Go-arrow.png
|
||||
skin/classic/browser/home.png
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
#close {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background: url(KUI-close.png) center center no-repeat;
|
||||
}
|
|
@ -10,6 +10,7 @@ browser.jar:
|
|||
skin/classic/browser/aboutCertError.css (aboutCertError.css)
|
||||
* skin/classic/browser/browser.css (browser.css)
|
||||
* skin/classic/browser/engineManager.css (engineManager.css)
|
||||
skin/classic/browser/fullscreen-video.css
|
||||
skin/classic/browser/Geo.png (Geo.png)
|
||||
skin/classic/browser/Info.png (Info.png)
|
||||
skin/classic/browser/identity.png (identity.png)
|
||||
|
@ -103,6 +104,7 @@ browser.jar:
|
|||
skin/classic/aero/browser/aboutCertError.css (aboutCertError.css)
|
||||
* skin/classic/aero/browser/browser.css (browser-aero.css)
|
||||
* skin/classic/aero/browser/engineManager.css (engineManager.css)
|
||||
skin/classic/aero/browser/fullscreen-video.css
|
||||
skin/classic/aero/browser/Geo.png (Geo-aero.png)
|
||||
skin/classic/aero/browser/Info.png (Info-aero.png)
|
||||
skin/classic/aero/browser/identity.png (identity-aero.png)
|
||||
|
|
Загрузка…
Ссылка в новой задаче