Bug 955438 - Add an /about command to open the about:* pages, r=clokep,florian.

This commit is contained in:
Nihanth Subramanya 2013-06-27 00:50:42 +02:00
Родитель 8c1d9e9e8b
Коммит 44f0b88e39
5 изменённых файлов: 192 добавлений и 10 удалений

122
im/content/aboutPanel.xml Normal file
Просмотреть файл

@ -0,0 +1,122 @@
<?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="aboutPanelBindings"
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="aboutPanel">
<content flex="1">
<xul:browser anonid="aboutBrowser" disablehistory="true" flex="1"/>
</content>
<implementation>
<method name="showAboutPage">
<parameter name="aPage"/>
<body>
<![CDATA[
let url = aPage.startsWith("about:") ? aPage : "about:" + aPage;
this.browser.loadURI(url);
]]>
</body>
</method>
<method name="refreshTitle">
<body>
<![CDATA[
let browser = this.browser;
this.tab.setAttribute("label",
browser.contentTitle.replace("\0", "", "g") || browser.currentURI.spec);
let imageUri = browser.currentURI.spec == "about:addons" ?
"chrome://mozapps/skin/extensions/extensionGeneric-16.png" :
"chrome://mozapps/skin/places/defaultFavicon.png";
this.tab.setAttribute("image", imageUri);
]]>
</body>
</method>
<method name="finishImport">
<parameter name="aAboutPanel"/>
<body>
<![CDATA[
this.browser.swapDocShells(aAboutPanel.browser);
this.refreshTitle();
]]>
</body>
</method>
<property name="browser" readonly="true">
<getter>
return document.getAnonymousElementByAttribute(this, "anonid", "aboutBrowser");
</getter>
</property>
<constructor>
<![CDATA[
this.browser.addEventListener("DOMTitleChanged", this.refreshTitle.bind(this));
// The addon manager does its own link handling using window.open().
// We need to override this method to open http links externally.
let win = this.browser.contentWindow;
let open = win.open;
win.open = function(aUrl) {
let uri = Services.io.newURI(aUrl, null, null);
if (!uri.schemeIs("http") && !uri.schemeIs("https")) {
open.apply(this, arguments);
}
else {
Components.classes["@mozilla.org/uriloader/external-protocol-service;1"]
.getService(Components.interfaces.nsIExternalProtocolService).loadUrl(uri);
}
}
]]>
</constructor>
</implementation>
<handlers>
<handler event="click">
<![CDATA[
// We only handle middle clicks. We don't handle the addon manager.
if (event.button != 1 || this.browser.currentURI.spec == "about:addons")
return;
// The event target may be a descendant of the actual link.
let url;
for (let elem = event.target; elem; elem = elem.parentNode) {
if (elem instanceof HTMLAnchorElement) {
url = elem.href;
if (url)
break;
}
}
if (!url)
return;
event.stopPropagation();
event.preventDefault();
// If it's an about page, open it.
if (url.startsWith("about:")) {
let panel = document.createElementNS(
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
"aboutPanel");
// addPanel will return null if the window can't accept new tabs.
if (window.getTabBrowser().addPanel(panel)) {
panel.showAboutPage(url);
return;
}
// If we couldn't add a new tab, load the page in this one.
this.showAboutPage(url);
return;
}
// Otherwise open in default browser.
// loadUrl can throw if the default browser is misconfigured.
Components.classes["@mozilla.org/uriloader/external-protocol-service;1"]
.getService(Components.interfaces.nsIExternalProtocolService)
.loadUrl(Services.io.newURI(url, null, null));
]]>
</handler>
</handlers>
</binding>
</bindings>

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

@ -6,6 +6,10 @@ conversation {
-moz-binding: url("chrome://instantbird/content/conversation.xml#conversation");
}
aboutPanel {
-moz-binding: url("chrome://instantbird/content/aboutPanel.xml#aboutPanel");
}
.conv-chat:not([chat]) {
display: none;
}

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

