Bug 953569 - Extensions should be able to register commands, r=clokep (for the JS part only).
This commit is contained in:
Родитель
e2e2418bb3
Коммит
d3277fee0e
|
@ -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;
|
||||
},
|
||||
|
|
Загрузка…
Ссылка в новой задаче