Bug 955641 - Open debug logs in a tab. r=aleth

This commit is contained in:
Nihanth Subramanya 2014-02-21 03:34:29 +05:30
Родитель 8e0feeb092
Коммит 0df6181e05
11 изменённых файлов: 340 добавлений и 27 удалений

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

@ -256,6 +256,11 @@ var gAccountManager = {
Cc["@mozilla.org/widget/clipboardhelper;1"]
.getService(Ci.nsIClipboardHelper).copyString(text);
},
showDebugLog: function am_showDebugLog() {
if (!"Core" in window)
Cu.import("resource:///modules/ibCore.jsm");
Core.showDebugLog(this.accountList.selectedItem.account.id);
},
updateConnectedLabels: function am_updateConnectedLabels() {
for (let i = 0; i < gAccountManager.accountList.itemCount; ++i) {
let item = gAccountManager.accountList.getItemAtIndex(i);

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

@ -52,6 +52,10 @@
label="&account.copyDebugLog.label;"
accesskey="&account.copyDebugLog.accesskey;"
oncommand="gAccountManager.copyDebugLog();"/>
<command id="cmd_showDebugLog"
label="&account.showDebugLog.label;"
accesskey="&account.showDebugLog.accesskey;"
oncommand="gAccountManager.showDebugLog();"/>
<command id="cmd_moveup"
label="&account.moveup.label;"
oncommand="gAccountManager.moveCurrentItem(-1)"/>
@ -104,6 +108,8 @@
observes="contextAccountsItems"/>
<menuitem id="context_copyDebugLog"
command="cmd_copyDebugLog"/>
<menuitem id="context_showDebugLog"
command="cmd_showDebugLog"/>
<menuseparator id="context_accountsItemsSeparator"
observes="contextAccountsItems"/>
<menuitem command="cmd_new"/>

13
im/content/debugLog.html Normal file
Просмотреть файл

@ -0,0 +1,13 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="chrome://instantbird/skin/debugLog.css" rel="stylesheet" type="text/css">
</head>
<body>
</body>
</html>

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

@ -0,0 +1,175 @@
<?xml version="1.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/. -->
<bindings id="debugLogPanelBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="debugLogPanel">
<resources>
<stylesheet src="chrome://instantbird/skin/debugLogPanel.css"/>
</resources>
<content flex="1">
<xul:vbox flex="1">
<xul:toolbar class="debugLogTab-toolbar">
<xul:menulist class="accountList" anonid="accountList" flex="1"
onselect="document.getBindingParent(this).onAccountSelect()"/>
<xul:toolbarbutton class="debugLogTab-button" anonid="refreshButton"
label="Refresh"
oncommand="document.getBindingParent(this).showDebugLog();"/>
<xul:toolbarbutton class="debugLogTab-button" anonid="copyButton"
label="Copy"
oncommand="document.getBindingParent(this).copyDebugLog()"/>
</xul:toolbar>
<xul:browser anonid="debugLogBrowser" disablehistory="true" type="content"
flex="1" src="chrome://instantbird/content/debugLog.html"/>
</xul:vbox>
</content>
<implementation>
<property name="browser" readonly="true">
<getter>
return document.getAnonymousElementByAttribute(this, "anonid", "debugLogBrowser");
</getter>
</property>
<property name="accountList" readonly="true">
<getter>
return document.getAnonymousElementByAttribute(this, "anonid", "accountList");
</getter>
</property>
<!-- Only show the debug log if the account list is already populated. This
is useful, for example, if we are importing into a new window and only
need to repopulate the account list without re-displaying the log. -->
<method name="onAccountSelect">
<body>
<![CDATA[
if (this._accountListInited)
this.showDebugLog();
]]>
</body>
</method>
<!-- This method populates the list of accounts and ensures the specified
account is selected. Since the _inited flag is set here before returning,
no debug log will be shown. -->
<method name="initAccountList">
<parameter name="aAccountId"/>
<body>
<![CDATA[
if (!("Services" in window))
Components.utils.import("resource:///modules/imServices.jsm");
let accounts = Services.accounts.getAccounts();
while (accounts.hasMoreElements()) {
let acc = accounts.getNext();
var proto = acc.protocol;
var item = this.accountList.appendItem(acc.name, acc.id, proto.name);
item.setAttribute("image", proto.iconBaseURI + "icon.png");
item.setAttribute("class", "menuitem-iconic");
let accId = acc.id;
item.accountId = accId;
if (accId == aAccountId)
this.accountList.selectedItem = item;
}
this._accountListInited = true;
]]>
</body>
</method>
<method name="copyDebugLog">
<body>
<![CDATA[
Components.classes["@mozilla.org/widget/clipboardhelper;1"]
.getService(Components.interfaces.nsIClipboardHelper)
.copyString(this.browser.contentDocument.body.textContent);
]]>
</body>
</method>
<method name="showDebugLog">
<body>
<![CDATA[
let accId = this.accountList.selectedItem.accountId;
let account = Services.accounts.getAccountById(accId);
this.tab.setAttribute("label", "Debug log for " + account.name);
let doc = this.browser.contentDocument;
let table = doc.createElement("table");
table.style = "width: 100%";
// Clear out any existing content before appending the table.
doc.body.innerHTML = "";
doc.body.appendChild(table);
for (let dbgMsg of account.getDebugMessages()) {
let m = dbgMsg.message;
const dateServ = Cc["@mozilla.org/intl/scriptabledateformat;1"]
.getService(Ci.nsIScriptableDateFormat);
let time = new Date(m.timeStamp);
time = dateServ.FormatDateTime("", dateServ.dateFormatShort,
dateServ.timeFormatSeconds,
time.getFullYear(), time.getMonth() + 1,
time.getDate(), time.getHours(),
time.getMinutes(), time.getSeconds());
let level = dbgMsg.logLevel;
let rowClass = "default";
let formattedMsg;
if (!level)
formattedMsg = "(" + m.errorMessage + ")";
else {
if (level == dbgMsg.LEVEL_ERROR) {
level = "ERROR";
rowClass = "error";
}
else if (level == dbgMsg.LEVEL_WARNING) {
level = "WARN.";
rowClass = "warn";
}
else if (level == dbgMsg.LEVEL_LOG) {
level = "LOG ";
rowClass = "log";
}
else {
level = "DEBUG";
rowClass = "debug";
}
formattedMsg = level + " (@ " + m.sourceLine +
" " + m.sourceName + ":" + m.lineNumber + ")\n" +
m.errorMessage;
}
let tr = doc.createElement("tr");
tr.className = rowClass;
let timeCell = doc.createElement("td");
timeCell.className = "time";
let msgCell = doc.createElement("td");
msgCell.className = "msg";
// The trailing space and newline are necessary to ensure correct
// formatting when text is selected/copied.
timeCell.textContent = "[" + time + "] ";
msgCell.textContent = formattedMsg + "\n";
tr.appendChild(timeCell);
tr.appendChild(msgCell);
table.appendChild(tr);
}
// Ensure the scroll position is reset.
doc.body.scrollTop = 0;
doc.body.scrollLeft = 0;
]]>
</body>
</method>
<method name="finishImport">
<parameter name="aDebugLogPanel"/>
<body>
<![CDATA[
this.browser.swapDocShells(aDebugLogPanel.browser);
this.initAccountList(aDebugLogPanel.accountList.selectedItem.accountId);
this.tab.setAttribute("label", aDebugLogPanel.tab.getAttribute("label"));
]]>
</body>
</method>
</implementation>
</binding>
</bindings>

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

@ -14,6 +14,10 @@ newtab {
-moz-binding: url("chrome://instantbird/content/newtab.xml#newtab-item");
}
debugLogPanel {
-moz-binding: url("chrome://instantbird/content/debugLogPanel.xml#debugLogPanel")
}
aboutPanel {
-moz-binding: url("chrome://instantbird/content/aboutPanel.xml#aboutPanel");
}

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

@ -32,6 +32,8 @@ instantbird.jar:
content/instantbird/conversation.xml
content/instantbird/conv.xml
content/instantbird/credits.xhtml
content/instantbird/debugLogPanel.xml
content/instantbird/debugLog.html
content/instantbird/engineManager.js
content/instantbird/engineManager.xul
content/instantbird/extensions.js

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

@ -29,6 +29,8 @@
<!ENTITY account.cancelReconnection.accesskey "A">
<!ENTITY account.copyDebugLog.label "Copy Debug Log">
<!ENTITY account.copyDebugLog.accesskey "C">
<!ENTITY account.showDebugLog.label "Show Debug Log">
<!ENTITY account.showDebugLog.accesskey "H">
<!ENTITY account.connecting "Connecting…">
<!ENTITY account.disconnecting "Disconnecting…">
<!ENTITY account.disconnected "Not Connected">

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

@ -110,32 +110,18 @@ var Core = {
Components.utils.reportError(e); // Log unexpected errors.
return false;
}
// Try to get the most recent conversation window. If no such window exists,
// win will be null.
let win = Services.wm.getMostRecentWindow("Messenger:convs");
// Tries to open an aboutPanel in the specified window.
let showPage = function(aWindow, aPage) {
// Return false if the window doesn't exist.
if (!aWindow)
return false;
let panel = aWindow.document.createElementNS(
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
"aboutPanel");
// Try to add the panel, and return false if the window couldn't accept
// it (e.g. tabbed conversations are disabled).
if (!aWindow.getTabBrowser().addPanel(panel))
return false;
panel.showAboutPage(aPage);
aWindow.getTabBrowser().selectPanel(panel);
return true;
}
// Try to show the page in win, and open a new window if it didn't work.
if (!showPage(win, page)) {
win = Services.ww.openWindow(null, "chrome://instantbird/content/instantbird.xul",
"_blank", "chrome,toolbar,resizable", null);
win.addEventListener("load", showPage.bind(null, win, page));
self.showTab("aboutPanel", aPanel => aPanel.showAboutPage(page));
return true;
}
});
Services.cmd.registerCommand({
name: "debug",
get helpString() self.bundle("debugCommnad.help"),
usageContext: Ci.imICommand.CMD_CONTEXT_ALL,
priority: Ci.imICommand.CMD_PRIORITY_DEFAULT,
run: (aMsg, aConv) => {
this.showDebugLog(aConv.account.id);
return true;
}
});
@ -144,6 +130,15 @@ var Core = {
return true;
},
showDebugLog: function(aAccountId) {
this.showTab("debugLogPanel", aPanel => {
aPanel.browser.addEventListener("DOMContentLoaded", () => {
aPanel.initAccountList(aAccountId);
aPanel.showDebugLog();
});
});
},
showWindow: function(aWindowType, aUrl, aName, aFeatures) {
var win = Services.wm.getMostRecentWindow(aWindowType);
if (win)
@ -192,6 +187,38 @@ var Core = {
prompter.checkForUpdates();
},
// Creates a panel from the given binding name, and opens it in a new tab,
// creating a new window if necessary. The callback is invoked after adding
// the panel, which is passed as a parameter.
showTab: function(aPanelName, aCallback) {
// Try to get the most recent conversation window. If no such window exists,
// win will be null.
let win = Services.wm.getMostRecentWindow("Messenger:convs");
// Tries to open the panel in the specified window.
let showPanel = function(aWindow) {
// Return false if the window doesn't exist.
if (!aWindow)
return false;
let panel = aWindow.document.createElementNS(
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
aPanelName);
// Try to add the panel, and return false if the window couldn't accept
// it (e.g. tabbed conversations are disabled).
if (!aWindow.getTabBrowser().addPanel(panel))
return false;
aWindow.getTabBrowser().selectPanel(panel);
panel.ownerDocument.defaultView.focus();
aCallback(panel);
return true;
}
// Try to show the debug logs in win, and open a new window if it didn't work.
if (showPanel(win))
return;
win = Services.ww.openWindow(null, "chrome://instantbird/content/instantbird.xul",
"_blank", "chrome,toolbar,resizable", null);
win.addEventListener("load", showPanel.bind(null, win));
},
getIter: function(aEnumerator) {
while (aEnumerator.hasMoreElements())
yield aEnumerator.getNext();

45
im/themes/debugLog.css Normal file
Просмотреть файл

@ -0,0 +1,45 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
body {
margin: 0;
}
table {
border-collapse: collapse;
font-size: small;
}
td {
padding: 5px;
}
tr {
border-bottom: 1px solid rgba(0, 0, 0, 0.4);
}
tr.debug {
background-color: #ecffe0;
}
tr.log {
background-color: #d3edff;
}
tr.warn {
background-color: #f8f3cc;
}
tr.error {
background-color: #ffd0dc;
}
td.time {
white-space: nowrap;
vertical-align: top;
}
td.msg {
white-space: pre-wrap;
}

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

@ -0,0 +1,32 @@
/* 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/. */
.debugLogTab-button {
-moz-appearance: toolbarbutton;
}
.debugLogTab-toolbar {
margin: 0;
padding: 2px;
border-style: none;
-moz-appearance: none;
%ifdef XP_MACOSX
background-color: -moz-mac-chrome-active;
background-image: -moz-linear-gradient(rgba(255,255,255,.43), rgba(255,255,255,0));
border-bottom: 1px solid rgba(0, 0, 0, 0.57);
}
.debugLogTab-toolbar:-moz-window-inactive {
background-color: -moz-mac-chrome-inactive;
border-bottom-color: rgba(0, 0, 0, 0.32);
%else
background-color: -moz-Dialog;
%ifdef XP_WIN
background-image: -moz-linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,0));
%else
background-image: -moz-linear-gradient(rgba(255,255,255,.3), rgba(255,255,255,0));
%endif
border-bottom: 1px solid ThreeDShadow;
%endif
}

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

@ -16,6 +16,8 @@ instantbird.jar:
* skin/classic/instantbird/richlistbox.css
* skin/classic/instantbird/accountWizard.css
* skin/classic/instantbird/newtab.css
skin/classic/instantbird/debugLog.css
* skin/classic/instantbird/debugLogPanel.css
skin/classic/instantbird/newConversation.png
skin/classic/instantbird/founder.png
skin/classic/instantbird/operator.png