@ -10,6 +10,7 @@ instantbird.jar:
#endif
content/instantbird/aboutDialog.css
* content/instantbird/aboutDialog.xul
content/instantbird/aboutPanel.xml
content/instantbird/account.js
content/instantbird/accounts.css
content/instantbird/accounts.js

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

@ -2,6 +2,9 @@
# 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/.
aboutCommand.help=about &lt;page&gt;: display about:&lt;page&gt; in a new tab.
aboutCommand.invalidPageMessage="%S" is not a valid about page.
startupFailure.title=Instantbird - Start up failure
startupFailure.apologize=Instantbird encountered a serious error and cannot start, we apologize for the inconvenience.
startupFailure.update=An updated version will probably be available shortly to fix the problem.

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

@ -9,6 +9,7 @@ Cu.import("resource:///modules/imServices.jsm");
Cu.import("resource:///modules/imWindows.jsm");
Cu.import("resource:///modules/ibNotifications.jsm");
Cu.import("resource:///modules/ibSounds.jsm");
Cu.import("resource:///modules/imXPCOMUtils.jsm");
var Core = {
_events: [
@ -17,6 +18,8 @@ var Core = {
"quit-application-requested"
],
get bundle() l10nHelper("chrome://instantbird/locale/core.properties"),
init: function() {
try {
// Set the Vendor for breakpad only
@ -66,6 +69,58 @@ var Core = {
Services.obs.addObserver(Core, aTopic, false);
});
let self = this;
Services.cmd.registerCommand({
name: "about",
get helpString() self.bundle("aboutCommand.help"),
usageContext: Ci.imICommand.CMD_CONTEXT_ALL,
priority: Ci.imICommand.CMD_PRIORITY_DEFAULT,
run: function(aMsg, aConv) {
let page = aMsg.replace(/^about:/, "");
let url = "about:" + page;
// If the page doesn't exist, we avoid opening a tab.
try {
Services.io.newChannelFromURI(Services.io.newURI(url, null, null));
} catch(e) {
if (e.result == Components.results.NS_ERROR_MALFORMED_URI) {
Services.conversations.getUIConversation(aConv).systemMessage(
self.bundle("aboutCommand.invalidPageMessage", page));
return true;
}
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().selectedTab = panel.tab;
panel.focus();
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));
return true;
}
return true;
}
});
this._showAccountManagerIfNeeded(true);
return true;
},
@ -225,15 +280,12 @@ var Core = {
},
_promptError: function(aKeyString, aMessage) {
var bundle =
Services.strings.createBundle("chrome://instantbird/locale/core.properties");
var bundle = this.bundle;
var title = bundle.GetStringFromName("startupFailure.title");
var message =
bundle.GetStringFromName("startupFailure.apologize") + "\n\n" +
(aMessage ? bundle.formatStringFromName(aKeyString, [aMessage], 1)
: bundle.GetStringFromName(aKeyString)) + "\n\n" +
bundle.GetStringFromName("startupFailure.update");
var title = bundle("startupFailure.title");
var message = bundle("startupFailure.apologize") + "\n\n" +
(aMessage ? bundle(aKeyString, aMessage)
: bundle(aKeyString) + "\n\n" + bundle("startupFailure.update"));
const nsIPromptService = Components.interfaces.nsIPromptService;
const flags =
nsIPromptService.BUTTON_POS_1 * nsIPromptService.BUTTON_TITLE_IS_STRING +
@ -241,8 +293,8 @@ var Core = {
var prompts = Services.prompt;
if (!prompts.confirmEx(null, title, message, flags,
bundle.GetStringFromName("startupFailure.buttonUpdate"),
bundle.GetStringFromName("startupFailure.buttonClose"),
bundle("startupFailure.buttonUpdate"),
bundle("startupFailure.buttonClose"),
null, null, {}))
this.showUpdates();
}