mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
merge m-c to fx-team
This commit is contained in:
commit
9c6aeeac42
@ -180,6 +180,9 @@ function setupSearchEngine()
|
||||
{
|
||||
gSearchEngine = JSON.parse(localStorage["search-engine"]);
|
||||
|
||||
if (!gSearchEngine)
|
||||
return;
|
||||
|
||||
// Look for extended information, like logo and links.
|
||||
let searchEngineInfo = SEARCH_ENGINES[gSearchEngine.name];
|
||||
if (searchEngineInfo) {
|
||||
|
@ -1963,6 +1963,8 @@
|
||||
else
|
||||
this.showTab(tab);
|
||||
}, this);
|
||||
|
||||
this.tabContainer.mTabstrip.ensureElementIsVisible(this.selectedTab, false);
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
@ -123,11 +123,12 @@
|
||||
toggle('expertContent');
|
||||
}
|
||||
|
||||
// if this is a Strict-Transport-Security host and the cert
|
||||
// is bad, don't allow overrides (STS Spec section 7.3).
|
||||
if (getCSSClass() == "badStsCert") {
|
||||
// Disallow overrides if this is a Strict-Transport-Security
|
||||
// host and the cert is bad (STS Spec section 7.3) or if the
|
||||
// certerror is in a frame (bug 633691).
|
||||
if (getCSSClass() == "badStsCert" || window != top) {
|
||||
var ec = document.getElementById('expertContent');
|
||||
document.getElementById('errorLongContent').removeChild(ec);
|
||||
ec.parentNode.removeChild(ec);
|
||||
}
|
||||
|
||||
var tech = document.getElementById("technicalContentText");
|
||||
|
@ -178,6 +178,16 @@ function SessionStoreService() {
|
||||
this._prefBranch.addObserver("sessionstore.resume_from_crash", this, true);
|
||||
return this._prefBranch.getBoolPref("sessionstore.resume_from_crash");
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "_max_tabs_undo", function () {
|
||||
this._prefBranch.addObserver("sessionstore.max_tabs_undo", this, true);
|
||||
return this._prefBranch.getIntPref("sessionstore.max_tabs_undo");
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "_max_windows_undo", function () {
|
||||
this._prefBranch.addObserver("sessionstore.max_windows_undo", this, true);
|
||||
return this._prefBranch.getIntPref("sessionstore.max_windows_undo");
|
||||
});
|
||||
}
|
||||
|
||||
SessionStoreService.prototype = {
|
||||
@ -291,10 +301,6 @@ SessionStoreService.prototype = {
|
||||
|
||||
// Do pref migration before we store any values and start observing changes
|
||||
this._migratePrefs();
|
||||
|
||||
// observe prefs changes so we can modify stored data to match
|
||||
this._prefBranch.addObserver("sessionstore.max_tabs_undo", this, true);
|
||||
this._prefBranch.addObserver("sessionstore.max_windows_undo", this, true);
|
||||
|
||||
// this pref is only read at startup, so no need to observe it
|
||||
this._sessionhistory_max_entries =
|
||||
@ -642,11 +648,13 @@ SessionStoreService.prototype = {
|
||||
// if the user decreases the max number of closed tabs they want
|
||||
// preserved update our internal states to match that max
|
||||
case "sessionstore.max_tabs_undo":
|
||||
this._max_tabs_undo = this._prefBranch.getIntPref("sessionstore.max_tabs_undo");
|
||||
for (let ix in this._windows) {
|
||||
this._windows[ix]._closedTabs.splice(this._prefBranch.getIntPref("sessionstore.max_tabs_undo"), this._windows[ix]._closedTabs.length);
|
||||
this._windows[ix]._closedTabs.splice(this._max_tabs_undo, this._windows[ix]._closedTabs.length);
|
||||
}
|
||||
break;
|
||||
case "sessionstore.max_windows_undo":
|
||||
this._max_windows_undo = this._prefBranch.getIntPref("sessionstore.max_windows_undo");
|
||||
this._capClosedWindows();
|
||||
break;
|
||||
case "sessionstore.interval":
|
||||
@ -1094,10 +1102,9 @@ SessionStoreService.prototype = {
|
||||
var event = aWindow.document.createEvent("Events");
|
||||
event.initEvent("SSTabClosing", true, false);
|
||||
aTab.dispatchEvent(event);
|
||||
|
||||
var maxTabsUndo = this._prefBranch.getIntPref("sessionstore.max_tabs_undo");
|
||||
|
||||
// don't update our internal state if we don't have to
|
||||
if (maxTabsUndo == 0) {
|
||||
if (this._max_tabs_undo == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1118,8 +1125,8 @@ SessionStoreService.prototype = {
|
||||
pos: aTab._tPos
|
||||
});
|
||||
var length = this._windows[aWindow.__SSi]._closedTabs.length;
|
||||
if (length > maxTabsUndo)
|
||||
this._windows[aWindow.__SSi]._closedTabs.splice(maxTabsUndo, length - maxTabsUndo);
|
||||
if (length > this._max_tabs_undo)
|
||||
this._windows[aWindow.__SSi]._closedTabs.splice(this._max_tabs_undo, length - this._max_tabs_undo);
|
||||
}
|
||||
},
|
||||
|
||||
@ -2518,7 +2525,7 @@ SessionStoreService.prototype = {
|
||||
// at startup we don't accidentally add them to a popup window
|
||||
do {
|
||||
total.unshift(lastClosedWindowsCopy.shift())
|
||||
} while (total[0].isPopup)
|
||||
} while (total[0].isPopup && lastClosedWindowsCopy.length > 0)
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -4264,17 +4271,16 @@ SessionStoreService.prototype = {
|
||||
* resize such that we have at least one non-popup window.
|
||||
*/
|
||||
_capClosedWindows : function sss_capClosedWindows() {
|
||||
let maxWindowsUndo = this._prefBranch.getIntPref("sessionstore.max_windows_undo");
|
||||
if (this._closedWindows.length <= maxWindowsUndo)
|
||||
if (this._closedWindows.length <= this._max_windows_undo)
|
||||
return;
|
||||
let spliceTo = maxWindowsUndo;
|
||||
let spliceTo = this._max_windows_undo;
|
||||
#ifndef XP_MACOSX
|
||||
let normalWindowIndex = 0;
|
||||
// try to find a non-popup window in this._closedWindows
|
||||
while (normalWindowIndex < this._closedWindows.length &&
|
||||
!!this._closedWindows[normalWindowIndex].isPopup)
|
||||
normalWindowIndex++;
|
||||
if (normalWindowIndex >= maxWindowsUndo)
|
||||
if (normalWindowIndex >= this._max_windows_undo)
|
||||
spliceTo = normalWindowIndex + 1;
|
||||
#endif
|
||||
this._closedWindows.splice(spliceTo, this._closedWindows.length);
|
||||
@ -4525,7 +4531,8 @@ let gRestoreTabsProgressListener = {
|
||||
onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
|
||||
// Ignore state changes on browsers that we've already restored and state
|
||||
// changes that aren't applicable.
|
||||
if (aBrowser.__SS_restoreState == TAB_STATE_RESTORING &&
|
||||
if (aBrowser.__SS_restoreState &&
|
||||
aBrowser.__SS_restoreState == TAB_STATE_RESTORING &&
|
||||
aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
|
||||
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK &&
|
||||
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW) {
|
||||
|
@ -164,6 +164,7 @@ _BROWSER_FILES = \
|
||||
browser_tabview_bug685476.js \
|
||||
browser_tabview_bug685692.js \
|
||||
browser_tabview_bug686654.js \
|
||||
browser_tabview_bug696602.js \
|
||||
browser_tabview_bug697390.js \
|
||||
browser_tabview_bug705621.js \
|
||||
browser_tabview_bug706430.js \
|
||||
|
51
browser/components/tabview/test/browser_tabview_bug696602.js
Normal file
51
browser/components/tabview/test/browser_tabview_bug696602.js
Normal file
@ -0,0 +1,51 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
let win;
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
newWindowWithTabView(function(newWin) {
|
||||
win = newWin;
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
win.close();
|
||||
});
|
||||
|
||||
let cw = win.TabView.getContentWindow();
|
||||
let groupItemOne = cw.GroupItems.groupItems[0];
|
||||
let groupItemTwo = createGroupItemWithBlankTabs(win, 300, 300, 20, 10);
|
||||
|
||||
is(win.gBrowser.tabContainer.getAttribute("overflow"), "true",
|
||||
"The tabstrip is overflow");
|
||||
|
||||
is(groupItemOne.getChildren().length, 10, "Group one has 10 tabs");
|
||||
is(groupItemTwo.getChildren().length, 10, "Group two has 10 tabs");
|
||||
|
||||
checkSelectedTabVisible("two", function() {
|
||||
showTabView(function() {
|
||||
checkSelectedTabVisible("one", finish);
|
||||
groupItemOne.getChild(9).zoomIn();
|
||||
}, win);
|
||||
});
|
||||
groupItemTwo.getChild(9).zoomIn();
|
||||
}, function(newWin) {
|
||||
for (let i = 0; i < 9; i++)
|
||||
newWin.gBrowser.addTab();
|
||||
});
|
||||
}
|
||||
|
||||
function isSelectedTabVisible() {
|
||||
let tabstrip = win.gBrowser.tabContainer.mTabstrip;
|
||||
let scrollRect = tabstrip.scrollClientRect;
|
||||
let tab = win.gBrowser.selectedTab.getBoundingClientRect();
|
||||
|
||||
return (scrollRect.left <= tab.left && tab.right <= scrollRect.right);
|
||||
}
|
||||
|
||||
function checkSelectedTabVisible(groupName, callback) {
|
||||
whenTabViewIsHidden(function() {
|
||||
ok(isSelectedTabVisible(), "Group " + groupName + " selected tab is visible");
|
||||
callback();
|
||||
}, win);
|
||||
}
|
@ -152,6 +152,10 @@ let UI = {
|
||||
// Used to keep track of the last opened tab.
|
||||
_lastOpenedTab: null,
|
||||
|
||||
// Variable: _originalSmoothScroll
|
||||
// Used to keep track of the tab strip smooth scroll value.
|
||||
_originalSmoothScroll: null,
|
||||
|
||||
// ----------
|
||||
// Function: toString
|
||||
// Prints [UI] for debug use
|
||||
@ -514,6 +518,11 @@ let UI = {
|
||||
|
||||
this._isChangingVisibility = true;
|
||||
|
||||
// store tab strip smooth scroll value and disable it.
|
||||
let tabStrip = gBrowser.tabContainer.mTabstrip;
|
||||
this._originalSmoothScroll = tabStrip.smoothScroll;
|
||||
tabStrip.smoothScroll = false;
|
||||
|
||||
// initialize the direction of the page
|
||||
this._initPageDirection();
|
||||
|
||||
@ -609,6 +618,7 @@ let UI = {
|
||||
gBrowser.selectedBrowser.focus();
|
||||
|
||||
gBrowser.updateTitlebar();
|
||||
gBrowser.tabContainer.mTabstrip.smoothScroll = this._originalSmoothScroll;
|
||||
#ifdef XP_MACOSX
|
||||
this.setTitlebarColors(false);
|
||||
#endif
|
||||
|
@ -285,6 +285,7 @@ Highlighter.prototype = {
|
||||
*/
|
||||
destroy: function Highlighter_destroy()
|
||||
{
|
||||
this.IUI.win.clearTimeout(this.transitionDisabler);
|
||||
this.browser.removeEventListener("scroll", this, true);
|
||||
this.browser.removeEventListener("resize", this, true);
|
||||
this.boundCloseEventHandler = null;
|
||||
|
@ -489,7 +489,8 @@
|
||||
let isVertical = event.axis == event.VERTICAL_AXIS;
|
||||
|
||||
if (this._prevMouseScrolls.every(function(prev) prev == isVertical))
|
||||
this.scrollByIndex(this._isRTLScrollbox ? -event.detail : event.detail);
|
||||
this.scrollByIndex(isVertical && this._isRTLScrollbox ? -event.detail :
|
||||
event.detail);
|
||||
|
||||
if (this._prevMouseScrolls.length > 1)
|
||||
this._prevMouseScrolls.shift();
|
||||
|
@ -94,3 +94,17 @@ html|span.statActivity[seeking] > html|span.statActivitySeeking {
|
||||
.controlBar[size="small"] .scrubber {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
/* Error description formatting */
|
||||
.errorLabel {
|
||||
display: none;
|
||||
}
|
||||
|
||||
[error="errorAborted"] > [anonid="errorAborted"],
|
||||
[error="errorNetwork"] > [anonid="errorNetwork"],
|
||||
[error="errorDecode"] > [anonid="errorDecode"],
|
||||
[error="errorSrcNotSupported"] > [anonid="errorSrcNotSupported"],
|
||||
[error="errorNoSource"] > [anonid="errorNoSource"],
|
||||
[error="errorGeneric"] > [anonid="errorGeneric"] {
|
||||
display: inline;
|
||||
}
|
||||
|
@ -198,6 +198,12 @@
|
||||
<stack flex="1">
|
||||
<vbox flex="1" class="statusOverlay" hidden="true">
|
||||
<box class="statusIcon"/>
|
||||
<label class="errorLabel" anonid="errorAborted">&error.aborted;</label>
|
||||
<label class="errorLabel" anonid="errorNetwork">&error.network;</label>
|
||||
<label class="errorLabel" anonid="errorDecode">&error.decode;</label>
|
||||
<label class="errorLabel" anonid="errorSrcNotSupported">&error.srcNotSupported;</label>
|
||||
<label class="errorLabel" anonid="errorNoSource">&error.noSource;</label>
|
||||
<label class="errorLabel" anonid="errorGeneric">&error.generic;</label>
|
||||
</vbox>
|
||||
|
||||
<vbox class="statsOverlay" hidden="true">
|
||||
@ -412,8 +418,9 @@
|
||||
this.bufferBar.setAttribute("value", 0);
|
||||
|
||||
// Set the current status icon.
|
||||
if (this.video.error || this.video.networkState == this.video.NETWORK_NO_SOURCE) {
|
||||
if (this.hasError()) {
|
||||
this.statusIcon.setAttribute("type", "error");
|
||||
this.updateErrorText();
|
||||
this.setupStatusFader(true);
|
||||
} else {
|
||||
this.statusIcon.setAttribute("type", "throbber");
|
||||
@ -452,7 +459,7 @@
|
||||
|
||||
// If the video hits an error, suppress controls if it
|
||||
// hasn't managed to do anything else yet.
|
||||
if (!this.firstFrameShown && (this.video.error || this.video.networkState == this.video.NETWORK_NO_SOURCE))
|
||||
if (!this.firstFrameShown && this.hasError())
|
||||
enabled = false;
|
||||
|
||||
return enabled;
|
||||
@ -514,6 +521,8 @@
|
||||
break;
|
||||
case "loadstart":
|
||||
this.maxCurrentTimeSeen = 0;
|
||||
this.controlsSpacer.removeAttribute("aria-label");
|
||||
this.statusOverlay.removeAttribute("error");
|
||||
this.statusIcon.setAttribute("type", "throbber");
|
||||
this.isAudioOnly = (this.video instanceof HTMLAudioElement);
|
||||
this.setPlayButtonState(true);
|
||||
@ -586,8 +595,9 @@
|
||||
// 2. The video's networkState is NETWORK_NO_SOURCE. This means we we're
|
||||
// loading from child source elements, but we were unable to select
|
||||
// any of the child elements for playback during resource selection.
|
||||
if (this.video.error || this.video.networkState == this.video.NETWORK_NO_SOURCE) {
|
||||
if (this.hasError()) {
|
||||
this.statusIcon.setAttribute("type", "error");
|
||||
this.updateErrorText();
|
||||
this.setupStatusFader(true);
|
||||
// If video hasn't shown anything yet, disable the controls.
|
||||
if (!this.firstFrameShown)
|
||||
@ -604,14 +614,54 @@
|
||||
clearInterval(this.statsInterval);
|
||||
this.statsInterval = null;
|
||||
}
|
||||
for each (var event in this.videoEvents)
|
||||
for each (let event in this.videoEvents)
|
||||
this.video.removeEventListener(event, this, false);
|
||||
this.video.removeEventListener("media-showStatistics", this._handleCustomEventsBound, false);
|
||||
this.video.ownerDocument.removeEventListener("mozfullscreenchange", this.setFullscreenButtonState, false);
|
||||
delete this._handleCustomEventsBound;
|
||||
this.video.ownerDocument.removeEventListener("mozfullscreenchange", this._setFullscreenButtonStateBound, false);
|
||||
delete this._setFullscreenButtonStateBound;
|
||||
this.log("--- videocontrols terminated ---");
|
||||
},
|
||||
|
||||
hasError : function () {
|
||||
return (this.video.error != null || this.video.networkState == this.video.NETWORK_NO_SOURCE);
|
||||
},
|
||||
|
||||
updateErrorText : function () {
|
||||
let error;
|
||||
let v = this.video;
|
||||
// It is possible to have both v.networkState == NETWORK_NO_SOURCE
|
||||
// as well as v.error being non-null. In this case, we will show
|
||||
// the v.error.code instead of the v.networkState error.
|
||||
if (v.error) {
|
||||
switch (v.error.code) {
|
||||
case v.error.MEDIA_ERR_ABORTED:
|
||||
error = "errorAborted";
|
||||
break;
|
||||
case v.error.MEDIA_ERR_NETWORK:
|
||||
error = "errorNetwork";
|
||||
break;
|
||||
case v.error.MEDIA_ERR_DECODE:
|
||||
error = "errorDecode";
|
||||
break;
|
||||
case v.error.MEDIA_ERR_SRC_NOT_SUPPORTED:
|
||||
error = "errorSrcNotSupported";
|
||||
break;
|
||||
default:
|
||||
error = "errorGeneric";
|
||||
break;
|
||||
}
|
||||
} else if (v.networkState == v.NETWORK_NO_SOURCE) {
|
||||
error = "errorNoSource";
|
||||
} else {
|
||||
return; // No error found.
|
||||
}
|
||||
|
||||
let label = document.getAnonymousElementByAttribute(this.videocontrols, "anonid", error);
|
||||
this.controlsSpacer.setAttribute("aria-label", label.textContent);
|
||||
this.statusOverlay.setAttribute("error", error);
|
||||
},
|
||||
|
||||
formatTime : function(aTime) {
|
||||
// Format the duration as "h:mm:ss" or "m:ss"
|
||||
aTime = Math.round(aTime / 1000);
|
||||
@ -738,11 +788,43 @@
|
||||
this.startFade(this.volumeStack, isMouseOver);
|
||||
},
|
||||
|
||||
_hideControlsTimeout : 0,
|
||||
_hideControlsFn : function () {
|
||||
if (!Utils.scrubber.isDragging)
|
||||
Utils.startFade(Utils.controlBar, false);
|
||||
},
|
||||
HIDE_CONTROLS_TIMEOUT_MS : 2000,
|
||||
onMouseMove : function (event) {
|
||||
// If the controls are static, don't change anything.
|
||||
if (!this.dynamicControls)
|
||||
return;
|
||||
|
||||
clearTimeout(this._hideControlsTimeout);
|
||||
|
||||
// Suppress fading out the controls until the video has rendered
|
||||
// its first frame. But since autoplay videos start off with no
|
||||
// controls, let them fade-out so the controls don't get stuck on.
|
||||
if (!this.firstFrameShown &&
|
||||
!(this.video.autoplay && this.video.mozAutoplayEnabled))
|
||||
return;
|
||||
|
||||
this.startFade(this.controlBar, true);
|
||||
// Only hide the controls if the mouse cursor is not left on top of
|
||||
// the control bar. We only need to check the Y position of the cursor
|
||||
// since the controls span the width of the video and are always located
|
||||
// at the bottom of the video.
|
||||
if (event.clientY < this.controlBar.getBoundingClientRect().top) {
|
||||
this._hideControlsTimeout = setTimeout(this._hideControlsFn, this.HIDE_CONTROLS_TIMEOUT_MS);
|
||||
}
|
||||
},
|
||||
|
||||
onMouseInOut : function (event) {
|
||||
// If the controls are static, don't change anything.
|
||||
if (!this.dynamicControls)
|
||||
return;
|
||||
|
||||
clearTimeout(this._hideControlsTimeout);
|
||||
|
||||
// Ignore events caused by transitions between child nodes.
|
||||
// Note that the videocontrols element is the same
|
||||
// size as the *content area* of the video element,
|
||||
@ -760,10 +842,13 @@
|
||||
!(this.video.autoplay && this.video.mozAutoplayEnabled))
|
||||
return;
|
||||
|
||||
if (!isMouseOver)
|
||||
if (!isMouseOver) {
|
||||
this.adjustControlSize();
|
||||
|
||||
this.startFade(this.controlBar, isMouseOver);
|
||||
// Setting a timer here to handle the case where the mouse leaves
|
||||
// the video from hovering over the controls.
|
||||
this._hideControlsTimeout = setTimeout(this._hideControlsFn, this.HIDE_CONTROLS_TIMEOUT_MS);
|
||||
}
|
||||
},
|
||||
|
||||
startFadeIn : function (element, immediate) {
|
||||
@ -775,11 +860,15 @@
|
||||
},
|
||||
|
||||
startFade : function (element, fadeIn, immediate) {
|
||||
// Bug 493523, the scrubber doesn't call valueChanged while hidden,
|
||||
// so our dependent state (eg, timestamp in the thumb) will be stale.
|
||||
// As a workaround, update it manually when it first becomes unhidden.
|
||||
if (element.className == "controlBar" && fadeIn && element.hidden)
|
||||
this.scrubber.valueChanged("curpos", this.video.currentTime * 1000, false);
|
||||
if (element.className == "controlBar" && fadeIn) {
|
||||
clearTimeout(this._hideControlsTimeout);
|
||||
|
||||
// Bug 493523, the scrubber doesn't call valueChanged while hidden,
|
||||
// so our dependent state (eg, timestamp in the thumb) will be stale.
|
||||
// As a workaround, update it manually when it first becomes unhidden.
|
||||
if (element.hidden)
|
||||
this.scrubber.valueChanged("curpos", this.video.currentTime * 1000, false);
|
||||
}
|
||||
|
||||
if (immediate)
|
||||
element.setAttribute("immediate", true);
|
||||
@ -1184,13 +1273,13 @@
|
||||
// Use the handleEvent() callback for all media events.
|
||||
// The "error" event listener must capture, so that it can trap error events
|
||||
// from the <source> children, which don't bubble.
|
||||
for each (var event in this.videoEvents)
|
||||
for each (let event in this.videoEvents)
|
||||
this.video.addEventListener(event, this, (event == "error") ? true : false);
|
||||
|
||||
var self = this;
|
||||
this.muteButton.addEventListener("command", function() { self.toggleMute(); }, false);
|
||||
this.playButton.addEventListener("command", function() { self.togglePause(); }, false);
|
||||
this.controlsSpacer.addEventListener("click", function(e) { if (e.button == 0) { self.togglePause(); } }, false);
|
||||
this.controlsSpacer.addEventListener("click", function(e) { if (e.button == 0 && !self.hasError()) { self.togglePause(); } }, false);
|
||||
this.fullscreenButton.addEventListener("command", function() { self.toggleFullscreen(); }, false );
|
||||
if (!this.isAudioOnly) {
|
||||
this.muteButton.addEventListener("mouseover", function(e) { self.onVolumeMouseInOut(e); }, false);
|
||||
@ -1200,7 +1289,8 @@
|
||||
}
|
||||
|
||||
this.videocontrols.addEventListener("transitionend", function(e) { self.onTransitionEnd(e); }, false);
|
||||
this.video.ownerDocument.addEventListener("mozfullscreenchange", this.setFullscreenButtonState, false);
|
||||
this._setFullscreenButtonStateBound = this.setFullscreenButtonState.bind(this);
|
||||
this.video.ownerDocument.addEventListener("mozfullscreenchange", this._setFullscreenButtonStateBound, false);
|
||||
|
||||
// Make the <video> element keyboard accessible.
|
||||
this.video.setAttribute("tabindex", 0);
|
||||
@ -1224,6 +1314,10 @@
|
||||
if (!this.isTouchControl)
|
||||
this.Utils.onMouseInOut(event);
|
||||
</handler>
|
||||
<handler event="mousemove">
|
||||
if (!this.isTouchControl)
|
||||
this.Utils.onMouseMove(event);
|
||||
</handler>
|
||||
</handlers>
|
||||
</binding>
|
||||
|
||||
|
@ -20,6 +20,13 @@
|
||||
<!ENTITY stats.framesPresented "Frames presented">
|
||||
<!ENTITY stats.framesPainted "Frames painted">
|
||||
|
||||
<!ENTITY error.aborted "Video loading stopped.">
|
||||
<!ENTITY error.network "Video playback aborted due to a network error.">
|
||||
<!ENTITY error.decode "Video can't be played because the file is corrupt.">
|
||||
<!ENTITY error.srcNotSupported "Video format or MIME type is not supported.">
|
||||
<!ENTITY error.noSource "Video not found.">
|
||||
<!ENTITY error.generic "Video playback aborted due to an unknown error.">
|
||||
|
||||
<!-- LOCALIZATION NOTE (scrubberScale.nameFormat): the #1 string is the current
|
||||
media position, and the #2 string is the total duration. For example, when at
|
||||
the 5 minute mark in a 6 hour long video, #1 would be "5:00" and #2 would be
|
||||
|
@ -206,7 +206,7 @@ html|td {
|
||||
padding: 0 2px;
|
||||
}
|
||||
html|table {
|
||||
font-family: Helvetica, Ariel, sans-serif;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
font-size: 11px;
|
||||
color: white;
|
||||
text-shadow:
|
||||
@ -245,3 +245,17 @@ html|table {
|
||||
.statusOverlay[fadeout] {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* Error description formatting */
|
||||
.errorLabel {
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
font-size: 11px;
|
||||
color: #bbb;
|
||||
text-shadow:
|
||||
-1px -1px 0 #000,
|
||||
1px -1px 0 #000,
|
||||
-1px 1px 0 #000,
|
||||
1px 1px 0 #000;
|
||||
padding: 0 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ html|td {
|
||||
padding: 0 2px;
|
||||
}
|
||||
html|table {
|
||||
font-family: Helvetica, Ariel, sans-serif;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
font-size: 11px;
|
||||
color: white;
|
||||
text-shadow:
|
||||
@ -254,3 +254,17 @@ html|table {
|
||||
.statusOverlay[fadeout] {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* Error description formatting */
|
||||
.errorLabel {
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
font-size: 11px;
|
||||
color: #bbb;
|
||||
text-shadow:
|
||||
-1px -1px 0 #000,
|
||||
1px -1px 0 #000,
|
||||
-1px 1px 0 #000,
|
||||
1px 1px 0 #000;
|
||||
padding: 0 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user