зеркало из https://github.com/mozilla/gecko-dev.git
Merge fx-team to m-c
This commit is contained in:
Коммит
442418699d
|
@ -1210,6 +1210,11 @@ pref("devtools.webconsole.fontSize", 0);
|
|||
// be cleared each time page navigation happens.
|
||||
pref("devtools.webconsole.persistlog", false);
|
||||
|
||||
// Web Console timestamp: |true| if you want the logs and instructions
|
||||
// in the Web Console to display a timestamp, or |false| to not display
|
||||
// any timestamps.
|
||||
pref("devtools.webconsole.timestampMessages", false);
|
||||
|
||||
// The number of lines that are displayed in the web console for the Net,
|
||||
// CSS, JS and Web Developer categories.
|
||||
pref("devtools.hud.loglimit.network", 200);
|
||||
|
|
|
@ -731,10 +731,6 @@ var gPluginHandler = {
|
|||
let principal = contentWindow.document.nodePrincipal;
|
||||
Services.perms.addFromPrincipal(principal, aPluginInfo.permissionString,
|
||||
permission, expireType, expireTime);
|
||||
|
||||
if (aNewState == "block") {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Manually activate the plugins that would have been automatically
|
||||
|
@ -752,19 +748,23 @@ var gPluginHandler = {
|
|||
}
|
||||
if (aPluginInfo.permissionString == pluginHost.getPermissionStringForType(plugin.actualType)) {
|
||||
pluginFound = true;
|
||||
if (gPluginHandler.canActivatePlugin(plugin)) {
|
||||
let overlay = this.getPluginUI(plugin, "main");
|
||||
if (overlay) {
|
||||
overlay.removeEventListener("click", gPluginHandler._overlayClickListener, true);
|
||||
if (aNewState == "block") {
|
||||
plugin.reload(true);
|
||||
} else {
|
||||
if (gPluginHandler.canActivatePlugin(plugin)) {
|
||||
let overlay = this.getPluginUI(plugin, "main");
|
||||
if (overlay) {
|
||||
overlay.removeEventListener("click", gPluginHandler._overlayClickListener, true);
|
||||
}
|
||||
plugin.playPlugin();
|
||||
}
|
||||
plugin.playPlugin();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there are no instances of the plugin on the page any more, what the
|
||||
// user probably needs is for us to allow and then refresh.
|
||||
if (!pluginFound) {
|
||||
if (aNewState != "block" && !pluginFound) {
|
||||
browser.reload();
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1514,6 +1514,7 @@ SocialStatus = {
|
|||
"class": "social-panel-frame",
|
||||
"id": notificationFrameId,
|
||||
"tooltip": "aHTMLTooltip",
|
||||
"context": "contentAreaContextMenu",
|
||||
|
||||
// work around bug 793057 - by making the panel roughly the final size
|
||||
// we are more likely to have the anchor in the correct position.
|
||||
|
|
|
@ -8,52 +8,6 @@ var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Co
|
|||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
// This listens for the next opened tab and checks it is of the right url.
|
||||
// opencallback is called when the new tab is fully loaded
|
||||
// closecallback is called when the tab is closed
|
||||
function TabOpenListener(url, opencallback, closecallback) {
|
||||
this.url = url;
|
||||
this.opencallback = opencallback;
|
||||
this.closecallback = closecallback;
|
||||
|
||||
gBrowser.tabContainer.addEventListener("TabOpen", this, false);
|
||||
}
|
||||
|
||||
TabOpenListener.prototype = {
|
||||
url: null,
|
||||
opencallback: null,
|
||||
closecallback: null,
|
||||
tab: null,
|
||||
browser: null,
|
||||
|
||||
handleEvent: function(event) {
|
||||
if (event.type == "TabOpen") {
|
||||
gBrowser.tabContainer.removeEventListener("TabOpen", this, false);
|
||||
this.tab = event.originalTarget;
|
||||
this.browser = this.tab.linkedBrowser;
|
||||
gBrowser.addEventListener("pageshow", this, false);
|
||||
} else if (event.type == "pageshow") {
|
||||
if (event.target.location.href != this.url)
|
||||
return;
|
||||
gBrowser.removeEventListener("pageshow", this, false);
|
||||
this.tab.addEventListener("TabClose", this, false);
|
||||
var url = this.browser.contentDocument.location.href;
|
||||
is(url, this.url, "Should have opened the correct tab");
|
||||
this.opencallback(this.tab, this.browser.contentWindow);
|
||||
} else if (event.type == "TabClose") {
|
||||
if (event.originalTarget != this.tab)
|
||||
return;
|
||||
this.tab.removeEventListener("TabClose", this, false);
|
||||
this.opencallback = null;
|
||||
this.tab = null;
|
||||
this.browser = null;
|
||||
// Let the window close complete
|
||||
executeSoon(this.closecallback);
|
||||
this.closecallback = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
registerCleanupFunction(function() {
|
||||
|
|
|
@ -9,52 +9,6 @@ var gRunNextTestAfterPluginRemoved = false;
|
|||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
// This listens for the next opened tab and checks it is of the right url.
|
||||
// opencallback is called when the new tab is fully loaded
|
||||
// closecallback is called when the tab is closed
|
||||
function TabOpenListener(url, opencallback, closecallback) {
|
||||
this.url = url;
|
||||
this.opencallback = opencallback;
|
||||
this.closecallback = closecallback;
|
||||
|
||||
gBrowser.tabContainer.addEventListener("TabOpen", this, false);
|
||||
}
|
||||
|
||||
TabOpenListener.prototype = {
|
||||
url: null,
|
||||
opencallback: null,
|
||||
closecallback: null,
|
||||
tab: null,
|
||||
browser: null,
|
||||
|
||||
handleEvent: function(event) {
|
||||
if (event.type == "TabOpen") {
|
||||
gBrowser.tabContainer.removeEventListener("TabOpen", this, false);
|
||||
this.tab = event.originalTarget;
|
||||
this.browser = this.tab.linkedBrowser;
|
||||
gBrowser.addEventListener("pageshow", this, false);
|
||||
} else if (event.type == "pageshow") {
|
||||
if (event.target.location.href != this.url)
|
||||
return;
|
||||
gBrowser.removeEventListener("pageshow", this, false);
|
||||
this.tab.addEventListener("TabClose", this, false);
|
||||
var url = this.browser.contentDocument.location.href;
|
||||
is(url, this.url, "Should have opened the correct tab");
|
||||
this.opencallback(this.tab, this.browser.contentWindow);
|
||||
} else if (event.type == "TabClose") {
|
||||
if (event.originalTarget != this.tab)
|
||||
return;
|
||||
this.tab.removeEventListener("TabClose", this, false);
|
||||
this.opencallback = null;
|
||||
this.tab = null;
|
||||
this.browser = null;
|
||||
// Let the window close complete
|
||||
executeSoon(this.closecallback);
|
||||
this.closecallback = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
registerCleanupFunction(function() {
|
||||
|
|
|
@ -8,52 +8,6 @@ var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Co
|
|||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
// This listens for the next opened tab and checks it is of the right url.
|
||||
// opencallback is called when the new tab is fully loaded
|
||||
// closecallback is called when the tab is closed
|
||||
function TabOpenListener(url, opencallback, closecallback) {
|
||||
this.url = url;
|
||||
this.opencallback = opencallback;
|
||||
this.closecallback = closecallback;
|
||||
|
||||
gBrowser.tabContainer.addEventListener("TabOpen", this, false);
|
||||
}
|
||||
|
||||
TabOpenListener.prototype = {
|
||||
url: null,
|
||||
opencallback: null,
|
||||
closecallback: null,
|
||||
tab: null,
|
||||
browser: null,
|
||||
|
||||
handleEvent: function(event) {
|
||||
if (event.type == "TabOpen") {
|
||||
gBrowser.tabContainer.removeEventListener("TabOpen", this, false);
|
||||
this.tab = event.originalTarget;
|
||||
this.browser = this.tab.linkedBrowser;
|
||||
gBrowser.addEventListener("pageshow", this, false);
|
||||
} else if (event.type == "pageshow") {
|
||||
if (event.target.location.href != this.url)
|
||||
return;
|
||||
gBrowser.removeEventListener("pageshow", this, false);
|
||||
this.tab.addEventListener("TabClose", this, false);
|
||||
var url = this.browser.contentDocument.location.href;
|
||||
is(url, this.url, "Should have opened the correct tab");
|
||||
this.opencallback(this.tab, this.browser.contentWindow);
|
||||
} else if (event.type == "TabClose") {
|
||||
if (event.originalTarget != this.tab)
|
||||
return;
|
||||
this.tab.removeEventListener("TabClose", this, false);
|
||||
this.opencallback = null;
|
||||
this.tab = null;
|
||||
this.browser = null;
|
||||
// Let the window close complete
|
||||
executeSoon(this.closecallback);
|
||||
this.closecallback = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
registerCleanupFunction(function() {
|
||||
|
|
|
@ -54,6 +54,10 @@
|
|||
<checkbox label="&options.enablePersistentLogging.label;"
|
||||
tooltiptext="&options.enablePersistentLogging.tooltip;"
|
||||
data-pref="devtools.webconsole.persistlog"/>
|
||||
<checkbox id="webconsole-timestamp-messages"
|
||||
label="&options.timestampMessages.label;"
|
||||
tooltiptext="&options.timestampMessages.tooltip;"
|
||||
data-pref="devtools.webconsole.timestampMessages"/>
|
||||
</vbox>
|
||||
<label value="&options.profiler.label;"/>
|
||||
<vbox id="profiler-options" class="options-groupbox">
|
||||
|
|
|
@ -239,3 +239,4 @@ skip-if = os == "linux"
|
|||
[browser_webconsole_view_source.js]
|
||||
[browser_webconsole_reflow.js]
|
||||
[browser_webconsole_log_file_filter.js]
|
||||
[browser_webconsole_expandable_timestamps.js]
|
||||
|
|
|
@ -22,6 +22,13 @@ function testFilterButtons(aHud) {
|
|||
testMenuFilterButton("css");
|
||||
testMenuFilterButton("js");
|
||||
testMenuFilterButton("logging");
|
||||
testMenuFilterButton("security");
|
||||
|
||||
testIsolateFilterButton("net");
|
||||
testIsolateFilterButton("css");
|
||||
testIsolateFilterButton("js");
|
||||
testIsolateFilterButton("logging");
|
||||
testIsolateFilterButton("security");
|
||||
|
||||
finishTest();
|
||||
}
|
||||
|
@ -72,15 +79,7 @@ function testMenuFilterButton(aCategory) {
|
|||
"checked after turning off its first menu item");
|
||||
|
||||
// Turn all the filters off by clicking the main part of the button.
|
||||
let anonymousNodes = hud.ui.document.getAnonymousNodes(button);
|
||||
let subbutton;
|
||||
for (let i = 0; i < anonymousNodes.length; i++) {
|
||||
let node = anonymousNodes[i];
|
||||
if (node.classList.contains("toolbarbutton-menubutton-button")) {
|
||||
subbutton = node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
let subbutton = getMainButton(button);
|
||||
ok(subbutton, "we have the subbutton for category " + aCategory);
|
||||
|
||||
clickButton(subbutton);
|
||||
|
@ -129,10 +128,81 @@ function testMenuFilterButton(aCategory) {
|
|||
clickButton(subbutton);
|
||||
}
|
||||
|
||||
function testIsolateFilterButton(aCategory) {
|
||||
let selector = ".webconsole-filter-button[category=\"" + aCategory + "\"]";
|
||||
let targetButton = hudBox.querySelector(selector);
|
||||
ok(targetButton, "we have the \"" + aCategory + "\" button");
|
||||
|
||||
// Get the main part of the filter button.
|
||||
let subbutton = getMainButton(targetButton);
|
||||
ok(subbutton, "we have the subbutton for category " + aCategory);
|
||||
|
||||
// Turn on all the filters by alt clicking the main part of the button.
|
||||
altClickButton(subbutton);
|
||||
ok(isChecked(targetButton), "the button for category " + aCategory +
|
||||
" is checked after isolating for filter");
|
||||
|
||||
// Check if all the filters for the target button are on.
|
||||
let menuItems = targetButton.querySelectorAll("menuitem");
|
||||
Array.forEach(menuItems, (item) => {
|
||||
let prefKey = item.getAttribute("prefKey");
|
||||
ok(isChecked(item), "menu item " + prefKey + " for category " +
|
||||
aCategory + " is checked after isolating for " + aCategory);
|
||||
ok(hud.ui.filterPrefs[prefKey], prefKey + " messages are " +
|
||||
"turned on after isolating for " + aCategory);
|
||||
});
|
||||
|
||||
// Ensure all other filter buttons are toggled off and their
|
||||
// associated filters are turned off
|
||||
let buttons = hudBox.querySelectorAll(".webconsole-filter-button[category]");
|
||||
Array.forEach(buttons, (filterButton) => {
|
||||
if (filterButton !== targetButton) {
|
||||
let category = filterButton.getAttribute("category");
|
||||
ok(!isChecked(filterButton), "the button for category " +
|
||||
category + " is unchecked after isolating for " + aCategory);
|
||||
|
||||
menuItems = filterButton.querySelectorAll("menuitem");
|
||||
Array.forEach(menuItems, (item) => {
|
||||
let prefKey = item.getAttribute("prefKey");
|
||||
ok(!isChecked(item), "menu item " + prefKey + " for category " +
|
||||
aCategory + " is unchecked after isolating for " + aCategory);
|
||||
ok(!hud.ui.filterPrefs[prefKey], prefKey + " messages are " +
|
||||
"turned off after isolating for " + aCategory);
|
||||
});
|
||||
|
||||
// Turn all the filters on again by clicking the button.
|
||||
let mainButton = getMainButton(filterButton);
|
||||
clickButton(mainButton);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the main part of the target filter button.
|
||||
*/
|
||||
function getMainButton(aTargetButton) {
|
||||
let anonymousNodes = hud.ui.document.getAnonymousNodes(aTargetButton);
|
||||
let subbutton;
|
||||
|
||||
for (let i = 0; i < anonymousNodes.length; i++) {
|
||||
let node = anonymousNodes[i];
|
||||
if (node.classList.contains("toolbarbutton-menubutton-button")) {
|
||||
subbutton = node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return subbutton;
|
||||
}
|
||||
|
||||
function clickButton(aNode) {
|
||||
EventUtils.sendMouseEvent({ type: "click" }, aNode);
|
||||
}
|
||||
|
||||
function altClickButton(aNode) {
|
||||
EventUtils.sendMouseEvent({ type: "click", altKey: true }, aNode);
|
||||
}
|
||||
|
||||
function chooseMenuItem(aNode) {
|
||||
let event = document.createEvent("XULCommandEvent");
|
||||
event.initCommandEvent("command", true, true, window, 0, false, false, false,
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test for the message timestamps option: check if the preference toggles the
|
||||
// display of messages in the console output. See bug 722267.
|
||||
|
||||
function test()
|
||||
{
|
||||
const PREF_MESSAGE_TIMESTAMP = "devtools.webconsole.timestampMessages";
|
||||
let hud;
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref(PREF_MESSAGE_TIMESTAMP);
|
||||
});
|
||||
|
||||
addTab("data:text/html;charset=utf-8,Web Console test for bug 722267 - " +
|
||||
"preference for toggling timestamps in messages");
|
||||
|
||||
browser.addEventListener("load", function tabLoad() {
|
||||
browser.removeEventListener("load", tabLoad, true);
|
||||
openConsole(null, consoleOpened);
|
||||
}, true);
|
||||
|
||||
function consoleOpened(aHud)
|
||||
{
|
||||
hud = aHud;
|
||||
|
||||
info("console opened");
|
||||
let prefValue = Services.prefs.getBoolPref(PREF_MESSAGE_TIMESTAMP);
|
||||
ok(!prefValue, "messages have no timestamp by default (pref check)");
|
||||
ok(hud.outputNode.classList.contains("hideTimestamps"),
|
||||
"messages have no timestamp (class name check)");
|
||||
|
||||
let toolbox = gDevTools.getToolbox(hud.target);
|
||||
toolbox.selectTool("options").then(onOptionsPanelSelected);
|
||||
}
|
||||
|
||||
function onOptionsPanelSelected(panel)
|
||||
{
|
||||
info("options panel opened");
|
||||
|
||||
gDevTools.once("pref-changed", onPrefChanged);
|
||||
|
||||
let checkbox = panel.panelDoc.getElementById("webconsole-timestamp-messages");
|
||||
checkbox.click();
|
||||
}
|
||||
|
||||
function onPrefChanged()
|
||||
{
|
||||
info("pref changed");
|
||||
let prefValue = Services.prefs.getBoolPref(PREF_MESSAGE_TIMESTAMP);
|
||||
ok(prefValue, "messages have timestamps (pref check)");
|
||||
ok(!hud.outputNode.classList.contains("hideTimestamps"),
|
||||
"messages have timestamps (class name check)");
|
||||
finishTest();
|
||||
}
|
||||
}
|
|
@ -171,6 +171,7 @@ const MAX_LONG_STRING_LENGTH = 200000;
|
|||
|
||||
const PREF_CONNECTION_TIMEOUT = "devtools.debugger.remote-timeout";
|
||||
const PREF_PERSISTLOG = "devtools.webconsole.persistlog";
|
||||
const PREF_MESSAGE_TIMESTAMP = "devtools.webconsole.timestampMessages";
|
||||
|
||||
/**
|
||||
* A WebConsoleFrame instance is an interactive console initialized *per target*
|
||||
|
@ -201,6 +202,7 @@ function WebConsoleFrame(aWebConsoleOwner)
|
|||
this._toggleFilter = this._toggleFilter.bind(this);
|
||||
this._onPanelSelected = this._onPanelSelected.bind(this);
|
||||
this._flushMessageQueue = this._flushMessageQueue.bind(this);
|
||||
this._onToolboxPrefChanged = this._onToolboxPrefChanged.bind(this);
|
||||
|
||||
this._outputTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
this._outputTimerInitialized = false;
|
||||
|
@ -571,6 +573,13 @@ WebConsoleFrame.prototype = {
|
|||
if (toolbox) {
|
||||
toolbox.on("webconsole-selected", this._onPanelSelected);
|
||||
}
|
||||
|
||||
// Toggle the timestamp on preference change
|
||||
gDevTools.on("pref-changed", this._onToolboxPrefChanged);
|
||||
this._onToolboxPrefChanged("pref-changed", {
|
||||
pref: PREF_MESSAGE_TIMESTAMP,
|
||||
newValue: Services.prefs.getBoolPref(PREF_MESSAGE_TIMESTAMP),
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -801,18 +810,26 @@ WebConsoleFrame.prototype = {
|
|||
break;
|
||||
}
|
||||
|
||||
// Toggle on the targeted filter button, and if the user alt clicked,
|
||||
// toggle off all other filter buttons and their associated filters.
|
||||
let state = target.getAttribute("checked") !== "true";
|
||||
if (aEvent.getModifierState("Alt")) {
|
||||
let buttons = this.document
|
||||
.querySelectorAll(".webconsole-filter-button");
|
||||
Array.forEach(buttons, (button) => {
|
||||
if (button !== target) {
|
||||
button.setAttribute("checked", false);
|
||||
this._setMenuState(button, false);
|
||||
}
|
||||
});
|
||||
state = true;
|
||||
}
|
||||
target.setAttribute("checked", state);
|
||||
|
||||
// This is a filter button with a drop-down, and the user clicked the
|
||||
// main part of the button. Go through all the severities and toggle
|
||||
// their associated filters.
|
||||
let menuItems = target.querySelectorAll("menuitem");
|
||||
for (let i = 0; i < menuItems.length; i++) {
|
||||
menuItems[i].setAttribute("checked", state);
|
||||
let prefKey = menuItems[i].getAttribute("prefKey");
|
||||
this.setFilterState(prefKey, state);
|
||||
}
|
||||
this._setMenuState(target, state);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -851,6 +868,25 @@ WebConsoleFrame.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the menu attributes for a specific toggle button.
|
||||
*
|
||||
* @private
|
||||
* @param XULElement aTarget
|
||||
* Button with drop down items to be toggled.
|
||||
* @param boolean aState
|
||||
* True if the menu item is being toggled on, and false otherwise.
|
||||
*/
|
||||
_setMenuState: function WCF__setMenuState(aTarget, aState)
|
||||
{
|
||||
let menuItems = aTarget.querySelectorAll("menuitem");
|
||||
Array.forEach(menuItems, (item) => {
|
||||
item.setAttribute("checked", aState);
|
||||
let prefKey = item.getAttribute("prefKey");
|
||||
this.setFilterState(prefKey, aState);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the filter state for a specific toggle button.
|
||||
*
|
||||
|
@ -2775,6 +2811,29 @@ WebConsoleFrame.prototype = {
|
|||
}, false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handler for the pref-changed event coming from the toolbox.
|
||||
* Currently this function only handles the timestamps preferences.
|
||||
*
|
||||
* @private
|
||||
* @param object aEvent
|
||||
* This parameter is a string that holds the event name
|
||||
* pref-changed in this case.
|
||||
* @param object aData
|
||||
* This is the pref-changed data object.
|
||||
*/
|
||||
_onToolboxPrefChanged: function WCF__onToolboxPrefChanged(aEvent, aData)
|
||||
{
|
||||
if (aData.pref == PREF_MESSAGE_TIMESTAMP) {
|
||||
if (aData.newValue) {
|
||||
this.outputNode.classList.remove("hideTimestamps");
|
||||
}
|
||||
else {
|
||||
this.outputNode.classList.add("hideTimestamps");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Copies the selected items to the system clipboard.
|
||||
*
|
||||
|
@ -2885,6 +2944,8 @@ WebConsoleFrame.prototype = {
|
|||
toolbox.off("webconsole-selected", this._onPanelSelected);
|
||||
}
|
||||
|
||||
gDevTools.off("pref-changed", this._onToolboxPrefChanged);
|
||||
|
||||
this._repeatNodes = {};
|
||||
this._outputQueue = [];
|
||||
this._pruneCategoriesQueue = {};
|
||||
|
|
|
@ -48,8 +48,8 @@ function goUpdateConsoleCommands() {
|
|||
<command id="cmd_close" oncommand="goDoCommand('cmd_close');" disabled="true"/>
|
||||
</commandset>
|
||||
<keyset id="consoleKeys">
|
||||
<key id="key_fullZoomReduce" key="&fullZoomReduceCmd.commandkey;" command="cmd_fullZoomReduce" modifiers="accel"/>
|
||||
<key key="&fullZoomReduceCmd.commandkey2;" command="cmd_fullZoomReduce" modifiers="accel"/>
|
||||
<key id="key_fullZoomReduce" key="&fullZoomReduceCmd.commandkey;" command="cmd_fullZoomReduce" modifiers="accel"/>
|
||||
<key key="&fullZoomReduceCmd.commandkey2;" command="cmd_fullZoomReduce" modifiers="accel"/>
|
||||
<key id="key_fullZoomEnlarge" key="&fullZoomEnlargeCmd.commandkey;" command="cmd_fullZoomEnlarge" modifiers="accel"/>
|
||||
<key key="&fullZoomEnlargeCmd.commandkey2;" command="cmd_fullZoomEnlarge" modifiers="accel"/>
|
||||
<key key="&fullZoomEnlargeCmd.commandkey3;" command="cmd_fullZoomEnlarge" modifiers="accel"/>
|
||||
|
|
|
@ -109,6 +109,11 @@
|
|||
<!ENTITY options.enablePersistentLogging.label "Enable persistent logs">
|
||||
<!ENTITY options.enablePersistentLogging.tooltip "If you enable this option the Web Console will not clear the output each time you navigate to a new page">
|
||||
|
||||
<!-- LOCALIZATION NOTE (options.timestampMessages.label): This is the
|
||||
- label for the checkbox that toggles timestamps in the Web Console -->
|
||||
<!ENTITY options.timestampMessages.label "Enable timestamps">
|
||||
<!ENTITY options.timestampMessages.tooltip "If you enable this option commands and output in the Web Console will display a timestamp">
|
||||
|
||||
<!-- LOCALIZATION NOTE (options.profiler.label): This is the label for the
|
||||
- heading of the group of JavaScript Profiler preferences in the options
|
||||
- panel. -->
|
||||
|
|
|
@ -1020,9 +1020,6 @@ Browser.MainDragger.prototype = {
|
|||
};
|
||||
|
||||
|
||||
|
||||
const OPEN_APPTAB = 100; // Hack until we get a real API
|
||||
|
||||
function nsBrowserAccess() { }
|
||||
|
||||
nsBrowserAccess.prototype = {
|
||||
|
@ -1032,56 +1029,59 @@ nsBrowserAccess.prototype = {
|
|||
throw Cr.NS_NOINTERFACE;
|
||||
},
|
||||
|
||||
_getOpenAction: function _getOpenAction(aURI, aOpener, aWhere, aContext) {
|
||||
let where = aWhere;
|
||||
/*
|
||||
* aWhere:
|
||||
* OPEN_DEFAULTWINDOW: default action
|
||||
* OPEN_CURRENTWINDOW: current window/tab
|
||||
* OPEN_NEWWINDOW: not allowed, converted to newtab below
|
||||
* OPEN_NEWTAB: open a new tab
|
||||
* OPEN_SWITCHTAB: open in an existing tab if it matches, otherwise open
|
||||
* a new tab. afaict we always open these in the current tab.
|
||||
*/
|
||||
if (where == Ci.nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW) {
|
||||
// query standard browser prefs indicating what to do for default action
|
||||
switch (aContext) {
|
||||
// indicates this is an open request from a 3rd party app.
|
||||
case Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL :
|
||||
where = Services.prefs.getIntPref("browser.link.open_external");
|
||||
break;
|
||||
// internal request
|
||||
default :
|
||||
where = Services.prefs.getIntPref("browser.link.open_newwindow");
|
||||
}
|
||||
}
|
||||
if (where == Ci.nsIBrowserDOMWindow.OPEN_NEWWINDOW) {
|
||||
Util.dumpLn("Invalid request - we can't open links in new windows.");
|
||||
where = Ci.nsIBrowserDOMWindow.OPEN_NEWTAB;
|
||||
}
|
||||
return where;
|
||||
},
|
||||
|
||||
_getBrowser: function _getBrowser(aURI, aOpener, aWhere, aContext) {
|
||||
let isExternal = (aContext == Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL);
|
||||
// We don't allow externals apps opening chrome docs
|
||||
if (isExternal && aURI && aURI.schemeIs("chrome"))
|
||||
return null;
|
||||
|
||||
let location;
|
||||
let browser;
|
||||
let loadflags = isExternal ?
|
||||
Ci.nsIWebNavigation.LOAD_FLAGS_FROM_EXTERNAL :
|
||||
Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
|
||||
let location;
|
||||
if (aWhere == Ci.nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW) {
|
||||
switch (aContext) {
|
||||
case Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL :
|
||||
aWhere = Services.prefs.getIntPref("browser.link.open_external");
|
||||
break;
|
||||
default : // OPEN_NEW or an illegal value
|
||||
aWhere = Services.prefs.getIntPref("browser.link.open_newwindow");
|
||||
}
|
||||
}
|
||||
let openAction = this._getOpenAction(aURI, aOpener, aWhere, aContext);
|
||||
|
||||
let browser;
|
||||
if (aWhere == Ci.nsIBrowserDOMWindow.OPEN_NEWWINDOW) {
|
||||
let url = aURI ? aURI.spec : "about:blank";
|
||||
let newWindow = openDialog("chrome://browser/content/browser.xul", "_blank",
|
||||
"all,dialog=no", url, null, null, null);
|
||||
// since newWindow.Browser doesn't exist yet, just return null
|
||||
return null;
|
||||
} else if (aWhere == Ci.nsIBrowserDOMWindow.OPEN_NEWTAB) {
|
||||
if (openAction == Ci.nsIBrowserDOMWindow.OPEN_NEWTAB) {
|
||||
let owner = isExternal ? null : Browser.selectedTab;
|
||||
let tab = Browser.addTab("about:blank", true, owner);
|
||||
if (isExternal)
|
||||
// Link clicks in content need to trigger peek tab functionality
|
||||
ContextUI.peekTabs(kOpenInNewTabAnimationDelayMsec);
|
||||
if (isExternal) {
|
||||
tab.closeOnExit = true;
|
||||
browser = tab.browser;
|
||||
} else if (aWhere == OPEN_APPTAB) {
|
||||
Browser.tabs.forEach(function(aTab) {
|
||||
if ("appURI" in aTab.browser && aTab.browser.appURI.spec == aURI.spec) {
|
||||
Browser.selectedTab = aTab;
|
||||
browser = aTab.browser;
|
||||
}
|
||||
});
|
||||
|
||||
if (!browser) {
|
||||
// Make a new tab to hold the app
|
||||
let tab = Browser.addTab("about:blank", true);
|
||||
browser = tab.browser;
|
||||
browser.appURI = aURI;
|
||||
} else {
|
||||
// Just use the existing browser, but return null to keep the system from trying to load the URI again
|
||||
browser = null;
|
||||
}
|
||||
} else { // OPEN_CURRENTWINDOW and illegal values
|
||||
browser = tab.browser;
|
||||
} else {
|
||||
browser = Browser.selectedBrowser;
|
||||
}
|
||||
|
||||
|
@ -1097,10 +1097,6 @@ nsBrowserAccess.prototype = {
|
|||
browser.focus();
|
||||
} catch(e) { }
|
||||
|
||||
// We are loading web content into this window, so make sure content is visible
|
||||
// XXX Can we remove this? It seems to be reproduced in BrowserUI already.
|
||||
BrowserUI.showContent();
|
||||
|
||||
return browser;
|
||||
},
|
||||
|
||||
|
|
|
@ -112,6 +112,10 @@ a {
|
|||
align-items: flex-start;
|
||||
}
|
||||
|
||||
#output-container.hideTimestamps > .message > .timestamp {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.filtered-by-type,
|
||||
.filtered-by-string {
|
||||
display: none;
|
||||
|
|
|
@ -1386,42 +1386,20 @@ function escapeAddonURI(aAddon, aUri, aUpdateType, aAppVersion)
|
|||
return uri;
|
||||
}
|
||||
|
||||
function recursiveRemoveAsync(aFile) {
|
||||
function removeAsync(aFile) {
|
||||
return Task.spawn(function () {
|
||||
let info = null;
|
||||
try {
|
||||
info = yield OS.File.stat(aFile.path);
|
||||
if (info.isDir)
|
||||
yield OS.File.removeDir(aFile.path);
|
||||
else
|
||||
yield OS.File.remove(aFile.path);
|
||||
}
|
||||
catch (e if e instanceof OS.File.Error && e.becauseNoSuchFile) {
|
||||
// The file has already gone away
|
||||
return;
|
||||
}
|
||||
|
||||
setFilePermissions(aFile, info.isDir ? FileUtils.PERMS_DIRECTORY
|
||||
: FileUtils.PERMS_FILE);
|
||||
|
||||
// OS.File means we have to recurse into directories
|
||||
if (info.isDir) {
|
||||
let iterator = new OS.File.DirectoryIterator(aFile.path);
|
||||
yield iterator.forEach(function(entry) {
|
||||
let nextFile = aFile.clone();
|
||||
nextFile.append(entry.name);
|
||||
return recursiveRemoveAsync(nextFile);
|
||||
});
|
||||
yield iterator.close();
|
||||
}
|
||||
|
||||
try {
|
||||
yield info.isDir ? OS.File.removeEmptyDir(aFile.path)
|
||||
: OS.File.remove(aFile.path);
|
||||
}
|
||||
catch (e if e instanceof OS.File.Error && e.becauseNoSuchFile) {
|
||||
// The file has already gone away
|
||||
}
|
||||
catch (e) {
|
||||
ERROR("Failed to remove file " + aFile.path, e);
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -5424,7 +5402,7 @@ AddonInstall.prototype = {
|
|||
LOG("Addon " + this.addon.id + " will be installed as " +
|
||||
"an unpacked directory");
|
||||
stagedAddon.append(this.addon.id);
|
||||
yield recursiveRemoveAsync(stagedAddon);
|
||||
yield removeAsync(stagedAddon);
|
||||
yield OS.File.makeDir(stagedAddon.path);
|
||||
yield extractFilesAsync(this.file, stagedAddon);
|
||||
installedUnpacked = 1;
|
||||
|
@ -5433,7 +5411,7 @@ AddonInstall.prototype = {
|
|||
LOG("Addon " + this.addon.id + " will be installed as " +
|
||||
"a packed xpi");
|
||||
stagedAddon.append(this.addon.id + ".xpi");
|
||||
yield recursiveRemoveAsync(stagedAddon);
|
||||
yield removeAsync(stagedAddon);
|
||||
yield OS.File.copy(this.file.path, stagedAddon.path);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче