Merge mozilla-central to mozilla-inbound
|
@ -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)
|
||||
});
|
Двоичные данные
browser/themes/linux/customizableui/thumburger-inverted.png
До Ширина: | Высота: | Размер: 411 B |
Двоичные данные
browser/themes/linux/customizableui/thumburger.png
До Ширина: | Высота: | Размер: 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)
|
||||
|
|
Двоичные данные
browser/themes/osx/customizableui/thumburger-inverted.png
До Ширина: | Высота: | Размер: 427 B |
Двоичные данные
browser/themes/osx/customizableui/thumburger-inverted@2x.png
До Ширина: | Высота: | Размер: 809 B |
Двоичные данные
browser/themes/osx/customizableui/thumburger-yosemite.png
До Ширина: | Высота: | Размер: 263 B |
Двоичные данные
browser/themes/osx/customizableui/thumburger-yosemite@2x.png
До Ширина: | Высота: | Размер: 477 B |
Двоичные данные
browser/themes/osx/customizableui/thumburger.png
До Ширина: | Высота: | Размер: 388 B |
Двоичные данные
browser/themes/osx/customizableui/thumburger@2x.png
До Ширина: | Высота: | Размер: 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,
|
||||
|
|
Двоичные данные
browser/themes/windows/customizableui/thumburger-XP.png
До Ширина: | Высота: | Размер: 610 B |
Двоичные данные
browser/themes/windows/customizableui/thumburger-XP@2x.png
До Ширина: | Высота: | Размер: 1.4 KiB |
Двоичные данные
browser/themes/windows/customizableui/thumburger-aero.png
До Ширина: | Высота: | Размер: 565 B |
Двоичные данные
browser/themes/windows/customizableui/thumburger-aero@2x.png
До Ширина: | Высота: | Размер: 1.2 KiB |
Двоичные данные
browser/themes/windows/customizableui/thumburger-inverted.png
До Ширина: | Высота: | Размер: 411 B |
Двоичные данные
browser/themes/windows/customizableui/thumburger-inverted@2x.png
До Ширина: | Высота: | Размер: 754 B |
Двоичные данные
browser/themes/windows/customizableui/thumburger-lunaSilver.png
До Ширина: | Высота: | Размер: 619 B |
До Ширина: | Высота: | Размер: 1.3 KiB |
Двоичные данные
browser/themes/windows/customizableui/thumburger-win8.png
До Ширина: | Высота: | Размер: 220 B |
Двоичные данные
browser/themes/windows/customizableui/thumburger-win8@2x.png
До Ширина: | Высота: | Размер: 379 B |
Двоичные данные
browser/themes/windows/customizableui/thumburger.png
До Ширина: | Высота: | Размер: 201 B |
Двоичные данные
browser/themes/windows/customizableui/thumburger@2x.png
До Ширина: | Высота: | Размер: 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;
|
||||
}
|
||||
|
|