Merge mozilla-central to mozilla-inbound

This commit is contained in:
Carsten "Tomcat" Book 2015-11-17 12:33:46 +01:00
Родитель cf6ee74e32 1cf9b8b2ab
Коммит a22ff2640a
127 изменённых файлов: 1498 добавлений и 1031 удалений

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="54167ef91545c948e44098deb9f721210890eaf0"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9473dbcbebf4e758a3b73200968efc69071b4312"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="54167ef91545c948e44098deb9f721210890eaf0"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9473dbcbebf4e758a3b73200968efc69071b4312"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>

Просмотреть файл

@ -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="54167ef91545c948e44098deb9f721210890eaf0"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="9473dbcbebf4e758a3b73200968efc69071b4312"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cb4604d5a578efd027277059ce3e0f6e3af59bd1"/>

Просмотреть файл

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="54167ef91545c948e44098deb9f721210890eaf0"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9473dbcbebf4e758a3b73200968efc69071b4312"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ac7e9ae8a24ab4a3f3da801ca53f95f39a32b89f"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="94bbf7890326d37f03fd2a6822b6618b08bec8e2"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="54167ef91545c948e44098deb9f721210890eaf0"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9473dbcbebf4e758a3b73200968efc69071b4312"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="54167ef91545c948e44098deb9f721210890eaf0"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9473dbcbebf4e758a3b73200968efc69071b4312"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

Просмотреть файл

@ -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="54167ef91545c948e44098deb9f721210890eaf0"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="9473dbcbebf4e758a3b73200968efc69071b4312"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cb4604d5a578efd027277059ce3e0f6e3af59bd1"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="54167ef91545c948e44098deb9f721210890eaf0"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9473dbcbebf4e758a3b73200968efc69071b4312"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>

Просмотреть файл

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "54167ef91545c948e44098deb9f721210890eaf0",
"git_revision": "9473dbcbebf4e758a3b73200968efc69071b4312",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "503587ee1e9b599ee7f2f8a0be7256141c4c48c6",
"revision": "0513f90869b616c88cfaa5fe52ff8ba22a472062",
"repo_path": "integration/gaia-central"
}

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="54167ef91545c948e44098deb9f721210890eaf0"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9473dbcbebf4e758a3b73200968efc69071b4312"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>

Просмотреть файл

@ -18,7 +18,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="54167ef91545c948e44098deb9f721210890eaf0"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9473dbcbebf4e758a3b73200968efc69071b4312"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ac7e9ae8a24ab4a3f3da801ca53f95f39a32b89f"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="94bbf7890326d37f03fd2a6822b6618b08bec8e2"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="54167ef91545c948e44098deb9f721210890eaf0"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9473dbcbebf4e758a3b73200968efc69071b4312"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>

Просмотреть файл

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1445462022000">
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1447453044000">
<emItems>
<emItem blockID="i58" id="webmaster@buzzzzvideos.info">
<versionRange minVersion="0" maxVersion="*">
@ -405,6 +405,12 @@
</versionRange>
<prefs>
</prefs>
</emItem>
<emItem blockID="i1050" id="87aukfkausiopoawjsuifhasefgased278djasi@jetpack">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
<prefs>
</prefs>
</emItem>
<emItem blockID="i504" id="aytac@abc.com">
<versionRange minVersion="0" maxVersion="*" severity="3">
@ -2823,12 +2829,13 @@
<infoURL>https://get.adobe.com/flashplayer/</infoURL>
</pluginItem>
<pluginItem blockID="p180">
<match name="filename" exp="JavaAppletPlugin\.plugin" /> <versionRange minVersion="Java 7 Update 0" maxVersion="Java 7 Update 11" severity="0" vulnerabilitystatus="1">
<match name="filename" exp="JavaAppletPlugin\.plugin" /> <versionRange minVersion="Java 7 Update 0" maxVersion="Java 7 Update 10" severity="0" vulnerabilitystatus="1">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="17.0" maxVersion="*" />
</targetApplication>
</versionRange>
</pluginItem>
<infoURL>https://java.com/</infoURL>
</pluginItem>
<pluginItem blockID="p182">
<match name="name" exp="Java\(TM\) Platform SE 7 U([0-9]|(1[0-1]))(\s[^\d\._U]|$)" /> <match name="filename" exp="npjp2\.dll" /> <versionRange severity="0" vulnerabilitystatus="1">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
@ -3277,6 +3284,22 @@
<match name="filename" exp="(NPSWF32.*\.dll)|(NPSWF64.*\.dll)|(Flash\ Player\.plugin)" /> <versionRange minVersion="19.0" maxVersion="19.0.0.225" severity="0" vulnerabilitystatus="1"></versionRange>
<infoURL>https://get.adobe.com/flashplayer/</infoURL>
</pluginItem>
<pluginItem blockID="p1052">
<match name="filename" exp="JavaAppletPlugin\.plugin" /> <versionRange minVersion="Java 7 Update 11" maxVersion="Java 7 Update 11" severity="0" vulnerabilitystatus="1"></versionRange>
<infoURL>https://java.com/</infoURL>
</pluginItem>
<pluginItem blockID="p1053">
<match name="filename" exp="nprpplugin\.dll" /> <versionRange minVersion="0" maxVersion="17.0.10.7" severity="0" vulnerabilitystatus="1"></versionRange>
<infoURL>https://real.com/</infoURL>
</pluginItem>
<pluginItem blockID="p1054">
<match name="filename" exp="np32dsw_[0-9]+\.dll" /> <versionRange minVersion="0" maxVersion="12.2.0.162" severity="0" vulnerabilitystatus="1"></versionRange>
<infoURL>https://get.adobe.com/shockwave/</infoURL>
</pluginItem>
<pluginItem blockID="p1055">
<match name="filename" exp="DirectorShockwave\.plugin" /> <versionRange minVersion="0" maxVersion="12.2.0.162" severity="0" vulnerabilitystatus="1"></versionRange>
<infoURL>https://get.adobe.com/shockwave/</infoURL>
</pluginItem>
</pluginItems>
<gfxItems>
@ -3341,6 +3364,11 @@
<device>0x6903</device>
<device>0x6907</device>
<device>0x7300</device>
<device>0x9870</device>
<device>0x9874</device>
<device>0x9875</device>
<device>0x9876</device>
<device>0x9877</device>
</devices>
<feature>DIRECT2D</feature> <featureStatus>BLOCKED_DRIVER_VERSION</featureStatus> <driverVersion>15.201.1151.0</driverVersion> <driverVersionComparator>LESS_THAN</driverVersionComparator> </gfxBlacklistEntry>
<gfxBlacklistEntry blockID="g984"> <os>All</os> <vendor>0x8086</vendor> <feature>DIRECT2D</feature> <featureStatus>BLOCKED_DRIVER_VERSION</featureStatus> <driverVersion>8.15.10.2413</driverVersion> <driverVersionComparator>LESS_THAN_OR_EQUAL</driverVersionComparator> </gfxBlacklistEntry>
@ -3360,6 +3388,11 @@
<device>0x6903</device>
<device>0x6907</device>
<device>0x7300</device>
<device>0x9870</device>
<device>0x9874</device>
<device>0x9875</device>
<device>0x9876</device>
<device>0x9877</device>
</devices>
<feature>DIRECT2D</feature> <featureStatus>BLOCKED_DRIVER_VERSION</featureStatus> <driverVersion>15.201.1151.0</driverVersion> <driverVersionComparator>LESS_THAN</driverVersionComparator> </gfxBlacklistEntry>
</gfxItems>

Просмотреть файл

@ -7,12 +7,6 @@ Components.utils.import("resource://gre/modules/Services.jsm");
const PREF_EM_HOTFIX_ID = "extensions.hotfix.id";
var gMenuButton = null;
try {
gMenuButton = Services.wm.getMostRecentWindow("navigator:browser")
.document.getElementById("PanelUI-menu-button");
} catch (ex) { };
function init(aEvent)
{
if (aEvent.target != document)
@ -55,17 +49,6 @@ function init(aEvent)
document.getElementById("communityDesc").hidden = true;
}
if (/^42/.test(version)) {
document.getElementById("version").addEventListener("click", event => {
if (gMenuButton) {
gMenuButton.classList.add("thumburger");
if (event.shiftKey) {
gMenuButton = null;
}
}
});
}
#ifdef MOZ_UPDATER
gAppUpdater = new appUpdater();
@ -100,9 +83,6 @@ function onUnload(aEvent) {
// Safe to call even when there isn't a download in progress.
gAppUpdater.removeDownloadListener();
gAppUpdater = null;
if (gMenuButton) {
gMenuButton.classList.remove("thumburger");
}
}

Просмотреть файл

