зеркало из https://github.com/mozilla/gecko-dev.git
Merge fx-team to m-c. a=merge
This commit is contained in:
Коммит
ca004651b3
|
@ -182,7 +182,7 @@ function makeNewWindow(domWindow, browserHint = false) {
|
|||
return new Window(domWindow);
|
||||
}
|
||||
|
||||
for (let domWindow of windows()) {
|
||||
for (let domWindow of windows(null, {includePrivate: supportPrivateWindows})) {
|
||||
let window = makeNewWindow(domWindow);
|
||||
if (window instanceof BrowserWindow)
|
||||
addListItem(browserWindows, window);
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 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/.
|
||||
<!-- 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 prefwindow SYSTEM "chrome://browser/locale/preferences/connection.dtd">
|
||||
|
||||
|
@ -15,16 +14,12 @@
|
|||
dlgbuttons="accept,cancel,help"
|
||||
onbeforeaccept="return gConnectionsDialog.beforeAccept();"
|
||||
onload="gConnectionsDialog.checkForSystemProxy();"
|
||||
ondialoghelp="openPrefsHelp()"
|
||||
#ifdef XP_MACOSX
|
||||
style="width: &window.macWidth; !important;">
|
||||
#else
|
||||
style="width: &window.width; !important;">
|
||||
#endif
|
||||
ondialoghelp="openPrefsHelp()">
|
||||
|
||||
<script type="application/javascript" src="chrome://browser/content/utilityOverlay.js"/>
|
||||
|
||||
<prefpane id="ConnectionsDialogPane"
|
||||
class="largeDialogContainer"
|
||||
helpTopic="prefs-connection-settings">
|
||||
|
||||
<preferences>
|
||||
|
@ -59,7 +54,7 @@
|
|||
<preference id="network.proxy.backup.socks" name="network.proxy.backup.socks" type="string"/>
|
||||
<preference id="network.proxy.backup.socks_port" name="network.proxy.backup.socks_port" type="int"/>
|
||||
</preferences>
|
||||
|
||||
|
||||
<script type="application/javascript" src="chrome://browser/content/preferences/connection.js"/>
|
||||
|
||||
<stringbundle id="preferencesBundle" src="chrome://browser/locale/preferences/preferences.properties"/>
|
||||
|
@ -156,7 +151,7 @@
|
|||
oninput="gConnectionsDialog.updateReloadButton();"/>
|
||||
<button id="autoReload" icon="refresh"
|
||||
label="&reload.label;" accesskey="&reload.accesskey;"
|
||||
oncommand="gConnectionsDialog.reloadPAC();"
|
||||
oncommand="gConnectionsDialog.reloadPAC();"
|
||||
preference="pref.advanced.proxies.disable_button.reload"/>
|
||||
</hbox>
|
||||
</radiogroup>
|
||||
|
@ -171,4 +166,3 @@
|
|||
<separator/>
|
||||
</prefpane>
|
||||
</prefwindow>
|
||||
|
||||
|
|
|
@ -351,10 +351,7 @@ var gAdvancedPane = {
|
|||
*/
|
||||
showConnections: function ()
|
||||
{
|
||||
openDialog("chrome://browser/content/preferences/connection.xul",
|
||||
"mozilla:connectionmanager",
|
||||
"modal=yes",
|
||||
null);
|
||||
gSubDialog.open("chrome://browser/content/preferences/connection.xul");
|
||||
},
|
||||
|
||||
// Retrieves the amount of space currently used by disk cache
|
||||
|
@ -506,10 +503,8 @@ var gAdvancedPane = {
|
|||
manageCapability : Components.interfaces.nsIPermissionManager.DENY_ACTION,
|
||||
windowTitle : bundlePreferences.getString("offlinepermissionstitle"),
|
||||
introText : bundlePreferences.getString("offlinepermissionstext") };
|
||||
openDialog("chrome://browser/content/preferences/permissions.xul",
|
||||
"Browser:Permissions",
|
||||
"modal=yes",
|
||||
params);
|
||||
gSubDialog.open("chrome://browser/content/preferences/permissions.xul",
|
||||
null, params);
|
||||
},
|
||||
|
||||
// XXX: duplicated in browser.js
|
||||
|
@ -779,9 +774,7 @@ var gAdvancedPane = {
|
|||
*/
|
||||
showSecurityDevices: function ()
|
||||
{
|
||||
openDialog("chrome://pippki/content/device_manager.xul",
|
||||
"mozilla:devicemanager",
|
||||
"modal=yes", null);
|
||||
gSubDialog.open("chrome://pippki/content/device_manager.xul");
|
||||
},
|
||||
|
||||
observe: function (aSubject, aTopic, aData) {
|
||||
|
|
|
@ -208,7 +208,7 @@ var gSearchPane = {
|
|||
|
||||
onTreeSelect: function() {
|
||||
document.getElementById("removeEngineButton").disabled =
|
||||
gEngineView.selectedIndex == -1 || gEngineView.lastIndex == 0;
|
||||
!gEngineView.isEngineSelectedAndRemovable();
|
||||
},
|
||||
|
||||
onTreeKeyPress: function(aEvent) {
|
||||
|
@ -229,7 +229,9 @@ var gSearchPane = {
|
|||
(!isMac && aEvent.keyCode == KeyEvent.DOM_VK_F2)) {
|
||||
tree.startEditing(index, tree.columns.getLastColumn());
|
||||
} else if (aEvent.keyCode == KeyEvent.DOM_VK_DELETE ||
|
||||
isMac && aEvent.shiftKey && aEvent.keyCode == KeyEvent.DOM_VK_BACK_SPACE) {
|
||||
(isMac && aEvent.shiftKey &&
|
||||
aEvent.keyCode == KeyEvent.DOM_VK_BACK_SPACE &&
|
||||
gEngineView.isEngineSelectedAndRemovable())) {
|
||||
// Delete and Shift+Backspace (Mac) removes selected engine.
|
||||
Services.search.removeEngine(gEngineView.selectedEngine.originalEngine);
|
||||
}
|
||||
|
@ -387,6 +389,10 @@ EngineStore.prototype = {
|
|||
},
|
||||
|
||||
removeEngine: function ES_removeEngine(aEngine) {
|
||||
if (this._engines.length == 1) {
|
||||
throw new Error("Cannot remove last engine!");
|
||||
}
|
||||
|
||||
let engineName = aEngine.name;
|
||||
let index = this._engines.findIndex(element => element.name == engineName);
|
||||
|
||||
|
@ -490,6 +496,10 @@ EngineView.prototype = {
|
|||
return column.id == "engineShown";
|
||||
},
|
||||
|
||||
isEngineSelectedAndRemovable: function() {
|
||||
return this.selectedIndex != -1 && this.lastIndex != 0;
|
||||
},
|
||||
|
||||
// nsITreeView
|
||||
get rowCount() {
|
||||
return this._engineStore.engines.length;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* 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/Task.jsm");
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
@ -18,53 +19,30 @@ function test() {
|
|||
});
|
||||
|
||||
let connectionURL = "chrome://browser/content/preferences/connection.xul";
|
||||
let windowWatcher = Services.ww;
|
||||
|
||||
// instantApply must be true, otherwise connection dialog won't save
|
||||
// when opened from in-content prefs
|
||||
Services.prefs.setBoolPref("browser.preferences.instantApply", true);
|
||||
|
||||
// this observer is registered after the pref tab loads
|
||||
let observer = {
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
if (aTopic == "domwindowopened") {
|
||||
// when connection window loads, run tests and acceptDialog()
|
||||
let win = aSubject.QueryInterface(Components.interfaces.nsIDOMWindow);
|
||||
win.addEventListener("load", function winLoadListener() {
|
||||
win.removeEventListener("load", winLoadListener, false);
|
||||
if (win.location.href == connectionURL) {
|
||||
ok(true, "connection window opened");
|
||||
runConnectionTests(win);
|
||||
win.document.documentElement.acceptDialog();
|
||||
}
|
||||
}, false);
|
||||
} else if (aTopic == "domwindowclosed") {
|
||||
// finish up when connection window closes
|
||||
let win = aSubject.QueryInterface(Components.interfaces.nsIDOMWindow);
|
||||
if (win.location.href == connectionURL) {
|
||||
windowWatcher.unregisterNotification(observer);
|
||||
ok(true, "connection window closed");
|
||||
// runConnectionTests will have changed this pref - make sure it was
|
||||
// sanitized correctly when the dialog was accepted
|
||||
is(Services.prefs.getCharPref("network.proxy.no_proxies_on"),
|
||||
".a.com,.b.com,.c.com", "no_proxies_on pref has correct value");
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
The connection dialog alone won't save onaccept since it uses type="child",
|
||||
so it has to be opened as a sub dialog of the main pref tab.
|
||||
Open the main tab here.
|
||||
*/
|
||||
open_preferences(function tabOpened(aContentWindow) {
|
||||
open_preferences(Task.async(function* tabOpened(aContentWindow) {
|
||||
is(gBrowser.currentURI.spec, "about:preferences", "about:preferences loaded");
|
||||
windowWatcher.registerNotification(observer);
|
||||
gBrowser.contentWindow.gAdvancedPane.showConnections();
|
||||
});
|
||||
let dialog = yield openAndLoadSubDialog(connectionURL);
|
||||
let dialogClosingPromise = waitForEvent(dialog.document.documentElement, "dialogclosing");
|
||||
|
||||
ok(dialog, "connection window opened");
|
||||
runConnectionTests(dialog);
|
||||
dialog.document.documentElement.acceptDialog();
|
||||
|
||||
let dialogClosingEvent = yield dialogClosingPromise;
|
||||
ok(dialogClosingEvent, "connection window closed");
|
||||
// runConnectionTests will have changed this pref - make sure it was
|
||||
// sanitized correctly when the dialog was accepted
|
||||
is(Services.prefs.getCharPref("network.proxy.no_proxies_on"),
|
||||
".a.com,.b.com,.c.com", "no_proxies_on pref has correct value");
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}));
|
||||
}
|
||||
|
||||
// run a bunch of tests on the window containing connection.xul
|
||||
|
|
|
@ -3,25 +3,13 @@
|
|||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
// From browser/components/preferences/in-content/test/head.js
|
||||
function open_preferences(aCallback) {
|
||||
gBrowser.selectedTab = gBrowser.addTab("about:preferences");
|
||||
let newTabBrowser = gBrowser.getBrowserForTab(gBrowser.selectedTab);
|
||||
newTabBrowser.addEventListener("Initialized", function () {
|
||||
newTabBrowser.removeEventListener("Initialized", arguments.callee, true);
|
||||
aCallback(gBrowser.contentWindow);
|
||||
}, true);
|
||||
}
|
||||
Components.utils.import("resource://gre/modules/Task.jsm");
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
let connectionTests = runConnectionTestsGen();
|
||||
connectionTests.next();
|
||||
const connectionURL = "chrome://browser/content/preferences/connection.xul";
|
||||
let closeable = false;
|
||||
let finalTest = false;
|
||||
let prefWin;
|
||||
|
||||
// The changed preferences need to be backed up and restored because this mochitest
|
||||
// changes them setting from the default
|
||||
|
@ -38,55 +26,34 @@ function test() {
|
|||
Services.prefs.clearUserPref("network.proxy.backup." + proxyType);
|
||||
Services.prefs.clearUserPref("network.proxy.backup." + proxyType + "_port");
|
||||
}
|
||||
try {
|
||||
Services.ww.unregisterNotification(observer);
|
||||
} catch (e) {
|
||||
// Do nothing, if the test was successful the above line should fail silently.
|
||||
}
|
||||
});
|
||||
|
||||
// this observer is registered after the pref tab loads
|
||||
let observer = {
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
if (aTopic == "domwindowopened") {
|
||||
// when the connection window loads, proceed forward in test
|
||||
let win = aSubject.QueryInterface(Components.interfaces.nsIDOMWindow);
|
||||
win.addEventListener("load", function winLoadListener() {
|
||||
win.removeEventListener("load", winLoadListener);
|
||||
if (win.location.href == connectionURL) {
|
||||
// If this is a connection window, run the next test
|
||||
connectionTests.next(win);
|
||||
}
|
||||
});
|
||||
} else if (aTopic == "domwindowclosed") {
|
||||
// Check if the window should have closed, and respawn another window for further testing
|
||||
let win = aSubject.QueryInterface(Components.interfaces.nsIDOMWindow);
|
||||
if (win.location.href == connectionURL) {
|
||||
ok(closeable, "Connection dialog closed");
|
||||
|
||||
// Last close event, don't respawn, and clean up
|
||||
if (finalTest) {
|
||||
Services.ww.unregisterNotification(observer);
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
// Open another connection pane for the next test
|
||||
gBrowser.contentWindow.gAdvancedPane.showConnections();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// The actual tests to run, in a generator
|
||||
function* runConnectionTestsGen() {
|
||||
let doc, connectionWin, proxyTypePref, sharePref, httpPref, httpPortPref, ftpPref, ftpPortPref;
|
||||
/*
|
||||
The connection dialog alone won't save onaccept since it uses type="child",
|
||||
so it has to be opened as a sub dialog of the main pref tab.
|
||||
Open the main tab here.
|
||||
*/
|
||||
open_preferences(Task.async(function* tabOpened(aContentWindow) {
|
||||
let dialog, dialogClosingPromise;
|
||||
let doc, proxyTypePref, sharePref, httpPref, httpPortPref, ftpPref, ftpPortPref;
|
||||
|
||||
// Convenient function to reset the variables for the new window
|
||||
function setDoc(win) {
|
||||
doc = win.document;
|
||||
connectionWin = win;
|
||||
function* setDoc() {
|
||||
if (closeable) {
|
||||
let dialogClosingEvent = yield dialogClosingPromise;
|
||||
ok(dialogClosingEvent, "Connection dialog closed");
|
||||
}
|
||||
|
||||
if (finalTest) {
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
dialog = yield openAndLoadSubDialog(connectionURL);
|
||||
dialogClosingPromise = waitForEvent(dialog.document.documentElement, "dialogclosing");
|
||||
|
||||
doc = dialog.document;
|
||||
proxyTypePref = doc.getElementById("network.proxy.type");
|
||||
sharePref = doc.getElementById("network.proxy.share_proxy_settings");
|
||||
httpPref = doc.getElementById("network.proxy.http");
|
||||
|
@ -96,7 +63,7 @@ function test() {
|
|||
}
|
||||
|
||||
// This batch of tests should not close the dialog
|
||||
setDoc(yield null);
|
||||
yield setDoc();
|
||||
|
||||
// Testing HTTP port 0 with share on
|
||||
proxyTypePref.value = 1;
|
||||
|
@ -126,7 +93,7 @@ function test() {
|
|||
doc.documentElement.acceptDialog();
|
||||
|
||||
// HTTP 80, FTP 0, with share on
|
||||
setDoc(yield null);
|
||||
yield setDoc();
|
||||
proxyTypePref.value = 1;
|
||||
sharePref.value = true;
|
||||
ftpPref.value = "localhost";
|
||||
|
@ -136,7 +103,7 @@ function test() {
|
|||
doc.documentElement.acceptDialog();
|
||||
|
||||
// HTTP host empty, port 0 with share on
|
||||
setDoc(yield null);
|
||||
yield setDoc();
|
||||
proxyTypePref.value = 1;
|
||||
sharePref.value = true;
|
||||
httpPref.value = "";
|
||||
|
@ -144,7 +111,7 @@ function test() {
|
|||
doc.documentElement.acceptDialog();
|
||||
|
||||
// HTTP 0, but in no proxy mode
|
||||
setDoc(yield null);
|
||||
yield setDoc();
|
||||
proxyTypePref.value = 0;
|
||||
sharePref.value = true;
|
||||
httpPref.value = "localhost";
|
||||
|
@ -153,16 +120,6 @@ function test() {
|
|||
// This is the final test, don't spawn another connection window
|
||||
finalTest = true;
|
||||
doc.documentElement.acceptDialog();
|
||||
yield null;
|
||||
}
|
||||
|
||||
/*
|
||||
The connection dialog alone won't save onaccept since it uses type="child",
|
||||
so it has to be opened as a sub dialog of the main pref tab.
|
||||
Open the main tab here.
|
||||
*/
|
||||
open_preferences(function tabOpened(aContentWindow) {
|
||||
Services.ww.registerNotification(observer);
|
||||
gBrowser.contentWindow.gAdvancedPane.showConnections();
|
||||
});
|
||||
yield setDoc();
|
||||
}));
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* 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/Task.jsm");
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
@ -27,11 +28,6 @@ function test() {
|
|||
});
|
||||
|
||||
let connectionURL = "chrome://browser/content/preferences/connection.xul";
|
||||
let windowWatcher = Services.ww;
|
||||
|
||||
// instantApply must be true, otherwise connection dialog won't save
|
||||
// when opened from in-content prefs
|
||||
Services.prefs.setBoolPref("browser.preferences.instantApply", true);
|
||||
|
||||
// Set a shared proxy and a SOCKS backup
|
||||
Services.prefs.setIntPref("network.proxy.type", 1);
|
||||
|
@ -43,46 +39,27 @@ function test() {
|
|||
Services.prefs.setCharPref("network.proxy.backup.socks", "127.0.0.1");
|
||||
Services.prefs.setIntPref("network.proxy.backup.socks_port", 9050);
|
||||
|
||||
// this observer is registered after the pref tab loads
|
||||
let observer = {
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
if (aTopic == "domwindowopened") {
|
||||
// when connection window loads, run tests and acceptDialog()
|
||||
let win = aSubject.QueryInterface(Components.interfaces.nsIDOMWindow);
|
||||
win.addEventListener("load", function winLoadListener() {
|
||||
win.removeEventListener("load", winLoadListener, false);
|
||||
if (win.location.href == connectionURL) {
|
||||
ok(true, "connection window opened");
|
||||
win.document.documentElement.acceptDialog();
|
||||
}
|
||||
}, false);
|
||||
} else if (aTopic == "domwindowclosed") {
|
||||
// finish up when connection window closes
|
||||
let win = aSubject.QueryInterface(Components.interfaces.nsIDOMWindow);
|
||||
if (win.location.href == connectionURL) {
|
||||
windowWatcher.unregisterNotification(observer);
|
||||
ok(true, "connection window closed");
|
||||
|
||||
// The SOCKS backup should not be replaced by the shared value
|
||||
is(Services.prefs.getCharPref("network.proxy.backup.socks"), "127.0.0.1", "Shared proxy backup shouldn't be replaced");
|
||||
is(Services.prefs.getIntPref("network.proxy.backup.socks_port"), 9050, "Shared proxy port backup shouldn't be replaced");
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
The connection dialog alone won't save onaccept since it uses type="child",
|
||||
so it has to be opened as a sub dialog of the main pref tab.
|
||||
Open the main tab here.
|
||||
*/
|
||||
open_preferences(function tabOpened(aContentWindow) {
|
||||
open_preferences(Task.async(function* tabOpened(aContentWindow) {
|
||||
is(gBrowser.currentURI.spec, "about:preferences", "about:preferences loaded");
|
||||
windowWatcher.registerNotification(observer);
|
||||
gBrowser.contentWindow.gAdvancedPane.showConnections();
|
||||
});
|
||||
}
|
||||
let dialog = yield openAndLoadSubDialog(connectionURL);
|
||||
let dialogClosingPromise = waitForEvent(dialog.document.documentElement, "dialogclosing");
|
||||
|
||||
ok(dialog, "connection window opened");
|
||||
dialog.document.documentElement.acceptDialog();
|
||||
|
||||
let dialogClosingEvent = yield dialogClosingPromise;
|
||||
ok(dialogClosingEvent, "connection window closed");
|
||||
|
||||
// The SOCKS backup should not be replaced by the shared value
|
||||
is(Services.prefs.getCharPref("network.proxy.backup.socks"), "127.0.0.1", "Shared proxy backup shouldn't be replaced");
|
||||
is(Services.prefs.getIntPref("network.proxy.backup.socks_port"), 9050, "Shared proxy port backup shouldn't be replaced");
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}));
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ browser.jar:
|
|||
* content/browser/preferences/colors.xul
|
||||
* content/browser/preferences/cookies.xul
|
||||
content/browser/preferences/cookies.js
|
||||
* content/browser/preferences/connection.xul
|
||||
content/browser/preferences/connection.xul
|
||||
content/browser/preferences/connection.js
|
||||
content/browser/preferences/donottrack.xul
|
||||
* content/browser/preferences/fonts.xul
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
|
||||
|
||||
<!ENTITY connectionsDialog.title "Connection Settings">
|
||||
<!ENTITY window.width "37em">
|
||||
<!ENTITY window.macWidth "39em">
|
||||
|
||||
<!ENTITY proxyTitle.label "Configure Proxies to Access the Internet">
|
||||
<!ENTITY noProxyTypeRadio.label "No proxy">
|
||||
|
|
|
@ -77,15 +77,11 @@
|
|||
background-color: -moz-Dialog;
|
||||
}
|
||||
|
||||
#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar):not(#nav-bar) {
|
||||
padding-top: 1px;
|
||||
padding-bottom: 1px;
|
||||
}
|
||||
|
||||
#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar):not(#nav-bar):not(#addon-bar) {
|
||||
overflow: -moz-hidden-unscrollable;
|
||||
max-height: 4em;
|
||||
transition: min-height 170ms ease-out, max-height 170ms ease-out;
|
||||
padding: 1px 4px;
|
||||
}
|
||||
|
||||
#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar):not(#nav-bar):not(#addon-bar)[collapsed=true] {
|
||||
|
|
|
@ -170,6 +170,7 @@
|
|||
overflow: -moz-hidden-unscrollable;
|
||||
max-height: 4em;
|
||||
transition: min-height 170ms ease-out, max-height 170ms ease-out;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar):not(#nav-bar):not(#addon-bar)[collapsed=true] {
|
||||
|
|
|
@ -5,6 +5,8 @@ support-files =
|
|||
doc_inspector_add_node.html
|
||||
doc_inspector_breadcrumbs.html
|
||||
doc_inspector_breadcrumbs_visibility.html
|
||||
doc_inspector_csp.html
|
||||
doc_inspector_csp.html^headers^
|
||||
doc_inspector_delete-selected-node-01.html
|
||||
doc_inspector_delete-selected-node-02.html
|
||||
doc_inspector_embed.html
|
||||
|
@ -68,7 +70,9 @@ skip-if = os == "mac" # Full keyboard navigation on OSX only works if Full Keybo
|
|||
[browser_inspector_highlighter-embed.js]
|
||||
[browser_inspector_highlighter-eyedropper-clipboard.js]
|
||||
subsuite = clipboard
|
||||
[browser_inspector_highlighter-eyedropper-csp.js]
|
||||
[browser_inspector_highlighter-eyedropper-events.js]
|
||||
[browser_inspector_highlighter-eyedropper-label.js]
|
||||
[browser_inspector_highlighter-eyedropper-show-hide.js]
|
||||
[browser_inspector_highlighter-geometry_01.js]
|
||||
[browser_inspector_highlighter-geometry_02.js]
|
||||
|
|
|
@ -14,7 +14,8 @@ add_task(function* () {
|
|||
.then(getHighlighterHelperFor(HIGHLIGHTER_TYPE));
|
||||
helper.prefix = ID;
|
||||
|
||||
let {show, finalize} = helper;
|
||||
let {show, finalize,
|
||||
waitForElementAttributeSet, waitForElementAttributeRemoved} = helper;
|
||||
|
||||
info("Show the eyedropper with the copyOnSelect option");
|
||||
yield show("html", {copyOnSelect: true});
|
||||
|
@ -36,29 +37,3 @@ add_task(function* () {
|
|||
finalize();
|
||||
});
|
||||
|
||||
function* waitForElementAttributeSet(id, name, {getElementAttribute}) {
|
||||
yield poll(function* () {
|
||||
let value = yield getElementAttribute(id, name);
|
||||
return !!value;
|
||||
}, `Waiting for element ${id} to have attribute ${name} set`);
|
||||
}
|
||||
|
||||
function* waitForElementAttributeRemoved(id, name, {getElementAttribute}) {
|
||||
yield poll(function* () {
|
||||
let value = yield getElementAttribute(id, name);
|
||||
return !value;
|
||||
}, `Waiting for element ${id} to have attribute ${name} removed`);
|
||||
}
|
||||
|
||||
function* poll(check, desc) {
|
||||
info(desc);
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
if (yield check()) {
|
||||
return;
|
||||
}
|
||||
yield new Promise(resolve => setTimeout(resolve, 200));
|
||||
}
|
||||
|
||||
throw new Error(`Timeout while: ${desc}`);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/* 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";
|
||||
|
||||
// Test that the eyedropper opens correctly even when the page defines CSP headers.
|
||||
|
||||
const HIGHLIGHTER_TYPE = "EyeDropper";
|
||||
const ID = "eye-dropper-";
|
||||
const TEST_URI = URL_ROOT + "doc_inspector_csp.html";
|
||||
|
||||
add_task(function* () {
|
||||
let helper = yield openInspectorForURL(TEST_URI)
|
||||
.then(getHighlighterHelperFor(HIGHLIGHTER_TYPE));
|
||||
helper.prefix = ID;
|
||||
let {show, hide, finalize, isElementHidden, waitForElementAttributeSet} = helper;
|
||||
|
||||
info("Try to display the eyedropper");
|
||||
yield show("html");
|
||||
|
||||
let hidden = yield isElementHidden("root");
|
||||
ok(!hidden, "The eyedropper is now shown");
|
||||
|
||||
info("Wait until the eyedropper is done taking a screenshot of the page");
|
||||
yield waitForElementAttributeSet("root", "drawn", helper);
|
||||
ok(true, "The image data was retrieved successfully from the window");
|
||||
|
||||
yield hide();
|
||||
finalize();
|
||||
});
|
|
@ -0,0 +1,115 @@
|
|||
/* 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";
|
||||
|
||||
// Test the position of the eyedropper label.
|
||||
// It should move around when the eyedropper is close to the edges of the viewport so as
|
||||
// to always stay visible.
|
||||
|
||||
const HIGHLIGHTER_TYPE = "EyeDropper";
|
||||
const ID = "eye-dropper-";
|
||||
|
||||
const HTML = `
|
||||
<style>
|
||||
html, body {height: 100%; margin: 0;}
|
||||
body {background: linear-gradient(red, gold); display: flex; justify-content: center;
|
||||
align-items: center;}
|
||||
</style>
|
||||
Eyedropper label position test
|
||||
`;
|
||||
const TEST_PAGE = "data:text/html;charset=utf-8," + encodeURI(HTML);
|
||||
|
||||
const TEST_DATA = [{
|
||||
desc: "Move the mouse to the center of the screen",
|
||||
getCoordinates: (width, height) => {
|
||||
return {x: width / 2, y: height / 2};
|
||||
},
|
||||
expectedPositions: {top: false, right: false, left: false}
|
||||
}, {
|
||||
desc: "Move the mouse to the center left",
|
||||
getCoordinates: (width, height) => {
|
||||
return {x: 0, y: height / 2};
|
||||
},
|
||||
expectedPositions: {top: false, right: true, left: false}
|
||||
}, {
|
||||
desc: "Move the mouse to the center right",
|
||||
getCoordinates: (width, height) => {
|
||||
return {x: width, y: height / 2};
|
||||
},
|
||||
expectedPositions: {top: false, right: false, left: true}
|
||||
}, {
|
||||
desc: "Move the mouse to the bottom center",
|
||||
getCoordinates: (width, height) => {
|
||||
return {x: width / 2, y: height};
|
||||
},
|
||||
expectedPositions: {top: true, right: false, left: false}
|
||||
}, {
|
||||
desc: "Move the mouse to the bottom left",
|
||||
getCoordinates: (width, height) => {
|
||||
return {x: 0, y: height};
|
||||
},
|
||||
expectedPositions: {top: true, right: true, left: false}
|
||||
}, {
|
||||
desc: "Move the mouse to the bottom right",
|
||||
getCoordinates: (width, height) => {
|
||||
return {x: width, y: height};
|
||||
},
|
||||
expectedPositions: {top: true, right: false, left: true}
|
||||
}, {
|
||||
desc: "Move the mouse to the top left",
|
||||
getCoordinates: (width, height) => {
|
||||
return {x: 0, y: 0};
|
||||
},
|
||||
expectedPositions: {top: false, right: true, left: false}
|
||||
}, {
|
||||
desc: "Move the mouse to the top right",
|
||||
getCoordinates: (width, height) => {
|
||||
return {x: width, y: 0};
|
||||
},
|
||||
expectedPositions: {top: false, right: false, left: true}
|
||||
}];
|
||||
|
||||
add_task(function* () {
|
||||
let {inspector, testActor} = yield openInspectorForURL(TEST_PAGE);
|
||||
let helper = yield getHighlighterHelperFor(HIGHLIGHTER_TYPE)({inspector, testActor});
|
||||
helper.prefix = ID;
|
||||
|
||||
let {mouse, show, hide, finalize} = helper;
|
||||
let {width, height} = yield testActor.getBoundingClientRect("html");
|
||||
|
||||
// This test fails in non-e10s windows if we use width and height. For some reasons, the
|
||||
// mouse events can't be dispatched/handled properly when we try to move the eyedropper
|
||||
// to the far right and/or bottom of the screen. So just removing 10px from each side
|
||||
// fixes it.
|
||||
width -= 10;
|
||||
height -= 10;
|
||||
|
||||
info("Show the eyedropper on the page");
|
||||
yield show("html");
|
||||
|
||||
info("Move the eyedropper around and check that the label appears at the right place");
|
||||
for (let {desc, getCoordinates, expectedPositions} of TEST_DATA) {
|
||||
info(desc);
|
||||
let {x, y} = getCoordinates(width, height);
|
||||
info(`Moving the mouse to ${x} ${y}`);
|
||||
yield mouse.move(x, y);
|
||||
yield checkLabelPositionAttributes(helper, expectedPositions);
|
||||
}
|
||||
|
||||
info("Hide the eyedropper");
|
||||
yield hide();
|
||||
finalize();
|
||||
});
|
||||
|
||||
function* checkLabelPositionAttributes(helper, positions) {
|
||||
for (let position in positions) {
|
||||
is((yield hasAttribute(helper, position)), positions[position],
|
||||
`The label was ${positions[position] ? "" : "not "}moved to the ${position}`);
|
||||
}
|
||||
}
|
||||
|
||||
function* hasAttribute({getElementAttribute}, name) {
|
||||
let value = yield getElementAttribute("root", name);
|
||||
return value !== null;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Inspector CSP Test</title>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
This HTTP response has CSP headers.
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,2 @@
|
|||
Content-Type: text/html; charset=UTF-8
|
||||
content-security-policy: default-src 'self'; connect-src 'self'; script-src 'self'; style-src 'self';
|
|
@ -394,6 +394,28 @@ function* getNodeFrontForSelector(selector, inspector) {
|
|||
return nodes[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple polling helper that executes a given function until it returns true.
|
||||
* @param {Function} check A generator function that is expected to return true at some
|
||||
* stage.
|
||||
* @param {String} desc A text description to be displayed when the polling starts.
|
||||
* @param {Number} attemptes Optional number of times we poll. Defaults to 10.
|
||||
* @param {Number} timeBetweenAttempts Optional time to wait between each attempt.
|
||||
* Defaults to 200ms.
|
||||
*/
|
||||
function* poll(check, desc, attempts = 10, timeBetweenAttempts = 200) {
|
||||
info(desc);
|
||||
|
||||
for (let i = 0; i < attempts; i++) {
|
||||
if (yield check()) {
|
||||
return;
|
||||
}
|
||||
yield new Promise(resolve => setTimeout(resolve, timeBetweenAttempts));
|
||||
}
|
||||
|
||||
throw new Error(`Timeout while: ${desc}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encapsulate some common operations for highlighter's tests, to have
|
||||
* the tests cleaner, without exposing directly `inspector`, `highlighter`, and
|
||||
|
@ -460,6 +482,22 @@ const getHighlighterHelperFor = (type) => Task.async(
|
|||
prefix + id, name, highlighter);
|
||||
},
|
||||
|
||||
waitForElementAttributeSet: function* (id, name) {
|
||||
yield poll(function* () {
|
||||
let value = yield testActor.getHighlighterNodeAttribute(
|
||||
prefix + id, name, highlighter);
|
||||
return !!value;
|
||||
}, `Waiting for element ${id} to have attribute ${name} set`);
|
||||
},
|
||||
|
||||
waitForElementAttributeRemoved: function* (id, name) {
|
||||
yield poll(function* () {
|
||||
let value = yield testActor.getHighlighterNodeAttribute(
|
||||
prefix + id, name, highlighter);
|
||||
return !value;
|
||||
}, `Waiting for element ${id} to have attribute ${name} removed`);
|
||||
},
|
||||
|
||||
synthesizeMouse: function* (options) {
|
||||
options = Object.assign({selector: ":root"}, options);
|
||||
yield testActor.synthesizeMouse(options);
|
||||
|
|
|
@ -258,7 +258,14 @@ severity.error=Error
|
|||
severity.warn=Warning
|
||||
severity.info=Info
|
||||
severity.log=Log
|
||||
severity.debug=Debug
|
||||
|
||||
# LOCALIZATION NOTE (level.error, level.warn, level.info, level.log, level.debug):
|
||||
# tooltip for icons next to console output
|
||||
level.error=Error
|
||||
level.warn=Warning
|
||||
level.info=Info
|
||||
level.log=Log
|
||||
level.debug=Debug
|
||||
|
||||
# LOCALIZATION NOTE (webconsole.find.key)
|
||||
# Key shortcut used to focus the search box on upper right of the console
|
||||
|
|
|
@ -69,19 +69,11 @@ define(function (require, exports, module) {
|
|||
|
||||
delim = (i == delimMax ? "" : ", ");
|
||||
|
||||
if (value === array) {
|
||||
items.push(Reference({
|
||||
key: i,
|
||||
object: value,
|
||||
delim: delim}
|
||||
));
|
||||
} else {
|
||||
items.push(GripArrayItem(Object.assign({}, this.props, {
|
||||
key: i,
|
||||
object: value,
|
||||
delim: delim}
|
||||
)));
|
||||
}
|
||||
items.push(GripArrayItem(Object.assign({}, this.props, {
|
||||
key: i,
|
||||
object: value,
|
||||
delim: delim}
|
||||
)));
|
||||
} catch (exc) {
|
||||
items.push(GripArrayItem(Object.assign({}, this.props, {
|
||||
object: exc,
|
||||
|
@ -178,21 +170,6 @@ define(function (require, exports, module) {
|
|||
}
|
||||
}));
|
||||
|
||||
/**
|
||||
* Renders cycle references in an array.
|
||||
*/
|
||||
let Reference = React.createFactory(React.createClass({
|
||||
displayName: "Reference",
|
||||
|
||||
render: function () {
|
||||
return (
|
||||
span({title: "Circular reference"},
|
||||
"[…]"
|
||||
)
|
||||
);
|
||||
}
|
||||
}));
|
||||
|
||||
function supportsObject(grip, type) {
|
||||
if (!isGrip(grip)) {
|
||||
return false;
|
||||
|
|
|
@ -161,9 +161,6 @@ window.onload = Task.async(function* () {
|
|||
}
|
||||
|
||||
function testRecursiveArray() {
|
||||
// @TODO This is not how this feature should actually work
|
||||
// See Bug 1282465 - Reps: fix or remove recursive handling in grip-array
|
||||
|
||||
// Test array = `let a = []; a = [a]`
|
||||
const testName = "testRecursiveArray";
|
||||
|
||||
|
|
|
@ -543,7 +543,18 @@ var TestActor = exports.TestActor = protocol.ActorClass(testSpec, {
|
|||
*/
|
||||
getBoundingClientRect: function (selector) {
|
||||
let node = this._querySelector(selector);
|
||||
return node.getBoundingClientRect();
|
||||
let rect = node.getBoundingClientRect();
|
||||
// DOMRect can't be stringified directly, so return a simple object instead.
|
||||
return {
|
||||
x: rect.x,
|
||||
y: rect.y,
|
||||
width: rect.width,
|
||||
height: rect.height,
|
||||
top: rect.top,
|
||||
right: rect.right,
|
||||
bottom: rect.bottom,
|
||||
left: rect.left
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -16,15 +16,11 @@
|
|||
--breakpoint-conditional-background: url("chrome://devtools/skin/images/breakpoint.svg#dark-conditional");
|
||||
}
|
||||
|
||||
.errors {
|
||||
.CodeMirror .errors {
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
.hit-counts {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.error {
|
||||
.CodeMirror .error {
|
||||
display: inline-block;
|
||||
margin-left: 5px;
|
||||
width: 12px;
|
||||
|
@ -32,9 +28,15 @@
|
|||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: contain;
|
||||
background-image: url("chrome://devtools/skin/images/editor-error.png");
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
.hit-count {
|
||||
.CodeMirror .hit-counts {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.CodeMirror .hit-count {
|
||||
display: inline-block;
|
||||
height: 12px;
|
||||
border: solid rgba(0,0,0,0.2);
|
||||
|
@ -45,11 +47,6 @@
|
|||
pointer-events: none;
|
||||
}
|
||||
|
||||
.error {
|
||||
background-image: url("chrome://devtools/skin/images/editor-error.png");
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
.CodeMirror-linenumber:before {
|
||||
content: " ";
|
||||
display: block;
|
||||
|
|
|
@ -342,14 +342,14 @@ a {
|
|||
}
|
||||
|
||||
.message[category=console] > .indent,
|
||||
.message.console > .indent {
|
||||
.message.console-api > .indent {
|
||||
border-inline-end: solid #cbcbcb 6px;
|
||||
}
|
||||
|
||||
.message[category=console][severity=error] > .icon::before,
|
||||
.message[category=output][severity=error] > .icon::before,
|
||||
.message[category=server][severity=error] > .icon::before,
|
||||
.message.console.error > .icon::before,
|
||||
.message.console-api.error > .icon::before,
|
||||
.message.output.error > .icon::before,
|
||||
.message.server.error > .icon::before {
|
||||
background-position: -12px -36px;
|
||||
|
@ -357,14 +357,14 @@ a {
|
|||
|
||||
.message[category=console][severity=warn] > .icon::before,
|
||||
.message[category=server][severity=warn] > .icon::before,
|
||||
.message.console.warn > .icon::before,
|
||||
.message.console-api.warn > .icon::before,
|
||||
.message.server.warn > .icon::before {
|
||||
background-position: -24px -36px;
|
||||
}
|
||||
|
||||
.message[category=console][severity=info] > .icon::before,
|
||||
.message[category=server][severity=info] > .icon::before,
|
||||
.message.console.info > .icon::before,
|
||||
.message.console-api.info > .icon::before,
|
||||
.message.server.info > .icon::before {
|
||||
background-position: -36px -36px;
|
||||
}
|
||||
|
@ -560,7 +560,8 @@ a {
|
|||
background-color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.message[open] .stacktrace {
|
||||
.message[open] .stacktrace,
|
||||
.message.open .stacktrace {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,9 @@ const { IdGenerator } = require("devtools/client/webconsole/new-console-output/u
|
|||
|
||||
const {
|
||||
MESSAGE_ADD,
|
||||
MESSAGES_CLEAR
|
||||
MESSAGES_CLEAR,
|
||||
MESSAGE_OPEN,
|
||||
MESSAGE_CLOSE,
|
||||
} = require("../constants");
|
||||
|
||||
const defaultIdGenerator = new IdGenerator();
|
||||
|
@ -36,5 +38,21 @@ function messagesClear() {
|
|||
};
|
||||
}
|
||||
|
||||
function messageOpen(id) {
|
||||
return {
|
||||
type: MESSAGE_OPEN,
|
||||
id
|
||||
};
|
||||
}
|
||||
|
||||
function messageClose(id) {
|
||||
return {
|
||||
type: MESSAGE_CLOSE,
|
||||
id
|
||||
};
|
||||
}
|
||||
|
||||
exports.messageAdd = messageAdd;
|
||||
exports.messagesClear = messagesClear;
|
||||
exports.messageOpen = messageOpen;
|
||||
exports.messageClose = messageClose;
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* 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";
|
||||
|
||||
// React & Redux
|
||||
const {
|
||||
createClass,
|
||||
DOM: dom,
|
||||
PropTypes,
|
||||
} = require("devtools/client/shared/vendor/react");
|
||||
|
||||
const CollapseButton = createClass({
|
||||
|
||||
displayName: "CollapseButton",
|
||||
|
||||
propTypes: {
|
||||
open: PropTypes.bool.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
},
|
||||
|
||||
render: function () {
|
||||
const { title, open, onClick } = this.props;
|
||||
|
||||
let classes = ["theme-twisty"];
|
||||
|
||||
if (open) {
|
||||
classes.push("open");
|
||||
}
|
||||
|
||||
return dom.a({
|
||||
className: classes.join(" "),
|
||||
onClick: onClick,
|
||||
title
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
module.exports.CollapseButton = CollapseButton;
|
|
@ -12,16 +12,16 @@ const {
|
|||
const ReactDOM = require("devtools/client/shared/vendor/react-dom");
|
||||
const { connect } = require("devtools/client/shared/vendor/react-redux");
|
||||
|
||||
const { getAllMessages } = require("devtools/client/webconsole/new-console-output/selectors/messages");
|
||||
const { getAllMessages, getAllMessagesUiById } = require("devtools/client/webconsole/new-console-output/selectors/messages");
|
||||
const MessageContainer = createFactory(require("devtools/client/webconsole/new-console-output/components/message-container").MessageContainer);
|
||||
|
||||
const ConsoleOutput = createClass({
|
||||
|
||||
propTypes: {
|
||||
jsterm: PropTypes.object.isRequired,
|
||||
// This function is created in mergeProps
|
||||
openVariablesView: PropTypes.func.isRequired,
|
||||
messages: PropTypes.array.isRequired
|
||||
messages: PropTypes.object.isRequired,
|
||||
sourceMapService: PropTypes.object,
|
||||
onViewSourceInDebugger: PropTypes.func.isRequired,
|
||||
},
|
||||
|
||||
displayName: "ConsoleOutput",
|
||||
|
@ -41,9 +41,24 @@ const ConsoleOutput = createClass({
|
|||
},
|
||||
|
||||
render() {
|
||||
let messageNodes = this.props.messages.map(function (message) {
|
||||
let {
|
||||
dispatch,
|
||||
messages,
|
||||
messagesUi,
|
||||
sourceMapService,
|
||||
onViewSourceInDebugger
|
||||
} = this.props;
|
||||
|
||||
let messageNodes = messages.map(function (message) {
|
||||
return (
|
||||
MessageContainer({ message, key: message.id })
|
||||
MessageContainer({
|
||||
dispatch,
|
||||
message,
|
||||
key: message.id,
|
||||
sourceMapService,
|
||||
onViewSourceInDebugger,
|
||||
open: messagesUi.includes(message.id)
|
||||
})
|
||||
);
|
||||
});
|
||||
return (
|
||||
|
@ -61,7 +76,8 @@ function isScrolledToBottom(outputNode, scrollNode) {
|
|||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
messages: getAllMessages(state)
|
||||
messages: getAllMessages(state),
|
||||
messagesUi: getAllMessagesUiById(state)
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -97,6 +97,12 @@ const FilterBar = createClass({
|
|||
label: "Info",
|
||||
filterKey: MESSAGE_LEVEL.INFO,
|
||||
dispatch
|
||||
}),
|
||||
FilterButton({
|
||||
active: filter.debug,
|
||||
label: "Debug",
|
||||
filterKey: MESSAGE_LEVEL.DEBUG,
|
||||
dispatch
|
||||
})
|
||||
)
|
||||
);
|
||||
|
@ -121,7 +127,7 @@ const FilterBar = createClass({
|
|||
|
||||
return (
|
||||
dom.div({className: "webconsole-filteringbar-wrapper"},
|
||||
children
|
||||
...children
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -25,7 +25,11 @@ const { Grip } = require("devtools/client/shared/components/reps/grip");
|
|||
GripMessageBody.displayName = "GripMessageBody";
|
||||
|
||||
GripMessageBody.propTypes = {
|
||||
grip: PropTypes.object.isRequired,
|
||||
grip: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.number,
|
||||
PropTypes.object,
|
||||
]).isRequired,
|
||||
};
|
||||
|
||||
function GripMessageBody(props) {
|
||||
|
|
|
@ -30,17 +30,34 @@ const MessageContainer = createClass({
|
|||
displayName: "MessageContainer",
|
||||
|
||||
propTypes: {
|
||||
message: PropTypes.object.isRequired
|
||||
message: PropTypes.object.isRequired,
|
||||
sourceMapService: PropTypes.object,
|
||||
onViewSourceInDebugger: PropTypes.func.isRequired,
|
||||
open: PropTypes.bool.isRequired,
|
||||
},
|
||||
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
return this.props.message.repeat !== nextProps.message.repeat;
|
||||
return this.props.message.repeat !== nextProps.message.repeat
|
||||
|| this.props.open !== nextProps.open;
|
||||
},
|
||||
|
||||
render() {
|
||||
const { message } = this.props;
|
||||
const {
|
||||
dispatch,
|
||||
message,
|
||||
sourceMapService,
|
||||
onViewSourceInDebugger,
|
||||
open
|
||||
} = this.props;
|
||||
|
||||
let MessageComponent = createFactory(getMessageComponent(message));
|
||||
return MessageComponent({ message });
|
||||
return MessageComponent({
|
||||
dispatch,
|
||||
message,
|
||||
sourceMapService,
|
||||
onViewSourceInDebugger,
|
||||
open
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -16,13 +16,13 @@ const {l10n} = require("devtools/client/webconsole/new-console-output/utils/mess
|
|||
MessageIcon.displayName = "MessageIcon";
|
||||
|
||||
MessageIcon.propTypes = {
|
||||
severity: PropTypes.string.isRequired,
|
||||
level: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
function MessageIcon(props) {
|
||||
const { severity } = props;
|
||||
const { level } = props;
|
||||
|
||||
const title = l10n.getStr("severity." + severity);
|
||||
const title = l10n.getStr("level." + level);
|
||||
return dom.div({
|
||||
className: "icon",
|
||||
title
|
||||
|
|
|
@ -12,51 +12,102 @@ const {
|
|||
DOM: dom,
|
||||
PropTypes
|
||||
} = require("devtools/client/shared/vendor/react");
|
||||
const FrameView = createFactory(require("devtools/client/shared/components/frame"));
|
||||
const StackTrace = createFactory(require("devtools/client/shared/components/stack-trace"));
|
||||
const GripMessageBody = createFactory(require("devtools/client/webconsole/new-console-output/components/grip-message-body").GripMessageBody);
|
||||
const MessageRepeat = createFactory(require("devtools/client/webconsole/new-console-output/components/message-repeat").MessageRepeat);
|
||||
const MessageIcon = createFactory(require("devtools/client/webconsole/new-console-output/components/message-icon").MessageIcon);
|
||||
const CollapseButton = createFactory(require("devtools/client/webconsole/new-console-output/components/collapse-button").CollapseButton);
|
||||
const {l10n} = require("devtools/client/webconsole/new-console-output/utils/messages");
|
||||
const actions = require("devtools/client/webconsole/new-console-output/actions/messages");
|
||||
|
||||
ConsoleApiCall.displayName = "ConsoleApiCall";
|
||||
|
||||
ConsoleApiCall.propTypes = {
|
||||
message: PropTypes.object.isRequired,
|
||||
sourceMapService: PropTypes.object,
|
||||
onViewSourceInDebugger: PropTypes.func.isRequired,
|
||||
open: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
function ConsoleApiCall(props) {
|
||||
const { message } = props;
|
||||
const {category, severity} = message;
|
||||
const { dispatch, message, sourceMapService, onViewSourceInDebugger, open } = props;
|
||||
const {source, level, stacktrace, type, frame } = message;
|
||||
|
||||
const messageBody = message.parameters ?
|
||||
message.parameters.map((grip) => GripMessageBody({grip})) :
|
||||
message.messageText;
|
||||
let messageBody;
|
||||
if (type === "trace") {
|
||||
messageBody = dom.span({className: "cm-variable"}, "console.trace()");
|
||||
} else if (message.parameters) {
|
||||
messageBody = message.parameters.map((grip, key) => GripMessageBody({grip, key}));
|
||||
} else {
|
||||
messageBody = message.messageText;
|
||||
}
|
||||
|
||||
const icon = MessageIcon({severity: severity});
|
||||
const icon = MessageIcon({level});
|
||||
const repeat = MessageRepeat({repeat: message.repeat});
|
||||
|
||||
let collapse = "";
|
||||
let attachment = "";
|
||||
if (stacktrace) {
|
||||
attachment = dom.div({className: "stacktrace devtools-monospace"},
|
||||
StackTrace({
|
||||
stacktrace: stacktrace,
|
||||
onViewSourceInDebugger: onViewSourceInDebugger
|
||||
})
|
||||
);
|
||||
|
||||
collapse = CollapseButton({
|
||||
open: open,
|
||||
title: l10n.getStr("messageToggleDetails"),
|
||||
onClick: function () {
|
||||
if (open) {
|
||||
dispatch(actions.messageClose(message.id));
|
||||
} else {
|
||||
dispatch(actions.messageOpen(message.id));
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const classes = ["message", "cm-s-mozilla"];
|
||||
|
||||
if (category) {
|
||||
classes.push(category);
|
||||
if (source) {
|
||||
classes.push(source);
|
||||
}
|
||||
|
||||
if (severity) {
|
||||
classes.push(severity);
|
||||
if (level) {
|
||||
classes.push(level);
|
||||
}
|
||||
|
||||
if (open === true) {
|
||||
classes.push("open");
|
||||
}
|
||||
|
||||
const shouldRenderFrame = frame && frame.source !== "debugger eval code";
|
||||
return dom.div({
|
||||
className: classes.join(" ")
|
||||
},
|
||||
// @TODO add timestamp
|
||||
// @TODO add indent if necessary
|
||||
icon,
|
||||
collapse,
|
||||
dom.span({className: "message-body-wrapper"},
|
||||
dom.span({},
|
||||
dom.span({className: "message-flex-body"},
|
||||
dom.span({className: "message-body devtools-monospace"},
|
||||
messageBody
|
||||
),
|
||||
repeat
|
||||
)
|
||||
repeat,
|
||||
dom.span({ className: "message-location devtools-monospace" },
|
||||
shouldRenderFrame ? FrameView({
|
||||
frame,
|
||||
onClick: onViewSourceInDebugger,
|
||||
showEmptyPathAsHost: true,
|
||||
sourceMapService
|
||||
}) : null
|
||||
)
|
||||
),
|
||||
attachment
|
||||
)
|
||||
)
|
||||
);
|
||||
|
|
|
@ -26,18 +26,18 @@ ConsoleCommand.propTypes = {
|
|||
*/
|
||||
function ConsoleCommand(props) {
|
||||
const { message } = props;
|
||||
const {category, severity} = message;
|
||||
const {source, level} = message;
|
||||
|
||||
const icon = MessageIcon({severity: severity});
|
||||
const icon = MessageIcon({level});
|
||||
|
||||
const classes = ["message"];
|
||||
|
||||
if (category) {
|
||||
classes.push(category);
|
||||
if (source) {
|
||||
classes.push(source);
|
||||
}
|
||||
|
||||
if (severity) {
|
||||
classes.push(severity);
|
||||
if (level) {
|
||||
classes.push(level);
|
||||
}
|
||||
|
||||
return dom.div({
|
||||
|
|
|
@ -23,17 +23,17 @@ EvaluationResult.propTypes = {
|
|||
|
||||
function EvaluationResult(props) {
|
||||
const { message } = props;
|
||||
const {category, severity} = message;
|
||||
const icon = MessageIcon({severity: severity});
|
||||
const {source, level} = message;
|
||||
const icon = MessageIcon({level});
|
||||
|
||||
const classes = ["message", "cm-s-mozilla"];
|
||||
|
||||
if (category) {
|
||||
classes.push(category);
|
||||
if (source) {
|
||||
classes.push(source);
|
||||
}
|
||||
|
||||
if (severity) {
|
||||
classes.push(severity);
|
||||
if (level) {
|
||||
classes.push(level);
|
||||
}
|
||||
|
||||
return dom.div({
|
||||
|
|
|
@ -23,19 +23,19 @@ PageError.propTypes = {
|
|||
|
||||
function PageError(props) {
|
||||
const { message } = props;
|
||||
const {category, severity} = message;
|
||||
const {source, level} = message;
|
||||
|
||||
const repeat = MessageRepeat({repeat: message.repeat});
|
||||
const icon = MessageIcon({severity: severity});
|
||||
const icon = MessageIcon({level});
|
||||
|
||||
const classes = ["message"];
|
||||
|
||||
if (category) {
|
||||
classes.push(category);
|
||||
if (source) {
|
||||
classes.push(source);
|
||||
}
|
||||
|
||||
if (severity) {
|
||||
classes.push(severity);
|
||||
if (level) {
|
||||
classes.push(level);
|
||||
}
|
||||
|
||||
return dom.div({
|
||||
|
|
|
@ -8,6 +8,7 @@ DIRS += [
|
|||
]
|
||||
|
||||
DevToolsModules(
|
||||
'collapse-button.js',
|
||||
'console-output.js',
|
||||
'filter-bar.js',
|
||||
'filter-button.js',
|
||||
|
|
|
@ -8,55 +8,14 @@
|
|||
const actionTypes = {
|
||||
MESSAGE_ADD: "MESSAGE_ADD",
|
||||
MESSAGES_CLEAR: "MESSAGES_CLEAR",
|
||||
MESSAGE_OPEN: "MESSAGE_OPEN",
|
||||
MESSAGE_CLOSE: "MESSAGE_CLOSE",
|
||||
FILTER_TOGGLE: "FILTER_TOGGLE",
|
||||
FILTER_TEXT_SET: "FILTER_TEXT_SET",
|
||||
FILTERS_CLEAR: "FILTERS_CLEAR",
|
||||
FILTER_BAR_TOGGLE: "FILTER_BAR_TOGGLE",
|
||||
};
|
||||
|
||||
const categories = {
|
||||
CATEGORY_NETWORK: "network",
|
||||
CATEGORY_CSS: "cssparser",
|
||||
CATEGORY_JS: "exception",
|
||||
CATEGORY_WEBDEV: "console",
|
||||
CATEGORY_INPUT: "input",
|
||||
CATEGORY_OUTPUT: "output",
|
||||
CATEGORY_SECURITY: "security",
|
||||
CATEGORY_SERVER: "server"
|
||||
};
|
||||
|
||||
const severities = {
|
||||
SEVERITY_ERROR: "error",
|
||||
SEVERITY_WARNING: "warn",
|
||||
SEVERITY_INFO: "info",
|
||||
SEVERITY_LOG: "log"
|
||||
};
|
||||
|
||||
// A mapping from the console API log event levels to the Web Console
|
||||
// severities.
|
||||
const levels = {
|
||||
LEVELS: {
|
||||
error: severities.SEVERITY_ERROR,
|
||||
exception: severities.SEVERITY_ERROR,
|
||||
assert: severities.SEVERITY_ERROR,
|
||||
warn: severities.SEVERITY_WARNING,
|
||||
info: severities.SEVERITY_INFO,
|
||||
log: severities.SEVERITY_LOG,
|
||||
clear: severities.SEVERITY_LOG,
|
||||
trace: severities.SEVERITY_LOG,
|
||||
table: severities.SEVERITY_LOG,
|
||||
debug: severities.SEVERITY_LOG,
|
||||
dir: severities.SEVERITY_LOG,
|
||||
dirxml: severities.SEVERITY_LOG,
|
||||
group: severities.SEVERITY_LOG,
|
||||
groupCollapsed: severities.SEVERITY_LOG,
|
||||
groupEnd: severities.SEVERITY_LOG,
|
||||
time: severities.SEVERITY_LOG,
|
||||
timeEnd: severities.SEVERITY_LOG,
|
||||
count: severities.SEVERITY_LOG
|
||||
}
|
||||
};
|
||||
|
||||
const chromeRDPEnums = {
|
||||
MESSAGE_SOURCE: {
|
||||
XML: "xml",
|
||||
|
@ -96,10 +55,5 @@ const chromeRDPEnums = {
|
|||
}
|
||||
};
|
||||
|
||||
const filterTypes = {
|
||||
FILTER_TOGGLE: "FILTER_TOGGLE"
|
||||
};
|
||||
|
||||
// Combine into a single constants object
|
||||
module.exports = Object.assign({}, actionTypes, categories, severities, levels,
|
||||
chromeRDPEnums, filterTypes);
|
||||
module.exports = Object.assign({}, actionTypes, chromeRDPEnums);
|
||||
|
|
|
@ -18,7 +18,7 @@ const NewConsoleOutputWrapper = BrowserLoader({
|
|||
baseURI: "resource://devtools/client/webconsole/new-console-output/",
|
||||
window: this}).require("./new-console-output-wrapper");
|
||||
|
||||
this.NewConsoleOutput = function (parentNode, jsterm) {
|
||||
this.NewConsoleOutput = function (parentNode, jsterm, toolbox) {
|
||||
console.log("Creating NewConsoleOutput", parentNode, NewConsoleOutputWrapper);
|
||||
return new NewConsoleOutputWrapper(parentNode, jsterm);
|
||||
return new NewConsoleOutputWrapper(parentNode, jsterm, toolbox);
|
||||
};
|
||||
|
|
|
@ -16,8 +16,17 @@ const FilterBar = React.createFactory(require("devtools/client/webconsole/new-co
|
|||
|
||||
const store = configureStore();
|
||||
|
||||
function NewConsoleOutputWrapper(parentNode, jsterm) {
|
||||
let childComponent = ConsoleOutput({ jsterm });
|
||||
function NewConsoleOutputWrapper(parentNode, jsterm, toolbox) {
|
||||
const sourceMapService = toolbox ? toolbox._sourceMapService : null;
|
||||
let childComponent = ConsoleOutput({
|
||||
jsterm,
|
||||
sourceMapService,
|
||||
onViewSourceInDebugger: frame => toolbox.viewSourceInDebugger.call(
|
||||
toolbox,
|
||||
frame.url,
|
||||
frame.line
|
||||
)
|
||||
});
|
||||
let filterBar = FilterBar({});
|
||||
let provider = React.createElement(
|
||||
Provider,
|
||||
|
|
|
@ -9,11 +9,12 @@ const Immutable = require("devtools/client/shared/vendor/immutable");
|
|||
const constants = require("devtools/client/webconsole/new-console-output/constants");
|
||||
|
||||
const FilterState = Immutable.Record({
|
||||
debug: true,
|
||||
error: true,
|
||||
warn: true,
|
||||
info: true,
|
||||
log: true,
|
||||
text: ""
|
||||
text: "",
|
||||
warn: true,
|
||||
});
|
||||
|
||||
function filters(state = new FilterState(), action) {
|
||||
|
|
|
@ -8,26 +8,47 @@
|
|||
const Immutable = require("devtools/client/shared/vendor/immutable");
|
||||
const constants = require("devtools/client/webconsole/new-console-output/constants");
|
||||
|
||||
function messages(state = Immutable.List(), action) {
|
||||
const MessageState = Immutable.Record({
|
||||
messagesById: Immutable.List(),
|
||||
messagesUiById: Immutable.List(),
|
||||
});
|
||||
|
||||
function messages(state = new MessageState(), action) {
|
||||
const messagesById = state.messagesById;
|
||||
const messagesUiById = state.messagesUiById;
|
||||
|
||||
switch (action.type) {
|
||||
case constants.MESSAGE_ADD:
|
||||
let newMessage = action.message;
|
||||
|
||||
if (newMessage.type === "clear") {
|
||||
return Immutable.List([newMessage]);
|
||||
return state.set("messagesById", Immutable.List([newMessage]));
|
||||
}
|
||||
|
||||
if (newMessage.allowRepeating && state.size > 0) {
|
||||
let lastMessage = state.last();
|
||||
if (newMessage.allowRepeating && messagesById.size > 0) {
|
||||
let lastMessage = messagesById.last();
|
||||
if (lastMessage.repeatId === newMessage.repeatId) {
|
||||
return state.pop().push(
|
||||
newMessage.set("repeat", lastMessage.repeat + 1)
|
||||
);
|
||||
return state.withMutations(function (record) {
|
||||
record.set("messagesById", messagesById.pop().push(
|
||||
newMessage.set("repeat", lastMessage.repeat + 1)
|
||||
));
|
||||
});
|
||||
}
|
||||
}
|
||||
return state.push(newMessage);
|
||||
|
||||
return state.withMutations(function (record) {
|
||||
record.set("messagesById", messagesById.push(newMessage));
|
||||
if (newMessage.type === "trace") {
|
||||
record.set("messagesUiById", messagesUiById.push(newMessage.id));
|
||||
}
|
||||
});
|
||||
case constants.MESSAGES_CLEAR:
|
||||
return Immutable.List();
|
||||
return state.set("messagesById", Immutable.List());
|
||||
case constants.MESSAGE_OPEN:
|
||||
return state.set("messagesUiById", messagesUiById.push(action.id));
|
||||
case constants.MESSAGE_CLOSE:
|
||||
let index = state.messagesUiById.indexOf(action.id);
|
||||
return state.deleteIn(["messagesUiById", index]);
|
||||
}
|
||||
|
||||
return state;
|
||||
|
|
|
@ -7,23 +7,33 @@
|
|||
|
||||
const { getAllFilters } = require("devtools/client/webconsole/new-console-output/selectors/filters");
|
||||
const { getLogLimit } = require("devtools/client/webconsole/new-console-output/selectors/prefs");
|
||||
const {
|
||||
MESSAGE_TYPE
|
||||
} = require("devtools/client/webconsole/new-console-output/constants");
|
||||
|
||||
function getAllMessages(state) {
|
||||
let messages = state.messages;
|
||||
let messages = state.messages.messagesById;
|
||||
let logLimit = getLogLimit(state);
|
||||
let filters = getAllFilters(state);
|
||||
|
||||
return prune(
|
||||
search(
|
||||
filterSeverity(messages, filters),
|
||||
filterLevel(messages, filters),
|
||||
filters.text
|
||||
),
|
||||
logLimit
|
||||
);
|
||||
}
|
||||
|
||||
function filterSeverity(messages, filters) {
|
||||
return messages.filter((message) => filters[message.level] === true);
|
||||
function getAllMessagesUiById(state) {
|
||||
return state.messages.messagesUiById;
|
||||
}
|
||||
|
||||
function filterLevel(messages, filters) {
|
||||
return messages.filter((message) => {
|
||||
return filters[message.level] === true
|
||||
|| [MESSAGE_TYPE.COMMAND, MESSAGE_TYPE.RESULT].includes(message.type);
|
||||
});
|
||||
}
|
||||
|
||||
function search(messages, text = "") {
|
||||
|
@ -53,3 +63,4 @@ function prune(messages, logLimit) {
|
|||
}
|
||||
|
||||
exports.getAllMessages = getAllMessages;
|
||||
exports.getAllMessagesUiById = getAllMessagesUiById;
|
||||
|
|
|
@ -7,12 +7,9 @@ const {FilterState} = require("devtools/client/webconsole/new-console-output/red
|
|||
const {PrefState} = require("devtools/client/webconsole/new-console-output/reducers/prefs");
|
||||
const { combineReducers, createStore } = require("devtools/client/shared/vendor/redux");
|
||||
const { reducers } = require("./reducers/index");
|
||||
const Services = require("Services");
|
||||
|
||||
function configureStore(Services) {
|
||||
if (!Services) {
|
||||
Services = require("Services");
|
||||
}
|
||||
|
||||
function configureStore() {
|
||||
const initialState = {
|
||||
prefs: new PrefState({
|
||||
logLimit: Math.max(Services.prefs.getIntPref("devtools.hud.loglimit"), 1),
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"use strict";
|
||||
|
||||
const { getRepeatId } = require("devtools/client/webconsole/new-console-output/utils/messages");
|
||||
const { stubConsoleMessages } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs");
|
||||
const stubConsoleMessages = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index");
|
||||
const { setupActions } = require("devtools/client/webconsole/new-console-output/test/helpers");
|
||||
const constants = require("devtools/client/webconsole/new-console-output/constants");
|
||||
|
||||
|
@ -26,9 +26,9 @@ describe("Message actions:", () => {
|
|||
"foobar",
|
||||
"test"
|
||||
],
|
||||
"columnNumber": 1,
|
||||
"columnNumber": 27,
|
||||
"counter": null,
|
||||
"filename": "file:///test.html",
|
||||
"filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js",
|
||||
"functionName": "",
|
||||
"groupName": "",
|
||||
"level": "log",
|
||||
|
@ -47,12 +47,7 @@ describe("Message actions:", () => {
|
|||
message: stubConsoleMessages.get("console.log('foobar', 'test')")
|
||||
};
|
||||
|
||||
// Some values on the message are generated by prepareMessage. Manually set
|
||||
// these on the expected message to match.
|
||||
expected.message = expected.message.set("repeatId", getRepeatId(expected.message));
|
||||
expected.message = expected.message.set("id", "1");
|
||||
|
||||
expect(action).toEqual(expected);
|
||||
expect(action.message.toJS()).toEqual(expected.message.toJS());
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -2,19 +2,22 @@
|
|||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
const { stubConsoleMessages } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs");
|
||||
const { ConsoleApiCall } = require("devtools/client/webconsole/new-console-output/components/message-types/console-api-call");
|
||||
// Test utils.
|
||||
const expect = require("expect");
|
||||
const { renderComponent } = require("devtools/client/webconsole/new-console-output/test/helpers");
|
||||
|
||||
const {
|
||||
renderComponent
|
||||
} = require("devtools/client/webconsole/new-console-output/test/helpers");
|
||||
// Components under test.
|
||||
const { ConsoleApiCall } = require("devtools/client/webconsole/new-console-output/components/message-types/console-api-call");
|
||||
|
||||
// Test fakes.
|
||||
const stubConsoleMessages = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index");
|
||||
const onViewSourceInDebugger = () => {};
|
||||
|
||||
describe("ConsoleAPICall component:", () => {
|
||||
describe("console.log", () => {
|
||||
it("renders string grips", () => {
|
||||
const message = stubConsoleMessages.get("console.log('foobar', 'test')");
|
||||
const rendered = renderComponent(ConsoleApiCall, {message});
|
||||
const rendered = renderComponent(ConsoleApiCall, {message, onViewSourceInDebugger});
|
||||
|
||||
const messageBody = getMessageBody(rendered);
|
||||
// @TODO should output: foobar test
|
||||
|
@ -27,7 +30,7 @@ describe("ConsoleAPICall component:", () => {
|
|||
const message =
|
||||
stubConsoleMessages.get("console.log('foobar', 'test')")
|
||||
.set("repeat", 107);
|
||||
const rendered = renderComponent(ConsoleApiCall, {message});
|
||||
const rendered = renderComponent(ConsoleApiCall, {message, onViewSourceInDebugger});
|
||||
|
||||
const repeatNode = getRepeatNode(rendered);
|
||||
expect(repeatNode[0].textContent).toBe("107");
|
||||
|
@ -37,7 +40,7 @@ describe("ConsoleAPICall component:", () => {
|
|||
describe("console.count", () => {
|
||||
it("renders", () => {
|
||||
const message = stubConsoleMessages.get("console.count('bar')");
|
||||
const rendered = renderComponent(ConsoleApiCall, {message});
|
||||
const rendered = renderComponent(ConsoleApiCall, {message, onViewSourceInDebugger});
|
||||
|
||||
const messageBody = getMessageBody(rendered);
|
||||
expect(messageBody.textContent).toBe(message.messageText);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
const { stubConsoleMessages } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs");
|
||||
const stubConsoleMessages = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index");
|
||||
const { EvaluationResult } = require("devtools/client/webconsole/new-console-output/components/message-types/evaluation-result");
|
||||
|
||||
const expect = require("expect");
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
// Require helper is necessary to load certain modules.
|
||||
require("devtools/client/webconsole/new-console-output/test/requireHelper")();
|
||||
const expect = require("expect");
|
||||
const sinon = require("sinon");
|
||||
const { render, mount } = require("enzyme");
|
||||
|
||||
const { createFactory } = require("devtools/client/shared/vendor/react");
|
||||
|
@ -19,9 +19,6 @@ const {
|
|||
|
||||
const { setupStore } = require("devtools/client/webconsole/new-console-output/test/helpers");
|
||||
|
||||
const expect = require("expect");
|
||||
const sinon = require("sinon");
|
||||
|
||||
describe("FilterBar component:", () => {
|
||||
it("initial render", () => {
|
||||
const store = setupStore([]);
|
||||
|
@ -65,13 +62,15 @@ describe("FilterBar component:", () => {
|
|||
};
|
||||
const logButton = FilterButton(Object.assign({}, buttonProps,
|
||||
{ label: "Logs", filterKey: MESSAGE_LEVEL.LOG }));
|
||||
const debugButton = FilterButton(Object.assign({}, buttonProps,
|
||||
{ label: "Debug", filterKey: MESSAGE_LEVEL.DEBUG }));
|
||||
const infoButton = FilterButton(Object.assign({}, buttonProps,
|
||||
{ label: "Info", filterKey: MESSAGE_LEVEL.INFO }));
|
||||
const warnButton = FilterButton(Object.assign({}, buttonProps,
|
||||
{ label: "Warnings", filterKey: MESSAGE_LEVEL.WARN }));
|
||||
const errorButton = FilterButton(Object.assign({}, buttonProps,
|
||||
{ label: "Errors", filterKey: MESSAGE_LEVEL.ERROR }));
|
||||
expect(wrapper.contains([errorButton, warnButton, logButton, infoButton])).toBe(true);
|
||||
expect(wrapper.contains([errorButton, warnButton, logButton, infoButton, debugButton])).toBe(true);
|
||||
});
|
||||
|
||||
it("fires MESSAGES_CLEAR action when clear button is clicked", () => {
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
// Require helper is necessary to load certain modules.
|
||||
require("devtools/client/webconsole/new-console-output/test/requireHelper")();
|
||||
const expect = require("expect");
|
||||
const sinon = require("sinon");
|
||||
const { render, shallow } = require("enzyme");
|
||||
|
||||
const { createFactory } = require("devtools/client/shared/vendor/react");
|
||||
|
@ -14,9 +14,6 @@ const {
|
|||
MESSAGE_LEVEL
|
||||
} = require("devtools/client/webconsole/new-console-output/constants");
|
||||
|
||||
const expect = require("expect");
|
||||
const sinon = require("sinon");
|
||||
|
||||
describe("FilterButton component:", () => {
|
||||
const props = {
|
||||
active: true,
|
||||
|
|
|
@ -2,24 +2,27 @@
|
|||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
const { stubConsoleMessages } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs");
|
||||
|
||||
const { MessageContainer } = require("devtools/client/webconsole/new-console-output/components/message-container");
|
||||
const { ConsoleApiCall } = require("devtools/client/webconsole/new-console-output/components/message-types/console-api-call");
|
||||
const { EvaluationResult } = require("devtools/client/webconsole/new-console-output/components/message-types/evaluation-result");
|
||||
const { PageError } = require("devtools/client/webconsole/new-console-output/components/message-types/page-error");
|
||||
|
||||
// Test utils.
|
||||
const expect = require("expect");
|
||||
|
||||
const {
|
||||
renderComponent,
|
||||
shallowRenderComponent
|
||||
} = require("devtools/client/webconsole/new-console-output/test/helpers");
|
||||
|
||||
// Components under test.
|
||||
const { MessageContainer } = require("devtools/client/webconsole/new-console-output/components/message-container");
|
||||
const { ConsoleApiCall } = require("devtools/client/webconsole/new-console-output/components/message-types/console-api-call");
|
||||
const { EvaluationResult } = require("devtools/client/webconsole/new-console-output/components/message-types/evaluation-result");
|
||||
const { PageError } = require("devtools/client/webconsole/new-console-output/components/message-types/page-error");
|
||||
|
||||
// Test fakes.
|
||||
const stubConsoleMessages = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index");
|
||||
const onViewSourceInDebugger = () => {};
|
||||
|
||||
describe("MessageContainer component:", () => {
|
||||
it("pipes data to children as expected", () => {
|
||||
const message = stubConsoleMessages.get("console.log('foobar', 'test')");
|
||||
const rendered = renderComponent(MessageContainer, {message});
|
||||
const rendered = renderComponent(MessageContainer, {message, onViewSourceInDebugger});
|
||||
|
||||
expect(rendered.textContent.includes("foobar")).toBe(true);
|
||||
});
|
||||
|
@ -35,13 +38,17 @@ describe("MessageContainer component:", () => {
|
|||
},
|
||||
{
|
||||
component: PageError,
|
||||
message: stubConsoleMessages.get("ReferenceError")
|
||||
message: stubConsoleMessages.get("ReferenceError: asdf is not defined")
|
||||
}
|
||||
];
|
||||
|
||||
messageTypes.forEach(info => {
|
||||
const rendered = shallowRenderComponent(MessageContainer, {message: info.message});
|
||||
expect(rendered.type).toBe(info.component);
|
||||
const { component, message } = info;
|
||||
const rendered = shallowRenderComponent(MessageContainer, {
|
||||
message,
|
||||
onViewSourceInDebugger,
|
||||
});
|
||||
expect(rendered.type).toBe(component);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"use strict";
|
||||
|
||||
const {
|
||||
SEVERITY_ERROR,
|
||||
MESSAGE_LEVEL,
|
||||
} = require("devtools/client/webconsole/new-console-output/constants");
|
||||
const { MessageIcon } = require("devtools/client/webconsole/new-console-output/components/message-icon");
|
||||
|
||||
|
@ -14,8 +14,8 @@ const {
|
|||
} = require("devtools/client/webconsole/new-console-output/test/helpers");
|
||||
|
||||
describe("MessageIcon component:", () => {
|
||||
it("renders icon based on severity", () => {
|
||||
const rendered = renderComponent(MessageIcon, { severity: SEVERITY_ERROR });
|
||||
it("renders icon based on level", () => {
|
||||
const rendered = renderComponent(MessageIcon, { level: MESSAGE_LEVEL.ERROR });
|
||||
|
||||
expect(rendered.classList.contains("icon")).toBe(true);
|
||||
expect(rendered.getAttribute("title")).toBe("Error");
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
const { stubConsoleMessages } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs");
|
||||
const stubConsoleMessages = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index");
|
||||
|
||||
const { PageError } = require("devtools/client/webconsole/new-console-output/components/message-types/page-error");
|
||||
|
||||
|
@ -14,7 +14,7 @@ const {
|
|||
|
||||
describe("PageError component:", () => {
|
||||
it("renders a page error", () => {
|
||||
const message = stubConsoleMessages.get("ReferenceError");
|
||||
const message = stubConsoleMessages.get("ReferenceError: asdf is not defined");
|
||||
const rendered = renderComponent(PageError, {message});
|
||||
|
||||
const messageBody = getMessageBody(rendered);
|
||||
|
|
|
@ -4,12 +4,14 @@
|
|||
"use strict";
|
||||
|
||||
// @TODO Load the actual strings from webconsole.properties instead.
|
||||
module.exports = {
|
||||
getStr: str => {
|
||||
class L10n {
|
||||
getStr(str) {
|
||||
switch (str) {
|
||||
case "severity.error":
|
||||
case "level.error":
|
||||
return "Error";
|
||||
}
|
||||
return str;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = L10n;
|
10
devtools/client/webconsole/new-console-output/test/fixtures/LocalizationHelper.js
поставляемый
Normal file
10
devtools/client/webconsole/new-console-output/test/fixtures/LocalizationHelper.js
поставляемый
Normal file
|
@ -0,0 +1,10 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const LocalizationHelper = require("devtools/client/webconsole/new-console-output/test/fixtures/L10n");
|
||||
|
||||
module.exports = {
|
||||
LocalizationHelper
|
||||
};
|
14
devtools/client/webconsole/new-console-output/test/fixtures/WebConsoleUtils.js
поставляемый
Normal file
14
devtools/client/webconsole/new-console-output/test/fixtures/WebConsoleUtils.js
поставляемый
Normal file
|
@ -0,0 +1,14 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const L10n = require("devtools/client/webconsole/new-console-output/test/fixtures/L10n");
|
||||
|
||||
const Utils = {
|
||||
L10n
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
Utils
|
||||
};
|
|
@ -3,7 +3,6 @@
|
|||
# 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/.
|
||||
|
||||
DevToolsModules(
|
||||
'l10n.js',
|
||||
'stubs.js',
|
||||
)
|
||||
DIRS += [
|
||||
'stub-generators'
|
||||
]
|
||||
|
|
15
devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/browser.ini
поставляемый
Normal file
15
devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/browser.ini
поставляемый
Normal file
|
@ -0,0 +1,15 @@
|
|||
[DEFAULT]
|
||||
tags = devtools
|
||||
subsuite = devtools
|
||||
support-files =
|
||||
head.js
|
||||
!/devtools/client/framework/test/shared-head.js
|
||||
test-console-api.html
|
||||
test-tempfile.js
|
||||
|
||||
[browser_webconsole_update_stubs_console_api.js]
|
||||
skip-if=true # This is only used to update stubs. It is not an actual test.
|
||||
[browser_webconsole_update_stubs_evaluation_result.js]
|
||||
skip-if=true # This is only used to update stubs. It is not an actual test.
|
||||
[browser_webconsole_update_stubs_page_error.js]
|
||||
skip-if=true # This is only used to update stubs. It is not an actual test.
|
|
@ -0,0 +1,40 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
Cu.import("resource://gre/modules/osfile.jsm");
|
||||
const { consoleApi: snippets } = require("devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/stub-snippets.js");
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html";
|
||||
|
||||
let stubs = [];
|
||||
|
||||
snippets.forEach((code, key) => {
|
||||
add_task(function* () {
|
||||
let tempFilePath = OS.Path.join(`${BASE_PATH}/stub-generators`, "test-tempfile.js");
|
||||
OS.File.writeAtomic(tempFilePath, `function triggerPacket() {${code}}`);
|
||||
|
||||
let toolbox = yield openNewTabAndToolbox(TEST_URI, "webconsole");
|
||||
let hud = toolbox.getCurrentPanel().hud;
|
||||
let {ui} = hud;
|
||||
|
||||
ok(ui.jsterm, "jsterm exists");
|
||||
ok(ui.newConsoleOutput, "newConsoleOutput exists");
|
||||
|
||||
toolbox.target.client.addListener("consoleAPICall", (type, res) => {
|
||||
stubs.push(formatStub(key, res));
|
||||
if (stubs.length == snippets.size) {
|
||||
let filePath = OS.Path.join(`${BASE_PATH}/stubs`, "consoleApi.js");
|
||||
OS.File.writeAtomic(filePath, formatFile(stubs));
|
||||
OS.File.writeAtomic(tempFilePath, "");
|
||||
}
|
||||
});
|
||||
|
||||
yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function() {
|
||||
content.wrappedJSObject.triggerPacket();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,29 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
Cu.import("resource://gre/modules/osfile.jsm");
|
||||
const TEST_URI = "data:text/html;charset=utf-8,stub generation";
|
||||
|
||||
const { evaluationResult: snippets} = require("devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/stub-snippets.js");
|
||||
|
||||
let stubs = [];
|
||||
|
||||
add_task(function* () {
|
||||
let toolbox = yield openNewTabAndToolbox(TEST_URI, "webconsole");
|
||||
ok(true, "make the test not fail");
|
||||
|
||||
for (var [code,key] of snippets) {
|
||||
const packet = yield new Promise(resolve => {
|
||||
toolbox.target.activeConsole.evaluateJS(code, resolve);
|
||||
});
|
||||
stubs.push(formatStub(key, packet));
|
||||
if (stubs.length == snippets.size) {
|
||||
let filePath = OS.Path.join(`${BASE_PATH}/stubs`, "evaluationResult.js");
|
||||
OS.File.writeAtomic(filePath, formatFile(stubs));
|
||||
}
|
||||
}
|
||||
});
|
|
@ -0,0 +1,45 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
Cu.import("resource://gre/modules/osfile.jsm");
|
||||
const TEST_URI = "data:text/html;charset=utf-8,stub generation";
|
||||
|
||||
const { pageError: snippets} = require("devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/stub-snippets.js");
|
||||
|
||||
let stubs = [];
|
||||
|
||||
add_task(function* () {
|
||||
let toolbox = yield openNewTabAndToolbox(TEST_URI, "webconsole");
|
||||
ok(true, "make the test not fail");
|
||||
|
||||
for (var [key,code] of snippets) {
|
||||
let received = new Promise(resolve => {
|
||||
toolbox.target.client.addListener("pageError", function onPacket(e, packet) {
|
||||
toolbox.target.client.removeListener("pageError", onPacket);
|
||||
info("Received page error:" + e + " " + JSON.stringify(packet, null, "\t"));
|
||||
|
||||
let message = prepareMessage(packet, {getNextId: () => 1});
|
||||
stubs.push(formatStub(message.messageText, packet));
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
info("Injecting script: " + code);
|
||||
|
||||
yield ContentTask.spawn(gBrowser.selectedBrowser, code, function(code) {
|
||||
let container = content.document.createElement("script");
|
||||
content.document.body.appendChild(container);
|
||||
container.textContent = code;
|
||||
content.document.body.removeChild(container);
|
||||
});
|
||||
|
||||
yield received;
|
||||
}
|
||||
|
||||
let filePath = OS.Path.join(`${BASE_PATH}/stubs`, "pageError.js");
|
||||
OS.File.writeAtomic(filePath, formatFile(stubs));
|
||||
});
|
47
devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/head.js
поставляемый
Normal file
47
devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/head.js
поставляемый
Normal file
|
@ -0,0 +1,47 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* import-globals-from ../../../../framework/test/shared-head.js */
|
||||
|
||||
"use strict";
|
||||
|
||||
// shared-head.js handles imports, constants, and utility functions
|
||||
// Load the shared-head file first.
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://mochitests/content/browser/devtools/client/framework/test/shared-head.js",
|
||||
this);
|
||||
|
||||
Services.prefs.setBoolPref("devtools.webconsole.new-frontend-enabled", true);
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("devtools.webconsole.new-frontend-enabled");
|
||||
});
|
||||
|
||||
const { prepareMessage } = require("devtools/client/webconsole/new-console-output/utils/messages");
|
||||
|
||||
const BASE_PATH = "../../../../devtools/client/webconsole/new-console-output/test/fixtures";
|
||||
|
||||
function formatStub(key, message) {
|
||||
let prepared = prepareMessage(message, {getNextId: () => "1"});
|
||||
return `
|
||||
stubConsoleMessages.set("${key}", new ConsoleMessage(${JSON.stringify(prepared, null, "\t")}));
|
||||
`;
|
||||
}
|
||||
|
||||
function formatFile(stubs) {
|
||||
return `/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
* THIS FILE IS AUTOGENERATED. DO NOT MODIFY BY HAND. RUN TESTS IN FIXTURES/ TO UPDATE.
|
||||
*/
|
||||
|
||||
const { ConsoleMessage } = require("devtools/client/webconsole/new-console-output/types");
|
||||
|
||||
let stubConsoleMessages = new Map();
|
||||
${stubs.join("")}
|
||||
|
||||
module.exports = stubConsoleMessages`;
|
||||
}
|
8
devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/moz.build
поставляемый
Normal file
8
devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/moz.build
поставляемый
Normal file
|
@ -0,0 +1,8 @@
|
|||
# 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/.
|
||||
|
||||
DevToolsModules(
|
||||
'stub-snippets.js',
|
||||
)
|
58
devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/stub-snippets.js
поставляемый
Normal file
58
devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/stub-snippets.js
поставляемый
Normal file
|
@ -0,0 +1,58 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Console API
|
||||
|
||||
const consoleApiCommands = [
|
||||
"console.log('foobar', 'test')",
|
||||
"console.log(undefined)",
|
||||
"console.warn('danger, will robinson!')",
|
||||
"console.log(NaN)",
|
||||
"console.log(null)",
|
||||
"console.clear()",
|
||||
"console.count('bar')",
|
||||
];
|
||||
|
||||
let consoleApi = new Map(consoleApiCommands.map(cmd => [cmd, cmd]));
|
||||
|
||||
consoleApi.set("console.trace()",
|
||||
`
|
||||
function bar() {
|
||||
console.trace()
|
||||
}
|
||||
function foo() {
|
||||
bar()
|
||||
}
|
||||
|
||||
foo()
|
||||
`);
|
||||
|
||||
consoleApi.set("console.time()",
|
||||
`
|
||||
console.time()
|
||||
console.timeEnd()
|
||||
`);
|
||||
|
||||
// Evaluation Result
|
||||
|
||||
const evaluationResultCommands = [
|
||||
"new Date(0)"
|
||||
];
|
||||
|
||||
let evaluationResult = new Map(evaluationResultCommands.map(cmd => [cmd, cmd]));
|
||||
|
||||
// Page Error
|
||||
|
||||
const pageErrorCommands = [
|
||||
"asdf()",
|
||||
];
|
||||
|
||||
let pageError = new Map(pageErrorCommands.map(cmd => [cmd, cmd]));
|
||||
|
||||
module.exports = {
|
||||
consoleApi,
|
||||
evaluationResult,
|
||||
pageError,
|
||||
};
|
11
devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html
поставляемый
Normal file
11
devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html
поставляемый
Normal file
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Stub generator</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>Stub generator</p>
|
||||
<script src="test-tempfile.js"></script>
|
||||
</body>
|
||||
</html>
|
0
devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js
поставляемый
Normal file
0
devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js
поставляемый
Normal file
|
@ -1,168 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {
|
||||
MESSAGE_SOURCE,
|
||||
MESSAGE_TYPE,
|
||||
MESSAGE_LEVEL,
|
||||
// Legacy
|
||||
CATEGORY_WEBDEV,
|
||||
SEVERITY_LOG,
|
||||
} = require("devtools/client/webconsole/new-console-output/constants");
|
||||
|
||||
const { ConsoleMessage } = require("devtools/client/webconsole/new-console-output/types");
|
||||
|
||||
exports.stubConsoleMessages = new Map([
|
||||
[
|
||||
"console.log('foobar', 'test')",
|
||||
new ConsoleMessage({
|
||||
allowRepeating: true,
|
||||
source: MESSAGE_SOURCE.CONSOLE_API,
|
||||
type: MESSAGE_TYPE.LOG,
|
||||
level: MESSAGE_LEVEL.LOG,
|
||||
messageText: null,
|
||||
parameters: ["foobar", "test"],
|
||||
repeat: 1,
|
||||
repeatId: null,
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
})
|
||||
],
|
||||
[
|
||||
"console.warn('danger, will robinson!')",
|
||||
new ConsoleMessage({
|
||||
allowRepeating: true,
|
||||
source: MESSAGE_SOURCE.CONSOLE_API,
|
||||
type: MESSAGE_TYPE.LOG,
|
||||
level: MESSAGE_LEVEL.WARN,
|
||||
messageText: null,
|
||||
parameters: ["danger, will robinson!"],
|
||||
repeat: 1,
|
||||
repeatId: null,
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
})
|
||||
],
|
||||
[
|
||||
"console.log(undefined)",
|
||||
new ConsoleMessage({
|
||||
allowRepeating: true,
|
||||
source: MESSAGE_SOURCE.CONSOLE_API,
|
||||
type: MESSAGE_TYPE.LOG,
|
||||
level: MESSAGE_LEVEL.LOG,
|
||||
messageText: null,
|
||||
parameters: [
|
||||
{ type: "undefined" }
|
||||
],
|
||||
repeat: 1,
|
||||
repeatId: null,
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
})
|
||||
],
|
||||
[
|
||||
"console.log(NaN)",
|
||||
new ConsoleMessage({
|
||||
allowRepeating: true,
|
||||
source: MESSAGE_SOURCE.CONSOLE_API,
|
||||
type: MESSAGE_TYPE.LOG,
|
||||
level: MESSAGE_LEVEL.LOG,
|
||||
messageText: null,
|
||||
parameters: [
|
||||
{ type: "NaN" }
|
||||
],
|
||||
repeat: 1,
|
||||
repeatId: null,
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
})
|
||||
],
|
||||
[
|
||||
"console.log(null)",
|
||||
new ConsoleMessage({
|
||||
allowRepeating: true,
|
||||
source: MESSAGE_SOURCE.CONSOLE_API,
|
||||
type: MESSAGE_TYPE.LOG,
|
||||
level: MESSAGE_LEVEL.LOG,
|
||||
messageText: null,
|
||||
parameters: [
|
||||
{ type: "null" }
|
||||
],
|
||||
repeat: 1,
|
||||
repeatId: null,
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
})
|
||||
],
|
||||
[
|
||||
"console.clear()",
|
||||
new ConsoleMessage({
|
||||
allowRepeating: true,
|
||||
source: MESSAGE_SOURCE.CONSOLE_API,
|
||||
type: MESSAGE_TYPE.CLEAR,
|
||||
level: MESSAGE_LEVEL.LOG,
|
||||
messageText: null,
|
||||
parameters: ["Console cleared."],
|
||||
repeat: 1,
|
||||
repeatId: null,
|
||||
})
|
||||
],
|
||||
[
|
||||
"console.count('bar')",
|
||||
new ConsoleMessage({
|
||||
allowRepeating: true,
|
||||
source: MESSAGE_SOURCE.CONSOLE_API,
|
||||
type: MESSAGE_TYPE.LOG,
|
||||
level: MESSAGE_LEVEL.DEBUG,
|
||||
messageText: "bar: 1",
|
||||
parameters: null,
|
||||
repeat: 1,
|
||||
repeatId: null,
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
})
|
||||
],
|
||||
[
|
||||
"new Date(0)",
|
||||
new ConsoleMessage({
|
||||
allowRepeating: true,
|
||||
source: MESSAGE_SOURCE.JAVASCRIPT,
|
||||
type: MESSAGE_TYPE.RESULT,
|
||||
level: MESSAGE_LEVEL.LOG,
|
||||
messageText: null,
|
||||
parameters: {
|
||||
"type": "object",
|
||||
"class": "Date",
|
||||
"actor": "server2.conn0.obj115",
|
||||
"extensible": true,
|
||||
"frozen": false,
|
||||
"sealed": false,
|
||||
"ownPropertyLength": 0,
|
||||
"preview": {
|
||||
"timestamp": 0
|
||||
}
|
||||
},
|
||||
repeat: 1,
|
||||
repeatId: null,
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
})
|
||||
],
|
||||
[
|
||||
"ReferenceError",
|
||||
new ConsoleMessage({
|
||||
allowRepeating: true,
|
||||
source: MESSAGE_SOURCE.JAVASCRIPT,
|
||||
type: MESSAGE_TYPE.LOG,
|
||||
level: MESSAGE_LEVEL.ERROR,
|
||||
messageText: "ReferenceError: asdf is not defined",
|
||||
parameters: null,
|
||||
repeat: 1,
|
||||
repeatId: null,
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
})
|
||||
]
|
||||
]);
|
200
devtools/client/webconsole/new-console-output/test/fixtures/stubs/consoleApi.js
поставляемый
Normal file
200
devtools/client/webconsole/new-console-output/test/fixtures/stubs/consoleApi.js
поставляемый
Normal file
|
@ -0,0 +1,200 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
* THIS FILE IS AUTOGENERATED. DO NOT MODIFY BY HAND. RUN TESTS IN FIXTURES/ TO UPDATE.
|
||||
*/
|
||||
|
||||
const { ConsoleMessage } = require("devtools/client/webconsole/new-console-output/types");
|
||||
|
||||
let stubConsoleMessages = new Map();
|
||||
|
||||
stubConsoleMessages.set("console.log('foobar', 'test')", new ConsoleMessage({
|
||||
"id": "1",
|
||||
"allowRepeating": true,
|
||||
"source": "console-api",
|
||||
"type": "log",
|
||||
"level": "log",
|
||||
"messageText": null,
|
||||
"parameters": [
|
||||
"foobar",
|
||||
"test"
|
||||
],
|
||||
"repeat": 1,
|
||||
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"foobar\",\"test\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js\",\"line\":1,\"column\":27}}",
|
||||
"stacktrace": null,
|
||||
"frame": {
|
||||
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js",
|
||||
"line": 1,
|
||||
"column": 27
|
||||
}
|
||||
}));
|
||||
|
||||
stubConsoleMessages.set("console.log(undefined)", new ConsoleMessage({
|
||||
"id": "1",
|
||||
"allowRepeating": true,
|
||||
"source": "console-api",
|
||||
"type": "log",
|
||||
"level": "log",
|
||||
"messageText": null,
|
||||
"parameters": [
|
||||
{
|
||||
"type": "undefined"
|
||||
}
|
||||
],
|
||||
"repeat": 1,
|
||||
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"undefined\"}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js\",\"line\":1,\"column\":27}}",
|
||||
"stacktrace": null,
|
||||
"frame": {
|
||||
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js",
|
||||
"line": 1,
|
||||
"column": 27
|
||||
}
|
||||
}));
|
||||
|
||||
stubConsoleMessages.set("console.warn('danger, will robinson!')", new ConsoleMessage({
|
||||
"id": "1",
|
||||
"allowRepeating": true,
|
||||
"source": "console-api",
|
||||
"type": "warn",
|
||||
"level": "warn",
|
||||
"messageText": null,
|
||||
"parameters": [
|
||||
"danger, will robinson!"
|
||||
],
|
||||
"repeat": 1,
|
||||
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"warn\",\"level\":\"warn\",\"messageText\":null,\"parameters\":[\"danger, will robinson!\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js\",\"line\":1,\"column\":27}}",
|
||||
"stacktrace": null,
|
||||
"frame": {
|
||||
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js",
|
||||
"line": 1,
|
||||
"column": 27
|
||||
}
|
||||
}));
|
||||
|
||||
stubConsoleMessages.set("console.log(NaN)", new ConsoleMessage({
|
||||
"id": "1",
|
||||
"allowRepeating": true,
|
||||
"source": "console-api",
|
||||
"type": "log",
|
||||
"level": "log",
|
||||
"messageText": null,
|
||||
"parameters": [
|
||||
{
|
||||
"type": "NaN"
|
||||
}
|
||||
],
|
||||
"repeat": 1,
|
||||
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"NaN\"}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js\",\"line\":1,\"column\":27}}",
|
||||
"stacktrace": null,
|
||||
"frame": {
|
||||
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js",
|
||||
"line": 1,
|
||||
"column": 27
|
||||
}
|
||||
}));
|
||||
|
||||
stubConsoleMessages.set("console.log(null)", new ConsoleMessage({
|
||||
"id": "1",
|
||||
"allowRepeating": true,
|
||||
"source": "console-api",
|
||||
"type": "log",
|
||||
"level": "log",
|
||||
"messageText": null,
|
||||
"parameters": [
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"repeat": 1,
|
||||
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"null\"}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js\",\"line\":1,\"column\":27}}",
|
||||
"stacktrace": null,
|
||||
"frame": {
|
||||
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js",
|
||||
"line": 1,
|
||||
"column": 27
|
||||
}
|
||||
}));
|
||||
|
||||
stubConsoleMessages.set("console.clear()", new ConsoleMessage({
|
||||
"id": "1",
|
||||
"allowRepeating": true,
|
||||
"source": "console-api",
|
||||
"type": "clear",
|
||||
"level": "log",
|
||||
"messageText": null,
|
||||
"parameters": [
|
||||
"Console was cleared."
|
||||
],
|
||||
"repeat": 1,
|
||||
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"clear\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"Console was cleared.\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js\",\"line\":1,\"column\":27}}",
|
||||
"stacktrace": null,
|
||||
"frame": {
|
||||
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js",
|
||||
"line": 1,
|
||||
"column": 27
|
||||
}
|
||||
}));
|
||||
|
||||
stubConsoleMessages.set("console.count('bar')", new ConsoleMessage({
|
||||
"id": "1",
|
||||
"allowRepeating": true,
|
||||
"source": "console-api",
|
||||
"type": "log",
|
||||
"level": "debug",
|
||||
"messageText": "bar: 1",
|
||||
"parameters": null,
|
||||
"repeat": 1,
|
||||
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"debug\",\"messageText\":\"bar: 1\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js\",\"line\":1,\"column\":27}}",
|
||||
"stacktrace": null,
|
||||
"frame": {
|
||||
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js",
|
||||
"line": 1,
|
||||
"column": 27
|
||||
}
|
||||
}));
|
||||
|
||||
stubConsoleMessages.set("console.trace()", new ConsoleMessage({
|
||||
"id": "1",
|
||||
"allowRepeating": true,
|
||||
"source": "console-api",
|
||||
"type": "trace",
|
||||
"level": "log",
|
||||
"messageText": null,
|
||||
"parameters": [],
|
||||
"repeat": 1,
|
||||
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"trace\",\"level\":\"log\",\"messageText\":null,\"parameters\":[],\"repeatId\":null,\"stacktrace\":[{\"columnNumber\":3,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js\",\"functionName\":\"bar\",\"language\":2,\"lineNumber\":3},{\"columnNumber\":3,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js\",\"functionName\":\"foo\",\"language\":2,\"lineNumber\":6},{\"columnNumber\":1,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js\",\"functionName\":\"triggerPacket\",\"language\":2,\"lineNumber\":9}],\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js\",\"line\":3,\"column\":3}}",
|
||||
"stacktrace": [
|
||||
{
|
||||
"columnNumber": 3,
|
||||
"filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js",
|
||||
"functionName": "bar",
|
||||
"language": 2,
|
||||
"lineNumber": 3
|
||||
},
|
||||
{
|
||||
"columnNumber": 3,
|
||||
"filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js",
|
||||
"functionName": "foo",
|
||||
"language": 2,
|
||||
"lineNumber": 6
|
||||
},
|
||||
{
|
||||
"columnNumber": 1,
|
||||
"filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js",
|
||||
"functionName": "triggerPacket",
|
||||
"language": 2,
|
||||
"lineNumber": 9
|
||||
}
|
||||
],
|
||||
"frame": {
|
||||
"source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js",
|
||||
"line": 3,
|
||||
"column": 3
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
module.exports = stubConsoleMessages
|
40
devtools/client/webconsole/new-console-output/test/fixtures/stubs/evaluationResult.js
поставляемый
Normal file
40
devtools/client/webconsole/new-console-output/test/fixtures/stubs/evaluationResult.js
поставляемый
Normal file
|
@ -0,0 +1,40 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
* THIS FILE IS AUTOGENERATED. DO NOT MODIFY BY HAND. RUN TESTS IN FIXTURES/ TO UPDATE.
|
||||
*/
|
||||
|
||||
const { ConsoleMessage } = require("devtools/client/webconsole/new-console-output/types");
|
||||
|
||||
let stubConsoleMessages = new Map();
|
||||
|
||||
stubConsoleMessages.set("new Date(0)", new ConsoleMessage({
|
||||
"id": "1",
|
||||
"allowRepeating": true,
|
||||
"source": "javascript",
|
||||
"type": "result",
|
||||
"level": "log",
|
||||
"messageText": null,
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"actor": "server1.conn0.child1/obj29",
|
||||
"class": "Date",
|
||||
"extensible": true,
|
||||
"frozen": false,
|
||||
"sealed": false,
|
||||
"ownPropertyLength": 0,
|
||||
"preview": {
|
||||
"timestamp": 0
|
||||
}
|
||||
},
|
||||
"repeat": 1,
|
||||
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"type\":\"result\",\"level\":\"log\",\"messageText\":null,\"parameters\":{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj29\",\"class\":\"Date\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":0,\"preview\":{\"timestamp\":0}},\"repeatId\":null,\"stacktrace\":null,\"frame\":null}",
|
||||
"stacktrace": null,
|
||||
"frame": null
|
||||
}));
|
||||
|
||||
|
||||
module.exports = stubConsoleMessages
|
22
devtools/client/webconsole/new-console-output/test/fixtures/stubs/index.js
поставляемый
Normal file
22
devtools/client/webconsole/new-console-output/test/fixtures/stubs/index.js
поставляемый
Normal file
|
@ -0,0 +1,22 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
let maps = [];
|
||||
|
||||
[
|
||||
"consoleApi",
|
||||
"evaluationResult",
|
||||
"pageError",
|
||||
].forEach((filename) => {
|
||||
maps[filename] = require(`./${filename}`);
|
||||
});
|
||||
|
||||
// Combine all the maps into a single map.
|
||||
module.exports = new Map([
|
||||
...maps.consoleApi,
|
||||
...maps.evaluationResult,
|
||||
...maps.pageError,
|
||||
]);
|
||||
|
29
devtools/client/webconsole/new-console-output/test/fixtures/stubs/pageError.js
поставляемый
Normal file
29
devtools/client/webconsole/new-console-output/test/fixtures/stubs/pageError.js
поставляемый
Normal file
|
@ -0,0 +1,29 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
* THIS FILE IS AUTOGENERATED. DO NOT MODIFY BY HAND. RUN TESTS IN FIXTURES/ TO UPDATE.
|
||||
*/
|
||||
|
||||
const { ConsoleMessage } = require("devtools/client/webconsole/new-console-output/types");
|
||||
|
||||
let stubConsoleMessages = new Map();
|
||||
|
||||
stubConsoleMessages.set("ReferenceError: asdf is not defined", new ConsoleMessage({
|
||||
"id": "1",
|
||||
"allowRepeating": true,
|
||||
"source": "javascript",
|
||||
"type": "log",
|
||||
"level": "error",
|
||||
"messageText": "ReferenceError: asdf is not defined",
|
||||
"parameters": null,
|
||||
"repeat": 1,
|
||||
"repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"type\":\"log\",\"level\":\"error\",\"messageText\":\"ReferenceError: asdf is not defined\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":null}",
|
||||
"stacktrace": null,
|
||||
"frame": null
|
||||
}));
|
||||
|
||||
|
||||
module.exports = stubConsoleMessages
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
require("devtools/client/webconsole/new-console-output/test/requireHelper")();
|
||||
|
||||
let ReactDOM = require("devtools/client/shared/vendor/react-dom");
|
||||
let React = require("devtools/client/shared/vendor/react");
|
||||
var TestUtils = React.addons.TestUtils;
|
||||
|
@ -12,8 +10,7 @@ var TestUtils = React.addons.TestUtils;
|
|||
const actions = require("devtools/client/webconsole/new-console-output/actions/messages");
|
||||
const { configureStore } = require("devtools/client/webconsole/new-console-output/store");
|
||||
const { IdGenerator } = require("devtools/client/webconsole/new-console-output/utils/id-generator");
|
||||
const { stubConsoleMessages } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs");
|
||||
const Services = require("devtools/client/webconsole/new-console-output/test/fixtures/Services");
|
||||
const stubConsoleMessages = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index");
|
||||
|
||||
/**
|
||||
* Prepare actions for use in testing.
|
||||
|
@ -35,8 +32,7 @@ function setupActions() {
|
|||
* Prepare the store for use in testing.
|
||||
*/
|
||||
function setupStore(input) {
|
||||
// Inject the Services stub.
|
||||
const store = configureStore(Services);
|
||||
const store = configureStore();
|
||||
|
||||
// Add the messages from the input commands to the store.
|
||||
input.forEach((cmd) => {
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
[DEFAULT]
|
||||
tags = devtools
|
||||
subsuite = devtools
|
||||
support-files =
|
||||
head.js
|
||||
!/devtools/client/framework/test/shared-head.js
|
||||
test-console.html
|
||||
|
||||
[browser_webconsole_init.js]
|
|
@ -0,0 +1,68 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/new-console-output/test/mochitest/test-console.html";
|
||||
|
||||
add_task(function* () {
|
||||
let toolbox = yield openNewTabAndToolbox(TEST_URI, "webconsole");
|
||||
let hud = toolbox.getCurrentPanel().hud;
|
||||
let {ui} = hud;
|
||||
|
||||
ok(ui.jsterm, "jsterm exists");
|
||||
ok(ui.newConsoleOutput, "newConsoleOutput exists");
|
||||
|
||||
// @TODO: fix proptype errors
|
||||
let receievedMessages = waitForMessages({
|
||||
hud,
|
||||
messages: [{
|
||||
text: '0',
|
||||
}, {
|
||||
text: '1',
|
||||
}, {
|
||||
text: '2',
|
||||
}],
|
||||
});
|
||||
|
||||
yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function() {
|
||||
content.wrappedJSObject.doLogs(3);
|
||||
});
|
||||
|
||||
yield receievedMessages;
|
||||
});
|
||||
|
||||
/**
|
||||
* Wait for messages in the web console output, resolving once they are receieved.
|
||||
*
|
||||
* @param object options
|
||||
* - hud: the webconsole
|
||||
* - messages: Array[Object]. An array of messages to match. Current supported options:
|
||||
* - text: Exact text match in .message-body
|
||||
*/
|
||||
function waitForMessages({ hud, messages }) {
|
||||
return new Promise(resolve => {
|
||||
let numMatched = 0;
|
||||
let receivedLog = hud.ui.on("new-messages", function messagesReceieved(e, newMessage) {
|
||||
for (let message of messages) {
|
||||
if (message.matched) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (newMessage.node.querySelector(".message-body").textContent == message.text) {
|
||||
numMatched++;
|
||||
message.matched = true;
|
||||
info("Matched a message with text: " + message.text + ", still waiting for " + (messages.length - numMatched) + " messages");
|
||||
}
|
||||
|
||||
if (numMatched === messages.length) {
|
||||
hud.ui.off("new-messages", messagesReceieved);
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* import-globals-from ../../../../framework/test/shared-head.js */
|
||||
|
||||
"use strict";
|
||||
|
||||
// shared-head.js handles imports, constants, and utility functions
|
||||
// Load the shared-head file first.
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://mochitests/content/browser/devtools/client/framework/test/shared-head.js",
|
||||
this);
|
||||
|
||||
Services.prefs.setBoolPref("devtools.webconsole.new-frontend-enabled", true);
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("devtools.webconsole.new-frontend-enabled");
|
||||
});
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Simple webconsole test page</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>Simple webconsole test page</p>
|
||||
<script>
|
||||
function doLogs(num) {
|
||||
num = num || 1;
|
||||
for (var i = 0; i < num; i++) {
|
||||
console.log(i);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -3,10 +3,15 @@
|
|||
# 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/.
|
||||
|
||||
BROWSER_CHROME_MANIFESTS += [
|
||||
'fixtures/stub-generators/browser.ini',
|
||||
'mochitest/browser.ini',
|
||||
]
|
||||
|
||||
DIRS += [
|
||||
'fixtures'
|
||||
]
|
||||
|
||||
MOCHITEST_CHROME_MANIFESTS += [
|
||||
'chrome/chrome.ini'
|
||||
'chrome/chrome.ini',
|
||||
]
|
||||
|
|
|
@ -4,23 +4,31 @@
|
|||
|
||||
const requireHacker = require("require-hacker");
|
||||
|
||||
module.exports = () => {
|
||||
try {
|
||||
requireHacker.global_hook("default", path => {
|
||||
switch (path) {
|
||||
case "react-dom/server":
|
||||
return `const React = require('react-dev'); module.exports = React`;
|
||||
case "react-addons-test-utils":
|
||||
return `const React = require('react-dev'); module.exports = React.addons.TestUtils`;
|
||||
case "react":
|
||||
return `const React = require('react-dev'); module.exports = React`;
|
||||
case "devtools/client/shared/vendor/react":
|
||||
return `const React = require('react-dev'); module.exports = React`;
|
||||
case "devtools/client/shared/vendor/react.default":
|
||||
return `const React = require('react-dev'); module.exports = React`;
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
// Do nothing. This means the hook is already registered.
|
||||
requireHacker.global_hook("default", path => {
|
||||
switch (path) {
|
||||
// For Enzyme
|
||||
case "react-dom/server":
|
||||
return `const React = require('react-dev'); module.exports = React`;
|
||||
case "react-addons-test-utils":
|
||||
return `const React = require('react-dev'); module.exports = React.addons.TestUtils`;
|
||||
// Use react-dev. This would be handled by browserLoader in Firefox.
|
||||
case "react":
|
||||
case "devtools/client/shared/vendor/react":
|
||||
return `const React = require('react-dev'); module.exports = React`;
|
||||
// For Rep's use of AMD
|
||||
case "devtools/client/shared/vendor/react.default":
|
||||
return `const React = require('react-dev'); module.exports = React`;
|
||||
}
|
||||
};
|
||||
|
||||
// Some modules depend on Chrome APIs which don't work in mocha. When such a module
|
||||
// is required, replace it with a mock version.
|
||||
switch (path) {
|
||||
case "devtools/client/webconsole/utils":
|
||||
return `module.exports = require("devtools/client/webconsole/new-console-output/test/fixtures/WebConsoleUtils")`;
|
||||
case "devtools/client/shared/l10n":
|
||||
return `module.exports = require("devtools/client/webconsole/new-console-output/test/fixtures/LocalizationHelper")`;
|
||||
case "Services":
|
||||
case "Services.default":
|
||||
return `module.exports = require("devtools/client/webconsole/new-console-output/test/fixtures/Services")`;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -14,27 +14,38 @@ const { setupStore } = require("devtools/client/webconsole/new-console-output/te
|
|||
const { MESSAGE_LEVEL } = require("devtools/client/webconsole/new-console-output/constants");
|
||||
|
||||
describe("Filtering", () => {
|
||||
const numMessages = 5;
|
||||
const numMessages = 7;
|
||||
const store = setupStore([
|
||||
// Console API
|
||||
"console.log('foobar', 'test')",
|
||||
"console.warn('danger, will robinson!')",
|
||||
"console.log(undefined)",
|
||||
"ReferenceError"
|
||||
"console.count('bar')",
|
||||
// Evaluation Result
|
||||
"new Date(0)",
|
||||
// PageError
|
||||
"ReferenceError: asdf is not defined"
|
||||
]);
|
||||
// Add a console command as well
|
||||
// Console Command
|
||||
store.dispatch(messageAdd(new ConsoleCommand({ messageText: `console.warn("x")` })));
|
||||
|
||||
beforeEach(() => {
|
||||
store.dispatch(actions.filtersClear());
|
||||
});
|
||||
|
||||
describe("Severity filter", () => {
|
||||
describe("Level filter", () => {
|
||||
it("filters log messages", () => {
|
||||
store.dispatch(actions.filterToggle(MESSAGE_LEVEL.LOG));
|
||||
|
||||
let messages = getAllMessages(store.getState());
|
||||
// @TODO It currently filters console command. This should be -2, not -3.
|
||||
expect(messages.size).toEqual(numMessages - 3);
|
||||
expect(messages.size).toEqual(numMessages - 2);
|
||||
});
|
||||
|
||||
it("filters debug messages", () => {
|
||||
store.dispatch(actions.filterToggle(MESSAGE_LEVEL.DEBUG));
|
||||
|
||||
let messages = getAllMessages(store.getState());
|
||||
expect(messages.size).toEqual(numMessages - 1);
|
||||
});
|
||||
|
||||
// @TODO add info stub
|
||||
|
@ -61,8 +72,8 @@ describe("Filtering", () => {
|
|||
|
||||
let messages = getAllMessages(store.getState());
|
||||
// @TODO figure out what this should filter
|
||||
// This does not filter out PageErrors or console commands
|
||||
expect(messages.size).toEqual(3);
|
||||
// This does not filter out PageErrors, Evaluation Results or console commands
|
||||
expect(messages.size).toEqual(5);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -81,6 +92,7 @@ describe("Clear filters", () => {
|
|||
store.dispatch(actions.filterTextSet("foobar"));
|
||||
let filters = getAllFilters(store.getState());
|
||||
expect(filters.toJS()).toEqual({
|
||||
"debug": true,
|
||||
"error": false,
|
||||
"info": true,
|
||||
"log": true,
|
||||
|
@ -92,6 +104,7 @@ describe("Clear filters", () => {
|
|||
|
||||
filters = getAllFilters(store.getState());
|
||||
expect(filters.toJS()).toEqual({
|
||||
"debug": true,
|
||||
"error": true,
|
||||
"info": true,
|
||||
"log": true,
|
||||
|
|
|
@ -8,7 +8,7 @@ const {
|
|||
setupActions,
|
||||
setupStore
|
||||
} = require("devtools/client/webconsole/new-console-output/test/helpers");
|
||||
const { stubConsoleMessages } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs");
|
||||
const stubConsoleMessages = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index");
|
||||
|
||||
const expect = require("expect");
|
||||
|
||||
|
@ -78,7 +78,7 @@ describe("Message reducer:", () => {
|
|||
const messages = getAllMessages(getState());
|
||||
|
||||
expect(messages.size).toBe(1);
|
||||
expect(messages.first().parameters[0]).toBe("Console cleared.");
|
||||
expect(messages.first().parameters[0]).toBe("Console was cleared.");
|
||||
});
|
||||
|
||||
it("limits the number of messages displayed", () => {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"use strict";
|
||||
|
||||
const { getRepeatId } = require("devtools/client/webconsole/new-console-output/utils/messages");
|
||||
const { stubConsoleMessages } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs");
|
||||
const stubConsoleMessages = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index");
|
||||
|
||||
const expect = require("expect");
|
||||
|
||||
|
|
|
@ -20,8 +20,6 @@ exports.ConsoleCommand = Immutable.Record({
|
|||
source: MESSAGE_SOURCE.JAVASCRIPT,
|
||||
type: MESSAGE_TYPE.COMMAND,
|
||||
level: MESSAGE_LEVEL.LOG,
|
||||
category: "input",
|
||||
severity: MESSAGE_TYPE.LOG,
|
||||
});
|
||||
|
||||
exports.ConsoleMessage = Immutable.Record({
|
||||
|
@ -34,6 +32,6 @@ exports.ConsoleMessage = Immutable.Record({
|
|||
parameters: null,
|
||||
repeat: 1,
|
||||
repeatId: null,
|
||||
category: "output",
|
||||
severity: "log",
|
||||
stacktrace: null,
|
||||
frame: null,
|
||||
});
|
||||
|
|
|
@ -6,25 +6,14 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
let l10n;
|
||||
try {
|
||||
const WebConsoleUtils = require("devtools/shared/webconsole/utils").Utils;
|
||||
const STRINGS_URI = "chrome://devtools/locale/webconsole.properties";
|
||||
l10n = new WebConsoleUtils.L10n(STRINGS_URI);
|
||||
} catch (e) {
|
||||
l10n = require("devtools/client/webconsole/new-console-output/test/fixtures/l10n");
|
||||
}
|
||||
const WebConsoleUtils = require("devtools/client/webconsole/utils").Utils;
|
||||
const STRINGS_URI = "chrome://devtools/locale/webconsole.properties";
|
||||
const l10n = new WebConsoleUtils.L10n(STRINGS_URI);
|
||||
|
||||
const {
|
||||
MESSAGE_SOURCE,
|
||||
MESSAGE_TYPE,
|
||||
MESSAGE_LEVEL,
|
||||
// Legacy
|
||||
CATEGORY_JS,
|
||||
CATEGORY_OUTPUT,
|
||||
CATEGORY_WEBDEV,
|
||||
LEVELS,
|
||||
SEVERITY_LOG,
|
||||
} = require("../constants");
|
||||
const { ConsoleMessage } = require("../types");
|
||||
|
||||
|
@ -54,7 +43,7 @@ function transformPacket(packet) {
|
|||
|
||||
let parameters = message.arguments;
|
||||
let type = message.level;
|
||||
let level = LEVELS[type] || MESSAGE_TYPE.LOG;
|
||||
let level = getLevelFromType(type);
|
||||
let messageText = null;
|
||||
|
||||
// Special per-type conversion.
|
||||
|
@ -66,7 +55,6 @@ function transformPacket(packet) {
|
|||
case "count":
|
||||
// Chrome RDP doesn't have a special type for count.
|
||||
type = MESSAGE_TYPE.LOG;
|
||||
level = MESSAGE_LEVEL.DEBUG;
|
||||
let {counter} = message;
|
||||
let label = counter.label ? counter.label : l10n.getStr("noCounterLabel");
|
||||
messageText = `${label}: ${counter.count}`;
|
||||
|
@ -74,14 +62,30 @@ function transformPacket(packet) {
|
|||
break;
|
||||
}
|
||||
|
||||
const frame = {
|
||||
source: message.filename || null,
|
||||
line: message.lineNumber || null,
|
||||
column: message.columnNumber || null
|
||||
};
|
||||
|
||||
return new ConsoleMessage({
|
||||
source: MESSAGE_SOURCE.CONSOLE_API,
|
||||
type,
|
||||
level,
|
||||
parameters,
|
||||
messageText,
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: level,
|
||||
stacktrace: message.stacktrace ? message.stacktrace : null,
|
||||
frame
|
||||
});
|
||||
}
|
||||
|
||||
case "navigationMessage": {
|
||||
let { message } = packet;
|
||||
return new ConsoleMessage({
|
||||
source: MESSAGE_SOURCE.CONSOLE_API,
|
||||
type: MESSAGE_TYPE.LOG,
|
||||
level: MESSAGE_LEVEL.LOG,
|
||||
messageText: "Navigated to " + message.url,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -97,9 +101,8 @@ function transformPacket(packet) {
|
|||
return new ConsoleMessage({
|
||||
source: MESSAGE_SOURCE.JAVASCRIPT,
|
||||
type: MESSAGE_TYPE.LOG,
|
||||
level,
|
||||
messageText: pageError.errorMessage,
|
||||
category: CATEGORY_JS,
|
||||
severity: level,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -112,8 +115,6 @@ function transformPacket(packet) {
|
|||
type: MESSAGE_TYPE.RESULT,
|
||||
level: MESSAGE_LEVEL.LOG,
|
||||
parameters: result,
|
||||
category: CATEGORY_OUTPUT,
|
||||
severity: SEVERITY_LOG,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -127,8 +128,8 @@ function getRepeatId(message) {
|
|||
}
|
||||
|
||||
function convertCachedPacket(packet) {
|
||||
// The devtools server provides cached message packets in a different shape
|
||||
// from those of consoleApiCalls, so we prepare them for preparation here.
|
||||
// The devtools server provides cached message packets in a different shape, so we
|
||||
// transform them here.
|
||||
let convertPacket = {};
|
||||
if (packet._type === "ConsoleAPI") {
|
||||
convertPacket.message = packet;
|
||||
|
@ -136,12 +137,52 @@ function convertCachedPacket(packet) {
|
|||
} else if (packet._type === "PageError") {
|
||||
convertPacket.pageError = packet;
|
||||
convertPacket.type = "pageError";
|
||||
} else if ("_navPayload" in packet) {
|
||||
convertPacket.type = "navigationMessage";
|
||||
convertPacket.message = packet;
|
||||
} else {
|
||||
throw new Error("Unexpected packet type");
|
||||
}
|
||||
return convertPacket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps a Firefox RDP type to its corresponding level.
|
||||
*/
|
||||
function getLevelFromType(type) {
|
||||
const levels = {
|
||||
LEVEL_ERROR: "error",
|
||||
LEVEL_WARNING: "warn",
|
||||
LEVEL_INFO: "info",
|
||||
LEVEL_LOG: "log",
|
||||
LEVEL_DEBUG: "debug",
|
||||
};
|
||||
|
||||
// A mapping from the console API log event levels to the Web Console levels.
|
||||
const levelMap = {
|
||||
error: levels.LEVEL_ERROR,
|
||||
exception: levels.LEVEL_ERROR,
|
||||
assert: levels.LEVEL_ERROR,
|
||||
warn: levels.LEVEL_WARNING,
|
||||
info: levels.LEVEL_INFO,
|
||||
log: levels.LEVEL_LOG,
|
||||
clear: levels.LEVEL_LOG,
|
||||
trace: levels.LEVEL_LOG,
|
||||
table: levels.LEVEL_LOG,
|
||||
debug: levels.LEVEL_LOG,
|
||||
dir: levels.LEVEL_LOG,
|
||||
dirxml: levels.LEVEL_LOG,
|
||||
group: levels.LEVEL_LOG,
|
||||
groupCollapsed: levels.LEVEL_LOG,
|
||||
groupEnd: levels.LEVEL_LOG,
|
||||
time: levels.LEVEL_LOG,
|
||||
timeEnd: levels.LEVEL_LOG,
|
||||
count: levels.LEVEL_DEBUG,
|
||||
};
|
||||
|
||||
return levelMap[type] || MESSAGE_TYPE.LOG;
|
||||
}
|
||||
|
||||
exports.prepareMessage = prepareMessage;
|
||||
// Export for use in testing.
|
||||
exports.getRepeatId = getRepeatId;
|
||||
|
|
|
@ -14,6 +14,6 @@
|
|||
"sinon": "^1.17.5"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "NODE_PATH=`pwd`/../../../:`pwd`/../../../devtools/client/shared/vendor/ mocha new-console-output/test/**/*.test.js --compilers js:babel-register -r jsdom-global/register"
|
||||
"test": "NODE_PATH=`pwd`/../../../:`pwd`/../../../devtools/client/shared/vendor/ mocha new-console-output/test/**/*.test.js --compilers js:babel-register -r jsdom-global/register -r ./new-console-output/test/requireHelper.js"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -539,6 +539,8 @@ WebConsoleFrame.prototype = {
|
|||
this.jsterm = new JSTerm(this);
|
||||
this.jsterm.init();
|
||||
|
||||
let toolbox = gDevTools.getToolbox(this.owner.target);
|
||||
|
||||
if (this.NEW_CONSOLE_OUTPUT_ENABLED) {
|
||||
// @TODO Remove this once JSTerm is handled with React/Redux.
|
||||
this.window.jsterm = this.jsterm;
|
||||
|
@ -551,7 +553,7 @@ WebConsoleFrame.prototype = {
|
|||
this.outputNode.parentNode.appendChild(this.experimentalOutputNode);
|
||||
// @TODO Once the toolbox has been converted to React, see if passing
|
||||
// in JSTerm is still necessary.
|
||||
this.newConsoleOutput = new this.window.NewConsoleOutput(this.experimentalOutputNode, this.jsterm);
|
||||
this.newConsoleOutput = new this.window.NewConsoleOutput(this.experimentalOutputNode, this.jsterm, toolbox);
|
||||
console.log("Created newConsoleOutput", this.newConsoleOutput);
|
||||
|
||||
let filterToolbar = doc.querySelector(".hud-console-filter-toolbar");
|
||||
|
@ -563,7 +565,6 @@ WebConsoleFrame.prototype = {
|
|||
this.jsterm.on("sidebar-opened", this.resize);
|
||||
this.jsterm.on("sidebar-closed", this.resize);
|
||||
|
||||
let toolbox = gDevTools.getToolbox(this.owner.target);
|
||||
if (toolbox) {
|
||||
toolbox.on("webconsole-selected", this._onPanelSelected);
|
||||
}
|
||||
|
@ -1929,8 +1930,14 @@ WebConsoleFrame.prototype = {
|
|||
handleTabNavigated: function (event, packet) {
|
||||
if (event == "will-navigate") {
|
||||
if (this.persistLog) {
|
||||
let marker = new Messages.NavigationMarker(packet, Date.now());
|
||||
this.output.addMessage(marker);
|
||||
if (this.NEW_CONSOLE_OUTPUT_ENABLED) {
|
||||
// Add a _type to hit convertCachedPacket.
|
||||
packet._type = true;
|
||||
this.newConsoleOutput.dispatchMessageAdd(packet);
|
||||
} else {
|
||||
let marker = new Messages.NavigationMarker(packet, Date.now());
|
||||
this.output.addMessage(marker);
|
||||
}
|
||||
} else {
|
||||
this.jsterm.clearOutput();
|
||||
}
|
||||
|
@ -3221,6 +3228,21 @@ WebConsoleConnectionProxy.prototype = {
|
|||
this.webConsoleFrame._onUpdateListeners();
|
||||
},
|
||||
|
||||
/**
|
||||
* Dispatch a message add on the new frontend and emit an event for tests.
|
||||
*/
|
||||
dispatchMessageAdd: function(packet) {
|
||||
this.webConsoleFrame.newConsoleOutput.dispatchMessageAdd(packet);
|
||||
|
||||
// Return the last message in the DOM as the message that was just dispatched. This may not
|
||||
// always be true in the case of filtered messages, but it's close enough for our tests.
|
||||
let messageNodes = this.webConsoleFrame.experimentalOutputNode.querySelectorAll(".message");
|
||||
this.webConsoleFrame.emit("new-messages", {
|
||||
response: packet,
|
||||
node: messageNodes[messageNodes.length - 1],
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* The "cachedMessages" response handler.
|
||||
*
|
||||
|
@ -3248,7 +3270,7 @@ WebConsoleConnectionProxy.prototype = {
|
|||
|
||||
if (this.webConsoleFrame.NEW_CONSOLE_OUTPUT_ENABLED) {
|
||||
for (let packet of messages) {
|
||||
this.webConsoleFrame.newConsoleOutput.dispatchMessageAdd(packet);
|
||||
this.dispatchMessageAdd(packet);
|
||||
}
|
||||
} else {
|
||||
this.webConsoleFrame.displayCachedMessages(messages);
|
||||
|
@ -3274,7 +3296,7 @@ WebConsoleConnectionProxy.prototype = {
|
|||
_onPageError: function (type, packet) {
|
||||
if (this.webConsoleFrame && packet.from == this._consoleActor) {
|
||||
if (this.webConsoleFrame.NEW_CONSOLE_OUTPUT_ENABLED) {
|
||||
this.webConsoleFrame.newConsoleOutput.dispatchMessageAdd(packet);
|
||||
this.dispatchMessageAdd(packet);
|
||||
return;
|
||||
}
|
||||
this.webConsoleFrame.handlePageError(packet.pageError);
|
||||
|
@ -3310,7 +3332,7 @@ WebConsoleConnectionProxy.prototype = {
|
|||
_onConsoleAPICall: function (type, packet) {
|
||||
if (this.webConsoleFrame && packet.from == this._consoleActor) {
|
||||
if (this.webConsoleFrame.NEW_CONSOLE_OUTPUT_ENABLED) {
|
||||
this.webConsoleFrame.newConsoleOutput.dispatchMessageAdd(packet);
|
||||
this.dispatchMessageAdd(packet);
|
||||
} else {
|
||||
this.webConsoleFrame.handleConsoleAPICall(packet.message);
|
||||
}
|
||||
|
|
|
@ -411,6 +411,7 @@
|
|||
--magnifier-height: 96px;
|
||||
/* Width accounts for all color formats (hsl being the longest) */
|
||||
--label-width: 160px;
|
||||
--label-height: 23px;
|
||||
--color: #e0e0e0;
|
||||
|
||||
position: absolute;
|
||||
|
@ -446,8 +447,45 @@
|
|||
background-color: var(--color);
|
||||
border-radius: 2px;
|
||||
width: var(--label-width);
|
||||
transform: translateX(calc((var(--magnifier-width) - var(--label-width)) / 2));
|
||||
height: var(--label-height);
|
||||
position: relative;
|
||||
|
||||
--label-horizontal-center:
|
||||
translateX(calc((var(--magnifier-width) - var(--label-width)) / 2));
|
||||
--label-horizontal-left:
|
||||
translateX(calc((-1 * var(--label-width) + var(--magnifier-width) / 2)));
|
||||
--label-horizontal-right:
|
||||
translateX(calc(var(--magnifier-width) / 2));
|
||||
--label-vertical-top:
|
||||
translateY(calc((-1 * var(--magnifier-height)) - var(--label-height)));
|
||||
|
||||
/* By default the color label container sits below the canvas.
|
||||
Here we just center it horizontally */
|
||||
transform: var(--label-horizontal-center);
|
||||
transition: transform .1s ease-in-out;
|
||||
}
|
||||
|
||||
/* If there isn't enough space below the canvas, we move the label container to the top */
|
||||
:-moz-native-anonymous .eye-dropper-root[top] .eye-dropper-color-container {
|
||||
transform: var(--label-horizontal-center) var(--label-vertical-top);
|
||||
}
|
||||
|
||||
/* If there isn't enough space right of the canvas to horizontally center the label
|
||||
container, offset it to the left */
|
||||
:-moz-native-anonymous .eye-dropper-root[left] .eye-dropper-color-container {
|
||||
transform: var(--label-horizontal-left);
|
||||
}
|
||||
:-moz-native-anonymous .eye-dropper-root[left][top] .eye-dropper-color-container {
|
||||
transform: var(--label-horizontal-left) var(--label-vertical-top);
|
||||
}
|
||||
|
||||
/* If there isn't enough space left of the canvas to horizontally center the label
|
||||
container, offset it to the right */
|
||||
:-moz-native-anonymous .eye-dropper-root[right] .eye-dropper-color-container {
|
||||
transform: var(--label-horizontal-right);
|
||||
}
|
||||
:-moz-native-anonymous .eye-dropper-root[right][top] .eye-dropper-color-container {
|
||||
transform: var(--label-horizontal-right) var(--label-vertical-top);
|
||||
}
|
||||
|
||||
:-moz-native-anonymous .eye-dropper-color-preview {
|
||||
|
|
|
@ -181,13 +181,13 @@ EyeDropper.prototype = {
|
|||
},
|
||||
|
||||
prepareImageCapture() {
|
||||
// Get the page as an image.
|
||||
// Get the image data from the content window.
|
||||
let imageData = getWindowAsImageData(this.win);
|
||||
let image = new this.win.Image();
|
||||
image.src = imageData;
|
||||
|
||||
// Wait for screenshot to load
|
||||
image.onload = () => {
|
||||
// We need to transform imageData to something drawWindow will consume. An ImageBitmap
|
||||
// works well. We could have used an Image, but doing so results in errors if the page
|
||||
// defines CSP headers.
|
||||
this.win.createImageBitmap(imageData).then(image => {
|
||||
this.pageImage = image;
|
||||
// We likely haven't drawn anything yet (no mousemove events yet), so start now.
|
||||
this.draw();
|
||||
|
@ -195,7 +195,7 @@ EyeDropper.prototype = {
|
|||
// Set an attribute on the root element to be able to run tests after the first draw
|
||||
// was done.
|
||||
this.getElement("root").setAttribute("drawn", "true");
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -338,7 +338,25 @@ EyeDropper.prototype = {
|
|||
},
|
||||
|
||||
moveTo(x, y) {
|
||||
this.getElement("root").setAttribute("style", `top:${y}px;left:${x}px;`);
|
||||
let root = this.getElement("root");
|
||||
root.setAttribute("style", `top:${y}px;left:${x}px;`);
|
||||
|
||||
// Move the label container to the top if the magnifier is close to the bottom edge.
|
||||
if (y >= this.win.innerHeight - MAGNIFIER_HEIGHT) {
|
||||
root.setAttribute("top", "");
|
||||
} else {
|
||||
root.removeAttribute("top");
|
||||
}
|
||||
|
||||
// Also offset the label container to the right or left if the magnifier is close to
|
||||
// the edge.
|
||||
root.removeAttribute("left");
|
||||
root.removeAttribute("right");
|
||||
if (x <= MAGNIFIER_WIDTH) {
|
||||
root.setAttribute("right", "");
|
||||
} else if (x >= this.win.innerWidth - MAGNIFIER_WIDTH) {
|
||||
root.setAttribute("left", "");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -438,9 +456,9 @@ EyeDropper.prototype = {
|
|||
exports.EyeDropper = EyeDropper;
|
||||
|
||||
/**
|
||||
* Get a content window as image data-url.
|
||||
* Draw the visible portion of the window on a canvas and get the resulting ImageData.
|
||||
* @param {Window} win
|
||||
* @return {String} The data-url
|
||||
* @return {ImageData} The image data for the window.
|
||||
*/
|
||||
function getWindowAsImageData(win) {
|
||||
let canvas = win.document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
|
||||
|
@ -456,7 +474,7 @@ function getWindowAsImageData(win) {
|
|||
ctx.scale(scale, scale);
|
||||
ctx.drawWindow(win, win.scrollX, win.scrollY, width, height, "#fff");
|
||||
|
||||
return canvas.toDataURL();
|
||||
return ctx.getImageData(0, 0, canvas.width, canvas.height);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -136,7 +136,8 @@ exports.getFrameElement = getFrameElement;
|
|||
function getFrameOffsets(boundaryWindow, node) {
|
||||
let xOffset = 0;
|
||||
let yOffset = 0;
|
||||
let frameWin = node.ownerDocument.defaultView;
|
||||
|
||||
let frameWin = getWindowFor(node);
|
||||
let scale = getCurrentZoom(node);
|
||||
|
||||
if (boundaryWindow === null) {
|
||||
|
@ -614,13 +615,7 @@ exports.isShadowAnonymous = isShadowAnonymous;
|
|||
* @return {Number}
|
||||
*/
|
||||
function getCurrentZoom(node) {
|
||||
let win = null;
|
||||
|
||||
if (node instanceof Ci.nsIDOMNode) {
|
||||
win = node.ownerDocument.defaultView;
|
||||
} else if (node instanceof Ci.nsIDOMWindow) {
|
||||
win = node;
|
||||
}
|
||||
let win = getWindowFor(node);
|
||||
|
||||
if (!win) {
|
||||
throw new Error("Unable to get the zoom from the given argument.");
|
||||
|
@ -629,3 +624,23 @@ function getCurrentZoom(node) {
|
|||
return utilsFor(win).fullZoom;
|
||||
}
|
||||
exports.getCurrentZoom = getCurrentZoom;
|
||||
|
||||
/**
|
||||
* Return the default view for a given node, where node can be:
|
||||
* - a DOM node
|
||||
* - the document node
|
||||
* - the window itself
|
||||
* @param {DOMNode|DOMWindow|DOMDocument} node The node to get the window for.
|
||||
* @return {DOMWindow}
|
||||
*/
|
||||
function getWindowFor(node) {
|
||||
if (node instanceof Ci.nsIDOMNode) {
|
||||
if (node.nodeType === node.DOCUMENT_NODE) {
|
||||
return node.defaultView;
|
||||
}
|
||||
return node.ownerDocument.defaultView;
|
||||
} else if (node instanceof Ci.nsIDOMWindow) {
|
||||
return node;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ function run_test() {
|
|||
"Common name is correct.");
|
||||
equal(result.subject.organization, DUMMY_CERT.organization,
|
||||
"Organization is correct.");
|
||||
equal(result.subject.organizationalUnit, DUMMY_CERT.organizationalUnit,
|
||||
equal(result.subject.organizationUnit, DUMMY_CERT.organizationUnit,
|
||||
"Organizational unit is correct.");
|
||||
|
||||
// Issuer
|
||||
|
@ -51,7 +51,7 @@ function run_test() {
|
|||
"Common name of the issuer is correct.");
|
||||
equal(result.issuer.organization, DUMMY_CERT.issuerOrganization,
|
||||
"Organization of the issuer is correct.");
|
||||
equal(result.issuer.organizationalUnit, DUMMY_CERT.issuerOrganizationalUnit,
|
||||
equal(result.issuer.organizationUnit, DUMMY_CERT.issuerOrganizationUnit,
|
||||
"Organizational unit of the issuer is correct.");
|
||||
|
||||
// Validity
|
||||
|
|
Загрузка…
Ссылка в новой задаче