Bug 953569 - Extensions should be able to register commands, r=clokep (for the JS part only).

This commit is contained in:
Florian Quèze 2011-02-10 22:22:23 +01:00
Родитель e2e2418bb3
Коммит d3277fee0e
8 изменённых файлов: 257 добавлений и 23 удалений

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

@ -459,6 +459,25 @@ var buddyList = {
return;
}
let status = {
back: "AVAILABLE",
away: "AWAY",
busy: "UNAVAILABLE",
dnd: "UNAVAILABLE",
offline: "OFFLINE"
};
for (let cmd in status) {
let statusValue = Ci.purpleICoreService["STATUS_" + status[cmd]];
Services.cmd.registerCommand({
name: cmd,
priority: Ci.imICommand.PRIORITY_HIGH,
run: function(aMsg) {
Services.core.setStatus(statusValue, aMsg);
return true;
}
});
}
// TODO remove this once we cleanup the way the menus are inserted
let menubar = document.getElementById("blistMenubar");
let statusArea = document.getElementById("statusArea");

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

@ -258,14 +258,12 @@
// the /say command is used to bypass command processing
var msg = aMsg.match(/^\/say (.*)/);
if (!msg) {
try {
if (this._conv.doCommand(aMsg)) {
if (!this._conv.isChat)
this._conv.sendTyping(0);
this.resetInput();
return;
}
} catch(e) { }
if (Services.cmd.executeCommand(aMsg, this._conv)) {
if (!this._conv.isChat)
this._conv.sendTyping(0);
this.resetInput();
return;
}
}
else
aMsg = msg[1];

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

@ -43,6 +43,9 @@ Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyServiceGetter(Services, "core",
"@instantbird.org/purple/core;1",
"purpleICoreService");
XPCOMUtils.defineLazyServiceGetter(Services, "cmd",
"@instantbird.org/purple/commands-service;1",
"imICommandsService");
XPCOMUtils.defineLazyServiceGetter(Services, "tags",
"@instantbird.org/purple/tags-service;1",
"imITagsService");

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

@ -0,0 +1,94 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Instantbird messenging client, released
* 2011.
*
* The Initial Developer of the Original Code is
* Florian QUEZE <florian@instantbird.org>.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
interface purpleIConversation;
[scriptable, uuid(dae17fae-0d04-4d89-a817-637ef433383f)]
interface imICommand: nsISupports {
readonly attribute AUTF8String name;
readonly attribute AUTF8String helpString;
const short PRIORITY_LOW = -1000;
const short PRIORITY_DEFAULT = 0;
const short PRIORITY_PRPL = 1000;
const short PRIORITY_HIGH = 4000;
// Any integer value is usable as a priority.
// 0 is the default priority.
// < 0 is lower priority.
// > 0 is higher priority.
// Commands registered by protocol plugins will usually use PRIORITY_PRPL.
readonly attribute PRInt32 priority;
// Will return true if the command handled the message (it should not be sent).
// The leading slash, the command name and the following space are not included
// in the aMessage parameter.
boolean run(in AUTF8String aMessage,
[optional] in purpleIConversation aConversation);
};
[scriptable, uuid(467709a0-0bed-4f44-9bdc-13f78b9eaeba)]
interface imICommandsService: nsISupports {
void initCommands();
void unInitCommands();
// Commands registered without a protocol id will work for all protocols.
// Registering several commands of the same name with the same
// protocol id or no protocol id will replace the former command
// with the latter.
void registerCommand(in imICommand aCommand,
[optional] in AUTF8String aPrplId);
// aPrplId should be the same as what was used for the command registration.
void unregisterCommand(in AUTF8String aCommandName,
[optional] in AUTF8String aPrplId);
void listCommands([optional] in purpleIConversation aConversation,
[optional] out unsigned long commandCount,
[retval, array, size_is(commandCount)] out imICommand commands);
// Will return true if a command handled the message (it should not be sent).
// The aConversation parameters is required to execute protocol specific
// commands. Application global commands will work without it.
boolean executeCommand(in AUTF8String aMessage,
[optional] in purpleIConversation aConversation);
};
%{ C++
#define IM_COMMANDS_SERVICE_CONTRACTID \
"@instantbird.org/purple/commands-service;1"
%}

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

