Merge m-c to m-i

This commit is contained in:
Phil Ringnalda 2016-07-09 09:01:35 -07:00
commit f69792c77b
75 changed files with 700 additions and 826 deletions

View File

@ -1,7 +1,7 @@
[DEFAULT]
support-files =
../../../dom/media/test/bug461281.ogg
dumbfile.xpi
dumbfile.zip
formimage.png
letters.gif
moz.png

View File

@ -6,7 +6,7 @@ support-files =
z_frames_textbox.html
z_frames_update.html
!/accessible/tests/mochitest/*.js
!/accessible/tests/mochitest/dumbfile.xpi
!/accessible/tests/mochitest/dumbfile.zip
!/accessible/tests/mochitest/formimage.png
!/accessible/tests/mochitest/treeview.css

View File

@ -74,6 +74,6 @@
<pre id="test">
</pre>
<a id="link" href="http://example.com/a11y/accessible/tests/mochitest/dumbfile.xpi">a file</a>
<a id="link" href="http://example.com/a11y/accessible/tests/mochitest/dumbfile.zip">a file</a>
</body>
</html>

View File

@ -3,6 +3,248 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
var PointerlockFsWarning = {
_element: null,
_origin: null,
init: function() {
this.Timeout.prototype = {
start: function() {
this.cancel();
this._id = setTimeout(() => this._handle(), this._delay);
},
cancel: function() {
if (this._id) {
clearTimeout(this._id);
this._id = 0;
}
},
_handle: function() {
this._id = 0;
this._func();
},
get delay() {
return this._delay;
}
};
},
/**
* Timeout object for managing timeout request. If it is started when
* the previous call hasn't finished, it would automatically cancelled
* the previous one.
*/
Timeout: function(func, delay) {
this._id = 0;
this._func = func;
this._delay = delay;
},
showPointerLock: function(aOrigin) {
if (!document.fullscreen) {
let timeout = gPrefService.getIntPref("pointer-lock-api.warning.timeout");
this.show(aOrigin, "pointerlock-warning", timeout, 0);
}
},
showFullScreen: function(aOrigin) {
let timeout = gPrefService.getIntPref("full-screen-api.warning.timeout");
let delay = gPrefService.getIntPref("full-screen-api.warning.delay");
this.show(aOrigin, "fullscreen-warning", timeout, delay);
},
// Shows a warning that the site has entered fullscreen or
// pointer lock for a short duration.
show: function(aOrigin, elementId, timeout, delay) {
if (!this._element) {
this._element = document.getElementById(elementId);
// Setup event listeners
this._element.addEventListener("transitionend", this);
window.addEventListener("mousemove", this, true);
// The timeout to hide the warning box after a while.
this._timeoutHide = new this.Timeout(() => {
this._state = "hidden";
}, timeout);
// The timeout to show the warning box when the pointer is at the top
this._timeoutShow = new this.Timeout(() => {
this._state = "ontop";
this._timeoutHide.start();
}, delay);
}
// Set the strings on the warning UI.
if (aOrigin) {
this._origin = aOrigin;
}
let uri = BrowserUtils.makeURI(this._origin);
let host = null;
try {
host = uri.host;
} catch (e) { }
let textElem = this._element.querySelector(".pointerlockfswarning-domain-text");
if (!host) {
textElem.setAttribute("hidden", true);
} else {
textElem.removeAttribute("hidden");
let hostElem = this._element.querySelector(".pointerlockfswarning-domain");
// Document's principal's URI has a host. Display a warning including it.
let utils = {};
Cu.import("resource://gre/modules/DownloadUtils.jsm", utils);
hostElem.textContent = utils.DownloadUtils.getURIHost(uri.spec)[0];
}
this._element.dataset.identity =
gIdentityHandler.pointerlockFsWarningClassName;
// User should be allowed to explicitly disable
// the prompt if they really want.
if (this._timeoutHide.delay <= 0) {
return;
}
// Explicitly set the last state to hidden to avoid the warning
// box being hidden immediately because of mousemove.
this._state = "onscreen";
this._lastState = "hidden";
this._timeoutHide.start();
},
close: function() {
if (!this._element) {
return;
}
// Cancel any pending timeout
this._timeoutHide.cancel();
this._timeoutShow.cancel();
// Reset state of the warning box
this._state = "hidden";
this._element.setAttribute("hidden", true);
// Remove all event listeners
this._element.removeEventListener("transitionend", this);
window.removeEventListener("mousemove", this, true);
// Clear fields
this._element = null;
this._timeoutHide = null;
this._timeoutShow = null;
// Ensure focus switches away from the (now hidden) warning box.
// If the user clicked buttons in the warning box, it would have
// been focused, and any key events would be directed at the (now
// hidden) chrome document instead of the target document.
gBrowser.selectedBrowser.focus();
},
// State could be one of "onscreen", "ontop", "hiding", and
// "hidden". Setting the state to "onscreen" and "ontop" takes
// effect immediately, while setting it to "hidden" actually
// turns the state to "hiding" before the transition finishes.
_lastState: null,
_STATES: ["hidden", "ontop", "onscreen"],
get _state() {
for (let state of this._STATES) {
if (this._element.hasAttribute(state)) {
return state;
}
}
return "hiding";
},
set _state(newState) {
let currentState = this._state;
if (currentState == newState) {
return;
}
if (currentState != "hiding") {
this._lastState = currentState;
this._element.removeAttribute(currentState);
}
if (newState != "hidden") {
if (currentState != "hidden") {
this._element.setAttribute(newState, true);
} else {
// When the previous state is hidden, the display was none,
// thus no box was constructed. We need to wait for the new
// display value taking effect first, otherwise, there won't
// be any transition. Since requestAnimationFrame callback is
// generally triggered before any style flush and layout, we
// should wait for the second animation frame.
requestAnimationFrame(() => {
requestAnimationFrame(() => {
if (this._element) {
this._element.setAttribute(newState, true);
}
});
});
}
}
},
handleEvent: function(event) {
switch (event.type) {
case "mousemove": {
let state = this._state;
if (state == "hidden") {
// If the warning box is currently hidden, show it after
// a short delay if the pointer is at the top.
if (event.clientY != 0) {
this._timeoutShow.cancel();
} else if (this._timeoutShow.delay >= 0) {
this._timeoutShow.start();
}
} else {
let elemRect = this._element.getBoundingClientRect();
if (state == "hiding" && this._lastState != "hidden") {
// If we are on the hiding transition, and the pointer
// moved near the box, restore to the previous state.
if (event.clientY <= elemRect.bottom + 50) {
this._state = this._lastState;
this._timeoutHide.start();
}
} else if (state == "ontop" || this._lastState != "hidden") {
// State being "ontop" or the previous state not being
// "hidden" indicates this current warning box is shown
// in response to user's action. Hide it immediately when
// the pointer leaves that area.
if (event.clientY > elemRect.bottom + 50) {
this._state = "hidden";
this._timeoutHide.cancel();
}
}
}
break;
}
case "transitionend": {
if (this._state == "hiding") {
this._element.setAttribute("hidden", true);
}
break;
}
}
}
};
var PointerLock = {
init: function() {
window.messageManager.addMessageListener("PointerLock:Entered", this);
window.messageManager.addMessageListener("PointerLock:Exited", this);
},
receiveMessage: function(aMessage) {
switch (aMessage.name) {
case "PointerLock:Entered": {
PointerlockFsWarning.showPointerLock(aMessage.data.originNoSuffix);
break;
}
case "PointerLock:Exited": {
PointerlockFsWarning.close();
break;
}
}
}
};
var FullScreen = {
_MESSAGES: [
"DOMFullscreen:Request",
@ -24,8 +266,6 @@ var FullScreen = {
window.messageManager.addMessageListener(type, this);
}
this._WarningBox.init();
if (window.fullScreen)
this.toggle();
},
@ -108,11 +348,6 @@ var FullScreen = {
handleEvent: function (event) {
switch (event.type) {
case "activate":
if (document.fullscreenElement) {
this._WarningBox.show();
}
break;
case "fullscreen":
this.toggle();
break;
@ -150,7 +385,7 @@ var FullScreen = {
break;
}
case "DOMFullscreen:NewOrigin": {
this._WarningBox.show(aMessage.data.originNoSuffix);
PointerlockFsWarning.showFullScreen(aMessage.data.originNoSuffix);
break;
}
case "DOMFullscreen:Exit": {
@ -166,10 +401,15 @@ var FullScreen = {
},
enterDomFullscreen : function(aBrowser) {
if (!document.fullscreenElement) {
return;
}
// If we have a current pointerlock warning shown then hide it
// before transition.
PointerlockFsWarning.close();
// If we've received a fullscreen notification, we have to ensure that the
// element that's requesting fullscreen belongs to the browser that's currently
// active. If not, we exit fullscreen since the "full-screen document" isn't
@ -222,7 +462,7 @@ var FullScreen = {
window.messageManager
.broadcastAsyncMessage("DOMFullscreen:CleanUp");
this._WarningBox.close();
PointerlockFsWarning.close();
gBrowser.tabContainer.removeEventListener("TabOpen", this.exitDomFullScreen);
gBrowser.tabContainer.removeEventListener("TabClose", this.exitDomFullScreen);
gBrowser.tabContainer.removeEventListener("TabSelect", this.exitDomFullScreen);
@ -320,213 +560,6 @@ var FullScreen = {
FullScreen.hideNavToolbox(true);
},
_WarningBox: {
_element: null,
_origin: null,
/**
* Timeout object for managing timeout request. If it is started when
* the previous call hasn't finished, it would automatically cancelled
* the previous one.
*/
Timeout: function(func, delay) {
this._id = 0;
this._func = func;
this._delay = delay;
},
init: function() {
this.Timeout.prototype = {
start: function() {
this.cancel();
this._id = setTimeout(() => this._handle(), this._delay);
},
cancel: function() {
if (this._id) {
clearTimeout(this._id);
this._id = 0;
}
},
_handle: function() {
this._id = 0;
this._func();
},
get delay() {
return this._delay;
}
};
},
// Shows a warning that the site has entered fullscreen for a short duration.
show: function(aOrigin) {
if (!document.fullscreenElement) {
return;
}
if (!this._element) {
this._element = document.getElementById("fullscreen-warning");
// Setup event listeners
this._element.addEventListener("transitionend", this);
window.addEventListener("mousemove", this, true);
// The timeout to hide the warning box after a while.
this._timeoutHide = new this.Timeout(() => {
this._state = "hidden";
}, gPrefService.getIntPref("full-screen-api.warning.timeout"));
// The timeout to show the warning box when the pointer is at the top
this._timeoutShow = new this.Timeout(() => {
this._state = "ontop";
this._timeoutHide.start();
}, gPrefService.getIntPref("full-screen-api.warning.delay"));
}
// Set the strings on the fullscreen warning UI.
if (aOrigin) {
this._origin = aOrigin;
}
let uri = BrowserUtils.makeURI(this._origin);
let host = null;
try {
host = uri.host;
} catch (e) { }
let textElem = document.getElementById("fullscreen-domain-text");
if (!host) {
textElem.setAttribute("hidden", true);
} else {
textElem.removeAttribute("hidden");
let hostElem = document.getElementById("fullscreen-domain");
// Document's principal's URI has a host. Display a warning including it.
let utils = {};
Cu.import("resource://gre/modules/DownloadUtils.jsm", utils);
hostElem.textContent = utils.DownloadUtils.getURIHost(uri.spec)[0];
}
this._element.className = gIdentityHandler.fullscreenWarningClassName;
// User should be allowed to explicitly disable
// the prompt if they really want.
if (this._timeoutHide.delay <= 0) {
return;
}
// Explicitly set the last state to hidden to avoid the warning
// box being hidden immediately because of mousemove.
this._state = "onscreen";
this._lastState = "hidden";
this._timeoutHide.start();
},
close: function() {
if (!this._element) {
return;
}
// Cancel any pending timeout
this._timeoutHide.cancel();
this._timeoutShow.cancel();
// Reset state of the warning box
this._state = "hidden";
this._element.setAttribute("hidden", true);
// Remove all event listeners
this._element.removeEventListener("transitionend", this);
window.removeEventListener("mousemove", this, true);
// Clear fields
this._element = null;
this._timeoutHide = null;
this._timeoutShow = null;
// Ensure focus switches away from the (now hidden) warning box.
// If the user clicked buttons in the warning box, it would have
// been focused, and any key events would be directed at the (now
// hidden) chrome document instead of the target document.
gBrowser.selectedBrowser.focus();
},
// State could be one of "onscreen", "ontop", "hiding", and
// "hidden". Setting the state to "onscreen" and "ontop" takes
// effect immediately, while setting it to "hidden" actually
// turns the state to "hiding" before the transition finishes.
_lastState: null,
_STATES: ["hidden", "ontop", "onscreen"],
get _state() {
for (let state of this._STATES) {
if (this._element.hasAttribute(state)) {
return state;
}
}
return "hiding";
},
set _state(newState) {
let currentState = this._state;
if (currentState == newState) {
return;
}
if (currentState != "hiding") {
this._lastState = currentState;
this._element.removeAttribute(currentState);
}
if (newState != "hidden") {
if (currentState != "hidden") {
this._element.setAttribute(newState, true);
} else {
// When the previous state is hidden, the display was none,
// thus no box was constructed. We need to wait for the new
// display value taking effect first, otherwise, there won't
// be any transition. Since requestAnimationFrame callback is
// generally triggered before any style flush and layout, we
// should wait for the second animation frame.
requestAnimationFrame(() => {
requestAnimationFrame(() => {
if (this._element) {
this._element.setAttribute(newState, true);
}
});
});
}
}
},
handleEvent: function(event) {
switch (event.type) {
case "mousemove": {
let state = this._state;
if (state == "hidden") {
// If the warning box is currently hidden, show it after
// a short delay if the pointer is at the top.
if (event.clientY != 0) {
this._timeoutShow.cancel();
} else if (this._timeoutShow.delay >= 0) {
this._timeoutShow.start();
}
} else {
let elemRect = this._element.getBoundingClientRect();
if (state == "hiding" && this._lastState != "hidden") {
// If we are on the hiding transition, and the pointer
// moved near the box, restore to the previous state.
if (event.clientY <= elemRect.bottom + 50) {
this._state = this._lastState;
this._timeoutHide.start();
}
} else if (state == "ontop" || this._lastState != "hidden") {
// State being "ontop" or the previous state not being
// "hidden" indicates this current warning box is shown
// in response to user's action. Hide it immediately when
// the pointer leaves that area.
if (event.clientY > elemRect.bottom + 50) {
this._state = "hidden";
this._timeoutHide.cancel();
}
}
}
break;
}
case "transitionend": {
if (this._state == "hiding") {
this._element.setAttribute("hidden", true);
}
break;
}
}
}
},
showNavToolbox: function(trackMouse = true) {
this._fullScrToggler.hidden = true;
gNavToolbox.removeAttribute("fullscreenShouldAnimate");

View File

@ -660,7 +660,7 @@ window[chromehidden~="toolbar"] toolbar:not(#nav-bar):not(#TabsToolbar):not(#pri
background: black;
}
html|*#fullscreen-warning {
html|*.pointerlockfswarning {
position: fixed;
z-index: 2147483647 !important;
visibility: visible;
@ -674,28 +674,28 @@ html|*#fullscreen-warning {
max-width: 95%;
pointer-events: none;
}
html|*#fullscreen-warning:not([hidden]) {
html|*.pointerlockfswarning:not([hidden]) {
display: flex;
will-change: transform;
}
html|*#fullscreen-warning[onscreen] {
html|*.pointerlockfswarning[onscreen] {
transform: translate(-50%, 50px);
}
html|*#fullscreen-warning[ontop] {
html|*.pointerlockfswarning[ontop] {
/* Use -10px to hide the border and border-radius on the top */
transform: translate(-50%, -10px);
}
#main-window[OSXLionFullscreen] html|*#fullscreen-warning[ontop] {
#main-window[OSXLionFullscreen] html|*.pointerlockfswarning[ontop] {
transform: translate(-50%, 80px);
}
html|*#fullscreen-domain-text,
html|*#fullscreen-generic-text {
html|*.pointerlockfswarning-domain-text,
html|*.pointerlockfswarning-generic-text {
word-wrap: break-word;
/* We must specify a min-width, otherwise word-wrap:break-word doesn't work. Bug 630864. */
min-width: 1px
}
html|*#fullscreen-domain-text:not([hidden]) + html|*#fullscreen-generic-text {
html|*.pointerlockfswarning-domain-text:not([hidden]) + html|*.pointerlockfswarning-generic-text {
display: none;
}

View File

@ -1297,7 +1297,9 @@ var gBrowserInit = {
if (Win7Features)
Win7Features.onOpenWindow();
PointerlockFsWarning.init();
FullScreen.init();
PointerLock.init();
// initialize the sync UI
gSyncUI.init();
@ -6820,7 +6822,7 @@ var gIdentityHandler = {
* display information about connection security in the notification shown
* when a site enters the fullscreen mode.
*/
get fullscreenWarningClassName() {
get pointerlockFsWarningClassName() {
// Note that the fullscreen warning does not handle _isSecureInternalUI.
if (this._uriHasHost && this._isEV) {
return "verifiedIdentity";

View File

@ -1142,13 +1142,13 @@
#include ../../components/customizableui/content/customizeMode.inc.xul
</deck>
<html:div id="fullscreen-warning" hidden="true">
<html:div id="fullscreen-domain-text">
<html:div id="fullscreen-warning" class="pointerlockfswarning" hidden="true">
<html:div class="pointerlockfswarning-domain-text">
&fullscreenWarning.beforeDomain.label;
<html:span id="fullscreen-domain"/>
<html:span class="pointerlockfswarning-domain"/>
&fullscreenWarning.afterDomain.label;
</html:div>
<html:div id="fullscreen-generic-text">
<html:div class="pointerlockfswarning-generic-text">
&fullscreenWarning.generic.label;
</html:div>
<html:button id="fullscreen-exit-button"
@ -1161,6 +1161,17 @@
</html:button>
</html:div>
<html:div id="pointerlock-warning" class="pointerlockfswarning" hidden="true">
<html:div class="pointerlockfswarning-domain-text">
&pointerlockWarning.beforeDomain.label;
<html:span class="pointerlockfswarning-domain"/>
&pointerlockWarning.afterDomain.label;
</html:div>
<html:div class="pointerlockfswarning-generic-text">
&pointerlockWarning.generic.label;
</html:div>
</html:div>
<vbox id="browser-bottombox" layer="true">
<notificationbox id="global-notificationbox" notificationside="bottom"/>
</vbox>

View File

@ -16,7 +16,7 @@
<script type="application/javascript" src="chrome://browser/content/browser-customization.js"/>
<script type="application/javascript" src="chrome://browser/content/browser-devedition.js"/>
<script type="application/javascript" src="chrome://browser/content/browser-feeds.js"/>
<script type="application/javascript" src="chrome://browser/content/browser-fullScreen.js"/>
<script type="application/javascript" src="chrome://browser/content/browser-fullScreenAndPointerLock.js"/>
<script type="application/javascript" src="chrome://browser/content/browser-fullZoom.js"/>
<script type="application/javascript" src="chrome://browser/content/browser-gestureSupport.js"/>
<script type="application/javascript" src="chrome://browser/content/browser-media.js"/>

View File

@ -41,6 +41,17 @@ XPCOMUtils.defineLazyGetter(this, "SimpleServiceDiscovery", function() {
var global = this;
addEventListener("MozDOMPointerLock:Entered", function(aEvent) {
sendAsyncMessage("PointerLock:Entered", {
originNoSuffix: aEvent.target.nodePrincipal.originNoSuffix
});
});
addEventListener("MozDOMPointerLock:Exited", function(aEvent) {
sendAsyncMessage("PointerLock:Exited");
});
addMessageListener("Browser:HideSessionRestoreButton", function (message) {
// Hide session restore button on about:home
let doc = content.document;

View File

@ -2730,6 +2730,13 @@
let ourPermanentKey = ourBrowser.permanentKey;
ourBrowser.permanentKey = aOtherBrowser.permanentKey;
aOtherBrowser.permanentKey = ourPermanentKey;
aOurTab.permanentKey = ourBrowser.permanentKey;
if (remoteBrowser) {
let otherTab = remoteBrowser.getTabForBrowser(aOtherBrowser);
if (otherTab) {
otherTab.permanentKey = aOtherBrowser.permanentKey;
}
}
// Restore the progress listener
tabListener = this.mTabProgressListener(aOurTab, ourBrowser, false, false);

View File

@ -79,7 +79,7 @@ browser.jar:
content/browser/browser-data-submission-info-bar.js (content/browser-data-submission-info-bar.js)
content/browser/browser-devedition.js (content/browser-devedition.js)
content/browser/browser-feeds.js (content/browser-feeds.js)
content/browser/browser-fullScreen.js (content/browser-fullScreen.js)
content/browser/browser-fullScreenAndPointerLock.js (content/browser-fullScreenAndPointerLock.js)
content/browser/browser-fullZoom.js (content/browser-fullZoom.js)
content/browser/browser-fxaccounts.js (content/browser-fxaccounts.js)
content/browser/browser-gestureSupport.js (content/browser-gestureSupport.js)

View File

@ -2740,62 +2740,6 @@ ContentPermissionPrompt.prototype = {
"web-notifications-notification-icon", options);
},
_promptPointerLock: function CPP_promtPointerLock(aRequest, autoAllow) {
let message = gBrowserBundle.GetStringFromName(autoAllow ?
"pointerLock.autoLock.title3" : "pointerLock.title3");
// If this is an autoAllow info prompt, offer no actions.
// _showPrompt() will allow the request when it's dismissed.
let actions = [];
if (!autoAllow) {
actions = [
{
stringId: "pointerLock.allow2",
action: null,
expireType: null,
callback: function() {},
},
{
stringId: "pointerLock.alwaysAllow",
action: Ci.nsIPermissionManager.ALLOW_ACTION,
expireType: null,
callback: function() {},
},
{
stringId: "pointerLock.neverAllow",
action: Ci.nsIPermissionManager.DENY_ACTION,
expireType: null,
callback: function() {},
},
];
}
function onFullScreen() {
notification.remove();
}
let options = {};
options.removeOnDismissal = autoAllow;
options.eventCallback = type => {
if (type == "removed") {
notification.browser.removeEventListener("fullscreenchange", onFullScreen, true);
if (autoAllow) {
aRequest.allow();
}
}
}
let notification =
this._showPrompt(aRequest, message, "pointerLock", actions, "pointerLock",
"pointerLock-notification-icon", options);
// pointerLock is automatically allowed in fullscreen mode (and revoked
// upon exit), so if the page enters fullscreen mode after requesting
// pointerLock (but before the user has granted permission), we should
// remove the now-impotent notification.
notification.browser.addEventListener("fullscreenchange", onFullScreen, true);
},
prompt: function CPP_prompt(request) {
// Only allow exactly one permission request here.
let types = request.types.QueryInterface(Ci.nsIArray);
@ -2806,8 +2750,7 @@ ContentPermissionPrompt.prototype = {
let perm = types.queryElementAt(0, Ci.nsIContentPermissionType);
const kFeatureKeys = { "geolocation" : "geo",
"desktop-notification" : "desktop-notification",
"pointerLock" : "pointerLock",
"desktop-notification" : "desktop-notification"
};
// Make sure that we support the request.
@ -2833,11 +2776,6 @@ ContentPermissionPrompt.prototype = {
if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
autoAllow = true;
// For pointerLock, we still want to show a warning prompt.
if (perm.type != "pointerLock") {
request.allow();
return;
}
}
var browser = this._getBrowserForRequest(request);
@ -2855,9 +2793,6 @@ ContentPermissionPrompt.prototype = {
case "desktop-notification":
this._promptWebNotifications(request);
break;
case "pointerLock":
this._promptPointerLock(request, autoAllow);
break;
}
},

View File

@ -1488,22 +1488,33 @@ var SessionStoreInternal = {
* @return Promise
*/
flushAllWindowsAsync: Task.async(function*(progress={}) {
let windowPromises = [];
let windowPromises = new Map();
// We collect flush promises and close each window immediately so that
// the user can't start changing any window state while we're waiting
// for the flushes to finish.
this._forEachBrowserWindow((win) => {
windowPromises.push(TabStateFlusher.flushWindow(win));
win.close();
windowPromises.set(win, TabStateFlusher.flushWindow(win));
// We have to wait for these messages to come up from
// each window and each browser. In the meantime, hide
// the windows to improve perceived shutdown speed.
let baseWin = win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell)
.QueryInterface(Ci.nsIDocShellTreeItem)
.treeOwner
.QueryInterface(Ci.nsIBaseWindow);
baseWin.visibility = false;
});
progress.total = windowPromises.length;
progress.total = windowPromises.size;
progress.current = 0;
// We'll iterate through the Promise array, yielding each one, so as to
// provide useful progress information to AsyncShutdown.
for (let i = 0; i < windowPromises.length; ++i) {
progress.current = i;
yield windowPromises[i];
for (let [win, promise] of windowPromises) {
yield promise;
this._collectWindowData(win);
progress.current++;
};
// We must cache this because _getMostRecentBrowserWindow will always

View File

@ -22,6 +22,14 @@
<input type="password" name="password"/>
<input type="PassWord" name="password2"/>
<input type="PASSWORD" name="password3"/>
<input autocomplete="off" name="auto1"/>
<input type="text" autocomplete="OFF" name="auto2"/>
<textarea autocomplete="off" name="auto3"/>
<select autocomplete="off" name="auto4">
<option value="1" selected="true"/>
<option value="2"/>
<option value="3"/>
</select>
</form>
</body>

View File

@ -128,6 +128,11 @@ These should match what Safari and other Apple applications use on OS X Lion. --
<!ENTITY fullscreenWarning.beforeDomain.label "">
<!ENTITY fullscreenWarning.afterDomain.label "is now full screen">
<!ENTITY fullscreenWarning.generic.label "This document is now full screen">
<!ENTITY pointerlockWarning.beforeDomain.label "">
<!ENTITY pointerlockWarning.afterDomain.label "has control of your pointer. Press Esc to take back control.">
<!ENTITY pointerlockWarning.generic.label "This document has control of your pointer. Press Esc to take back control">
<!-- LOCALIZATION NOTE (exitDOMFullscreen.button,
exitDOMFullscreenMac.button): the "escape" button on PC keyboards
is uppercase, while on Mac keyboards it is lowercase -->

View File

@ -388,17 +388,6 @@ webNotifications.upgradeTitle=Upgraded notifications
# LOCALIZATION NOTE (webNotifications.upgradeBody): When using native notifications on OS X, the body may be truncated around 100 characters in some views.
webNotifications.upgradeBody=You can now receive notifications from sites that are not currently loaded. Click to learn more.
# Pointer lock UI
pointerLock.allow2=Hide pointer
pointerLock.allow2.accesskey=H
pointerLock.alwaysAllow=Always allow hiding
pointerLock.alwaysAllow.accesskey=A
pointerLock.neverAllow=Never allow hiding
pointerLock.neverAllow.accesskey=N
pointerLock.title3=Would you like to allow the pointer to be hidden on this site?
pointerLock.autoLock.title3=This site will hide the pointer.
# Phishing/Malware Notification Bar.
# LOCALIZATION NOTE (notADeceptiveSite, notAnAttack)
# The two button strings will never be shown at the same time, so

View File

@ -16,4 +16,3 @@ permission.install.label = Install Add-ons
permission.popup.label = Open Pop-up Windows
permission.geo.label = Access Your Location
permission.indexedDB.label = Maintain Offline Storage
permission.pointerLock.label = Hide the Mouse Pointer

View File

@ -245,11 +245,7 @@ var gPermissionObject = {
exactHostMatch: true
},
"indexedDB": {},
"pointerLock": {
exactHostMatch: true
}
"indexedDB": {}
};
const kPermissionIDs = Object.keys(gPermissionObject);

View File

@ -9,7 +9,7 @@ Components.utils.import("resource://gre/modules/Services.jsm");
add_task(function* testPermissionsListing() {
Assert.deepEqual(SitePermissions.listPermissions().sort(),
["camera","cookie","desktop-notification","geo","image",
"indexedDB","install","microphone","pointerLock","popup"],
"indexedDB","install","microphone","popup"],
"Correct list of all permissions");
});
@ -38,8 +38,6 @@ add_task(function* testHasGrantedPermissions() {
SitePermissions.remove(uri, "microphone");
Assert.equal(SitePermissions.hasGrantedPermissions(uri), false);
SitePermissions.set(uri, "pointerLock", SitePermissions.BLOCK);
// check that a combination of ALLOW and BLOCK states returns true
SitePermissions.set(uri, "geo", SitePermissions.ALLOW);
Assert.equal(SitePermissions.hasGrantedPermissions(uri), true);
@ -52,7 +50,6 @@ add_task(function* testHasGrantedPermissions() {
SitePermissions.remove(uri, "geo");
Assert.equal(SitePermissions.hasGrantedPermissions(uri), false);
SitePermissions.remove(uri, "pointerLock");
});
add_task(function* testGetPermissionsByURI() {

View File

@ -4,7 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
%endif
html|*#fullscreen-warning {
html|*.pointerlockfswarning {
align-items: center;
background: rgba(45, 62, 72, 0.9);
border: 2px solid #fafafa;
@ -14,38 +14,38 @@ html|*#fullscreen-warning {
font: message-box;
}
html|*#fullscreen-warning::before {
html|*.pointerlockfswarning::before {
margin: 0;
width: 24px; height: 24px;
}
html|*#fullscreen-warning.verifiedIdentity::before,
html|*#fullscreen-warning.verifiedDomain::before {
html|*.pointerlockfswarning[data-identity="verifiedIdentity"]::before,
html|*.pointerlockfswarning[data-identity="verifiedDomain"]::before {
content: url("chrome://browser/skin/fullscreen/secure.svg");
}
html|*#fullscreen-warning.unknownIdentity::before {
html|*.pointerlockfswarning[data-identity="unknownIdentity"]::before {
content: url("chrome://browser/skin/fullscreen/insecure.svg");
}
html|*#fullscreen-domain-text,
html|*#fullscreen-generic-text {
html|*.pointerlockfswarning-domain-text,
html|*.pointerlockfswarning-generic-text {
font-size: 21px;
font-weight: lighter;
color: #fafafa;
margin: 0 16px;
}
html|*#fullscreen-domain {
html|*.pointerlockfswarning-domain {
font-weight: bold;
margin: 0;
}
html|*#fullscreen-exit-button {
html|*.pointerlockfswarning-exit-button {
padding: 5px 30px;
font: message-box;
font-size: 14px;
font-weight: lighter;
margin: 0;
box-sizing: content-box;
}
}

View File

@ -57,7 +57,6 @@
skin/classic/browser/filters.svg (../shared/filters.svg)
skin/classic/browser/fullscreen/insecure.svg (../shared/fullscreen/insecure.svg)
skin/classic/browser/fullscreen/secure.svg (../shared/fullscreen/secure.svg)
skin/classic/browser/glyphs.svg (../shared/glyphs.svg)
skin/classic/browser/heartbeat-icon.svg (../shared/heartbeat-icon.svg)
skin/classic/browser/heartbeat-star-lit.svg (../shared/heartbeat-star-lit.svg)
skin/classic/browser/heartbeat-star-off.svg (../shared/heartbeat-star-off.svg)
@ -67,6 +66,7 @@
skin/classic/browser/identity-mixed-passive-loaded.svg (../shared/identity-block/identity-mixed-passive-loaded.svg)
skin/classic/browser/identity-mixed-active-loaded.svg (../shared/identity-block/identity-mixed-active-loaded.svg)
skin/classic/browser/info.svg (../shared/info.svg)
skin/classic/browser/permissions.svg (../shared/permissions.svg)
skin/classic/browser/tracking-protection-16.svg (../shared/identity-block/tracking-protection-16.svg)
skin/classic/browser/tracking-protection-disabled-16.svg (../shared/identity-block/tracking-protection-disabled-16.svg)
skin/classic/browser/newtab/close.png (../shared/newtab/close.png)

View File

@ -81,58 +81,58 @@
.popup-notification-icon[popupid="web-notifications"],
.desktop-notification-icon {
list-style-image: url(chrome://browser/skin/glyphs.svg#desktop-notification);
list-style-image: url(chrome://browser/skin/permissions.svg#desktop-notification);
}
.desktop-notification-icon.blocked {
list-style-image: url(chrome://browser/skin/glyphs.svg#desktop-notification-blocked);
list-style-image: url(chrome://browser/skin/permissions.svg#desktop-notification-blocked);
}
.geo-icon {
%ifdef XP_MACOSX
list-style-image: url(chrome://browser/skin/glyphs.svg#geo-osx);
list-style-image: url(chrome://browser/skin/permissions.svg#geo-osx);
%elif defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_QT)
list-style-image: url(chrome://browser/skin/glyphs.svg#geo-linux);
list-style-image: url(chrome://browser/skin/permissions.svg#geo-linux);
%else
list-style-image: url(chrome://browser/skin/glyphs.svg#geo-windows);
list-style-image: url(chrome://browser/skin/permissions.svg#geo-windows);
%endif
}
.geo-icon.blocked {
%ifdef XP_MACOSX
list-style-image: url(chrome://browser/skin/glyphs.svg#geo-osx-blocked);
list-style-image: url(chrome://browser/skin/permissions.svg#geo-osx-blocked);
%elif defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_QT)
list-style-image: url(chrome://browser/skin/glyphs.svg#geo-linux-blocked);
list-style-image: url(chrome://browser/skin/permissions.svg#geo-linux-blocked);
%else
list-style-image: url(chrome://browser/skin/glyphs.svg#geo-windows-blocked);
list-style-image: url(chrome://browser/skin/permissions.svg#geo-windows-blocked);
%endif
}
.popup-notification-icon[popupid="geolocation"] {
%ifdef XP_MACOSX
list-style-image: url(chrome://browser/skin/glyphs.svg#geo-osx);
list-style-image: url(chrome://browser/skin/permissions.svg#geo-osx);
%elif defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_QT)
list-style-image: url(chrome://browser/skin/glyphs.svg#geo-linux-detailed);
list-style-image: url(chrome://browser/skin/permissions.svg#geo-linux-detailed);
%else
list-style-image: url(chrome://browser/skin/glyphs.svg#geo-windows-detailed);
list-style-image: url(chrome://browser/skin/permissions.svg#geo-windows-detailed);
%endif
}
.popup-notification-icon[popupid="indexedDB-permissions-prompt"],
.indexedDB-icon {
list-style-image: url(chrome://browser/skin/glyphs.svg#indexedDB);
list-style-image: url(chrome://browser/skin/permissions.svg#indexedDB);
}
.indexedDB-icon.blocked {
list-style-image: url(chrome://browser/skin/glyphs.svg#indexedDB-blocked);
list-style-image: url(chrome://browser/skin/permissions.svg#indexedDB-blocked);
}
.login-icon {
list-style-image: url(chrome://browser/skin/glyphs.svg#login);
list-style-image: url(chrome://browser/skin/permissions.svg#login);
}
.popup-notification-icon[popupid="password"] {
list-style-image: url(chrome://browser/skin/glyphs.svg#login-detailed);
list-style-image: url(chrome://browser/skin/permissions.svg#login-detailed);
}
#login-fill-notification-icon {
@ -145,50 +145,50 @@
.camera-icon,
.popup-notification-icon[popupid="webRTC-shareDevices"],
.popup-notification-icon[popupid="webRTC-sharingDevices"] {
list-style-image: url(chrome://browser/skin/glyphs.svg#camera);
list-style-image: url(chrome://browser/skin/permissions.svg#camera);
}
.camera-icon.blocked {
list-style-image: url(chrome://browser/skin/glyphs.svg#camera-blocked);
list-style-image: url(chrome://browser/skin/permissions.svg#camera-blocked);
}
/* The first selector is used by socialchat.xml (bug 1275558). */
.webRTC-sharingMicrophone-notification-icon,
.microphone-icon {
list-style-image: url(chrome://browser/skin/glyphs.svg#microphone);
list-style-image: url(chrome://browser/skin/permissions.svg#microphone);
}
.microphone-icon.blocked {
list-style-image: url(chrome://browser/skin/glyphs.svg#microphone-blocked);
list-style-image: url(chrome://browser/skin/permissions.svg#microphone-blocked);
}
.popup-notification-icon[popupid="webRTC-shareMicrophone"],
.popup-notification-icon[popupid="webRTC-sharingMicrophone"] {
list-style-image: url(chrome://browser/skin/glyphs.svg#microphone-detailed);
list-style-image: url(chrome://browser/skin/permissions.svg#microphone-detailed);
}
.popup-notification-icon[popupid="webRTC-shareScreen"],
.popup-notification-icon[popupid="webRTC-sharingScreen"],
.screen-icon {
list-style-image: url(chrome://browser/skin/glyphs.svg#screen);
list-style-image: url(chrome://browser/skin/permissions.svg#screen);
}
.screen-icon.blocked {
list-style-image: url(chrome://browser/skin/glyphs.svg#screen-blocked);
list-style-image: url(chrome://browser/skin/permissions.svg#screen-blocked);
}
.popup-notification-icon[popupid="pointerLock"],
.pointerLock-icon {
list-style-image: url(chrome://browser/skin/glyphs.svg#pointerLock);
list-style-image: url(chrome://browser/skin/permissions.svg#pointerLock);
}
.pointerLock-icon.blocked {
list-style-image: url(chrome://browser/skin/glyphs.svg#pointerLock-blocked);
list-style-image: url(chrome://browser/skin/permissions.svg#pointerLock-blocked);
}
/* This icon has a block sign in it, so we don't need a blocked version. */
.popup-icon {
list-style-image: url("chrome://browser/skin/glyphs.svg#popup");
list-style-image: url("chrome://browser/skin/permissions.svg#popup");
}
/* EME */

View File

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

@ -114,15 +114,15 @@
}
.tab-sharing-icon-overlay[sharing="camera"] {
list-style-image: url("chrome://browser/skin/glyphs.svg#camera");
list-style-image: url("chrome://browser/skin/permissions.svg#camera");
}
.tab-sharing-icon-overlay[sharing="microphone"] {
list-style-image: url("chrome://browser/skin/glyphs.svg#microphone");
list-style-image: url("chrome://browser/skin/permissions.svg#microphone");
}
.tab-sharing-icon-overlay[sharing="screen"] {
list-style-image: url("chrome://browser/skin/glyphs.svg#screen");
list-style-image: url("chrome://browser/skin/permissions.svg#screen");
}
.tab-sharing-icon-overlay[sharing] {

View File

@ -5,42 +5,6 @@
/******************************************************************************/
/* Search Box */
.searchBox {
height: 18px;
font-size: 12px;
margin-top: 0;
border: 1px solid rgb(170, 188, 207);
width: 200px;
.dom-searchbox {
float: right;
background-image: url("./search.svg");
background-repeat: no-repeat;
background-position: 2px center;
padding-left: 20px;
margin-right: 5px;
}
/******************************************************************************/
/* Light Theme & Dark Theme*/
.theme-dark .searchBox,
.theme-light .searchBox {
border: 1px solid rgb(170, 170, 170);
background-image: url("chrome://devtools/skin/images/magnifying-glass-light.png");
background-position: 8px center;
border-radius: 2px;
padding-left: 25px;
margin-top: 1px;
height: 16px;
font-style: italic;
}
/******************************************************************************/
/* Dark Theme */
.theme-dark .searchBox {
background-color: rgba(24, 29, 32, 1);
color: rgba(184, 200, 217, 1);
border-color: var(--theme-splitter-color);
background-image: url("chrome://devtools/skin/images/magnifying-glass.png");
}
}

View File

@ -53,7 +53,7 @@ var SearchBox = React.createClass({
render: function () {
return (
input({
className: "searchBox",
className: "dom-searchbox devtools-filterinput",
placeholder: l10n.getStr("dom.filterDOMPanel"),
onChange: this.onSearch
})

View File

@ -104,6 +104,15 @@ Menu.prototype._createMenuItems = function (parent) {
let menu = doc.createElement("menu");
menu.appendChild(menupopup);
menu.setAttribute("label", item.label);
if (item.disabled) {
menu.setAttribute("disabled", "true");
}
if (item.accesskey) {
menu.setAttribute("accesskey", item.accesskey);
}
if (item.id) {
menu.id = item.id;
}
parent.appendChild(menu);
} else if (item.type === "separator") {
let menusep = doc.createElement("menuseparator");

View File

@ -130,6 +130,13 @@ function* testSubmenu(toolbox) {
label: "Submenu parent",
submenu: submenu,
}));
menu.append(new MenuItem({
label: "Submenu parent with attributes",
id: "submenu-parent-with-attrs",
submenu: submenu,
accesskey: "A",
disabled: true,
}));
menu.popup(0, 0, toolbox);
ok(toolbox.doc.querySelector("#menu-popup"), "A popup is in the DOM");
@ -137,8 +144,13 @@ function* testSubmenu(toolbox) {
"No menuitem children");
let menus = toolbox.doc.querySelectorAll("#menu-popup > menu");
is(menus.length, 1, "Correct number of menus");
is(menus.length, 2, "Correct number of menus");
is(menus[0].getAttribute("label"), "Submenu parent", "Correct label");
ok(!menus[0].hasAttribute("disabled"), "Correct disabled state");
is(menus[1].getAttribute("accesskey"), "A", "Correct accesskey");
ok(menus[1].hasAttribute("disabled"), "Correct disabled state");
ok(menus[1].id, "submenu-parent-with-attrs", "Correct id");
let subMenuItems = menus[0].querySelectorAll("menupopup > menuitem");
is(subMenuItems.length, 1, "Correct number of submenu items");

View File

@ -69,7 +69,7 @@ InspectorSearch.prototype = {
this._lastSearched = query;
if (query.length === 0) {
this.searchBox.classList.remove("devtools-no-search-result");
this.searchBox.classList.remove("devtools-style-searchbox-no-match");
if (!lastSearched || lastSearched.length > 0) {
this.emit("search-cleared");
}
@ -85,12 +85,12 @@ InspectorSearch.prototype = {
if (res) {
this.inspector.selection.setNodeFront(res.node, "inspectorsearch");
this.searchBox.classList.remove("devtools-no-search-result");
this.searchBox.classList.remove("devtools-style-searchbox-no-match");
res.query = query;
this.emit("search-result", res);
} else {
this.searchBox.classList.add("devtools-no-search-result");
this.searchBox.classList.add("devtools-style-searchbox-no-match");
this.emit("search-result");
}
}),

View File

@ -72,7 +72,7 @@
<html:div id="ruleview-toolbar">
<html:div class="devtools-searchbox">
<html:input id="ruleview-searchbox"
class="devtools-searchinput devtools-rule-searchbox"
class="devtools-filterinput devtools-rule-searchbox"
type="search"
placeholder="&filterStylesPlaceholder;"/>
<html:button id="ruleview-searchinput-clear" class="devtools-searchinput-clear"></html:button>
@ -97,7 +97,7 @@
<html:div class="devtools-toolbar">
<html:div class="devtools-searchbox">
<html:input id="computedview-searchbox"
class="devtools-searchinput devtools-rule-searchbox"
class="devtools-filterinput devtools-rule-searchbox"
type="search"
placeholder="&filterStylesPlaceholder;"/>
<html:button id="computedview-searchinput-clear" class="devtools-searchinput-clear"></html:button>

View File

@ -88,7 +88,7 @@ add_task(function* () {
is(inspector.selection.nodeFront, nodeFront,
"Correct node is selected for state " + index);
is(!searchBox.classList.contains("devtools-no-search-result"), isValid,
is(!searchBox.classList.contains("devtools-style-searchbox-no-match"), isValid,
"Correct searchbox result state for state " + index);
index++;

View File

@ -75,7 +75,7 @@ function* synthesizeKeys(keys, inspector) {
}
function assertHasResult(inspector, expectResult) {
is(inspector.searchBox.classList.contains("devtools-no-search-result"),
is(inspector.searchBox.classList.contains("devtools-style-searchbox-no-match"),
!expectResult,
"There are" + (expectResult ? "" : " no") + " search results");
}

View File

@ -218,6 +218,8 @@ devtools.jar:
skin/images/magnifying-glass@2x.png (themes/images/magnifying-glass@2x.png)
skin/images/magnifying-glass-light.png (themes/images/magnifying-glass-light.png)
skin/images/magnifying-glass-light@2x.png (themes/images/magnifying-glass-light@2x.png)
skin/images/filter.svg (themes/images/filter.svg)
skin/images/search.svg (themes/images/search.svg)
skin/images/itemToggle.png (themes/images/itemToggle.png)
skin/images/itemToggle@2x.png (themes/images/itemToggle@2x.png)
skin/images/itemArrow-dark-rtl.svg (themes/images/itemArrow-dark-rtl.svg)

View File

@ -8,9 +8,8 @@
.toolbar {
line-height: 20px;
font-size: 12px;
height: 22px;
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
font: message-box;
padding: 4px 0 3px 0;
}

View File

@ -109,7 +109,7 @@ module.exports = createClass({
dom.input({
id: "filter",
type: "search",
className: "devtools-searchinput",
className: "devtools-filterinput",
placeholder: L10N.getStr("filter.placeholder"),
title: L10N.getStr("filter.tooltip"),
onChange: event => setFilterString(event.target.value),

View File

@ -160,7 +160,7 @@
class="devtools-toolbarbutton icon-and-text"
tooltiptext="&netmonitorUI.footer.perf;"/>
<textbox id="requests-menu-filter-freetext-text"
class="devtools-searchinput"
class="devtools-filterinput"
type="search"
required="true"
placeholder="&netmonitorUI.footer.filterFreetext.label;"/>

View File

@ -458,7 +458,7 @@ VariablesView.prototype = {
container.hidden = !this._store.length;
let searchbox = this._searchboxNode = document.createElement("textbox");
searchbox.className = "variables-view-searchinput devtools-searchinput";
searchbox.className = "variables-view-searchinput devtools-filterinput";
searchbox.setAttribute("placeholder", this._searchboxPlaceholder);
searchbox.setAttribute("type", "search");
searchbox.setAttribute("flex", "1");

View File

@ -42,7 +42,7 @@
<vbox flex="1">
<hbox id="storage-toolbar" class="devtools-toolbar">
<textbox id="storage-searchbox"
class="devtools-searchinput"
class="devtools-filterinput"
type="search"
timeout="200"
placeholder="&searchBox.placeholder;"/>

View File

@ -374,7 +374,8 @@ div.CodeMirror span.eval-text {
}
.devtools-textinput,
.devtools-searchinput {
.devtools-searchinput,
.devtools-filterinput {
background-color: rgba(24, 29, 32, 1);
color: rgba(184, 200, 217, 1);
}

View File

@ -35,7 +35,7 @@
cursor: pointer;
position: absolute;
bottom: 0;
right: 0;
offset-inline-end: 0;
}
.dim > #font-container,
@ -70,7 +70,6 @@
}
#font-preview-text-input {
font: inherit;
margin-top: 1px;
margin-bottom: 1px;
padding-top: 0;

View File

@ -0,0 +1,7 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="#aaa">
<path fill-opacity="0.3" d="M6.6 8.4c0-.6-1.7.3-1.7-.3C4.9 7.7 2.4 4 2.4 4h11.3s-2.5 3.4-2.5 4.1c0 .3-2.1-.1-2.1.3v5.9H7s-.4-3.9-.4-5.9z"/>
<path d="M2 2v2.3l2.7 4.5h1.6v5.5s1.1.6 1.8.6c.5 0 1.8-.6 1.8-.6V8.8h1.6L14 4.3V2H2zm10.8 2l-2.1 3.6H8.5v5.9c-.1 0-.1.1-.2.1-.2.1-.3.1-.3.1s-.1 0-.2-.1c-.1 0-.2-.1-.3-.1V7.6H5.4L3.2 4v-.8h9.5V4z"/>
</svg>

After

Width:  |  Height:  |  Size: 657 B

View File

@ -0,0 +1,6 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="#aaa">
<path d="M10.716 10.032C11.516 9.077 12 7.845 12 6.5 12 3.462 9.538 1 6.5 1S1 3.462 1 6.5 3.462 12 6.5 12c1.345 0 2.577-.483 3.532-1.284l4.143 4.142c.19.19.495.19.683 0 .19-.188.19-.494 0-.683l-4.142-4.143zM6.5 11C8.985 11 11 8.985 11 6.5S8.985 2 6.5 2 2 4.015 2 6.5 4.015 11 6.5 11z" fill-rule="evenodd"/>
</svg>

After

Width:  |  Height:  |  Size: 624 B

View File

@ -146,7 +146,8 @@ li.linked-file-error .stylesheet-linked-file:after {
margin-inline-end: 2px;
}
.devtools-searchinput {
.devtools-searchinput,
.devtools-filterinput {
max-width: 25ex;
font-size: 11px;
}

View File

@ -11,8 +11,8 @@
--searchbox-border-color: #ffbf00;
--searcbox-no-match-background-color: #ffe5e5;
--searcbox-no-match-border-color: #e52e2e;
--magnifying-glass-image: url(images/magnifying-glass-light.png);
--magnifying-glass-image-2x: url(images/magnifying-glass-light@2x.png);
--magnifying-glass-image: url(images/search.svg);
--filter-image: url(images/filter.svg);
--tool-options-image: url(images/tool-options.svg);
--close-button-image: url(chrome://devtools/skin/images/close.svg);
--icon-filter: invert(1);
@ -42,8 +42,8 @@
--searchbox-border-color: #d99f2b;
--searcbox-no-match-background-color: #402325;
--searcbox-no-match-border-color: #cc3d3d;
--magnifying-glass-image: url(images/magnifying-glass.png);
--magnifying-glass-image-2x: url(images/magnifying-glass@2x.png);
--magnifying-glass-image: url(images/search.svg);
--filter-image: url(images/filter.svg);
--tool-options-image: url(images/tool-options.svg);
--close-button-image: url(chrome://devtools/skin/images/close.svg);
--icon-filter: none;
@ -376,40 +376,59 @@
/* Text input */
.devtools-textinput,
.devtools-searchinput {
.devtools-searchinput,
.devtools-filterinput {
-moz-appearance: none;
margin: 1px 3px;
border: 1px solid;
border-radius: 2px;
padding: 4px 6px;
border-color: var(--theme-splitter-color);
font: message-box;
}
:root[platform="mac"] .devtools-textinput,
:root[platform="mac"] .devtools-searchinput {
:root[platform="mac"] .devtools-searchinput,
:root[platform="mac"] .devtools-filterinput {
border-radius: 20px;
}
.devtools-searchinput {
.devtools-searchinput,
.devtools-filterinput {
padding: 0;
padding-inline-start: 22px;
padding-inline-end: 4px;
background-image: var(--magnifying-glass-image);
background-position: 8px center;
background-size: 11px 11px;
background-repeat: no-repeat;
font-size: inherit;
}
.devtools-searchinput {
background-image: var(--magnifying-glass-image);
}
.devtools-filterinput {
background-image: var(--filter-image);
}
.devtools-searchinput:-moz-locale-dir(rtl),
.devtools-searchinput:dir(rtl) {
.devtools-searchinput:dir(rtl),
.devtools-filterinput:-moz-locale-dir(rtl),
.devtools-filterinput:dir(rtl) {
background-position: calc(100% - 8px) center;
}
.devtools-searchinput > .textbox-input-box > .textbox-search-icons > .textbox-search-icon {
.devtools-searchinput > .textbox-input-box > .textbox-search-icons > .textbox-search-icon,
.devtools-filterinput > .textbox-input-box > .textbox-search-icons > .textbox-search-icon {
visibility: hidden;
}
.devtools-searchinput .textbox-input::-moz-placeholder,
.devtools-filterinput .textbox-input::-moz-placeholder {
font-style: normal;
}
/* Searchbox is a div container element for a search input element */
.devtools-searchbox {
display: flex;
@ -420,13 +439,15 @@
/* The spacing is accomplished with a padding on the searchbox */
.devtools-searchbox > .devtools-textinput,
.devtools-searchbox > .devtools-searchinput {
.devtools-searchbox > .devtools-searchinput,
.devtools-searchbox > .devtools-filterinput {
margin-left: 0;
margin-right: 0;
}
.devtools-searchbox > .devtools-textinput:-moz-focusring,
.devtools-searchbox > .devtools-searchinput:-moz-focusring {
.devtools-searchbox > .devtools-searchinput:-moz-focusring,
.devtools-searchbox > .devtools-filterinput:-moz-focusring {
border-color: var(--theme-focus-border-color-textbox);
box-shadow: var(--theme-focus-box-shadow-textbox);
transition: all 0.2s ease-in-out;
@ -436,11 +457,13 @@
/* Don't add 'double spacing' for inputs that are at beginning / end
of a toolbar (since the toolbar has it's own spacing). */
.devtools-toolbar > .devtools-textinput:first-child,
.devtools-toolbar > .devtools-searchinput:first-child {
.devtools-toolbar > .devtools-searchinput:first-child,
.devtools-toolbar > .devtools-filterinput:first-child {
margin-inline-start: 0;
}
.devtools-toolbar > .devtools-textinput:last-child,
.devtools-toolbar > .devtools-searchinput:last-child {
.devtools-toolbar > .devtools-searchinput:last-child,
.devtools-toolbar > .devtools-filterinput:last-child {
margin-inline-end: 0;
}
.devtools-toolbar > .devtools-searchbox:first-child {
@ -453,7 +476,6 @@
.devtools-rule-searchbox {
-moz-box-flex: 1;
width: 100%;
font: inherit;
}
.devtools-rule-searchbox[filled] {
@ -467,10 +489,6 @@
border-color: var(--searcbox-no-match-border-color) !important;
}
.devtools-no-search-result {
border-color: var(--theme-highlight-red) !important;
}
.devtools-searchinput-clear {
position: absolute;
top: 3.5px;
@ -505,30 +523,28 @@
background-position: -16px 0;
}
.theme-dark .devtools-searchinput > .textbox-input-box > .textbox-search-icons > .textbox-search-clear {
.theme-dark .devtools-searchinput > .textbox-input-box > .textbox-search-icons > .textbox-search-clear,
.theme-dark .devtools-filterinput > .textbox-input-box > .textbox-search-icons > .textbox-search-clear {
list-style-image: url("chrome://devtools/skin/images/search-clear-dark.svg");
-moz-image-region: rect(0, 16px, 16px, 0);
}
.theme-light .devtools-searchinput > .textbox-input-box > .textbox-search-icons > .textbox-search-clear {
.theme-light .devtools-searchinput > .textbox-input-box > .textbox-search-icons > .textbox-search-clear,
.theme-light .devtools-filterinput > .textbox-input-box > .textbox-search-icons > .textbox-search-clear {
list-style-image: url("chrome://devtools/skin/images/search-clear-light.svg");
-moz-image-region: rect(0, 16px, 16px, 0);
}
.devtools-searchinput > .textbox-input-box > .textbox-search-icons > .textbox-search-clear {
.devtools-searchinput > .textbox-input-box > .textbox-search-icons > .textbox-search-clear,
.devtools-filterinput > .textbox-input-box > .textbox-search-icons > .textbox-search-clear {
margin-bottom: 0;
}
.devtools-searchinput > .textbox-input-box > .textbox-search-icons > .textbox-search-clear:hover {
.devtools-searchinput > .textbox-input-box > .textbox-search-icons > .textbox-search-clear:hover,
.devtools-filterinput > .textbox-input-box > .textbox-search-icons > .textbox-search-clear:hover {
-moz-image-region: rect(0, 32px, 16px, 16px);
}
@media (min-resolution: 1.1dppx) {
.devtools-searchinput {
background-image: var(--magnifying-glass-image-2x);
}
}
/* Close button */
#toolbox-close::before {

View File

@ -179,7 +179,7 @@ function goUpdateConsoleCommands() {
<spacer flex="1"/>
<textbox class="compact hud-filter-box devtools-searchinput" type="search"
<textbox class="compact hud-filter-box devtools-filterinput" type="search"
placeholder="&filterOutput.placeholder;" tabindex="2"/>
</toolbar>

View File

@ -2513,10 +2513,6 @@ nsDocShell::GetFullscreenAllowed(bool* aFullscreenAllowed)
// Assume false until we determine otherwise...
*aFullscreenAllowed = false;
// If it is sandboxed, fullscreen is not allowed.
if (mSandboxFlags & SANDBOXED_FULLSCREEN) {
return NS_OK;
}
nsCOMPtr<nsPIDOMWindowOuter> win = GetWindow();
if (!win) {
return NS_OK;
@ -2556,10 +2552,6 @@ nsDocShell::GetFullscreenAllowed(bool* aFullscreenAllowed)
// neither iframe nor embed
return NS_OK;
}
nsIDocument* doc = frameElement->GetUncomposedDoc();
if (!doc || !doc->FullscreenEnabledInternal()) {
return NS_OK;
}
}
// If we have no parent then we're the root docshell; no ancestor of the
@ -3837,13 +3829,6 @@ nsDocShell::IsSandboxedFrom(nsIDocShell* aTargetDocShell)
return true;
}
void
nsDocShell::ApplySandboxAndFullscreenFlags(nsIDocument* aDoc)
{
aDoc->SetSandboxFlags(mSandboxFlags);
aDoc->SetFullscreenEnabled(GetFullscreenAllowed());
}
NS_IMETHODIMP
nsDocShell::GetTreeOwner(nsIDocShellTreeOwner** aTreeOwner)
{
@ -8062,9 +8047,9 @@ nsDocShell::CreateAboutBlankContentViewer(nsIPrincipal* aPrincipal,
blankDoc->SetContainer(this);
// Apply the sandbox and fullscreen enabled flags to the document.
// These are immutable after being set here.
ApplySandboxAndFullscreenFlags(blankDoc);
// Copy our sandbox flags to the document. These are immutable
// after being set here.
blankDoc->SetSandboxFlags(mSandboxFlags);
// create a content viewer for us and the new document
docFactory->CreateInstanceForDocument(

View File

@ -25,7 +25,6 @@ interface nsIChannel;
interface nsIContentViewer;
interface nsIDOMEventTarget;
interface nsIDocShellLoadInfo;
interface nsIDocument;
interface nsIEditor;
interface nsIEditingSession;
interface nsISimpleEnumerator;
@ -901,11 +900,6 @@ interface nsIDocShell : nsIDocShellTreeItem
*/
[noscript,notxpcom,nostdcall] bool isSandboxedFrom(in nsIDocShell aTargetDocShell);
/**
* Apply sandbox flags and fullscreen enabled flag to the given document.
*/
[noscript,notxpcom] void applySandboxAndFullscreenFlags(in nsIDocument aDoc);
/**
* This member variable determines whether a document has Mixed Active Content that
* was initially blocked from loading, but the user has choosen to override the

View File

@ -601,7 +601,6 @@ ImportLoader::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
// We want to inherit the sandbox flags and fullscreen enabled flag
// from the master document.
mDocument->SetSandboxFlags(master->GetSandboxFlags());
mDocument->SetFullscreenEnabled(master->FullscreenEnabledInternal());
// We have to connect the blank document we created with the channel we opened,
// and create its own LoadGroup for it.

View File

@ -1455,7 +1455,6 @@ nsIDocument::nsIDocument()
mFontFaceSetDirty(true),
mGetUserFontSetCalled(false),
mPostedFlushUserFontSet(false),
mFullscreenEnabled(false),
mPartID(0),
mDidFireDOMContentLoaded(true),
mHasScrollLinkedEffect(false),
@ -2594,7 +2593,8 @@ nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(aContainer);
if (docShell) {
docShell->ApplySandboxAndFullscreenFlags(this);
nsresult rv = docShell->GetSandboxFlags(&mSandboxFlags);
NS_ENSURE_SUCCESS(rv, rv);
WarnIfSandboxIneffective(docShell, mSandboxFlags, GetChannel());
}
@ -11802,7 +11802,11 @@ GetFullscreenError(nsIDocument* aDoc, bool aCallerIsChrome)
if (!nsContentUtils::IsFullScreenApiEnabled()) {
return "FullscreenDeniedDisabled";
}
if (!aDoc->FullscreenEnabledInternal()) {
// Ensure that all containing elements are <iframe> and have
// allowfullscreen attribute set.
nsCOMPtr<nsIDocShell> docShell(aDoc->GetDocShell());
if (!docShell || !docShell->GetFullscreenAllowed()) {
return "FullscreenDeniedContainerNotAllowed";
}
return nullptr;
@ -12366,10 +12370,7 @@ public:
return NS_OK;
}
// Handling a request from user input in non-fullscreen mode.
// Do a normal permission check.
nsCOMPtr<nsPIDOMWindowInner> window = doc->GetInnerWindow();
nsContentPermissionUtils::AskPermission(this, window);
Allow(JS::UndefinedHandleValue);
return NS_OK;
}
@ -12492,6 +12493,10 @@ nsPointerLockPermissionRequest::Allow(JS::HandleValue aChoices)
EventStateManager::sPointerLockedDoc,
"aElement and this should support weak references!");
nsContentUtils::DispatchEventOnlyToChrome(
doc, ToSupports(e), NS_LITERAL_STRING("MozDOMPointerLock:Entered"),
/* Bubbles */ true, /* Cancelable */ false, /* DefaultAction */ nullptr);
DispatchPointerLockChange(d);
return NS_OK;
}
@ -12766,6 +12771,12 @@ nsDocument::UnlockPointer(nsIDocument* aDoc)
EventStateManager::sPointerLockedDoc = nullptr;
static_cast<nsDocument*>(pointerLockedDoc.get())->mAllowRelocking = !!aDoc;
gPendingPointerLockRequest = nullptr;
nsContentUtils::DispatchEventOnlyToChrome(
doc, ToSupports(pointerLockedElement),
NS_LITERAL_STRING("MozDOMPointerLock:Exited"),
/* Bubbles */ true, /* Cancelable */ false, /* DefaultAction */ nullptr);
DispatchPointerLockChange(pointerLockedDoc);
}

View File

@ -2593,11 +2593,6 @@ public:
return !!GetFullscreenElement();
}
void ExitFullscreen();
bool FullscreenEnabledInternal() const { return mFullscreenEnabled; }
void SetFullscreenEnabled(bool aEnabled)
{
mFullscreenEnabled = aEnabled;
}
Element* GetMozPointerLockElement();
void MozExitPointerLock()
{
@ -3059,10 +3054,6 @@ protected:
// Do we currently have an event posted to call FlushUserFontSet?
bool mPostedFlushUserFontSet : 1;
// Whether fullscreen is enabled for this document. This corresponds
// to the "fullscreen enabled flag" in the HTML spec.
bool mFullscreenEnabled : 1;
enum Type {
eUnknown, // should never be used
eHTML,

View File

@ -84,34 +84,29 @@ const unsigned long SANDBOXED_AUTOMATIC_FEATURES = 0x100;
// We don't have an explicit representation of this one, apparently?
// const unsigned long SANDBOXED_STORAGE_AREA_URLS = 0x200;
/**
* This flag prevents content from using the requestFullscreen() method.
*/
const unsigned long SANDBOXED_FULLSCREEN = 0x400;
/**
* This flag blocks the document from changing document.domain.
*/
const unsigned long SANDBOXED_DOMAIN = 0x800;
const unsigned long SANDBOXED_DOMAIN = 0x400;
/**
* This flag prevents content from using window.alert(), window.confirm(),
* window.print(), window.prompt() and the beforeunload event from putting up
* dialogs.
*/
const unsigned long SANDBOXED_MODALS = 0x1000;
const unsigned long SANDBOXED_MODALS = 0x800;
/**
* This flag prevents content from escaping the sandbox by ensuring that any
* auxiliary browsing context it creates inherits the content's active
* sandboxing flag set.
*/
const unsigned long SANDBOX_PROPAGATES_TO_AUXILIARY_BROWSING_CONTEXTS = 0x2000;
const unsigned long SANDBOX_PROPAGATES_TO_AUXILIARY_BROWSING_CONTEXTS = 0x1000;
/**
* This flag prevents locking screen orientation.
*/
const unsigned long SANDBOXED_ORIENTATION_LOCK = 0x4000;
const unsigned long SANDBOXED_ORIENTATION_LOCK = 0x2000;
const unsigned long SANDBOX_ALL_FLAGS = 0x7FFF;
const unsigned long SANDBOX_ALL_FLAGS = 0x3FFF;
#endif

View File

@ -204,11 +204,7 @@ HTMLIFrameElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
const nsAttrValue* aValue,
bool aNotify)
{
if ((aName == nsGkAtoms::sandbox ||
// The allowfullscreen attribute affects the sandboxed fullscreen
// flag, thus we should also reapply it if that is changed.
aName == nsGkAtoms::allowfullscreen ||
aName == nsGkAtoms::mozallowfullscreen) &&
if (aName == nsGkAtoms::sandbox &&
aNameSpaceID == kNameSpaceID_None && mFrameLoader) {
// If we have an nsFrameLoader, apply the new sandbox flags.
// Since this is called after the setter, the sandbox flags have
@ -244,15 +240,7 @@ HTMLIFrameElement::GetSandboxFlags()
if (!sandboxAttr) {
return SANDBOXED_NONE;
}
uint32_t out = nsContentUtils::ParseSandboxAttributeToFlags(sandboxAttr);
if (GetParsedAttr(nsGkAtoms::allowfullscreen) ||
GetParsedAttr(nsGkAtoms::mozallowfullscreen)) {
out &= ~SANDBOXED_FULLSCREEN;
}
return out;
return nsContentUtils::ParseSandboxAttributeToFlags(sandboxAttr);
}
JSObject*

View File

@ -43,7 +43,3 @@ support-files =
support-files =
/.well-known/idp-proxy/login.html
/.well-known/idp-proxy/idp.sjs
# Bug 950317: Hack for making a cleanup hook after finishing all WebRTC cases
[../test_zmedia_cleanup.html]

View File

@ -284,5 +284,3 @@ skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g (Bug 1059867)
[test_selftest.html]
# Bug 1227781: Crash with bogus TURN server.
[test_peerConnection_bug1227781.html]
# Bug 950317: Hack for making a cleanup hook after finishing all WebRTC cases
[test_zmedia_cleanup.html]

View File

@ -5,118 +5,16 @@
"use strict";
/**
* Query function for determining if any IP address is available for
* generating SDP.
*
* @return false if required additional network setup.
*/
function isNetworkReady() {
// for gonk platform
if ("nsINetworkInterfaceListService" in SpecialPowers.Ci) {
var listService = SpecialPowers.Cc["@mozilla.org/network/interface-list-service;1"]
.getService(SpecialPowers.Ci.nsINetworkInterfaceListService);
var itfList = listService.getDataInterfaceList(
SpecialPowers.Ci.nsINetworkInterfaceListService.LIST_NOT_INCLUDE_MMS_INTERFACES |
SpecialPowers.Ci.nsINetworkInterfaceListService.LIST_NOT_INCLUDE_SUPL_INTERFACES |
SpecialPowers.Ci.nsINetworkInterfaceListService.LIST_NOT_INCLUDE_IMS_INTERFACES |
SpecialPowers.Ci.nsINetworkInterfaceListService.LIST_NOT_INCLUDE_DUN_INTERFACES |
SpecialPowers.Ci.nsINetworkInterfaceListService.LIST_NOT_INCLUDE_FOTA_INTERFACES);
var num = itfList.getNumberOfInterface();
for (var i = 0; i < num; i++) {
var ips = {};
var prefixLengths = {};
var length = itfList.getInterfaceInfo(i).getAddresses(ips, prefixLengths);
for (var j = 0; j < length; j++) {
var ip = ips.value[j];
// skip IPv6 address until bug 797262 is implemented
if (ip.indexOf(":") < 0) {
info("Network interface is ready with address: " + ip);
return true;
}
}
}
// ip address is not available
info("Network interface is not ready, required additional network setup");
return false;
}
info("Network setup is not required");
return true;
}
/**
* Network setup utils for Gonk
*
* @return {object} providing functions for setup/teardown data connection
*/
function getNetworkUtils() {
var url = SimpleTest.getTestFileURL("NetworkPreparationChromeScript.js");
var script = SpecialPowers.loadChromeScript(url);
var utils = {
/**
* Utility for setting up data connection.
*
* @param aCallback callback after data connection is ready.
*/
prepareNetwork: function() {
return new Promise(resolve => {
script.addMessageListener('network-ready', () => {
info("Network interface is ready");
resolve();
});
info("Setting up network interface");
script.sendAsyncMessage("prepare-network", true);
});
},
/**
* Utility for tearing down data connection.
*
* @param aCallback callback after data connection is closed.
*/
tearDownNetwork: function() {
if (!isNetworkReady()) {
info("No network to tear down");
return Promise.resolve();
}
return new Promise(resolve => {
script.addMessageListener('network-disabled', message => {
info("Network interface torn down");
script.destroy();
resolve();
});
info("Tearing down network interface");
script.sendAsyncMessage("network-cleanup", true);
});
}
};
return utils;
}
/**
* Setup network on Gonk if needed and execute test once network is up
* A stub function for preparing the network if needed
*
*/
function startNetworkAndTest() {
if (isNetworkReady()) {
return Promise.resolve();
}
var utils = getNetworkUtils();
// Trigger network setup to obtain IP address before creating any PeerConnection.
return utils.prepareNetwork();
return Promise.resolve();
}
/**
* A wrapper around SimpleTest.finish() to handle B2G network teardown
* A stub function to shutdown the network if needed
*/
function networkTestFinished() {
var p;
if ("nsINetworkInterfaceListService" in SpecialPowers.Ci) {
var utils = getNetworkUtils();
p = utils.tearDownNetwork();
} else {
p = Promise.resolve();
}
return p.then(() => finish());
return Promise.resolve().then(() => finish());
}

View File

@ -1,28 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="network.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
if ("nsINetworkInterfaceListService" in SpecialPowers.Ci) {
getNetworkUtils().tearDownNetwork()
.then(() =>
ok(true, 'Successfully teared down network interface'),
() =>
ok(true, 'Network interface was in down state already'))
.then(() => SimpleTest.finish());
} else {
ok(true, 'No need to cleanup network interface');
SimpleTest.finish();
}
</script>
</pre>
</body>
</html>

View File

@ -383,7 +383,6 @@ XULDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
mStillWalking = true;
mMayStartLayout = false;
mDocumentLoadGroup = do_GetWeakReference(aLoadGroup);
mFullscreenEnabled = true;
mChannel = aChannel;

View File

@ -1672,8 +1672,31 @@ public abstract class GeckoApp
final JSONArray tabs = new JSONArray();
final JSONObject windowObject = new JSONObject();
SessionParser parser = new SessionParser() {
private boolean selectNextTab;
@Override
public void onTabRead(final SessionTab sessionTab) {
if (sessionTab.isAboutHomeWithoutHistory()) {
// This is a tab pointing to about:home with no history. We won't restore
// this tab. If we end up restoring no tabs then the browser will decide
// whether it needs to open about:home or a different 'homepage'. If we'd
// always restore about:home only tabs then we'd never open the homepage.
// See bug 1261008.
if (sessionTab.isSelected()) {
// Unfortunately this tab is the selected tab. Let's just try to select
// the first tab. If we haven't restored any tabs so far then remember
// to select the next tab that gets restored.
if (!Tabs.getInstance().selectLastTab()) {
selectNextTab = true;
}
}
// Do not restore this tab.
return;
}
JSONObject tabObject = sessionTab.getTabObject();
int flags = Tabs.LOADURL_NEW_TAB;
@ -1682,6 +1705,13 @@ public abstract class GeckoApp
flags |= (tabObject.optBoolean("isPrivate") ? Tabs.LOADURL_PRIVATE : 0);
final Tab tab = Tabs.getInstance().loadUrl(sessionTab.getUrl(), flags);
if (selectNextTab) {
// We did not restore the selected tab previously. Now let's select this tab.
Tabs.getInstance().selectTab(tab.getId());
selectNextTab = false;
}
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {

View File

@ -48,6 +48,14 @@ public abstract class SessionParser {
public JSONObject getTabObject() {
return mTabObject;
}
/**
* Is this tab pointing to about:home and does not contain any other history?
*/
public boolean isAboutHomeWithoutHistory() {
JSONArray entries = mTabObject.optJSONArray("entries");
return entries != null && entries.length() == 1 && AboutPages.isAboutHome(mUrl);
}
};
abstract public void onTabRead(SessionTab tab);

View File

@ -260,6 +260,15 @@ public class Tabs implements GeckoEventListener {
return tab;
}
public synchronized boolean selectLastTab() {
if (mOrder.isEmpty()) {
return false;
}
selectTab(mOrder.get(mOrder.size() - 1).getId());
return true;
}
private int getIndexOf(Tab tab) {
return mOrder.lastIndexOf(tab);
}

View File

@ -52,18 +52,25 @@ ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
ac_add_options --enable-warnings-as-errors
ac_add_options --with-mozilla-api-keyfile=/builds/mozilla-fennec-geoloc-api.key
# MOZ_INSTALL_TRACKING does not guarantee MOZ_UPDATE_CHANNEL will be set so we
# provide a default state. Currently, the default state provides a default
# keyfile because an assertion will be thrown if MOZ_INSTALL_TRACKING is
# specified but a keyfile is not. This assertion can catch if we misconfigure a
# release or beta build and it does not have a valid keyfile.
#
# However, by providing a default keyfile, if we misconfigure beta or release,
# the default keyfile may be used instead and the assertion won't catch the
# error. Therefore, it would be ideal to have MOZ_INSTALL_TRACKING guarantee
# MOZ_UPDATE_CHANNEL was set so we can remove the default case. This may occur
# when release promotion is implemented on Android.
#
# In all cases, we don't upload Adjust pings in automation.
if test "$MOZ_UPDATE_CHANNEL" = "release" ; then
ac_add_options --with-adjust-sdk-keyfile=/builds/adjust-sdk.token
elif test "$MOZ_UPDATE_CHANNEL" = "beta" ; then
ac_add_options --with-adjust-sdk-keyfile=/builds/adjust-sdk-beta.token
else
# (bug 1277553) In Aurora -> Beta simulation builds, no update channel is
# specified, causing an assertion to throw that MOZ_INSTALL_TRACKING is
# specified but the keyfile is not. In this case, we add a default keyfile.
# This has the disadvantage that if our beta/release checks above ever
# fail, we'll come to this default case and the compile-time check to
# specify a valid keyfile will be broken. I don't have any better
# alternatives.
ac_add_options --with-adjust-sdk-keyfile="$topsrcdir/mobile/android/base/adjust-sdk-sandbox.token"
fi
export SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE=/builds/crash-stats-api.token

View File

@ -11,10 +11,36 @@ import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import android.util.Patterns;
import java.util.regex.Pattern;
public class WebURLFinder {
/**
* These regular expressions are taken from Android's Patterns.java.
* We brought them in to standardize URL matching across Android versions, instead of relying
* on Android version-dependent built-ins that can vary across Android versions.
* The original code can be found here:
* http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/android/util/Patterns.java
*
*/
public static final String GOOD_IRI_CHAR = "a-zA-Z0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF";
public static final String GOOD_GTLD_CHAR = "a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF";
public static final String IRI = "[" + GOOD_IRI_CHAR + "]([" + GOOD_IRI_CHAR + "\\-]{0,61}[" + GOOD_IRI_CHAR + "]){0,1}";
public static final String GTLD = "[" + GOOD_GTLD_CHAR + "]{2,63}";
public static final String HOST_NAME = "(" + IRI + "\\.)+" + GTLD;
public static final Pattern IP_ADDRESS = Pattern.compile("((25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(25[0-5]|2[0-4]"
+ "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]"
+ "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}"
+ "|[1-9][0-9]|[0-9]))");
public static final Pattern DOMAIN_NAME = Pattern.compile("(" + HOST_NAME + "|" + IP_ADDRESS + ")");
public static final Pattern WEB_URL = Pattern.compile("((?:(http|https|Http|Https|rtsp|Rtsp):\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)"
+ "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_"
+ "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?"
+ "(?:" + DOMAIN_NAME + ")"
+ "(?:\\:\\d{1,5})?)"
+ "(\\/(?:(?:[" + GOOD_IRI_CHAR + "\\;\\/\\?\\:\\@\\&\\=\\#\\~"
+ "\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])|(?:\\%[a-fA-F0-9]{2}))*)?"
+ "(?:\\b|$)");
public final List<String> candidates;
public WebURLFinder(String string) {
@ -90,7 +116,7 @@ public class WebURLFinder {
}
protected static List<String> candidateWebURLs(String string) {
Matcher matcher = Patterns.WEB_URL.matcher(string);
Matcher matcher = WEB_URL.matcher(string);
List<String> matches = new LinkedList<String>();
while (matcher.find()) {

View File

@ -4674,6 +4674,10 @@ pref("full-screen-api.warning.timeout", 3000);
// delay for the warning box to show when pointer stays on the top, unit: ms
pref("full-screen-api.warning.delay", 500);
// DOM pointerlock API
// time for the warning box stays on the screen before sliding out, unit: ms
pref("pointer-lock-api.warning.timeout", 3000);
// DOM idle observers API
pref("dom.idle-observers-api.enabled", true);

View File

@ -1104,7 +1104,7 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) {
infoObject->GetPort(),
versions.max);
bool usesWeakCipher = false;
bool usesFallbackCipher = false;
SSLChannelInfo channelInfo;
rv = SSL_GetChannelInfo(fd, &channelInfo, sizeof(channelInfo));
MOZ_ASSERT(rv == SECSuccess);
@ -1124,7 +1124,7 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) {
sizeof cipherInfo);
MOZ_ASSERT(rv == SECSuccess);
if (rv == SECSuccess) {
usesWeakCipher = cipherInfo.symCipher == ssl_calg_rc4;
usesFallbackCipher = cipherInfo.keaType == ssl_kea_dh;
// keyExchange null=0, rsa=1, dh=2, fortezza=3, ecdh=4
Telemetry::Accumulate(
@ -1207,20 +1207,19 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) {
status);
uint32_t state;
if (usesWeakCipher || renegotiationUnsafe) {
if (renegotiationUnsafe) {
state = nsIWebProgressListener::STATE_IS_BROKEN;
if (usesWeakCipher) {
state |= nsIWebProgressListener::STATE_USES_WEAK_CRYPTO;
}
} else {
state = nsIWebProgressListener::STATE_IS_SECURE |
nsIWebProgressListener::STATE_SECURE_HIGH;
SSLVersionRange defVersion;
rv = SSL_VersionRangeGetDefault(ssl_variant_stream, &defVersion);
if (rv == SECSuccess && versions.max >= defVersion.max) {
// we know this site no longer requires a weak cipher
ioLayerHelpers.removeInsecureFallbackSite(infoObject->GetHostName(),
infoObject->GetPort());
if (!usesFallbackCipher) {
SSLVersionRange defVersion;
rv = SSL_VersionRangeGetDefault(ssl_variant_stream, &defVersion);
if (rv == SECSuccess && versions.max >= defVersion.max) {
// we know this site no longer requires a fallback cipher
ioLayerHelpers.removeInsecureFallbackSite(infoObject->GetHostName(),
infoObject->GetPort());
}
}
}

View File

@ -224,11 +224,17 @@ add_task(function* () {
// retry manually to simulate the HTTP layer
yield startClient("server: fallback only, client: fallback enabled retry, public",
port, Cr.NS_OK);
// make sure that we remember the TLS intolerance
yield startClient("server: fallback only, client: second try after fallback success, public",
port, Cr.NS_OK);
yield startClient("server: fallback only, client: fallback enabled, private",
port, getXPCOMStatusFromNSS(SSL_ERROR_NO_CYPHER_OVERLAP),
{isPrivate: true, allowReset: true});
yield startClient("server: fallback only, client: fallback enabled retry, private",
port, Cr.NS_OK, {isPrivate: true});
// make sure that we remember the TLS intolerance
yield startClient("server: fallback only, client: second try after fallback success, private",
port, Cr.NS_OK);
});
do_register_cleanup(function() {

View File

@ -158,21 +158,14 @@ class UpdateTestCase(FirefoxTestCase):
return about_window.deck.selected_panel != about_window.deck.no_updates_found
def check_update_applied(self):
self.updates[self.current_update_index]['build_post'] = self.software_update.build_info
"""Check that the update has been applied correctly"""
update = self.updates[self.current_update_index]
update['build_post'] = self.software_update.build_info
about_window = self.browser.open_about_window()
try:
update_available = self.check_for_updates(about_window)
# No further updates should be offered now with the same update type
if update_available:
self.download_update(about_window, wait_for_finish=False)
self.assertNotEqual(self.software_update.active_update.type,
self.updates[self.current_update_index].type)
# Check that the update has been applied correctly
update = self.updates[self.current_update_index]
# The upgraded version should be identical with the version given by
# the update and we shouldn't have run a downgrade
check = self.marionette.execute_script("""
@ -202,6 +195,17 @@ class UpdateTestCase(FirefoxTestCase):
self.assertEqual(update['build_post']['disabled_addons'],
update['build_pre']['disabled_addons'])
# Bug 604364 - We do not support watershed releases yet.
if update_available:
self.download_update(about_window, wait_for_finish=False)
self.assertNotEqual(self.software_update.active_update.type,
update['patch']['type'],
'No further update of the same type gets offered: '
'{0} != {1}'.format(
self.software_update.active_update.type,
update['patch']['type']
))
update['success'] = True
finally:

View File

@ -10,9 +10,8 @@
<div id="log"></div>
<script>
function test_allowfullscreen(t, setup_iframe) {
async_test(function(t) {
var iframe = document.createElement("iframe");
setup_iframe(iframe);
iframe.src = "support/blank.htm";
var eventWatcher = new EventWatcher(t, iframe, "load");
document.body.appendChild(iframe);
@ -21,74 +20,15 @@
});
assert_true(document.fullscreenEnabled, "Top level document has fullscreen enabled flag set");
eventWatcher.wait_for("load").then(t.step_func(function() {
eventWatcher.wait_for("load").then(t.step_func_done(function() {
assert_false(iframe.contentDocument.fullscreenEnabled, "Document inside iframe without allowfullscreen attribute should not have fullscreen enabled flag set");
iframe.setAttribute("allowfullscreen", true);
assert_false(iframe.contentDocument.fullscreenEnabled, "Setting allowfullscreen attribute after document load should not affect fullscreen enabled flag");
iframe.contentWindow.location.reload();
return eventWatcher.wait_for("load");
})).then(t.step_func(function() {
assert_true(iframe.contentDocument.fullscreenEnabled, "Fullscreen enabled flag should be set when a new document is loaded with allowfullscreen attribute present");
assert_true(iframe.contentDocument.fullscreenEnabled, "Fullscreen should be allowed when allowfullscreen attribute is set");
iframe.removeAttribute("allowfullscreen");
assert_true(iframe.contentDocument.fullscreenEnabled, "Removing allowfullscreen attribute should not affect fullscreen enabled flag");
iframe.contentWindow.location.reload();
return eventWatcher.wait_for("load");
})).then(t.step_func_done(function() {
assert_false(iframe.contentDocument.fullscreenEnabled, "Fullscreen enabled flag should be reset when a new document is loaded with allowfullscreen attribute absent");
assert_false(iframe.contentDocument.fullscreenEnabled, "Fullscreen should be denied when allowfullscreen attribute is removed");
}));
}
async_test(function(t) {
test_allowfullscreen(t, function(iframe) {});
}, "iframe-allowfullscreen");
async_test(function(t) {
test_allowfullscreen(t, function(iframe) {
iframe.setAttribute("sandbox", "allow-same-origin");
});
}, "iframe-sandbox-allowfullscreen");
/* Fullscreen enabled flag with dialog */
function test_allowfullscreen_dialog(t, setup_iframe, check) {
var iframe = document.createElement("iframe");
setup_iframe(iframe);
iframe.src = "support/blank.htm";
var eventWatcher = new EventWatcher(t, iframe, "load");
document.body.appendChild(iframe);
t.add_cleanup(function() {
document.body.removeChild(iframe);
});
var newWin;
assert_true(document.fullscreenEnabled, "Top level document has fullscreen enabled flag set");
eventWatcher.wait_for("load").then(t.step_func(function() {
assert_false(iframe.contentDocument.fullscreenEnabled, "Document inside iframe without allowfullscreen attribute should not have fullscreen enabled flag set");
newWin = iframe.contentWindow.open("support/blank.htm");
t.add_cleanup(function() {
newWin.close();
});
var newWinEventWatcher = new EventWatcher(t, newWin, "load");
return newWinEventWatcher.wait_for("load");
})).then(t.step_func_done(function() {
check(newWin);
}));
}
async_test(function(t) {
test_allowfullscreen_dialog(t, function() {}, function(newWin) {
assert_true(newWin.document.fullscreenEnabled, "Document in the new window is a top level document, thus should has fullscreen enabled flag set");
});
}, "iframe-allowfullscreen-dialog");
async_test(function(t) {
test_allowfullscreen_dialog(t, function(iframe) {
iframe.setAttribute("sandbox", "allow-same-origin allow-popups");
}, function(newWin) {
assert_false(newWin.document.fullscreenEnabled, "Document in the new window should inherit the sandboxed fullscreen flag and should not have fullscreen enabled flag set");
});
}, "iframe-sandbox-allowfullscreen-dialog");
/* Fullscreen enabled flag with about:blank */
function test_allowfullscreen_noload(setup_iframe, check) {

View File

@ -84,11 +84,12 @@ this.HostManifestManager = {
},
_winLookup(application, context) {
let regPath = `${REGPATH}\\${application}`;
let path = WindowsRegistry.readRegKey(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER,
REGPATH, application);
regPath, "");
if (!path) {
path = WindowsRegistry.readRegKey(Ci.nsIWindowsRegKey.ROOT_KEY_LOCAL_MACHINE,
REGPATH, application);
regPath, "");
}
if (!path) {
return null;

View File

@ -234,7 +234,7 @@ add_task(function* setup() {
yield OS.File.writeAtomic(manifestPath, JSON.stringify(manifest));
registry.setValue(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER,
REGKEY, script.name, manifestPath);
`${REGKEY}\\${script.name}`, "", manifestPath);
// Create a version of the manifest with a relative path
let relativeName = `relative.${script.name}`;
@ -245,7 +245,7 @@ add_task(function* setup() {
yield OS.File.writeAtomic(manifestPath, JSON.stringify(manifest));
registry.setValue(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER,
REGKEY, relativeName, manifestPath);
`${REGKEY}\\${relativeName}`, "", manifestPath);
}
break;

View File

@ -19,7 +19,7 @@ if (AppConstants.platform == "win") {
});
}
const REGKEY = "Software\\Mozilla\\NativeMessagingHosts";
const REGPATH = "Software\\Mozilla\\NativeMessagingHosts";
const BASE_SCHEMA = "chrome://extensions/content/schemas/manifest.json";
@ -102,7 +102,7 @@ add_task(function* test_good_manifest() {
yield writeManifest(USER_TEST_JSON, templateManifest);
if (registry) {
registry.setValue(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER,
REGKEY, "test", USER_TEST_JSON);
`${REGPATH}\\test`, "", USER_TEST_JSON);
}
let result = yield HostManifestManager.lookupApplication("test", context);
@ -177,9 +177,9 @@ add_task(function* good_manifest_system_dir() {
yield writeManifest(GLOBAL_TEST_JSON, globalManifest);
if (registry) {
registry.setValue(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER,
REGKEY, "test", null);
`${REGPATH}\\test`, "", null);
registry.setValue(Ci.nsIWindowsRegKey.ROOT_KEY_LOCAL_MACHINE,
REGKEY, "test", GLOBAL_TEST_JSON);
`${REGPATH}\\test`, "", GLOBAL_TEST_JSON);
}
let where = (AppConstants.platform == "win") ? "registry location" : "directory";
@ -193,7 +193,7 @@ add_task(function* test_user_dir_precedence() {
yield writeManifest(USER_TEST_JSON, templateManifest);
if (registry) {
registry.setValue(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER,
REGKEY, "test", USER_TEST_JSON);
`${REGPATH}\\test`, "", USER_TEST_JSON);
}
// global test.json and LOCAL_MACHINE registry key on windows are
// still present from the previous test
@ -247,7 +247,7 @@ while True:
yield writeManifest(manifestPath, manifest);
registry.setValue(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER,
REGKEY, "wontdie", manifestPath);
`${REGPATH}\\wontdie`, "", manifestPath);
} else {
yield OS.File.writeAtomic(scriptPath, `#!${PYTHON} -u\n${SCRIPT}`);
yield OS.File.setPermissions(scriptPath, {unixMode: 0o755});

View File

@ -285,9 +285,14 @@ this.SafeBrowsing = {
for (let i = 0; i < trackingProtectionLists.length; ++i) {
if (this.trackingEnabled) {
listManager.enableUpdate(trackingProtectionLists[i]);
listManager.enableUpdate(trackingProtectionWhitelists[i]);
} else {
listManager.disableUpdate(trackingProtectionLists[i]);
}
}
for (let i = 0; i < trackingProtectionWhitelists.length; ++i) {
if (this.trackingEnabled) {
listManager.enableUpdate(trackingProtectionWhitelists[i]);
} else {
listManager.disableUpdate(trackingProtectionWhitelists[i]);
}
}

View File

@ -1,6 +1,52 @@
[DEFAULT]
support-files =
addons/*
addon_about.xul
addon_prefs.xul
cancelCompatCheck.sjs
discovery.html
discovery_frame.html
discovery_install.html
head.js
signed_hotfix.rdf
signed_hotfix.xpi
unsigned_hotfix.rdf
unsigned_hotfix.xpi
more_options.xul
options.xul
plugin_test.html
redirect.sjs
releaseNotes.xhtml
blockNoPlugins.xml
blockPluginHard.xml
browser_bug557956.rdf
browser_bug557956_8_2.xpi
browser_bug557956_9_2.xpi
browser_bug557956.xml
browser_bug591465.xml
browser_bug593535.xml
browser_searching.xml
browser_searching_empty.xml
browser_updatessl.rdf
browser_updatessl.rdf^headers^
browser_install.rdf
browser_install.rdf^headers^
browser_install.xml
browser_install1_3.xpi
browser_eula.xml
browser_purchase.xml
webapi_addon_listener.html
webapi_checkavailable.html
webapi_checkchromeframe.xul
webapi_checkframed.html
webapi_checknavigatedwindow.html
!/toolkit/mozapps/extensions/test/xpinstall/corrupt.xpi
!/toolkit/mozapps/extensions/test/xpinstall/incompatible.xpi
!/toolkit/mozapps/extensions/test/xpinstall/installtrigger.html
!/toolkit/mozapps/extensions/test/xpinstall/restartless.xpi
!/toolkit/mozapps/extensions/test/xpinstall/theme.xpi
!/toolkit/mozapps/extensions/test/xpinstall/unsigned.xpi
!/toolkit/mozapps/extensions/test/xpinstall/amosigned.xpi
[browser_about.js]
skip-if = os == 'linux' || os == 'win' # bug 632290

View File

@ -1,54 +1,6 @@
[DEFAULT]
skip-if = buildapp == 'mulet'
tags = addons
support-files =
addons/*
addon_about.xul
addon_prefs.xul
cancelCompatCheck.sjs
discovery.html
discovery_frame.html
discovery_install.html
head.js
signed_hotfix.rdf
signed_hotfix.xpi
unsigned_hotfix.rdf
unsigned_hotfix.xpi
more_options.xul
options.xul
plugin_test.html
redirect.sjs
releaseNotes.xhtml
blockNoPlugins.xml
blockPluginHard.xml
browser_bug557956.rdf
browser_bug557956_8_2.xpi
browser_bug557956_9_2.xpi
browser_bug557956.xml
browser_bug591465.xml
browser_bug593535.xml
browser_searching.xml
browser_searching_empty.xml
browser_updatessl.rdf
browser_updatessl.rdf^headers^
browser_install.rdf
browser_install.rdf^headers^
browser_install.xml
browser_install1_3.xpi
browser_eula.xml
browser_purchase.xml
webapi_addon_listener.html
webapi_checkavailable.html
webapi_checkchromeframe.xul
webapi_checkframed.html
webapi_checknavigatedwindow.html
!/toolkit/mozapps/extensions/test/xpinstall/corrupt.xpi
!/toolkit/mozapps/extensions/test/xpinstall/incompatible.xpi
!/toolkit/mozapps/extensions/test/xpinstall/installtrigger.html
!/toolkit/mozapps/extensions/test/xpinstall/restartless.xpi
!/toolkit/mozapps/extensions/test/xpinstall/theme.xpi
!/toolkit/mozapps/extensions/test/xpinstall/unsigned.xpi
!/toolkit/mozapps/extensions/test/xpinstall/amosigned.xpi
[browser_addonrepository_performance.js]
[browser_bug557956.js]

View File

@ -21,15 +21,6 @@ from mozbuild.base import MachCommandBase, MozbuildObject
@CommandProvider
class SearchProvider(object):
@Command('mxr', category='misc',
description='Search for something in MXR.')
@CommandArgument('term', nargs='+', help='Term(s) to search for.')
def mxr(self, term):
import webbrowser
term = ' '.join(term)
uri = 'https://mxr.mozilla.org/mozilla-central/search?string=%s' % term
webbrowser.open_new_tab(uri)
@Command('dxr', category='misc',
description='Search for something in DXR.')
@CommandArgument('term', nargs='+', help='Term(s) to search for.')
@ -60,12 +51,12 @@ class SearchProvider(object):
@Command('search', category='misc',
description='Search for something on the Internets. '
'This will open 3 new browser tabs and search for the term on Google, '
'MDN, and MXR.')
'MDN, and DXR.')
@CommandArgument('term', nargs='+', help='Term(s) to search for.')
def search(self, term):
self.google(term)
self.mdn(term)
self.mxr(term)
self.dxr(term)
@CommandProvider