@ -51,16 +51,6 @@
return decodeURIComponent(matches[1]);
}
function goBack(buttonEl)
{
if (history.length > 1) {
history.back();
} else {
location.href = "about:home";
}
buttonEl.disabled = true;
}
function toggleVisibility(id)
{
var node = document.getElementById(id);
@ -213,7 +203,7 @@
</div>
<div id="buttonContainer">
<button id="returnButton" autocomplete="off" onclick="goBack(this);" autofocus="true">&certerror.returnToPreviousPage.label;</button>
<button id="returnButton" autocomplete="off" autofocus="true">&certerror.returnToPreviousPage.label;</button>
<div id="buttonSpacer"></div>
<button id="advancedButton" autocomplete="off" onclick="toggleVisibility('advancedPanel');" autofocus="true">&certerror.advanced.label;</button>
</div>

Просмотреть файл

@ -2982,20 +2982,14 @@ var BrowserOnClick = {
}
break;
case "getMeOutOfHereButton":
case "returnButton":
if (isTopFrame) {
secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_BAD_CERT_TOP_GET_ME_OUT_OF_HERE);
}
getMeOutOfHere();
goBackFromErrorPage();
break;
case "technicalContent":
if (isTopFrame) {
secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_BAD_CERT_TOP_TECHNICAL_DETAILS);
}
break;
case "expertContent":
case "advancedButton":
if (isTopFrame) {
secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_BAD_CERT_TOP_UNDERSTAND_RISKS);
}
@ -3134,6 +3128,35 @@ var BrowserOnClick = {
* when their own homepage is infected, we can get them somewhere safe.
*/
function getMeOutOfHere() {
gBrowser.loadURI(getDefaultHomePage());
}
/**
* Re-direct the browser to the previous page or a known-safe page if no
* previous page is found in history. This function is used when the user
* browses to a secure page with certificate issues and is presented with
* about:certerror. The "Go Back" button should take the user to the previous
* or a default start page so that even when their own homepage is on a server
* that has certificate errors, we can get them somewhere safe.
*/
function goBackFromErrorPage() {
const ss = Cc["@mozilla.org/browser/sessionstore;1"].
getService(Ci.nsISessionStore);
let state = JSON.parse(ss.getTabState(gBrowser.selectedTab));
if (state.index == 1) {
// If the unsafe page is the first or the only one in history, go to the
// start page.
gBrowser.loadURI(getDefaultHomePage());
} else {
BrowserBack();
}
}
/**
* Return the default start page for the cases when the user's own homepage is
* infected, so we can get them somewhere safe.
*/
function getDefaultHomePage() {
// Get the start page from the *default* pref branch, not the user's
var prefs = Services.prefs.getDefaultBranch(null);
var url = BROWSER_NEW_TAB_URL;
@ -3146,7 +3169,7 @@ function getMeOutOfHere() {
} catch(e) {
Components.utils.reportError("Couldn't get homepage pref: " + e);
}
gBrowser.loadURI(url);
return url;
}
function BrowserFullScreen()

Просмотреть файл

@ -7,6 +7,8 @@
const GOOD_PAGE = "https://example.com/";
const BAD_CERT = "https://expired.example.com/";
const BAD_STS_CERT = "https://badchain.include-subdomains.pinning.example.com:443";
const {TabStateFlusher} = Cu.import("resource:///modules/sessionstore/TabStateFlusher.jsm", {});
const ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
add_task(function* checkReturnToAboutHome() {
info("Loading a bad cert page directly and making sure 'return to previous page' goes to about:home");
@ -24,6 +26,12 @@ add_task(function* checkReturnToAboutHome() {
is(browser.webNavigation.canGoBack, false, "!webNavigation.canGoBack");
is(browser.webNavigation.canGoForward, false, "!webNavigation.canGoForward");
// Populate the shistory entries manually, since it happens asynchronously
// and the following tests will be too soon otherwise.
yield TabStateFlusher.flush(browser);
let {entries} = JSON.parse(ss.getTabState(tab));
is(entries.length, 1, "there is one shistory entry");
info("Clicking the go back button on about:certerror");
let pageshowPromise = promiseWaitForEvent(browser, "pageshow");
yield ContentTask.spawn(browser, null, function* () {
@ -53,6 +61,12 @@ add_task(function* checkReturnToPreviousPage() {
is(browser.webNavigation.canGoBack, true, "webNavigation.canGoBack");
is(browser.webNavigation.canGoForward, false, "!webNavigation.canGoForward");
// Populate the shistory entries manually, since it happens asynchronously
// and the following tests will be too soon otherwise.
yield TabStateFlusher.flush(browser);
let {entries} = JSON.parse(ss.getTabState(tab));
is(entries.length, 2, "there are two shistory entries");
info("Clicking the go back button on about:certerror");
let pageshowPromise = promiseWaitForEvent(browser, "pageshow");
yield ContentTask.spawn(browser, null, function* () {

Просмотреть файл

@ -108,7 +108,6 @@ static const mozilla::Module::ContractIDEntry kBrowserContracts[] = {
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "home", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "newtab", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "remote-newtab", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "permissions", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "preferences", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "downloads", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "accounts", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },

Просмотреть файл

@ -39,6 +39,7 @@ function BrowserAction(options, extension)
}
this.defaults = {
enabled: true,
title: title,
badgeText: "",
badgeBackgroundColor: null,
@ -113,6 +114,12 @@ BrowserAction.prototype = {
node.removeAttribute("badge");
}
if (tabData.enabled) {
node.removeAttribute("disabled");
} else {
node.setAttribute("disabled", "true");
}
let badgeNode = node.ownerDocument.getAnonymousElementByAttribute(node,
'class', 'toolbarbutton-badge');
if (badgeNode) {
@ -207,6 +214,16 @@ extensions.registerAPI((extension, context) => {
};
}).api(),
enable: function(tabId) {
let tab = tabId ? TabManager.getTab(tabId) : null;
browserActionOf(extension).setProperty(tab, "enabled", true);
},
disable: function(tabId) {
let tab = tabId ? TabManager.getTab(tabId) : null;
browserActionOf(extension).setProperty(tab, "enabled", false);
},
setTitle: function(details) {
let tab = details.tabId ? TabManager.getTab(details.tabId) : null;
browserActionOf(extension).setProperty(tab, "title", details.title);

Просмотреть файл

@ -11,8 +11,10 @@ support-files =
[browser_ext_browserAction_simple.js]
[browser_ext_browserAction_pageAction_icon.js]
[browser_ext_browserAction_context.js]
[browser_ext_browserAction_disabled.js]
[browser_ext_pageAction_context.js]
[browser_ext_pageAction_popup.js]
[browser_ext_browserAction_popup.js]
[browser_ext_contextMenus.js]
[browser_ext_getViews.js]
[browser_ext_tabs_executeScript.js]

Просмотреть файл

@ -30,12 +30,20 @@ add_task(function* testTabSwitchContext() {
"popup": browser.runtime.getURL("2.html"),
"title": "Title 2",
"badge": "2",
"badgeBackgroundColor": [0xff, 0, 0] },
"badgeBackgroundColor": [0xff, 0, 0],
"disabled": true },
{ "icon": browser.runtime.getURL("1.png"),
"popup": browser.runtime.getURL("default-2.html"),
"title": "Default Title 2",
"badge": "d2",
"badgeBackgroundColor": [0, 0xff, 0] },
"badgeBackgroundColor": [0, 0xff, 0],
"disabled": true },
{ "icon": browser.runtime.getURL("1.png"),
"popup": browser.runtime.getURL("default-2.html"),
"title": "Default Title 2",
"badge": "d2",
"badgeBackgroundColor": [0, 0xff, 0],
"disabled": false },
{ "icon": browser.runtime.getURL("default-2.png"),
"popup": browser.runtime.getURL("default-2.html"),
"title": "Default Title 2",
@ -48,18 +56,24 @@ add_task(function* testTabSwitchContext() {
var tests = [
expect => {
browser.test.log("Initial state, expect default properties.");
expect(details[0]);
expectDefaults(details[0]).then(() => {
expect(details[0]);
});
},
expect => {
browser.test.log("Change the icon in the current tab. Expect default properties excluding the icon.");
browser.browserAction.setIcon({ tabId: tabs[0], path: "1.png" });
expect(details[1]);
expectDefaults(details[0]).then(() => {
expect(details[1]);
});
},
expect => {
browser.test.log("Create a new tab. Expect default properties.");
browser.tabs.create({ active: true, url: "about:blank?0" }, tab => {
tabs.push(tab.id);
expect(details[0]);
expectDefaults(details[0]).then(() => {
expect(details[0]);
});
});
},
expect => {
@ -70,8 +84,11 @@ add_task(function* testTabSwitchContext() {
browser.browserAction.setTitle({ tabId, title: "Title 2" });
browser.browserAction.setBadgeText({ tabId, text: "2" });
browser.browserAction.setBadgeBackgroundColor({ tabId, color: [0xff, 0, 0] });
browser.browserAction.disable(tabId);
expect(details[2]);
expectDefaults(details[0]).then(() => {
expect(details[2]);
});
},
expect => {
browser.test.log("Navigate to a new page. Expect no changes.");
@ -100,49 +117,56 @@ add_task(function* testTabSwitchContext() {
browser.browserAction.setTitle({ title: "Default Title 2" });
browser.browserAction.setBadgeText({ text: "d2" });
browser.browserAction.setBadgeBackgroundColor({ color: [0, 0xff, 0] });
expect(details[3]);
browser.browserAction.disable();
expectDefaults(details[3]).then(() => {
expect(details[3]);
});
},
expect => {
browser.test.log("Re-enable by default. Expect enabled.");
browser.browserAction.enable();
expectDefaults(details[4]).then(() => {
expect(details[4]);
});
},
expect => {
browser.test.log("Switch back to tab 2. Expect former value, unaffected by changes to defaults in previous step.");
browser.tabs.update(tabs[1], { active: true }, () => {
expect(details[2]);
expectDefaults(details[3]).then(() => {
expect(details[2]);
});
});
},
expect => {
browser.test.log("Delete tab, switch back to tab 1. Expect previous results again.");
browser.tabs.remove(tabs[1], () => {
expect(details[3]);
expect(details[4]);
});
},
expect => {
browser.test.log("Create a new tab. Expect new default properties.");
browser.tabs.create({ active: true, url: "about:blank?2" }, tab => {
tabs.push(tab.id);
expect(details[4]);
expect(details[5]);
});
},
expect => {
browser.test.log("Delete tab.");
browser.tabs.remove(tabs[2], () => {
expect(details[3]);
expect(details[4]);
});
},
];
// Gets the current details of the browser action, and returns a
// promise that resolves to an object containing them.
function getDetails() {
return new Promise(resolve => {
return browser.tabs.query({ active: true, currentWindow: true }, resolve);
}).then(tabs => {
var tabId = tabs[0].id;
return Promise.all([
new Promise(resolve => browser.browserAction.getTitle({tabId}, resolve)),
new Promise(resolve => browser.browserAction.getPopup({tabId}, resolve)),
new Promise(resolve => browser.browserAction.getBadgeText({tabId}, resolve)),
new Promise(resolve => browser.browserAction.getBadgeBackgroundColor({tabId}, resolve))])
}).then(details => {
function getDetails(tabId) {
return Promise.all([
new Promise(resolve => browser.browserAction.getTitle({tabId}, resolve)),
new Promise(resolve => browser.browserAction.getPopup({tabId}, resolve)),
new Promise(resolve => browser.browserAction.getBadgeText({tabId}, resolve)),
new Promise(resolve => browser.browserAction.getBadgeBackgroundColor({tabId}, resolve))]
).then(details => {
return Promise.resolve({ title: details[0],
popup: details[1],
badge: details[2],
@ -150,6 +174,26 @@ add_task(function* testTabSwitchContext() {
});
}
function checkDetails(expecting, tabId) {
return getDetails(tabId).then(details => {
browser.test.assertEq(expecting.title, details.title,
"expected value from getTitle");
browser.test.assertEq(expecting.popup, details.popup,
"expected value from getPopup");
browser.test.assertEq(expecting.badge, details.badge,
"expected value from getBadge");
browser.test.assertEq(String(expecting.badgeBackgroundColor),
String(details.badgeBackgroundColor),
"expected value from getBadgeBackgroundColor");
});
}
function expectDefaults(expecting) {
return checkDetails(expecting);
}
// Runs the next test in the `tests` array, checks the results,
// and passes control back to the outer test scope.
@ -159,20 +203,11 @@ add_task(function* testTabSwitchContext() {
test(expecting => {
// Check that the API returns the expected values, and then
// run the next test.
getDetails().then(details => {
browser.test.assertEq(expecting.title, details.title,
"expected value from getTitle");
browser.test.assertEq(expecting.popup, details.popup,
"expected value from getPopup");
browser.test.assertEq(expecting.badge, details.badge,
"expected value from getBadge");
browser.test.assertEq(String(expecting.badgeBackgroundColor),
String(details.badgeBackgroundColor),
"expected value from getBadgeBackgroundColor");
new Promise(resolve => {
return browser.tabs.query({ active: true, currentWindow: true }, resolve);
}).then(tabs => {
return checkDetails(expecting, tabs[0].id);
}).then(() => {
// Check that the actual icon has the expected values, then
// run the next test.
browser.test.sendMessage("nextTest", expecting, tests.length);
@ -208,6 +243,7 @@ add_task(function* testTabSwitchContext() {
is(button.getAttribute("label"), details.title, "image label is correct");
is(button.getAttribute("aria-label"), details.title, "image aria-label is correct");
is(button.getAttribute("badge"), details.badge, "badge text is correct");
is(button.getAttribute("disabled") == "true", Boolean(details.disabled), "disabled state is correct");
if (details.badge && details.badgeBackgroundColor) {
let badge = button.ownerDocument.getAnonymousElementByAttribute(

Просмотреть файл

@ -0,0 +1,74 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
add_task(function* testDisabled() {
let extension = ExtensionTestUtils.loadExtension({
manifest: {
"browser_action": {}
},
background: function () {
var clicked = false;
browser.browserAction.onClicked.addListener(() => {
browser.test.log("Got click event");
clicked = true;
});
browser.test.onMessage.addListener((msg, expectClick) => {
if (msg == "enable") {
browser.test.log("enable browserAction");
browser.browserAction.enable();
} else if (msg == "disable") {
browser.test.log("disable browserAction");
browser.browserAction.disable();
} else if (msg == "check-clicked") {
browser.test.assertEq(expectClick, clicked, "got click event?");
clicked = false;
} else {
browser.test.fail("Unexpected message");
}
browser.test.sendMessage("next-test");
});
browser.test.sendMessage("ready");
},
});
let browserActionId = makeWidgetId(extension.id) + "-browser-action";
yield Promise.all([extension.startup(), extension.awaitMessage("ready")]);
let elem = document.getElementById(browserActionId);
function click() {
EventUtils.synthesizeMouseAtCenter(elem, {}, window);
return new Promise(SimpleTest.executeSoon);
}
yield click();
extension.sendMessage("check-clicked", true);
yield extension.awaitMessage("next-test");
extension.sendMessage("disable");
yield extension.awaitMessage("next-test");
yield click();
extension.sendMessage("check-clicked", false);
yield extension.awaitMessage("next-test");
extension.sendMessage("enable");
yield extension.awaitMessage("next-test");
yield click();
extension.sendMessage("check-clicked", true);
yield extension.awaitMessage("next-test");
yield extension.unload();
});

Просмотреть файл

@ -0,0 +1,147 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
function promisePopupShown(popup) {
return new Promise(resolve => {
if (popup.popupOpen) {
resolve();
} else {
let onPopupShown = event => {
popup.removeEventListener("popupshown", onPopupShown);
resolve();
};
popup.addEventListener("popupshown", onPopupShown);
}
});
}
add_task(function* testPageActionPopup() {
let extension = ExtensionTestUtils.loadExtension({
manifest: {
"background": {
"page": "data/background.html"
},
"browser_action": {
"default_popup": "popup-a.html"
}
},
files: {
"popup-a.html": `<script src="popup-a.js"></script>`,
"popup-a.js": function() {
browser.runtime.sendMessage("from-popup-a");
},
"data/popup-b.html": `<script src="popup-b.js"></script>`,
"data/popup-b.js": function() {
browser.runtime.sendMessage("from-popup-b");
},
"data/background.html": `<script src="background.js"></script>`,
"data/background.js": function() {
var tests = [
() => {
sendClick({ expectEvent: false, expectPopup: "a" });
},
() => {
sendClick({ expectEvent: false, expectPopup: "a" });
},
() => {
browser.browserAction.setPopup({ popup: "popup-b.html" });
sendClick({ expectEvent: false, expectPopup: "b" });
},
() => {
sendClick({ expectEvent: false, expectPopup: "b" });
},
() => {
browser.browserAction.setPopup({ popup: "" });
sendClick({ expectEvent: true, expectPopup: null });
},
() => {
sendClick({ expectEvent: true, expectPopup: null });
},
() => {
browser.browserAction.setPopup({ popup: "/popup-a.html" });
sendClick({ expectEvent: false, expectPopup: "a" });
},
];
var expect = {};
function sendClick({ expectEvent, expectPopup }) {
expect = { event: expectEvent, popup: expectPopup };
browser.test.sendMessage("send-click");
}
browser.runtime.onMessage.addListener(msg => {
if (expect.popup) {
browser.test.assertEq(msg, `from-popup-${expect.popup}`,
"expected popup opened");
} else {
browser.test.fail("unexpected popup");
}
expect.popup = null;
browser.test.sendMessage("next-test");
});
browser.browserAction.onClicked.addListener(() => {
if (expect.event) {
browser.test.succeed("expected click event received");
} else {
browser.test.fail("unexpected click event");
}
expect.event = false;
browser.test.sendMessage("next-test");
});
browser.test.onMessage.addListener((msg) => {
if (msg != "next-test") {
browser.test.fail("Expecting 'next-test' message");
}
if (tests.length) {
var test = tests.shift();
test();
} else {
browser.test.notifyPass("browseraction-tests-done");
}
});
browser.test.sendMessage("next-test");
},
},
});
let browserActionId = makeWidgetId(extension.id) + "-browser-action";
let panelId = makeWidgetId(extension.id) + "-panel";
extension.onMessage("send-click", () => {
let button = document.getElementById(browserActionId);
EventUtils.synthesizeMouseAtCenter(button, {}, window);
});
extension.onMessage("next-test", Task.async(function* () {
let panel = document.getElementById(panelId);
if (panel) {
yield promisePopupShown(panel);
panel.hidePopup();
panel = document.getElementById(panelId);
is(panel, undefined, "panel successfully removed from document after hiding");
}
extension.sendMessage("next-test");
}));
yield Promise.all([extension.startup(), extension.awaitFinish("browseraction-tests-done")]);
yield extension.unload();
let panel = document.getElementById(panelId);
is(panel, undefined, "browserAction panel removed from document");
});

Просмотреть файл

@ -391,6 +391,7 @@ html[dir="rtl"] .room-entry-context-actions > .dropdown-menu {
vertical-align: middle;
}
.room-entry-context-item > img,
.room-entry-context-item > a > img {
width: 16px;
}

Просмотреть файл

@ -1,377 +0,0 @@
/* 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/. */
"use strict";
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
// Make it possible to load LoopStorage.jsm in xpcshell tests
try {
Cu.importGlobalProperties(["indexedDB"]);
} catch (ex) {
// don't write this is out in xpcshell, since it's expected there
if (typeof window !== "undefined" && "console" in window) {
console.log("Failed to import indexedDB; if this isn't a unit test," +
" something is wrong", ex);
}
}
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyGetter(this, "eventEmitter", function() {
const { EventEmitter } = Cu.import("resource://devtools/shared/event-emitter.js", {});
return new EventEmitter();
});
this.EXPORTED_SYMBOLS = ["LoopStorage"];
const kDatabasePrefix = "loop-";
const kDefaultDatabaseName = "default";
var gDatabaseName = kDatabasePrefix + kDefaultDatabaseName;
const kDatabaseVersion = 1;
var gWaitForOpenCallbacks = new Set();
var gDatabase = null;
var gClosed = false;
/**
* Properly shut the database instance down. This is done on application shutdown.
*/
const closeDatabase = function() {
Services.obs.removeObserver(closeDatabase, "quit-application");
if (!gDatabase) {
return;
}
gDatabase.close();
gDatabase = null;
gClosed = true;
};
/**
* Open a connection to the IndexedDB database.
* This function is different than IndexedDBHelper.jsm provides, as it ensures
* only one connection is open during the lifetime of this API. Callbacks are
* queued when a connection attempt is in progress and are invoked once the
* connection is established.
*
* @param {Function} onOpen Callback to be invoked once a database connection is
* established. It takes an Error object as first argument
* and the database connection object as second argument,
* if successful.
*/
const ensureDatabaseOpen = function(onOpen) {
if (gClosed) {
onOpen(new Error("Database already closed"));
return;
}
if (gDatabase) {
onOpen(null, gDatabase);
return;
}
if (!gWaitForOpenCallbacks.has(onOpen)) {
gWaitForOpenCallbacks.add(onOpen);
if (gWaitForOpenCallbacks.size !== 1) {
return;
}
}
let invokeCallbacks = err => {
for (let callback of gWaitForOpenCallbacks) {
callback(err, gDatabase);
}
gWaitForOpenCallbacks.clear();
};
let openRequest = indexedDB.open(gDatabaseName, kDatabaseVersion);
openRequest.onblocked = function(event) {
invokeCallbacks(new Error("Database cannot be upgraded cause in use: " + event.target.error));
};
openRequest.onerror = function(event) {
// Try to delete the old database so that we can start this process over
// next time.
indexedDB.deleteDatabase(gDatabaseName);
invokeCallbacks(new Error("Error while opening database: " + event.target.errorCode));
};
openRequest.onupgradeneeded = function(event) {
let db = event.target.result;
eventEmitter.emit("upgrade", db, event.oldVersion, kDatabaseVersion);
};
openRequest.onsuccess = function(event) {
gDatabase = event.target.result;
invokeCallbacks();
// Close the database instance properly on application shutdown.
Services.obs.addObserver(closeDatabase, "quit-application", false);
};
};
/**
* Switch to a database with a different name by closing the current connection
* and making sure that the next connection attempt will be made using the updated
* name.
*
* @param {String} name New name of the database to switch to.
*/
const switchDatabase = function(name) {
if (!name) {
name = kDefaultDatabaseName;
}
name = kDatabasePrefix + name;
if (name == gDatabaseName) {
// This is already the current database, so there's no need to switch.
return;
}
gDatabaseName = name;
if (gDatabase) {
try {
gDatabase.close();
} finally {
gDatabase = null;
}
}
};
/**
* Start a transaction on the loop database and return it.
*
* @param {String} store Name of the object store to start a transaction on
* @param {Function} callback Callback to be invoked once a database connection
* is established and a transaction can be started.
* It takes an Error object as first argument and the
* transaction object as second argument.
* @param {String} mode Mode of the transaction. May be 'readonly' or 'readwrite'
*
* @note we can't use a Promise here, as they are resolved after a spin of the
* event loop; the transaction will have finished by then and no operations
* are possible anymore, yielding an error.
*/
const getTransaction = function(store, callback, mode) {
ensureDatabaseOpen((err, db) => {
if (err) {
callback(err);
return;
}
let trans;
try {
trans = db.transaction(store, mode);
} catch (ex) {
callback(ex);
return;
}
callback(null, trans);
});
};
/**
* Start a transaction on the loop database and return the requested store.
*
* @param {String} store Name of the object store to retrieve
* @param {Function} callback Callback to be invoked once a database connection
* is established and a transaction can be started.
* It takes an Error object as first argument and the
* store object as second argument.
* @param {String} mode Mode of the transaction. May be 'readonly' or 'readwrite'
*
* @note we can't use a Promise here, as they are resolved after a spin of the
* event loop; the transaction will have finished by then and no operations
* are possible anymore, yielding an error.
*/
const getStore = function(store, callback, mode) {
getTransaction(store, (err, trans) => {
if (err) {
callback(err);
return;
}
callback(null, trans.objectStore(store));
}, mode);
};
/**
* Public Loop Storage API.
*
* Since IndexedDB transaction can not stand a spin of the event loop _before_
* using a IDBTransaction object, we can't use Promise.jsm promises. Therefore
* LoopStorage provides two async helper functions, `asyncForEach` and `asyncParallel`.
*
* LoopStorage implements the EventEmitter interface by exposing two methods, `on`
* and `off`, to subscribe to events.
* At this point only the `upgrade` event will be emitted. This happens when the
* database is loaded in memory and consumers will be able to change its structure.
*/
this.LoopStorage = Object.freeze({
/**
* @var {String} databaseName The name of the database that is currently active,
* WITHOUT the prefix
*/
get databaseName() {
return gDatabaseName.substr(kDatabasePrefix.length);
},
/**
* Open a connection to the IndexedDB database and return the database object.
*
* @param {Function} callback Callback to be invoked once a database connection
* is established. It takes an Error object as first
* argument and the database connection object as
* second argument, if successful.
*/
getSingleton: function(callback) {
ensureDatabaseOpen(callback);
},
/**
* Switch to a database with a different name.
*
* @param {String} name New name of the database to switch to. Defaults to
* `kDefaultDatabaseName`
*/
switchDatabase: function(name = kDefaultDatabaseName) {
switchDatabase(name);
},
/**
* Start a transaction on the loop database and return it.
* If only two arguments are passed, the default mode will be assumed and the
* second argument is assumed to be a callback.
*
* @param {String} store Name of the object store to start a transaction on
* @param {Function} callback Callback to be invoked once a database connection
* is established and a transaction can be started.
* It takes an Error object as first argument and the
* transaction object as second argument.
* @param {String} mode Mode of the transaction. May be 'readonly' or 'readwrite'
*
* @note we can't use a Promise here, as they are resolved after a spin of the
* event loop; the transaction will have finished by then and no operations
* are possible anymore, yielding an error.
*/
getTransaction: function(store, callback, mode = "readonly") {
getTransaction(store, callback, mode);
},
/**
* Start a transaction on the loop database and return the requested store.
* If only two arguments are passed, the default mode will be assumed and the
* second argument is assumed to be a callback.
*
* @param {String} store Name of the object store to retrieve
* @param {Function} callback Callback to be invoked once a database connection
* is established and a transaction can be started.
* It takes an Error object as first argument and the
* store object as second argument.
* @param {String} mode Mode of the transaction. May be 'readonly' or 'readwrite'
*
* @note we can't use a Promise here, as they are resolved after a spin of the
* event loop; the transaction will have finished by then and no operations
* are possible anymore, yielding an error.
*/
getStore: function(store, callback, mode = "readonly") {
getStore(store, callback, mode);
},
/**
* Perform an async function in serial on each of the list items and call a
* callback Function when all list items are done.
* IMPORTANT: only use this iteration method if you are sure that the operations
* performed in `onItem` are guaranteed to be async in the success case.
*
* @param {Array} list Non-empty list of items to iterate
* @param {Function} onItem Callback to invoke for each item in the list. It
* takes the item is first argument and a callback
* function as second, which is to be invoked once
* the consumer is done with its async operation. If
* an error is passed as the first argument to this
* callback function, the iteration will stop and
* `onDone` callback will be invoked with that error.
* @param {callback} onDone Callback to invoke when the list is completed or
* on error. It takes an Error object as first
* argument.
*/
asyncForEach: function(list, onItem, onDone) {
let i = 0;
let len = list.length;
if (!len) {
onDone(new Error("Argument error: empty list"));
return;
}
onItem(list[i], function handler(err) {
if (err) {
onDone(err);
return;
}
i++;
if (i < len) {
onItem(list[i], handler, i);
} else {
onDone();
}
}, i);
},
/**
* Perform an async function in parallel on each of the list items and call a
* callback Function when all list items are done.
* IMPORTANT: only use this iteration method if you are sure that the operations
* performed in `onItem` are guaranteed to be async in the success case.
*
* @param {Array} list Non-empty list of items to iterate
* @param {Function} onItem Callback to invoke for each item in the list. It
* takes the item is first argument and a callback
* function as second, which is to be invoked once
* the consumer is done with its async operation. If
* an error is passed as the first argument to this
* callback function, the iteration will stop and
* `onDone` callback will be invoked with that error.
* @param {callback} onDone Callback to invoke when the list is completed or
* on error. It takes an Error object as first
* argument.
*/
asyncParallel: function(list, onItem, onDone) {
let i = 0;
let done = 0;
let callbackCalled = false;
let len = list.length;
if (!len) {
onDone(new Error("Argument error: empty list"));
return;
}
function handleCallback(err) {
if (callbackCalled) {
return;
}
if (err) {
onDone(err);
callbackCalled = true;
return;
}
if (++done === len) {
onDone();
callbackCalled = true;
}
}
for (; i < len; ++i) {
onItem(list[i], handleCallback, i);
}
},
on: (...params) => eventEmitter.on(...params),
off: (...params) => eventEmitter.off(...params)
});

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 411 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 453 B

Просмотреть файл

@ -61,8 +61,6 @@ browser.jar:
skin/classic/browser/customizableui/customizeMode-separatorHorizontal.png (customizableui/customizeMode-separatorHorizontal.png)
skin/classic/browser/customizableui/customizeMode-separatorVertical.png (customizableui/customizeMode-separatorVertical.png)
* skin/classic/browser/customizableui/panelUIOverlay.css (customizableui/panelUIOverlay.css)
skin/classic/browser/customizableui/thumburger.png (customizableui/thumburger.png)
skin/classic/browser/customizableui/thumburger-inverted.png (customizableui/thumburger-inverted.png)
skin/classic/browser/downloads/allDownloadsViewOverlay.css (downloads/allDownloadsViewOverlay.css)
skin/classic/browser/downloads/buttons.png (downloads/buttons.png)
skin/classic/browser/downloads/download-glow-menuPanel.png (downloads/download-glow-menuPanel.png)

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 427 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 809 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 263 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 477 B

Двоичные данные
browser/themes/osx/customizableui/thumburger.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 388 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 891 B

Просмотреть файл

@ -93,10 +93,6 @@ browser.jar:
skin/classic/browser/customizableui/customizeMode-separatorHorizontal.png (customizableui/customizeMode-separatorHorizontal.png)
skin/classic/browser/customizableui/customizeMode-separatorVertical.png (customizableui/customizeMode-separatorVertical.png)
* skin/classic/browser/customizableui/panelUIOverlay.css (customizableui/panelUIOverlay.css)
skin/classic/browser/customizableui/thumburger-inverted.png (customizableui/thumburger-inverted.png)
skin/classic/browser/customizableui/thumburger-inverted@2x.png (customizableui/thumburger-inverted@2x.png)
skin/classic/browser/customizableui/thumburger.png (customizableui/thumburger.png)
skin/classic/browser/customizableui/thumburger@2x.png (customizableui/thumburger@2x.png)
skin/classic/browser/downloads/allDownloadsViewOverlay.css (downloads/allDownloadsViewOverlay.css)
skin/classic/browser/downloads/buttons.png (downloads/buttons.png)
skin/classic/browser/downloads/buttons@2x.png (downloads/buttons@2x.png)
@ -265,8 +261,6 @@ browser.jar:
skin/classic/browser/yosemite/reload-stop-go@2x.png (reload-stop-go-yosemite@2x.png)
skin/classic/browser/yosemite/sync-horizontalbar.png (sync-horizontalbar-yosemite.png)
skin/classic/browser/yosemite/sync-horizontalbar@2x.png (sync-horizontalbar-yosemite@2x.png)
skin/classic/browser/yosemite/thumburger.png (customizableui/thumburger-yosemite.png)
skin/classic/browser/yosemite/thumburger@2x.png (customizableui/thumburger-yosemite@2x.png)
skin/classic/browser/yosemite/tab-selected-end-inactive.svg (tabbrowser/tab-selected-end-yosemite-inactive.svg)
skin/classic/browser/yosemite/tab-selected-start-inactive.svg (tabbrowser/tab-selected-start-yosemite-inactive.svg)
skin/classic/browser/yosemite/tab-active-middle-inactive.png (tabbrowser/tab-active-middle-yosemite-inactive.png)
@ -290,8 +284,6 @@ browser.jar:
% override chrome://browser/skin/places/toolbar.png chrome://browser/skin/lion/places/toolbar.png os=Darwin osversion>=10.7
% override chrome://browser/skin/Toolbar.png chrome://browser/skin/yosemite/Toolbar.png os=Darwin osversion>=10.10
% override chrome://browser/skin/Toolbar@2x.png chrome://browser/skin/yosemite/Toolbar@2x.png os=Darwin osversion>=10.10
% override chrome://browser/skin/customizableui/thumburger.png chrome://browser/skin/yosemite/thumburger.png os=Darwin osversion>=10.10
% override chrome://browser/skin/customizableui/thumburger@2x.png chrome://browser/skin/yosemite/thumburger@2x.png os=Darwin osversion>=10.10
% override chrome://browser/skin/menuPanel.png chrome://browser/skin/yosemite/menuPanel.png os=Darwin osversion>=10.10
% override chrome://browser/skin/menuPanel@2x.png chrome://browser/skin/yosemite/menuPanel@2x.png os=Darwin osversion>=10.10
% override chrome://browser/skin/loop/menuPanel.png chrome://browser/skin/yosemite/loop/menuPanel.png os=Darwin osversion>=10.10

Просмотреть файл

@ -124,15 +124,6 @@ toolbar[brighttext] #sync-button[status="active"] {
-moz-image-region: rect(0, 486px, 18px, 468px);
}
#PanelUI-menu-button.thumburger {
list-style-image: url("chrome://browser/skin/customizableui/thumburger.png") !important;
-moz-image-region: auto !important;
}
toolbar[brighttext] #PanelUI-menu-button.thumburger {
list-style-image: url("chrome://browser/skin/customizableui/thumburger-inverted.png") !important;
}
#edit-controls:not(@inAnyPanel@) > #cut-button {
-moz-image-region: rect(0, 504px, 18px, 486px);
}
@ -439,14 +430,6 @@ toolbar[brighttext] #loop-button {
%endif
}
#PanelUI-menu-button.thumburger {
list-style-image: url("chrome://browser/skin/customizableui/thumburger@2x.png") !important;
}
toolbar[brighttext] #PanelUI-menu-button.thumburger {
list-style-image: url("chrome://browser/skin/customizableui/thumburger-inverted@2x.png") !important;
}
#loop-button {
list-style-image: url("chrome://browser/skin/loop/toolbar@2x.png");
-moz-image-region: rect(0, 36px, 36px, 0);

Просмотреть файл

@ -656,20 +656,12 @@ menuitem.bookmark-item {
#loop-button {
list-style-image: url(chrome://browser/skin/loop/toolbar-lunaSilver.png)
}
#PanelUI-menu-button.thumburger {
list-style-image: url("chrome://browser/skin/customizableui/thumburger-lunaSilver.png") !important;
}
}
@media (-moz-windows-theme: luna-silver) and (min-resolution: 1.1dppx) {
#loop-button {
list-style-image: url(chrome://browser/skin/loop/toolbar-lunaSilver@2x.png)
}
#PanelUI-menu-button.thumburger {
list-style-image: url("chrome://browser/skin/customizableui/thumburger-lunaSilver@2x.png") !important;
}
}
#main-window:not([customizing]) .toolbarbutton-1[disabled=true] > .toolbarbutton-icon,

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 610 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.4 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 565 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.2 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 411 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 754 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 619 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.3 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 220 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 379 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 201 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 343 B

Просмотреть файл

@ -110,18 +110,6 @@ browser.jar:
skin/classic/browser/customizableui/customizeMode-separatorVertical.png (customizableui/customizeMode-separatorVertical.png)
skin/classic/browser/customizableui/menu-arrow.svg (customizableui/menu-arrow.svg)
* skin/classic/browser/customizableui/panelUIOverlay.css (customizableui/panelUIOverlay.css)
skin/classic/browser/customizableui/thumburger-XP.png (customizableui/thumburger-XP.png)
skin/classic/browser/customizableui/thumburger-XP@2x.png (customizableui/thumburger-XP@2x.png)
skin/classic/browser/customizableui/thumburger-aero.png (customizableui/thumburger-aero.png)
skin/classic/browser/customizableui/thumburger-aero@2x.png (customizableui/thumburger-aero@2x.png)
skin/classic/browser/customizableui/thumburger-inverted.png (customizableui/thumburger-inverted.png)
skin/classic/browser/customizableui/thumburger-inverted@2x.png (customizableui/thumburger-inverted@2x.png)
skin/classic/browser/customizableui/thumburger-lunaSilver.png (customizableui/thumburger-lunaSilver.png)
skin/classic/browser/customizableui/thumburger-lunaSilver@2x.png (customizableui/thumburger-lunaSilver@2x.png)
skin/classic/browser/customizableui/thumburger-win8.png (customizableui/thumburger-win8.png)
skin/classic/browser/customizableui/thumburger-win8@2x.png (customizableui/thumburger-win8@2x.png)
skin/classic/browser/customizableui/thumburger.png (customizableui/thumburger.png)
skin/classic/browser/customizableui/thumburger@2x.png (customizableui/thumburger@2x.png)
skin/classic/browser/downloads/allDownloadsViewOverlay.css (downloads/allDownloadsViewOverlay.css)
skin/classic/browser/downloads/buttons.png (downloads/buttons.png)
skin/classic/browser/downloads/buttons-XP.png (downloads/buttons-XP.png)
@ -361,16 +349,6 @@ browser.jar:
% override chrome://browser/skin/Toolbar.png chrome://browser/skin/Toolbar-aero.png os=WINNT osversion=6.1
% override chrome://browser/skin/Toolbar.png chrome://browser/skin/Toolbar-win8.png os=WINNT osversion=6.2
% override chrome://browser/skin/Toolbar.png chrome://browser/skin/Toolbar-win8.png os=WINNT osversion=6.3
% override chrome://browser/skin/customizableui/thumburger.png chrome://browser/skin/customizableui/thumburger-XP.png os=WINNT osversion<6
% override chrome://browser/skin/customizableui/thumburger.png chrome://browser/skin/customizableui/thumburger-aero.png os=WINNT osversion=6
% override chrome://browser/skin/customizableui/thumburger.png chrome://browser/skin/customizableui/thumburger-aero.png os=WINNT osversion=6.1
% override chrome://browser/skin/customizableui/thumburger.png chrome://browser/skin/customizableui/thumburger-win8.png os=WINNT osversion=6.2
% override chrome://browser/skin/customizableui/thumburger.png chrome://browser/skin/customizableui/thumburger-win8.png os=WINNT osversion=6.3
% override chrome://browser/skin/customizableui/thumburger@2x.png chrome://browser/skin/customizableui/thumburger-XP@2x.png os=WINNT osversion<6
% override chrome://browser/skin/customizableui/thumburger@2x.png chrome://browser/skin/customizableui/thumburger-aero@2x.png os=WINNT osversion=6
% override chrome://browser/skin/customizableui/thumburger@2x.png chrome://browser/skin/customizableui/thumburger-aero@2x.png os=WINNT osversion=6.1
% override chrome://browser/skin/customizableui/thumburger@2x.png chrome://browser/skin/customizableui/thumburger-win8@2x.png os=WINNT osversion=6.2
% override chrome://browser/skin/customizableui/thumburger@2x.png chrome://browser/skin/customizableui/thumburger-win8@2x.png os=WINNT osversion=6.3
% override chrome://browser/skin/loop/toolbar.png chrome://browser/skin/loop/toolbar-XP.png os=WINNT osversion<6
% override chrome://browser/skin/loop/toolbar.png chrome://browser/skin/loop/toolbar-aero.png os=WINNT osversion=6
% override chrome://browser/skin/loop/toolbar.png chrome://browser/skin/loop/toolbar-aero.png os=WINNT osversion=6.1

Просмотреть файл

@ -64,15 +64,19 @@ label {
align-items: center;
}
.target-logo {
.target-icon {
height: 24px;
margin-right: 5px;
}
.target-logo:not([src]) {
.target-icon:not([src]) {
display: none;
}
.inverted-icons .target-icon {
filter: invert(30%);
}
.target-details {
flex: 1;
}

Просмотреть файл

@ -21,11 +21,11 @@
<body id="body">
<div id="categories">
<div class="category" value="addons" selected="true">
<img class="category-icon" src="chrome://mozapps/skin/extensions/category-extensions.png"/>
<img class="category-icon" src="chrome://devtools/skin/images/debugging-addons.svg"/>
<div class="category-name">&aboutDebugging.addons;</div>
</div>
<div class="category" value="workers">
<img class="category-icon" src="chrome://browser/skin/preferences/in-content/icons.svg#applications"/>
<img class="category-icon" src="chrome://devtools/skin/images/debugging-workers.svg"/>
<div class="category-name">&aboutDebugging.workers;</div>
</div>
</div>

Просмотреть файл

@ -53,7 +53,7 @@ exports.TargetComponent = React.createClass({
let target = this.props.target;
return React.createElement("div", { className: "target" },
React.createElement("img", {
className: "target-logo",
className: "target-icon",
src: target.icon }),
React.createElement("div", { className: "target-details" },
React.createElement("div", { className: "target-name" }, target.name),

Просмотреть файл

@ -16,6 +16,7 @@ loader.lazyRequireGetter(this, "Services");
const Strings = Services.strings.createBundle(
"chrome://devtools/locale/aboutdebugging.properties");
const WorkerIcon = "chrome://devtools/skin/images/debugging-workers.svg";
exports.WorkersComponent = React.createClass({
displayName: "WorkersComponent",
@ -42,7 +43,7 @@ exports.WorkersComponent = React.createClass({
render() {
let client = this.props.client;
let workers = this.state.workers;
return React.createElement("div", null,
return React.createElement("div", { className: "inverted-icons" },
React.createElement(TargetListComponent, {
name: Strings.GetStringFromName("serviceWorkers"),
targets: workers.service, client }),
@ -63,6 +64,7 @@ exports.WorkersComponent = React.createClass({
forms.forEach(form => {
let worker = {
name: form.url,
icon: WorkerIcon,
actorID: form.actor
};
switch (form.type) {

Просмотреть файл

@ -53,13 +53,6 @@ testDir = testDir.replace("chrome:/mochitest", "chrome://mochitest");
var helpersjs = testDir + "/../../../commandline/test/helpers.js";
Services.scriptloader.loadSubScript(helpersjs, this);
// Redeclare dbg_assert with a fatal behavior.
function dbg_assert(cond, e) {
if (!cond) {
throw e;
}
}
function addWindow(aUrl) {
info("Adding window: " + aUrl);
return promise.resolve(getChromeWindow(window.open(aUrl)));

Просмотреть файл

@ -289,6 +289,9 @@ devtools.jar:
skin/images/tool-canvas.svg (themes/images/tool-canvas.svg)
skin/images/tool-debugger.svg (themes/images/tool-debugger.svg)
skin/images/tool-debugger-paused.svg (themes/images/tool-debugger-paused.svg)
skin/images/debugging-addons.svg (themes/images/debugging-addons.svg)
skin/images/debugging-devices.svg (themes/images/debugging-devices.svg)
skin/images/debugging-workers.svg (themes/images/debugging-workers.svg)
skin/images/tool-inspector.svg (themes/images/tool-inspector.svg)
skin/images/tool-shadereditor.svg (themes/images/tool-shadereditor.svg)
skin/images/tool-styleeditor.svg (themes/images/tool-styleeditor.svg)

Просмотреть файл

@ -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 height="16" width="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18" fill="#fbfbfb">
<path d="M12,17c0.5,0,1-0.5,1-1v-4c0,0,0.2-0.8,0.8-0.8c0.6,0,0.6,0.8,1.8,0.8 c0.6,0,1.5-0.2,1.5-2c0-1.8-0.9-2-1.5-2c-1.1,0-1.2,0.8-1.8,0.8C13.2,8.8,13,8,13,8V6c0-0.6-0.4-1-1-1H9c0,0-0.8-0.1-0.8-0.8 S9,3.6,9,2.5C9,1.9,8.8,1,7,1S5,1.9,5,2.5c0,1.1,0.8,1.2,0.8,1.8S5,5,5,5H2C1.4,5,1,5.4,1,6l0,2.5c0,0-0.1,1.5,1.1,1.5 c0.8,0,0.9-1,1.9-1c0.5,0,1,0.5,1,1.6c0,1-0.5,1.6-1,1.6c-1,0-1.1-1-1.9-1C0.9,11,1,12.5,1,12.5L1,16c0,0.6,0.4,1,1,1h3.9 c0,0,1.5,0.1,1.5-1.1c0-0.8-1-0.9-1-1.9c0-0.5,0.7-1.2,1.8-1.2s1.9,0.7,1.9,1.2c0,1-1,1.1-1,1.9c0,1.2,1.5,1.1,1.5,1.1H12z" />
</svg>

После

Ширина:  |  Высота:  |  Размер: 874 B

Просмотреть файл

@ -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 height="16" width="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="#fbfbfb">
<path d="M10.7,14.4H5.3c-1.2,0-1.5-0.4-1.5-1.2V2.8c0-0.9,0.3-1.2,1.5-1.2h5.3c1.1,0,1.5,0.3,1.5,1.2v10.3
C12.2,14.1,11.8,14.4,10.7,14.4z M5,12.6h6V3.5H5V12.6z"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 482 B

Просмотреть файл

@ -0,0 +1,11 @@
<!-- 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 height="16" width="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="#fbfbfb">
<path d="M14.6,6.1L13.5,5l0,0c0.1-0.1,0.2-0.4,0.2-0.6c0-0.2-0.1-0.4-0.2-0.6l-0.4-0.4c-0.3-0.3-0.8-0.3-1.1,0l0,0
L10.5,2c-0.2-0.2-0.3-0.2-0.5-0.2c-0.2,0-0.3,0.1-0.5,0.2L8.3,3.2C8.1,3.3,8.1,3.4,8.1,3.6S8.2,4,8.3,4.1l1.6,1.6L7.8,7.8L5.6,5.7
l1.5-1.5C7.3,4,7.4,3.8,7.4,3.6c0-0.2-0.1-0.4-0.2-0.6l-1-1C5.8,1.7,5.3,1.7,5,2L0.9,6.1C0.7,6.3,0.6,6.5,0.6,6.7
c0,0.2,0.1,0.4,0.2,0.6l1,1c0.3,0.3,0.9,0.3,1.2,0l1.4-1.4l2,2.1l-3.4,3.3c-0.3,0.3-0.3,0.8,0,1.1l0.3,0.3c0.3,0.3,0.8,0.3,1.1,0
l3.3-3.4l3.3,3.4c0.1,0.1,0.3,0.2,0.6,0.2c0.2,0,0.4-0.1,0.6-0.2l0.3-0.3c0.3-0.3,0.3-0.8,0-1.1L9,9l2-2.1l1.4,1.4
c0.1,0.1,2.3,1.1,2.7,0.7C15.5,8.6,14.8,6.3,14.6,6.1z"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 963 B

Просмотреть файл

@ -1820,7 +1820,8 @@ Messages.ConsoleTable.prototype = Heritage.extend(Messages.Extended.prototype,
let data = this._arguments[0];
if (data.class != "Array" && data.class != "Object" &&
data.class != "Map" && data.class != "Set") {
data.class != "Map" && data.class != "Set" &&
data.class != "WeakMap" && data.class != "WeakSet") {
return;
}
@ -1900,7 +1901,7 @@ Messages.ConsoleTable.prototype = Heritage.extend(Messages.Extended.prototype,
deferred.resolve();
});
} else if (data.class == "Map") {
} else if (data.class == "Map" || data.class == "WeakMap") {
let entries = data.preview.entries;
if (!hasColumnsArg) {
@ -1925,7 +1926,7 @@ Messages.ConsoleTable.prototype = Heritage.extend(Messages.Extended.prototype,
}
deferred.resolve();
} else if (data.class == "Set") {
} else if (data.class == "Set" || data.class == "WeakSet") {
let entries = data.preview.items;
if (!hasColumnsArg) {

Просмотреть файл

@ -153,6 +153,26 @@ var inputTests = [
inspectable: true,
variablesViewLabel: "Map[3]",
},
// 15 - WeakSet
{
input: "window.weakset",
// Need a regexp because the order may vary.
output: new RegExp("WeakSet \\[ (String\\[7\\], <head>|<head>, String\\[7\\]) \\]"),
printOutput: "[object WeakSet]",
inspectable: true,
variablesViewLabel: "WeakSet[2]",
},
// 16 - WeakMap
{
input: "window.weakmap",
// Need a regexp because the order may vary.
output: new RegExp("WeakMap { (String\\[7\\]: 23, HTMLCollection\\[2\\]: Object|HTMLCollection\\[2\\]: Object, String\\[7\\]: 23) }"),
printOutput: "[object WeakMap]",
inspectable: true,
variablesViewLabel: "WeakMap[2]",
},
];
function test() {

Просмотреть файл

@ -120,7 +120,25 @@ const TEST_DATA = [
{ _index: 1, _key: "5", _value: "\"value associated with 5\"" },
],
columns: { _index: "(iteration index)", _key: "Key", _value: "Values" }
}
},
{
command: "console.table(weakset)",
data: [
{ _value: "String[7]" },
{ _value: "String[7]" },
],
columns: { _index: "(iteration index)", _value: "Values" },
couldBeOutOfOrder: true,
},
{
command: "console.table(weakmap)",
data: [
{ _key: "String[7]", _value: "\"oh no\"" },
{ _key: "String[7]", _value: "23" },
],
columns: { _index: "(iteration index)", _key: "Key", _value: "Values" },
couldBeOutOfOrder: true,
},
];
add_task(function*() {
@ -156,14 +174,23 @@ add_task(function*() {
let entryResult = {};
for (let key of Object.keys(entries)) {
entryResult[key] = entries[key] instanceof HTMLElement ?
entries[key].textContent : entries[key];
// If the results can be out of order, then ignore _index.
if (!testdata.couldBeOutOfOrder || key !== "_index") {
entryResult[key] = entries[key] instanceof HTMLElement ?
entries[key].textContent : entries[key];
}
}
return entryResult;
});
is(data.toSource(), testdata.data.toSource(), "table data is correct");
if (testdata.couldBeOutOfOrder) {
data = data.map(e => e.toSource()).sort().join(",");
let expected = testdata.data.map(e => e.toSource()).sort().join(",");
is(data, expected, "table data is correct");
} else {
is(data.toSource(), testdata.data.toSource(), "table data is correct");
}
ok(obj._columns, "found table column object");
is(obj._columns.toSource(), testdata.columns.toSource(),
"table column is correct");

Просмотреть файл

@ -36,6 +36,9 @@ var typedarray1 = new Int32Array([1, 287, 8651, 40983, 8754]);
var set1 = new Set([1, 2, null, array3, "a", "b", undefined, document.head]);
set1.add(set1);
var bunnies = new String("bunnies")
var weakset = new WeakSet([bunnies, document.head]);
var testobj2 = {a: "b", c: "d", e: 1, f: "2"};
testobj2.foo = testobj1;
testobj2.bar = testobj2;
@ -56,6 +59,8 @@ Object.defineProperty(testobj4, "nonEnumerable", { value: "hello world" });
var map1 = new Map([["a", "b"], [document.body.children, testobj2]]);
map1.set(map1, set1);
var weakmap = new WeakMap([[bunnies, 23], [document.body.children, testobj2]]);
</script>
</body>
</html>

Просмотреть файл

@ -44,6 +44,17 @@
mySet.add("some text");
mySet.add(null);
mySet.add(undefined);
// These are globals and so won't be reclaimed by the GC.
var bunnies = new String("bunnies");
var lizards = new String("lizards");
var weakmap = new WeakMap();
weakmap.set(bunnies, 23);
weakmap.set(lizards, "oh no");
var weakset = new WeakSet([bunnies, lizards]);
</script>
</head>
<body>

Просмотреть файл

@ -11,7 +11,7 @@ var { TabSources } = require("./utils/TabSources");
var makeDebugger = require("./utils/make-debugger");
var { ConsoleAPIListener } = require("devtools/shared/webconsole/utils");
var DevToolsUtils = require("devtools/shared/DevToolsUtils");
var { dbg_assert, update } = DevToolsUtils;
var { assert, update } = DevToolsUtils;
loader.lazyRequireGetter(this, "AddonThreadActor", "devtools/server/actors/script", true);
loader.lazyRequireGetter(this, "unwrapDebuggerObjectGlobal", "devtools/server/actors/script", true);
@ -64,7 +64,7 @@ BrowserAddonActor.prototype = {
get sources() {
if (!this._sources) {
dbg_assert(this.threadActor, "threadActor should exist when creating sources.");
assert(this.threadActor, "threadActor should exist when creating sources.");
this._sources = new TabSources(this.threadActor, this._allowSource);
}
return this._sources;
@ -72,7 +72,7 @@ BrowserAddonActor.prototype = {
form: function BAA_form() {
dbg_assert(this.actorID, "addon should have an actorID.");
assert(this.actorID, "addon should have an actorID.");
if (!this._consoleActor) {
this._consoleActor = new AddonConsoleActor(this._addon, this.conn, this);
this._contextPool.addActor(this._consoleActor);

Просмотреть файл

@ -11,7 +11,7 @@ const { WebConsoleActor } = require("devtools/server/actors/webconsole");
const makeDebugger = require("devtools/server/actors/utils/make-debugger");
const { ActorPool } = require("devtools/server/main");
const Services = require("Services");
const { dbg_assert } = require("devtools/shared/DevToolsUtils");
const { assert } = require("devtools/shared/DevToolsUtils");
const { TabSources } = require("./utils/TabSources");
function ChildProcessActor(aConnection) {
@ -56,7 +56,7 @@ ChildProcessActor.prototype = {
get sources() {
if (!this._sources) {
dbg_assert(this.threadActor, "threadActor should exist when creating sources.");
assert(this.threadActor, "threadActor should exist when creating sources.");
this._sources = new TabSources(this.threadActor);
}
return this._sources;

Просмотреть файл

@ -10,9 +10,11 @@ const { Cu, Ci } = require("chrome");
const { GeneratedLocation } = require("devtools/server/actors/common");
const { DebuggerServer } = require("devtools/server/main")
const DevToolsUtils = require("devtools/shared/DevToolsUtils");
const { dbg_assert, dumpn } = DevToolsUtils;
const { assert, dumpn } = DevToolsUtils;
const PromiseDebugging = require("PromiseDebugging");
loader.lazyRequireGetter(this, "ThreadSafeChromeUtils");
const TYPED_ARRAY_CLASSES = ["Uint8Array", "Uint8ClampedArray", "Uint16Array",
"Uint32Array", "Int8Array", "Int16Array", "Int32Array", "Float32Array",
"Float64Array"];
@ -54,8 +56,8 @@ function ObjectActor(obj, {
decrementGripDepth,
getGlobalDebugObject
}) {
dbg_assert(!obj.optimizedOut,
"Should not create object actors for optimized out values!");
assert(!obj.optimizedOut,
"Should not create object actors for optimized out values!");
this.obj = obj;
this.hooks = {
createValueGrip,
@ -1067,6 +1069,43 @@ DebuggerServer.ObjectActorPreviewers = {
return true;
}],
WeakSet: [function({obj, hooks}, grip) {
let raw = obj.unsafeDereference();
// We currently lack XrayWrappers for WeakSet, so when we iterate over
// the values, the temporary iterator objects get created in the target
// compartment. However, we _do_ have Xrays to Object now, so we end up
// Xraying those temporary objects, and filtering access to |it.value|
// based on whether or not it's Xrayable and/or callable, which breaks
// the for/of iteration.
//
// This code is designed to handle untrusted objects, so we can safely
// waive Xrays on the iterable, and relying on the Debugger machinery to
// make sure we handle the resulting objects carefully.
let keys = Cu.waiveXrays(ThreadSafeChromeUtils.nondeterministicGetWeakSetKeys(raw));
grip.preview = {
kind: "ArrayLike",
length: keys.length,
};
// Avoid recursive object grips.
if (hooks.getGripDepth() > 1) {
return true;
}
let items = grip.preview.items = [];
for (let item of keys) {
item = Cu.unwaiveXrays(item);
item = makeDebuggeeValueIfNeeded(obj, item);
items.push(hooks.createValueGrip(item));
if (items.length == OBJECT_PREVIEW_MAX_ITEMS) {
break;
}
}
return true;
}],
Map: [function({obj, hooks}, grip) {
let size = DevToolsUtils.getProperty(obj, "size");
if (typeof size != "number") {
@ -1111,6 +1150,45 @@ DebuggerServer.ObjectActorPreviewers = {
return true;
}],
WeakMap: [function({obj, hooks}, grip) {
let raw = obj.unsafeDereference();
// We currently lack XrayWrappers for WeakMap, so when we iterate over
// the values, the temporary iterator objects get created in the target
// compartment. However, we _do_ have Xrays to Object now, so we end up
// Xraying those temporary objects, and filtering access to |it.value|
// based on whether or not it's Xrayable and/or callable, which breaks
// the for/of iteration.
//
// This code is designed to handle untrusted objects, so we can safely
// waive Xrays on the iterable, and relying on the Debugger machinery to
// make sure we handle the resulting objects carefully.
let rawEntries = Cu.waiveXrays(ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(raw));
grip.preview = {
kind: "MapLike",
size: rawEntries.length,
};
if (hooks.getGripDepth() > 1) {
return true;
}
let entries = grip.preview.entries = [];
for (let key of rawEntries) {
let value = Cu.unwaiveXrays(WeakMap.prototype.get.call(raw, key));
key = Cu.unwaiveXrays(key);
key = makeDebuggeeValueIfNeeded(obj, key);
value = makeDebuggeeValueIfNeeded(obj, value);
entries.push([hooks.createValueGrip(key),
hooks.createValueGrip(value)]);
if (entries.length == OBJECT_PREVIEW_MAX_ITEMS) {
break;
}
}
return true;
}],
DOMStringMap: [function({obj, hooks}, grip, rawObj) {
if (!rawObj) {
return false;
@ -1923,7 +2001,7 @@ function createValueGrip(value, pool, makeObjectGrip) {
return form;
default:
dbg_assert(false, "Failed to provide a grip for: " + value);
assert(false, "Failed to provide a grip for: " + value);
return null;
}
}

Просмотреть файл

@ -29,7 +29,7 @@
importScripts("resource://devtools/shared/worker/helper.js");
importScripts("resource://devtools/acorn/acorn.js");
importScripts("resource://devtools/sourcemap/source-map.js");
importScripts("resource://devtools/shared/sourcemap/source-map.js");
importScripts("resource://devtools/shared/pretty-fast/pretty-fast.js");
workerHelper.createTask(self, "pretty-print", ({ url, indent, source }) => {

Просмотреть файл

@ -12,7 +12,7 @@ const { ActorPool, OriginalLocation, GeneratedLocation } = require("devtools/ser
const { ObjectActor, createValueGrip, longStringGrip } = require("devtools/server/actors/object");
const { DebuggerServer } = require("devtools/server/main");
const DevToolsUtils = require("devtools/shared/DevToolsUtils");
const { dbg_assert, dumpn, update, fetch } = DevToolsUtils;
const { assert, dbg_assert, dumpn, update, fetch } = DevToolsUtils;
const { dirname, joinURI } = require("devtools/shared/path");
const promise = require("promise");
const PromiseDebugging = require("PromiseDebugging");
@ -354,8 +354,7 @@ EventLoop.prototype = {
}
}
dbg_assert(this._thread.state === "running",
"Should be in the running state");
dbg_assert(this._thread.state === "running", "Should be in the running state");
if (this._hooks.postNest) {
this._hooks.postNest(nestData);
@ -545,7 +544,7 @@ ThreadActor.prototype = {
},
_popThreadPause: function () {
const eventLoop = this._threadPauseEventLoops.pop();
dbg_assert(eventLoop, "Should have an event loop.");
assert(eventLoop, "Should have an event loop.");
eventLoop.resolve();
},
@ -1536,7 +1535,7 @@ ThreadActor.prototype = {
// Create the actor pool that will hold the pause actor and its
// children.
dbg_assert(!this._pausePool, "No pause pool should exist yet");
assert(!this._pausePool, "No pause pool should exist yet");
this._pausePool = new ActorPool(this.conn);
this.conn.addActorPool(this._pausePool);
@ -1545,7 +1544,7 @@ ThreadActor.prototype = {
this._pausePool.threadActor = this;
// Create the pause actor itself...
dbg_assert(!this._pauseActor, "No pause actor should exist yet");
assert(!this._pauseActor, "No pause actor should exist yet");
this._pauseActor = new PauseActor(this._pausePool);
this._pausePool.addActor(this._pauseActor);
@ -3319,8 +3318,7 @@ BreakpointActor.prototype = {
message: message
};
} else if (completion.yield) {
dbg_assert(false,
"Shouldn't ever get yield completions from an eval");
assert(false, "Shouldn't ever get yield completions from an eval");
} else {
return { result: completion.return ? true : false };
}
@ -3722,7 +3720,7 @@ exports.AddonThreadActor = AddonThreadActor;
*/
var oldReportError = reportError;
reportError = function(aError, aPrefix="") {
dbg_assert(aError instanceof Error, "Must pass Error objects to reportError");
assert(aError instanceof Error, "Must pass Error objects to reportError");
let msg = aPrefix + aError.message + ":\n" + aError.stack;
oldReportError(msg);
dumpn(msg);

Просмотреть файл

@ -7,7 +7,7 @@
const { Ci, Cu } = require("chrome");
const Services = require("Services");
const DevToolsUtils = require("devtools/shared/DevToolsUtils");
const { dbg_assert, fetch } = DevToolsUtils;
const { assert, fetch } = DevToolsUtils;
const EventEmitter = require("devtools/shared/event-emitter");
const { OriginalLocation, GeneratedLocation } = require("devtools/server/actors/common");
const { resolve } = require("promise");
@ -102,9 +102,9 @@ TabSources.prototype = {
* @returns a SourceActor representing the source or null.
*/
source: function ({ source, originalUrl, generatedSource,
isInlineSource, contentType }) {
dbg_assert(source || (originalUrl && generatedSource),
"TabSources.prototype.source needs an originalUrl or a source");
isInlineSource, contentType }) {
assert(source || (originalUrl && generatedSource),
"TabSources.prototype.source needs an originalUrl or a source");
if (source) {
// If a source is passed, we are creating an actor for a real
@ -765,7 +765,7 @@ TabSources.prototype = {
* Normalize multiple relative paths towards the base paths on the right.
*/
_normalize: function (...aURLs) {
dbg_assert(aURLs.length > 1, "Should have more than 1 URL");
assert(aURLs.length > 1, "Should have more than 1 URL");
let base = Services.io.newURI(aURLs.pop(), null, null);
let url;
while ((url = aURLs.pop())) {

Просмотреть файл

@ -41,6 +41,7 @@ const GRAPHENE_ID = "{d1bfe7d9-c01e-4237-998b-7b5f960a4314}";
module.exports = function mapURIToAddonID(uri, id) {
if (!Services.appinfo
|| Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT
|| Services.appinfo.ID === undefined /* XPCShell */
|| Services.appinfo.ID == B2G_ID
|| Services.appinfo.ID == GRAPHENE_ID
|| !uri

Просмотреть файл

@ -12,7 +12,7 @@ var promise = require("promise");
var { ActorPool, createExtraActors, appendExtraActors } = require("devtools/server/actors/common");
var { DebuggerServer } = require("devtools/server/main");
var DevToolsUtils = require("devtools/shared/DevToolsUtils");
var { assert, dbg_assert } = DevToolsUtils;
var { assert } = DevToolsUtils;
var { TabSources } = require("./utils/TabSources");
var makeDebugger = require("./utils/make-debugger");
@ -345,8 +345,7 @@ BrowserTabList.prototype._getActorForBrowser = function(browser) {
this._checkListening();
return actor.connect();
} else {
actor = new BrowserTabActor(this._connection, browser,
browser.getTabBrowser());
actor = new BrowserTabActor(this._connection, browser);
this._actorByBrowser.set(browser, actor);
this._checkListening();
return promise.resolve(actor);
@ -894,7 +893,7 @@ TabActor.prototype = {
get sources() {
if (!this._sources) {
dbg_assert(this.threadActor, "threadActor should exist when creating sources.");
assert(this.threadActor, "threadActor should exist when creating sources.");
this._sources = new TabSources(this.threadActor);
}
return this._sources;
@ -1847,20 +1846,21 @@ exports.TabActor = TabActor;
/**
* Creates a tab actor for handling requests to a single in-process
* <browser> tab. Most of the implementation comes from TabActor.
* <xul:browser> tab, or <html:iframe>.
* Most of the implementation comes from TabActor.
*
* @param aConnection DebuggerServerConnection
* The connection to the client.
* @param aBrowser browser
* The browser instance that contains this tab.
* @param aTabBrowser tabbrowser
* The tabbrowser that can receive nsIWebProgressListener events.
* The frame instance that contains this tab.
*/
function BrowserTabActor(aConnection, aBrowser, aTabBrowser)
function BrowserTabActor(aConnection, aBrowser)
{
TabActor.call(this, aConnection, aBrowser);
this._browser = aBrowser;
this._tabbrowser = aTabBrowser;
if (typeof(aBrowser.getTabBrowser) == "function") {
this._tabbrowser = aBrowser.getTabBrowser();
}
Object.defineProperty(this, "docShell", {
value: this._browser.docShell,

Просмотреть файл

@ -17,7 +17,7 @@ var { ActorPool, OriginalLocation, RegisteredActorFactory,
var { LocalDebuggerTransport, ChildDebuggerTransport, WorkerDebuggerTransport } =
require("devtools/shared/transport/transport");
var DevToolsUtils = require("devtools/shared/DevToolsUtils");
var { dumpn, dumpv, dbg_assert } = DevToolsUtils;
var { dumpn, dumpv } = DevToolsUtils;
var EventEmitter = require("devtools/shared/event-emitter");
var Debugger = require("Debugger");
var Promise = require("promise");
@ -43,7 +43,6 @@ this.ActorPool = ActorPool;
this.DevToolsUtils = DevToolsUtils;
this.dumpn = dumpn;
this.dumpv = dumpv;
this.dbg_assert = dbg_assert;
// Overload `Components` to prevent SDK loader exception on Components
// object usage

Просмотреть файл

@ -251,13 +251,6 @@ function scriptErrorFlagsToKind(aFlags) {
return kind;
}
// Redeclare dbg_assert with a fatal behavior.
function dbg_assert(cond, e) {
if (!cond) {
throw e;
}
}
// Register a console listener, so console messages don't just disappear
// into the ether.
var errorCount = 0;

Просмотреть файл

@ -12,6 +12,8 @@ add_task(function*() {
let client = yield startTestDebuggerServer("promises-actor-test");
let chromeActors = yield getChromeActors(client);
// We have to attach the chrome TabActor before playing with the PromiseActor
yield attachTab(client, chromeActors);
yield testAttach(client, chromeActors);
let response = yield listTabs(client);

Просмотреть файл

@ -15,6 +15,8 @@ add_task(function*() {
let client = yield startTestDebuggerServer("promises-actor-test");
let chromeActors = yield getChromeActors(client);
// We have to attach the chrome TabActor before playing with the PromiseActor
yield attachTab(client, chromeActors);
yield testListPromises(client, chromeActors, v =>
new Promise(resolve => resolve(v)));

Просмотреть файл

@ -18,6 +18,8 @@ add_task(function*() {
ok(Promise.toString().contains("native code"), "Expect native DOM Promise");
// We have to attach the chrome TabActor before playing with the PromiseActor
yield attachTab(client, chromeActors);
yield testNewPromisesEvent(client, chromeActors,
v => new Promise(resolve => resolve(v)));

Просмотреть файл

@ -18,6 +18,8 @@ add_task(function*() {
ok(Promise.toString().contains("native code"), "Expect native DOM Promise");
// We have to attach the chrome TabActor before playing with the PromiseActor
yield attachTab(client, chromeActors);
yield testPromisesSettled(client, chromeActors,
v => new Promise(resolve => resolve(v)),
v => new Promise((resolve, reject) => reject(v)));

Просмотреть файл

@ -17,6 +17,8 @@ add_task(function*() {
ok(Promise.toString().contains("native code"), "Expect native DOM Promise.");
// We have to attach the chrome TabActor before playing with the PromiseActor
yield attachTab(client, chromeActors);
yield testPromiseCreationTimestamp(client, chromeActors, v => {
return new Promise(resolve => resolve(v));
});

Просмотреть файл

@ -18,6 +18,8 @@ add_task(function*() {
ok(Promise.toString().contains("native code"), "Expect native DOM Promise.");
// We have to attach the chrome TabActor before playing with the PromiseActor
yield attachTab(client, chromeActors);
yield testGetTimeToSettle(client, chromeActors, () => {
let p = new Promise(() => {});
p.name = "p";

Просмотреть файл

@ -19,6 +19,8 @@ add_task(function*() {
ok(Promise.toString().contains("native code"), "Expect native DOM Promise.");
// We have to attach the chrome TabActor before playing with the PromiseActor
yield attachTab(client, chromeActors);
yield testGetTimeToSettle(client, chromeActors,
v => new Promise(resolve => setTimeout(() => resolve(v), 100)));

Просмотреть файл

@ -459,6 +459,9 @@ exports.dbg_assert = function dbg_assert(cond, e) {
};
exports.defineLazyGetter(this, "AppConstants", () => {
if (isWorker) {
return {};
}
const scope = {};
Cu.import("resource://gre/modules/AppConstants.jsm", scope);
return scope.AppConstants;

Просмотреть файл

@ -95,7 +95,7 @@ BuiltinProvider.prototype = {
// ⚠ DISCUSSION ON DEV-DEVELOPER-TOOLS REQUIRED BEFORE MODIFYING ⚠
"acorn/util/walk": "resource://devtools/acorn/walk.js",
// ⚠ DISCUSSION ON DEV-DEVELOPER-TOOLS REQUIRED BEFORE MODIFYING ⚠
"source-map": "resource://devtools/sourcemap/source-map.js",
"source-map": "resource://devtools/shared/sourcemap/source-map.js",
// ⚠ DISCUSSION ON DEV-DEVELOPER-TOOLS REQUIRED BEFORE MODIFYING ⚠
// Allow access to xpcshell test items from the loader.
"xpcshell-test": "resource://test"

Просмотреть файл

@ -6,6 +6,6 @@
XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
FINAL_TARGET_FILES.chrome.devtools.modules.devtools.sourcemap += [
'source-map.js',
]
DevToolsModules(
'source-map.js'
)

Просмотреть файл

@ -53,13 +53,6 @@ function scriptErrorFlagsToKind(aFlags) {
return kind;
}
// Redeclare dbg_assert with a fatal behavior.
function dbg_assert(cond, e) {
if (!cond) {
throw e;
}
}
// Register a console listener, so console messages don't just disappear
// into the ether.
var errorCount = 0;

Просмотреть файл

@ -503,11 +503,9 @@ this.worker = new WorkerDebuggerLoader({
// ⚠ DISCUSSION ON DEV-DEVELOPER-TOOLS REQUIRED BEFORE MODIFYING ⚠
"devtools": "resource://devtools",
// ⚠ DISCUSSION ON DEV-DEVELOPER-TOOLS REQUIRED BEFORE MODIFYING ⚠
"devtools/client": "resource://devtools/client",
// ⚠ DISCUSSION ON DEV-DEVELOPER-TOOLS REQUIRED BEFORE MODIFYING ⚠
"promise": "resource://gre/modules/Promise-backend.js",
// ⚠ DISCUSSION ON DEV-DEVELOPER-TOOLS REQUIRED BEFORE MODIFYING ⚠
"source-map": "resource://devtools/sourcemap/source-map.js",
"source-map": "resource://devtools/shared/sourcemap/source-map.js",
// ⚠ DISCUSSION ON DEV-DEVELOPER-TOOLS REQUIRED BEFORE MODIFYING ⚠
"xpcshell-test": "resource://test"
// ⚠ DISCUSSION ON DEV-DEVELOPER-TOOLS REQUIRED BEFORE MODIFYING ⚠

Просмотреть файл

@ -30,6 +30,26 @@ ThreadSafeChromeUtils::NondeterministicGetWeakMapKeys(GlobalObject& aGlobal,
}
}
/* static */ void
ThreadSafeChromeUtils::NondeterministicGetWeakSetKeys(GlobalObject& aGlobal,
JS::Handle<JS::Value> aSet,
JS::MutableHandle<JS::Value> aRetval,
ErrorResult& aRv)
{
if (!aSet.isObject()) {
aRetval.setUndefined();
} else {
JSContext* cx = aGlobal.Context();
JS::Rooted<JSObject*> objRet(cx);
JS::Rooted<JSObject*> setObj(cx, &aSet.toObject());
if (!JS_NondeterministicGetWeakSetKeys(cx, setObj, &objRet)) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
} else {
aRetval.set(objRet ? JS::ObjectValue(*objRet) : JS::UndefinedValue());
}
}
}
/* static */ void
ChromeUtils::OriginAttributesToSuffix(dom::GlobalObject& aGlobal,
const dom::OriginAttributesDictionary& aAttrs,

Просмотреть файл

@ -38,6 +38,11 @@ public:
JS::Handle<JS::Value> aMap,
JS::MutableHandle<JS::Value> aRetval,
ErrorResult& aRv);
static void NondeterministicGetWeakSetKeys(GlobalObject& aGlobal,
JS::Handle<JS::Value> aSet,
JS::MutableHandle<JS::Value> aRetval,
ErrorResult& aRv);
};
class ChromeUtils : public ThreadSafeChromeUtils

Просмотреть файл

@ -43,6 +43,18 @@ interface ThreadSafeChromeUtils {
*/
[Throws, NewObject]
static any nondeterministicGetWeakMapKeys(any map);
/**
* Return the keys in a weak set. This operation is
* non-deterministic because it is affected by the scheduling of the
* garbage collector and the cycle collector.
*
* @param aSet weak set or other JavaScript value
* @returns If aSet is a weak set object, return the keys of the weak
* set as an array. Otherwise, return undefined.
*/
[Throws, NewObject]
static any nondeterministicGetWeakSetKeys(any aSet);
};
/**

Просмотреть файл

@ -761,6 +761,7 @@ void
ClientLayerManager::GetBackendName(nsAString& aName)
{
switch (mForwarder->GetCompositorBackendType()) {
case LayersBackend::LAYERS_NONE: aName.AssignLiteral("None"); return;
case LayersBackend::LAYERS_BASIC: aName.AssignLiteral("Basic"); return;
case LayersBackend::LAYERS_OPENGL: aName.AssignLiteral("OpenGL"); return;
case LayersBackend::LAYERS_D3D9: aName.AssignLiteral("Direct3D 9"); return;

Просмотреть файл

@ -0,0 +1,4 @@
[DEFAULT]
support-files =
[browser_windowless_troubleshoot_crash.js]

Просмотреть файл

@ -0,0 +1,43 @@
let { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
add_task(function* test_windowlessBrowserTroubleshootCrash() {
let webNav = Services.appShell.createWindowlessBrowser(false);
let onLoaded = new Promise((resolve, reject) => {
let docShell = webNav.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell);
let listener = {
observe(contentWindow, topic, data) {
let observedDocShell = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.sameTypeRootTreeItem
.QueryInterface(Ci.nsIDocShell);
if (docShell === observedDocShell) {
Services.obs.removeObserver(listener, "content-document-global-created", false);
resolve();
}
}
}
Services.obs.addObserver(listener, "content-document-global-created", false);
});
webNav.loadURI("about:blank", 0, null, null, null);
yield onLoaded;
let winUtils = webNav.document.defaultView.
QueryInterface(Ci.nsIInterfaceRequestor).
getInterface(Ci.nsIDOMWindowUtils);
is(winUtils.layerManagerType, "None", "windowless browser's layerManagerType should be 'None'");
ok(true, "not crashed");
var Troubleshoot = Cu.import("resource://gre/modules/Troubleshoot.jsm", {}).Troubleshoot;
var data = yield new Promise((resolve, reject) => {
Troubleshoot.snapshot((data) => {
resolve(data);
});
});
ok(data.graphics.windowLayerManagerType !== "None", "windowless browser window should not set windowLayerManagerType to 'None'");
});

Просмотреть файл

@ -6,3 +6,4 @@
XPCSHELL_TESTS_MANIFESTS += ['unit/xpcshell.ini']
MOCHITEST_MANIFESTS += ['mochitest/mochitest.ini']
BROWSER_CHROME_MANIFESTS += ['browser/browser.ini']

Просмотреть файл

@ -156,3 +156,21 @@ js::InitWeakSetClass(JSContext* cx, HandleObject obj)
{
return WeakSetObject::initClass(cx, obj);
}
JS_FRIEND_API(bool)
JS_NondeterministicGetWeakSetKeys(JSContext* cx, HandleObject objArg, MutableHandleObject ret)
{
RootedObject obj(cx, objArg);
obj = UncheckedUnwrap(obj);
if (!obj || !obj->is<WeakSetObject>()) {
ret.set(nullptr);
return true;
}
Rooted<WeakSetObject*> weakset(cx, &obj->as<WeakSetObject>());
if (!weakset)
return false;
RootedObject map(cx, &weakset->getReservedSlot(WEAKSET_MAP_SLOT).toObject());
return JS_NondeterministicGetWeakMapKeys(cx, map, ret);
}

Просмотреть файл

@ -81,6 +81,9 @@ JS_GetCustomIteratorCount(JSContext* cx);
extern JS_FRIEND_API(bool)
JS_NondeterministicGetWeakMapKeys(JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject ret);
extern JS_FRIEND_API(bool)
JS_NondeterministicGetWeakSetKeys(JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject ret);
// Raw JSScript* because this needs to be callable from a signal handler.
extern JS_FRIEND_API(unsigned)
JS_PCToLineNumber(JSScript* script, jsbytecode* pc, unsigned* columnp = nullptr);

Просмотреть файл

@ -0,0 +1,45 @@
/* 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/. */
/* See https://bugzilla.mozilla.org/show_bug.cgi?id=1165807 */
function run_test()
{
var bunnies = new String("bunnies");
var lizards = new String("lizards");
var weakset = new WeakSet([bunnies, lizards]);
var weakmap = new WeakMap();
weakmap.set(bunnies, 23);
weakmap.set(lizards, "oh no");
var keys = ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(bunnies);
equal(keys, undefined, "test nondeterministicGetWeakMapKeys on non-WeakMap");
keys = ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(weakmap);
equal(keys.length, 2, "length of nondeterministicGetWeakMapKeys");
equal(weakmap.get(bunnies), 23, "check bunnies in weakmap");
equal(weakmap.get(lizards), "oh no", "check lizards in weakmap");
keys = ThreadSafeChromeUtils.nondeterministicGetWeakSetKeys(bunnies);
equal(keys, undefined, "test nondeterministicGetWeakSetKeys on non-WeakMap");
keys = ThreadSafeChromeUtils.nondeterministicGetWeakSetKeys(weakset);
equal(keys.length, 2, "length of nondeterministicGetWeakSetKeys");
ok(weakset.has(bunnies), "check bunnies in weakset");
ok(weakset.has(lizards), "check lizards in weakset");
bunnies = null;
keys = null;
Components.utils.forceGC();
keys = ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(weakmap);
equal(keys.length, 1, "length of nondeterministicGetWeakMapKeys after GC");
equal(weakmap.get(lizards), "oh no", "check lizards still in weakmap");
keys = ThreadSafeChromeUtils.nondeterministicGetWeakSetKeys(weakset);
equal(keys.length, 1, "length of nondeterministicGetWeakSetKeys after GC");
ok(weakset.has(lizards), "check lizards still in weakset");
}

Просмотреть файл

@ -126,6 +126,7 @@ head = head_watchdog.js
head = head_watchdog.js
[test_watchdog_hibernate.js]
head = head_watchdog.js
[test_weak_keys.js]
[test_writeToGlobalPrototype.js]
[test_xpcwn_tamperproof.js]
[test_xrayed_iterator.js]

Просмотреть файл

@ -1101,7 +1101,7 @@ PeerConnectionImpl::ConfigureJsepSessionCodecs() {
NS_IMETHODIMP
PeerConnectionImpl::EnsureDataConnection(uint16_t aNumstreams)
{
PC_AUTO_ENTER_API_CALL_NO_CHECK();
PC_AUTO_ENTER_API_CALL(false);
#if !defined(MOZILLA_EXTERNAL_LINKAGE)
if (mDataConnection) {
@ -1249,7 +1249,7 @@ PeerConnectionImpl::AddTrackToJsepSession(SdpMediaSection::MediaType type,
nsresult
PeerConnectionImpl::InitializeDataChannel()
{
PC_AUTO_ENTER_API_CALL_NO_CHECK();
PC_AUTO_ENTER_API_CALL(false);
CSFLogDebug(logTag, "%s", __FUNCTION__);
const JsepApplicationCodecDescription* codec;
@ -1331,7 +1331,7 @@ PeerConnectionImpl::CreateDataChannel(const nsAString& aLabel,
uint16_t aStream,
nsDOMDataChannel** aRetval)
{
PC_AUTO_ENTER_API_CALL_NO_CHECK();
PC_AUTO_ENTER_API_CALL(false);
MOZ_ASSERT(aRetval);
#if !defined(MOZILLA_EXTERNAL_LINKAGE)

Просмотреть файл

@ -762,11 +762,6 @@ pref("layers.enable-tiles", true);
// Enable the dynamic toolbar
pref("browser.chrome.dynamictoolbar", true);
// The mode of browser titlebar
// 0: Show a current page title.
// 1: Show a current page url.
pref("browser.chrome.titlebarMode", 1);
// Hide common parts of URLs like "www." or "http://"
pref("browser.urlbar.trimURLs", true);

Просмотреть файл

@ -294,6 +294,7 @@ public class CrashHandler implements Thread.UncaughtExceptionHandler {
final Intent intent = new Intent(action);
intent.setComponent(new ComponentName(pkg, component));
intent.putExtra("minidumpPath", dumpFile);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
return true;
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше