This commit is contained in:
Ryan VanderMeulen 2014-12-05 19:16:21 -05:00
Родитель b6b0fc882e 5e0f31c0c5
Коммит 0d016bc066
85 изменённых файлов: 1025 добавлений и 153 удалений

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

@ -610,6 +610,9 @@ pref("app.update.log", true);
pref("shutdown.watchdog.timeoutSecs", -1);
#endif
// Allow webapps update checking
pref("webapps.update.enabled", true);
// Check daily for apps updates.
pref("webapps.update.interval", 86400);

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

@ -74,6 +74,11 @@ window.addEventListener('ContentStart', function() {
screenarg = args.handleFlagWithParam('screen', false);
}
// Override default screen size with a pref
if (screenarg === null && Services.prefs.prefHasUserValue('b2g.screen.size')) {
screenarg = Services.prefs.getCharPref('b2g.screen.size');
}
// If there isn't one, use the default screen
if (screenarg === null)
screenarg = DEFAULT_SCREEN;

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

@ -60,6 +60,15 @@ this.WebappsUpdater = {
return;
}
let allowUpdate = true;
try {
allowUpdate = Services.prefs.getBoolPref("webapps.update.enabled");
} catch (ex) { }
if (!allowUpdate) {
return;
}
this._checkingApps = true;
let self = this;

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="529c5fcd234ffd108b57629673ca97c2ef73376d"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="0e429d970c160e580e19e61ad8ff5612de159f00"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

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

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="529c5fcd234ffd108b57629673ca97c2ef73376d"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0e429d970c160e580e19e61ad8ff5612de159f00"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>

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

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="529c5fcd234ffd108b57629673ca97c2ef73376d"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="0e429d970c160e580e19e61ad8ff5612de159f00"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a3e4614c7fb0a6ffa8c748bf5d49b34612c9d6d4"/>
@ -136,7 +136,7 @@
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c5f8d282efe4a4e8b1e31a37300944e338e60e4f"/>
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9f28c4faea3b2f01db227b2467b08aeba96d9bec"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="b06bb64646c5a109856ad461ac91336f8edc2579"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="58567be92162a64b3bbcc1cce911a27ca935610f"/>
<project name="android-sdk" path="sdk" remote="b2g" revision="8b1365af38c9a653df97349ee53a3f5d64fd590a"/>
<project name="darwinstreamingserver" path="system/darwinstreamingserver" remote="b2g" revision="cf85968c7f85e0ec36e72c87ceb4837a943b8af6"/>
</manifest>

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="529c5fcd234ffd108b57629673ca97c2ef73376d"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="0e429d970c160e580e19e61ad8ff5612de159f00"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

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

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="529c5fcd234ffd108b57629673ca97c2ef73376d"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0e429d970c160e580e19e61ad8ff5612de159f00"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="529c5fcd234ffd108b57629673ca97c2ef73376d"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="0e429d970c160e580e19e61ad8ff5612de159f00"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
@ -155,7 +155,7 @@
<project name="platform/hardware/ril" path="hardware/ril" revision="12b1977cc704b35f2e9db2bb423fa405348bc2f3"/>
<project name="platform/system/bluetooth" path="system/bluetooth" revision="985bf15264d865fe7b9c5b45f61c451cbaafa43d"/>
<project name="platform/system/core" path="system/core" revision="350eac5403124dacb2a5fd9e28ac290a59fc3b8e"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="b06bb64646c5a109856ad461ac91336f8edc2579"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="58567be92162a64b3bbcc1cce911a27ca935610f"/>
<project name="platform/system/qcom" path="system/qcom" revision="63e3f6f176caad587d42bba4c16b66d953fb23c2"/>
<project name="platform/vendor/qcom-opensource/wlan/prima" path="vendor/qcom/opensource/wlan/prima" revision="d8952a42771045fca73ec600e2b42a4c7129d723"/>
<project name="platform/vendor/qcom/msm8610" path="device/qcom/msm8610" revision="018b44e52b2bac5d3631d559550e88a4b68c6e67"/>

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

@ -17,7 +17,7 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="529c5fcd234ffd108b57629673ca97c2ef73376d"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="0e429d970c160e580e19e61ad8ff5612de159f00"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a3e4614c7fb0a6ffa8c748bf5d49b34612c9d6d4"/>
@ -145,7 +145,7 @@
<project name="platform/hardware/ril" path="hardware/ril" revision="c4e2ac95907a5519a0e09f01a0d8e27fec101af0"/>
<project name="platform/system/bluetooth" path="system/bluetooth" revision="e1eb226fa3ad3874ea7b63c56a9dc7012d7ff3c2"/>
<project name="platform/system/core" path="system/core" revision="adc485d8755af6a61641d197de7cfef667722580"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="b06bb64646c5a109856ad461ac91336f8edc2579"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="58567be92162a64b3bbcc1cce911a27ca935610f"/>
<project name="platform/system/qcom" path="system/qcom" revision="1cdab258b15258b7f9657da70e6f06ebd5a2fc25"/>
<project name="platform/vendor/qcom/msm8610" path="device/qcom/msm8610" revision="4ae5df252123591d5b941191790e7abed1bce5a4"/>
<project name="platform/vendor/qcom-opensource/wlan/prima" path="vendor/qcom/opensource/wlan/prima" revision="ce18b47b4a4f93a581d672bbd5cb6d12fe796ca9"/>

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

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "cd198e4a55361d72002c22acf726ea10dbdc7e9f",
"revision": "5686a4726b2c90d5bd20cf96f8e97038cbe3f083",
"repo_path": "integration/gaia-central"
}

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

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="529c5fcd234ffd108b57629673ca97c2ef73376d"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0e429d970c160e580e19e61ad8ff5612de159f00"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>

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

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="529c5fcd234ffd108b57629673ca97c2ef73376d"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0e429d970c160e580e19e61ad8ff5612de159f00"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

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

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="529c5fcd234ffd108b57629673ca97c2ef73376d"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="0e429d970c160e580e19e61ad8ff5612de159f00"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a3e4614c7fb0a6ffa8c748bf5d49b34612c9d6d4"/>
@ -131,7 +131,7 @@
<project name="device-mako" path="device/lge/mako" remote="b2g" revision="78d17f0c117f0c66dd55ee8d5c5dde8ccc93ecba"/>
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="3a9a17613cc685aa232432566ad6cc607eab4ec1"/>
<project name="device/lge/mako-kernel" path="device/lge/mako-kernel" revision="d1729e53d71d711c8fde25eab8728ff2b9b4df0e"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="b06bb64646c5a109856ad461ac91336f8edc2579"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="58567be92162a64b3bbcc1cce911a27ca935610f"/>
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="7d33aaf740bbf6c7c6e9c34a92b371eda311b66b"/>
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
<project name="platform/hardware/broadcom/wlan" path="hardware/broadcom/wlan" revision="0e1929fa3aa38bf9d40e9e953d619fab8164c82e"/>

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

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="529c5fcd234ffd108b57629673ca97c2ef73376d"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0e429d970c160e580e19e61ad8ff5612de159f00"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

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

@ -1,2 +1,3 @@
user_pref("devtools.debugger.prompt-connection", false);
user_pref("devtools.debugger.forbid-certified-apps", false);
user_pref("devtools.apps.forbidden-permissions", "");

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

@ -1221,27 +1221,18 @@ toolbarpaletteitem[place="palette"][hidden] {
animation-duration: 2s;
}
#abouthome-search-panel .panel-arrowcontent {
-moz-padding-start: 0;
-moz-padding-end: 0;
padding-top: 0;
padding-bottom: 0;
background: rgb(248, 250, 251);
#abouthome-search-panel > .panel-arrowcontainer > .panel-arrowcontent {
padding: 0;
font-size: 110%;
}
.abouthome-search-panel-item {
-moz-box-align: center;
padding-top: 4px;
padding-bottom: 4px;
-moz-padding-start: 24px;
-moz-padding-end: 24px;
#abouthome-search-panel-manage {
padding: 4px 24px;
}
.abouthome-search-panel-item > label {
-moz-padding-start: 0;
-moz-margin-start: 0;
color: rgb(130, 132, 133);
#abouthome-search-panel-manage > label {
padding: 0;
margin: 0;
}
/* Combined context-menu items */

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

@ -278,7 +278,7 @@
<panel id="abouthome-search-panel" orient="vertical" type="arrow" hidden="true"
onclick="this.hidePopup()">
<hbox id="abouthome-search-panel-manage" class="abouthome-search-panel-item"
<hbox id="abouthome-search-panel-manage"
onclick="openPreferences('paneSearch')">
<label>&changeSearchSettings.button;</label>
</hbox>

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

