mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Merge m-c to m-i
This commit is contained in:
commit
f69792c77b
@ -1,7 +1,7 @@
|
||||
[DEFAULT]
|
||||
support-files =
|
||||
../../../dom/media/test/bug461281.ogg
|
||||
dumbfile.xpi
|
||||
dumbfile.zip
|
||||
formimage.png
|
||||
letters.gif
|
||||
moz.png
|
||||
|
@ -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
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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");
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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";
|
||||
|
@ -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>
|
||||
|
@ -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"/>
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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 -->
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -245,11 +245,7 @@ var gPermissionObject = {
|
||||
exactHostMatch: true
|
||||
},
|
||||
|
||||
"indexedDB": {},
|
||||
|
||||
"pointerLock": {
|
||||
exactHostMatch: true
|
||||
}
|
||||
"indexedDB": {}
|
||||
};
|
||||
|
||||
const kPermissionIDs = Object.keys(gPermissionObject);
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
@ -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] {
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
@ -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
|
||||
})
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
}
|
||||
}),
|
||||
|
@ -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>
|
||||
|
@ -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++;
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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;"/>
|
||||
|
@ -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");
|
||||
|
@ -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;"/>
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
7
devtools/client/themes/images/filter.svg
Normal file
7
devtools/client/themes/images/filter.svg
Normal 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 |
6
devtools/client/themes/images/search.svg
Normal file
6
devtools/client/themes/images/search.svg
Normal 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 |
@ -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;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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*
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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>
|
@ -383,7 +383,6 @@ XULDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
|
||||
mStillWalking = true;
|
||||
mMayStartLayout = false;
|
||||
mDocumentLoadGroup = do_GetWeakReference(aLoadGroup);
|
||||
mFullscreenEnabled = true;
|
||||
|
||||
mChannel = aChannel;
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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()) {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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:
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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});
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user