mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge m-c to inbound a=merge CLOSED TREE
This commit is contained in:
commit
4a03f303d6
@ -319,7 +319,7 @@ pref("media.fragmented-mp4.gonk.enabled", true);
|
||||
pref("media.video-queue.default-size", 3);
|
||||
|
||||
// optimize images' memory usage
|
||||
pref("image.mem.decodeondraw", true);
|
||||
pref("image.mem.decodeondraw", false);
|
||||
pref("image.mem.allow_locking_in_content_processes", false); /* don't allow image locking */
|
||||
// Limit the surface cache to 1/8 of main memory or 128MB, whichever is smaller.
|
||||
// Almost everything that was factored into 'max_decoded_image_kb' is now stored
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="e06971db7acf7a35c32eb74d675a4e12e288e6be">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="0244121522343877d65a69377226a836688e3004"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a0e71e61922bde009a3b6714cbe965021d3279f1"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||
<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="0244121522343877d65a69377226a836688e3004"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a0e71e61922bde009a3b6714cbe965021d3279f1"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="eb1795a9002eb142ac58c8d68f8f4ba094af07ca"/>
|
||||
|
@ -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="0244121522343877d65a69377226a836688e3004"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a0e71e61922bde009a3b6714cbe965021d3279f1"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="e354d8de334a4ad52d131f0575ccf9f79e86cadd"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="e06971db7acf7a35c32eb74d675a4e12e288e6be">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="0244121522343877d65a69377226a836688e3004"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a0e71e61922bde009a3b6714cbe965021d3279f1"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||
<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="0244121522343877d65a69377226a836688e3004"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a0e71e61922bde009a3b6714cbe965021d3279f1"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="eb1795a9002eb142ac58c8d68f8f4ba094af07ca"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="e06971db7acf7a35c32eb74d675a4e12e288e6be">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="0244121522343877d65a69377226a836688e3004"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a0e71e61922bde009a3b6714cbe965021d3279f1"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="0244121522343877d65a69377226a836688e3004"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a0e71e61922bde009a3b6714cbe965021d3279f1"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="e354d8de334a4ad52d131f0575ccf9f79e86cadd"/>
|
||||
|
@ -1,9 +1,9 @@
|
||||
{
|
||||
"git": {
|
||||
"git_revision": "0244121522343877d65a69377226a836688e3004",
|
||||
"git_revision": "a0e71e61922bde009a3b6714cbe965021d3279f1",
|
||||
"remote": "https://git.mozilla.org/releases/gaia.git",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "33d9ca589ca27af7f98b29b97a232ca599f111fe",
|
||||
"revision": "0829f98e30c6f7795f66052d32e25456eb54bda5",
|
||||
"repo_path": "integration/gaia-central"
|
||||
}
|
||||
|
@ -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="0244121522343877d65a69377226a836688e3004"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a0e71e61922bde009a3b6714cbe965021d3279f1"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="e354d8de334a4ad52d131f0575ccf9f79e86cadd"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="7f2ee9f4cb926684883fc2a2e407045fd9db2199">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="0244121522343877d65a69377226a836688e3004"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a0e71e61922bde009a3b6714cbe965021d3279f1"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
@ -1438,6 +1438,7 @@ pref("devtools.profiler.ui.show-idle-blocks", true);
|
||||
|
||||
// The default Performance UI settings
|
||||
pref("devtools.performance.ui.invert-call-tree", true);
|
||||
pref("devtools.performance.ui.invert-flame-graph", false);
|
||||
pref("devtools.performance.ui.flatten-tree-recursion", true);
|
||||
pref("devtools.performance.ui.show-platform-data", false);
|
||||
pref("devtools.performance.ui.show-idle-blocks", true);
|
||||
|
36
browser/base/content/browser-eme.js
Normal file
36
browser/base/content/browser-eme.js
Normal file
@ -0,0 +1,36 @@
|
||||
# -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
|
||||
# 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/.
|
||||
|
||||
function gEMEListener(msg /*{target: browser, data: data} */) {
|
||||
let browser = msg.target;
|
||||
let notificationId = "drmContentPlaying";
|
||||
// Don't need to show if disabled, nor reshow if it's already there
|
||||
if (!Services.prefs.getBoolPref("browser.eme.ui.enabled") ||
|
||||
PopupNotifications.getNotification(notificationId, browser)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let msgId = "emeNotifications.drmContentPlaying.message";
|
||||
let brandName = document.getElementById("bundle_brand").getString("brandShortName");
|
||||
let message = gNavigatorBundle.getFormattedString(msgId, [msg.data.drmProvider, brandName]);
|
||||
let anchorId = "eme-notification-icon";
|
||||
|
||||
let mainAction = {
|
||||
label: gNavigatorBundle.getString("emeNotifications.drmContentPlaying.button.label"),
|
||||
accessKey: gNavigatorBundle.getString("emeNotifications.drmContentPlaying.button.accesskey"),
|
||||
callback: function() { openPreferences("paneContent"); },
|
||||
dismiss: true
|
||||
};
|
||||
let options = {
|
||||
dismissed: true,
|
||||
eventCallback: aTopic => aTopic == "swapping",
|
||||
};
|
||||
PopupNotifications.show(browser, notificationId, message, anchorId, mainAction, null, options);
|
||||
};
|
||||
|
||||
window.messageManager.addMessageListener("EMEVideo:MetadataLoaded", gEMEListener);
|
||||
window.addEventListener("unload", function() {
|
||||
window.messageManager.removeMessageListener("EMEVideo:MetadataLoaded", gEMEListener);
|
||||
}, false);
|
@ -214,6 +214,7 @@ let gInitialPages = [
|
||||
#include browser-ctrlTab.js
|
||||
#include browser-customization.js
|
||||
#include browser-devedition.js
|
||||
#include browser-eme.js
|
||||
#include browser-feeds.js
|
||||
#include browser-fullScreen.js
|
||||
#include browser-fullZoom.js
|
||||
|
@ -822,6 +822,7 @@
|
||||
<image id="servicesInstall-notification-icon" class="notification-anchor-icon" role="button"/>
|
||||
<image id="translate-notification-icon" class="notification-anchor-icon" role="button"/>
|
||||
<image id="translated-notification-icon" class="notification-anchor-icon" role="button"/>
|
||||
<image id="eme-notification-icon" class="notification-anchor-icon" role="button"/>
|
||||
</box>
|
||||
<!-- Use onclick instead of normal popup= syntax since the popup
|
||||
code fires onmousedown, and hence eats our favicon drag events.
|
||||
|
@ -8,6 +8,7 @@ let {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource:///modules/ContentWebRTC.jsm");
|
||||
Cu.import("resource:///modules/ContentObservers.jsm");
|
||||
Cu.import("resource://gre/modules/InlineSpellChecker.jsm");
|
||||
Cu.import("resource://gre/modules/InlineSpellCheckerContent.jsm");
|
||||
|
||||
|
@ -19,7 +19,6 @@ DIRS += [
|
||||
'sessionstore',
|
||||
'shell',
|
||||
'selfsupport',
|
||||
'sidebar',
|
||||
'tabview',
|
||||
'uitour',
|
||||
'translation',
|
||||
|
@ -11,6 +11,7 @@ support-files =
|
||||
testEngine.xml
|
||||
testEngine_dupe.xml
|
||||
testEngine_mozsearch.xml
|
||||
webapi.html
|
||||
|
||||
[browser_405664.js]
|
||||
[browser_426329.js]
|
||||
@ -43,3 +44,4 @@ skip-if = e10s || true # Bug ??????, Bug 1100301 - leaks windows until shutdown
|
||||
[browser_searchbar_openpopup.js]
|
||||
skip-if = os == "linux" || e10s # Linux has different focus behaviours and e10s seems to have timing issues.
|
||||
[browser_searchbar_keyboard_navigation.js]
|
||||
[browser_webapi.js]
|
||||
|
174
browser/components/search/test/browser_webapi.js
Normal file
174
browser/components/search/test/browser_webapi.js
Normal file
@ -0,0 +1,174 @@
|
||||
let ROOT = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "http://example.com");
|
||||
|
||||
function AddSearchProvider(...args) {
|
||||
return gBrowser.addTab(ROOT + "webapi.html?AddSearchProvider:" + encodeURIComponent(JSON.stringify(args)));
|
||||
}
|
||||
|
||||
function addSearchEngine(...args) {
|
||||
return gBrowser.addTab(ROOT + "webapi.html?addSearchEngine:" + encodeURIComponent(JSON.stringify(args)));
|
||||
}
|
||||
|
||||
function promiseDialogOpened() {
|
||||
return new Promise((resolve, reject) => {
|
||||
Services.wm.addListener({
|
||||
onOpenWindow: function(xulWin) {
|
||||
Services.wm.removeListener(this);
|
||||
|
||||
let win = xulWin.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindow);
|
||||
waitForFocus(() => {
|
||||
if (win.location == "chrome://global/content/commonDialog.xul")
|
||||
resolve(win)
|
||||
else
|
||||
reject();
|
||||
}, win);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
add_task(function* test_working_AddSearchProvider() {
|
||||
gBrowser.selectedTab = AddSearchProvider(ROOT + "testEngine.xml");
|
||||
|
||||
let dialog = yield promiseDialogOpened();
|
||||
is(dialog.args.promptType, "confirmEx", "Should see the confirmation dialog.");
|
||||
is(dialog.args.text, "Add \"Foo\" to the list of engines available in the search bar?\n\nFrom: example.com",
|
||||
"Should have seen the right install message");
|
||||
dialog.document.documentElement.cancelDialog();
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
||||
|
||||
add_task(function* test_HTTP_AddSearchProvider() {
|
||||
gBrowser.selectedTab = AddSearchProvider(ROOT.replace("http:", "HTTP:") + "testEngine.xml");
|
||||
|
||||
let dialog = yield promiseDialogOpened();
|
||||
is(dialog.args.promptType, "confirmEx", "Should see the confirmation dialog.");
|
||||
is(dialog.args.text, "Add \"Foo\" to the list of engines available in the search bar?\n\nFrom: example.com",
|
||||
"Should have seen the right install message");
|
||||
dialog.document.documentElement.cancelDialog();
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
||||
|
||||
add_task(function* test_relative_AddSearchProvider() {
|
||||
gBrowser.selectedTab = AddSearchProvider("testEngine.xml");
|
||||
|
||||
let dialog = yield promiseDialogOpened();
|
||||
is(dialog.args.promptType, "confirmEx", "Should see the confirmation dialog.");
|
||||
is(dialog.args.text, "Add \"Foo\" to the list of engines available in the search bar?\n\nFrom: example.com",
|
||||
"Should have seen the right install message");
|
||||
dialog.document.documentElement.cancelDialog();
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
||||
|
||||
add_task(function* test_invalid_AddSearchProvider() {
|
||||
gBrowser.selectedTab = AddSearchProvider("z://foobar");
|
||||
|
||||
let dialog = yield promiseDialogOpened();
|
||||
is(dialog.args.promptType, "alert", "Should see the alert dialog.");
|
||||
is(dialog.args.text, "This search engine isn't supported by Nightly and can't be installed.",
|
||||
"Should have seen the right error message")
|
||||
dialog.document.documentElement.acceptDialog();
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
||||
|
||||
add_task(function* test_missing_AddSearchProvider() {
|
||||
let url = ROOT + "foobar.xml";
|
||||
gBrowser.selectedTab = AddSearchProvider(url);
|
||||
|
||||
let dialog = yield promiseDialogOpened();
|
||||
is(dialog.args.promptType, "alert", "Should see the alert dialog.");
|
||||
is(dialog.args.text, "Nightly could not download the search plugin from:\n" + url,
|
||||
"Should have seen the right error message")
|
||||
dialog.document.documentElement.acceptDialog();
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
||||
|
||||
add_task(function* test_working_addSearchEngine_xml() {
|
||||
gBrowser.selectedTab = addSearchEngine(ROOT + "testEngine.xml", "", "", "");
|
||||
|
||||
let dialog = yield promiseDialogOpened();
|
||||
is(dialog.args.promptType, "confirmEx", "Should see the confirmation dialog.");
|
||||
is(dialog.args.text, "Add \"Foo\" to the list of engines available in the search bar?\n\nFrom: example.com",
|
||||
"Should have seen the right install message");
|
||||
dialog.document.documentElement.cancelDialog();
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
||||
|
||||
add_task(function* test_working_addSearchEngine_src() {
|
||||
gBrowser.selectedTab = addSearchEngine(ROOT + "testEngine.src", "", "", "");
|
||||
|
||||
let dialog = yield promiseDialogOpened();
|
||||
is(dialog.args.promptType, "confirmEx", "Should see the confirmation dialog.");
|
||||
is(dialog.args.text, "Add \"Test Sherlock\" to the list of engines available in the search bar?\n\nFrom: example.com",
|
||||
"Should have seen the right install message");
|
||||
dialog.document.documentElement.cancelDialog();
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
||||
|
||||
add_task(function* test_relative_addSearchEngine_xml() {
|
||||
gBrowser.selectedTab = addSearchEngine("testEngine.xml", "", "", "");
|
||||
|
||||
let dialog = yield promiseDialogOpened();
|
||||
is(dialog.args.promptType, "confirmEx", "Should see the confirmation dialog.");
|
||||
is(dialog.args.text, "Add \"Foo\" to the list of engines available in the search bar?\n\nFrom: example.com",
|
||||
"Should have seen the right install message");
|
||||
dialog.document.documentElement.cancelDialog();
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
||||
|
||||
add_task(function* test_relative_addSearchEngine_src() {
|
||||
gBrowser.selectedTab = addSearchEngine("testEngine.src", "", "", "");
|
||||
|
||||
let dialog = yield promiseDialogOpened();
|
||||
is(dialog.args.promptType, "confirmEx", "Should see the confirmation dialog.");
|
||||
is(dialog.args.text, "Add \"Test Sherlock\" to the list of engines available in the search bar?\n\nFrom: example.com",
|
||||
"Should have seen the right install message");
|
||||
dialog.document.documentElement.cancelDialog();
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
||||
|
||||
add_task(function* test_invalid_addSearchEngine() {
|
||||
gBrowser.selectedTab = addSearchEngine("z://foobar", "", "", "");
|
||||
|
||||
let dialog = yield promiseDialogOpened();
|
||||
is(dialog.args.promptType, "alert", "Should see the alert dialog.");
|
||||
is(dialog.args.text, "This search engine isn't supported by Nightly and can't be installed.",
|
||||
"Should have seen the right error message")
|
||||
dialog.document.documentElement.acceptDialog();
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
||||
|
||||
add_task(function* test_invalid_icon_addSearchEngine() {
|
||||
gBrowser.selectedTab = addSearchEngine(ROOT + "testEngine.src", "z://foobar", "", "");
|
||||
|
||||
let dialog = yield promiseDialogOpened();
|
||||
is(dialog.args.promptType, "alert", "Should see the alert dialog.");
|
||||
is(dialog.args.text, "This search engine isn't supported by Nightly and can't be installed.",
|
||||
"Should have seen the right error message")
|
||||
dialog.document.documentElement.acceptDialog();
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
||||
|
||||
add_task(function* test_missing_addSearchEngine() {
|
||||
let url = ROOT + "foobar.xml";
|
||||
gBrowser.selectedTab = addSearchEngine(url, "", "", "");
|
||||
|
||||
let dialog = yield promiseDialogOpened();
|
||||
is(dialog.args.promptType, "alert", "Should see the alert dialog.");
|
||||
is(dialog.args.text, "Nightly could not download the search plugin from:\n" + url,
|
||||
"Should have seen the right error message")
|
||||
dialog.document.documentElement.acceptDialog();
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
20
browser/components/search/test/webapi.html
Normal file
20
browser/components/search/test/webapi.html
Normal file
@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
function installEngine() {
|
||||
var query = window.location.search.substring(1).split(":");
|
||||
var func = query[0];
|
||||
var args = JSON.parse(decodeURIComponent(query[1]));
|
||||
|
||||
if (func == "AddSearchProvider")
|
||||
window.external.AddSearchProvider(...args);
|
||||
else if (func == "addSearchEngine")
|
||||
window.sidebar.addSearchEngine(...args);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="installEngine()">
|
||||
</body>
|
||||
</html>
|
@ -1,10 +0,0 @@
|
||||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
EXTRA_COMPONENTS += [
|
||||
'nsSidebar.js',
|
||||
'nsSidebar.manifest',
|
||||
]
|
@ -1,127 +0,0 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
|
||||
/* 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/. */
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
const DEBUG = false; /* set to false to suppress debug messages */
|
||||
|
||||
const SIDEBAR_CONTRACTID = "@mozilla.org/sidebar;1";
|
||||
const SIDEBAR_CID = Components.ID("{22117140-9c6e-11d3-aaf1-00805f8a4905}");
|
||||
|
||||
// File extension for Sherlock search plugin description files
|
||||
const SHERLOCK_FILE_EXT_REGEXP = /\.src$/i;
|
||||
|
||||
function nsSidebar()
|
||||
{
|
||||
}
|
||||
|
||||
nsSidebar.prototype.classID = SIDEBAR_CID;
|
||||
|
||||
nsSidebar.prototype.validateSearchEngine =
|
||||
function (engineURL, iconURL)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Make sure the URLs are HTTP, HTTPS, or FTP.
|
||||
var isWeb = /^(https?|ftp):\/\//i;
|
||||
|
||||
if (!isWeb.test(engineURL))
|
||||
throw "Unsupported search engine URL";
|
||||
|
||||
if (iconURL && !isWeb.test(iconURL))
|
||||
throw "Unsupported search icon URL.";
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
debug(ex);
|
||||
Components.utils.reportError("Invalid argument passed to window.sidebar.addSearchEngine: " + ex);
|
||||
|
||||
var searchBundle = Services.strings.createBundle("chrome://global/locale/search/search.properties");
|
||||
var brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
|
||||
var brandName = brandBundle.GetStringFromName("brandShortName");
|
||||
var title = searchBundle.GetStringFromName("error_invalid_engine_title");
|
||||
var msg = searchBundle.formatStringFromName("error_invalid_engine_msg",
|
||||
[brandName], 1);
|
||||
Services.ww.getNewPrompter(null).alert(title, msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// The suggestedTitle and suggestedCategory parameters are ignored, but remain
|
||||
// for backward compatibility.
|
||||
nsSidebar.prototype.addSearchEngine =
|
||||
function (engineURL, iconURL, suggestedTitle, suggestedCategory)
|
||||
{
|
||||
debug("addSearchEngine(" + engineURL + ", " + iconURL + ", " +
|
||||
suggestedCategory + ", " + suggestedTitle + ")");
|
||||
|
||||
if (!this.validateSearchEngine(engineURL, iconURL))
|
||||
return;
|
||||
|
||||
// OpenSearch files will likely be far more common than Sherlock files, and
|
||||
// have less consistent suffixes, so we assume that ".src" is a Sherlock
|
||||
// (text) file, and anything else is OpenSearch (XML).
|
||||
var dataType;
|
||||
if (SHERLOCK_FILE_EXT_REGEXP.test(engineURL))
|
||||
dataType = Components.interfaces.nsISearchEngine.DATA_TEXT;
|
||||
else
|
||||
dataType = Components.interfaces.nsISearchEngine.DATA_XML;
|
||||
|
||||
Services.search.addEngine(engineURL, dataType, iconURL, true);
|
||||
}
|
||||
|
||||
// This function exists largely to implement window.external.AddSearchProvider(),
|
||||
// to match other browsers' APIs. The capitalization, although nonstandard here,
|
||||
// is therefore important.
|
||||
nsSidebar.prototype.AddSearchProvider =
|
||||
function (aDescriptionURL)
|
||||
{
|
||||
// Get the favicon URL for the current page, or our best guess at the current
|
||||
// page since we don't have easy access to the active document. Most search
|
||||
// engines will override this with an icon specified in the OpenSearch
|
||||
// description anyway.
|
||||
var win = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
var browser = win.gBrowser;
|
||||
var iconURL = "";
|
||||
// Use documentURIObject in the check for shouldLoadFavIcon so that we
|
||||
// do the right thing with about:-style error pages. Bug 453442
|
||||
if (browser.shouldLoadFavIcon(browser.selectedBrowser
|
||||
.contentDocument
|
||||
.documentURIObject))
|
||||
iconURL = browser.getIcon();
|
||||
|
||||
if (!this.validateSearchEngine(aDescriptionURL, iconURL))
|
||||
return;
|
||||
|
||||
const typeXML = Components.interfaces.nsISearchEngine.DATA_XML;
|
||||
Services.search.addEngine(aDescriptionURL, typeXML, iconURL, true);
|
||||
}
|
||||
|
||||
// This function exists to implement window.external.IsSearchProviderInstalled(),
|
||||
// for compatibility with other browsers. It will return an integer value
|
||||
// indicating whether the given engine is installed for the current user.
|
||||
// However, it is currently stubbed out due to security/privacy concerns
|
||||
// stemming from difficulties in determining what domain issued the request.
|
||||
// See bug 340604 and
|
||||
// http://msdn.microsoft.com/en-us/library/aa342526%28VS.85%29.aspx .
|
||||
// XXX Implement this!
|
||||
nsSidebar.prototype.IsSearchProviderInstalled =
|
||||
function (aSearchURL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
nsSidebar.prototype.QueryInterface = XPCOMUtils.generateQI([Components.interfaces.nsISupports]);
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([nsSidebar]);
|
||||
|
||||
/* static functions */
|
||||
if (DEBUG)
|
||||
debug = function (s) { dump("-*- sidebar component: " + s + "\n"); }
|
||||
else
|
||||
debug = function (s) {}
|
@ -1,2 +0,0 @@
|
||||
component {22117140-9c6e-11d3-aaf1-00805f8a4905} nsSidebar.js
|
||||
contract @mozilla.org/sidebar;1 {22117140-9c6e-11d3-aaf1-00805f8a4905}
|
@ -20,6 +20,12 @@ const RecordingModel = function (options={}) {
|
||||
this._front = options.front;
|
||||
this._performance = options.performance;
|
||||
this._label = options.label || "";
|
||||
|
||||
this._configuration = {
|
||||
withTicks: options.withTicks || false,
|
||||
withMemory: options.withMemory || false,
|
||||
withAllocations: options.withAllocations || false
|
||||
};
|
||||
};
|
||||
|
||||
RecordingModel.prototype = {
|
||||
@ -29,6 +35,7 @@ RecordingModel.prototype = {
|
||||
_profilerStartTime: 0,
|
||||
_timelineStartTime: 0,
|
||||
_memoryStartTime: 0,
|
||||
_configuration: {},
|
||||
|
||||
// Serializable fields, necessary and sufficient for import and export.
|
||||
_label: "",
|
||||
@ -99,12 +106,9 @@ RecordingModel.prototype = {
|
||||
|
||||
/**
|
||||
* Stops recording with the PerformanceFront.
|
||||
*
|
||||
* @param object options
|
||||
* @see RecordingModel.prototype.startRecording
|
||||
*/
|
||||
stopRecording: Task.async(function *(options) {
|
||||
let info = yield this._front.stopRecording(options);
|
||||
stopRecording: Task.async(function *() {
|
||||
let info = yield this._front.stopRecording(this.getConfiguration());
|
||||
this._profile = info.profile;
|
||||
this._duration = info.profilerEndTime - this._profilerStartTime;
|
||||
this._recording = false;
|
||||
@ -143,6 +147,15 @@ RecordingModel.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns configuration object of specifying whether the recording
|
||||
* was started withTicks, withMemory and withAllocations.
|
||||
* @return object
|
||||
*/
|
||||
getConfiguration: function () {
|
||||
return this._configuration;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the accumulated markers in the current recording.
|
||||
* @return array
|
||||
|
@ -58,11 +58,10 @@ const BRANCH_NAME = "devtools.performance.ui.";
|
||||
// Events emitted by various objects in the panel.
|
||||
const EVENTS = {
|
||||
// Fired by the OptionsView when a preference changes.
|
||||
PREF_CHANGED: "Preformance:PrefChanged",
|
||||
PREF_CHANGED: "Performance:PrefChanged",
|
||||
|
||||
// Emitted by the PerformanceController or RecordingView
|
||||
// when a recording model is selected
|
||||
RECORDING_SELECTED: "Performance:RecordingSelected",
|
||||
// Emitted by the PerformanceView when the state (display mode) changes.
|
||||
UI_STATE_CHANGED: "Performance:UI:StateChanged",
|
||||
|
||||
// Emitted by the PerformanceView on clear button click
|
||||
UI_CLEAR_RECORDINGS: "Performance:UI:ClearRecordings",
|
||||
@ -82,6 +81,10 @@ const EVENTS = {
|
||||
RECORDING_WILL_START: "Performance:RecordingWillStart",
|
||||
RECORDING_WILL_STOP: "Performance:RecordingWillStop",
|
||||
|
||||
// Emitted by the PerformanceController or RecordingView
|
||||
// when a recording model is selected
|
||||
RECORDING_SELECTED: "Performance:RecordingSelected",
|
||||
|
||||
// When recordings have been cleared out
|
||||
RECORDINGS_CLEARED: "Performance:RecordingsCleared",
|
||||
|
||||
@ -220,15 +223,15 @@ let PerformanceController = {
|
||||
* when the front has started to record.
|
||||
*/
|
||||
startRecording: Task.async(function *() {
|
||||
let recording = this._createRecording();
|
||||
|
||||
let withMemory = this.getPref("enable-memory");
|
||||
let withTicks = this.getPref("enable-framerate");
|
||||
let withAllocations = true;
|
||||
let withAllocations = this.getPref("enable-memory");
|
||||
|
||||
let recording = this._createRecording({ withMemory, withTicks, withAllocations });
|
||||
|
||||
this.emit(EVENTS.RECORDING_WILL_START, recording);
|
||||
yield recording.startRecording({ withTicks, withMemory, withAllocations });
|
||||
this.emit(EVENTS.RECORDING_STARTED, recording, { withTicks, withMemory, withAllocations });
|
||||
this.emit(EVENTS.RECORDING_STARTED, recording);
|
||||
|
||||
this.setCurrentRecording(recording);
|
||||
}),
|
||||
@ -241,9 +244,7 @@ let PerformanceController = {
|
||||
let recording = this._getLatestRecording();
|
||||
|
||||
this.emit(EVENTS.RECORDING_WILL_STOP, recording);
|
||||
yield recording.stopRecording({
|
||||
withAllocations: true
|
||||
});
|
||||
yield recording.stopRecording();
|
||||
this.emit(EVENTS.RECORDING_STOPPED, recording);
|
||||
}),
|
||||
|
||||
@ -295,11 +296,18 @@ let PerformanceController = {
|
||||
* Creates a new RecordingModel, fires events and stores it
|
||||
* internally in the controller.
|
||||
*
|
||||
* @param object options
|
||||
* @see PerformanceFront.prototype.startRecording
|
||||
* @return RecordingModel
|
||||
* The newly created recording model.
|
||||
*/
|
||||
_createRecording: function () {
|
||||
let recording = new RecordingModel({ front: gFront, performance });
|
||||
_createRecording: function (options={}) {
|
||||
let { withMemory, withTicks, withAllocations } = options;
|
||||
let front = gFront;
|
||||
|
||||
let recording = new RecordingModel(
|
||||
{ front, performance, withMemory, withTicks, withAllocations });
|
||||
|
||||
this._recordings.push(recording);
|
||||
return recording;
|
||||
},
|
||||
|
@ -29,7 +29,7 @@ let PerformanceView = {
|
||||
/**
|
||||
* Sets up the view with event binding and main subviews.
|
||||
*/
|
||||
initialize: function () {
|
||||
initialize: Task.async(function* () {
|
||||
this._recordButton = $("#main-record-button");
|
||||
this._importButton = $("#import-button");
|
||||
this._clearButton = $("#clear-button");
|
||||
@ -59,22 +59,23 @@ let PerformanceView = {
|
||||
|
||||
this.setState("empty");
|
||||
|
||||
return promise.all([
|
||||
RecordingsView.initialize(),
|
||||
OverviewView.initialize(),
|
||||
ToolbarView.initialize(),
|
||||
DetailsView.initialize()
|
||||
]);
|
||||
},
|
||||
// Initialize the ToolbarView first, because other views may need access
|
||||
// to the OptionsView via the controller, to read prefs.
|
||||
yield ToolbarView.initialize();
|
||||
yield RecordingsView.initialize();
|
||||
yield OverviewView.initialize();
|
||||
yield DetailsView.initialize();
|
||||
}),
|
||||
|
||||
/**
|
||||
* Unbinds events and destroys subviews.
|
||||
*/
|
||||
destroy: function () {
|
||||
destroy: Task.async(function* () {
|
||||
for (let button of $$(".record-button")) {
|
||||
button.removeEventListener("click", this._onRecordButtonClick);
|
||||
}
|
||||
this._importButton.removeEventListener("click", this._onImportButtonClick);
|
||||
this._clearButton.removeEventListener("click", this._onClearButtonClick);
|
||||
|
||||
PerformanceController.off(EVENTS.RECORDING_WILL_START, this._onRecordingWillStart);
|
||||
PerformanceController.off(EVENTS.RECORDING_WILL_STOP, this._onRecordingWillStop);
|
||||
@ -82,13 +83,11 @@ let PerformanceView = {
|
||||
PerformanceController.off(EVENTS.RECORDING_STOPPED, this._onRecordingStopped);
|
||||
PerformanceController.off(EVENTS.RECORDING_SELECTED, this._onRecordingSelected);
|
||||
|
||||
return promise.all([
|
||||
RecordingsView.destroy(),
|
||||
OverviewView.destroy(),
|
||||
ToolbarView.destroy(),
|
||||
DetailsView.destroy()
|
||||
]);
|
||||
},
|
||||
yield ToolbarView.destroy();
|
||||
yield RecordingsView.destroy();
|
||||
yield OverviewView.destroy();
|
||||
yield DetailsView.destroy();
|
||||
}),
|
||||
|
||||
/**
|
||||
* Sets the state of the profiler view. Possible options are "empty",
|
||||
@ -104,6 +103,7 @@ let PerformanceView = {
|
||||
}
|
||||
|
||||
this._state = state;
|
||||
this.emit(EVENTS.UI_STATE_CHANGED, state);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -50,6 +50,11 @@
|
||||
data-pref="invert-call-tree"
|
||||
label="&profilerUI.invertTree;"
|
||||
tooltiptext="&profilerUI.invertTree.tooltiptext;"/>
|
||||
<menuitem id="option-invert-flame-graph"
|
||||
type="checkbox"
|
||||
data-pref="invert-flame-graph"
|
||||
label="&profilerUI.invertFlameGraph;"
|
||||
tooltiptext="&profilerUI.invertFlameGraph.tooltiptext;"/>
|
||||
<menuitem id="option-flatten-tree-recursion"
|
||||
type="checkbox"
|
||||
data-pref="flatten-tree-recursion"
|
||||
|
@ -21,6 +21,7 @@ support-files =
|
||||
[browser_perf-details-waterfall-render.js]
|
||||
[browser_perf-details-01.js]
|
||||
[browser_perf-details-02.js]
|
||||
[browser_perf-details-03.js]
|
||||
[browser_perf-front-basic-profiler-01.js]
|
||||
[browser_perf-front-basic-timeline-01.js]
|
||||
#[browser_perf-front-profiler-01.js] bug 1077464
|
||||
@ -36,13 +37,16 @@ support-files =
|
||||
[browser_perf-options-02.js]
|
||||
[browser_perf-options-invert-call-tree-01.js]
|
||||
[browser_perf-options-invert-call-tree-02.js]
|
||||
[browser_perf-options-invert-flame-graph-01.js]
|
||||
[browser_perf-options-invert-flame-graph-02.js]
|
||||
[browser_perf-options-flatten-tree-recursion-01.js]
|
||||
[browser_perf-options-flatten-tree-recursion-02.js]
|
||||
[browser_perf-options-show-platform-data-01.js]
|
||||
[browser_perf-options-show-platform-data-02.js]
|
||||
[browser_perf-options-show-idle-blocks-01.js]
|
||||
[browser_perf-options-show-idle-blocks-02.js]
|
||||
[browser_perf-options-enable-memory.js]
|
||||
[browser_perf-options-enable-memory-01.js]
|
||||
[browser_perf-options-enable-memory-02.js]
|
||||
[browser_perf-options-enable-framerate.js]
|
||||
[browser_perf-overview-render-01.js]
|
||||
[browser_perf-overview-render-02.js]
|
||||
@ -53,6 +57,7 @@ support-files =
|
||||
[browser_perf-overview-time-interval.js]
|
||||
[browser_perf-shared-connection-02.js]
|
||||
[browser_perf-shared-connection-03.js]
|
||||
[browser_perf-states.js]
|
||||
[browser_perf-ui-recording.js]
|
||||
[browser_perf-recording-notices-01.js]
|
||||
[browser_perf-recording-notices-02.js]
|
||||
|
@ -20,22 +20,19 @@ let TEST_DATA = {
|
||||
sites: [0, 0, 1, 2, 3],
|
||||
timestamps: [50, 100, 150, 200, 250],
|
||||
frames: [
|
||||
null,
|
||||
{
|
||||
null, {
|
||||
source: "A",
|
||||
line: 1,
|
||||
column: 2,
|
||||
functionDisplayName: "x",
|
||||
parent: 0
|
||||
},
|
||||
{
|
||||
}, {
|
||||
source: "B",
|
||||
line: 3,
|
||||
column: 4,
|
||||
functionDisplayName: "y",
|
||||
parent: 1
|
||||
},
|
||||
{
|
||||
}, {
|
||||
source: "C",
|
||||
line: 5,
|
||||
column: 6,
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
let test = Task.async(function*() {
|
||||
let { target, panel, toolbox } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, PerformanceController, PerformanceView, RecordingsView } = panel.panelWin;
|
||||
let { EVENTS, PerformanceController, PerformanceView, RecordingsView, OverviewView } = panel.panelWin;
|
||||
|
||||
yield startRecording(panel);
|
||||
yield stopRecording(panel);
|
||||
|
@ -14,7 +14,7 @@ function spawnTest () {
|
||||
|
||||
let selected = DetailsView.whenViewSelected(JsCallTreeView);
|
||||
let notified = DetailsView.once(EVENTS.DETAILS_VIEW_SELECTED);
|
||||
DetailsView.selectView("js-calltree");
|
||||
yield DetailsView.selectView("js-calltree");
|
||||
yield Promise.all([selected, notified]);
|
||||
|
||||
ok(DetailsView.isViewSelected(JsCallTreeView),
|
||||
@ -22,7 +22,7 @@ function spawnTest () {
|
||||
|
||||
selected = DetailsView.whenViewSelected(JsFlameGraphView);
|
||||
notified = DetailsView.once(EVENTS.DETAILS_VIEW_SELECTED);
|
||||
DetailsView.selectView("js-flamegraph");
|
||||
yield DetailsView.selectView("js-flamegraph");
|
||||
yield Promise.all([selected, notified]);
|
||||
|
||||
ok(DetailsView.isViewSelected(JsFlameGraphView),
|
||||
@ -30,7 +30,7 @@ function spawnTest () {
|
||||
|
||||
selected = DetailsView.whenViewSelected(WaterfallView);
|
||||
notified = DetailsView.once(EVENTS.DETAILS_VIEW_SELECTED);
|
||||
DetailsView.selectView("waterfall");
|
||||
yield DetailsView.selectView("waterfall");
|
||||
yield Promise.all([selected, notified]);
|
||||
|
||||
ok(DetailsView.isViewSelected(WaterfallView),
|
||||
|
58
browser/devtools/performance/test/browser_perf-details-03.js
Normal file
58
browser/devtools/performance/test/browser_perf-details-03.js
Normal file
@ -0,0 +1,58 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
let MEMORY_PREF = "devtools.performance.ui.enable-memory";
|
||||
|
||||
/**
|
||||
* Tests that the details view hides the memory buttons when `enable-memory` is toggled,
|
||||
* and that it switches to default panel if toggling while a memory panel is selected.
|
||||
*/
|
||||
function spawnTest () {
|
||||
let { panel } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, DetailsView } = panel.panelWin;
|
||||
let { $, WaterfallView, MemoryCallTreeView, MemoryFlameGraphView } = panel.panelWin;
|
||||
|
||||
Services.prefs.setBoolPref(MEMORY_PREF, false);
|
||||
|
||||
ok(DetailsView.isViewSelected(WaterfallView),
|
||||
"The waterfall view is selected by default in the details view.");
|
||||
|
||||
let flameBtn = $("toolbarbutton[data-view='memory-flamegraph']");
|
||||
let callBtn = $("toolbarbutton[data-view='memory-calltree']");
|
||||
|
||||
is(flameBtn.hidden, true, "memory-flamegraph button hidden when enable-memory=false");
|
||||
is(callBtn.hidden, true, "memory-calltree button hidden when enable-memory=false");
|
||||
|
||||
Services.prefs.setBoolPref(MEMORY_PREF, true);
|
||||
|
||||
is(flameBtn.hidden, false, "memory-flamegraph button shown when enable-memory=true");
|
||||
is(callBtn.hidden, false, "memory-calltree button shown when enable-memory=true");
|
||||
|
||||
let selected = DetailsView.whenViewSelected(MemoryCallTreeView);
|
||||
let notified = DetailsView.once(EVENTS.DETAILS_VIEW_SELECTED);
|
||||
DetailsView.selectView("memory-calltree");
|
||||
yield Promise.all([selected, notified]);
|
||||
|
||||
selected = DetailsView.whenViewSelected(WaterfallView);
|
||||
notified = DetailsView.once(EVENTS.DETAILS_VIEW_SELECTED);
|
||||
Services.prefs.setBoolPref(MEMORY_PREF, false);
|
||||
yield Promise.all([selected, notified]);
|
||||
|
||||
ok(DetailsView.isViewSelected(WaterfallView),
|
||||
"The waterfall view is now selected when toggling off enable-memory when a memory panel is selected.");
|
||||
|
||||
Services.prefs.setBoolPref(MEMORY_PREF, true);
|
||||
|
||||
selected = DetailsView.whenViewSelected(MemoryFlameGraphView);
|
||||
notified = DetailsView.once(EVENTS.DETAILS_VIEW_SELECTED);
|
||||
DetailsView.selectView("memory-flamegraph");
|
||||
yield Promise.all([selected, notified]);
|
||||
|
||||
selected = DetailsView.whenViewSelected(WaterfallView);
|
||||
notified = DetailsView.once(EVENTS.DETAILS_VIEW_SELECTED);
|
||||
Services.prefs.setBoolPref(MEMORY_PREF, false);
|
||||
yield Promise.all([selected, notified]);
|
||||
|
||||
yield teardown(panel);
|
||||
finish();
|
||||
}
|
@ -8,7 +8,7 @@ function spawnTest () {
|
||||
let { panel } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, DetailsView, JsCallTreeView } = panel.panelWin;
|
||||
|
||||
DetailsView.selectView("js-calltree");
|
||||
yield DetailsView.selectView("js-calltree");
|
||||
ok(DetailsView.isViewSelected(JsCallTreeView), "The call tree is now selected.");
|
||||
|
||||
yield startRecording(panel);
|
||||
|
@ -8,7 +8,7 @@ function spawnTest () {
|
||||
let { panel } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, DetailsView, JsFlameGraphView } = panel.panelWin;
|
||||
|
||||
DetailsView.selectView("js-flamegraph");
|
||||
yield DetailsView.selectView("js-flamegraph");
|
||||
ok(DetailsView.isViewSelected(JsFlameGraphView), "The flamegraph is now selected.");
|
||||
|
||||
yield startRecording(panel);
|
||||
|
@ -8,7 +8,7 @@ function spawnTest () {
|
||||
let { panel } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, DetailsView, MemoryCallTreeView } = panel.panelWin;
|
||||
|
||||
DetailsView.selectView("memory-calltree");
|
||||
yield DetailsView.selectView("memory-calltree");
|
||||
ok(DetailsView.isViewSelected(MemoryCallTreeView), "The call tree is now selected.");
|
||||
|
||||
yield startRecording(panel);
|
||||
|
@ -8,7 +8,7 @@ function spawnTest () {
|
||||
let { panel } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, DetailsView, MemoryFlameGraphView } = panel.panelWin;
|
||||
|
||||
DetailsView.selectView("memory-flamegraph");
|
||||
yield DetailsView.selectView("memory-flamegraph");
|
||||
ok(DetailsView.isViewSelected(MemoryFlameGraphView), "The flamegraph is now selected.");
|
||||
|
||||
yield startRecording(panel);
|
||||
|
@ -10,16 +10,36 @@ let WAIT_TIME = 1000;
|
||||
function spawnTest () {
|
||||
let { target, front } = yield initBackend(SIMPLE_URL);
|
||||
|
||||
let { profilerStartTime, timelineStartTime } = yield front.startRecording();
|
||||
let startData = yield front.startRecording();
|
||||
let { profilerStartTime, timelineStartTime, memoryStartTime } = startData;
|
||||
|
||||
ok("profilerStartTime" in startData,
|
||||
"A `profilerStartTime` property is properly set in the recording data.");
|
||||
ok("timelineStartTime" in startData,
|
||||
"A `timelineStartTime` property is properly set in the recording data.");
|
||||
ok("memoryStartTime" in startData,
|
||||
"A `memoryStartTime` property is properly set in the recording data.");
|
||||
|
||||
ok(profilerStartTime !== undefined,
|
||||
"A `profilerStartTime` property exists in the recording data.");
|
||||
ok(timelineStartTime !== undefined,
|
||||
"A `timelineStartTime` property exists in the recording data.");
|
||||
is(memoryStartTime, 0,
|
||||
"A `memoryStartTime` property exists in the recording data, but it's 0.");
|
||||
|
||||
yield busyWait(WAIT_TIME);
|
||||
|
||||
let { profile, profilerEndTime, timelineEndTime } = yield front.stopRecording();
|
||||
let stopData = yield front.stopRecording();
|
||||
let { profile, profilerEndTime, timelineEndTime, memoryEndTime } = stopData;
|
||||
|
||||
ok("profile" in stopData,
|
||||
"A `profile` property is properly set in the recording data.");
|
||||
ok("profilerEndTime" in stopData,
|
||||
"A `profilerEndTime` property is properly set in the recording data.");
|
||||
ok("timelineEndTime" in stopData,
|
||||
"A `timelineEndTime` property is properly set in the recording data.");
|
||||
ok("memoryEndTime" in stopData,
|
||||
"A `memoryEndTime` property is properly set in the recording data.");
|
||||
|
||||
ok(profile,
|
||||
"A `profile` property exists in the recording data.");
|
||||
@ -27,6 +47,8 @@ function spawnTest () {
|
||||
"A `profilerEndTime` property exists in the recording data.");
|
||||
ok(timelineEndTime !== undefined,
|
||||
"A `timelineEndTime` property exists in the recording data.");
|
||||
is(memoryEndTime, 0,
|
||||
"A `memoryEndTime` property exists in the recording data, but it's 0.");
|
||||
|
||||
yield removeTab(target.tab);
|
||||
finish();
|
||||
|
@ -28,9 +28,7 @@ function spawnTest () {
|
||||
front.on("ticks", handler);
|
||||
|
||||
yield front.startRecording({ withMemory: true, withTicks: true });
|
||||
|
||||
yield Promise.all(Object.keys(deferreds).map(type => deferreds[type].promise));
|
||||
|
||||
yield front.stopRecording();
|
||||
|
||||
is(counters.markers.length, 1, "one marker event fired.");
|
||||
|
@ -2,8 +2,8 @@
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if the performance tool can jump to the debugger, when the source was already
|
||||
* loaded in that tool.
|
||||
* Tests if the performance tool can jump to the debugger, when the source was
|
||||
* already loaded in that tool.
|
||||
*/
|
||||
|
||||
function spawnTest() {
|
||||
|
@ -8,7 +8,7 @@ function spawnTest () {
|
||||
let { panel } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, DetailsView, JsCallTreeView } = panel.panelWin;
|
||||
|
||||
DetailsView.selectView("js-calltree");
|
||||
yield DetailsView.selectView("js-calltree");
|
||||
|
||||
// Manually call the _onPrefChanged function so we can catch an error
|
||||
try {
|
||||
|
@ -8,7 +8,7 @@ function spawnTest () {
|
||||
let { panel } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, DetailsView, JsCallTreeView } = panel.panelWin;
|
||||
|
||||
DetailsView.selectView("js-calltree");
|
||||
yield DetailsView.selectView("js-calltree");
|
||||
|
||||
yield startRecording(panel);
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const FRAMERATE_PREF = "devtools.performance.ui.enable-framerate";
|
||||
|
||||
/**
|
||||
* Tests that `enable-framerate` toggles the visibility of the fps graph,
|
||||
* as well as enabling ticks data on the PerformanceFront.
|
||||
@ -11,20 +9,14 @@ function spawnTest () {
|
||||
let { panel } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, PerformanceController, $ } = panel.panelWin;
|
||||
|
||||
let recordedWithTicks = null;
|
||||
|
||||
let onStart = (_, recording, { withMemory, withTicks }) => {
|
||||
recordedWithTicks = withTicks;
|
||||
};
|
||||
PerformanceController.on(EVENTS.RECORDING_STARTED, onStart);
|
||||
|
||||
Services.prefs.setBoolPref(FRAMERATE_PREF, false);
|
||||
ok($("#time-framerate").hidden, "fps graph is hidden when ticks disabled");
|
||||
|
||||
yield startRecording(panel);
|
||||
yield stopRecording(panel);
|
||||
|
||||
ok(recordedWithTicks === false, "PerformanceFront started without ticks recording.");
|
||||
is(PerformanceController.getCurrentRecording().getConfiguration().withTicks, false,
|
||||
"PerformanceFront started without ticks recording.");
|
||||
|
||||
Services.prefs.setBoolPref(FRAMERATE_PREF, true);
|
||||
ok(!$("#time-framerate").hidden, "fps graph is not hidden when ticks enabled");
|
||||
@ -32,9 +24,9 @@ function spawnTest () {
|
||||
yield startRecording(panel);
|
||||
yield stopRecording(panel);
|
||||
|
||||
ok(recordedWithTicks === true, "PerformanceFront started with ticks recording.");
|
||||
is(PerformanceController.getCurrentRecording().getConfiguration().withTicks, true,
|
||||
"PerformanceFront started with ticks recording.");
|
||||
|
||||
PerformanceController.off(EVENTS.RECORDING_STARTED, onStart);
|
||||
yield teardown(panel);
|
||||
finish();
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const MEMORY_PREF = "devtools.performance.ui.enable-memory";
|
||||
|
||||
/**
|
||||
* Tests that `enable-memory` toggles the visibility of the memory graph,
|
||||
* as well as enabling memory data on the PerformanceFront.
|
||||
@ -11,20 +9,16 @@ function spawnTest () {
|
||||
let { panel } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, PerformanceController, $ } = panel.panelWin;
|
||||
|
||||
let recordedWithMemory = null;
|
||||
|
||||
let onStart = (_, recording, { withMemory, withTicks }) => {
|
||||
recordedWithMemory = withMemory;
|
||||
};
|
||||
PerformanceController.on(EVENTS.RECORDING_STARTED, onStart);
|
||||
|
||||
Services.prefs.setBoolPref(MEMORY_PREF, false);
|
||||
ok($("#memory-overview").hidden, "memory graph is hidden when memory disabled");
|
||||
|
||||
yield startRecording(panel);
|
||||
yield stopRecording(panel);
|
||||
|
||||
ok(recordedWithMemory === false, "PerformanceFront started without memory recording.");
|
||||
is(PerformanceController.getCurrentRecording().getConfiguration().withMemory, false,
|
||||
"PerformanceFront started without memory recording.");
|
||||
is(PerformanceController.getCurrentRecording().getConfiguration().withAllocations, false,
|
||||
"PerformanceFront started without allocations recording.");
|
||||
|
||||
Services.prefs.setBoolPref(MEMORY_PREF, true);
|
||||
ok(!$("#memory-overview").hidden, "memory graph is not hidden when memory enabled");
|
||||
@ -32,9 +26,11 @@ function spawnTest () {
|
||||
yield startRecording(panel);
|
||||
yield stopRecording(panel);
|
||||
|
||||
ok(recordedWithMemory === true, "PerformanceFront started with memory recording.");
|
||||
is(PerformanceController.getCurrentRecording().getConfiguration().withMemory, true,
|
||||
"PerformanceFront started with memory recording.");
|
||||
is(PerformanceController.getCurrentRecording().getConfiguration().withAllocations, true,
|
||||
"PerformanceFront started with allocations recording.");
|
||||
|
||||
PerformanceController.off(EVENTS.RECORDING_STARTED, onStart);
|
||||
yield teardown(panel);
|
||||
finish();
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that toggling `enable-memory` during a recording doesn't change that
|
||||
* recording's state and does not break.
|
||||
*/
|
||||
function spawnTest () {
|
||||
let { panel } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, PerformanceController, $ } = panel.panelWin;
|
||||
|
||||
// Test starting without memory, and stopping with it.
|
||||
Services.prefs.setBoolPref(MEMORY_PREF, false);
|
||||
yield startRecording(panel);
|
||||
|
||||
Services.prefs.setBoolPref(MEMORY_PREF, true);
|
||||
yield stopRecording(panel);
|
||||
|
||||
is(PerformanceController.getCurrentRecording().getConfiguration().withMemory, false,
|
||||
"The recording finished without tracking memory.");
|
||||
is(PerformanceController.getCurrentRecording().getConfiguration().withAllocations, false,
|
||||
"The recording finished without tracking allocations.");
|
||||
|
||||
// Test starting with memory, and stopping without it.
|
||||
yield startRecording(panel);
|
||||
Services.prefs.setBoolPref(MEMORY_PREF, false);
|
||||
yield stopRecording(panel);
|
||||
|
||||
is(PerformanceController.getCurrentRecording().getConfiguration().withMemory, true,
|
||||
"The recording finished with tracking memory.");
|
||||
is(PerformanceController.getCurrentRecording().getConfiguration().withAllocations, true,
|
||||
"The recording finished with tracking allocations.");
|
||||
|
||||
yield teardown(panel);
|
||||
finish();
|
||||
}
|
@ -1,19 +1,17 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const FLATTEN_PREF = "devtools.performance.ui.flatten-tree-recursion";
|
||||
|
||||
/**
|
||||
* Tests that the js Flamegraphs gets rerendered when toggling `flatten-tree-recursion`
|
||||
* Tests that the js flamegraphs get rerendered when toggling `flatten-tree-recursion`
|
||||
*/
|
||||
function spawnTest () {
|
||||
let { panel } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, DetailsView, JsFlameGraphView } = panel.panelWin;
|
||||
|
||||
DetailsView.selectView("js-flamegraph");
|
||||
let { EVENTS, PerformanceController, DetailsView, JsFlameGraphView } = panel.panelWin;
|
||||
|
||||
Services.prefs.setBoolPref(FLATTEN_PREF, true);
|
||||
|
||||
yield DetailsView.selectView("js-flamegraph");
|
||||
|
||||
yield startRecording(panel);
|
||||
yield busyWait(100);
|
||||
|
||||
@ -21,18 +19,42 @@ function spawnTest () {
|
||||
yield stopRecording(panel);
|
||||
yield rendered;
|
||||
|
||||
let samples1 = PerformanceController.getCurrentRecording().getProfile().threads[0].samples;
|
||||
let rendering1 = FlameGraphUtils._cache.get(samples1);
|
||||
|
||||
ok(samples1,
|
||||
"The samples were retrieved from the controller.");
|
||||
ok(rendering1,
|
||||
"The rendering data was cached.");
|
||||
|
||||
rendered = once(JsFlameGraphView, EVENTS.JS_FLAMEGRAPH_RENDERED);
|
||||
Services.prefs.setBoolPref(FLATTEN_PREF, false);
|
||||
yield rendered;
|
||||
|
||||
ok(true, "JsFlameGraphView rerendered when toggling flatten-tree-recursion.");
|
||||
|
||||
let samples2 = PerformanceController.getCurrentRecording().getProfile().threads[0].samples;
|
||||
let rendering2 = FlameGraphUtils._cache.get(samples2);
|
||||
|
||||
is(samples1, samples2,
|
||||
"The same samples data should be retrieved from the controller (1).");
|
||||
isnot(rendering1, rendering2,
|
||||
"The rendering data should be different because other options were used (1).");
|
||||
|
||||
rendered = once(JsFlameGraphView, EVENTS.JS_FLAMEGRAPH_RENDERED);
|
||||
Services.prefs.setBoolPref(FLATTEN_PREF, true);
|
||||
yield rendered;
|
||||
|
||||
ok(true, "JsFlameGraphView rerendered when toggling back flatten-tree-recursion.");
|
||||
|
||||
let samples3 = PerformanceController.getCurrentRecording().getProfile().threads[0].samples;
|
||||
let rendering3 = FlameGraphUtils._cache.get(samples3);
|
||||
|
||||
is(samples2, samples3,
|
||||
"The same samples data should be retrieved from the controller (2).");
|
||||
isnot(rendering2, rendering3,
|
||||
"The rendering data should be different because other options were used (2).");
|
||||
|
||||
yield teardown(panel);
|
||||
finish();
|
||||
}
|
||||
|
@ -1,19 +1,19 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const FLATTEN_PREF = "devtools.performance.ui.flatten-tree-recursion";
|
||||
|
||||
/**
|
||||
* Tests that the memory Flamegraphs gets rerendered when toggling `flatten-tree-recursion`
|
||||
* Tests that the memory flamegraphs get rerendered when toggling `flatten-tree-recursion`
|
||||
*/
|
||||
function spawnTest () {
|
||||
let { panel } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, DetailsView, MemoryFlameGraphView } = panel.panelWin;
|
||||
|
||||
DetailsView.selectView("memory-flamegraph");
|
||||
let { EVENTS, PerformanceController, DetailsView, MemoryFlameGraphView } = panel.panelWin;
|
||||
|
||||
// Enable memory to test
|
||||
Services.prefs.setBoolPref(MEMORY_PREF, true);
|
||||
Services.prefs.setBoolPref(FLATTEN_PREF, true);
|
||||
|
||||
yield DetailsView.selectView("memory-flamegraph");
|
||||
|
||||
yield startRecording(panel);
|
||||
yield busyWait(100);
|
||||
|
||||
@ -21,18 +21,51 @@ function spawnTest () {
|
||||
yield stopRecording(panel);
|
||||
yield rendered;
|
||||
|
||||
let allocations1 = PerformanceController.getCurrentRecording().getAllocations();
|
||||
let samples1 = RecordingUtils.getSamplesFromAllocations(allocations1);
|
||||
let rendering1 = FlameGraphUtils._cache.get(samples1);
|
||||
|
||||
ok(allocations1,
|
||||
"The allocations were retrieved from the controller.");
|
||||
ok(samples1,
|
||||
"The samples were retrieved from the utility funcs.");
|
||||
ok(rendering1,
|
||||
"The rendering data was cached.");
|
||||
|
||||
rendered = once(MemoryFlameGraphView, EVENTS.MEMORY_FLAMEGRAPH_RENDERED);
|
||||
Services.prefs.setBoolPref(FLATTEN_PREF, false);
|
||||
yield rendered;
|
||||
|
||||
ok(true, "MemoryFlameGraphView rerendered when toggling flatten-tree-recursion.");
|
||||
|
||||
let allocations2 = PerformanceController.getCurrentRecording().getAllocations();
|
||||
let samples2 = RecordingUtils.getSamplesFromAllocations(allocations2);
|
||||
let rendering2 = FlameGraphUtils._cache.get(samples2);
|
||||
|
||||
is(allocations1, allocations2,
|
||||
"The same allocations data should be retrieved from the controller (1).");
|
||||
is(samples1, samples2,
|
||||
"The same samples data should be retrieved from the utility funcs. (1).");
|
||||
isnot(rendering1, rendering2,
|
||||
"The rendering data should be different because other options were used (1).");
|
||||
|
||||
rendered = once(MemoryFlameGraphView, EVENTS.MEMORY_FLAMEGRAPH_RENDERED);
|
||||
Services.prefs.setBoolPref(FLATTEN_PREF, true);
|
||||
yield rendered;
|
||||
|
||||
ok(true, "MemoryFlameGraphView rerendered when toggling back flatten-tree-recursion.");
|
||||
|
||||
let allocations3 = PerformanceController.getCurrentRecording().getAllocations();
|
||||
let samples3 = RecordingUtils.getSamplesFromAllocations(allocations3);
|
||||
let rendering3 = FlameGraphUtils._cache.get(samples3);
|
||||
|
||||
is(allocations2, allocations3,
|
||||
"The same allocations data should be retrieved from the controller (2).");
|
||||
is(samples2, samples3,
|
||||
"The same samples data should be retrieved from the utility funcs. (2).");
|
||||
isnot(rendering2, rendering3,
|
||||
"The rendering data should be different because other options were used (2).");
|
||||
|
||||
yield teardown(panel);
|
||||
finish();
|
||||
}
|
||||
|
@ -1,11 +1,8 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const INVERT_PREF = "devtools.performance.ui.invert-call-tree";
|
||||
|
||||
/**
|
||||
* Tests that the js call tree view is re-rendered after the
|
||||
* "invert-call-tree" pref is changed.
|
||||
* Tests that the js call tree views get rerendered when toggling `invert-call-tree`
|
||||
*/
|
||||
function spawnTest () {
|
||||
let { panel } = yield initPerformance(SIMPLE_URL);
|
||||
@ -13,7 +10,7 @@ function spawnTest () {
|
||||
|
||||
Services.prefs.setBoolPref(INVERT_PREF, true);
|
||||
|
||||
DetailsView.selectView("js-calltree");
|
||||
yield DetailsView.selectView("js-calltree");
|
||||
ok(DetailsView.isViewSelected(JsCallTreeView), "The call tree is now selected.");
|
||||
|
||||
yield startRecording(panel);
|
||||
|
@ -1,19 +1,18 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const INVERT_PREF = "devtools.performance.ui.invert-call-tree";
|
||||
|
||||
/**
|
||||
* Tests that the memory call tree view is re-rendered after the
|
||||
* "invert-call-tree" pref is changed.
|
||||
* Tests that the memory call tree views get rerendered when toggling `invert-call-tree`
|
||||
*/
|
||||
function spawnTest () {
|
||||
let { panel } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, DetailsView, MemoryCallTreeView } = panel.panelWin;
|
||||
|
||||
// Enable memory to test
|
||||
Services.prefs.setBoolPref(MEMORY_PREF, true);
|
||||
Services.prefs.setBoolPref(INVERT_PREF, true);
|
||||
|
||||
DetailsView.selectView("memory-calltree");
|
||||
yield DetailsView.selectView("memory-calltree");
|
||||
ok(DetailsView.isViewSelected(MemoryCallTreeView), "The call tree is now selected.");
|
||||
|
||||
yield startRecording(panel);
|
||||
|
@ -0,0 +1,38 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const INVERT_PREF = "devtools.performance.ui.invert-flame-graph";
|
||||
|
||||
/**
|
||||
* Tests that the js Flamegraphs gets rerendered when toggling `invert-flame-graph`
|
||||
*/
|
||||
function spawnTest () {
|
||||
let { panel } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, DetailsView, JsFlameGraphView } = panel.panelWin;
|
||||
|
||||
yield DetailsView.selectView("js-flamegraph");
|
||||
|
||||
Services.prefs.setBoolPref(INVERT_PREF, true);
|
||||
|
||||
yield startRecording(panel);
|
||||
yield busyWait(100);
|
||||
|
||||
let rendered = once(JsFlameGraphView, EVENTS.JS_FLAMEGRAPH_RENDERED);
|
||||
yield stopRecording(panel);
|
||||
yield rendered;
|
||||
|
||||
rendered = once(JsFlameGraphView, EVENTS.JS_FLAMEGRAPH_RENDERED);
|
||||
Services.prefs.setBoolPref(INVERT_PREF, false);
|
||||
yield rendered;
|
||||
|
||||
ok(true, "JsFlameGraphView rerendered when toggling invert-flame-graph.");
|
||||
|
||||
rendered = once(JsFlameGraphView, EVENTS.JS_FLAMEGRAPH_RENDERED);
|
||||
Services.prefs.setBoolPref(INVERT_PREF, true);
|
||||
yield rendered;
|
||||
|
||||
ok(true, "JsFlameGraphView rerendered when toggling back invert-flame-graph.");
|
||||
|
||||
yield teardown(panel);
|
||||
finish();
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const INVERT_PREF = "devtools.performance.ui.invert-flame-graph";
|
||||
|
||||
/**
|
||||
* Tests that the memory Flamegraphs gets rerendered when toggling `invert-flame-graph`
|
||||
*/
|
||||
function spawnTest () {
|
||||
let { panel } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, DetailsView, MemoryFlameGraphView } = panel.panelWin;
|
||||
|
||||
yield DetailsView.selectView("memory-flamegraph");
|
||||
|
||||
Services.prefs.setBoolPref(INVERT_PREF, true);
|
||||
|
||||
yield startRecording(panel);
|
||||
yield busyWait(100);
|
||||
|
||||
let rendered = once(MemoryFlameGraphView, EVENTS.MEMORY_FLAMEGRAPH_RENDERED);
|
||||
yield stopRecording(panel);
|
||||
yield rendered;
|
||||
|
||||
rendered = once(MemoryFlameGraphView, EVENTS.MEMORY_FLAMEGRAPH_RENDERED);
|
||||
Services.prefs.setBoolPref(INVERT_PREF, false);
|
||||
yield rendered;
|
||||
|
||||
ok(true, "MemoryFlameGraphView rerendered when toggling invert-flame-graph.");
|
||||
|
||||
rendered = once(MemoryFlameGraphView, EVENTS.MEMORY_FLAMEGRAPH_RENDERED);
|
||||
Services.prefs.setBoolPref(INVERT_PREF, true);
|
||||
yield rendered;
|
||||
|
||||
ok(true, "MemoryFlameGraphView rerendered when toggling back invert-flame-graph.");
|
||||
|
||||
yield teardown(panel);
|
||||
finish();
|
||||
}
|
@ -1,19 +1,17 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const IDLE_PREF = "devtools.performance.ui.show-idle-blocks";
|
||||
|
||||
/**
|
||||
* Tests that the js Flamegraphs gets rerendered when toggling `show-idle-blocks`
|
||||
* Tests that the js flamegraphs get rerendered when toggling `show-idle-blocks`
|
||||
*/
|
||||
function spawnTest () {
|
||||
let { panel } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, DetailsView, JsFlameGraphView } = panel.panelWin;
|
||||
|
||||
DetailsView.selectView("js-flamegraph");
|
||||
|
||||
Services.prefs.setBoolPref(IDLE_PREF, true);
|
||||
|
||||
yield DetailsView.selectView("js-flamegraph");
|
||||
|
||||
yield startRecording(panel);
|
||||
yield busyWait(100);
|
||||
|
||||
|
@ -1,19 +1,19 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const IDLE_PREF = "devtools.performance.ui.show-idle-blocks";
|
||||
|
||||
/**
|
||||
* Tests that the memory Flamegraphs gets rerendered when toggling `show-idle-blocks`
|
||||
* Tests that the memory flamegraphs get rerendered when toggling `show-idle-blocks`
|
||||
*/
|
||||
function spawnTest () {
|
||||
let { panel } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, DetailsView, MemoryFlameGraphView } = panel.panelWin;
|
||||
|
||||
DetailsView.selectView("memory-flamegraph");
|
||||
|
||||
// Enable memory to test
|
||||
Services.prefs.setBoolPref(MEMORY_PREF, true);
|
||||
Services.prefs.setBoolPref(IDLE_PREF, true);
|
||||
|
||||
yield DetailsView.selectView("memory-flamegraph");
|
||||
|
||||
yield startRecording(panel);
|
||||
yield busyWait(100);
|
||||
|
||||
|
@ -1,19 +1,17 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const PLATFORM_DATA_PREF = "devtools.performance.ui.show-platform-data";
|
||||
|
||||
/**
|
||||
* Tests that the JsCallTree get rerendered when toggling `show-platform-data`
|
||||
* Tests that the js call tree views get rerendered when toggling `show-platform-data`
|
||||
*/
|
||||
function spawnTest () {
|
||||
let { panel } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, DetailsView, JsFlameGraphView, JsCallTreeView } = panel.panelWin;
|
||||
|
||||
DetailsView.selectView("js-calltree");
|
||||
let { EVENTS, DetailsView, JsCallTreeView } = panel.panelWin;
|
||||
|
||||
Services.prefs.setBoolPref(PLATFORM_DATA_PREF, true);
|
||||
|
||||
yield DetailsView.selectView("js-calltree");
|
||||
|
||||
yield startRecording(panel);
|
||||
yield busyWait(100);
|
||||
|
||||
|
@ -1,17 +1,16 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const PLATFORM_DATA_PREF = "devtools.performance.ui.show-platform-data";
|
||||
|
||||
/**
|
||||
* Tests that the JsFlamegraphs get rerendered when toggling `show-platform-data`
|
||||
* Tests that the js flamegraphs get rerendered when toggling `show-platform-data`
|
||||
*/
|
||||
function spawnTest () {
|
||||
let { panel } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, DetailsView, JsFlameGraphView } = panel.panelWin;
|
||||
|
||||
Services.prefs.setBoolPref(PLATFORM_DATA_PREF, false);
|
||||
DetailsView.selectView("js-flamegraph");
|
||||
|
||||
yield DetailsView.selectView("js-flamegraph");
|
||||
|
||||
yield startRecording(panel);
|
||||
yield busyWait(100);
|
||||
|
@ -8,6 +8,9 @@ function spawnTest () {
|
||||
let { panel } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, OverviewView } = panel.panelWin;
|
||||
|
||||
// Enable memory to test all the overview graphs.
|
||||
Services.prefs.setBoolPref(MEMORY_PREF, true);
|
||||
|
||||
yield startRecording(panel);
|
||||
|
||||
yield Promise.all([
|
||||
|
@ -9,8 +9,18 @@ function spawnTest () {
|
||||
let { panel } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, OverviewView } = panel.panelWin;
|
||||
|
||||
// Enable memory to test all the overview graphs.
|
||||
Services.prefs.setBoolPref(MEMORY_PREF, true);
|
||||
|
||||
yield startRecording(panel);
|
||||
|
||||
yield Promise.all([
|
||||
once(OverviewView, EVENTS.FRAMERATE_GRAPH_RENDERED),
|
||||
once(OverviewView, EVENTS.MARKERS_GRAPH_RENDERED),
|
||||
once(OverviewView, EVENTS.MEMORY_GRAPH_RENDERED),
|
||||
once(OverviewView, EVENTS.OVERVIEW_RENDERED),
|
||||
]);
|
||||
|
||||
ok("selectionEnabled" in OverviewView.framerateGraph,
|
||||
"The selection should not be enabled for the framerate overview (1).");
|
||||
is(OverviewView.framerateGraph.selectionEnabled, false,
|
||||
|
@ -8,8 +8,8 @@ function spawnTest () {
|
||||
let { panel } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, PerformanceController, OverviewView } = panel.panelWin;
|
||||
|
||||
Services.prefs.setBoolPref("devtools.performance.ui.enable-memory", true);
|
||||
Services.prefs.setBoolPref("devtools.performance.ui.enable-framerate", true);
|
||||
// Enable memory to test all the overview graphs.
|
||||
Services.prefs.setBoolPref(MEMORY_PREF, true);
|
||||
|
||||
yield startRecording(panel);
|
||||
|
||||
@ -24,9 +24,6 @@ function spawnTest () {
|
||||
|
||||
yield stopRecording(panel);
|
||||
|
||||
// Wait for the overview graph to be rerendered *after* recording.
|
||||
yield once(OverviewView, EVENTS.OVERVIEW_RENDERED);
|
||||
|
||||
ok(OverviewView.markersOverview.width > 0,
|
||||
"The overview's framerate graph has a width.");
|
||||
ok(OverviewView.markersOverview.dataScaleX > 0,
|
||||
|
@ -11,14 +11,14 @@ function spawnTest () {
|
||||
|
||||
yield startRecording(panel);
|
||||
|
||||
// Wait for the overview graph to be rendered while recording.
|
||||
yield once(OverviewView, EVENTS.OVERVIEW_RENDERED);
|
||||
yield Promise.all([
|
||||
once(OverviewView, EVENTS.FRAMERATE_GRAPH_RENDERED),
|
||||
once(OverviewView, EVENTS.MARKERS_GRAPH_RENDERED),
|
||||
once(OverviewView, EVENTS.OVERVIEW_RENDERED)
|
||||
]);
|
||||
|
||||
yield stopRecording(panel);
|
||||
|
||||
// Wait for the overview graph to be rerendered *after* recording.
|
||||
yield once(OverviewView, EVENTS.OVERVIEW_RENDERED);
|
||||
|
||||
let graph = OverviewView.markersOverview;
|
||||
let MAX = graph.width;
|
||||
|
||||
|
@ -7,12 +7,30 @@
|
||||
function spawnTest () {
|
||||
let { panel } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, OverviewView } = panel.panelWin;
|
||||
let framerateGraph = OverviewView.framerateGraph;
|
||||
let markersOverview = OverviewView.markersOverview;
|
||||
let memoryOverview = OverviewView.memoryOverview;
|
||||
|
||||
// Enable memory to test all the overview graphs.
|
||||
Services.prefs.setBoolPref(MEMORY_PREF, true);
|
||||
|
||||
yield startRecording(panel);
|
||||
|
||||
yield Promise.all([
|
||||
once(OverviewView, EVENTS.FRAMERATE_GRAPH_RENDERED),
|
||||
once(OverviewView, EVENTS.MARKERS_GRAPH_RENDERED),
|
||||
once(OverviewView, EVENTS.MEMORY_GRAPH_RENDERED),
|
||||
once(OverviewView, EVENTS.OVERVIEW_RENDERED),
|
||||
]);
|
||||
|
||||
let markersOverview = OverviewView.markersOverview;
|
||||
let memoryOverview = OverviewView.memoryOverview;
|
||||
let framerateGraph = OverviewView.framerateGraph;
|
||||
|
||||
ok(markersOverview,
|
||||
"The markers graph should have been created now.");
|
||||
ok(memoryOverview,
|
||||
"The memory graph should have been created now.");
|
||||
ok(framerateGraph,
|
||||
"The framerate graph should have been created now.");
|
||||
|
||||
ok(!framerateGraph.selectionEnabled,
|
||||
"Selection shouldn't be enabled when the first recording started (1).");
|
||||
ok(!markersOverview.selectionEnabled,
|
||||
@ -31,6 +49,13 @@ function spawnTest () {
|
||||
|
||||
yield startRecording(panel);
|
||||
|
||||
yield Promise.all([
|
||||
once(OverviewView, EVENTS.FRAMERATE_GRAPH_RENDERED),
|
||||
once(OverviewView, EVENTS.MARKERS_GRAPH_RENDERED),
|
||||
once(OverviewView, EVENTS.MEMORY_GRAPH_RENDERED),
|
||||
once(OverviewView, EVENTS.OVERVIEW_RENDERED),
|
||||
]);
|
||||
|
||||
ok(!framerateGraph.selectionEnabled,
|
||||
"Selection shouldn't be enabled when the second recording started (1).");
|
||||
ok(!markersOverview.selectionEnabled,
|
||||
|
@ -7,15 +7,26 @@
|
||||
function spawnTest () {
|
||||
let { panel } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, OverviewView } = panel.panelWin;
|
||||
|
||||
// Enable memory to test all the overview graphs.
|
||||
Services.prefs.setBoolPref(MEMORY_PREF, true);
|
||||
|
||||
yield startRecording(panel);
|
||||
|
||||
yield Promise.all([
|
||||
once(OverviewView, EVENTS.FRAMERATE_GRAPH_RENDERED),
|
||||
once(OverviewView, EVENTS.MARKERS_GRAPH_RENDERED),
|
||||
once(OverviewView, EVENTS.MEMORY_GRAPH_RENDERED),
|
||||
once(OverviewView, EVENTS.OVERVIEW_RENDERED),
|
||||
]);
|
||||
|
||||
yield stopRecording(panel);
|
||||
|
||||
let framerateGraph = OverviewView.framerateGraph;
|
||||
let markersOverview = OverviewView.markersOverview;
|
||||
let memoryOverview = OverviewView.memoryOverview;
|
||||
|
||||
let MAX = framerateGraph.width;
|
||||
|
||||
yield startRecording(panel);
|
||||
yield stopRecording(panel);
|
||||
|
||||
// Perform a selection inside the framerate graph.
|
||||
|
||||
let selected = once(OverviewView, EVENTS.OVERVIEW_RANGE_SELECTED);
|
||||
|
@ -24,11 +24,14 @@ function spawnTest () {
|
||||
}
|
||||
|
||||
yield startRecording(panel);
|
||||
busyWait(100);
|
||||
|
||||
let rendered = once(OverviewView, EVENTS.OVERVIEW_RENDERED);
|
||||
yield Promise.all([
|
||||
once(OverviewView, EVENTS.FRAMERATE_GRAPH_RENDERED),
|
||||
once(OverviewView, EVENTS.MARKERS_GRAPH_RENDERED),
|
||||
once(OverviewView, EVENTS.OVERVIEW_RENDERED)
|
||||
]);
|
||||
|
||||
yield stopRecording(panel);
|
||||
yield rendered;
|
||||
|
||||
// Get/set the time interval and wait for the event propagation.
|
||||
|
||||
|
@ -27,12 +27,12 @@ function spawnTest () {
|
||||
ok(true, "Waterfall rerenders when a range in the overview graph is selected.");
|
||||
|
||||
rendered = once(JsCallTreeView, EVENTS.JS_CALL_TREE_RENDERED);
|
||||
DetailsView.selectView("js-calltree");
|
||||
yield DetailsView.selectView("js-calltree");
|
||||
yield rendered;
|
||||
ok(true, "Call tree rerenders after its corresponding pane is shown.");
|
||||
|
||||
rendered = once(JsFlameGraphView, EVENTS.JS_FLAMEGRAPH_RENDERED);
|
||||
DetailsView.selectView("js-flamegraph");
|
||||
yield DetailsView.selectView("js-flamegraph");
|
||||
yield rendered;
|
||||
ok(true, "Flamegraph rerenders after its corresponding pane is shown.");
|
||||
|
||||
@ -42,12 +42,12 @@ function spawnTest () {
|
||||
ok(true, "Flamegraph rerenders when a range in the overview graph is removed.");
|
||||
|
||||
rendered = once(JsCallTreeView, EVENTS.JS_CALL_TREE_RENDERED);
|
||||
DetailsView.selectView("js-calltree");
|
||||
yield DetailsView.selectView("js-calltree");
|
||||
yield rendered;
|
||||
ok(true, "Call tree rerenders after its corresponding pane is shown.");
|
||||
|
||||
rendered = once(WaterfallView, EVENTS.WATERFALL_RENDERED);
|
||||
DetailsView.selectView("waterfall");
|
||||
yield DetailsView.selectView("waterfall");
|
||||
yield rendered;
|
||||
ok(true, "Waterfall rerenders after its corresponding pane is shown.");
|
||||
|
||||
|
@ -8,10 +8,23 @@
|
||||
|
||||
let test = Task.async(function*() {
|
||||
let { target, panel, toolbox } = yield initPerformance(SIMPLE_URL);
|
||||
let { $, EVENTS, PerformanceController, DetailsSubview, RecordingsView } = panel.panelWin;
|
||||
let { $, EVENTS, PerformanceController, DetailsView, DetailsSubview, RecordingsView } = panel.panelWin;
|
||||
|
||||
// Enable memory to test the memory-calltree and memory-flamegraph.
|
||||
Services.prefs.setBoolPref(MEMORY_PREF, true);
|
||||
|
||||
// Need to allow widgets to be updated while hidden, otherwise we can't use
|
||||
// `waitForWidgetsRendered`.
|
||||
DetailsSubview.canUpdateWhileHidden = true;
|
||||
|
||||
// Cycle through all the views to initialize them, otherwise we can't use
|
||||
// `waitForWidgetsRendered`. The waterfall is shown by default, but all the
|
||||
// other views are created lazily, so won't emit any events.
|
||||
yield DetailsView.selectView("js-calltree");
|
||||
yield DetailsView.selectView("js-flamegraph");
|
||||
yield DetailsView.selectView("memory-calltree");
|
||||
yield DetailsView.selectView("memory-flamegraph");
|
||||
|
||||
yield startRecording(panel);
|
||||
yield stopRecording(panel);
|
||||
|
||||
|
95
browser/devtools/performance/test/browser_perf-states.js
Normal file
95
browser/devtools/performance/test/browser_perf-states.js
Normal file
@ -0,0 +1,95 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that view states and lazy component intialization works.
|
||||
*/
|
||||
function spawnTest () {
|
||||
let { panel } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, PerformanceView, OverviewView, DetailsView } = panel.panelWin;
|
||||
|
||||
is(PerformanceView.getState(), "empty",
|
||||
"The intial state of the performance panel view is correct.");
|
||||
|
||||
ok(!("markersOverview" in OverviewView),
|
||||
"The markers graph should not have been created yet.");
|
||||
ok(!("memoryOverview" in OverviewView),
|
||||
"The memory graph should not have been created yet.");
|
||||
ok(!("framerateGraph" in OverviewView),
|
||||
"The framerate graph should not have been created yet.");
|
||||
|
||||
ok(DetailsView.components["waterfall"].initialized,
|
||||
"The waterfall detail view should have been created by default.");
|
||||
ok(!DetailsView.components["js-calltree"].initialized,
|
||||
"The js-calltree detail view should not have been created yet.");
|
||||
ok(!DetailsView.components["js-flamegraph"].initialized,
|
||||
"The js-flamegraph detail view should not have been created yet.");
|
||||
ok(!DetailsView.components["memory-calltree"].initialized,
|
||||
"The memory-calltree detail view should not have been created yet.");
|
||||
ok(!DetailsView.components["memory-flamegraph"].initialized,
|
||||
"The memory-flamegraph detail view should not have been created yet.");
|
||||
|
||||
Services.prefs.setBoolPref(MEMORY_PREF, true);
|
||||
|
||||
ok(!("markersOverview" in OverviewView),
|
||||
"The markers graph should still not have been created yet.");
|
||||
ok(!("memoryOverview" in OverviewView),
|
||||
"The memory graph should still not have been created yet.");
|
||||
ok(!("framerateGraph" in OverviewView),
|
||||
"The framerate graph should still not have been created yet.");
|
||||
|
||||
let stateChanged = once(PerformanceView, EVENTS.UI_STATE_CHANGED);
|
||||
yield startRecording(panel);
|
||||
yield stateChanged;
|
||||
|
||||
is(PerformanceView.getState(), "recording",
|
||||
"The current state of the performance panel view is 'recording'.");
|
||||
ok(OverviewView.memoryOverview,
|
||||
"The memory graph should have been created now.");
|
||||
ok(OverviewView.framerateGraph,
|
||||
"The framerate graph should have been created now.");
|
||||
|
||||
stateChanged = once(PerformanceView, EVENTS.UI_STATE_CHANGED);
|
||||
yield stopRecording(panel);
|
||||
yield stateChanged;
|
||||
|
||||
is(PerformanceView.getState(), "recorded",
|
||||
"The current state of the performance panel view is 'recorded'.");
|
||||
ok(!DetailsView.components["js-calltree"].initialized,
|
||||
"The js-calltree detail view should still not have been created yet.");
|
||||
ok(!DetailsView.components["js-flamegraph"].initialized,
|
||||
"The js-flamegraph detail view should still not have been created yet.");
|
||||
ok(!DetailsView.components["memory-calltree"].initialized,
|
||||
"The memory-calltree detail view should still not have been created yet.");
|
||||
ok(!DetailsView.components["memory-flamegraph"].initialized,
|
||||
"The memory-flamegraph detail view should still not have been created yet.");
|
||||
|
||||
yield DetailsView.selectView("js-calltree");
|
||||
|
||||
is(PerformanceView.getState(), "recorded",
|
||||
"The current state of the performance panel view is still 'recorded'.");
|
||||
ok(DetailsView.components["js-calltree"].initialized,
|
||||
"The js-calltree detail view should still have been created now.");
|
||||
ok(!DetailsView.components["js-flamegraph"].initialized,
|
||||
"The js-flamegraph detail view should still not have been created yet.");
|
||||
ok(!DetailsView.components["memory-calltree"].initialized,
|
||||
"The memory-calltree detail view should still not have been created yet.");
|
||||
ok(!DetailsView.components["memory-flamegraph"].initialized,
|
||||
"The memory-flamegraph detail view should still not have been created yet.");
|
||||
|
||||
yield DetailsView.selectView("memory-calltree");
|
||||
|
||||
is(PerformanceView.getState(), "recorded",
|
||||
"The current state of the performance panel view is still 'recorded'.");
|
||||
ok(DetailsView.components["js-calltree"].initialized,
|
||||
"The js-calltree detail view should still register as being created.");
|
||||
ok(!DetailsView.components["js-flamegraph"].initialized,
|
||||
"The js-flamegraph detail view should still not have been created yet.");
|
||||
ok(DetailsView.components["memory-calltree"].initialized,
|
||||
"The memory-calltree detail view should still have been created now.");
|
||||
ok(!DetailsView.components["memory-flamegraph"].initialized,
|
||||
"The memory-flamegraph detail view should still not have been created yet.");
|
||||
|
||||
yield teardown(panel);
|
||||
finish();
|
||||
}
|
@ -7,8 +7,21 @@
|
||||
|
||||
let test = Task.async(function*() {
|
||||
let { target, panel, toolbox } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, PerformanceController, DetailsSubview } = panel.panelWin;
|
||||
let { EVENTS, PerformanceController, DetailsView, DetailsSubview } = panel.panelWin;
|
||||
|
||||
// Enable memory to test the memory-calltree and memory-flamegraph.
|
||||
Services.prefs.setBoolPref(MEMORY_PREF, true);
|
||||
|
||||
// Cycle through all the views to initialize them, otherwise we can't use
|
||||
// `waitForWidgetsRendered`. The waterfall is shown by default, but all the
|
||||
// other views are created lazily, so won't emit any events.
|
||||
yield DetailsView.selectView("js-calltree");
|
||||
yield DetailsView.selectView("js-flamegraph");
|
||||
yield DetailsView.selectView("memory-calltree");
|
||||
yield DetailsView.selectView("memory-flamegraph");
|
||||
|
||||
// Need to allow widgets to be updated while hidden, otherwise we can't use
|
||||
// `waitForWidgetsRendered`.
|
||||
DetailsSubview.canUpdateWhileHidden = true;
|
||||
|
||||
yield startRecording(panel);
|
||||
|
@ -8,8 +8,21 @@
|
||||
|
||||
let test = Task.async(function*() {
|
||||
let { target, panel, toolbox } = yield initPerformance(SIMPLE_URL);
|
||||
let { EVENTS, PerformanceController, DetailsSubview } = panel.panelWin;
|
||||
let { EVENTS, PerformanceController, DetailsView, DetailsSubview } = panel.panelWin;
|
||||
|
||||
// Enable memory to test the memory-calltree and memory-flamegraph.
|
||||
Services.prefs.setBoolPref(MEMORY_PREF, true);
|
||||
|
||||
// Cycle through all the views to initialize them, otherwise we can't use
|
||||
// `waitForWidgetsRendered`. The waterfall is shown by default, but all the
|
||||
// other views are created lazily, so won't emit any events.
|
||||
yield DetailsView.selectView("js-calltree");
|
||||
yield DetailsView.selectView("js-flamegraph");
|
||||
yield DetailsView.selectView("memory-calltree");
|
||||
yield DetailsView.selectView("memory-flamegraph");
|
||||
|
||||
// Need to allow widgets to be updated while hidden, otherwise we can't use
|
||||
// `waitForWidgetsRendered`.
|
||||
DetailsSubview.canUpdateWhileHidden = true;
|
||||
|
||||
yield startRecording(panel);
|
||||
|
@ -22,6 +22,13 @@ const FRAME_SCRIPT_UTILS_URL = "chrome://browser/content/devtools/frame-script-u
|
||||
const EXAMPLE_URL = "http://example.com/browser/browser/devtools/performance/test/";
|
||||
const SIMPLE_URL = EXAMPLE_URL + "doc_simple-test.html";
|
||||
|
||||
const FRAMERATE_PREF = "devtools.performance.ui.enable-framerate";
|
||||
const MEMORY_PREF = "devtools.performance.ui.enable-memory";
|
||||
const PLATFORM_DATA_PREF = "devtools.performance.ui.show-platform-data";
|
||||
const IDLE_PREF = "devtools.performance.ui.show-idle-blocks";
|
||||
const INVERT_PREF = "devtools.performance.ui.invert-call-tree";
|
||||
const FLATTEN_PREF = "devtools.performance.ui.flatten-tree-recursion";
|
||||
|
||||
// All tests are asynchronous.
|
||||
waitForExplicitFinish();
|
||||
|
||||
@ -248,12 +255,10 @@ function* startRecording(panel) {
|
||||
|
||||
ok(!button.hasAttribute("checked"),
|
||||
"The record button should not be checked yet.");
|
||||
|
||||
ok(!button.hasAttribute("locked"),
|
||||
"The record button should not be locked yet.");
|
||||
|
||||
click(win, button);
|
||||
|
||||
yield clicked;
|
||||
|
||||
ok(button.hasAttribute("checked"),
|
||||
@ -262,7 +267,16 @@ function* startRecording(panel) {
|
||||
"The record button should be locked.");
|
||||
|
||||
yield willStart;
|
||||
let stateChanged = once(win.PerformanceView, win.EVENTS.UI_STATE_CHANGED);
|
||||
|
||||
yield hasStarted;
|
||||
let overviewRendered = once(win.OverviewView, win.EVENTS.OVERVIEW_RENDERED);
|
||||
|
||||
yield stateChanged;
|
||||
yield overviewRendered;
|
||||
|
||||
is(win.PerformanceView.getState(), "recording",
|
||||
"The current state is 'recording'.");
|
||||
|
||||
ok(button.hasAttribute("checked"),
|
||||
"The record button should still be checked.");
|
||||
@ -283,7 +297,6 @@ function* stopRecording(panel) {
|
||||
"The record button should not be locked yet.");
|
||||
|
||||
click(win, button);
|
||||
|
||||
yield clicked;
|
||||
|
||||
ok(!button.hasAttribute("checked"),
|
||||
@ -292,7 +305,16 @@ function* stopRecording(panel) {
|
||||
"The record button should be locked.");
|
||||
|
||||
yield willStop;
|
||||
let stateChanged = once(win.PerformanceView, win.EVENTS.UI_STATE_CHANGED);
|
||||
|
||||
yield hasStopped;
|
||||
let overviewRendered = once(win.OverviewView, win.EVENTS.OVERVIEW_RENDERED);
|
||||
|
||||
yield stateChanged;
|
||||
yield overviewRendered;
|
||||
|
||||
is(win.PerformanceView.getState(), "recorded",
|
||||
"The current state is 'recorded'.");
|
||||
|
||||
ok(!button.hasAttribute("checked"),
|
||||
"The record button should not be checked.");
|
||||
@ -306,7 +328,9 @@ function waitForWidgetsRendered(panel) {
|
||||
OverviewView,
|
||||
WaterfallView,
|
||||
JsCallTreeView,
|
||||
JsFlameGraphView
|
||||
JsFlameGraphView,
|
||||
MemoryCallTreeView,
|
||||
MemoryFlameGraphView,
|
||||
} = panel.panelWin;
|
||||
|
||||
return Promise.all([
|
||||
@ -316,7 +340,9 @@ function waitForWidgetsRendered(panel) {
|
||||
once(OverviewView, EVENTS.OVERVIEW_RENDERED),
|
||||
once(WaterfallView, EVENTS.WATERFALL_RENDERED),
|
||||
once(JsCallTreeView, EVENTS.JS_CALL_TREE_RENDERED),
|
||||
once(JsFlameGraphView, EVENTS.JS_FLAMEGRAPH_RENDERED)
|
||||
once(JsFlameGraphView, EVENTS.JS_FLAMEGRAPH_RENDERED),
|
||||
once(MemoryCallTreeView, EVENTS.MEMORY_CALL_TREE_RENDERED),
|
||||
once(MemoryFlameGraphView, EVENTS.MEMORY_FLAMEGRAPH_RENDERED),
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -102,11 +102,10 @@ let DetailsSubview = {
|
||||
/**
|
||||
* Fired when a preference in `devtools.performance.ui.` is changed.
|
||||
*/
|
||||
_onPrefChanged: function (_, prefName, value) {
|
||||
_onPrefChanged: function (_, prefName) {
|
||||
// All detail views require a recording to be complete, so do not
|
||||
// attempt to render if recording is in progress or does not exist.
|
||||
let recording = PerformanceController.getCurrentRecording();
|
||||
|
||||
if (!recording || recording.isRecording()) {
|
||||
return;
|
||||
}
|
||||
@ -115,6 +114,10 @@ let DetailsSubview = {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._onRerenderPrefChanged) {
|
||||
this._onRerenderPrefChanged();
|
||||
}
|
||||
|
||||
if (DetailsView.isViewSelected(this) || this.canUpdateWhileHidden) {
|
||||
this.render(OverviewView.getTimeInterval());
|
||||
} else {
|
||||
|
@ -8,7 +8,10 @@
|
||||
*/
|
||||
let JsCallTreeView = Heritage.extend(DetailsSubview, {
|
||||
|
||||
rerenderPrefs: ["invert-call-tree", "show-platform-data"],
|
||||
rerenderPrefs: [
|
||||
"invert-call-tree",
|
||||
"show-platform-data"
|
||||
],
|
||||
|
||||
rangeChangeDebounceTime: 50, // ms
|
||||
|
||||
|
@ -9,7 +9,12 @@
|
||||
*/
|
||||
let JsFlameGraphView = Heritage.extend(DetailsSubview, {
|
||||
|
||||
rerenderPrefs: ["flatten-tree-recursion", "show-platform-data", "show-idle-blocks"],
|
||||
rerenderPrefs: [
|
||||
"invert-flame-graph",
|
||||
"flatten-tree-recursion",
|
||||
"show-platform-data",
|
||||
"show-idle-blocks"
|
||||
],
|
||||
|
||||
/**
|
||||
* Sets up the view with event binding.
|
||||
@ -48,6 +53,7 @@ let JsFlameGraphView = Heritage.extend(DetailsSubview, {
|
||||
let samples = profile.threads[0].samples;
|
||||
|
||||
let data = FlameGraphUtils.createFlameGraphDataFromSamples(samples, {
|
||||
invertStack: PerformanceController.getPref("invert-flame-graph"),
|
||||
flattenRecursion: PerformanceController.getPref("flatten-tree-recursion"),
|
||||
filterFrames: !PerformanceController.getPref("show-platform-data") && FrameNode.isContent,
|
||||
showIdleBlocks: PerformanceController.getPref("show-idle-blocks") && L10N.getStr("table.idle")
|
||||
@ -73,5 +79,15 @@ let JsFlameGraphView = Heritage.extend(DetailsSubview, {
|
||||
_onRangeChangeInGraph: function () {
|
||||
let interval = this.graph.getViewRange();
|
||||
OverviewView.setTimeInterval(interval, { stopPropagation: true });
|
||||
},
|
||||
|
||||
/**
|
||||
* Called whenever a pref is changed and this view needs to be rerendered.
|
||||
*/
|
||||
_onRerenderPrefChanged: function() {
|
||||
let recording = PerformanceController.getCurrentRecording();
|
||||
let profile = recording.getProfile();
|
||||
let samples = profile.threads[0].samples;
|
||||
FlameGraphUtils.removeFromCache(samples);
|
||||
}
|
||||
});
|
||||
|
@ -8,7 +8,9 @@
|
||||
*/
|
||||
let MemoryCallTreeView = Heritage.extend(DetailsSubview, {
|
||||
|
||||
rerenderPrefs: ["invert-call-tree", "show-platform-data"],
|
||||
rerenderPrefs: [
|
||||
"invert-call-tree"
|
||||
],
|
||||
|
||||
rangeChangeDebounceTime: 100, // ms
|
||||
|
||||
@ -60,11 +62,10 @@ let MemoryCallTreeView = Heritage.extend(DetailsSubview, {
|
||||
*/
|
||||
_prepareCallTree: function (allocations, { startTime, endTime }, options) {
|
||||
let samples = RecordingUtils.getSamplesFromAllocations(allocations);
|
||||
let contentOnly = !PerformanceController.getPref("show-platform-data");
|
||||
let invertTree = PerformanceController.getPref("invert-call-tree");
|
||||
|
||||
let threadNode = new ThreadNode(samples,
|
||||
{ startTime, endTime, contentOnly, invertTree });
|
||||
{ startTime, endTime, invertTree });
|
||||
|
||||
// If we have an empty profile (no samples), then don't invert the tree, as
|
||||
// it would hide the root node and a completely blank call tree space can be
|
||||
@ -101,5 +102,4 @@ let MemoryCallTreeView = Heritage.extend(DetailsSubview, {
|
||||
// Memory allocation samples don't contain cateogry labels.
|
||||
root.toggleCategories(false);
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -9,7 +9,11 @@
|
||||
*/
|
||||
let MemoryFlameGraphView = Heritage.extend(DetailsSubview, {
|
||||
|
||||
rerenderPrefs: ["flatten-tree-recursion", "show-idle-blocks"],
|
||||
rerenderPrefs: [
|
||||
"invert-flame-graph",
|
||||
"flatten-tree-recursion",
|
||||
"show-idle-blocks"
|
||||
],
|
||||
|
||||
/**
|
||||
* Sets up the view with event binding.
|
||||
@ -48,6 +52,7 @@ let MemoryFlameGraphView = Heritage.extend(DetailsSubview, {
|
||||
|
||||
let samples = RecordingUtils.getSamplesFromAllocations(allocations);
|
||||
let data = FlameGraphUtils.createFlameGraphDataFromSamples(samples, {
|
||||
invertStack: PerformanceController.getPref("invert-flame-graph"),
|
||||
flattenRecursion: PerformanceController.getPref("flatten-tree-recursion"),
|
||||
showIdleBlocks: PerformanceController.getPref("show-idle-blocks") && L10N.getStr("table.idle")
|
||||
});
|
||||
@ -72,5 +77,15 @@ let MemoryFlameGraphView = Heritage.extend(DetailsSubview, {
|
||||
_onRangeChangeInGraph: function () {
|
||||
let interval = this.graph.getViewRange();
|
||||
OverviewView.setTimeInterval(interval, { stopPropagation: true });
|
||||
},
|
||||
|
||||
/**
|
||||
* Called whenever a pref is changed and this view needs to be rerendered.
|
||||
*/
|
||||
_onRerenderPrefChanged: function() {
|
||||
let recording = PerformanceController.getCurrentRecording();
|
||||
let allocations = recording.getAllocations();
|
||||
let samples = RecordingUtils.getSamplesFromAllocations(allocations);
|
||||
FlameGraphUtils.removeFromCache(samples);
|
||||
}
|
||||
});
|
||||
|
@ -7,6 +7,7 @@
|
||||
* Waterfall view containing the timeline markers, controlled by DetailsView.
|
||||
*/
|
||||
let WaterfallView = Heritage.extend(DetailsSubview, {
|
||||
|
||||
rangeChangeDebounceTime: 10, // ms
|
||||
|
||||
/**
|
||||
@ -18,12 +19,9 @@ let WaterfallView = Heritage.extend(DetailsSubview, {
|
||||
this.waterfall = new Waterfall($("#waterfall-breakdown"), $("#details-pane"), TIMELINE_BLUEPRINT);
|
||||
this.details = new MarkerDetails($("#waterfall-details"), $("#waterfall-view > splitter"));
|
||||
|
||||
this._onRecordingStarted = this._onRecordingStarted.bind(this);
|
||||
this._onMarkerSelected = this._onMarkerSelected.bind(this);
|
||||
this._onResize = this._onResize.bind(this);
|
||||
|
||||
PerformanceController.on(EVENTS.RECORDING_STARTED, this._onRecordingStarted);
|
||||
|
||||
this.waterfall.on("selected", this._onMarkerSelected);
|
||||
this.waterfall.on("unselected", this._onMarkerSelected);
|
||||
this.details.on("resize", this._onResize);
|
||||
@ -37,8 +35,6 @@ let WaterfallView = Heritage.extend(DetailsSubview, {
|
||||
destroy: function () {
|
||||
DetailsSubview.destroy.call(this);
|
||||
|
||||
PerformanceController.off(EVENTS.RECORDING_STARTED, this._onRecordingStarted);
|
||||
|
||||
this.waterfall.off("selected", this._onMarkerSelected);
|
||||
this.waterfall.off("unselected", this._onMarkerSelected);
|
||||
this.details.off("resize", this._onResize);
|
||||
@ -59,13 +55,6 @@ let WaterfallView = Heritage.extend(DetailsSubview, {
|
||||
this.emit(EVENTS.WATERFALL_RENDERED);
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when recording starts.
|
||||
*/
|
||||
_onRecordingStarted: function () {
|
||||
this.waterfall.clearView();
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when a marker is selected in the waterfall view,
|
||||
* updating the markers detail view.
|
||||
|
@ -17,8 +17,8 @@ let DetailsView = {
|
||||
"waterfall": { id: "waterfall-view", view: WaterfallView },
|
||||
"js-calltree": { id: "js-calltree-view", view: JsCallTreeView },
|
||||
"js-flamegraph": { id: "js-flamegraph-view", view: JsFlameGraphView },
|
||||
"memory-calltree": { id: "memory-calltree-view", view: MemoryCallTreeView },
|
||||
"memory-flamegraph": { id: "memory-flamegraph-view", view: MemoryFlameGraphView }
|
||||
"memory-calltree": { id: "memory-calltree-view", view: MemoryCallTreeView, pref: "enable-memory" },
|
||||
"memory-flamegraph": { id: "memory-flamegraph-view", view: MemoryFlameGraphView, pref: "enable-memory" }
|
||||
},
|
||||
|
||||
/**
|
||||
@ -29,16 +29,16 @@ let DetailsView = {
|
||||
this.toolbar = $("#performance-toolbar-controls-detail-views");
|
||||
|
||||
this._onViewToggle = this._onViewToggle.bind(this);
|
||||
this.setAvailableViews = this.setAvailableViews.bind(this);
|
||||
|
||||
for (let button of $$("toolbarbutton[data-view]", this.toolbar)) {
|
||||
button.addEventListener("command", this._onViewToggle);
|
||||
}
|
||||
|
||||
for (let [_, { view }] of Iterator(this.components)) {
|
||||
yield view.initialize();
|
||||
}
|
||||
yield this.selectView(DEFAULT_DETAILS_SUBVIEW);
|
||||
this.setAvailableViews();
|
||||
|
||||
this.selectView(DEFAULT_DETAILS_SUBVIEW);
|
||||
PerformanceController.on(EVENTS.PREF_CHANGED, this.setAvailableViews);
|
||||
}),
|
||||
|
||||
/**
|
||||
@ -49,11 +49,34 @@ let DetailsView = {
|
||||
button.removeEventListener("command", this._onViewToggle);
|
||||
}
|
||||
|
||||
for (let [_, { view }] of Iterator(this.components)) {
|
||||
yield view.destroy();
|
||||
for (let [_, component] of Iterator(this.components)) {
|
||||
component.initialized && (yield component.view.destroy());
|
||||
}
|
||||
|
||||
PerformanceController.off(EVENTS.PREF_CHANGED, this.setAvailableViews);
|
||||
}),
|
||||
|
||||
/**
|
||||
* Sets the possible views based off of prefs by hiding/showing the
|
||||
* buttons that select them and going to default view if currently selected.
|
||||
* Called when a preference changes in `devtools.performance.ui.`.
|
||||
*/
|
||||
setAvailableViews: function () {
|
||||
for (let [name, { view, pref }] of Iterator(this.components)) {
|
||||
if (!pref) {
|
||||
continue;
|
||||
}
|
||||
let value = PerformanceController.getPref(pref);
|
||||
$(`toolbarbutton[data-view=${name}]`).hidden = !value;
|
||||
|
||||
// If the view is currently selected and not enabled, go back to the
|
||||
// default view.
|
||||
if (!value && this.isViewSelected(view)) {
|
||||
this.selectView(DEFAULT_DETAILS_SUBVIEW);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Select one of the DetailView's subviews to be rendered,
|
||||
* hiding the others.
|
||||
@ -61,8 +84,11 @@ let DetailsView = {
|
||||
* @param String viewName
|
||||
* Name of the view to be shown.
|
||||
*/
|
||||
selectView: function (viewName) {
|
||||
this.el.selectedPanel = $("#" + this.components[viewName].id);
|
||||
selectView: Task.async(function *(viewName) {
|
||||
let component = this.components[viewName];
|
||||
this.el.selectedPanel = $("#" + component.id);
|
||||
|
||||
yield this._whenViewInitialized(component);
|
||||
|
||||
for (let button of $$("toolbarbutton[data-view]", this.toolbar)) {
|
||||
if (button.getAttribute("data-view") === viewName) {
|
||||
@ -73,7 +99,7 @@ let DetailsView = {
|
||||
}
|
||||
|
||||
this.emit(EVENTS.DETAILS_VIEW_SELECTED, viewName);
|
||||
},
|
||||
}),
|
||||
|
||||
/**
|
||||
* Checks if the provided view is currently selected.
|
||||
@ -109,6 +135,30 @@ let DetailsView = {
|
||||
return this.whenViewSelected(viewObject);
|
||||
}),
|
||||
|
||||
/**
|
||||
* Initializes a subview if it wasn't already set up, and makes sure
|
||||
* it's populated with recording data if there is some available.
|
||||
*
|
||||
* @param object component
|
||||
* A component descriptor from DetailsView.components
|
||||
*/
|
||||
_whenViewInitialized: Task.async(function *(component) {
|
||||
if (component.initialized) {
|
||||
return;
|
||||
}
|
||||
component.initialized = true;
|
||||
yield component.view.initialize();
|
||||
|
||||
// If this view is initialized *after* a recording is shown, it won't display
|
||||
// any data. Make sure it's populated by setting `shouldUpdateWhenShown`.
|
||||
// All detail views require a recording to be complete, so do not
|
||||
// attempt to render if recording is in progress or does not exist.
|
||||
let recording = PerformanceController.getCurrentRecording();
|
||||
if (recording && !recording.isRecording()) {
|
||||
component.view.shouldUpdateWhenShown = true;
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Called when a view button is clicked.
|
||||
*/
|
||||
|
@ -25,7 +25,7 @@ let OverviewView = {
|
||||
/**
|
||||
* Sets up the view with event binding.
|
||||
*/
|
||||
initialize: Task.async(function *() {
|
||||
initialize: function () {
|
||||
this._onRecordingWillStart = this._onRecordingWillStart.bind(this);
|
||||
this._onRecordingStarted = this._onRecordingStarted.bind(this);
|
||||
this._onRecordingWillStop = this._onRecordingWillStop.bind(this);
|
||||
@ -35,39 +35,25 @@ let OverviewView = {
|
||||
this._onGraphSelecting = this._onGraphSelecting.bind(this);
|
||||
this._onPrefChanged = this._onPrefChanged.bind(this);
|
||||
|
||||
yield this._showMarkersGraph();
|
||||
yield this._showMemoryGraph();
|
||||
yield this._showFramerateGraph();
|
||||
|
||||
this.markersOverview.on("selecting", this._onGraphSelecting);
|
||||
|
||||
PerformanceController.on(EVENTS.RECORDING_WILL_START, this._onRecordingWillStart);
|
||||
|
||||
// Toggle the initial state of memory and framerate graph based off of
|
||||
// the prefs.
|
||||
// Toggle the initial visibility of memory and framerate graph containers
|
||||
// based off of prefs.
|
||||
$("#memory-overview").hidden = !PerformanceController.getPref("enable-memory");
|
||||
$("#time-framerate").hidden = !PerformanceController.getPref("enable-framerate");
|
||||
|
||||
PerformanceController.on(EVENTS.PREF_CHANGED, this._onPrefChanged);
|
||||
PerformanceController.on(EVENTS.RECORDING_WILL_START, this._onRecordingWillStart);
|
||||
PerformanceController.on(EVENTS.RECORDING_STARTED, this._onRecordingStarted);
|
||||
PerformanceController.on(EVENTS.RECORDING_WILL_STOP, this._onRecordingWillStop);
|
||||
PerformanceController.on(EVENTS.RECORDING_STOPPED, this._onRecordingStopped);
|
||||
PerformanceController.on(EVENTS.RECORDING_SELECTED, this._onRecordingSelected);
|
||||
|
||||
// Populate this overview with some dummy initial data.
|
||||
this.markersOverview.setData({ duration: 1000, markers: [] });
|
||||
this.memoryOverview.setData([]);
|
||||
this.framerateGraph.setData([]);
|
||||
}),
|
||||
},
|
||||
|
||||
/**
|
||||
* Unbinds events.
|
||||
*/
|
||||
destroy: function () {
|
||||
this.markersOverview.off("selecting", this._onGraphSelecting);
|
||||
|
||||
PerformanceController.off(EVENTS.RECORDING_WILL_START, this._onRecordingWillStart);
|
||||
PerformanceController.off(EVENTS.PREF_CHANGED, this._onPrefChanged);
|
||||
PerformanceController.off(EVENTS.RECORDING_WILL_START, this._onRecordingWillStart);
|
||||
PerformanceController.off(EVENTS.RECORDING_STARTED, this._onRecordingStarted);
|
||||
PerformanceController.off(EVENTS.RECORDING_WILL_STOP, this._onRecordingWillStop);
|
||||
PerformanceController.off(EVENTS.RECORDING_STOPPED, this._onRecordingStopped);
|
||||
@ -111,43 +97,64 @@ let OverviewView = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets up the framerate graph.
|
||||
* Sets up the markers overivew graph, if needed.
|
||||
*
|
||||
* @return object
|
||||
* A promise resolved to `true` when the graph was initialized.
|
||||
*/
|
||||
_showFramerateGraph: Task.async(function *() {
|
||||
this.framerateGraph = new LineGraphWidget($("#time-framerate"), {
|
||||
metric: L10N.getStr("graphs.fps")
|
||||
});
|
||||
this.framerateGraph.fixedHeight = FRAMERATE_GRAPH_HEIGHT;
|
||||
yield this.framerateGraph.ready();
|
||||
}),
|
||||
|
||||
/**
|
||||
* Sets up the markers overivew graph.
|
||||
*/
|
||||
_showMarkersGraph: Task.async(function *() {
|
||||
_markersGraphAvailable: Task.async(function *() {
|
||||
if (this.markersOverview) {
|
||||
yield this.markersOverview.ready();
|
||||
return true;
|
||||
}
|
||||
this.markersOverview = new MarkersOverview($("#markers-overview"), TIMELINE_BLUEPRINT);
|
||||
this.markersOverview.headerHeight = MARKERS_GRAPH_HEADER_HEIGHT;
|
||||
this.markersOverview.rowHeight = MARKERS_GRAPH_ROW_HEIGHT;
|
||||
this.markersOverview.groupPadding = MARKERS_GROUP_VERTICAL_PADDING;
|
||||
this.markersOverview.on("selecting", this._onGraphSelecting);
|
||||
yield this.markersOverview.ready();
|
||||
return true;
|
||||
}),
|
||||
|
||||
/**
|
||||
* Sets up the memory overview graph.
|
||||
* Sets up the memory overview graph, if allowed and needed.
|
||||
*
|
||||
* @return object
|
||||
* A promise resolved to `true` if the graph was initialized and is
|
||||
* ready to use, `false` if the graph is disabled.
|
||||
*/
|
||||
_showMemoryGraph: Task.async(function *() {
|
||||
_memoryGraphAvailable: Task.async(function *() {
|
||||
if (!PerformanceController.getPref("enable-memory")) {
|
||||
return false;
|
||||
}
|
||||
if (this.memoryOverview) {
|
||||
yield this.memoryOverview.ready();
|
||||
return true;
|
||||
}
|
||||
this.memoryOverview = new MemoryOverview($("#memory-overview"));
|
||||
this.memoryOverview.fixedHeight = MEMORY_GRAPH_HEIGHT;
|
||||
yield this.memoryOverview.ready();
|
||||
|
||||
CanvasGraphUtils.linkAnimation(this.markersOverview, this.memoryOverview);
|
||||
CanvasGraphUtils.linkSelection(this.markersOverview, this.memoryOverview);
|
||||
return true;
|
||||
}),
|
||||
|
||||
/**
|
||||
* Sets up the framerate graph.
|
||||
* Sets up the framerate graph, if allowed and needed.
|
||||
*
|
||||
* @return object
|
||||
* A promise resolved to `true` if the graph was initialized and is
|
||||
* ready to use, `false` if the graph is disabled.
|
||||
*/
|
||||
_showFramerateGraph: Task.async(function *() {
|
||||
_framerateGraphAvailable: Task.async(function *() {
|
||||
if (!PerformanceController.getPref("enable-framerate")) {
|
||||
return false;
|
||||
}
|
||||
if (this.framerateGraph) {
|
||||
yield this.framerateGraph.ready();
|
||||
return true;
|
||||
}
|
||||
let metric = L10N.getStr("graphs.fps");
|
||||
this.framerateGraph = new LineGraphWidget($("#time-framerate"), { metric });
|
||||
this.framerateGraph.fixedHeight = FRAMERATE_GRAPH_HEIGHT;
|
||||
@ -155,6 +162,7 @@ let OverviewView = {
|
||||
|
||||
CanvasGraphUtils.linkAnimation(this.markersOverview, this.framerateGraph);
|
||||
CanvasGraphUtils.linkSelection(this.markersOverview, this.framerateGraph);
|
||||
return true;
|
||||
}),
|
||||
|
||||
/**
|
||||
@ -171,16 +179,16 @@ let OverviewView = {
|
||||
let timestamps = recording.getTicks();
|
||||
|
||||
// Empty or older recordings might yield no markers, memory or timestamps.
|
||||
if (markers) {
|
||||
if (markers && (yield this._markersGraphAvailable())) {
|
||||
this.markersOverview.setData({ markers, duration });
|
||||
this.emit(EVENTS.MARKERS_GRAPH_RENDERED);
|
||||
}
|
||||
if (memory) {
|
||||
if (memory && (yield this._memoryGraphAvailable())) {
|
||||
this.memoryOverview.dataDuration = duration;
|
||||
this.memoryOverview.setData(memory);
|
||||
this.emit(EVENTS.MEMORY_GRAPH_RENDERED);
|
||||
}
|
||||
if (timestamps) {
|
||||
if (timestamps && (yield this._framerateGraphAvailable())) {
|
||||
this.framerateGraph.dataDuration = duration;
|
||||
yield this.framerateGraph.setDataFromTimestamps(timestamps, resolution);
|
||||
this.emit(EVENTS.FRAMERATE_GRAPH_RENDERED);
|
||||
@ -200,13 +208,23 @@ let OverviewView = {
|
||||
this._prepareNextTick();
|
||||
}),
|
||||
|
||||
/**
|
||||
* Called to refresh the timer to keep firing _onRecordingTick.
|
||||
*/
|
||||
_prepareNextTick: function () {
|
||||
// Check here to see if there's still a _timeoutId, incase
|
||||
// `stop` was called before the _prepareNextTick call was executed.
|
||||
if (this._timeoutId) {
|
||||
this._timeoutId = setTimeout(this._onRecordingTick, OVERVIEW_UPDATE_INTERVAL);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Fired when the graph selection has changed. Called by
|
||||
* mouseup and scroll events.
|
||||
*/
|
||||
_onGraphSelecting: function () {
|
||||
let recording = PerformanceController.getCurrentRecording();
|
||||
if (recording == null || this._stopSelectionChangeEventPropagation) {
|
||||
if (this._stopSelectionChangeEventPropagation) {
|
||||
return;
|
||||
}
|
||||
// If the range is smaller than a pixel (which can happen when performing
|
||||
@ -219,24 +237,13 @@ let OverviewView = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Called to refresh the timer to keep firing _onRecordingTick.
|
||||
*/
|
||||
_prepareNextTick: function () {
|
||||
// Check here to see if there's still a _timeoutId, incase
|
||||
// `stop` was called before the _prepareNextTick call was executed.
|
||||
if (this._timeoutId) {
|
||||
this._timeoutId = setTimeout(this._onRecordingTick, OVERVIEW_UPDATE_INTERVAL);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when recording will start.
|
||||
*/
|
||||
_onRecordingWillStart: function (_, recording) {
|
||||
this._checkSelection(recording);
|
||||
this.framerateGraph.dropSelection();
|
||||
},
|
||||
_onRecordingWillStart: Task.async(function* (_, recording) {
|
||||
yield this._checkSelection(recording);
|
||||
this.markersOverview.dropSelection();
|
||||
}),
|
||||
|
||||
/**
|
||||
* Called when recording actually starts.
|
||||
@ -256,40 +263,50 @@ let OverviewView = {
|
||||
/**
|
||||
* Called when recording actually stops.
|
||||
*/
|
||||
_onRecordingStopped: function (_, recording) {
|
||||
this._checkSelection(recording);
|
||||
_onRecordingStopped: Task.async(function* (_, recording) {
|
||||
this.render(FRAMERATE_GRAPH_HIGH_RES_INTERVAL);
|
||||
},
|
||||
yield this._checkSelection(recording);
|
||||
}),
|
||||
|
||||
/**
|
||||
* Called when a new recording is selected.
|
||||
*/
|
||||
_onRecordingSelected: function (_, recording) {
|
||||
_onRecordingSelected: Task.async(function* (_, recording) {
|
||||
if (!recording) {
|
||||
return;
|
||||
}
|
||||
this.markersOverview.dropSelection();
|
||||
this._checkSelection(recording);
|
||||
|
||||
// If timeout exists, we have something recording, so
|
||||
// this will still tick away at rendering. Otherwise, force a render.
|
||||
if (!this._timeoutId) {
|
||||
this.render(FRAMERATE_GRAPH_HIGH_RES_INTERVAL);
|
||||
yield this.render(FRAMERATE_GRAPH_HIGH_RES_INTERVAL);
|
||||
}
|
||||
},
|
||||
yield this._checkSelection(recording);
|
||||
this.markersOverview.dropSelection();
|
||||
}),
|
||||
|
||||
_checkSelection: function (recording) {
|
||||
/**
|
||||
* Makes sure the selection is enabled or disabled in all the graphs,
|
||||
* based on whether a recording currently exists and is not in progress.
|
||||
*/
|
||||
_checkSelection: Task.async(function* (recording) {
|
||||
let selectionEnabled = !recording.isRecording();
|
||||
this.markersOverview.selectionEnabled = selectionEnabled;
|
||||
this.memoryOverview.selectionEnabled = selectionEnabled;
|
||||
this.framerateGraph.selectionEnabled = selectionEnabled;
|
||||
},
|
||||
|
||||
if (yield this._markersGraphAvailable()) {
|
||||
this.markersOverview.selectionEnabled = selectionEnabled;
|
||||
}
|
||||
if (yield this._memoryGraphAvailable()) {
|
||||
this.memoryOverview.selectionEnabled = selectionEnabled;
|
||||
}
|
||||
if (yield this._framerateGraphAvailable()) {
|
||||
this.framerateGraph.selectionEnabled = selectionEnabled;
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Called whenever a preference in `devtools.performance.ui.` changes. Used
|
||||
* to toggle the visibility of memory and framerate graphs.
|
||||
*/
|
||||
_onPrefChanged: function (_, prefName, value) {
|
||||
_onPrefChanged: function (_, prefName) {
|
||||
if (prefName === "enable-memory") {
|
||||
$("#memory-overview").hidden = !PerformanceController.getPref("enable-memory");
|
||||
}
|
||||
|
@ -143,10 +143,10 @@ function FlameGraph(parent, sharpness) {
|
||||
this._onResize = this._onResize.bind(this);
|
||||
this.refresh = this.refresh.bind(this);
|
||||
|
||||
container.addEventListener("mousemove", this._onMouseMove);
|
||||
container.addEventListener("mousedown", this._onMouseDown);
|
||||
container.addEventListener("mouseup", this._onMouseUp);
|
||||
container.addEventListener("MozMousePixelScroll", this._onMouseWheel);
|
||||
this._window.addEventListener("mousemove", this._onMouseMove);
|
||||
this._window.addEventListener("mousedown", this._onMouseDown);
|
||||
this._window.addEventListener("mouseup", this._onMouseUp);
|
||||
this._window.addEventListener("MozMousePixelScroll", this._onMouseWheel);
|
||||
|
||||
let ownerWindow = this._parent.ownerDocument.defaultView;
|
||||
ownerWindow.addEventListener("resize", this._onResize);
|
||||
@ -181,11 +181,10 @@ FlameGraph.prototype = {
|
||||
* Destroys this graph.
|
||||
*/
|
||||
destroy: function() {
|
||||
let container = this._container;
|
||||
container.removeEventListener("mousemove", this._onMouseMove);
|
||||
container.removeEventListener("mousedown", this._onMouseDown);
|
||||
container.removeEventListener("mouseup", this._onMouseUp);
|
||||
container.removeEventListener("MozMousePixelScroll", this._onMouseWheel);
|
||||
this._window.removeEventListener("mousemove", this._onMouseMove);
|
||||
this._window.removeEventListener("mousedown", this._onMouseDown);
|
||||
this._window.removeEventListener("mouseup", this._onMouseUp);
|
||||
this._window.removeEventListener("MozMousePixelScroll", this._onMouseWheel);
|
||||
|
||||
let ownerWindow = this._parent.ownerDocument.defaultView;
|
||||
ownerWindow.removeEventListener("resize", this._onResize);
|
||||
@ -870,6 +869,8 @@ let FlameGraphUtils = {
|
||||
* A list of { time, frames: [{ location }] } objects.
|
||||
* @param object options [optional]
|
||||
* Additional options supported by this operation:
|
||||
* - invertStack: specifies if the frames array in every sample
|
||||
* should be reversed
|
||||
* - flattenRecursion: specifies if identical consecutive frames
|
||||
* should be omitted from the output
|
||||
* - filterFrames: predicate used for filtering all frames, passing
|
||||
@ -917,6 +918,11 @@ let FlameGraphUtils = {
|
||||
frames = frames.filter(options.filterFrames);
|
||||
}
|
||||
|
||||
// Invert the stack if preferred, reversing the frames array in place.
|
||||
if (options.invertStack) {
|
||||
frames.reverse();
|
||||
}
|
||||
|
||||
// If no frames are available, add a pseudo "idle" block in between.
|
||||
if (options.showIdleBlocks && frames.length == 0) {
|
||||
frames = [{ location: options.showIdleBlocks || "" }];
|
||||
|
@ -191,11 +191,11 @@ this.AbstractCanvasGraph = function(parent, name, sharpness) {
|
||||
this._onResize = this._onResize.bind(this);
|
||||
this.refresh = this.refresh.bind(this);
|
||||
|
||||
container.addEventListener("mousemove", this._onMouseMove);
|
||||
container.addEventListener("mousedown", this._onMouseDown);
|
||||
container.addEventListener("mouseup", this._onMouseUp);
|
||||
container.addEventListener("MozMousePixelScroll", this._onMouseWheel);
|
||||
container.addEventListener("mouseout", this._onMouseOut);
|
||||
this._window.addEventListener("mousemove", this._onMouseMove);
|
||||
this._window.addEventListener("mousedown", this._onMouseDown);
|
||||
this._window.addEventListener("mouseup", this._onMouseUp);
|
||||
this._window.addEventListener("MozMousePixelScroll", this._onMouseWheel);
|
||||
this._window.addEventListener("mouseout", this._onMouseOut);
|
||||
|
||||
let ownerWindow = this._parent.ownerDocument.defaultView;
|
||||
ownerWindow.addEventListener("resize", this._onResize);
|
||||
@ -230,12 +230,11 @@ AbstractCanvasGraph.prototype = {
|
||||
* Destroys this graph.
|
||||
*/
|
||||
destroy: function() {
|
||||
let container = this._container;
|
||||
container.removeEventListener("mousemove", this._onMouseMove);
|
||||
container.removeEventListener("mousedown", this._onMouseDown);
|
||||
container.removeEventListener("mouseup", this._onMouseUp);
|
||||
container.removeEventListener("MozMousePixelScroll", this._onMouseWheel);
|
||||
container.removeEventListener("mouseout", this._onMouseOut);
|
||||
this._window.removeEventListener("mousemove", this._onMouseMove);
|
||||
this._window.removeEventListener("mousedown", this._onMouseDown);
|
||||
this._window.removeEventListener("mouseup", this._onMouseUp);
|
||||
this._window.removeEventListener("MozMousePixelScroll", this._onMouseWheel);
|
||||
this._window.removeEventListener("mouseout", this._onMouseOut);
|
||||
|
||||
let ownerWindow = this._parent.ownerDocument.defaultView;
|
||||
ownerWindow.removeEventListener("resize", this._onResize);
|
||||
|
@ -24,3 +24,5 @@ webide.jar:
|
||||
content/devicepreferences.xhtml (devicepreferences.xhtml)
|
||||
content/devicesettings.js (devicesettings.js)
|
||||
content/devicesettings.xhtml (devicesettings.xhtml)
|
||||
content/wifi-auth.js (wifi-auth.js)
|
||||
content/wifi-auth.xhtml (wifi-auth.xhtml)
|
||||
|
44
browser/devtools/webide/content/wifi-auth.js
Normal file
44
browser/devtools/webide/content/wifi-auth.js
Normal file
@ -0,0 +1,44 @@
|
||||
/* 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 Cu = Components.utils;
|
||||
const { Services } = Cu.import("resource://gre/modules/Services.jsm");
|
||||
const { require } =
|
||||
Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools;
|
||||
const QR = require("devtools/toolkit/qrcode/index");
|
||||
|
||||
window.addEventListener("load", function onLoad() {
|
||||
window.removeEventListener("load", onLoad);
|
||||
document.getElementById("close").onclick = () => window.close();
|
||||
document.getElementById("no-scanner").onclick = showToken;
|
||||
document.getElementById("yes-scanner").onclick = hideToken;
|
||||
buildUI();
|
||||
});
|
||||
|
||||
function buildUI() {
|
||||
let { oob } = window.arguments[0];
|
||||
createQR(oob);
|
||||
createToken(oob);
|
||||
}
|
||||
|
||||
function createQR(oob) {
|
||||
let oobData = JSON.stringify(oob);
|
||||
let imgData = QR.encodeToDataURI(oobData, "L" /* low quality */);
|
||||
document.querySelector("#qr-code img").src = imgData.src;
|
||||
}
|
||||
|
||||
function createToken(oob) {
|
||||
let token = oob.sha256.replace(/:/g, "").toLowerCase() + oob.k;
|
||||
document.querySelector("#token pre").textContent = token;
|
||||
}
|
||||
|
||||
function showToken() {
|
||||
document.querySelector("body").setAttribute("token", "true");
|
||||
}
|
||||
|
||||
function hideToken() {
|
||||
document.querySelector("body").removeAttribute("token");
|
||||
}
|
42
browser/devtools/webide/content/wifi-auth.xhtml
Normal file
42
browser/devtools/webide/content/wifi-auth.xhtml
Normal file
@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!-- 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/. -->
|
||||
|
||||
<!DOCTYPE html [
|
||||
<!ENTITY % webideDTD SYSTEM "chrome://browser/locale/devtools/webide.dtd" >
|
||||
%webideDTD;
|
||||
]>
|
||||
|
||||
<html id="devtools:wifi-auth" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta charset="utf8"/>
|
||||
<link rel="stylesheet" href="chrome://webide/skin/deck.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="chrome://webide/skin/wifi-auth.css" type="text/css"/>
|
||||
<script type="application/javascript;version=1.8" src="chrome://webide/content/wifi-auth.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="controls">
|
||||
<a id="close">&deck_close;</a>
|
||||
</div>
|
||||
|
||||
<h3 id="header">&wifi_auth_header;</h3>
|
||||
<div id="scan-request">&wifi_auth_scan_request;</div>
|
||||
|
||||
<div id="qr-code">
|
||||
<div id="qr-code-wrapper">
|
||||
<img/>
|
||||
</div>
|
||||
<a id="no-scanner" class="toggle-scanner">&wifi_auth_no_scanner;</a>
|
||||
</div>
|
||||
|
||||
<div id="token">
|
||||
<div>&wifi_auth_token_request;</div>
|
||||
<pre id="token-value"/>
|
||||
<a id="yes-scanner" class="toggle-scanner">&wifi_auth_yes_scanner;</a>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -365,7 +365,10 @@ let AppManager = exports.AppManager = {
|
||||
try {
|
||||
// Reset the connection's state to defaults
|
||||
this.connection.resetOptions();
|
||||
deferred.resolve(this.selectedRuntime.connect(this.connection));
|
||||
// Only watch for errors here. Final resolution occurs above, once
|
||||
// we've reached the CONNECTED state.
|
||||
this.selectedRuntime.connect(this.connection)
|
||||
.then(null, e => deferred.reject(e));
|
||||
} catch(e) {
|
||||
deferred.reject(e);
|
||||
}
|
||||
|
@ -2,7 +2,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/. */
|
||||
|
||||
const {Cu} = require("chrome");
|
||||
const {Cu, Ci} = require("chrome");
|
||||
const {Devices} = Cu.import("resource://gre/modules/devtools/Devices.jsm");
|
||||
const {Services} = Cu.import("resource://gre/modules/Services.jsm");
|
||||
const {Simulator} = Cu.import("resource://gre/modules/devtools/Simulator.jsm");
|
||||
@ -11,6 +11,10 @@ const {DebuggerServer} = require("resource://gre/modules/devtools/dbg-server.jsm
|
||||
const discovery = require("devtools/toolkit/discovery/discovery");
|
||||
const EventEmitter = require("devtools/toolkit/event-emitter");
|
||||
const promise = require("promise");
|
||||
loader.lazyRequireGetter(this, "AuthenticationResult",
|
||||
"devtools/toolkit/security/auth", true);
|
||||
loader.lazyRequireGetter(this, "DevToolsUtils",
|
||||
"devtools/toolkit/DevToolsUtils");
|
||||
|
||||
const Strings = Services.strings.createBundle("chrome://browser/locale/devtools/webide.properties");
|
||||
|
||||
@ -448,7 +452,7 @@ WiFiRuntime.prototype = {
|
||||
return promise.reject(new Error("Can't find device: " + this.name));
|
||||
}
|
||||
connection.advertisement = service;
|
||||
// TODO: Customize client authentication UX
|
||||
connection.authenticator.sendOOB = this.sendOOB;
|
||||
connection.connect();
|
||||
return promise.resolve();
|
||||
},
|
||||
@ -458,6 +462,81 @@ WiFiRuntime.prototype = {
|
||||
get name() {
|
||||
return this.deviceName;
|
||||
},
|
||||
|
||||
/**
|
||||
* During OOB_CERT authentication, a notification dialog like this is used to
|
||||
* to display a token which the user must transfer through some mechanism to the
|
||||
* server to authenticate the devices.
|
||||
*
|
||||
* This implementation presents the token as text for the user to transfer
|
||||
* manually. For a mobile device, you should override this implementation with
|
||||
* something more convenient, such as displaying a QR code.
|
||||
*
|
||||
* This method receives an object containing:
|
||||
* @param host string
|
||||
* The host name or IP address of the debugger server.
|
||||
* @param port number
|
||||
* The port number of the debugger server.
|
||||
* @param cert object (optional)
|
||||
* The server's cert details.
|
||||
* @param authResult AuthenticationResult
|
||||
* Authentication result sent from the server.
|
||||
* @param oob object (optional)
|
||||
* The token data to be transferred during OOB_CERT step 8:
|
||||
* * sha256: hash(ClientCert)
|
||||
* * k : K(random 128-bit number)
|
||||
* @return object containing:
|
||||
* * close: Function to hide the notification
|
||||
*/
|
||||
sendOOB(session) {
|
||||
const WINDOW_ID = "devtools:wifi-auth";
|
||||
let { authResult } = session;
|
||||
// Only show in the PENDING state
|
||||
if (authResult != AuthenticationResult.PENDING) {
|
||||
throw new Error("Expected PENDING result, got " + authResult);
|
||||
}
|
||||
|
||||
// Listen for the window our prompt opens, so we can close it programatically
|
||||
let promptWindow;
|
||||
let windowListener = {
|
||||
onOpenWindow(xulWindow) {
|
||||
let win = xulWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindow);
|
||||
win.addEventListener("load", function listener() {
|
||||
win.removeEventListener("load", listener, false);
|
||||
if (win.document.documentElement.getAttribute("id") != WINDOW_ID) {
|
||||
return;
|
||||
}
|
||||
// Found the window
|
||||
promptWindow = win;
|
||||
Services.wm.removeListener(windowListener);
|
||||
}, false);
|
||||
},
|
||||
onCloseWindow() {},
|
||||
onWindowTitleChange() {}
|
||||
};
|
||||
Services.wm.addListener(windowListener);
|
||||
|
||||
// |openDialog| is typically a blocking API, so |executeSoon| to get around this
|
||||
DevToolsUtils.executeSoon(() => {
|
||||
let win = Services.wm.getMostRecentWindow("devtools:webide");
|
||||
let width = win.outerWidth * 0.8;
|
||||
let height = win.outerHeight * 0.5;
|
||||
win.openDialog("chrome://webide/content/wifi-auth.xhtml",
|
||||
WINDOW_ID,
|
||||
"modal=yes,width=" + width + ",height=" + height, session);
|
||||
});
|
||||
|
||||
return {
|
||||
close() {
|
||||
if (!promptWindow) {
|
||||
return;
|
||||
}
|
||||
promptWindow.close();
|
||||
promptWindow = null;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// For testing use only
|
||||
|
@ -16,3 +16,4 @@ webide.jar:
|
||||
skin/permissionstable.css (permissionstable.css)
|
||||
skin/monitor.css (monitor.css)
|
||||
skin/config-view.css (config-view.css)
|
||||
skin/wifi-auth.css (wifi-auth.css)
|
||||
|
60
browser/devtools/webide/themes/wifi-auth.css
Normal file
60
browser/devtools/webide/themes/wifi-auth.css
Normal file
@ -0,0 +1,60 @@
|
||||
/* 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/. */
|
||||
|
||||
html, body {
|
||||
background: white;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 90%;
|
||||
}
|
||||
|
||||
div {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
#qr-code {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#qr-code-wrapper {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
margin: 2em 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#qr-code img {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.toggle-scanner {
|
||||
color: #4C9ED9;
|
||||
font-size: small;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px dotted;
|
||||
}
|
||||
|
||||
#token {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body[token] > #token {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
body[token] > #qr-code {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#token pre,
|
||||
#token a {
|
||||
align-self: center;
|
||||
}
|
@ -400,6 +400,7 @@
|
||||
@RESPATH@/components/toolkitsearch.manifest
|
||||
@RESPATH@/components/nsSearchService.js
|
||||
@RESPATH@/components/nsSearchSuggestions.js
|
||||
@RESPATH@/components/nsSidebar.js
|
||||
@RESPATH@/components/passwordmgr.manifest
|
||||
@RESPATH@/components/nsLoginInfo.js
|
||||
@RESPATH@/components/nsLoginManager.js
|
||||
@ -419,8 +420,6 @@
|
||||
@RESPATH@/components/nsHelperAppDlg.js
|
||||
@RESPATH@/components/NetworkGeolocationProvider.manifest
|
||||
@RESPATH@/components/NetworkGeolocationProvider.js
|
||||
@RESPATH@/browser/components/nsSidebar.manifest
|
||||
@RESPATH@/browser/components/nsSidebar.js
|
||||
@RESPATH@/components/extensions.manifest
|
||||
@RESPATH@/components/addonManager.js
|
||||
@RESPATH@/components/amContentHandler.js
|
||||
|
@ -591,6 +591,11 @@ getUserMedia.sharingMenuMicrophoneWindow = %S (microphone and window)
|
||||
# origin for the sharing menu if no readable origin could be deduced from the URL.
|
||||
getUserMedia.sharingMenuUnknownHost = Unknown origin
|
||||
|
||||
# LOCALIZATION NOTE(emeNotifications.drmContentPlaying.message): %1$S is the vendor name of the DRM that's in use, %2$S is brandShortName.
|
||||
emeNotifications.drmContentPlaying.message = Some audio or video on this site uses %1$S DRM software, which may limit what %2$S can let you do with it.
|
||||
emeNotifications.drmContentPlaying.button.label = Configure…
|
||||
emeNotifications.drmContentPlaying.button.accesskey = C
|
||||
|
||||
# LOCALIZATION NOTE - %S is brandShortName
|
||||
slowStartup.message = %S seems slow… to… start.
|
||||
slowStartup.helpButton.label = Learn How to Speed It Up
|
||||
|
@ -81,6 +81,11 @@
|
||||
<!ENTITY profilerUI.invertTree "Invert Call Tree">
|
||||
<!ENTITY profilerUI.invertTree.tooltiptext "Inverting the call tree displays the profiled call paths starting from the youngest frames and expanding out to the older frames.">
|
||||
|
||||
<!-- LOCALIZATION NOTE (profilerUI.invertFlameGraph): This is the label shown next to
|
||||
- a checkbox that inverts and un-inverts the profiler's flame graph. -->
|
||||
<!ENTITY profilerUI.invertFlameGraph "Invert Flame Chart">
|
||||
<!ENTITY profilerUI.invertFlameGraph.tooltiptext "Inverting the flame chart displays the profiled call paths starting from the youngest frames and expanding out to the older frames.">
|
||||
|
||||
<!-- LOCALIZATION NOTE (profilerUI.showPlatformData): This is the
|
||||
- label for the checkbox that toggles whether or not Gecko platform data
|
||||
- is displayed in the profiler. -->
|
||||
|
@ -173,3 +173,21 @@
|
||||
<!-- Monitor -->
|
||||
<!ENTITY monitor_title "Monitor">
|
||||
<!ENTITY monitor_help "Help">
|
||||
|
||||
<!-- WiFi Authentication -->
|
||||
<!-- LOCALIZATION NOTE (wifi_auth_header): The header displayed on the dialog
|
||||
that instructs the user to transfer an authentication token to the
|
||||
server. -->
|
||||
<!ENTITY wifi_auth_header "Client Identification">
|
||||
<!-- LOCALIZATION NOTE (wifi_auth_scan_request): Instructions requesting the
|
||||
user to transfer authentication info by scanning a QR code. -->
|
||||
<!ENTITY wifi_auth_scan_request "The endpoint you are connecting to needs more information to authenticate this connection. Please scan the QR code below via the prompt on your other device.">
|
||||
<!-- LOCALIZATION NOTE (wifi_auth_no_scanner): Link text to assist users with
|
||||
devices that can't scan a QR code. -->
|
||||
<!ENTITY wifi_auth_no_scanner "No QR scanner prompt?">
|
||||
<!-- LOCALIZATION NOTE (wifi_auth_yes_scanner): Link text to assist users with
|
||||
devices that can scan a QR code. -->
|
||||
<!ENTITY wifi_auth_yes_scanner "Have a QR scanner prompt?">
|
||||
<!-- LOCALIZATION NOTE (wifi_auth_token_request): Instructions requesting the
|
||||
user to transfer authentication info by transferring a token. -->
|
||||
<!ENTITY wifi_auth_token_request "If your other device asks for a token instead of scanning a QR code, please copy the value below to the other device:">
|
||||
|
47
browser/modules/ContentObservers.jsm
Normal file
47
browser/modules/ContentObservers.jsm
Normal file
@ -0,0 +1,47 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
/**
|
||||
* This module is for small observers that we want to register once per content
|
||||
* process, usually in order to forward content-based observer service notifications
|
||||
* to the chrome process through message passing. Using a JSM avoids having them
|
||||
* in content.js and thereby registering N observers for N open tabs, which is bad
|
||||
* for perf.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = [];
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
let gEMEUIObserver = function(subject, topic, data) {
|
||||
let win = subject.ownerDocument.defaultView.top;
|
||||
let mm = getMessageManagerForWindow(win);
|
||||
if (mm) {
|
||||
mm.sendAsyncMessage("EMEVideo:MetadataLoaded", {
|
||||
// bug 1129370 covers making this the actual DRM provider inferred from
|
||||
// either |subject| or |data| here.
|
||||
drmProvider: "Adobe"
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function getMessageManagerForWindow(aContentWindow) {
|
||||
let ir = aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDocShell)
|
||||
.sameTypeRootTreeItem
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor);
|
||||
try {
|
||||
// If e10s is disabled, this throws NS_NOINTERFACE for closed tabs.
|
||||
return ir.getInterface(Ci.nsIContentFrameMessageManager);
|
||||
} catch(e if e.result == Cr.NS_NOINTERFACE) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Services.obs.addObserver(gEMEUIObserver, "media-eme-metadataloaded", false);
|
@ -16,6 +16,7 @@ EXTRA_JS_MODULES += [
|
||||
'Chat.jsm',
|
||||
'ContentClick.jsm',
|
||||
'ContentLinkHandler.jsm',
|
||||
'ContentObservers.jsm',
|
||||
'ContentSearch.jsm',
|
||||
'ContentWebRTC.jsm',
|
||||
'CustomizationTabPreloader.jsm',
|
||||
|
@ -2185,6 +2185,17 @@ chatbox {
|
||||
border-top-right-radius: 2.5px;
|
||||
}
|
||||
|
||||
/* EME notifications */
|
||||
|
||||
.popup-notification-icon[popupid="drmContentPlaying"],
|
||||
#eme-notification-icon {
|
||||
list-style-image: url("chrome://browser/skin/drm-icon.svg#chains");
|
||||
}
|
||||
|
||||
#eme-notification-icon:hover:active {
|
||||
list-style-image: url("chrome://browser/skin/drm-icon.svg#chains-pressed");
|
||||
}
|
||||
|
||||
/* Customization mode */
|
||||
|
||||
%include ../shared/customizableui/customizeMode.inc.css
|
||||
|
@ -30,6 +30,7 @@ browser.jar:
|
||||
skin/classic/browser/content-contextmenu.svg
|
||||
skin/classic/browser/dots.png (../shared/dots.png)
|
||||
skin/classic/browser/dots@2x.png (../shared/dots@2x.png)
|
||||
skin/classic/browser/drm-icon.svg (../shared/drm-icon.svg)
|
||||
* skin/classic/browser/engineManager.css
|
||||
skin/classic/browser/fullscreen-darknoise.png
|
||||
skin/classic/browser/Geolocation-16.png
|
||||
|
@ -4612,6 +4612,17 @@ window > chatbox {
|
||||
border-bottom-right-radius: @toolbarbuttonCornerRadius@;
|
||||
}
|
||||
|
||||
/* EME notifications */
|
||||
|
||||
.popup-notification-icon[popupid="drmContentPlaying"],
|
||||
#eme-notification-icon {
|
||||
list-style-image: url("chrome://browser/skin/drm-icon.svg#chains");
|
||||
}
|
||||
|
||||
#eme-notification-icon:hover:active {
|
||||
list-style-image: url("chrome://browser/skin/drm-icon.svg#chains-pressed");
|
||||
}
|
||||
|
||||
/* Customization mode */
|
||||
|
||||
%include ../shared/customizableui/customizeMode.inc.css
|
||||
|
@ -30,6 +30,7 @@ browser.jar:
|
||||
skin/classic/browser/content-contextmenu.svg
|
||||
skin/classic/browser/dots.png (../shared/dots.png)
|
||||
skin/classic/browser/dots@2x.png (../shared/dots@2x.png)
|
||||
skin/classic/browser/drm-icon.svg (../shared/drm-icon.svg)
|
||||
* skin/classic/browser/engineManager.css (engineManager.css)
|
||||
skin/classic/browser/fullscreen-darknoise.png
|
||||
skin/classic/browser/Geolocation-16.png
|
||||
|
47
browser/themes/shared/drm-icon.svg
Normal file
47
browser/themes/shared/drm-icon.svg
Normal file
@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||
<style>
|
||||
#chains > use > path {
|
||||
fill: url(#baseGradient);
|
||||
}
|
||||
#chains-pressed > use > path {
|
||||
fill: url(#pressedGradient);
|
||||
}
|
||||
|
||||
g:not(:target) {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<defs>
|
||||
<linearGradient id="baseGradient" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="16" y2="0">
|
||||
<stop offset="0" style="stop-color:#808080"/>
|
||||
<stop offset="1" style="stop-color:#999999"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="pressedGradient" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="16" y2="0">
|
||||
<stop offset="0" style="stop-color:#4D4D4D"/>
|
||||
<stop offset="1" style="stop-color:#808080"/>
|
||||
</linearGradient>
|
||||
<path id="path1" d="M7.058,9.72c-0.245,0.245-0.62,0.27-0.834,0.056C6.01,9.562,6.035,9.186,6.28,8.942l0.218-0.218
|
||||
c-0.245-0.245-0.645-0.245-0.89,0L4.496,9.836c-0.245,0.245-0.245,0.645,0,0.89l0.779,0.779c0.245,0.245,0.645,0.245,0.89,0
|
||||
l1.112-1.112c0.245-0.245,0.245-0.645,0-0.89L7.058,9.72z"/>
|
||||
<path id="path2" d="M10.726,4.496c-0.245-0.245-0.645-0.245-0.89,0L8.723,5.608c-0.245,0.245-0.245,0.645,0,0.89
|
||||
L8.95,6.272c0.245-0.245,0.62-0.27,0.834-0.056s0.189,0.59-0.056,0.834L9.502,7.277c0.245,0.245,0.645,0.245,0.89,0l1.112-1.112
|
||||
c0.245-0.245,0.245-0.645,0-0.89L10.726,4.496z"/>
|
||||
<path id="path3" d="M8,0C3.582,0,0,3.582,0,8s3.582,8,8,8s8-3.582,8-8S12.418,0,8,0z M12.527,6.81l-1.489,1.489
|
||||
c-0.631,0.631-1.663,0.631-2.293,0L8.612,8.167L8.167,8.612l0.133,0.133c0.631,0.631,0.631,1.663,0,2.293L6.81,12.527
|
||||
c-0.631,0.631-1.663,0.631-2.293,0l-1.044-1.044c-0.631-0.631-0.631-1.663,0-2.293l1.489-1.489c0.631-0.631,1.663-0.631,2.293,0
|
||||
l0.133,0.133l0.445-0.445L7.701,7.255c-0.631-0.631-0.631-1.663,0-2.293L9.19,3.473c0.631-0.631,1.663-0.631,2.293,0l1.044,1.044
|
||||
C13.158,5.148,13.158,6.18,12.527,6.81z"/>
|
||||
</defs>
|
||||
<g id="chains">
|
||||
<use xlink:href="#path1"/>
|
||||
<use xlink:href="#path2"/>
|
||||
<use xlink:href="#path3"/>
|
||||
</g>
|
||||
<g id="chains-pressed">
|
||||
<use xlink:href="#path1"/>
|
||||
<use xlink:href="#path2"/>
|
||||
<use xlink:href="#path3"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.3 KiB |
@ -153,15 +153,19 @@ treecol {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#startupTable > tr > .content-cell {
|
||||
display: flex;
|
||||
#startupTable > tr > .content-cell > menulist,
|
||||
#startupTable > tr > .content-cell > textbox {
|
||||
width: calc(100% - 8px);
|
||||
margin-left: 4px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
#startupTable > tr > .homepage-buttons {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
#startupTable > tr > td > .content-cell-item {
|
||||
#startupTable > tr > .homepage-buttons > .content-cell-item {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
|
@ -2807,6 +2807,17 @@ chatbox {
|
||||
border-top-right-radius: 2.5px;
|
||||
}
|
||||
|
||||
/* EME notifications */
|
||||
|
||||
.popup-notification-icon[popupid="drmContentPlaying"],
|
||||
#eme-notification-icon {
|
||||
list-style-image: url("chrome://browser/skin/drm-icon.svg#chains");
|
||||
}
|
||||
|
||||
#eme-notification-icon:hover:active {
|
||||
list-style-image: url("chrome://browser/skin/drm-icon.svg#chains-pressed");
|
||||
}
|
||||
|
||||
/* Customization mode */
|
||||
|
||||
%include ../shared/customizableui/customizeMode.inc.css
|
||||
|
@ -32,6 +32,7 @@ browser.jar:
|
||||
skin/classic/browser/content-contextmenu.svg
|
||||
skin/classic/browser/dots.png (../shared/dots.png)
|
||||
skin/classic/browser/dots@2x.png (../shared/dots@2x.png)
|
||||
skin/classic/browser/drm-icon.svg (../shared/drm-icon.svg)
|
||||
* skin/classic/browser/engineManager.css
|
||||
skin/classic/browser/fullscreen-darknoise.png
|
||||
skin/classic/browser/Geolocation-16.png
|
||||
@ -494,6 +495,7 @@ browser.jar:
|
||||
* skin/classic/aero/browser/content-contextmenu.svg
|
||||
skin/classic/aero/browser/dots.png (../shared/dots.png)
|
||||
skin/classic/aero/browser/dots@2x.png (../shared/dots@2x.png)
|
||||
skin/classic/aero/browser/drm-icon.svg (../shared/drm-icon.svg)
|
||||
* skin/classic/aero/browser/engineManager.css
|
||||
skin/classic/aero/browser/fullscreen-darknoise.png
|
||||
skin/classic/aero/browser/Geolocation-16.png
|
||||
|
@ -505,7 +505,7 @@ IsFeatureInBlacklist(const nsCOMPtr<nsIGfxInfo>& gfxInfo, int32_t feature)
|
||||
|
||||
static already_AddRefed<GLContext>
|
||||
CreateHeadlessNativeGL(bool forceEnabled, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
|
||||
bool requireCompatProfile, WebGLContext* webgl)
|
||||
WebGLContext* webgl)
|
||||
{
|
||||
if (!forceEnabled &&
|
||||
IsFeatureInBlacklist(gfxInfo, nsIGfxInfo::FEATURE_WEBGL_OPENGL))
|
||||
@ -515,7 +515,7 @@ CreateHeadlessNativeGL(bool forceEnabled, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<GLContext> gl = gl::GLContextProvider::CreateHeadless(requireCompatProfile);
|
||||
nsRefPtr<GLContext> gl = gl::GLContextProvider::CreateHeadless();
|
||||
if (!gl) {
|
||||
webgl->GenerateWarning("Error during native OpenGL init.");
|
||||
return nullptr;
|
||||
@ -530,7 +530,7 @@ CreateHeadlessNativeGL(bool forceEnabled, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
|
||||
// Eventually, we want to be able to pick ANGLE-EGL or native EGL.
|
||||
static already_AddRefed<GLContext>
|
||||
CreateHeadlessANGLE(bool forceEnabled, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
|
||||
bool requireCompatProfile, WebGLContext* webgl)
|
||||
WebGLContext* webgl)
|
||||
{
|
||||
nsRefPtr<GLContext> gl;
|
||||
|
||||
@ -543,7 +543,7 @@ CreateHeadlessANGLE(bool forceEnabled, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
gl = gl::GLContextProviderEGL::CreateHeadless(requireCompatProfile);
|
||||
gl = gl::GLContextProviderEGL::CreateHeadless();
|
||||
if (!gl) {
|
||||
webgl->GenerateWarning("Error during ANGLE OpenGL init.");
|
||||
return nullptr;
|
||||
@ -555,13 +555,13 @@ CreateHeadlessANGLE(bool forceEnabled, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
|
||||
}
|
||||
|
||||
static already_AddRefed<GLContext>
|
||||
CreateHeadlessEGL(bool forceEnabled, bool requireCompatProfile,
|
||||
CreateHeadlessEGL(bool forceEnabled, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
|
||||
WebGLContext* webgl)
|
||||
{
|
||||
nsRefPtr<GLContext> gl;
|
||||
|
||||
#ifdef ANDROID
|
||||
gl = gl::GLContextProviderEGL::CreateHeadless(requireCompatProfile);
|
||||
gl = gl::GLContextProviderEGL::CreateHeadless();
|
||||
if (!gl) {
|
||||
webgl->GenerateWarning("Error during EGL OpenGL init.");
|
||||
return nullptr;
|
||||
@ -583,22 +583,16 @@ CreateHeadlessGL(bool forceEnabled, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
|
||||
if (PR_GetEnv("MOZ_WEBGL_FORCE_OPENGL"))
|
||||
disableANGLE = true;
|
||||
|
||||
bool requireCompatProfile = webgl->IsWebGL2() ? false : true;
|
||||
|
||||
nsRefPtr<GLContext> gl;
|
||||
|
||||
if (preferEGL)
|
||||
gl = CreateHeadlessEGL(forceEnabled, requireCompatProfile, webgl);
|
||||
gl = CreateHeadlessEGL(forceEnabled, gfxInfo, webgl);
|
||||
|
||||
if (!gl && !disableANGLE) {
|
||||
gl = CreateHeadlessANGLE(forceEnabled, gfxInfo, requireCompatProfile,
|
||||
webgl);
|
||||
}
|
||||
if (!gl && !disableANGLE)
|
||||
gl = CreateHeadlessANGLE(forceEnabled, gfxInfo, webgl);
|
||||
|
||||
if (!gl) {
|
||||
gl = CreateHeadlessNativeGL(forceEnabled, gfxInfo,
|
||||
requireCompatProfile, webgl);
|
||||
}
|
||||
if (!gl)
|
||||
gl = CreateHeadlessNativeGL(forceEnabled, gfxInfo, webgl);
|
||||
|
||||
return gl.forget();
|
||||
}
|
||||
|
@ -1209,10 +1209,9 @@ protected:
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// WebGL 2 specifics (implemented in WebGL2Context.cpp)
|
||||
public:
|
||||
|
||||
virtual bool IsWebGL2() const = 0;
|
||||
|
||||
protected:
|
||||
bool InitWebGL2();
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user