@ -454,27 +454,20 @@ input[type=button] {
transition-duration: 0ms;
}
#newtab-customize-panel .panel-arrowcontent,
#newtab-search-panel .panel-arrowcontent {
-moz-padding-start: 0;
-moz-padding-end: 0;
padding-top: 0;
padding-bottom: 0;
background: rgb(248, 250, 251);
#newtab-customize-panel > .panel-arrowcontainer > .panel-arrowcontent,
#newtab-search-panel > .panel-arrowcontainer > .panel-arrowcontent {
padding: 0;
}
.newtab-customize-panel-item,
.newtab-search-panel-engine {
-moz-box-align: center;
padding-top: 4px;
padding-bottom: 4px;
-moz-padding-start: 24px;
-moz-padding-end: 24px;
.newtab-search-panel-engine,
#newtab-search-manage {
padding: 4px 24px;
}
.newtab-customize-panel-item:not(:last-child),
.newtab-search-panel-engine:not(:last-child) {
border-bottom: 1px solid #ccc;
.newtab-search-panel-engine {
border-bottom: 1px solid threedshadow;
}
.newtab-search-panel-engine > image {
@ -485,10 +478,10 @@ input[type=button] {
}
.newtab-customize-panel-item > label,
.newtab-search-panel-engine > label {
-moz-padding-start: 0;
-moz-margin-start: 0;
color: rgb(130, 132, 133);
.newtab-search-panel-engine > label,
#newtab-search-manage > label {
padding: 0;
margin: 0;
}
.newtab-customize-panel-item[selected],

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

@ -29,7 +29,7 @@
<xul:panel id="newtab-search-panel" orient="vertical" type="arrow"
noautohide="true" hidden="true">
<xul:hbox id="newtab-search-manage" class="newtab-search-panel-engine">
<xul:hbox id="newtab-search-manage">
<xul:label>&changeSearchSettings.button;</xul:label>
</xul:hbox>
</xul:panel>

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

@ -1659,6 +1659,9 @@
// allows the TabLabelModified event to be properly dispatched.
if (!aURI || isBlankPageURL(aURI)) {
t.label = this.mStringBundle.getString("tabs.emptyTabTitle");
} else if (aURI.toLowerCase().startsWith("javascript:")) {
// This can go away when bug 672618 or bug 55696 are fixed.
t.label = aURI;
}
this.tabContainer.updateVisibility();

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

@ -121,7 +121,7 @@ function setUpTest(aTestName, aIDForNextTest, aFuncForNextTest, aChildTabLink) {
mainTab = gTestWin.gBrowser.selectedTab;
// get the link for the next test from the main page
let target = gTestWin.content.document.getElementById(aIDForNextTest);
let target = gTestWin.content.document.getElementById(aIDForNextTest).href;
gTestWin.gBrowser.addTab(target);
gTestWin.gBrowser.selectTabAtIndex(1);
waitForSomeTabToLoad(checkPopUpNotification);

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

@ -130,7 +130,6 @@ skip-if = os == "linux"
skip-if = e10s # bug 1090635
[browser_981305_separator_insertion.js]
[browser_988072_sidebar_events.js]
skip-if = e10s # bug 1101482 - fails in --run-by-dir
[browser_989338_saved_placements_not_resaved.js]
[browser_989751_subviewbutton_class.js]
[browser_987177_destroyWidget_xul.js]

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

@ -80,8 +80,7 @@ let showSidebarPopup = Task.async(function*() {
let subviewShownPromise = subviewShown(subview);
EventUtils.synthesizeMouseAtCenter(button, {});
yield subviewShownPromise;
return waitForCondition(() => !subview.panelMultiView.hasAttribute("transitioning"));
return subviewShownPromise;
});
// Check the sidebar widget shows the default items

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

@ -537,6 +537,12 @@ loop.panel = (function(_, mozL10n) {
return {edit: false, text: this.props.text};
},
componentWillReceiveProps: function(nextProps) {
if (nextProps.text !== this.props.text) {
this.setState({text: nextProps.text});
}
},
handleTextClick: function(event) {
event.stopPropagation();
event.preventDefault();

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

@ -537,6 +537,12 @@ loop.panel = (function(_, mozL10n) {
return {edit: false, text: this.props.text};
},
componentWillReceiveProps: function(nextProps) {
if (nextProps.text !== this.props.text) {
this.setState({text: nextProps.text});
}
},
handleTextClick: function(event) {
event.stopPropagation();
event.preventDefault();

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

@ -391,8 +391,7 @@ loop.store.ActiveRoomStore = (function() {
this._leaveRoom(ROOM_STATES.CLOSING);
// If we're closing the window, we can stop listening to updates.
this._mozLoop.rooms.off("update:" + this.getStoreState().roomToken,
this._handleRoomUpdate.bind(this));
this._mozLoop.rooms.off("update:" + this.getStoreState().roomToken);
},
/**

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

@ -857,6 +857,25 @@ describe("loop.panel", function() {
new sharedActions.OpenRoom({roomToken: roomData.roomToken}));
});
});
describe("Room name updated", function() {
it("should update room name", function() {
var roomEntry = mountRoomEntry({
dispatcher: dispatcher,
room: new loop.store.Room(roomData)
});
var updatedRoom = new loop.store.Room(_.extend({}, roomData, {
roomName: "New room name",
ctime: new Date().getTime()
}));
roomEntry.setProps({room: updatedRoom});
expect(
roomEntry.getDOMNode().querySelector(".edit-in-place").textContent)
.eql("New room name");
});
});
});
describe("loop.panel.RoomList", function() {

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

@ -2,8 +2,8 @@
subsuite = devtools
support-files =
browser_fontinspector.html
ostrich-black.woff
ostrich-regular.woff
ostrich-black.ttf
ostrich-regular.ttf
head.js
[browser_fontinspector.js]

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

@ -3,12 +3,12 @@
<style>
@font-face {
font-family: bar;
src: url(bad/font/name.ttf), url(ostrich-regular.woff) format("woff");
src: url(bad/font/name.ttf), url(ostrich-regular.ttf) format("truetype");
}
@font-face {
font-family: bar;
font-weight: 800;
src: url(ostrich-black.woff);
src: url(ostrich-black.ttf);
}
body{

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

@ -47,10 +47,10 @@ function* testBodyFonts(inspector) {
ok(s[0].classList.contains("is-remote"),
"font 0: is remote");
is(s[0].querySelector(".font-url").value,
"http://mochi.test:8888/browser/browser/devtools/fontinspector/test/ostrich-regular.woff",
"http://mochi.test:8888/browser/browser/devtools/fontinspector/test/ostrich-regular.ttf",
"font 0: right url");
is(s[0].querySelector(".font-format").textContent,
"woff", "font 0: right font format");
"truetype", "font 0: right font format");
is(s[0].querySelector(".font-css-name").textContent,
"bar", "font 0: right css name");

Двоичные данные
browser/devtools/fontinspector/test/ostrich-black.ttf Executable file

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

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

Двоичные данные
browser/devtools/fontinspector/test/ostrich-regular.ttf Executable file

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

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

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

@ -93,6 +93,7 @@ browser.jar:
content/browser/devtools/performance/views/overview.js (performance/views/overview.js)
content/browser/devtools/performance/views/details.js (performance/views/details.js)
content/browser/devtools/performance/views/call-tree.js (performance/views/call-tree.js)
content/browser/devtools/performance/views/waterfall.js (performance/views/waterfall.js)
#endif
content/browser/devtools/responsivedesign/resize-commands.js (responsivedesign/resize-commands.js)
content/browser/devtools/commandline.css (commandline/commandline.css)

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

@ -2317,7 +2317,7 @@ ElementEditor.prototype = {
* Called when the tag name editor has is done editing.
*/
onTagEdit: function(newTagName, isCommit) {
if (!isCommit || newTagName == this.node.tagName ||
if (!isCommit || newTagName.toLowerCase() === this.node.tagName.toLowerCase() ||
!("editTagName" in this.markup.walker)) {
return;
}

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

@ -81,6 +81,7 @@ skip-if = e10s # Bug 1036409 - The last selected node isn't reselected
[browser_markupview_tag_edit_08.js]
[browser_markupview_tag_edit_09.js]
[browser_markupview_tag_edit_10.js]
[browser_markupview_tag_edit_11.js]
[browser_markupview_textcontent_edit_01.js]
[browser_markupview_toggle_01.js]
[browser_markupview_toggle_02.js]

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

@ -0,0 +1,36 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Bug 1090874 - Tests that a node is not recreated when it's tagname editor
// is blurred and no changes were done.
const TEST_URL = "data:text/html;charset=utf-8,<div></div>";
let test = asyncTest(function*() {
let isEditTagNameCalled = false;
let {toolbox, inspector} = yield addTab(TEST_URL).then(openInspector);
// Overriding the editTagName walkerActor method here to check that it isn't
// called when blurring the tagname field.
inspector.walker.editTagName = function() { isEditTagNameCalled = true; }
yield selectNode("div", inspector);
let container = yield getContainerForSelector("div", inspector);
let tagEditor = container.editor.tag;
info("Blurring the tagname field");
tagEditor.blur();
is(isEditTagNameCalled, false, "The editTagName method wasn't called");
info("Updating the tagname to uppercase");
setEditableFieldValue(tagEditor, "DIV", inspector);
is(isEditTagNameCalled, false, "The editTagName method wasn't called");
info("Updating the tagname to a different value");
setEditableFieldValue(tagEditor, "SPAN", inspector);
is(isEditTagNameCalled, true, "The editTagName method was called");
});

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

@ -23,6 +23,10 @@ devtools.lazyRequireGetter(this, "L10N",
"devtools/profiler/global", true);
devtools.lazyImporter(this, "LineGraphWidget",
"resource:///modules/devtools/Graphs.jsm");
devtools.lazyRequireGetter(this, "Waterfall",
"devtools/timeline/waterfall", true);
devtools.lazyRequireGetter(this, "MarkerDetails",
"devtools/timeline/marker-details", true);
devtools.lazyRequireGetter(this, "CallView",
"devtools/profiler/tree-view", true);
devtools.lazyRequireGetter(this, "ThreadNode",
@ -47,8 +51,14 @@ const EVENTS = {
// Emitted by the OverviewView when a selection range has been removed
OVERVIEW_RANGE_CLEARED: "Performance:UI:OverviewRangeCleared",
// Emitted by the DetailsView when a subview is selected
DETAILS_VIEW_SELECTED: "Performance:UI:DetailsViewSelected",
// Emitted by the CallTreeView when a call tree has been rendered
CALL_TREE_RENDERED: "Performance:UI:CallTreeRendered"
CALL_TREE_RENDERED: "Performance:UI:CallTreeRendered",
// Emitted by the WaterfallView when it has been rendered
WATERFALL_RENDERED: "Performance:UI:WaterfallRendered"
};
/**
@ -112,6 +122,7 @@ let PerformanceController = {
PerformanceView.on(EVENTS.UI_START_RECORDING, this.startRecording);
PerformanceView.on(EVENTS.UI_STOP_RECORDING, this.stopRecording);
gFront.on("ticks", this._onTimelineData);
gFront.on("markers", this._onTimelineData);
},
/**
@ -120,6 +131,8 @@ let PerformanceController = {
destroy: function() {
PerformanceView.off(EVENTS.UI_START_RECORDING, this.startRecording);
PerformanceView.off(EVENTS.UI_STOP_RECORDING, this.stopRecording);
gFront.off("ticks", this._onTimelineData);
gFront.off("markers", this._onTimelineData);
},
/**
@ -127,8 +140,12 @@ let PerformanceController = {
* when the front is starting to record.
*/
startRecording: Task.async(function *() {
yield gFront.startRecording();
this.emit(EVENTS.RECORDING_STARTED);
// Save local start time for use with faking the endTime
// if not returned from the timeline actor
this._localStartTime = performance.now();
let startTime = this._startTime = yield gFront.startRecording();
this.emit(EVENTS.RECORDING_STARTED, startTime);
}),
/**
@ -137,6 +154,12 @@ let PerformanceController = {
*/
stopRecording: Task.async(function *() {
let results = yield gFront.stopRecording();
// If `endTime` is not yielded from timeline actor (< Fx36),
// fake an endTime
if (!results.endTime) {
this._endTime = results.endTime = this._startTime + (performance.now() - this._localStartTime);
}
this.emit(EVENTS.RECORDING_STOPPED, results);
}),

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

@ -237,7 +237,12 @@ PerformanceFront.prototype = {
// The timeline actor is target-dependent, so just make sure
// it's recording.
let withMemory = showTimelineMemory();
yield this._request("timeline", "start", { withTicks: true, withMemory: withMemory });
// Return start time from timeline actor
let startTime = yield this._request("timeline", "start", { withTicks: true, withMemory: withMemory });
this._startTime = startTime;
return { startTime };
}),
/**
@ -254,12 +259,13 @@ PerformanceFront.prototype = {
filterSamples(profilerData, this._profilingStartTime);
offsetSampleTimes(profilerData, this._profilingStartTime);
yield this._request("timeline", "stop");
let endTime = this._endTime = yield this._request("timeline", "stop");
// Join all the acquired data and return it for outside consumers.
return {
recordingDuration: profilerData.currentTime - this._profilingStartTime,
profilerData: profilerData
profilerData: profilerData,
endTime: endTime
};
}),

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

@ -19,6 +19,7 @@
<script type="application/javascript" src="performance/views/overview.js"/>
<script type="application/javascript" src="performance/views/details.js"/>
<script type="application/javascript" src="performance/views/call-tree.js"/>
<script type="application/javascript" src="performance/views/waterfall.js"/>
<vbox class="theme-body" flex="1">
<toolbar id="performance-toolbar" class="devtools-toolbar">
@ -37,17 +38,32 @@
label="&profilerUI.importButton;"/>
</hbox>
</toolbar>
<splitter class="devtools-horizontal-splitter" />
<box id="overview-pane"
class="devtools-responsive-container"
flex="1">
class="devtools-responsive-container">
<vbox id="time-framerate" flex="1"/>
</box>
<splitter class="devtools-horizontal-splitter" />
<box id="details-pane"
<toolbar id="details-toolbar" class="devtools-toolbar">
<hbox class="devtools-toolbarbutton-group">
<toolbarbutton id="select-waterfall-view"
class="devtools-toolbarbutton"
tooltiptext="waterfall"
data-view="waterfall" />
<toolbarbutton id="select-calltree-view"
class="devtools-toolbarbutton"
tooltiptext="calltree"
data-view="calltree" />
</hbox>
</toolbar>
<deck id="details-pane"
class="devtools-responsive-container"
flex="1">
<vbox class="call-tree" flex="1">
<hbox id="waterfall-view" flex="1">
<vbox id="waterfall-graph" flex="1" />
<splitter class="devtools-side-splitter"/>
<vbox id="waterfall-details" class="theme-sidebar" width="150" height="150"/>
</hbox>
<vbox id="calltree-view" class="call-tree" flex="1">
<hbox class="call-tree-headers-container">
<label class="plain call-tree-header"
type="duration"
@ -76,6 +92,6 @@
</hbox>
<vbox class="call-tree-cells-container" flex="1"/>
</vbox>
</box>
</deck>
</vbox>
</window>

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

@ -9,6 +9,7 @@ support-files =
# that need to be moved over to performance tool
[browser_perf-aaa-run-first-leaktest.js]
[browser_perf-front.js]
[browser_perf-front-basic-timeline-01.js]
[browser_perf-front-basic-profiler-01.js]
# bug 1077464
@ -32,5 +33,8 @@ support-files =
[browser_perf-overview-render-01.js]
[browser_perf-overview-render-02.js]
[browser_perf-overview-selection.js]
[browser_perf-details.js]
[browser_perf-details-calltree-render-01.js]
[browser_perf-details-calltree-render-02.js]
[browser_perf-details-waterfall-render-01.js]

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

@ -0,0 +1,26 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that the waterfall view renders content after recording.
*/
function spawnTest () {
let { panel } = yield initPerformance(SIMPLE_URL);
let { EVENTS, WaterfallView } = panel.panelWin;
yield startRecording(panel);
yield waitUntil(() => WaterfallView._markers.length);
let rendered = once(WaterfallView, EVENTS.WATERFALL_RENDERED);
yield stopRecording(panel);
yield rendered;
ok(true, "WaterfallView rendered after recording is stopped.");
ok(WaterfallView._markers.length, "WaterfallView contains markers");
yield teardown(panel);
finish();
}

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

@ -0,0 +1,46 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that the details view toggles subviews.
*/
function spawnTest () {
let { panel } = yield initPerformance(SIMPLE_URL);
let { EVENTS, $, DetailsView, document: doc } = panel.panelWin;
info("views on startup");
checkViews(DetailsView, doc, "waterfall");
// Select calltree view
let viewChanged = onceSpread(DetailsView, EVENTS.DETAILS_VIEW_SELECTED);
command($("toolbarbutton[data-view='calltree']"));
let [_, viewName] = yield viewChanged;
is(viewName, "calltree", "DETAILS_VIEW_SELECTED fired with view name");
checkViews(DetailsView, doc, "calltree");
// Select waterfall view
viewChanged = onceSpread(DetailsView, EVENTS.DETAILS_VIEW_SELECTED);
command($("toolbarbutton[data-view='waterfall']"));
[_, viewName] = yield viewChanged;
is(viewName, "waterfall", "DETAILS_VIEW_SELECTED fired with view name");
checkViews(DetailsView, doc, "waterfall");
yield teardown(panel);
finish();
}
function checkViews (DetailsView, doc, currentView) {
for (let viewName in DetailsView.views) {
let view = DetailsView.views[viewName].el;
let button = doc.querySelector("toolbarbutton[data-view='" + viewName + "']");
if (viewName === currentView) {
ok(!view.getAttribute("hidden"), view + " view displayed");
ok(button.getAttribute("checked"), view + " button checked");
} else {
ok(view.getAttribute("hidden"), view + " view hidden");
ok(!button.getAttribute("checked"), view + " button not checked");
}
}
}

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

@ -0,0 +1,27 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Test basic functionality of PerformanceFront, emitting start and endtime values
*/
let WAIT = 1000;
function spawnTest () {
let { target, front } = yield initBackend(SIMPLE_URL);
let { startTime } = yield front.startRecording();
ok(typeof startTime === "number", "front.startRecording() emits start time");
yield busyWait(WAIT);
let { endTime } = yield front.stopRecording();
ok(typeof endTime === "number", "front.stopRecording() emits end time");
ok(endTime > startTime, "endTime is after startTime");
yield removeTab(target.tab);
finish();
}

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

@ -211,8 +211,14 @@ function busyWait(time) {
while (Date.now() - start < time) { stack = Components.stack; }
}
function idleWait(time) {
return DevToolsUtils.waitForTime(time);
function command (button) {
let ev = button.ownerDocument.createEvent("XULCommandEvent");
ev.initCommandEvent("command", true, true, button.ownerDocument.defaultView, 0, false, false, false, false, null);
button.dispatchEvent(ev);
}
function click (win, button) {
EventUtils.sendMouseEvent({ type: "click" }, button, win);
}
function* startRecording(panel) {
@ -227,7 +233,7 @@ function* startRecording(panel) {
ok(!button.hasAttribute("locked"),
"The record button should not be locked yet.");
EventUtils.sendMouseEvent({ type: "click" }, button, win);
click(win, button);
yield clicked;
@ -255,7 +261,7 @@ function* stopRecording(panel) {
ok(!button.hasAttribute("locked"),
"The record button should not be locked yet.");
EventUtils.sendMouseEvent({ type: "click" }, button, win);
click(win, button);
yield clicked;

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

@ -3,34 +3,69 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const DEFAULT_DETAILS_SUBVIEW = "waterfall";
/**
* Details view containing profiler call tree. Manages
* subviews and toggles visibility between them.
*/
let DetailsView = {
/**
* Name to index mapping of subviews, used by selecting view.
*/
viewIndexes: {
waterfall: 0,
calltree: 1
},
/**
* Sets up the view with event binding, initializes
* subviews.
*/
initialize: function () {
this.views = {
callTree: CallTreeView
};
initialize: Task.async(function *() {
this.el = $("#details-pane");
// Initialize subviews
return promise.all([
CallTreeView.initialize()
]);
this._onViewToggle = this._onViewToggle.bind(this);
for (let button of $$("toolbarbutton[data-view]", $("#details-toolbar"))) {
button.addEventListener("command", this._onViewToggle);
}
yield CallTreeView.initialize();
yield WaterfallView.initialize();
this.selectView(DEFAULT_DETAILS_SUBVIEW);
}),
/**
* Select one of the DetailView's subviews to be rendered,
* hiding the others.
*
* @params {String} selectedView
* Name of the view to be shown.
*/
selectView: function (selectedView) {
this.el.selectedIndex = this.viewIndexes[selectedView];
this.emit(EVENTS.DETAILS_VIEW_SELECTED, selectedView);
},
/**
* Called when a view button is clicked.
*/
_onViewToggle: function (e) {
this.selectView(e.target.getAttribute("data-view"));
},
/**
* Unbinds events, destroys subviews.
*/
destroy: function () {
return promise.all([
CallTreeView.destroy()
]);
}
destroy: Task.async(function *() {
for (let button of $$("toolbarbutton[data-view]", $("#details-toolbar"))) {
button.removeEventListener("command", this._onViewToggle);
}
yield CallTreeView.destroy();
yield WaterfallView.destroy();
})
};
/**

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

@ -0,0 +1,116 @@
/* 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";
/**
* Waterfall view controlled by DetailsView.
*/
let WaterfallView = {
_startTime: 0,
_endTime: 0,
_markers: [],
/**
* Sets up the view with event binding.
*/
initialize: Task.async(function *() {
this.el = $("#waterfall-view");
this._stop = this._stop.bind(this);
this._start = this._start.bind(this);
this._onTimelineData = this._onTimelineData.bind(this);
this._onMarkerSelected = this._onMarkerSelected.bind(this);
this._onResize = this._onResize.bind(this);
this.graph = new Waterfall($("#waterfall-graph"), $("#details-pane"));
this.markerDetails = new MarkerDetails($("#waterfall-details"), $("#waterfall-view > splitter"));
this.graph.on("selected", this._onMarkerSelected);
this.graph.on("unselected", this._onMarkerSelected);
this.markerDetails.on("resize", this._onResize);
PerformanceController.on(EVENTS.RECORDING_STARTED, this._start);
PerformanceController.on(EVENTS.RECORDING_STOPPED, this._stop);
PerformanceController.on(EVENTS.TIMELINE_DATA, this._onTimelineData);
yield this.graph.recalculateBounds();
}),
/**
* Unbinds events.
*/
destroy: function () {
this.graph.off("selected", this._onMarkerSelected);
this.graph.off("unselected", this._onMarkerSelected);
this.markerDetails.off("resize", this._onResize);
PerformanceController.off(EVENTS.RECORDING_STARTED, this._start);
PerformanceController.off(EVENTS.RECORDING_STOPPED, this._stop);
PerformanceController.off(EVENTS.TIMELINE_DATA, this._onTimelineData);
},
render: Task.async(function *() {
yield this.graph.recalculateBounds();
this.graph.setData(this._markers, this._startTime, this._startTime, this._endTime);
this.emit(EVENTS.WATERFALL_RENDERED);
}),
/**
* Event handlers
*/
/**
* Called when recording starts.
*/
_start: function (_, { startTime }) {
this._startTime = startTime;
this._endTime = startTime;
this.graph.clearView();
},
/**
* Called when recording stops.
*/
_stop: Task.async(function *(_, { endTime }) {
this._endTime = endTime;
this._markers = this._markers.sort((a,b) => (a.start > b.start));
this.render();
}),
/**
* Called when a marker is selected in the waterfall view,
* updating the markers detail view.
*/
_onMarkerSelected: function (event, marker) {
if (event === "selected") {
this.markerDetails.render(marker);
}
if (event === "unselected") {
this.markerDetails.empty();
}
},
/**
* Called when the marker details view is resized.
*/
_onResize: function () {
this.render();
},
/**
* Called when the TimelineFront has new data for
* framerate, markers or memory, and stores the data
* to be plotted subsequently.
*/
_onTimelineData: function (_, eventName, ...data) {
if (eventName === "markers") {
let [markers, endTime] = data;
Array.prototype.push.apply(this._markers, markers);
}
}
};
/**
* Convenient way of emitting events from the view.
*/
EventEmitter.decorate(WaterfallView);

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

@ -251,8 +251,8 @@ let TimelineView = {
*/
initialize: Task.async(function*() {
this.markersOverview = new MarkersOverview($("#markers-overview"));
this.waterfall = new Waterfall($("#timeline-waterfall"));
this.markerDetails = new MarkerDetails($("#timeline-waterfall-details"));
this.waterfall = new Waterfall($("#timeline-waterfall"), $("#timeline-pane"));
this.markerDetails = new MarkerDetails($("#timeline-waterfall-details"), $("#timeline-waterfall-container > splitter"));
this._onSelecting = this._onSelecting.bind(this);
this._onRefresh = this._onRefresh.bind(this);
@ -273,8 +273,10 @@ let TimelineView = {
*/
destroy: function() {
this.markerDetails.off("resize", this._onRefresh);
this.markerDetails.destroy();
this.waterfall.off("selected", this._onMarkerSelected);
this.waterfall.off("unselected", this._onMarkerSelected);
this.waterfall.destroy();
this.markersOverview.off("selecting", this._onSelecting);
this.markersOverview.off("refresh", this._onRefresh);
this.markersOverview.destroy();

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

@ -22,12 +22,14 @@ loader.lazyRequireGetter(this, "EventEmitter",
*
* @param nsIDOMNode parent
* The parent node holding the view.
* @param nsIDOMNode splitter
* The splitter node that the resize event is bound to.
*/
function MarkerDetails(parent) {
function MarkerDetails(parent, splitter) {
EventEmitter.decorate(this);
this._document = parent.ownerDocument;
this._parent = parent;
this._splitter = this._document.querySelector("#timeline-waterfall-container > splitter");
this._splitter = splitter;
this._splitter.addEventListener("mouseup", () => this.emit("resize"));
}
@ -35,6 +37,7 @@ MarkerDetails.prototype = {
destroy: function() {
this.empty();
this._parent = null;
this._splitter = null;
},
/**

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

@ -48,11 +48,14 @@ const WATERFALL_ROWCOUNT_ONPAGEUPDOWN = 10;
*
* @param nsIDOMNode parent
* The parent node holding the waterfall.
* @param nsIDOMNode container
* The container node that key events should be bound to.
*/
function Waterfall(parent) {
function Waterfall(parent, container) {
EventEmitter.decorate(this);
this._parent = parent;
this._document = parent.ownerDocument;
this._container = container;
this._fragment = this._document.createDocumentFragment();
this._outstandingMarkers = [];
@ -78,9 +81,15 @@ function Waterfall(parent) {
// Selected row index. By default, we want the first
// row to be selected.
this._selectedRowIdx = 0;
// Default rowCount
this.rowCount = WATERFALL_ROWCOUNT_ONPAGEUPDOWN;
}
Waterfall.prototype = {
destroy: function() {
this._parent = this._document = this._container = null;
},
/**
* Populates this view with the provided data source.
*
@ -110,7 +119,7 @@ Waterfall.prototype = {
* Keybindings.
*/
setupKeys: function() {
let pane = this._document.querySelector("#timeline-pane");
let pane = this._container;
pane.parentNode.parentNode.addEventListener("keydown", e => {
if (e.keyCode === Ci.nsIDOMKeyEvent.DOM_VK_UP) {
e.preventDefault();
@ -130,11 +139,11 @@ Waterfall.prototype = {
}
if (e.keyCode === Ci.nsIDOMKeyEvent.DOM_VK_PAGE_UP) {
e.preventDefault();
this.selectNearestRow(this._selectedRowIdx - WATERFALL_ROWCOUNT_ONPAGEUPDOWN);
this.selectNearestRow(this._selectedRowIdx - this.rowCount);
}
if (e.keyCode === Ci.nsIDOMKeyEvent.DOM_VK_PAGE_DOWN) {
e.preventDefault();
this.selectNearestRow(this._selectedRowIdx + WATERFALL_ROWCOUNT_ONPAGEUPDOWN);
this.selectNearestRow(this._selectedRowIdx + this.rowCount);
}
}, true);
},

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

@ -204,3 +204,12 @@ functionality specific to firefox. -->
<!ENTITY remoteXUL.title "Remote XUL">
<!ENTITY remoteXUL.longDesc "<p><ul><li>Please contact the website owners to inform them of this problem.</li></ul></p>">
<!ENTITY oldSecurityProtocol.title "Unable to Connect Securely">
<!-- LOCALIZATION NOTE (oldSecurityProtocol.longDesc) - Do not translate the
<span id='hostname'></span>. -->
<!ENTITY oldSecurityProtocol.longDesc "Firefox cannot guarantee the safety of your data on <span id='hostname'></span> because it uses SSLv3, a broken security protocol.">
<!-- LOCALIZATION NOTE (oldSecurityProtocol.advancedInfo) - Do not translate
the <span id='errorcode'></span>. -->
<!ENTITY oldSecurityProtocol.advancedInfo "Advanced info: <span id='errorcode'></span>">
<!ENTITY oldSecurityProtocol.learnMore "Learn More…">

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

@ -10,11 +10,16 @@
background-color: white;
border-color: hsla(210,100%,85%,0.7);
border-style: dotted;
color: hsl(210,53%,45%);
color: var(--theme-selection-color);
}
.margin,
.size {
color: var(--theme-highlight-blue);
}
#content {
background-color: #80d4ff;
background-color: #87ceeb;
border-color: hsl(210,100%,85%);
border-style: dotted;
}
@ -26,18 +31,19 @@
}
#padding {
background-color: #66cc52;
background-color: #6a5acd;
}
#borders {
background-color: #ffe431;
background-color: #444444;
border-style: dotted;
border-color: hsl(210,100%,85%);
}
#margins {
background-color: #d89b28;
opacity: 0.6;
background-color: #edff64;
/* This opacity applies to all of the regions, since they are nested. */
opacity: .8;
}
.editable {

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

@ -33,6 +33,17 @@
pointer-events: none;
}
/* Details Panel */
#select-waterfall-view {
list-style-image: url(performance-icons.svg#waterfall);
}
#select-calltree-view {
list-style-image: url(performance-icons.svg#call-tree);
}
/* Profile call tree */
.theme-dark .call-tree-headers-container {
@ -255,3 +266,148 @@
transform: scale(0.75);
transform-origin: center right;
}
/**
* Details Waterfall Styles
*/
.waterfall-list-contents {
/* Hack: force hardware acceleration */
transform: translateZ(1px);
overflow-x: hidden;
overflow-y: auto;
}
.waterfall-header-contents {
overflow-x: hidden;
}
.waterfall-background-ticks {
/* Background created on a <canvas> in js. */
/* @see browser/devtools/timeline/widgets/waterfall.js */
background-image: -moz-element(#waterfall-background);
background-repeat: repeat-y;
background-position: -1px center;
}
.waterfall-marker-container[is-spacer] {
pointer-events: none;
}
.theme-dark .waterfall-marker-container:not([is-spacer]):nth-child(2n) {
background-color: rgba(255,255,255,0.03);
}
.theme-light .waterfall-marker-container:not([is-spacer]):nth-child(2n) {
background-color: rgba(128,128,128,0.03);
}
.theme-dark .waterfall-marker-container:hover {
background-color: rgba(255,255,255,0.1) !important;
}
.theme-light .waterfall-marker-container:hover {
background-color: rgba(128,128,128,0.1) !important;
}
.waterfall-marker-item {
overflow: hidden;
}
.waterfall-sidebar {
-moz-border-end: 1px solid;
}
.theme-dark .waterfall-sidebar {
-moz-border-end-color: #000;
}
.theme-light .waterfall-sidebar {
-moz-border-end-color: #aaa;
}
.waterfall-marker-container:hover > .waterfall-sidebar {
background-color: transparent;
}
.waterfall-header-name {
padding: 4px;
}
.waterfall-header-tick {
width: 100px;
font-size: 9px;
transform-origin: left center;
}
.theme-dark .waterfall-header-tick {
color: #a9bacb;
}
.theme-light .waterfall-header-tick {
color: #292e33;
}
.waterfall-header-tick:not(:first-child) {
-moz-margin-start: -100px !important; /* Don't affect layout. */
}
.waterfall-marker-bullet {
width: 8px;
height: 8px;
-moz-margin-start: 8px;
-moz-margin-end: 6px;
border: 1px solid;
border-radius: 1px;
}
.waterfall-marker-name {
font-size: 95%;
padding-bottom: 1px !important;
}
.waterfall-marker-bar {
height: 9px;
border: 1px solid;
border-radius: 1px;
transform-origin: left center;
}
.theme-light .waterfall-marker-container.selected > .waterfall-sidebar,
.theme-light .waterfall-marker-container.selected > .waterfall-marker-item {
background-color: #4c9ed9; /* Select Highlight Blue */
color: #f5f7fa; /* Light foreground text */
}
.theme-dark .waterfall-marker-container.selected > .waterfall-sidebar,
.theme-dark .waterfall-marker-container.selected > .waterfall-marker-item {
background-color: #1d4f73; /* Select Highlight Blue */
color: #f5f7fa; /* Light foreground text */
}
.waterfall-marker-container.selected .waterfall-marker-bullet,
.waterfall-marker-container.selected .waterfall-marker-bar {
border-color: initial!important;
}
#waterfall-details {
padding-top: 28px;
overflow: auto;
}
.marker-details-bullet {
width: 8px;
height: 8px;
margin: 0 8px;
border: 1px solid;
border-radius: 1px;
}
.marker-details-type {
font-size: 1.2em;
font-weight: bold;
}
.marker-details-duration {
font-weight: bold;
}

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

@ -765,9 +765,9 @@ TelephonyService.prototype = {
let fullmmi = "(" + procedure + serviceCode + allSi + "#)";
// Dial string after the #.
let dialString = "([^#]*)";
let optionalDialString = "([^#]+)?";
return new RegExp(fullmmi + dialString);
return new RegExp("^" + fullmmi + optionalDialString + "$");
},
/**

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

@ -102,7 +102,22 @@ add_test(function test_parseMMI_USSD() {
equal(mmi.sib, undefined);
equal(mmi.sic, undefined);
equal(mmi.pwd, undefined);
equal(mmi.dialNumber, "");
equal(mmi.dialNumber, undefined);
run_next_test();
});
add_test(function test_parseMMI_USSD_with_two_sharps() {
let mmi = parseMMI("*225#4384903113430962#");
equal(mmi.fullMMI, "*225#4384903113430962#");
equal(mmi.procedure, undefined);
equal(mmi.serviceCode, undefined);
equal(mmi.sia, undefined);
equal(mmi.sib, undefined);
equal(mmi.sic, undefined);
equal(mmi.pwd, undefined);
equal(mmi.dialNumber, undefined);
run_next_test();
});
@ -117,7 +132,7 @@ add_test(function test_parseMMI_sia() {
equal(mmi.sib, undefined);
equal(mmi.sic, undefined);
equal(mmi.pwd, undefined);
equal(mmi.dialNumber, "");
equal(mmi.dialNumber, undefined);
run_next_test();
});
@ -132,7 +147,7 @@ add_test(function test_parseMMI_sib() {
equal(mmi.sib, "1");
equal(mmi.sic, undefined);
equal(mmi.pwd, undefined);
equal(mmi.dialNumber, "");
equal(mmi.dialNumber, undefined);
run_next_test();
});
@ -147,7 +162,7 @@ add_test(function test_parseMMI_sic() {
equal(mmi.sib, "");
equal(mmi.sic, "1");
equal(mmi.pwd, undefined);
equal(mmi.dialNumber, "");
equal(mmi.dialNumber, undefined);
run_next_test();
});
@ -162,7 +177,7 @@ add_test(function test_parseMMI_sia_sib() {
equal(mmi.sib, "1");
equal(mmi.sic, undefined);
equal(mmi.pwd, undefined);
equal(mmi.dialNumber, "");
equal(mmi.dialNumber, undefined);
run_next_test();
});
@ -177,7 +192,7 @@ add_test(function test_parseMMI_sia_sic() {
equal(mmi.sib, "");
equal(mmi.sic, "1");
equal(mmi.pwd, undefined);
equal(mmi.dialNumber, "");
equal(mmi.dialNumber, undefined);
run_next_test();
});
@ -192,7 +207,7 @@ add_test(function test_parseMMI_sib_sic() {
equal(mmi.sib, "1");
equal(mmi.sic, "1");
equal(mmi.pwd, undefined);
equal(mmi.dialNumber, "");
equal(mmi.dialNumber, undefined);
run_next_test();
});
@ -207,7 +222,7 @@ add_test(function test_parseMMI_pwd() {
equal(mmi.sib, "");
equal(mmi.sic, "");
equal(mmi.pwd, "1");
equal(mmi.dialNumber, "");
equal(mmi.dialNumber, undefined);
run_next_test();
});
@ -242,7 +257,7 @@ add_test(function test_parseMMI_activation() {
equal(mmi.sib, "34");
equal(mmi.sic, "56");
equal(mmi.pwd, undefined);
equal(mmi.dialNumber, "");
equal(mmi.dialNumber, undefined);
run_next_test();
});
@ -257,7 +272,7 @@ add_test(function test_parseMMI_deactivation() {
equal(mmi.sib, "34");
equal(mmi.sic, "56");
equal(mmi.pwd, undefined);
equal(mmi.dialNumber, "");
equal(mmi.dialNumber, undefined);
run_next_test();
});
@ -272,7 +287,7 @@ add_test(function test_parseMMI_interrogation() {
equal(mmi.sib, "34");
equal(mmi.sic, "56");
equal(mmi.pwd, undefined);
equal(mmi.dialNumber, "");
equal(mmi.dialNumber, undefined);
run_next_test();
});
@ -287,7 +302,7 @@ add_test(function test_parseMMI_registration() {
equal(mmi.sib, "34");
equal(mmi.sic, "56");
equal(mmi.pwd, undefined);
equal(mmi.dialNumber, "");
equal(mmi.dialNumber, undefined);
run_next_test();
});
@ -302,7 +317,7 @@ add_test(function test_parseMMI_erasure() {
equal(mmi.sib, "34");
equal(mmi.sic, "56");
equal(mmi.pwd, undefined);
equal(mmi.dialNumber, "");
equal(mmi.dialNumber, undefined);
run_next_test();
});

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

@ -118,6 +118,15 @@ class B2GDesktopReftest(RefTest):
"app://test-container.gaiamobile.org/index.html"
prefs["b2g.system_manifest_url"] = \
"app://test-container.gaiamobile.org/manifest.webapp"
# Make sure we disable system updates
prefs["app.update.enabled"] = False
prefs["app.update.url"] = ""
prefs["app.update.url.override"] = ""
# Disable webapp updates
prefs["webapps.update.enabled"] = False
# Disable tiles also
prefs["browser.newtabpage.directory.source"] = ""
prefs["browser.newtabpage.directory.ping"] = ""
prefs["dom.ipc.tabs.disabled"] = False
prefs["dom.mozBrowserFramesEnabled"] = True
prefs["font.size.inflation.emPerLine"] = 0

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

@ -443,6 +443,15 @@ class B2GRemoteReftest(RefTest):
# Set a future policy version to avoid the telemetry prompt.
prefs["toolkit.telemetry.prompted"] = 999
prefs["toolkit.telemetry.notifiedOptOut"] = 999
# Make sure we disable system updates
prefs["app.update.enabled"] = False
prefs["app.update.url"] = ""
prefs["app.update.url.override"] = ""
# Disable webapp updates
prefs["webapps.update.enabled"] = False
# Disable tiles also
prefs["browser.newtabpage.directory.source"] = ""
prefs["browser.newtabpage.directory.ping"] = ""
if options.oop:
prefs['browser.tabs.remote.autostart'] = True

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

@ -7,6 +7,7 @@ package org.mozilla.gecko;
import org.mozilla.gecko.db.BrowserContract;
import org.mozilla.gecko.db.BrowserDB;
import org.mozilla.gecko.home.HomePanelsManager;
import org.mozilla.gecko.lwt.LightweightTheme;
import org.mozilla.gecko.mozglue.GeckoLoader;
import org.mozilla.gecko.util.Clipboard;
import org.mozilla.gecko.util.HardwareUtils;

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

@ -3,13 +3,14 @@
* 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/. */
package org.mozilla.gecko;
package org.mozilla.gecko.lwt;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONObject;
import org.mozilla.gecko.AppConstants.Versions;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.GeckoSharedPrefs;
import org.mozilla.gecko.gfx.BitmapUtils;
import org.mozilla.gecko.util.GeckoEventListener;

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

@ -3,7 +3,7 @@
* 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/. */
package org.mozilla.gecko;
package org.mozilla.gecko.lwt;
import android.content.res.Resources;
import android.graphics.Bitmap;

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

@ -326,10 +326,10 @@ gbjar.sources += [
'InputMethods.java',
'IntentHelper.java',
'JavaAddonManager.java',
'LightweightTheme.java',
'LightweightThemeDrawable.java',
'LocaleAware.java',
'LocaleManager.java',
'lwt/LightweightTheme.java',
'lwt/LightweightThemeDrawable.java',
'MediaCastingBar.java',
'MemoryMonitor.java',
'menu/GeckoMenu.java',

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

@ -9,14 +9,14 @@ import org.mozilla.gecko.AppConstants.Versions;
import org.mozilla.gecko.GeckoApp;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.GeckoApplication;
import org.mozilla.gecko.LightweightTheme;
import org.mozilla.gecko.LightweightThemeDrawable;
import org.mozilla.gecko.NewTabletUI;
import org.mozilla.gecko.R;
import org.mozilla.gecko.Telemetry;
import org.mozilla.gecko.TelemetryContract;
import org.mozilla.gecko.animation.PropertyAnimator;
import org.mozilla.gecko.animation.ViewHelper;
import org.mozilla.gecko.lwt.LightweightTheme;
import org.mozilla.gecko.lwt.LightweightThemeDrawable;
import org.mozilla.gecko.util.HardwareUtils;
import org.mozilla.gecko.widget.GeckoPopupMenu;
import org.mozilla.gecko.widget.IconTabWidget;

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

@ -76,6 +76,16 @@ public class ToolbarComponent extends BaseComponent {
return this;
}
public ToolbarComponent assertIsUrlEditTextSelected() {
fAssertTrue("The edit text is selected", isUrlEditTextSelected());
return this;
}
public ToolbarComponent assertIsUrlEditTextNotSelected() {
fAssertFalse("The edit text is not selected", isUrlEditTextSelected());
return this;
}
/**
* Returns the root View for the browser toolbar.
*/
@ -192,7 +202,7 @@ public class ToolbarComponent extends BaseComponent {
urlEditText.isInputMethodTarget());
mSolo.clearEditText(urlEditText);
mSolo.enterText(urlEditText, url);
mSolo.typeText(urlEditText, url);
return this;
}
@ -246,4 +256,8 @@ public class ToolbarComponent extends BaseComponent {
}
});
}
private boolean isUrlEditTextSelected() {
return getUrlEditText().isSelected();
}
}

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

@ -134,6 +134,7 @@ skip-if = android_version == "10"
# disabled on Android 2.3; bug 946656
skip-if = android_version == "10"
[testAppMenuPathways]
[testBackButtonInEditMode]
[testEventDispatcher]
[testGeckoRequest]
[testInputConnection]

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

@ -0,0 +1,47 @@
package org.mozilla.gecko.tests;
import org.mozilla.gecko.tests.helpers.GeckoHelper;
import android.view.View;
/**
* Tests that verify the behavior of back button in edit mode.
*/
public class testBackButtonInEditMode extends UITest {
public void testBackButtonInEditMode() {
GeckoHelper.blockForReady();
// Verify back button behavior for edit mode.
mToolbar.enterEditingMode()
.assertIsUrlEditTextSelected();
testBackPressInEditMode();
testExitUsingBackButton();
// Verify back button behavior in edit mode after input.
mToolbar.enterEditingMode()
.enterUrl("dummy")
.assertIsUrlEditTextSelected();
testBackPressInEditMode();
testExitUsingBackButton();
// Verify the swipe behavior in edit mode.
mToolbar.enterEditingMode()
.assertIsUrlEditTextSelected();
mAboutHome.swipeToPanelOnLeft();
mToolbar.assertIsUrlEditTextNotSelected()
.assertIsEditing();
testExitUsingBackButton();
}
public void testBackPressInEditMode() {
// Press back button and verify URLEditText is not selected.
getSolo().goBack();
mToolbar.assertIsUrlEditTextNotSelected()
.assertIsEditing();
}
public void testExitUsingBackButton() {
getSolo().goBack();
mToolbar.assertIsNotEditing();
}
}

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

@ -14,7 +14,6 @@ import org.mozilla.gecko.AppConstants.Versions;
import org.mozilla.gecko.BrowserApp;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.GeckoApplication;
import org.mozilla.gecko.LightweightTheme;
import org.mozilla.gecko.NewTabletUI;
import org.mozilla.gecko.R;
import org.mozilla.gecko.Tab;
@ -24,6 +23,7 @@ import org.mozilla.gecko.TelemetryContract;
import org.mozilla.gecko.animation.PropertyAnimator;
import org.mozilla.gecko.animation.PropertyAnimator.PropertyAnimationListener;
import org.mozilla.gecko.animation.ViewHelper;
import org.mozilla.gecko.lwt.LightweightTheme;
import org.mozilla.gecko.menu.GeckoMenu;
import org.mozilla.gecko.menu.MenuPopup;
import org.mozilla.gecko.tabs.TabHistoryController;

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

@ -5,9 +5,9 @@
package org.mozilla.gecko.toolbar;
import org.mozilla.gecko.GeckoApplication;
import org.mozilla.gecko.LightweightTheme;
import org.mozilla.gecko.LightweightThemeDrawable;
import org.mozilla.gecko.R;
import org.mozilla.gecko.lwt.LightweightTheme;
import org.mozilla.gecko.lwt.LightweightThemeDrawable;
import org.mozilla.gecko.tabs.TabCurve;
import org.mozilla.gecko.widget.ThemedImageButton;

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

@ -14,6 +14,10 @@ import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.Shape;
public class ResizablePathDrawable extends ShapeDrawable {
// An attribute mirroring the super class' value. getAlpha() is only
// available in API 19+ so to use that alpha value, we have to mirror it.
private int alpha = 255;
private final ColorStateList colorStateList;
private int currentColor;
@ -51,9 +55,21 @@ public class ResizablePathDrawable extends ShapeDrawable {
@Override
protected void onDraw(Shape shape, Canvas canvas, Paint paint) {
paint.setColor(currentColor);
// setAlpha overrides the alpha value in set color. Since we just set the color,
// the alpha value is reset: override the alpha value with the old value.
//
// Note: We *should* be able to call Shape.setAlpha, rather than Paint.setAlpha, but
// then the opacity doesn't change - dunno why but probably not worth the time.
paint.setAlpha(alpha);
super.onDraw(shape, canvas, paint);
}
@Override
public void setAlpha(final int alpha) {
super.setAlpha(alpha);
this.alpha = alpha;
}
@Override
protected boolean onStateChange(int[] stateSet) {
return updateColor(stateSet);

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

@ -7,8 +7,8 @@
package org.mozilla.gecko.widget;
import org.mozilla.gecko.GeckoApplication;
import org.mozilla.gecko.LightweightTheme;
import org.mozilla.gecko.R;
import org.mozilla.gecko.lwt.LightweightTheme;
import android.content.Context;
import android.content.res.TypedArray;

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

@ -7,8 +7,8 @@
package org.mozilla.gecko.widget;
import org.mozilla.gecko.GeckoApplication;
import org.mozilla.gecko.LightweightTheme;
import org.mozilla.gecko.R;
import org.mozilla.gecko.lwt.LightweightTheme;
import android.content.Context;
import android.content.res.TypedArray;

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

@ -7,8 +7,8 @@
package org.mozilla.gecko.widget;
import org.mozilla.gecko.GeckoApplication;
import org.mozilla.gecko.LightweightTheme;
import org.mozilla.gecko.R;
import org.mozilla.gecko.lwt.LightweightTheme;
import android.content.Context;
import android.content.res.TypedArray;

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

@ -7,8 +7,8 @@
package org.mozilla.gecko.widget;
import org.mozilla.gecko.GeckoApplication;
import org.mozilla.gecko.LightweightTheme;
import org.mozilla.gecko.R;
import org.mozilla.gecko.lwt.LightweightTheme;
import android.content.Context;
import android.content.res.TypedArray;

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

@ -7,8 +7,8 @@
package org.mozilla.gecko.widget;
import org.mozilla.gecko.GeckoApplication;
import org.mozilla.gecko.LightweightTheme;
import org.mozilla.gecko.R;
import org.mozilla.gecko.lwt.LightweightTheme;
import android.content.Context;
import android.content.res.TypedArray;

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

@ -7,8 +7,8 @@
package org.mozilla.gecko.widget;
import org.mozilla.gecko.GeckoApplication;
import org.mozilla.gecko.LightweightTheme;
import org.mozilla.gecko.R;
import org.mozilla.gecko.lwt.LightweightTheme;
import android.content.Context;
import android.content.res.TypedArray;

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

@ -7,8 +7,8 @@
package org.mozilla.gecko.widget;
import org.mozilla.gecko.GeckoApplication;
import org.mozilla.gecko.LightweightTheme;
import org.mozilla.gecko.R;
import org.mozilla.gecko.lwt.LightweightTheme;
import android.content.Context;
import android.content.res.TypedArray;

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

@ -7,8 +7,8 @@
package org.mozilla.gecko.widget;
import org.mozilla.gecko.GeckoApplication;
import org.mozilla.gecko.LightweightTheme;
import org.mozilla.gecko.R;
import org.mozilla.gecko.lwt.LightweightTheme;
import android.content.Context;
import android.content.res.TypedArray;

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

@ -27,23 +27,23 @@
/* Box model highlighter */
:-moz-native-anonymous .box-model-regions {
opacity: 0.4;
opacity: 0.6;
}
:-moz-native-anonymous .box-model-content {
fill: #80d4ff;
fill: #87ceeb;
}
:-moz-native-anonymous .box-model-padding {
fill: #66cc52;
fill: #6a5acd;
}
:-moz-native-anonymous .box-model-border {
fill: #ffe431;
fill: #444444;
}
:-moz-native-anonymous .box-model-margin {
fill: #d89b28;
fill: #edff64;
}
:-moz-native-anonymous .box-model-content,

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

@ -241,7 +241,14 @@ let TimelineActor = exports.TimelineActor = protocol.ActorClass({
}
clearTimeout(this._dataPullTimeout);
}, {}),
return this.docShells[0].now();
}, {
response: {
// Set as possibly nullable due to the end time possibly being
// undefined during destruction
value: RetVal("nullable:number")
}
}),
/**
* When a new window becomes available in the tabActor, start recording its

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

@ -613,7 +613,9 @@ WebappsActor.prototype = {
}
// Check that we are not overriding a preinstalled application.
if (appId in reg.webapps && reg.webapps[appId].removable === false) {
if (appId in reg.webapps &&
reg.webapps[appId].removable === false &&
!this._isUnrestrictedAccessAllowed()) {
return { error: "installationFailed",
message: "The application " + appId + " can't be overridden."
};

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

@ -21,6 +21,12 @@ let chromeGlobal = this;
if (!DebuggerServer.initialized) {
DebuggerServer.init();
// message manager helpers provided for actor module parent/child message exchange
DebuggerServer.parentMessageManager = {
sendSyncMessage: sendSyncMessage,
addMessageListener: addMessageListener
};
}
// In case of apps being loaded in parent process, DebuggerServer is already

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

@ -0,0 +1,116 @@
Lazy Actor Modules and E10S setup
---------------------------------
The **DebuggerServer** loads and creates most of the actors lazily to keep
the initial memory usage down (which is extremely important on lower end devices).
## Register a lazy global/tab actor module
register a global actor:
```js
DebuggerServer.registerModule("devtools/server/actors/webapps", {
prefix: "webapps",
constructor: "WebappsActor",
type: { global: true }
});
```
register a tab actor:
```js
DebuggerServer.registerModule("devtools/server/actors/webconsole", {
prefix: "console",
constructor: "WebConsoleActor",
type: { tab: true }
});
```
## E10S Setup
Some of the actor modules needs to exchange messages between the parent and child processes.
E.g. the **director-manager** needs to ask the list installed **director scripts** from
the **director-registry** running in the parent process) and the parent/child setup
is lazily directed by the **DebuggerServer**.
When the actor is loaded for the first time in the the **DebuggerServer** running in the
child process, it has the chances to run its setup procedure, e.g. in the **director-registry**:
```js
...
const {DebuggerServer} = require("devtools/server/main");
...
// skip child setup if this actor module is not running in a child process
if (DebuggerServer.isInChildProcess) {
setupChildProcess();
}
...
```
The above setupChildProcess helper will use the **DebuggerServer.setupInParent**
to start a setup process in the parent process Debugger Server, e.g. in the the **director-registry**:
```js
function setupChildProcess() {
const { sendSyncMessage } = DebuggerServer.parentMessageManager;
DebuggerServer.setupInParent({
module: "devtools/server/actors/director-registry",
setupParent: "setupParentProcess"
});
...
```
in the parent process, the **DebuggerServer** will require the requested module
and call the **setupParent** exported helper with the **MessageManager**
connected to the child process as parameter, e.g. in the **director-registry**:
```js
/**
* E10S parent/child setup helpers
*/
let gTrackedMessageManager = new Set();
exports.setupParentProcess = function setupParentProcess({ mm, childID }) {
if (gTrackedMessageManager.has(mm)) { return; }
gTrackedMessageManager.add(mm);
// listen for director-script requests from the child process
mm.addMessageListener("debug:director-registry-request", handleChildRequest);
// time to unsubscribe from the disconnected message manager
DebuggerServer.once("disconnected-from-child:" + childID, handleMessageManagerDisconnected);
function handleMessageManagerDisconnected(evt, { mm: disconnected_mm }) {
...
}
```
The DebuggerServer emits "disconnected-from-child:CHILDID" events to give the actor modules
the chance to cleanup their handlers registered on the disconnected message manager.
## E10S setup flow
In the child process:
- DebuggerServer loads an actor module
- the actor module check DebuggerServer.isInChildProcess
- the actor module calls the DebuggerServer.setupInParent helper
- the DebuggerServer.setupInParent helper asks to the parent process
to run the required setup
- the actor module use the DebuggerServer.parentMessageManager.sendSyncMessage,
DebuggerServer.parentMessageManager.addMessageListener helpers to send requests
or to subscribe message handlers
In the parent process:
- The DebuggerServer receives the DebuggerServer.setupInParent request
- it tries to load the required module
- it tries to call the **mod[setupParent]** method with the frame message manager and the childID
in the json parameter **{ mm, childID }**
- the module setupParent helper use the mm to subscribe the messagemanager events
- the module setupParent helper use the DebuggerServer object to subscribe *once* the
**"disconnected-from-child:CHILDID"** event (needed to unsubscribe the messagemanager events)

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

@ -137,7 +137,7 @@ function ModuleAPI() {
}
activeGlobalActors = null;
}
}
};
};
/***
@ -213,7 +213,7 @@ var DebuggerServer = {
for (let id of Object.getOwnPropertyNames(gRegisteredModules)) {
this.unregisterModule(id);
}
gRegisteredModules = {};
gRegisteredModules = Object.create(null);
this.closeAllListeners();
this.globalActorFactories = {};
@ -711,6 +711,39 @@ var DebuggerServer = {
return deferred.promise;
},
/**
* Check if the caller is running in a content child process.
*
* @return boolean
* true if the caller is running in a content
*/
get isInChildProcess() !!this.parentMessageManager,
/**
* In a content child process, ask the DebuggerServer in the parent process
* to execute a given module setup helper.
*
* @param module
* The module to be required
* @param setupParent
* The name of the setup helper exported by the above module
* (setup helper signature: function ({mm}) { ... })
* @return boolean
* true if the setup helper returned successfully
*/
setupInParent: function({ module, setupParent }) {
if (!this.isInChildProcess) {
return false;
}
let { sendSyncMessage } = DebuggerServer.parentMessageManager;
return sendSyncMessage("debug:setup-in-parent", {
module: module,
setupParent: setupParent
});
},
/**
* Connect to a child process.
*
@ -736,6 +769,33 @@ var DebuggerServer = {
let childID = null;
let netMonitor = null;
// provides hook to actor modules that need to exchange messages
// between e10s parent and child processes
let onSetupInParent = function (msg) {
let { module, setupParent } = msg.json;
let m, fn;
try {
m = require(module);
if (!setupParent in m) {
dumpn("ERROR: module '" + module + "' does not export '" + setupParent + "'");
return false;
}
m[setupParent]({ mm: mm, childID: childID });
return true;
} catch(e) {
let error_msg = "exception during actor module setup running in the parent process: ";
DevToolsUtils.reportException(error_msg + e);
dumpn("ERROR: " + error_msg + " \n\t module: '" + module + "' \n\t setupParent: '" + setupParent + "'\n" +
DevToolsUtils.safeErrorString(e));
return false;
}
};
mm.addMessageListener("debug:setup-in-parent", onSetupInParent);
let onActorCreated = DevToolsUtils.makeInfallible(function (msg) {
mm.removeMessageListener("debug:actor", onActorCreated);
@ -765,6 +825,13 @@ var DebuggerServer = {
let onMessageManagerDisconnect = DevToolsUtils.makeInfallible(function (subject, topic, data) {
if (subject == mm) {
Services.obs.removeObserver(onMessageManagerDisconnect, topic);
// provides hook to actor modules that need to exchange messages
// between e10s parent and child processes
this.emit("disconnected-from-child:" + childID, { mm: mm, childID: childID });
mm.removeMessageListener("debug:setup-in-parent", onSetupInParent);
if (childTransport) {
// If we have a child transport, the actor has already
// been created. We need to stop using this message manager.

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

@ -770,7 +770,7 @@ let Pool = Class({
* Remove an actor as a child of this pool.
*/
unmanage: function(actor) {
this.__poolMap.delete(actor.actorID);
this.__poolMap && this.__poolMap.delete(actor.actorID);
},
// true if the given actor ID exists in the pool.