mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 11:55:49 +00:00
Merge m-c to inbound. a=merge
This commit is contained in:
commit
45dc96e55f
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="ddf5b92f43ec27c93ad4fea4fd1207da8936b8e7"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="ae3a84acaab80a5b35d5542d63e68462273c8a1b"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -19,7 +19,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="ddf5b92f43ec27c93ad4fea4fd1207da8936b8e7"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="ae3a84acaab80a5b35d5542d63e68462273c8a1b"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="ddf5b92f43ec27c93ad4fea4fd1207da8936b8e7"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="ae3a84acaab80a5b35d5542d63e68462273c8a1b"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="11ad0ea69796915552c9bae148d81fddf9856ddb"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="ddf5b92f43ec27c93ad4fea4fd1207da8936b8e7"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="ae3a84acaab80a5b35d5542d63e68462273c8a1b"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -19,7 +19,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="ddf5b92f43ec27c93ad4fea4fd1207da8936b8e7"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="ae3a84acaab80a5b35d5542d63e68462273c8a1b"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="ddf5b92f43ec27c93ad4fea4fd1207da8936b8e7"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="ae3a84acaab80a5b35d5542d63e68462273c8a1b"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="ddf5b92f43ec27c93ad4fea4fd1207da8936b8e7"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="ae3a84acaab80a5b35d5542d63e68462273c8a1b"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="11ad0ea69796915552c9bae148d81fddf9856ddb"/>
|
||||
|
@ -4,6 +4,6 @@
|
||||
"remote": "",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "8c025d0c8038d8e0c90e294d0501f6c5fb252d59",
|
||||
"revision": "587d98bf26625137015c17d5b937bf06bd055dd0",
|
||||
"repo_path": "integration/gaia-central"
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="ddf5b92f43ec27c93ad4fea4fd1207da8936b8e7"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="ae3a84acaab80a5b35d5542d63e68462273c8a1b"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="ddf5b92f43ec27c93ad4fea4fd1207da8936b8e7"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="ae3a84acaab80a5b35d5542d63e68462273c8a1b"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="ddf5b92f43ec27c93ad4fea4fd1207da8936b8e7"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="ae3a84acaab80a5b35d5542d63e68462273c8a1b"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="11ad0ea69796915552c9bae148d81fddf9856ddb"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="ddf5b92f43ec27c93ad4fea4fd1207da8936b8e7"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="ae3a84acaab80a5b35d5542d63e68462273c8a1b"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -1319,7 +1319,7 @@ pref("devtools.devedition.promo.shown", false);
|
||||
pref("devtools.devedition.promo.url", "https://mozilla.org/firefox/developer");
|
||||
|
||||
// Only potentially show in beta release
|
||||
#ifdef MOZ_UPDATE_CHANNEL == beta
|
||||
#if MOZ_UPDATE_CHANNEL == beta
|
||||
pref("devtools.devedition.promo.enabled", true);
|
||||
#else
|
||||
pref("devtools.devedition.promo.enabled", false);
|
||||
|
@ -50,6 +50,17 @@ let DevEdition = {
|
||||
}
|
||||
},
|
||||
|
||||
_inferBrightness: function() {
|
||||
ToolbarIconColor.inferFromText();
|
||||
// Get an inverted full screen button if the dark theme is applied.
|
||||
if (this.styleSheet &&
|
||||
document.documentElement.getAttribute("devtoolstheme") == "dark") {
|
||||
document.documentElement.setAttribute("brighttitlebarforeground", "true");
|
||||
} else {
|
||||
document.documentElement.removeAttribute("brighttitlebarforeground");
|
||||
}
|
||||
},
|
||||
|
||||
_updateDevtoolsThemeAttribute: function() {
|
||||
// Set an attribute on root element to make it possible
|
||||
// to change colors based on the selected devtools theme.
|
||||
@ -58,7 +69,7 @@ let DevEdition = {
|
||||
devtoolsTheme = "light";
|
||||
}
|
||||
document.documentElement.setAttribute("devtoolstheme", devtoolsTheme);
|
||||
ToolbarIconColor.inferFromText();
|
||||
this._inferBrightness();
|
||||
this._updateStyleSheetFromPrefs();
|
||||
},
|
||||
|
||||
@ -83,7 +94,7 @@ let DevEdition = {
|
||||
if (e.type === "load") {
|
||||
this.styleSheet.removeEventListener("load", this);
|
||||
gBrowser.tabContainer._positionPinnedTabs();
|
||||
ToolbarIconColor.inferFromText();
|
||||
this._inferBrightness();
|
||||
Services.obs.notifyObservers(window, "devedition-theme-state-changed", true);
|
||||
}
|
||||
},
|
||||
@ -102,7 +113,7 @@ let DevEdition = {
|
||||
this.styleSheet.remove();
|
||||
this.styleSheet = null;
|
||||
gBrowser.tabContainer._positionPinnedTabs();
|
||||
ToolbarIconColor.inferFromText();
|
||||
this._inferBrightness();
|
||||
Services.obs.notifyObservers(window, "devedition-theme-state-changed", false);
|
||||
}
|
||||
},
|
||||
|
@ -11,7 +11,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "PanelFrame", "resource:///modules/Panel
|
||||
|
||||
|
||||
(function() {
|
||||
|
||||
LoopUI = {
|
||||
get toolbarButton() {
|
||||
delete this.toolbarButton;
|
||||
@ -84,8 +83,28 @@ XPCOMUtils.defineLazyModuleGetter(this, "PanelFrame", "resource:///modules/Panel
|
||||
state = "active";
|
||||
} else if (MozLoopService.doNotDisturb) {
|
||||
state = "disabled";
|
||||
} else if (MozLoopService.roomsParticipantsCount > 0) {
|
||||
state = "active";
|
||||
}
|
||||
this.toolbarButton.node.setAttribute("state", state);
|
||||
},
|
||||
|
||||
/**
|
||||
* Play a sound in this window IF there's no sound playing yet.
|
||||
*
|
||||
* @param {String} name Name of the sound, like 'ringtone' or 'room-joined'
|
||||
*/
|
||||
playSound: function(name) {
|
||||
if (this.ActiveSound || MozLoopService.doNotDisturb) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.activeSound = new window.Audio();
|
||||
this.activeSound.src = `chrome://browser/content/loop/shared/sounds/${name}.ogg`;
|
||||
this.activeSound.load();
|
||||
this.activeSound.play();
|
||||
|
||||
this.activeSound.addEventListener("ended", () => this.activeSound = undefined, false);
|
||||
},
|
||||
};
|
||||
})();
|
||||
|
@ -87,41 +87,61 @@ addEventListener("blur", function(event) {
|
||||
LoginManagerContent.onUsernameInput(event);
|
||||
});
|
||||
|
||||
if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
|
||||
let handleContentContextMenu = function (event) {
|
||||
let defaultPrevented = event.defaultPrevented;
|
||||
if (!Services.prefs.getBoolPref("dom.event.contextmenu.enabled")) {
|
||||
let plugin = null;
|
||||
try {
|
||||
plugin = event.target.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
} catch (e) {}
|
||||
if (plugin && plugin.displayedType == Ci.nsIObjectLoadingContent.TYPE_PLUGIN) {
|
||||
// Don't open a context menu for plugins.
|
||||
return;
|
||||
}
|
||||
|
||||
defaultPrevented = false;
|
||||
let handleContentContextMenu = function (event) {
|
||||
let defaultPrevented = event.defaultPrevented;
|
||||
if (!Services.prefs.getBoolPref("dom.event.contextmenu.enabled")) {
|
||||
let plugin = null;
|
||||
try {
|
||||
plugin = event.target.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
} catch (e) {}
|
||||
if (plugin && plugin.displayedType == Ci.nsIObjectLoadingContent.TYPE_PLUGIN) {
|
||||
// Don't open a context menu for plugins.
|
||||
return;
|
||||
}
|
||||
|
||||
if (!defaultPrevented) {
|
||||
let editFlags = SpellCheckHelper.isEditable(event.target, content);
|
||||
let spellInfo;
|
||||
if (editFlags &
|
||||
(SpellCheckHelper.EDITABLE | SpellCheckHelper.CONTENTEDITABLE)) {
|
||||
spellInfo =
|
||||
InlineSpellCheckerContent.initContextMenu(event, editFlags, this);
|
||||
}
|
||||
|
||||
sendSyncMessage("contextmenu", { editFlags, spellInfo }, { event });
|
||||
}
|
||||
defaultPrevented = false;
|
||||
}
|
||||
|
||||
Cc["@mozilla.org/eventlistenerservice;1"]
|
||||
.getService(Ci.nsIEventListenerService)
|
||||
.addSystemEventListener(global, "contextmenu", handleContentContextMenu, true);
|
||||
if (defaultPrevented)
|
||||
return;
|
||||
|
||||
let addonInfo = {};
|
||||
let subject = {
|
||||
event: event,
|
||||
addonInfo: addonInfo,
|
||||
};
|
||||
subject.wrappedJSObject = subject;
|
||||
Services.obs.notifyObservers(subject, "content-contextmenu", null);
|
||||
|
||||
if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
|
||||
let editFlags = SpellCheckHelper.isEditable(event.target, content);
|
||||
let spellInfo;
|
||||
if (editFlags &
|
||||
(SpellCheckHelper.EDITABLE | SpellCheckHelper.CONTENTEDITABLE)) {
|
||||
spellInfo =
|
||||
InlineSpellCheckerContent.initContextMenu(event, editFlags, this);
|
||||
}
|
||||
|
||||
sendSyncMessage("contextmenu", { editFlags, spellInfo, addonInfo }, { event, popupNode: event.target });
|
||||
}
|
||||
else {
|
||||
// Break out to the parent window and pass the add-on info along
|
||||
let browser = docShell.chromeEventHandler;
|
||||
let mainWin = browser.ownerDocument.defaultView;
|
||||
mainWin.gContextMenuContentData = {
|
||||
isRemote: false,
|
||||
event: event,
|
||||
popupNode: event.target,
|
||||
browser: browser,
|
||||
addonInfo: addonInfo,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Cc["@mozilla.org/eventlistenerservice;1"]
|
||||
.getService(Ci.nsIEventListenerService)
|
||||
.addSystemEventListener(global, "contextmenu", handleContentContextMenu, false);
|
||||
|
||||
let AboutNetErrorListener = {
|
||||
init: function(chromeGlobal) {
|
||||
chromeGlobal.addEventListener('AboutNetErrorLoad', this, false, true);
|
||||
|
@ -528,17 +528,16 @@ nsContextMenu.prototype = {
|
||||
|
||||
// Set various context menu attributes based on the state of the world.
|
||||
setTarget: function (aNode, aRangeParent, aRangeOffset) {
|
||||
// If gContextMenuContentData is not null, this event was forwarded from a
|
||||
// child process, so use that information instead.
|
||||
// gContextMenuContentData.isRemote tells us if the event came from a remote
|
||||
// process. gContextMenuContentData can be null if something (like tests)
|
||||
// opens the context menu directly.
|
||||
let editFlags;
|
||||
if (gContextMenuContentData) {
|
||||
this.isRemote = true;
|
||||
this.isRemote = gContextMenuContentData && gContextMenuContentData.isRemote;
|
||||
if (this.isRemote) {
|
||||
aNode = gContextMenuContentData.event.target;
|
||||
aRangeParent = gContextMenuContentData.event.rangeParent;
|
||||
aRangeOffset = gContextMenuContentData.event.rangeOffset;
|
||||
editFlags = gContextMenuContentData.editFlags;
|
||||
} else {
|
||||
this.isRemote = false;
|
||||
}
|
||||
|
||||
const xulNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
@ -647,7 +646,7 @@ nsContextMenu.prototype = {
|
||||
this.onTextInput = (editFlags & SpellCheckHelper.TEXTINPUT) !== 0;
|
||||
this.onEditableArea = (editFlags & SpellCheckHelper.EDITABLE) !== 0;
|
||||
if (this.onEditableArea) {
|
||||
if (gContextMenuContentData) {
|
||||
if (this.isRemote) {
|
||||
InlineSpellCheckerUI.initFromRemote(gContextMenuContentData.spellInfo);
|
||||
}
|
||||
else {
|
||||
@ -772,7 +771,7 @@ nsContextMenu.prototype = {
|
||||
this.hasBGImage = false;
|
||||
this.isDesignMode = true;
|
||||
this.onEditableArea = true;
|
||||
if (gContextMenuContentData) {
|
||||
if (this.isRemote) {
|
||||
InlineSpellCheckerUI.initFromRemote(gContextMenuContentData.spellInfo);
|
||||
}
|
||||
else {
|
||||
|
@ -3082,10 +3082,13 @@
|
||||
let spellInfo = aMessage.data.spellInfo;
|
||||
if (spellInfo)
|
||||
spellInfo.target = aMessage.target.messageManager;
|
||||
gContextMenuContentData = { event: aMessage.objects.event,
|
||||
gContextMenuContentData = { isRemote: true,
|
||||
event: aMessage.objects.event,
|
||||
popupNode: aMessage.objects.popupNode,
|
||||
browser: browser,
|
||||
editFlags: aMessage.data.editFlags,
|
||||
spellInfo: spellInfo };
|
||||
spellInfo: spellInfo,
|
||||
addonInfo: aMessage.data.addonInfo };
|
||||
let popup = browser.ownerDocument.getElementById("contentAreaContextMenu");
|
||||
let event = gContextMenuContentData.event;
|
||||
let pos = browser.mapScreenCoordinatesFromContent(event.screenX, event.screenY);
|
||||
|
@ -16,12 +16,7 @@ registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref(PREF_DEVTOOLS_THEME);
|
||||
});
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
startTests();
|
||||
}
|
||||
|
||||
function startTests() {
|
||||
add_task(function* startTests() {
|
||||
Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "dark");
|
||||
|
||||
info ("Setting browser.devedition.theme.enabled to false.");
|
||||
@ -37,40 +32,54 @@ function startTests() {
|
||||
ok (!DevEdition.styleSheet, "The devedition stylesheet has been removed when a lightweight theme is applied.");
|
||||
|
||||
info ("Removing a lightweight theme.");
|
||||
let onAttributeAdded = waitForBrightTitlebarAttribute();
|
||||
Services.prefs.setBoolPref(PREF_LWTHEME, false);
|
||||
ok (DevEdition.styleSheet, "The devedition stylesheet has been added when a lightweight theme is removed.");
|
||||
yield onAttributeAdded;
|
||||
|
||||
is (document.documentElement.getAttribute("brighttitlebarforeground"), "true",
|
||||
"The brighttitlebarforeground attribute is set on the window.");
|
||||
|
||||
info ("Setting browser.devedition.theme.enabled to false.");
|
||||
Services.prefs.setBoolPref(PREF_DEVEDITION_THEME, false);
|
||||
ok (!DevEdition.styleSheet, "The devedition stylesheet has been removed.");
|
||||
|
||||
testDevtoolsTheme();
|
||||
testLightweightThemePreview();
|
||||
finish();
|
||||
}
|
||||
ok (!document.documentElement.hasAttribute("brighttitlebarforeground"),
|
||||
"The brighttitlebarforeground attribute is not set on the window after devedition.theme is false.");
|
||||
});
|
||||
|
||||
function testDevtoolsTheme() {
|
||||
add_task(function* testDevtoolsTheme() {
|
||||
info ("Checking that Australis is shown when the light devtools theme is applied.");
|
||||
|
||||
let onAttributeAdded = waitForBrightTitlebarAttribute();
|
||||
Services.prefs.setBoolPref(PREF_DEVEDITION_THEME, true);
|
||||
ok (DevEdition.styleSheet, "The devedition stylesheet exists.");
|
||||
yield onAttributeAdded;
|
||||
ok (document.documentElement.hasAttribute("brighttitlebarforeground"),
|
||||
"The brighttitlebarforeground attribute is set on the window with dark devtools theme.");
|
||||
|
||||
info ("Checking stylesheet and :root attributes based on devtools theme.");
|
||||
Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "light");
|
||||
is (document.documentElement.getAttribute("devtoolstheme"), "light",
|
||||
"The documentElement has an attribute based on devtools theme.");
|
||||
ok (DevEdition.styleSheet, "The devedition stylesheet is still there with the light devtools theme.");
|
||||
ok (!document.documentElement.hasAttribute("brighttitlebarforeground"),
|
||||
"The brighttitlebarforeground attribute is not set on the window with light devtools theme.");
|
||||
|
||||
Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "dark");
|
||||
is (document.documentElement.getAttribute("devtoolstheme"), "dark",
|
||||
"The documentElement has an attribute based on devtools theme.");
|
||||
ok (DevEdition.styleSheet, "The devedition stylesheet is still there with the dark devtools theme.");
|
||||
is (document.documentElement.getAttribute("brighttitlebarforeground"), "true",
|
||||
"The brighttitlebarforeground attribute is set on the window with dark devtools theme.");
|
||||
|
||||
Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "foobar");
|
||||
is (document.documentElement.getAttribute("devtoolstheme"), "light",
|
||||
"The documentElement has 'light' as a default for the devtoolstheme attribute");
|
||||
ok (DevEdition.styleSheet, "The devedition stylesheet is still there with the foobar devtools theme.");
|
||||
}
|
||||
ok (!document.documentElement.hasAttribute("brighttitlebarforeground"),
|
||||
"The brighttitlebarforeground attribute is not set on the window with light devtools theme.");
|
||||
});
|
||||
|
||||
function dummyLightweightTheme(id) {
|
||||
return {
|
||||
@ -83,7 +92,7 @@ function dummyLightweightTheme(id) {
|
||||
};
|
||||
}
|
||||
|
||||
function testLightweightThemePreview() {
|
||||
add_task(function* testLightweightThemePreview() {
|
||||
let {LightweightThemeManager} = Components.utils.import("resource://gre/modules/LightweightThemeManager.jsm", {});
|
||||
|
||||
info ("Turning the pref on, then previewing lightweight themes");
|
||||
@ -114,4 +123,21 @@ function testLightweightThemePreview() {
|
||||
ok (DevEdition.styleSheet, "The devedition stylesheet is still enabled after the default theme is applied.");
|
||||
LightweightThemeManager.resetPreview();
|
||||
ok (DevEdition.styleSheet, "The devedition stylesheet is still enabled after resetting the preview.");
|
||||
});
|
||||
|
||||
// Use a mutation observer to wait for the brighttitlebarforeground
|
||||
// attribute to change. Using this instead of waiting for the load
|
||||
// event on the DevEdition styleSheet.
|
||||
function waitForBrightTitlebarAttribute() {
|
||||
return new Promise((resolve, reject) => {
|
||||
let mutationObserver = new MutationObserver(function (mutations) {
|
||||
for (let mutation of mutations) {
|
||||
if (mutation.attributeName == "brighttitlebarforeground") {
|
||||
mutationObserver.disconnect();
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
});
|
||||
mutationObserver.observe(document.documentElement, { attributes: true });
|
||||
});
|
||||
}
|
||||
|
@ -56,7 +56,11 @@ const extend = function(target, source) {
|
||||
*/
|
||||
const containsParticipant = function(room, participant) {
|
||||
for (let user of room.participants) {
|
||||
if (user.roomConnectionId == participant.roomConnectionId) {
|
||||
// XXX until a bug 1100318 is implemented and deployed,
|
||||
// we need to check the "id" field here as well - roomConnectionId is the
|
||||
// official value for the interface.
|
||||
if (user.roomConnectionId == participant.roomConnectionId &&
|
||||
user.id == participant.id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -107,13 +111,34 @@ const checkForParticipantsUpdate = function(room, updatedRoom) {
|
||||
* violated. You'll notice this as well in the documentation for each method.
|
||||
*/
|
||||
let LoopRoomsInternal = {
|
||||
/**
|
||||
* @var {Map} rooms Collection of rooms currently in cache.
|
||||
*/
|
||||
rooms: new Map(),
|
||||
|
||||
/**
|
||||
* @var {String} sessionType The type of user session. May be 'FXA' or 'GUEST'.
|
||||
*/
|
||||
get sessionType() {
|
||||
return MozLoopService.userProfile ? LOOP_SESSION_TYPE.FXA :
|
||||
LOOP_SESSION_TYPE.GUEST;
|
||||
},
|
||||
|
||||
/**
|
||||
* @var {Number} participantsCount The total amount of participants currently
|
||||
* inside all rooms.
|
||||
*/
|
||||
get participantsCount() {
|
||||
let count = 0;
|
||||
for (let room of this.rooms.values()) {
|
||||
if (!("participants" in room)) {
|
||||
continue;
|
||||
}
|
||||
count += room.participants.length;
|
||||
}
|
||||
return count;
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch a list of rooms that the currently registered user is a member of.
|
||||
*
|
||||
@ -154,6 +179,10 @@ let LoopRoomsInternal = {
|
||||
if (orig) {
|
||||
checkForParticipantsUpdate(orig, room);
|
||||
}
|
||||
// Remove the `currSize` for posterity.
|
||||
if ("currSize" in room) {
|
||||
delete room.currSize;
|
||||
}
|
||||
this.rooms.set(room.roomToken, room);
|
||||
// When a version is specified, all the data is already provided by this
|
||||
// request.
|
||||
@ -203,11 +232,6 @@ let LoopRoomsInternal = {
|
||||
room.roomToken = roomToken;
|
||||
checkForParticipantsUpdate(room, data);
|
||||
extend(room, data);
|
||||
|
||||
// Remove the `currSize` for posterity.
|
||||
if ("currSize" in room) {
|
||||
delete room.currSize;
|
||||
}
|
||||
this.rooms.set(roomToken, room);
|
||||
|
||||
let eventName = !needsUpdate ? "update" : "add";
|
||||
@ -382,6 +406,10 @@ Object.freeze(LoopRoomsInternal);
|
||||
* See the internal code for the API documentation.
|
||||
*/
|
||||
this.LoopRooms = {
|
||||
get participantsCount() {
|
||||
return LoopRoomsInternal.participantsCount;
|
||||
},
|
||||
|
||||
getAll: function(version, callback) {
|
||||
return LoopRoomsInternal.getAll(version, callback);
|
||||
},
|
||||
|
@ -81,6 +81,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "gDNSService",
|
||||
"@mozilla.org/network/dns-service;1",
|
||||
"nsIDNSService");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "gWM",
|
||||
"@mozilla.org/appshell/window-mediator;1",
|
||||
"nsIWindowMediator");
|
||||
|
||||
// Create a new instance of the ConsoleAPI so we can control the maxLogLevel with a pref.
|
||||
XPCOMUtils.defineLazyGetter(this, "log", () => {
|
||||
let ConsoleAPI = Cu.import("resource://gre/modules/devtools/Console.jsm", {}).ConsoleAPI;
|
||||
@ -965,6 +969,10 @@ this.MozLoopService = {
|
||||
gInitializeTimerFunc = value;
|
||||
},
|
||||
|
||||
get roomsParticipantsCount() {
|
||||
return LoopRooms.participantsCount;
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialized the loop service, and starts registration with the
|
||||
* push and loop servers.
|
||||
@ -995,6 +1003,26 @@ this.MozLoopService = {
|
||||
}
|
||||
}
|
||||
|
||||
// The Loop toolbar button should change icon when the room participant count
|
||||
// changes from 0 to something.
|
||||
const onRoomsChange = () => {
|
||||
MozLoopServiceInternal.notifyStatusChanged();
|
||||
};
|
||||
LoopRooms.on("add", onRoomsChange);
|
||||
LoopRooms.on("update", onRoomsChange);
|
||||
LoopRooms.on("joined", (e, roomToken, participant) => {
|
||||
// Don't alert if we're in the doNotDisturb mode, or the participant
|
||||
// is the owner - the content code deals with the rest of the sounds.
|
||||
if (MozLoopServiceInternal.doNotDisturb || participant.owner) {
|
||||
return;
|
||||
}
|
||||
|
||||
let window = gWM.getMostRecentWindow("navigator:browser");
|
||||
if (window) {
|
||||
window.LoopUI.playSound("room-joined");
|
||||
}
|
||||
});
|
||||
|
||||
// If expiresTime is not in the future and the user hasn't
|
||||
// previously authenticated then skip registration.
|
||||
if (!MozLoopServiceInternal.urlExpiryTimeIsInFuture() &&
|
||||
|
@ -31,13 +31,19 @@ loop.panel = (function(_, mozL10n) {
|
||||
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
buttonsHidden: false,
|
||||
selectedTab: "call"
|
||||
buttonsHidden: false
|
||||
};
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {selectedTab: this.props.selectedTab};
|
||||
// XXX Work around props.selectedTab being undefined initially.
|
||||
// When we don't need to rely on the pref, this can move back to
|
||||
// getDefaultProps (bug 1100258).
|
||||
return {
|
||||
selectedTab: this.props.selectedTab ||
|
||||
(navigator.mozLoop.getLoopBoolPref("rooms.enabled") ?
|
||||
"rooms" : "call")
|
||||
};
|
||||
},
|
||||
|
||||
handleSelectTab: function(event) {
|
||||
@ -678,13 +684,17 @@ loop.panel = (function(_, mozL10n) {
|
||||
}
|
||||
},
|
||||
|
||||
_roomsEnabled: function() {
|
||||
return navigator.mozLoop.getLoopBoolPref("rooms.enabled");
|
||||
},
|
||||
|
||||
_onStatusChanged: function() {
|
||||
var profile = navigator.mozLoop.userProfile;
|
||||
var currUid = this.state.userProfile ? this.state.userProfile.uid : null;
|
||||
var newUid = profile ? profile.uid : null;
|
||||
if (currUid != newUid) {
|
||||
// On profile change (login, logout), switch back to the default tab.
|
||||
this.selectTab("call");
|
||||
this.selectTab(this._roomsEnabled() ? "rooms" : "call");
|
||||
this.setState({userProfile: profile});
|
||||
}
|
||||
this.updateServiceErrors();
|
||||
@ -692,17 +702,28 @@ loop.panel = (function(_, mozL10n) {
|
||||
|
||||
/**
|
||||
* The rooms feature is hidden by default for now. Once it gets mainstream,
|
||||
* this method can be safely removed.
|
||||
* this method can be simplified.
|
||||
*/
|
||||
_renderRoomsTab: function() {
|
||||
if (!navigator.mozLoop.getLoopBoolPref("rooms.enabled")) {
|
||||
return null;
|
||||
_renderRoomsOrCallTab: function() {
|
||||
if (!this._roomsEnabled()) {
|
||||
return (
|
||||
Tab({name: "call"},
|
||||
React.DOM.div({className: "content-area"},
|
||||
CallUrlResult({client: this.props.client,
|
||||
notifications: this.props.notifications,
|
||||
callUrl: this.props.callUrl}),
|
||||
ToSView(null)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
Tab({name: "rooms"},
|
||||
RoomList({dispatcher: this.props.dispatcher,
|
||||
store: this.props.roomStore,
|
||||
userDisplayName: this._getUserDisplayName()})
|
||||
userDisplayName: this._getUserDisplayName()}),
|
||||
ToSView(null)
|
||||
)
|
||||
);
|
||||
},
|
||||
@ -735,21 +756,14 @@ loop.panel = (function(_, mozL10n) {
|
||||
|
||||
render: function() {
|
||||
var NotificationListView = sharedViews.NotificationListView;
|
||||
|
||||
return (
|
||||
React.DOM.div(null,
|
||||
NotificationListView({notifications: this.props.notifications,
|
||||
clearOnDocumentHidden: true}),
|
||||
TabView({ref: "tabView", selectedTab: this.props.selectedTab,
|
||||
buttonsHidden: !this.state.userProfile && !this.props.showTabButtons},
|
||||
Tab({name: "call"},
|
||||
React.DOM.div({className: "content-area"},
|
||||
CallUrlResult({client: this.props.client,
|
||||
notifications: this.props.notifications,
|
||||
callUrl: this.props.callUrl}),
|
||||
ToSView(null)
|
||||
)
|
||||
),
|
||||
this._renderRoomsTab(),
|
||||
this._renderRoomsOrCallTab(),
|
||||
Tab({name: "contacts"},
|
||||
ContactsList({selectTab: this.selectTab,
|
||||
startForm: this.startForm})
|
||||
|
@ -31,13 +31,19 @@ loop.panel = (function(_, mozL10n) {
|
||||
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
buttonsHidden: false,
|
||||
selectedTab: "call"
|
||||
buttonsHidden: false
|
||||
};
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {selectedTab: this.props.selectedTab};
|
||||
// XXX Work around props.selectedTab being undefined initially.
|
||||
// When we don't need to rely on the pref, this can move back to
|
||||
// getDefaultProps (bug 1100258).
|
||||
return {
|
||||
selectedTab: this.props.selectedTab ||
|
||||
(navigator.mozLoop.getLoopBoolPref("rooms.enabled") ?
|
||||
"rooms" : "call")
|
||||
};
|
||||
},
|
||||
|
||||
handleSelectTab: function(event) {
|
||||
@ -678,13 +684,17 @@ loop.panel = (function(_, mozL10n) {
|
||||
}
|
||||
},
|
||||
|
||||
_roomsEnabled: function() {
|
||||
return navigator.mozLoop.getLoopBoolPref("rooms.enabled");
|
||||
},
|
||||
|
||||
_onStatusChanged: function() {
|
||||
var profile = navigator.mozLoop.userProfile;
|
||||
var currUid = this.state.userProfile ? this.state.userProfile.uid : null;
|
||||
var newUid = profile ? profile.uid : null;
|
||||
if (currUid != newUid) {
|
||||
// On profile change (login, logout), switch back to the default tab.
|
||||
this.selectTab("call");
|
||||
this.selectTab(this._roomsEnabled() ? "rooms" : "call");
|
||||
this.setState({userProfile: profile});
|
||||
}
|
||||
this.updateServiceErrors();
|
||||
@ -692,17 +702,28 @@ loop.panel = (function(_, mozL10n) {
|
||||
|
||||
/**
|
||||
* The rooms feature is hidden by default for now. Once it gets mainstream,
|
||||
* this method can be safely removed.
|
||||
* this method can be simplified.
|
||||
*/
|
||||
_renderRoomsTab: function() {
|
||||
if (!navigator.mozLoop.getLoopBoolPref("rooms.enabled")) {
|
||||
return null;
|
||||
_renderRoomsOrCallTab: function() {
|
||||
if (!this._roomsEnabled()) {
|
||||
return (
|
||||
<Tab name="call">
|
||||
<div className="content-area">
|
||||
<CallUrlResult client={this.props.client}
|
||||
notifications={this.props.notifications}
|
||||
callUrl={this.props.callUrl} />
|
||||
<ToSView />
|
||||
</div>
|
||||
</Tab>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Tab name="rooms">
|
||||
<RoomList dispatcher={this.props.dispatcher}
|
||||
store={this.props.roomStore}
|
||||
userDisplayName={this._getUserDisplayName()}/>
|
||||
<ToSView />
|
||||
</Tab>
|
||||
);
|
||||
},
|
||||
@ -735,21 +756,14 @@ loop.panel = (function(_, mozL10n) {
|
||||
|
||||
render: function() {
|
||||
var NotificationListView = sharedViews.NotificationListView;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<NotificationListView notifications={this.props.notifications}
|
||||
clearOnDocumentHidden={true} />
|
||||
<TabView ref="tabView" selectedTab={this.props.selectedTab}
|
||||
buttonsHidden={!this.state.userProfile && !this.props.showTabButtons}>
|
||||
<Tab name="call">
|
||||
<div className="content-area">
|
||||
<CallUrlResult client={this.props.client}
|
||||
notifications={this.props.notifications}
|
||||
callUrl={this.props.callUrl} />
|
||||
<ToSView />
|
||||
</div>
|
||||
</Tab>
|
||||
{this._renderRoomsTab()}
|
||||
{this._renderRoomsOrCallTab()}
|
||||
<Tab name="contacts">
|
||||
<ContactsList selectTab={this.selectTab}
|
||||
startForm={this.startForm} />
|
||||
|
@ -140,7 +140,6 @@ body {
|
||||
|
||||
/* Rooms */
|
||||
.rooms {
|
||||
background: #f5f5f5;
|
||||
min-height: 100px;
|
||||
}
|
||||
|
||||
|
@ -154,6 +154,10 @@ loop.shared.mixins = (function() {
|
||||
* @param {String} name The filename to play (excluding the extension).
|
||||
*/
|
||||
play: function(name, options) {
|
||||
if (this._isLoopDesktop() && rootObject.navigator.mozLoop.doNotDisturb) {
|
||||
return;
|
||||
}
|
||||
|
||||
options = options || {};
|
||||
options.loop = options.loop || false;
|
||||
|
||||
|
BIN
browser/components/loop/content/shared/sounds/room-joined.ogg
Normal file
BIN
browser/components/loop/content/shared/sounds/room-joined.ogg
Normal file
Binary file not shown.
@ -86,6 +86,7 @@ browser.jar:
|
||||
content/browser/loop/shared/sounds/connecting.ogg (content/shared/sounds/connecting.ogg)
|
||||
content/browser/loop/shared/sounds/connected.ogg (content/shared/sounds/connected.ogg)
|
||||
content/browser/loop/shared/sounds/terminated.ogg (content/shared/sounds/terminated.ogg)
|
||||
content/browser/loop/shared/sounds/room-joined.ogg (content/shared/sounds/room-joined.ogg)
|
||||
content/browser/loop/shared/sounds/failure.ogg (content/shared/sounds/failure.ogg)
|
||||
|
||||
# Partner SDK assets
|
||||
|
@ -917,6 +917,7 @@ describe("loop.conversation", function() {
|
||||
pause: sinon.spy(),
|
||||
removeAttribute: sinon.spy()
|
||||
};
|
||||
navigator.mozLoop.doNotDisturb = false;
|
||||
sandbox.stub(window, "Audio").returns(fakeAudio);
|
||||
|
||||
view = TestUtils.renderIntoDocument(
|
||||
|
@ -184,7 +184,7 @@ describe("loop.panel", function() {
|
||||
|
||||
view = createTestPanelView();
|
||||
|
||||
[callTab, roomsTab, contactsTab] =
|
||||
[roomsTab, contactsTab] =
|
||||
TestUtils.scryRenderedDOMComponentsWithClass(view, "tab");
|
||||
});
|
||||
|
||||
@ -203,14 +203,6 @@ describe("loop.panel", function() {
|
||||
expect(roomsTab.getDOMNode().classList.contains("selected"))
|
||||
.to.be.true;
|
||||
});
|
||||
|
||||
it("should select call tab when clicking tab button", function() {
|
||||
TestUtils.Simulate.click(
|
||||
view.getDOMNode().querySelector("li[data-tab-name=\"call\"]"));
|
||||
|
||||
expect(callTab.getDOMNode().classList.contains("selected"))
|
||||
.to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
describe("loop.rooms.enabled off", function() {
|
||||
|
@ -8,6 +8,7 @@
|
||||
"use strict";
|
||||
|
||||
Components.utils.import("resource://gre/modules/Promise.jsm", this);
|
||||
const {LoopRoomsInternal} = Components.utils.import("resource:///modules/loop/LoopRooms.jsm", {});
|
||||
|
||||
registerCleanupFunction(function*() {
|
||||
MozLoopService.doNotDisturb = false;
|
||||
@ -79,3 +80,14 @@ add_task(function* test_active() {
|
||||
Assert.strictEqual(LoopUI.toolbarButton.node.getAttribute("state"), "", "Check button is in default state");
|
||||
});
|
||||
|
||||
add_task(function* test_room_participants() {
|
||||
Assert.strictEqual(LoopUI.toolbarButton.node.getAttribute("state"), "", "Check button is in default state");
|
||||
LoopRoomsInternal.rooms.set("test_room", {participants: [{displayName: "hugh", id: "008"}]});
|
||||
MozLoopServiceInternal.notifyStatusChanged();
|
||||
Assert.strictEqual(LoopUI.toolbarButton.node.getAttribute("state"), "active", "Check button is in active state");
|
||||
LoopRoomsInternal.rooms.set("test_room", {participants: []});
|
||||
MozLoopServiceInternal.notifyStatusChanged();
|
||||
Assert.strictEqual(LoopUI.toolbarButton.node.getAttribute("state"), "", "Check button is in default state");
|
||||
LoopRoomsInternal.rooms.delete("test_room");
|
||||
});
|
||||
|
||||
|
@ -166,4 +166,52 @@ describe("loop.shared.mixins", function() {
|
||||
sinon.assert.calledOnce(onDocumentHiddenStub);
|
||||
});
|
||||
});
|
||||
|
||||
describe("loop.shared.mixins.AudioMixin", function() {
|
||||
var view, fakeAudio, TestComp;
|
||||
|
||||
beforeEach(function() {
|
||||
navigator.mozLoop = {
|
||||
doNotDisturb: true,
|
||||
getAudioBlob: sinon.spy(function(name, callback) {
|
||||
callback(null, new Blob([new ArrayBuffer(10)], {type: 'audio/ogg'}));
|
||||
})
|
||||
};
|
||||
|
||||
fakeAudio = {
|
||||
play: sinon.spy(),
|
||||
pause: sinon.spy(),
|
||||
removeAttribute: sinon.spy()
|
||||
};
|
||||
sandbox.stub(window, "Audio").returns(fakeAudio);
|
||||
|
||||
TestComp = React.createClass({
|
||||
mixins: [loop.shared.mixins.AudioMixin],
|
||||
componentDidMount: function() {
|
||||
this.play("failure");
|
||||
},
|
||||
render: function() {
|
||||
return React.DOM.div();
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should not play a failure sound when doNotDisturb true", function() {
|
||||
view = TestUtils.renderIntoDocument(TestComp());
|
||||
sinon.assert.notCalled(navigator.mozLoop.getAudioBlob);
|
||||
sinon.assert.notCalled(fakeAudio.play);
|
||||
});
|
||||
|
||||
it("should play a failure sound, once", function() {
|
||||
navigator.mozLoop.doNotDisturb = false;
|
||||
view = TestUtils.renderIntoDocument(TestComp());
|
||||
sinon.assert.calledOnce(navigator.mozLoop.getAudioBlob);
|
||||
sinon.assert.calledWithExactly(navigator.mozLoop.getAudioBlob,
|
||||
"failure", sinon.match.func);
|
||||
sinon.assert.calledOnce(fakeAudio.play);
|
||||
expect(fakeAudio.loop).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -1529,7 +1529,7 @@ WebGLContext::InitAndValidateGL()
|
||||
|
||||
mMinCapability = Preferences::GetBool("webgl.min_capability_mode", false);
|
||||
mDisableExtensions = Preferences::GetBool("webgl.disable-extensions", false);
|
||||
mLoseContextOnMemoryPressure = Preferences::GetBool("webgl.lose-context-on-memory-preasure", false);
|
||||
mLoseContextOnMemoryPressure = Preferences::GetBool("webgl.lose-context-on-memory-pressure", false);
|
||||
mCanLoseContextInForeground = Preferences::GetBool("webgl.can-lose-context-in-foreground", true);
|
||||
mRestoreWhenVisible = Preferences::GetBool("webgl.restore-context-when-visible", true);
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "nsIAudioManager.h"
|
||||
#include "AudioManager.h"
|
||||
#include "nsDOMClassInfo.h"
|
||||
#include "mozilla/LazyIdleThread.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/dom/FMRadioChild.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
@ -19,6 +20,8 @@
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/SettingChangeNotificationBinding.h"
|
||||
|
||||
#define TUNE_THREAD_TIMEOUT_MS 5000
|
||||
|
||||
#define BAND_87500_108000_kHz 1
|
||||
#define BAND_76000_108000_kHz 2
|
||||
#define BAND_76000_90000_kHz 3
|
||||
@ -161,9 +164,10 @@ public:
|
||||
|
||||
FMRadioService* fmRadioService = FMRadioService::Singleton();
|
||||
if (!fmRadioService->mTuneThread) {
|
||||
// SeekRunnable and SetFrequencyRunnable run on this thread.
|
||||
// These call ioctls that can stall the main thread, so we run them here.
|
||||
NS_NewNamedThread("FM Tuning", getter_AddRefs(fmRadioService->mTuneThread));
|
||||
// SeekRunnable and SetFrequencyRunnable run on this thread. These
|
||||
// call ioctls that can stall the main thread, so we run them here.
|
||||
fmRadioService->mTuneThread = new LazyIdleThread(
|
||||
TUNE_THREAD_TIMEOUT_MS, NS_LITERAL_CSTRING("FM Tuning"));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -3935,8 +3935,25 @@ RilObject.prototype = {
|
||||
/**
|
||||
* Helpers for processing call state changes.
|
||||
*/
|
||||
_processClassifiedCalls: function(removedCalls, remainedCalls, addedCalls,
|
||||
failCause) {
|
||||
_processCalls: function(newCalls, failCause) {
|
||||
// Let's get the failCause first if there are removed calls. Otherwise, we
|
||||
// need to trigger another async request when removing call and it cause
|
||||
// the order of callDisconnected and conferenceCallStateChanged
|
||||
// unpredictable.
|
||||
if (failCause === undefined) {
|
||||
for each (let currentCall in this.currentCalls) {
|
||||
if (!newCalls[currentCall.callIndex] && !currentCall.hangUpLocal) {
|
||||
this.getFailCauseCode((function(newCalls, failCause) {
|
||||
this._processCalls(newCalls, failCause);
|
||||
}).bind(this, newCalls));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let [removedCalls, remainedCalls, addedCalls] =
|
||||
this._classifyCalls(newCalls);
|
||||
|
||||
// Handle removed calls.
|
||||
// Only remove it from the map here. Notify callDisconnected later.
|
||||
for (let call of removedCalls) {
|
||||
@ -4019,22 +4036,6 @@ RilObject.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
_processCalls: function(newCalls) {
|
||||
let [removed, remained, added] = this._classifyCalls(newCalls);
|
||||
|
||||
// Let's get the failCause first if there are removed calls. Otherwise, we
|
||||
// need to trigger another async request when removing call and it cause
|
||||
// the order of callDisconnected and conferenceCallStateChanged
|
||||
// unpredictable.
|
||||
if (removed.length) {
|
||||
this.getFailCauseCode((function(removed, remained, added, failCause) {
|
||||
this._processClassifiedCalls(removed, remained, added, failCause);
|
||||
}).bind(this, removed, remained, added));
|
||||
} else {
|
||||
this._processClassifiedCalls(removed, remained, added);
|
||||
}
|
||||
},
|
||||
|
||||
_detectAudioState: function() {
|
||||
let callNum = Object.keys(this.currentCalls).length;
|
||||
if (!callNum) {
|
||||
@ -5389,10 +5390,6 @@ RilObject.prototype[REQUEST_GET_CURRENT_CALLS] = function REQUEST_GET_CURRENT_CA
|
||||
if (length) {
|
||||
calls_length = Buf.readInt32();
|
||||
}
|
||||
if (!calls_length) {
|
||||
this._processCalls(null);
|
||||
return;
|
||||
}
|
||||
|
||||
let calls = {};
|
||||
for (let i = 0; i < calls_length; i++) {
|
||||
@ -5466,10 +5463,6 @@ RilObject.prototype[REQUEST_HANGUP] = function REQUEST_HANGUP(length, options) {
|
||||
options.success = options.rilRequestError === 0;
|
||||
options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
|
||||
this.sendChromeMessage(options);
|
||||
|
||||
if (options.success) {
|
||||
this.getCurrentCalls();
|
||||
}
|
||||
};
|
||||
RilObject.prototype[REQUEST_HANGUP_WAITING_OR_BACKGROUND] = function REQUEST_HANGUP_WAITING_OR_BACKGROUND(length, options) {
|
||||
RilObject.prototype[REQUEST_HANGUP].call(this, length, options);
|
||||
@ -5478,11 +5471,6 @@ RilObject.prototype[REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND] = function REQU
|
||||
RilObject.prototype[REQUEST_HANGUP].call(this, length, options);
|
||||
};
|
||||
RilObject.prototype[REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE] = function REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE(length, options) {
|
||||
if (options.rilRequestError) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.getCurrentCalls();
|
||||
};
|
||||
RilObject.prototype[REQUEST_CONFERENCE] = function REQUEST_CONFERENCE(length, options) {
|
||||
options.success = (options.rilRequestError === 0);
|
||||
|
@ -72,7 +72,7 @@ add_test(function test_notification() {
|
||||
do_check_eq(postedMessage.callIndex, resultCallIndex);
|
||||
|
||||
// Clear all existed calls.
|
||||
context.RIL._processCalls(null);
|
||||
context.RIL._processCalls({});
|
||||
}
|
||||
|
||||
testNotification(oneCall, SUPP_SVC_NOTIFICATION_CODE2_PUT_ON_HOLD, null,
|
||||
|
@ -12,6 +12,7 @@ import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.TypedValue;
|
||||
import android.view.TouchDelegate;
|
||||
import android.view.View;
|
||||
import android.view.ViewTreeObserver;
|
||||
@ -93,12 +94,21 @@ public class TabsLayoutItemView extends LinearLayout
|
||||
public boolean onPreDraw() {
|
||||
getViewTreeObserver().removeOnPreDrawListener(this);
|
||||
|
||||
final Rect r = new Rect();
|
||||
mCloseButton.getHitRect(r);
|
||||
r.left -= 25;
|
||||
r.bottom += 25;
|
||||
final Rect hitRect = new Rect();
|
||||
mCloseButton.getHitRect(hitRect);
|
||||
|
||||
setTouchDelegate(new TouchDelegate(r, mCloseButton));
|
||||
// Ideally we want the close button hit area to be 40x40dp but we are constrained by the height of the parent, so
|
||||
// we make it as tall as the parent view and 40dp across.
|
||||
final int targetHitArea = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 40, getResources().getDisplayMetrics());;
|
||||
final View parent = ((View) mCloseButton.getParent());
|
||||
|
||||
|
||||
hitRect.top = 0;
|
||||
hitRect.right = getWidth();
|
||||
hitRect.left = getWidth() - targetHitArea;
|
||||
hitRect.bottom = parent.getHeight();
|
||||
|
||||
setTouchDelegate(new TouchDelegate(hitRect, mCloseButton));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -3834,7 +3834,7 @@ pref("webgl.msaa-force", false);
|
||||
pref("webgl.prefer-16bpp", false);
|
||||
pref("webgl.default-no-alpha", false);
|
||||
pref("webgl.force-layers-readback", false);
|
||||
pref("webgl.lose-context-on-memory-preasure", false);
|
||||
pref("webgl.lose-context-on-memory-pressure", false);
|
||||
pref("webgl.can-lose-context-in-foreground", true);
|
||||
pref("webgl.restore-context-when-visible", true);
|
||||
pref("webgl.max-warnings-per-context", 32);
|
||||
|
@ -47,6 +47,9 @@ function installAddon(url) {
|
||||
logLevel: "verbose",
|
||||
format: "tbpl",
|
||||
},
|
||||
console: {
|
||||
logLevel: "info",
|
||||
},
|
||||
}
|
||||
setPrefs("extensions." + install.addon.id + ".sdk", options);
|
||||
|
||||
|
@ -156,6 +156,9 @@ function testInit() {
|
||||
logLevel: "verbose",
|
||||
format: "tbpl",
|
||||
},
|
||||
console: {
|
||||
logLevel: "info",
|
||||
},
|
||||
}
|
||||
setPrefs("extensions." + TEST_ID + ".sdk", options);
|
||||
|
||||
|
@ -103,7 +103,7 @@
|
||||
|
||||
height: 0;
|
||||
width: 0;
|
||||
border: 14px solid hsl(210,2%,22%);
|
||||
border: 14px solid hsl(214,13%,24%);
|
||||
border-left-color: transparent;
|
||||
border-right-color: transparent;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ menubar:-moz-lwtheme,
|
||||
toolbar:-moz-lwtheme {
|
||||
-moz-appearance: none;
|
||||
background: none;
|
||||
border-style: none;
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
menubar {
|
||||
|
@ -127,7 +127,7 @@ menubar > menu[_moz-menuactive="true"][open="true"] {
|
||||
|
||||
menubar > menu:-moz-lwtheme {
|
||||
-moz-appearance: none;
|
||||
border-style: none;
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
menubar > menu:-moz-lwtheme:not([disabled="true"]) {
|
||||
|
@ -43,7 +43,7 @@ toolbox:-moz-lwtheme,
|
||||
toolbar:-moz-lwtheme {
|
||||
-moz-appearance: none;
|
||||
background: none;
|
||||
border-style: none;
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
/* ::::: toolbar decorations ::::: */
|
||||
|
Loading…
Reference in New Issue
Block a user