@ -74,20 +74,6 @@ interface purpleIConversation: nsISupports {
/* Send a message in the conversation */
void sendMsg(in AUTF8String aMsg);
/* Handle commands from a potential message.
Will return true if the message as been handled as a command and
should not be sent as a message, false if the message should be sent.
Will fail (NS_ERROR_FAILURE) if the message starts with / which
is the native command character of the protocol but is not a
valid command.
Will also fail (NS_ERROR_FAILURE) if a valid command had wrong
arguments or failed to execute for any other reason.
*/
boolean doCommand(in AUTF8String aMsg);
/* Un-initialize the conversation. Will be called by
purpleCoreService::RemoveConversation when the conversation is
closed or by purpleCoreService::Quit while exiting. */

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

@ -0,0 +1,133 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Instantbird messenging client, released
* 2011.
*
* The Initial Developer of the Original Code is
* Florian QUEZE <florian@instantbird.org>.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
XPCOMUtils.defineLazyServiceGetter(this, "obs",
"@mozilla.org/observer-service;1",
"nsIObserverService");
function CommandsService() { }
CommandsService.prototype = {
initCommands: function() {
this._commands = {};
this.registerCommand({
name: "raw",
priority: Ci.imICommand.PRIORITY_DEFAULT,
run: function(aMsg, aConv) {
aConv.sendMsg(aMsg);
return true;
}
});
},
unInitCommands: function() {
delete this._commands;
},
registerCommand: function(aCommand, aPrplId) {
let name = aCommand.name;
if (!name)
throw Cr.NS_ERROR_INVALID_ARG;
if (!(this._commands.hasOwnProperty(name)))
this._commands[name] = {};
this._commands[name][aPrplId || ""] = aCommand;
},
unregisterCommand: function(aCommandName, aPrplId) {
if (this._commands.hasOwnProperty(aCommandName)) {
let prplId = aPrplId || "";
let commands = this._commands[aCommandName];
if (commands.hasOwnProperty(aPrplId))
delete commands[aPrplId];
if (!Object.keys(commands).length)
delete this._commands[aCommandName];
}
},
listCommands: function(aConversation, commandCount) {
let result = [];
let prplId = aConversation && aConversation.account.protocol.id;
for (let name in this._commands) {
let commands = this._commands[name];
if (commands.hasOwnProperty(""))
result.push(commands[""]);
if (prplId && commands.hasOwnProperty(prplId))
result.push(commands[prplId]);
}
commandCount.value = result.length;
return result;
},
executeCommand: function (aMessage, aConversation) {
if (!aMessage)
throw Cr.NS_ERROR_INVALID_ARG;
let matchResult;
if (aMessage[0] != "/" ||
!(matchResult = /^\/([a-z]+)(?: |$)([\s\S]*)/(aMessage)))
return false;
let [, name, args] = matchResult;
if (!(this._commands.hasOwnProperty(name)))
return false;
// Get the 2 possible commands (the global and the proto specific)
let cmdArray = [];
let commands = this._commands[name];
if (commands.hasOwnProperty(""))
cmdArray.push(commands[""]);
if (aConversation) {
let prplId = aConversation.account.protocol.id;
if (commands.hasOwnProperty(prplId))
cmdArray.push(commands[prplId]);
}
// Attempt to apply them in order until one succeeds.
return cmdArray.sort(function(a, b) b.priority - a.priority)
.some(function (aCmd) aCmd.run(args, aConversation));
},
QueryInterface: XPCOMUtils.generateQI([Ci.imICommandsService]),
classDescription: "Commands",
classID: Components.ID("{7cb20c68-ccc8-4a79-b6f1-0b4771ed6c23}"),
contractID: "@instantbird.org/purple/commands-service;1"
};
const NSGetFactory = XPCOMUtils.generateNSGetFactory([CommandsService]);

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

@ -0,0 +1,2 @@
component {7cb20c68-ccc8-4a79-b6f1-0b4771ed6c23} imCommands.js
contract @instantbird.org/purple/commands-service;1 {7cb20c68-ccc8-4a79-b6f1-0b4771ed6c23}

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

@ -469,7 +469,6 @@ const GenericConversationPrototype = {
observer.observe(aSubject, aTopic, aData);
},
doCommand: function(aMsg) false,
sendMsg: function (aMsg) {
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
},