Bug 1316000 - Remove old Yahoo! Messenger support. r=aleth
This commit is contained in:
Родитель
6837d90b95
Коммит
4581f09477
|
@ -86,6 +86,8 @@ pref("chat.xmpp.messageCarbons", true);
|
|||
pref("chat.prpls.prpl-skype.disable", true);
|
||||
// Disable Facebook as the XMPP gateway no longer exists.
|
||||
pref("chat.prpls.prpl-facebook.disable", true);
|
||||
// Disable Yahoo Messenger as legacy Yahoo was shut down.
|
||||
pref("chat.prpls.prpl-yahoo.disable", true);
|
||||
// Whether to disable SRV lookups that use the system DNS library.
|
||||
pref("chat.dns.srv.disable", false);
|
||||
|
||||
|
|
|
@ -2,6 +2,5 @@
|
|||
# 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/.
|
||||
|
||||
connection.error.useUsernameNotEmailAddress=Please use your Facebook username, not an email address
|
||||
|
||||
facebook.chat.name=Facebook Chat
|
||||
facebook.disabled=Facebook Chat is no longer supported due to Facebook disabling their XMPP gateway.
|
||||
|
|
|
@ -2,36 +2,4 @@
|
|||
# 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/.
|
||||
|
||||
login.error.badCredentials=Username or password is incorrect.
|
||||
login.error.accountLockedFailed=Account locked due to too many failed login attempts.
|
||||
login.error.accountLockedGeneral=Account locked due to too many login attempts.
|
||||
login.error.accountDeactivated=Account has been deactivated.
|
||||
login.error.usernameNotExist=The username does not exist.
|
||||
# The %S will be an error code returned by the server.
|
||||
login.error.unknown=Unknown error: %S
|
||||
network.error.http=HTTP connection error.
|
||||
|
||||
conference.invite.message=Join my conference.
|
||||
|
||||
# Some options are commented out because they aren't used. We do the same thing
|
||||
# to their description strings.
|
||||
options.pagerPort=Port
|
||||
options.transferHost=File transfer server
|
||||
options.transferPort=File transfer port
|
||||
options.chatEncoding=Encoding
|
||||
options.ignoreInvites=Ignore conference invitations
|
||||
|
||||
# In this message, %S is replaced with the username of the user who left.
|
||||
system.message.conferenceLogoff=%S has left the conference.
|
||||
system.message.conferenceLogon=%S has joined the conference.
|
||||
|
||||
# LOCALZIATION NOTE (command.*):
|
||||
# These are the help messages for each command, the %S is the command name
|
||||
# Each command first gives the parameter it accepts and then a description of
|
||||
# the command.
|
||||
command.help.invite2=%S <user1>[,<user2>,...] [<invite message>]: invite one or more users into this conference chat.
|
||||
command.help.conference=%S: Create a new conference room in which you can later invite other users.
|
||||
|
||||
# LOCALIZATION NOTE (command.feedback.invite):
|
||||
# %S is the user, or comma separated list of users, invited to the conference.
|
||||
command.feedback.invite=You have invited %S to the conference.
|
||||
yahoo.disabled=Yahoo Messenger is no longer supported due to Yahoo disabling their legacy protocol.
|
||||
|
|
|
@ -6,33 +6,27 @@ var {interfaces: Ci, utils: Cu} = Components;
|
|||
|
||||
Cu.import("resource:///modules/imXPCOMUtils.jsm");
|
||||
Cu.import("resource:///modules/jsProtoHelper.jsm");
|
||||
Cu.import("resource:///modules/xmpp.jsm");
|
||||
Cu.import("resource:///modules/xmpp-session.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "_", () =>
|
||||
l10nHelper("chrome://chat/locale/facebook.properties")
|
||||
);
|
||||
XPCOMUtils.defineLazyGetter(this, "_irc", () =>
|
||||
l10nHelper("chrome://chat/locale/irc.properties")
|
||||
);
|
||||
|
||||
function FacebookAccount(aProtoInstance, aImAccount) {
|
||||
this._init(aProtoInstance, aImAccount);
|
||||
}
|
||||
FacebookAccount.prototype = {
|
||||
__proto__: XMPPAccountPrototype,
|
||||
get canJoinChat() { return false; },
|
||||
__proto__: GenericAccountPrototype,
|
||||
|
||||
connect: function() {
|
||||
this.WARN("As Facebook deprecated its XMPP gateway, it is currently not " +
|
||||
"possible to connect to Facebook Chat. See bug 1141674.");
|
||||
this.reportDisconnecting(Ci.prplIAccount.ERROR_OTHER_ERROR,
|
||||
_irc("error.unavailable", _("facebook.chat.name")));
|
||||
_("facebook.disabled"));
|
||||
this.reportDisconnected();
|
||||
}
|
||||
};
|
||||
|
||||
function FacebookProtocol() {
|
||||
}
|
||||
function FacebookProtocol() {}
|
||||
FacebookProtocol.prototype = {
|
||||
__proto__: GenericProtocolPrototype,
|
||||
get normalizedName() { return "facebook"; },
|
||||
|
|
|
@ -3,15 +3,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/.
|
||||
|
||||
XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell.ini']
|
||||
|
||||
EXTRA_COMPONENTS += [
|
||||
'yahoo.js',
|
||||
'yahoo.manifest',
|
||||
]
|
||||
|
||||
EXTRA_JS_MODULES += [
|
||||
'yahoo-session.jsm',
|
||||
]
|
||||
|
||||
JAR_MANIFESTS += ['jar.mn']
|
||||
|
|
|
@ -1,98 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
var yahoo = {};
|
||||
Services.scriptloader.loadSubScript("resource:///components/yahoo.js", yahoo);
|
||||
|
||||
function run_test()
|
||||
{
|
||||
add_test(test_cleanUsername);
|
||||
add_test(test_fixFontSize);
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
// Test the stripping of @yahoo.* domains from usernames.
|
||||
function test_cleanUsername()
|
||||
{
|
||||
// These are just a few of the many possible domains.
|
||||
let domains = ["yahoo.com.ar", "yahoo.com.au", "yahoo.com", "yahoo.co.jp",
|
||||
"yahoo.it", "yahoo.cn", "yahoo.co.in"];
|
||||
let userId = "user";
|
||||
|
||||
// We must provide a mimimal fake implementation of a protocol object, to keep
|
||||
// the YahooAccount constructor happy.
|
||||
let fakeProtocol = {
|
||||
id: "fake-proto",
|
||||
options: {
|
||||
local_charset: "UTF-8"
|
||||
},
|
||||
_getOptionDefault: function(aOption) { return this.options[aOption]; }
|
||||
};
|
||||
let fakeImAccount = {};
|
||||
|
||||
for (let domain of domains) {
|
||||
fakeImAccount.name = userId + "@" + domain;
|
||||
let yahooAccount = new yahoo.YahooAccount(fakeProtocol, fakeImAccount);
|
||||
do_check_eq(userId, yahooAccount.cleanUsername);
|
||||
}
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
// Test the _fixFontSize() method and ensure that it correctly fixes font sizes
|
||||
// in <font> tags while keeping any mention of size= in conversation untouched.
|
||||
function test_fixFontSize()
|
||||
{
|
||||
// This is an array of two-element arrays. Each inner two-element array
|
||||
// contains a message with a badly formed font size as the first element,
|
||||
// and a message with a well-formed font size as the second element. We test
|
||||
// to ensure that the badly formed message is converted to the well-formed
|
||||
// one.
|
||||
let testMessages = [
|
||||
// Single font tag.
|
||||
["<font face=\"Arial\" size=\"12\">Test message 1",
|
||||
"<font face=\"Arial\" size=\"3\">Test message 1"],
|
||||
// Single font tag with size="<digit>" in innner message.
|
||||
["<font face=\"Arial\" size=\"9\">size=\"30\" is a big size.</font>",
|
||||
"<font face=\"Arial\" size=\"2\">size=\"30\" is a big size.</font>"],
|
||||
// Single font tag with no face attribute.
|
||||
["<font size=\"12\">This message has no font face attribute.",
|
||||
"<font size=\"3\">This message has no font face attribute."],
|
||||
// Single font tag with no size attribute.
|
||||
["<font face=\"Arial\">This message has no font size attribute.",
|
||||
"<font face=\"Arial\">This message has no font size attribute."],
|
||||
// Single font tag with rearranged attribute order.
|
||||
["<font size=\"9\" face=\"Arial\">size=\"30\" is a big size.</font>",
|
||||
"<font size=\"2\" face=\"Arial\">size=\"30\" is a big size.</font>"],
|
||||
// Multiple font tags.
|
||||
["<font face=\"Arial\" size=\"12\">Hello. <font face=\"Consolas\" size=\"40\">World",
|
||||
"<font face=\"Arial\" size=\"3\">Hello. <font face=\"Consolas\" size=\"7\">World"]
|
||||
];
|
||||
|
||||
let fakeProtocol = {
|
||||
id: "fake-proto",
|
||||
options: {
|
||||
local_charset: "UTF-8"
|
||||
},
|
||||
_getOptionDefault: function(aOption) { return this.options[aOption]; }
|
||||
};
|
||||
let fakeImAccount = {name: "test-user"};
|
||||
// We create a fake conversation object so we can obtain the cleaned up
|
||||
// message from the conv.writeMessage() call.
|
||||
let messagePair;
|
||||
let fakeConversation = {
|
||||
writeMessage: function(aName, aMessage, aProperties) {
|
||||
do_check_eq(aMessage, messagePair[1]); // Compare to the good message.
|
||||
},
|
||||
updateTyping: function(aStatus, aName) { }
|
||||
};
|
||||
|
||||
let yahooAccount = new yahoo.YahooAccount(fakeProtocol, fakeImAccount);
|
||||
yahooAccount._conversations.set("test-user", fakeConversation);
|
||||
for (let pair of testMessages) {
|
||||
messagePair = pair;
|
||||
// Send in the badly formed message.
|
||||
yahooAccount.receiveMessage("test-user", messagePair[0]);
|
||||
}
|
||||
run_next_test();
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
Components.utils.import("resource:///modules/ArrayBufferUtils.jsm");
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
Components.utils.import("resource:///modules/yahoo-session.jsm");
|
||||
var yahoo = {};
|
||||
Services.scriptloader.loadSubScript("resource:///modules/yahoo-session.jsm", yahoo);
|
||||
|
||||
// Preset test values.
|
||||
var kUsername = "testUser";
|
||||
var kPassword = "instantbird";
|
||||
var kPagerIp = "123.456.78.9";
|
||||
var kCrumb = "MG-Z/jNG+Q==";
|
||||
var kChallengeString = "AEF08DBAC33F9EEDABCFEA==";
|
||||
var kYCookie = "OTJmMTQyOTU1ZGQ4MDA3Y2I2ODljMTU5";
|
||||
var kTCookie = "NTdlZmIzY2Q4ODI3ZTc3NTIxYTk1MDhm";
|
||||
var kToken = "MThmMzg3OWM3ODcxMW";
|
||||
|
||||
var kPagerAddressResponse = "COLO_CAPACITY=1\r\nCS_IP_ADDRESS=" + kPagerIp;
|
||||
var kTokenResponse = "0\r\n" + kToken + "\r\npartnerid=dummyValue";
|
||||
var kCookieResponse = "0\r\ncrumb=" + kCrumb + "\r\nY=" + kYCookie +
|
||||
"\r\nT=" + kTCookie + "\r\ncookievalidfor=86400";
|
||||
|
||||
/* In each test, we override the function that would normally be called next in
|
||||
* the login process. We do this so that we can intercept the login process,
|
||||
* preventing calls to real Yahoo! servers, and do equality testing. */
|
||||
function run_test()
|
||||
{
|
||||
add_test(test_pagerAddress);
|
||||
add_test(test_challengeString);
|
||||
add_test(test_loginToken);
|
||||
add_test(test_cookies);
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_pagerAddress()
|
||||
{
|
||||
let helper = new yahoo.YahooLoginHelper({}, {});
|
||||
|
||||
helper._getChallengeString = function() {
|
||||
do_check_eq(kPagerIp, helper._session.pagerAddress);
|
||||
run_next_test();
|
||||
};
|
||||
|
||||
helper._onPagerAddressResponse(kPagerAddressResponse, null);
|
||||
}
|
||||
|
||||
function test_challengeString()
|
||||
{
|
||||
let helper = new yahoo.YahooLoginHelper({}, {});
|
||||
|
||||
helper._getLoginToken = function() {
|
||||
do_check_eq(kChallengeString, helper._challengeString);
|
||||
run_next_test();
|
||||
};
|
||||
|
||||
let response = new yahoo.YahooPacket(yahoo.kPacketType.AuthResponse, 0, 0);
|
||||
response.addValue(1, helper._username);
|
||||
response.addValue(94, kChallengeString);
|
||||
response.addValue(13, 0);
|
||||
helper._onChallengeStringResponse(response.toArrayBuffer());
|
||||
}
|
||||
|
||||
function test_loginToken()
|
||||
{
|
||||
let helper = new yahoo.YahooLoginHelper({}, {});
|
||||
|
||||
helper._getCookies = function() {
|
||||
do_check_eq(kToken, helper._loginToken);
|
||||
run_next_test();
|
||||
};
|
||||
|
||||
helper._onLoginTokenResponse(kTokenResponse, null);
|
||||
}
|
||||
|
||||
function test_cookies()
|
||||
{
|
||||
let helper = new yahoo.YahooLoginHelper({}, {});
|
||||
|
||||
helper._sendPagerAuthResponse = function() {
|
||||
do_check_eq(kCrumb, helper._crumb);
|
||||
do_check_eq(kYCookie, helper._session.yCookie);
|
||||
do_check_eq(kTCookie, helper._session.tCookie);
|
||||
run_next_test();
|
||||
};
|
||||
|
||||
helper._onLoginCookiesResponse(kCookieResponse, null);
|
||||
}
|
|
@ -1,217 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
Components.utils.import("resource:///modules/ArrayBufferUtils.jsm");
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
Components.utils.import("resource:///modules/yahoo-session.jsm");
|
||||
var yahoo = {};
|
||||
Services.scriptloader.loadSubScript("resource:///modules/yahoo-session.jsm", yahoo);
|
||||
|
||||
var kPacketIdBytes = StringToBytes(yahoo.kPacketIdentfier);
|
||||
var kHelloKey = 1;
|
||||
var kHelloValue = "Hello";
|
||||
var kWorldKey = 20;
|
||||
var kWorldValue = "World";
|
||||
var kNumberKey = 4;
|
||||
var kNumberValue = 32;
|
||||
var kParamsKey = 60;
|
||||
var kParam1Value = "param1";
|
||||
var kParam2Value = "param2";
|
||||
var kPacketDataString = "1\xC0\x80Hello\xC0\x8020\xC0\x80World\xC0\x80" +
|
||||
"4\xC0\x8032\xC0\x8060\xC0\x80param1\xC0\x80" +
|
||||
"60\xC0\x80param2\xC0\x80";
|
||||
|
||||
function run_test()
|
||||
{
|
||||
add_test(test_headerCreation);
|
||||
add_test(test_fullPacketCreation);
|
||||
add_test(test_packetDecoding);
|
||||
add_test(test_extractPackets);
|
||||
add_test(test_malformedPacketExtraction);
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_headerCreation()
|
||||
{
|
||||
let packetLength = 0;
|
||||
// Random numbers.
|
||||
let serviceNumber = 0x57;
|
||||
let status = 0x04;
|
||||
let sessionId = 0x57842390;
|
||||
|
||||
let packet = new yahoo.YahooPacket(serviceNumber, status, sessionId);
|
||||
let buf = packet.toArrayBuffer();
|
||||
let view = new DataView(buf);
|
||||
|
||||
// Ensure that the first 4 bytes contain the YMSG identifier.
|
||||
for (let i = 0; i < kPacketIdBytes.length; ++i)
|
||||
do_check_eq(kPacketIdBytes[i], view.getUint8(i));
|
||||
|
||||
do_check_eq(yahoo.kProtocolVersion, view.getUint16(4));
|
||||
do_check_eq(yahoo.kVendorId, view.getUint16(6));
|
||||
do_check_eq(packetLength, view.getUint16(8));
|
||||
do_check_eq(serviceNumber, view.getUint16(10));
|
||||
do_check_eq(status, view.getUint32(12));
|
||||
do_check_eq(sessionId, view.getUint32(16));
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_fullPacketCreation()
|
||||
{
|
||||
packetLength = kPacketDataString.length;
|
||||
// Random numbers.
|
||||
let serviceNumber = 0x55;
|
||||
let status = 0x02;
|
||||
let sessionId = 0x12567800;
|
||||
|
||||
let packet = new yahoo.YahooPacket(serviceNumber, status, sessionId);
|
||||
packet.addValue(kHelloKey, kHelloValue);
|
||||
packet.addValue(kWorldKey, kWorldValue);
|
||||
packet.addValue(kNumberKey, kNumberValue);
|
||||
packet.addValues(kParamsKey, [kParam1Value, kParam2Value]);
|
||||
let buf = packet.toArrayBuffer();
|
||||
let view = new DataView(buf);
|
||||
|
||||
// Header check.
|
||||
|
||||
// Ensure that the first 4 bytes contain the YMSG identifier.
|
||||
for (let i = 0; i < kPacketIdBytes.length; ++i)
|
||||
do_check_eq(kPacketIdBytes[i], view.getUint8(i));
|
||||
|
||||
do_check_eq(yahoo.kProtocolVersion, view.getUint16(4));
|
||||
do_check_eq(yahoo.kVendorId, view.getUint16(6));
|
||||
do_check_eq(packetLength, view.getUint16(8));
|
||||
do_check_eq(serviceNumber, view.getUint16(10));
|
||||
do_check_eq(status, view.getUint32(12));
|
||||
do_check_eq(sessionId, view.getUint32(16));
|
||||
|
||||
// Packet data check.
|
||||
let dataBytes = StringToBytes(kPacketDataString);
|
||||
for (let i = 0; i < dataBytes.length; ++i)
|
||||
do_check_eq(dataBytes[i], view.getUint8(yahoo.kPacketHeaderSize + i));
|
||||
run_next_test()
|
||||
}
|
||||
|
||||
function test_packetDecoding()
|
||||
{
|
||||
let packetLength = kPacketDataString.length;
|
||||
// Random numbers.
|
||||
let serviceNumber = 0x20;
|
||||
let status = 0x06;
|
||||
let sessionId = 0x13319AB2;
|
||||
|
||||
let buf = new ArrayBuffer(yahoo.kPacketHeaderSize + packetLength);
|
||||
let view = new DataView(buf);
|
||||
|
||||
for (let i = 0; i < kPacketIdBytes.length; ++i)
|
||||
view.setUint8(i, kPacketIdBytes[i]);
|
||||
|
||||
view.setUint16(4, yahoo.kProtocolVersion);
|
||||
view.setUint16(6, yahoo.kVendorId);
|
||||
view.setUint16(8, packetLength);
|
||||
view.setUint16(10, serviceNumber);
|
||||
view.setUint32(12, status);
|
||||
view.setUint32(16, sessionId);
|
||||
|
||||
let dataBuf = BytesToArrayBuffer(StringToBytes(kPacketDataString));
|
||||
copyBytes(buf, dataBuf, 20);
|
||||
|
||||
// Now we decode and test.
|
||||
let packet = new yahoo.YahooPacket();
|
||||
packet.fromArrayBuffer(buf);
|
||||
|
||||
// Test header information.
|
||||
do_check_eq(serviceNumber, packet.service);
|
||||
do_check_eq(status, packet.status);
|
||||
do_check_eq(sessionId, packet.sessionId);
|
||||
|
||||
// Test the getting of single packet data values.
|
||||
do_check_eq(kHelloValue, packet.getValue(kHelloKey));
|
||||
do_check_eq(kWorldValue, packet.getValue(kWorldKey));
|
||||
do_check_eq(kNumberValue, packet.getValue(kNumberKey));
|
||||
|
||||
// Test the getting of multiple values with a single key.
|
||||
let multiValue = packet.getValues(kParamsKey);
|
||||
do_check_eq(2, multiValue.length);
|
||||
do_check_eq(kParam1Value, multiValue[0]);
|
||||
do_check_eq(kParam2Value, multiValue[1]);
|
||||
|
||||
// Test if certain keys are non-existant.
|
||||
do_check_true(packet.hasKey(kHelloKey));
|
||||
do_check_false(packet.hasKey(500)); // There is no key 500.
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_extractPackets()
|
||||
{
|
||||
// Some constants for each packet.
|
||||
const kP1Service = 0x47;
|
||||
const kP1Status = 0;
|
||||
const kP1SessionId = 0x12345678;
|
||||
// Used for testing packet verification.
|
||||
const kP1FuzzerKey = 42;
|
||||
const kP1FuzzerValue = "I am using the YMSG protocol!";
|
||||
|
||||
const kP2Service = 0x57;
|
||||
const kP2Status = 5;
|
||||
const kP2SessionId = 0x87654321;
|
||||
|
||||
// First, create two packets and obtain their buffers.
|
||||
let packet1 = new yahoo.YahooPacket(kP1Service, kP1Status, kP1SessionId);
|
||||
packet1.addValue(kHelloKey, kHelloValue);
|
||||
packet1.addValue(kP1FuzzerKey, kP1FuzzerValue);
|
||||
let packet1Buffer = packet1.toArrayBuffer();
|
||||
|
||||
let packet2 = new yahoo.YahooPacket(kP2Service, kP2Status, kP2SessionId);
|
||||
packet2.addValue(kWorldKey, kWorldValue);
|
||||
let packet2Buffer = packet2.toArrayBuffer();
|
||||
|
||||
// Create one full buffer with both packets inside.
|
||||
let fullBuffer = new ArrayBuffer(packet1Buffer.byteLength +
|
||||
packet2Buffer.byteLength);
|
||||
copyBytes(fullBuffer, packet1Buffer);
|
||||
copyBytes(fullBuffer, packet2Buffer, packet1Buffer.byteLength);
|
||||
|
||||
// Now, run the packets through the extractPackets() method.
|
||||
let [extractedPackets, bytesHandled] =
|
||||
yahoo.YahooPacket.extractPackets(fullBuffer);
|
||||
do_check_eq(2, extractedPackets.length);
|
||||
|
||||
// Packet 1 checks.
|
||||
let p1 = extractedPackets[0];
|
||||
do_check_eq(kP1Service, p1.service);
|
||||
do_check_eq(kP1Status, p1.status);
|
||||
do_check_eq(kP1SessionId, p1.sessionId);
|
||||
do_check_true(p1.hasKey(kHelloKey));
|
||||
do_check_eq(kHelloValue, p1.getValue(kHelloKey));
|
||||
|
||||
// Packet 2 checks.
|
||||
let p2 = extractedPackets[1];
|
||||
do_check_eq(kP2Service, p2.service);
|
||||
do_check_eq(kP2Status, p2.status);
|
||||
do_check_eq(kP2SessionId, p2.sessionId);
|
||||
do_check_true(p2.hasKey(kWorldKey));
|
||||
do_check_eq(kWorldValue, p2.getValue(kWorldKey));
|
||||
|
||||
// Check if all the bytes were handled.
|
||||
do_check_eq(fullBuffer.byteLength, bytesHandled);
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_malformedPacketExtraction()
|
||||
{
|
||||
const kInvalidPacketData = "MSYG1\xC0\x80Hello\xC0\x8020\xC0\x80World\xC0\x80";
|
||||
let buffer = BytesToArrayBuffer(StringToBytes(kInvalidPacketData));
|
||||
let malformed = false;
|
||||
try {
|
||||
yahoo.YahooPacket.extractPackets(buffer);
|
||||
} catch(e) {
|
||||
malformed = true;
|
||||
}
|
||||
do_check_true(malformed);
|
||||
run_next_test();
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
[DEFAULT]
|
||||
head =
|
||||
tail =
|
||||
|
||||
[test_yahooAccount.js]
|
||||
[test_yahooLoginHelper.js]
|
||||
[test_yahoopacket.js]
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -2,575 +2,38 @@
|
|||
* 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/. */
|
||||
|
||||
var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
||||
var {interfaces: Ci, utils: Cu} = Components;
|
||||
|
||||
Cu.import("resource:///modules/imServices.jsm");
|
||||
Cu.import("resource:///modules/imXPCOMUtils.jsm");
|
||||
Cu.import("resource:///modules/jsProtoHelper.jsm");
|
||||
Cu.import("resource:///modules/yahoo-session.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "_", () =>
|
||||
l10nHelper("chrome://chat/locale/yahoo.properties")
|
||||
);
|
||||
|
||||
// These timeouts are in milliseconds.
|
||||
var kKeepAliveTimeout = 60 * 1000; // One minute.
|
||||
var kPingTimeout = 3600 * 1000; // One hour.
|
||||
|
||||
function YahooConversation(aAccount, aName)
|
||||
{
|
||||
this._buddyUserName = aName;
|
||||
this._account = aAccount;
|
||||
this.buddy = aAccount.getBuddy(aName);
|
||||
this._init(aAccount);
|
||||
}
|
||||
YahooConversation.prototype = {
|
||||
__proto__: GenericConvIMPrototype,
|
||||
_account: null,
|
||||
_buddyUserName: null,
|
||||
_typingTimer: null,
|
||||
|
||||
close: function() {
|
||||
this._account.deleteConversation(this._buddyUserName);
|
||||
GenericConvChatPrototype.close.call(this);
|
||||
},
|
||||
|
||||
sendMsg: function (aMsg) {
|
||||
// Deliver the message, then write it to the window.
|
||||
this._account._session.sendChatMessage(this._buddyUserName,
|
||||
this._account.encodeMessage(aMsg));
|
||||
this.finishedComposing();
|
||||
this.writeMessage(this._account.cleanUsername, aMsg,
|
||||
{outgoing: true, _alias: this._account.imAccount.alias});
|
||||
},
|
||||
|
||||
sendTyping: function(aString) {
|
||||
if (aString.length) {
|
||||
if (!this._typingTimer)
|
||||
this._account._session.sendTypingStatus(this._buddyUserName, true);
|
||||
this._refreshTypingTimer();
|
||||
}
|
||||
return Ci.prplIConversation.NO_TYPING_LIMIT;
|
||||
},
|
||||
|
||||
finishedComposing: function() {
|
||||
this._account._session.sendTypingStatus(this._buddyUserName, false);
|
||||
this._cancelTypingTimer();
|
||||
},
|
||||
|
||||
_refreshTypingTimer: function() {
|
||||
this._cancelTypingTimer();
|
||||
this._typingTimer = setTimeout(this.finishedComposing.bind(this), 10000);
|
||||
},
|
||||
|
||||
_cancelTypingTimer: function() {
|
||||
if (!this._typingTimer)
|
||||
return;
|
||||
clearTimeout(this._typingTimer);
|
||||
delete this._typingTimer
|
||||
this._typingTimer = null;
|
||||
},
|
||||
|
||||
get name() { return this._buddyUserName; }
|
||||
};
|
||||
|
||||
function YahooConference(aAccount, aRoom, aOwner)
|
||||
{
|
||||
this._account = aAccount;
|
||||
this._roomName = aRoom;
|
||||
this._owner = aOwner;
|
||||
this._init(aAccount, aRoom, aAccount.cleanUsername);
|
||||
}
|
||||
YahooConference.prototype = {
|
||||
__proto__: GenericConvChatPrototype,
|
||||
_account: null,
|
||||
_roomName: null,
|
||||
_owner: null,
|
||||
|
||||
close: function() {
|
||||
this.reportLogoff();
|
||||
this._account.deleteConference(this._roomName);
|
||||
GenericConvChatPrototype.close.call(this);
|
||||
},
|
||||
|
||||
reportLogoff: function() {
|
||||
if (this.left)
|
||||
return;
|
||||
this._account._session.sendConferenceLogoff(this._account.cleanUsername,
|
||||
this.getParticipantNames(),
|
||||
this._roomName);
|
||||
this.left = true;
|
||||
},
|
||||
|
||||
sendMsg: function(aMsg) {
|
||||
this._account._session.sendConferenceMessage(this.getParticipantNames(),
|
||||
this._roomName,
|
||||
this._account.encodeMessage(aMsg));
|
||||
},
|
||||
|
||||
addParticipant: function(aName) {
|
||||
// In case we receive multiple conference logon packets, prevent adding
|
||||
// duplicate buddies.
|
||||
if (this._participants.get(aName))
|
||||
return;
|
||||
let buddy = new YahooConferenceBuddy(aName, this);
|
||||
this._participants.set(aName, buddy);
|
||||
this.notifyObservers(new nsSimpleEnumerator([buddy]), "chat-buddy-add");
|
||||
this.writeMessage(this._roomName,
|
||||
_("system.message.conferenceLogon", aName),
|
||||
{system: true});
|
||||
},
|
||||
|
||||
getParticipantNames: function() { return Array.from(this._participants.values()).map(p => p.name); }
|
||||
};
|
||||
|
||||
function YahooConferenceBuddy(aName, aConference)
|
||||
{
|
||||
this._name = aName;
|
||||
this._conference = aConference;
|
||||
}
|
||||
YahooConferenceBuddy.prototype = {
|
||||
__proto__: GenericConvChatBuddyPrototype,
|
||||
_conference: null,
|
||||
|
||||
get founder() { return this._conference._owner == this._name; }
|
||||
};
|
||||
|
||||
function YahooAccountBuddy(aAccount, aBuddy, aTag, aUserName)
|
||||
{
|
||||
this._init(aAccount, aBuddy, aTag, aUserName);
|
||||
}
|
||||
YahooAccountBuddy.prototype = {
|
||||
__proto__: GenericAccountBuddyPrototype,
|
||||
iconChecksum: null,
|
||||
|
||||
// This removes the buddy locally, and from the Yahoo! servers.
|
||||
remove: function() { return this._account.removeBuddy(this, true); },
|
||||
// This removes the buddy locally, but keeps him on the servers.
|
||||
removeLocal: function() { return this._account.removeBuddy(this, false); },
|
||||
createConversation: function() { return this._account.createConversation(this.userName); }
|
||||
}
|
||||
|
||||
function YahooAccount(aProtoInstance, aImAccount)
|
||||
{
|
||||
this._init(aProtoInstance, aImAccount);
|
||||
this._buddies = new Map();
|
||||
this._conversations = new Map();
|
||||
this._conferences = new Map();
|
||||
this._protocol = aProtoInstance;
|
||||
this._converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
|
||||
.createInstance(Ci.nsIScriptableUnicodeConverter);
|
||||
this._converter.charset = this.getString("local_charset") || "UTF-8";
|
||||
|
||||
// The username stripped of any @yahoo.* domain.
|
||||
this.cleanUsername = this.name.replace(/@yahoo\..+$/, "");
|
||||
}
|
||||
YahooAccount.prototype = {
|
||||
__proto__: GenericAccountPrototype,
|
||||
// YahooSession object passed in constructor.
|
||||
_session: null,
|
||||
// A Map holding the list of buddies associated with their usernames.
|
||||
_buddies: null,
|
||||
// A Map holding the list of open buddy conversations associated with the
|
||||
// username of the buddy.
|
||||
_conversations: null,
|
||||
// A Map holding the list of open conference rooms associated with the room
|
||||
// name.
|
||||
_conferences: null,
|
||||
// YahooProtocol object passed in the constructor.
|
||||
_protocol: null,
|
||||
// An nsIScriptableUnicodeConverter used to convert incoming/outgoing chat
|
||||
// messages to the correct charset.
|
||||
_converter: null,
|
||||
// This is simply incremented by one everytime a new conference room is
|
||||
// created. It is appened to the end of the room name when a new room is
|
||||
// created, ensuring name uniqueness.
|
||||
_roomsCreated: 0,
|
||||
// The username stripped of any @yahoo.* domain.
|
||||
cleanUsername: null,
|
||||
// The timers used to send keepalive and ping packets to the server to ensrue
|
||||
// the server that the user is still connected.
|
||||
_keepAliveTimer: null,
|
||||
_pingTimer: null,
|
||||
|
||||
connect: function() {
|
||||
this._session = new YahooSession(this);
|
||||
this._session.login(this.imAccount.name, this.imAccount.password);
|
||||
},
|
||||
|
||||
disconnect: function(aSilent) {
|
||||
// Log out of all of the conferences the user is in.
|
||||
for (let conf of this._conferences)
|
||||
conf[1].reportLogoff();
|
||||
|
||||
if (this.connected) {
|
||||
this.reportDisconnecting(Ci.prplIAccount.NO_ERROR, "");
|
||||
if (this._session.isConnected)
|
||||
this._session.disconnect();
|
||||
this.reportDisconnected();
|
||||
}
|
||||
// buddy[1] is the actual object.
|
||||
for (let buddy of this._buddies)
|
||||
buddy[1].setStatus(Ci.imIStatusInfo.STATUS_UNKNOWN, "");
|
||||
|
||||
// Clear and delete the timers to avoid memory leaks.
|
||||
if (this._keepAliveTimer) {
|
||||
this._keepAliveTimer.cancel();
|
||||
delete this._keepAliveTimer;
|
||||
}
|
||||
|
||||
if (this._pingTimer) {
|
||||
this._pingTimer.cancel();
|
||||
delete this._pingTimer;
|
||||
}
|
||||
},
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
if (aTopic == "status-changed")
|
||||
this._session.setStatus(aSubject.statusType, aData);
|
||||
else if (aTopic == "user-icon-changed")
|
||||
this._session.setProfileIcon(aData);
|
||||
},
|
||||
|
||||
remove: function() {
|
||||
for (let conv of this._conversations.values())
|
||||
conv.close();
|
||||
delete this._conversations;
|
||||
for (let buddy of this._buddies)
|
||||
buddy[1].removeLocal(); // buddy[1] is the actual object.
|
||||
},
|
||||
|
||||
unInit: function() {
|
||||
this.disconnect(true);
|
||||
delete this.imAccount;
|
||||
},
|
||||
|
||||
createConversation: function(aName) {
|
||||
let conv = new YahooConversation(this, aName);
|
||||
this._conversations.set(aName, conv);
|
||||
return conv;
|
||||
},
|
||||
|
||||
deleteConversation: function(aName) {
|
||||
if (this._conversations.has(aName))
|
||||
this._conversations.delete(aName);
|
||||
},
|
||||
|
||||
receiveConferenceInvite: function(aOwner, aRoom, aParticipants, aMessage) {
|
||||
// Do nothing if we wish to ignore invites.
|
||||
if (!Services.prefs.getIntPref("messenger.conversations.autoAcceptChatInvitations") ||
|
||||
this.getBool("ignore_invites"))
|
||||
return;
|
||||
|
||||
let conf = new YahooConference(this, aRoom, aOwner);
|
||||
this._conferences.set(aRoom, conf);
|
||||
|
||||
for (let participant of aParticipants)
|
||||
conf.addParticipant(participant);
|
||||
|
||||
// Add ourselves to the conference room as well.
|
||||
conf.addParticipant(this.imAccount.name);
|
||||
|
||||
this._session.acceptConferenceInvite(aOwner, aRoom,
|
||||
conf.getParticipantNames());
|
||||
},
|
||||
|
||||
receiveConferenceLogon: function(aRoom, aUsername) {
|
||||
if (!this._conferences.has(aRoom))
|
||||
return;
|
||||
let conf = this._conferences.get(aRoom);
|
||||
conf.addParticipant(aUsername);
|
||||
},
|
||||
|
||||
receiveConferenceLogoff: function(aRoom, aUsername) {
|
||||
if (!this._conferences.has(aRoom))
|
||||
return;
|
||||
let conf = this._conferences.get(aRoom);
|
||||
conf.removeParticipant(aUsername);
|
||||
conf.writeMessage(this._roomName,
|
||||
_("system.message.conferenceLogoff", aName),
|
||||
{system: true});
|
||||
},
|
||||
|
||||
deleteConference: function(aName) {
|
||||
if (this._conferences.has(aName))
|
||||
this._conferences.delete(aName);
|
||||
},
|
||||
|
||||
// Called when the user adds or authorizes a new contact.
|
||||
addBuddy: function(aTag, aName) {
|
||||
let buddy = new YahooAccountBuddy(this, null, aTag, aName);
|
||||
this._buddies.set(buddy.userName, buddy);
|
||||
this._session.addBuddyToServer(buddy);
|
||||
Services.contacts.accountBuddyAdded(buddy);
|
||||
},
|
||||
|
||||
hasBuddy: function(aName) {
|
||||
return this._buddies.has(aName);
|
||||
},
|
||||
|
||||
// Called for each buddy that is sent in a list packet from Yahoo! on login.
|
||||
addBuddyFromServer: function(aTag, aName) {
|
||||
let buddy;
|
||||
if (this._buddies.has(aName))
|
||||
buddy = this._buddies.get(aName);
|
||||
else {
|
||||
buddy = new YahooAccountBuddy(this, null, aTag, aName);
|
||||
Services.contacts.accountBuddyAdded(buddy);
|
||||
this._buddies.set(aName, buddy);
|
||||
}
|
||||
|
||||
// Set all new buddies as offline because a following status packet will
|
||||
// tell their status if they are online.
|
||||
buddy.setStatus(Ci.imIStatusInfo.STATUS_OFFLINE, "");
|
||||
|
||||
// Request the buddy's picture.
|
||||
this._session.requestBuddyIcon(aName);
|
||||
},
|
||||
|
||||
// Called when a user removes a contact from within Instantbird.
|
||||
removeBuddy: function(aBuddy, aRemoveFromServer) {
|
||||
if (aRemoveFromServer) {
|
||||
// We will remove the buddy locally when we get a server ack packet.
|
||||
this._session.removeBuddyFromServer(aBuddy);
|
||||
return;
|
||||
}
|
||||
|
||||
this._buddies.delete(aBuddy.userName);
|
||||
Services.contacts.accountBuddyRemoved(aBuddy);
|
||||
},
|
||||
|
||||
loadBuddy: function(aBuddy, aTag) {
|
||||
let buddy = new YahooAccountBuddy(this, aBuddy, aTag);
|
||||
this._buddies.set(buddy.userName, buddy);
|
||||
|
||||
return buddy;
|
||||
},
|
||||
|
||||
// Both the status and message can be defined, or only one can be defined.
|
||||
// When defining just the message, set aStatus to undefined.
|
||||
setBuddyStatus: function(aName, aStatus, aMessage) {
|
||||
if (!this._buddies.has(aName))
|
||||
return;
|
||||
let buddy = this._buddies.get(aName);
|
||||
// If the message is set as undefined, use the existing message.
|
||||
if (aMessage === undefined)
|
||||
aMessage = buddy.statusText;
|
||||
// If the status is undefined, use the existing status.
|
||||
if (aStatus === undefined)
|
||||
aStatus = buddy.statusType;
|
||||
buddy.setStatus(aStatus, aMessage);
|
||||
},
|
||||
|
||||
getBuddy: function(aName) {
|
||||
if (this._buddies.has(aName))
|
||||
return this._buddies.get(aName);
|
||||
return null;
|
||||
},
|
||||
|
||||
getOnlineBuddies: function() {
|
||||
let onlineBuddies = [];
|
||||
for (let buddy of this._buddies) {
|
||||
if (buddy[1].statusType != Ci.imIStatusInfo.STATUS_OFFLINE)
|
||||
onlineBuddies.push(buddy[1]);
|
||||
}
|
||||
return onlineBuddies;
|
||||
},
|
||||
|
||||
receiveMessage: function(aName, aMessage) {
|
||||
let conv;
|
||||
// Check if we have an existing converstaion open with this user. If not,
|
||||
// create one and add it to the list.
|
||||
if (!this._conversations.has(aName))
|
||||
conv = this.createConversation(aName);
|
||||
else
|
||||
conv = this._conversations.get(aName);
|
||||
|
||||
// Certain Yahoo clients, such as the official web client, sends formatted
|
||||
// messages, but the size value is the actual pt size, not the 1 - 7 size
|
||||
// expected from the HTML <font> tag. We replace it with the correct size.
|
||||
let message = this.decodeMessage(aMessage)
|
||||
.replace(/(<font[^>]+)size=\"(\d+)\"/g, this._fixFontSize);
|
||||
|
||||
conv.writeMessage(aName, message, {incoming: true});
|
||||
conv.updateTyping(Ci.prplIConvIM.NOT_TYPING, conv.name);
|
||||
},
|
||||
|
||||
receiveConferenceMessage: function(aName, aRoom, aMessage) {
|
||||
if (!this._conferences.has(aRoom))
|
||||
return;
|
||||
|
||||
this._conferences.get(aRoom).writeMessage(aName,
|
||||
this.decodeMessage(aMessage),
|
||||
{incoming: true});
|
||||
},
|
||||
|
||||
receiveTypingNotification: function(aName, aIsTyping) {
|
||||
if (!this._conversations.has(aName))
|
||||
return;
|
||||
|
||||
let conv = this._conversations.get(aName);
|
||||
if (aIsTyping)
|
||||
conv.updateTyping(Ci.prplIConvIM.TYPING, conv.name);
|
||||
else
|
||||
conv.updateTyping(Ci.prplIConvIM.NOT_TYPING, conv.name);
|
||||
},
|
||||
|
||||
encodeMessage: function(aMessage) {
|
||||
// Try to perform a convertion from JavaScript UTF-16 into the charset
|
||||
// specified in the options. If the conversion fails, just leave
|
||||
// the message as it is.
|
||||
let encodedMsg;
|
||||
try {
|
||||
encodedMsg = this._converter.ConvertFromUnicode(aMessage);
|
||||
} catch (e) {
|
||||
encodedMsg = aMessage;
|
||||
this.WARN("Could not encode UTF-16 message into " +
|
||||
this._converter.charset + ". Message: " + aMessage);
|
||||
}
|
||||
return encodedMsg;
|
||||
},
|
||||
|
||||
decodeMessage: function(aMessage) {
|
||||
// Try to perform a convertion from the charset specified in the options
|
||||
// to JavaScript UTF-16. If the conversion fails, just leave the message
|
||||
// as it is.
|
||||
let decodedMsg;
|
||||
try {
|
||||
decodedMsg = this._converter.ConvertToUnicode(aMessage);
|
||||
} catch (e) {
|
||||
decodedMsg = aMessage;
|
||||
this.WARN("Could not decode " + this._converter.charset +
|
||||
" message into UTF-16. Message: " + aMessage);
|
||||
}
|
||||
return decodedMsg;
|
||||
},
|
||||
|
||||
get canJoinChat() { return true; },
|
||||
chatRoomFields: {},
|
||||
joinChat: function(aComponents) {
|
||||
// Use _roomsCreated to append a unique number to the room name.
|
||||
let roomName = this.cleanUsername + "-" + ++this._roomsCreated;
|
||||
let conf = new YahooConference(this, roomName, this.cleanUsername);
|
||||
this._conferences.set(roomName, conf);
|
||||
this._session.createConference(roomName);
|
||||
},
|
||||
|
||||
// Callbacks.
|
||||
onLoginComplete: function() {
|
||||
// Now that we are connected, get ready to start to sending pings and
|
||||
// keepalive packets.
|
||||
this._keepAliveTimer = Cc["@mozilla.org/timer;1"]
|
||||
.createInstance(Ci.nsITimer);
|
||||
this._pingTimer = Cc["@mozilla.org/timer;1"]
|
||||
.createInstance(Ci.nsITimer);
|
||||
|
||||
// We use slack timers since we don't need millisecond precision when
|
||||
// sending the keepalive and ping packets.
|
||||
let s = this._session;
|
||||
this._keepAliveTimer
|
||||
.initWithCallback(s.sendKeepAlive.bind(s), kKeepAliveTimeout,
|
||||
this._keepAliveTimer.TYPE_REPEATING_SLACK);
|
||||
|
||||
this._pingTimer
|
||||
.initWithCallback(s.sendPing.bind(s), kPingTimeout,
|
||||
this._pingTimer.TYPE_REPEATING_SLACK);
|
||||
|
||||
},
|
||||
|
||||
// Private methods.
|
||||
|
||||
// This method is used to fix font sizes given by formatted messages. This
|
||||
// method is designed to be used as a method for a string replace() call.
|
||||
_fixFontSize: function(aMatch, aTagAttributes, aFontSize, aOffset, aString) {
|
||||
// Approximate the font size.
|
||||
let newSize;
|
||||
if (aFontSize <= 8)
|
||||
newSize = "1";
|
||||
else if (aFontSize <= 10)
|
||||
newSize = "2";
|
||||
else if (aFontSize <= 12)
|
||||
newSize = "3";
|
||||
else if (aFontSize <= 14)
|
||||
newSize = "4";
|
||||
else if (aFontSize <= 20)
|
||||
newSize = "5";
|
||||
else if (aFontSize <= 30)
|
||||
newSize = "6";
|
||||
else if (aFontSize <= 40)
|
||||
newSize = "7";
|
||||
else // If we get some gigantic size, just default to the standard 3 size.
|
||||
newSize = "3";
|
||||
|
||||
let sizeAttribute = "size=\"" + newSize + "\"";
|
||||
// We keep any preceding attributes, but replace the size attribute.
|
||||
return aTagAttributes + sizeAttribute;
|
||||
this.WARN("The legacy versions of Yahoo Messenger was disabled on August " +
|
||||
"5, 2016. It is currently not possible to connect to Yahoo " +
|
||||
"Messenger. See bug 1316000");
|
||||
this.reportDisconnecting(Ci.prplIAccount.ERROR_OTHER_ERROR,
|
||||
_("yahoo.disabled"));
|
||||
this.reportDisconnected();
|
||||
}
|
||||
};
|
||||
|
||||
function YahooProtocol() {
|
||||
this.registerCommands();
|
||||
}
|
||||
function YahooProtocol() {}
|
||||
YahooProtocol.prototype = {
|
||||
__proto__: GenericProtocolPrototype,
|
||||
// Protocol specific connection parameters.
|
||||
pagerRequestUrl: "http://scsa.msg.yahoo.com/capacity",
|
||||
loginTokenGetUrl: "https://login.yahoo.com/config/pwtoken_get",
|
||||
loginTokenLoginUrl: "https://login.yahoo.com/config/pwtoken_login",
|
||||
buildId: "4194239",
|
||||
|
||||
get id() { return "prpl-yahoo"; },
|
||||
get name() { return "Yahoo"; },
|
||||
get iconBaseURI() { return "chrome://prpl-yahoo/skin/"; },
|
||||
options: {
|
||||
port: {get label() { return _("options.pagerPort"); }, default: 5050},
|
||||
local_charset: {get label() { return _("options.chatEncoding"); }, default: "UTF-8"},
|
||||
ignore_invites: {get label() { return _("options.ignoreInvites"); }, default: false}
|
||||
},
|
||||
commands: [
|
||||
{
|
||||
name: "invite",
|
||||
get helpString() { return _("command.help.invite2", "invite"); },
|
||||
usageContext: Ci.imICommand.CMD_CONTEXT_ALL,
|
||||
run: function(aMsg, aConv) {
|
||||
if (aMsg.trim().length == 0)
|
||||
return false;
|
||||
|
||||
let splitPosition = aMsg.indexOf(" "); // Split at first space.
|
||||
let invitees;
|
||||
let message;
|
||||
|
||||
// If we have an invite message.
|
||||
if (splitPosition > 0) {
|
||||
invitees = aMsg.substring(0, splitPosition).split(",");
|
||||
message = aMsg.substring(splitPosition);
|
||||
} else {
|
||||
invitees = aMsg.split(",");
|
||||
message = _("conference.invite.message"); // Use default message.
|
||||
}
|
||||
|
||||
let conf = aConv.wrappedJSObject;
|
||||
conf._account._session.inviteToConference(invitees, conf._roomName,
|
||||
conf.getParticipantNames(),
|
||||
message);
|
||||
conf.writeMessage(conf._roomName,
|
||||
_("command.feedback.invite", invitees.join(", ")),
|
||||
{system: true, noLog: true});
|
||||
conf._account.LOG("Sending conference invite to " + invitees);
|
||||
return true;
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: "conference",
|
||||
get helpString() { return _("command.help.conference", "conference"); },
|
||||
usageContext: Ci.imICommand.CMD_CONTEXT_CHAT,
|
||||
run: function(aMsg, aConv) {
|
||||
aConv.account.joinChat(null);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
],
|
||||
getAccount: function(aImAccount) { return new YahooAccount(this, aImAccount); },
|
||||
classID: Components.ID("{50ea817e-5d79-4657-91ae-aa0a52bdb98c}")
|
||||
};
|
||||
|
|
|
@ -342,8 +342,7 @@
|
|||
msg = "<font face=\"" + style.fontFamily + "\">" + msg + "</font>";
|
||||
// MSN doesn't support font size info in messages...
|
||||
}
|
||||
else if (proto == "prpl-aim" || proto == "prpl-icq" ||
|
||||
proto == "prpl-yahoo" || proto == "prpl-yahoojp") {
|
||||
else if (proto == "prpl-aim" || proto == "prpl-icq") {
|
||||
let styleAttributes = ""
|
||||
if ("color" in style)
|
||||
styleAttributes += " color=\"" + style.color + "\"";
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
# Exceeding 4 protocols may cause scrolling. A list of the
|
||||
# available protocols can be found at
|
||||
# https://wiki.instantbird.org/Protocol_Identifiers
|
||||
topProtocol.list=prpl-gtalk,prpl-twitter,prpl-aim,prpl-yahoo,prpl-irc
|
||||
topProtocol.list=prpl-gtalk,prpl-twitter,prpl-aim,prpl-irc,prpl-xmpp
|
||||
|
||||
# LOCALIZATION NOTE
|
||||
# These are the descriptions of the top protocols specified above.
|
||||
|
@ -16,5 +16,5 @@ topProtocol.list=prpl-gtalk,prpl-twitter,prpl-aim,prpl-yahoo,prpl-irc
|
|||
topProtocol.prpl-gtalk.description=Talk to your Gmail contacts
|
||||
topProtocol.prpl-twitter.description=Stay up to date with your Twitter timeline
|
||||
topProtocol.prpl-aim.description=Chat with your buddies on AOL Instant Messenger
|
||||
topProtocol.prpl-yahoo.description=Chat with friends using Yahoo! Messenger
|
||||
topProtocol.prpl-irc.description=Join IRC channels
|
||||
topProtocol.prpl-xmpp.description=Chat using the open Jabber/XMPP protocol
|
||||
|
|
|
@ -7,5 +7,4 @@
|
|||
[include:chat/protocols/irc/test/xpcshell.ini]
|
||||
[include:chat/protocols/skype/test/xpcshell.ini]
|
||||
[include:chat/protocols/xmpp/test/xpcshell.ini]
|
||||
[include:chat/protocols/yahoo/test/xpcshell.ini]
|
||||
#[include:extensions/purple/purplexpcom/src/test/xpcshell.ini]
|
||||
|
|
|
@ -282,8 +282,7 @@
|
|||
msg = "<font face=\"" + style.fontFamily + "\">" + msg + "</font>";
|
||||
// MSN doesn't support font size info in messages...
|
||||
}
|
||||
else if (proto == "prpl-aim" || proto == "prpl-icq" ||
|
||||
proto == "prpl-yahoo" || proto == "prpl-yahoojp") {
|
||||
else if (proto == "prpl-aim" || proto == "prpl-icq") {
|
||||
let styleAttributes = ""
|
||||
if ("color" in style)
|
||||
styleAttributes += " color=\"" + style.color + "\"";
|
||||
|
|
Загрузка…
Ссылка в новой задаче