Merge remote-tracking branch 'origin' into 0.8

Conflicts:
	converse.js
	docs/CHANGES.rst
	index.html
This commit is contained in:
JC Brand 2014-02-23 02:54:35 +02:00
commit 1ce7620b88
36 changed files with 4183 additions and 883 deletions

View File

@ -29,7 +29,7 @@ It has the following features:
* Custom status messages * Custom status messages
* Typing notifications * Typing notifications
* Third person messages (/me ) * Third person messages (/me )
* Translated into multiple languages (af, de, es, fr, it, hu, pt-BR, ru) * Translated into multiple languages (af, de, en, es, fr, he, hu, id, it, ja, nl, pt_BR, ru)
* Off-the-record encryption support (via `OTR.js <http://arlolra.github.io/otr>`_) * Off-the-record encryption support (via `OTR.js <http://arlolra.github.io/otr>`_)
----------- -----------
@ -88,9 +88,16 @@ Licence
``Converse.js`` is released under both the MIT_ and GPL_ licenses. ``Converse.js`` is released under both the MIT_ and GPL_ licenses.
------ -------
Donate Support
------ -------
For support queries and discussions, please join the mailing list: conversejs@librelist.com
Issues can be logged on the `Github issue tracker <https://github.com/jcbrand/converse.js/issues>`_.
---------------------------------
Donations or tips are appreciated
---------------------------------
* Bitcoin: 16FsPqE9DhFTryxrUenpsGX4LJ1TPu8GqS * Bitcoin: 16FsPqE9DhFTryxrUenpsGX4LJ1TPu8GqS
* Litecoin: LLvLH6qJch7HAamLguHkwobCrxmHLhiwZw * Litecoin: LLvLH6qJch7HAamLguHkwobCrxmHLhiwZw

View File

@ -1,6 +1,6 @@
{ {
"name": "converse", "name": "converse",
"version": "0.7.2", "version": "0.7.3",
"devDependencies": { "devDependencies": {
"jasmine": "https://github.com/jcbrand/jasmine.git#1_3_x", "jasmine": "https://github.com/jcbrand/jasmine.git#1_3_x",
"otr": "0.2.7", "otr": "0.2.7",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -333,22 +333,18 @@ you can use the generic selector below, but it's slower:
span.spinner { span.spinner {
background: url(images/spinner.gif) no-repeat center; background: url(images/spinner.gif) no-repeat center;
width: 22px;
height: 22px; height: 22px;
padding: 0 2px 0 2px; padding: 0 2px 0 2px;
display: block; display: block;
} }
span.spinner.centered { span.spinner.centered {
position: absolute; text-align: center;
top: 30%; padding-top: 5em;
left: 50%;
margin: 0 0 0 -25%;
} }
span.spinner.hor_centered { span.spinner.hor_centered {
left: 40%; text-align: center;
position: absolute;
} }
#toggle-controlbox { #toggle-controlbox {
@ -1157,6 +1153,7 @@ ul.chat-toolbar li {
list-style: none; list-style: none;
padding: 0 3px 0 3px; padding: 0 3px 0 3px;
cursor: pointer; cursor: pointer;
margin-top: 1px;
} }
ul.chat-toolbar li:hover { ul.chat-toolbar li:hover {

View File

@ -141,9 +141,12 @@
this.allow_otr = true; this.allow_otr = true;
this.animate = true; this.animate = true;
this.auto_list_rooms = false; this.auto_list_rooms = false;
this.auto_reconnect = true;
this.auto_subscribe = false; this.auto_subscribe = false;
this.bosh_service_url = undefined; // The BOSH connection manager URL. this.bosh_service_url = undefined; // The BOSH connection manager URL.
this.cache_otr_key = false;
this.debug = false; this.debug = false;
this.expose_rid_and_sid = false;
this.hide_muc_server = false; this.hide_muc_server = false;
this.i18n = locales.en; this.i18n = locales.en;
this.prebind = false; this.prebind = false;
@ -152,6 +155,7 @@
this.show_call_button = false; this.show_call_button = false;
this.show_emoticons = true; this.show_emoticons = true;
this.show_toolbar = true; this.show_toolbar = true;
this.use_otr_by_default = false;
this.use_vcards = true; this.use_vcards = true;
this.xhr_custom_status = false; this.xhr_custom_status = false;
this.xhr_custom_status_url = ''; this.xhr_custom_status_url = '';
@ -166,22 +170,26 @@
'allow_otr', 'allow_otr',
'animate', 'animate',
'auto_list_rooms', 'auto_list_rooms',
'auto_reconnect',
'auto_subscribe', 'auto_subscribe',
'bosh_service_url', 'bosh_service_url',
'cache_otr_key',
'connection', 'connection',
'debug', 'debug',
'expose_rid_and_sid',
'fullname', 'fullname',
'hide_muc_server', 'hide_muc_server',
'i18n', 'i18n',
'jid', 'jid',
'prebind', 'prebind',
'rid', 'rid',
'show_call_button',
'show_controlbox_by_default', 'show_controlbox_by_default',
'show_emoticons', 'show_emoticons',
'show_only_online_users', 'show_only_online_users',
'show_toolbar', 'show_toolbar',
'show_call_button',
'sid', 'sid',
'use_otr_by_default',
'use_vcards', 'use_vcards',
'xhr_custom_status', 'xhr_custom_status',
'xhr_custom_status_url', 'xhr_custom_status_url',
@ -192,6 +200,9 @@
// Only allow OTR if we have the capability // Only allow OTR if we have the capability
this.allow_otr = this.allow_otr && HAS_CRYPTO; this.allow_otr = this.allow_otr && HAS_CRYPTO;
// Only use OTR by default if allow OTR is enabled to begin with
this.use_otr_by_default = this.use_otr_by_default && this.allow_otr;
// Translation machinery // Translation machinery
// --------------------- // ---------------------
var __ = $.proxy(function (str) { var __ = $.proxy(function (str) {
@ -249,13 +260,6 @@
// Module-level functions // Module-level functions
// ---------------------- // ----------------------
// TODO: REMOVE
this.createLinks = function (text) {
// Convert URLs into hyperlinks
var re = /((http|https|ftp):\/\/[\w?=&.\/\-;#~%\-]+(?![\w\s?&.\/;#~%"=\-]*>))/g;
return text.replace(re, '<a target="_blank" href="$1">$1</a>');
};
this.giveFeedback = function (message, klass) { this.giveFeedback = function (message, klass) {
$('.conn-feedback').text(message); $('.conn-feedback').text(message);
$('.conn-feedback').attr('class', 'conn-feedback'); $('.conn-feedback').attr('class', 'conn-feedback');
@ -322,41 +326,63 @@
); );
}; };
this.onConnect = function (status) { this.reconnect = function () {
var $button, $form; converse.giveFeedback(__('Reconnecting'), 'error');
if (status === Strophe.Status.CONNECTED) { if (!converse.prebind) {
converse.log('Connected'); this.connection.connect(
converse.onConnected(); this.connection.jid,
} else if (status === Strophe.Status.DISCONNECTED) { this.connection.pass,
$form = $('#converse-login'); function (status, condition) {
$button = $form.find('input[type=submit]'); converse.onConnect(status, condition, true);
if ($button) { $button.show().siblings('span').remove(); } },
converse.giveFeedback(__('Disconnected'), 'error'); this.connection.wait,
converse.connection.connect( this.connection.hold,
converse.connection.jid, this.connection.route
converse.connection.pass,
converse.onConnect
); );
}
};
this.showLoginButton = function () {
var view = converse.chatboxesview.views.controlbox;
if (typeof view.loginpanel !== 'undefined') {
view.loginpanel.showLoginButton();
}
};
this.onConnect = function (status, condition, reconnect) {
var $button, $form;
if ((status === Strophe.Status.CONNECTED) ||
(status === Strophe.Status.ATTACHED)) {
if ((typeof reconnect !== 'undefined') && (reconnect)) {
converse.log(status === Strophe.Status.CONNECTED ? 'Reconnected' : 'Reattached');
converse.onReconnected();
} else {
converse.log(status === Strophe.Status.CONNECTED ? 'Connected' : 'Attached');
converse.onConnected();
}
} else if (status === Strophe.Status.DISCONNECTED) {
// TODO: Handle case where user manually logs out...
converse.giveFeedback(__('Disconnected'), 'error');
if (converse.auto_reconnect) {
converse.reconnect();
} else {
converse.showLoginButton();
}
} else if (status === Strophe.Status.Error) { } else if (status === Strophe.Status.Error) {
$form = $('#converse-login'); converse.showLoginButton();
$button = $form.find('input[type=submit]');
if ($button) { $button.show().siblings('span').remove(); }
converse.giveFeedback(__('Error'), 'error'); converse.giveFeedback(__('Error'), 'error');
} else if (status === Strophe.Status.CONNECTING) { } else if (status === Strophe.Status.CONNECTING) {
converse.giveFeedback(__('Connecting')); converse.giveFeedback(__('Connecting'));
} else if (status === Strophe.Status.CONNFAIL) { } else if (status === Strophe.Status.CONNFAIL) {
converse.chatboxesview.views.controlbox.trigger('connection-fail'); converse.showLoginButton();
converse.giveFeedback(__('Connection Failed'), 'error'); converse.giveFeedback(__('Connection Failed'), 'error');
} else if (status === Strophe.Status.AUTHENTICATING) { } else if (status === Strophe.Status.AUTHENTICATING) {
converse.giveFeedback(__('Authenticating')); converse.giveFeedback(__('Authenticating'));
} else if (status === Strophe.Status.AUTHFAIL) { } else if (status === Strophe.Status.AUTHFAIL) {
converse.chatboxesview.views.controlbox.trigger('auth-fail'); converse.showLoginButton();
converse.giveFeedback(__('Authentication Failed'), 'error'); converse.giveFeedback(__('Authentication Failed'), 'error');
} else if (status === Strophe.Status.DISCONNECTING) { } else if (status === Strophe.Status.DISCONNECTING) {
converse.giveFeedback(__('Disconnecting'), 'error'); converse.giveFeedback(__('Disconnecting'), 'error');
} else if (status === Strophe.Status.ATTACHED) {
converse.log('Attached');
converse.onConnected();
} }
}; };
@ -381,7 +407,7 @@
this.parseISO8601 = function (datestr) { this.parseISO8601 = function (datestr) {
/* Parses string formatted as 2013-02-14T11:27:08.268Z to a Date obj. /* Parses string formatted as 2013-02-14T11:27:08.268Z to a Date obj.
*/ */
    var numericKeys = [1, 4, 5, 6, 7, 10, 11], var numericKeys = [1, 4, 5, 6, 7, 10, 11],
struct = /^\s*(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}\.?\d*)Z\s*$/.exec(datestr), struct = /^\s*(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}\.?\d*)Z\s*$/.exec(datestr),
minutesOffset = 0, minutesOffset = 0,
i, k; i, k;
@ -434,32 +460,81 @@
this.xmppstatus.fetch({success: callback, error: callback}); this.xmppstatus.fetch({success: callback, error: callback});
}; };
this.initRoster = function () { this.registerRosterHandler = function () {
// Set up the roster // Register handlers that depend on the roster
this.roster = new this.RosterItems();
this.roster.localStorage = new Backbone.LocalStorage(
hex_sha1('converse.rosteritems-'+converse.bare_jid));
// Register callbacks that depend on the roster
this.connection.roster.registerCallback( this.connection.roster.registerCallback(
$.proxy(this.roster.rosterHandler, this.roster), $.proxy(this.roster.rosterHandler, this.roster),
null, 'presence', null); null, 'presence', null);
};
this.registerRosterXHandler = function () {
this.connection.addHandler( this.connection.addHandler(
$.proxy(this.roster.subscribeToSuggestedItems, this.roster), $.proxy(this.roster.subscribeToSuggestedItems, this.roster),
'http://jabber.org/protocol/rosterx', 'message', null); 'http://jabber.org/protocol/rosterx', 'message', null);
};
this.registerPresenceHandler = function () {
this.connection.addHandler( this.connection.addHandler(
$.proxy(function (presence) { $.proxy(function (presence) {
this.presenceHandler(presence); this.presenceHandler(presence);
return true; return true;
}, this.roster), null, 'presence', null); }, this.roster), null, 'presence', null);
};
this.initRoster = function () {
// Set up the roster
this.roster = new this.RosterItems();
this.roster.localStorage = new Backbone.LocalStorage(
hex_sha1('converse.rosteritems-'+converse.bare_jid));
this.registerRosterHandler();
this.registerRosterXHandler();
this.registerPresenceHandler();
// No create the view which will fetch roster items from // No create the view which will fetch roster items from
// localStorage // localStorage
this.rosterview = new this.RosterView({'model':this.roster}); this.rosterview = new this.RosterView({'model':this.roster});
}; };
this.registerGlobalEventHandlers = function () {
$(document).click(function() {
if ($('.toggle-otr ul').is(':visible')) {
$('.toggle-otr ul', this).slideUp();
}
if ($('.toggle-smiley ul').is(':visible')) {
$('.toggle-smiley ul', this).slideUp();
}
});
$(document).on('mousemove', $.proxy(function (ev) {
if (!this.resized_chatbox || !this.allow_dragresize) { return true; }
ev.preventDefault();
this.resized_chatbox.resizeChatbox(ev);
}, this));
$(document).on('mouseup', $.proxy(function (ev) {
if (!this.resized_chatbox || !this.allow_dragresize) { return true; }
this.resized_chatbox = null;
}, this));
$(window).on("blur focus", $.proxy(function(e) {
if ((this.windowState != e.type) && (e.type == 'focus')) {
converse.clearMsgCounter();
}
this.windowState = e.type;
},this));
};
this.onReconnected = function () {
// We need to re-register all the event handlers on the newly
// created connection.
this.initStatus($.proxy(function () {
this.registerRosterXHandler();
this.registerPresenceHandler();
this.chatboxes.registerMessageHandler();
converse.xmppstatus.sendPresence();
this.giveFeedback(__('Online Contacts'));
}, this));
};
this.onConnected = function () { this.onConnected = function () {
if (this.debug) { if (this.debug) {
this.connection.xmlInput = function (body) { console.log(body); }; this.connection.xmlInput = function (body) { console.log(body); };
@ -474,32 +549,7 @@
this.initRoster(); this.initRoster();
this.chatboxes.onConnected(); this.chatboxes.onConnected();
this.connection.roster.get(function () {}); this.connection.roster.get(function () {});
$(document).click(function() { this.registerGlobalEventHandlers();
if ($('.toggle-otr ul').is(':visible')) {
$('.toggle-otr ul', this).slideUp();
}
if ($('.toggle-smiley ul').is(':visible')) {
$('.toggle-smiley ul', this).slideUp();
}
});
$(document).on('mousemove', $.proxy(function (ev) {
if (!this.resized_chatbox || !this.allow_dragresize) { return true; }
ev.preventDefault();
this.resized_chatbox.resizeChatbox(ev);
}, this));
$(document).on('mouseup', $.proxy(function (ev) {
if (!this.resized_chatbox || !this.allow_dragresize) { return true; }
this.resized_chatbox = null;
}, this));
$(window).on("blur focus", $.proxy(function (e) {
if ((this.windowState != e.type) && (e.type == 'focus')) {
converse.clearMsgCounter();
}
this.windowState = e.type;
},this));
this.giveFeedback(__('Online Contacts')); this.giveFeedback(__('Online Contacts'));
if (this.callback) { if (this.callback) {
@ -524,6 +574,41 @@
// Backbone Models and Views // Backbone Models and Views
// ------------------------- // -------------------------
this.OTR = Backbone.Model.extend({
// A model for managing OTR settings.
getSessionPassphrase: function () {
if (converse.prebind) {
var key = hex_sha1(converse.connection.jid),
pass = window.sessionStorage[key];
if (typeof pass === 'undefined') {
pass = Math.floor(Math.random()*4294967295).toString();
window.sessionStorage[key] = pass;
}
return pass;
} else {
return converse.connection.pass;
}
},
generatePrivateKey: function () {
var key = new DSA();
var jid = converse.connection.jid;
if (converse.cache_otr_key) {
var cipher = CryptoJS.lib.PasswordBasedCipher;
var pass = this.getSessionPassphrase();
if (typeof pass !== "undefined") {
// Encrypt the key and set in sessionStorage. Also store instance tag.
window.sessionStorage[hex_sha1(jid+'priv_key')] =
cipher.encrypt(CryptoJS.algo.AES, key.packPrivate(), pass).toString();
window.sessionStorage[hex_sha1(jid+'instance_tag')] = instance_tag;
window.sessionStorage[hex_sha1(jid+'pass_check')] =
cipher.encrypt(CryptoJS.algo.AES, 'match', pass).toString();
}
}
return key;
}
});
this.Message = Backbone.Model.extend(); this.Message = Backbone.Model.extend();
this.Messages = Backbone.Collection.extend({ this.Messages = Backbone.Collection.extend({
@ -533,9 +618,6 @@
this.ChatBox = Backbone.Model.extend({ this.ChatBox = Backbone.Model.extend({
initialize: function () { initialize: function () {
if (this.get('box_id') !== 'controlbox') { if (this.get('box_id') !== 'controlbox') {
if (_.contains([UNVERIFIED, VERIFIED], this.get('otr_status'))) {
this.initiateOTR();
}
this.messages = new converse.Messages(); this.messages = new converse.Messages();
this.messages.localStorage = new Backbone.LocalStorage( this.messages.localStorage = new Backbone.LocalStorage(
hex_sha1('converse.messages'+this.get('jid')+converse.bare_jid)); hex_sha1('converse.messages'+this.get('jid')+converse.bare_jid));
@ -547,43 +629,43 @@
} }
}, },
getSession: function () { getSession: function (callback) {
// XXX: sessionStorage is not supported in IE < 8. Perhaps a
// user alert is required here...
var saved_key = window.sessionStorage[hex_sha1(this.id+'priv_key')];
var instance_tag = window.sessionStorage[hex_sha1(this.id+'instance_tag')];
var cipher = CryptoJS.lib.PasswordBasedCipher; var cipher = CryptoJS.lib.PasswordBasedCipher;
var pass = converse.connection.pass; var result, pass, instance_tag, saved_key, pass_check;
var pass_check = this.get('pass_check'); if (converse.cache_otr_key) {
var result, key; pass = converse.otr.getSessionPassphrase();
if (saved_key && instance_tag && typeof pass_check !== 'undefined') { if (typeof pass !== "undefined") {
var decrypted = cipher.decrypt(CryptoJS.algo.AES, saved_key, pass); instance_tag = window.sessionStorage[hex_sha1(this.id+'instance_tag')];
key = DSA.parsePrivate(decrypted.toString(CryptoJS.enc.Latin1)); saved_key = window.sessionStorage[hex_sha1(this.id+'priv_key')];
if (cipher.decrypt(CryptoJS.algo.AES, pass_check, pass).toString(CryptoJS.enc.Latin1) === 'match') { pass_check = window.sessionStorage[hex_sha1(this.connection.jid+'pass_check')];
// Verified that the user's password is still the same if (saved_key && instance_tag && typeof pass_check !== 'undefined') {
this.trigger('showHelpMessages', [__('Re-establishing encrypted session')]); var decrypted = cipher.decrypt(CryptoJS.algo.AES, saved_key, pass);
return { var key = DSA.parsePrivate(decrypted.toString(CryptoJS.enc.Latin1));
'key': key, if (cipher.decrypt(CryptoJS.algo.AES, pass_check, pass).toString(CryptoJS.enc.Latin1) === 'match') {
'instance_tag': instance_tag // Verified that the passphrase is still the same
}; this.trigger('showHelpMessages', [__('Re-establishing encrypted session')]);
callback({
'key': key,
'instance_tag': instance_tag
});
return; // Our work is done here
}
}
} }
} }
// We need to generate a new key and instance tag // We need to generate a new key and instance tag
result = alert(__('Your browser needs to generate a private key, which will be used in your encrypted chat session. This can take up to 30 seconds during which your browser might freeze and become unresponsive.')); this.trigger('showHelpMessages', [
instance_tag = OTR.makeInstanceTag(); __('Generating private key.'),
key = new DSA(); __('Your browser might become unresponsive.')],
// Encrypt the key and set in sessionStorage. Also store null,
// instance tag true // show spinner
window.sessionStorage[hex_sha1(this.id+'priv_key')] = );
cipher.encrypt(CryptoJS.algo.AES, key.packPrivate(), pass).toString(); setTimeout(function () {
window.sessionStorage[hex_sha1(this.id+'instance_tag')] = instance_tag; callback({
'key': converse.otr.generatePrivateKey.apply(this),
this.trigger('showHelpMessages', [__('Private key generated.')]); 'instance_tag': OTR.makeInstanceTag()
this.save({'pass_check': cipher.encrypt(CryptoJS.algo.AES, 'match', pass).toString()}); });
return { }, 500);
'key': key,
'instance_tag': instance_tag
};
}, },
updateOTRStatus: function (state) { updateOTRStatus: function (state) {
@ -636,32 +718,34 @@
// query message from our buddy. Otherwise, it is us who will // query message from our buddy. Otherwise, it is us who will
// send the query message to them. // send the query message to them.
this.save({'otr_status': UNENCRYPTED}); this.save({'otr_status': UNENCRYPTED});
var session = this.getSession(); var session = this.getSession($.proxy(function (session) {
this.otr = new OTR({ this.otr = new OTR({
fragment_size: 140, fragment_size: 140,
send_interval: 200, send_interval: 200,
priv: session.key, priv: session.key,
instance_tag: session.instance_tag, instance_tag: session.instance_tag,
debug: this.debug debug: this.debug
}); });
this.otr.on('status', $.proxy(this.updateOTRStatus, this)); this.otr.on('status', $.proxy(this.updateOTRStatus, this));
this.otr.on('smp', $.proxy(this.onSMP, this)); this.otr.on('smp', $.proxy(this.onSMP, this));
this.otr.on('ui', $.proxy(function (msg) { this.otr.on('ui', $.proxy(function (msg) {
this.trigger('showReceivedOTRMessage', msg); this.trigger('showReceivedOTRMessage', msg);
}, this)); }, this));
this.otr.on('io', $.proxy(function (msg) { this.otr.on('io', $.proxy(function (msg) {
this.trigger('sendMessageStanza', msg); this.trigger('sendMessageStanza', msg);
}, this)); }, this));
this.otr.on('error', $.proxy(function (msg) { this.otr.on('error', $.proxy(function (msg) {
this.trigger('showOTRError', msg); this.trigger('showOTRError', msg);
}, this)); }, this));
if (query_msg) { this.trigger('showHelpMessages', [__('Exchanging private key with buddy.')]);
this.otr.receiveMsg(query_msg); if (query_msg) {
} else { this.otr.receiveMsg(query_msg);
this.otr.sendQueryMsg(); } else {
} this.otr.sendQueryMsg();
}
}, this));
}, },
endOTR: function () { endOTR: function () {
@ -719,19 +803,22 @@
if ((!text) || (!converse.allow_otr)) { if ((!text) || (!converse.allow_otr)) {
return this.createMessage(message); return this.createMessage(message);
} }
if (_.contains([UNVERIFIED, VERIFIED], this.get('otr_status'))) { if (text.match(/^\?OTRv23?/)) {
this.otr.receiveMsg(text); this.initiateOTR(text);
} else { } else {
if (text.match(/^\?OTR/)) { if (_.contains([UNVERIFIED, VERIFIED], this.get('otr_status'))) {
// They want to initiate OTR this.otr.receiveMsg(text);
if (!this.otr) {
this.initiateOTR(text);
} else {
this.otr.receiveMsg(text);
}
} else { } else {
// Normal unencrypted message. if (text.match(/^\?OTR/)) {
this.createMessage(message); if (!this.otr) {
this.initiateOTR(text);
} else {
this.otr.receiveMsg(text);
}
} else {
// Normal unencrypted message.
this.createMessage(message);
}
} }
} }
} }
@ -775,13 +862,19 @@
this.updateVCard(); this.updateVCard();
this.$el.appendTo(converse.chatboxesview.$el); this.$el.appendTo(converse.chatboxesview.$el);
this.render().show().model.messages.fetch({add: true}); this.render().show().model.messages.fetch({add: true});
if (this.model.get('status')) { if (this.model.get('status')) {
this.showStatusMessage(this.model.get('status')); this.showStatusMessage(this.model.get('status'));
} }
// Drag to resize values // Drag to resize values
this.chatboxMinHeight = 250; this.chatboxMinHeight = 250;
this.chatboxHeight = this.$el.children('.box-flyout').height(); this.chatboxHeight = this.$el.children('.box-flyout').height();
this.prevPageY = 0; // To store last known mouse position this.prevPageY = 0; // To store last known mouse position
if ((_.contains([UNVERIFIED, VERIFIED], this.model.get('otr_status'))) || converse.use_otr_by_default) {
this.model.initiateOTR();
}
}, },
render: function () { render: function () {
@ -853,12 +946,17 @@
return this.scrollDown(); return this.scrollDown();
}, },
showHelpMessages: function (msgs, type) { showHelpMessages: function (msgs, type, spinner) {
var $chat_content = this.$el.find('.chat-content'), i, var $chat_content = this.$el.find('.chat-content'), i,
msgs_length = msgs.length; msgs_length = msgs.length;
for (i=0; i<msgs_length; i++) { for (i=0; i<msgs_length; i++) {
$chat_content.append($('<div class="chat-'+(type||'info')+'">'+msgs[i]+'</div>')); $chat_content.append($('<div class="chat-'+(type||'info')+'">'+msgs[i]+'</div>'));
} }
if (spinner === true) {
$chat_content.append('<span class="spinner"/>');
} else if (spinner === false) {
$chat_content.find('span.spinner').remove();
}
return this.scrollDown(); return this.scrollDown();
}, },
@ -1094,7 +1192,7 @@
this.model.save({'otr_status': UNVERIFIED}); this.model.save({'otr_status': UNVERIFIED});
} }
} else if (scheme === 'smp') { } else if (scheme === 'smp') {
alert(__('You will be prompted to provide a security question and then an answer to that question.\n\nYour buddy will then be prompted the same question and if they type the exact same answer (case sensitive), their identity will have been verified.')); alert(__('You will be prompted to provide a security question and then an answer to that question.\n\nYour buddy will then be prompted the same question and if they type the exact same answer (case sensitive), their identity will be verified.'));
question = prompt(__('What is your security question?')); question = prompt(__('What is your security question?'));
if (question) { if (question) {
answer = prompt(__('What is the answer to the security question?')); answer = prompt(__('What is the answer to the security question?'));
@ -1218,7 +1316,7 @@
} else if (data.otr_status == FINISHED){ } else if (data.otr_status == FINISHED){
msgs.push(__("Your buddy has ended encryption on their end, you should do the same.")); msgs.push(__("Your buddy has ended encryption on their end, you should do the same."));
} }
return this.showHelpMessages(msgs); return this.showHelpMessages(msgs, 'info', false);
}, },
renderToolbar: function () { renderToolbar: function () {
@ -2254,6 +2352,17 @@
this.ChatBoxes = Backbone.Collection.extend({ this.ChatBoxes = Backbone.Collection.extend({
model: converse.ChatBox, model: converse.ChatBox,
registerMessageHandler: function () {
// TODO: Make this method global to converse, trigger an event
// and let messageReceived be called via a handler for that
// event.
converse.connection.addHandler(
$.proxy(function (message) {
this.messageReceived(message);
return true;
}, this), null, 'message', 'chat');
},
onConnected: function () { onConnected: function () {
this.localStorage = new Backbone.LocalStorage( this.localStorage = new Backbone.LocalStorage(
hex_sha1('converse.chatboxes-'+converse.bare_jid)); hex_sha1('converse.chatboxes-'+converse.bare_jid));
@ -2265,16 +2374,9 @@
} else { } else {
this.get('controlbox').save(); this.get('controlbox').save();
} }
// This will make sure the Roster is set up // This line below will make sure the Roster is set up
this.get('controlbox').set({connected:true}); this.get('controlbox').set({connected:true});
this.registerMessageHandler();
// Register message handler
converse.connection.addHandler(
$.proxy(function (message) {
this.messageReceived(message);
return true;
}, this), null, 'message', 'chat');
// Get cached chatboxes from localstorage // Get cached chatboxes from localstorage
this.fetch({ this.fetch({
add: true, add: true,
@ -2728,8 +2830,7 @@
}, this), }, this),
$.proxy(function (jid, fullname, img, img_type, url) { $.proxy(function (jid, fullname, img, img_type, url) {
converse.log("Error while retrieving vcard"); converse.log("Error while retrieving vcard");
// XXX: Should vcard_updated be set here as // XXX: Should vcard_updated be set here as well?
// well?
this.add({ this.add({
jid: bare_jid, jid: bare_jid,
subscription: 'none', subscription: 'none',
@ -2752,8 +2853,6 @@
var $presence = $(presence), var $presence = $(presence),
presence_type = $presence.attr('type'); presence_type = $presence.attr('type');
if (presence_type === 'error') { if (presence_type === 'error') {
// TODO
// error presence stanzas don't necessarily have a 'from' attr.
return true; return true;
} }
var jid = $presence.attr('from'), var jid = $presence.attr('from'),
@ -3089,7 +3188,7 @@
} else if (stat === 'away') { } else if (stat === 'away') {
pretty_status = __('away'); pretty_status = __('away');
} else { } else {
pretty_status = __(stat) || __('online'); // XXX: Is 'online' the right default choice here? pretty_status = __(stat) || __('online');
} }
return pretty_status; return pretty_status;
}, },
@ -3208,7 +3307,7 @@
converse.connection.connect(jid, password, converse.onConnect); converse.connection.connect(jid, password, converse.onConnect);
}, },
showConnectButton: function () { showLoginButton: function () {
var $form = this.$el.find('#converse-login'); var $form = this.$el.find('#converse-login');
var $button = $form.find('input[type=submit]'); var $button = $form.find('input[type=submit]');
if ($button.length) { if ($button.length) {
@ -3225,8 +3324,6 @@
}) })
)); ));
this.$tabs = cfg.$parent.parent().find('#controlbox-tabs'); this.$tabs = cfg.$parent.parent().find('#controlbox-tabs');
this.model.on('connection-fail', function () { this.showConnectButton(); }, this);
this.model.on('auth-fail', function () { this.showConnectButton(); }, this);
}, },
render: function () { render: function () {
@ -3340,6 +3437,7 @@
this.chatboxes = new this.ChatBoxes(); this.chatboxes = new this.ChatBoxes();
this.chatboxesview = new this.ChatBoxesView({model: this.chatboxes}); this.chatboxesview = new this.ChatBoxesView({model: this.chatboxes});
this.controlboxtoggle = new this.ControlBoxToggle(); this.controlboxtoggle = new this.ControlBoxToggle();
this.otr = new this.OTR();
if ((this.prebind) && (!this.connection)) { if ((this.prebind) && (!this.connection)) {
if ((!this.jid) || (!this.sid) || (!this.rid) || (!this.bosh_service_url)) { if ((!this.jid) || (!this.sid) || (!this.rid) || (!this.bosh_service_url)) {
@ -3358,6 +3456,18 @@
'initialize': function (settings, callback) { 'initialize': function (settings, callback) {
converse.initialize(settings, callback); converse.initialize(settings, callback);
}, },
'getRID': function () {
if (converse.expose_rid_and_sid && typeof converse.connection !== "undefined") {
return converse.connection.rid;
}
return null;
},
'getSID': function () {
if (converse.expose_rid_and_sid && typeof converse.connection !== "undefined") {
return converse.connection.sid;
}
return null;
},
'once': function(evt, handler) { 'once': function(evt, handler) {
converse.once(evt, handler); converse.once(evt, handler);
}, },

2
converse.min.css vendored

File diff suppressed because one or more lines are too long

View File

@ -7,11 +7,16 @@ Changelog
* Chat boxes and rooms can now be resized vertically. [jcbrand] * Chat boxes and rooms can now be resized vertically. [jcbrand]
* Chat boxes and rooms can be minimized. [jcbrand] * Chat boxes and rooms can be minimized. [jcbrand]
0.7.3 (Unreleased) 0.7.3 (2014-02-23)
------------------ ------------------
* Option to display a call button in the chatbox toolbar, to allow third-party libraries to provide a calling feature. [Aupajo] * #93 Add API methods exposing the RID and SID values. Can be disabled. [jcbrand]
* #108 Japanese Translations. [mako09] * #102 Option to enable OTR by default. [Aupajo]
* #103 Option to display a call button in the chatbox toolbar, to allow third-party libraries to provide a calling feature. [Aupajo]
* #108 Japanese Translations [mako09]
* #111 OTR not working when using converse.js with prebinding. [jseidl, jcbrand]
* #114, #124 Hewbrew Translations [GreenLunar]
* #115 Indonesian Translations [priyadi]
0.7.2 (2013-12-18) 0.7.2 (2013-12-18)
------------------ ------------------

Binary file not shown.

View File

@ -1,4 +1,4 @@
# Sphinx build info version 1 # Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: 652c197d955de4d2c90bb99dc6534a15 config: 738ca7b60aed811ee1668ad08d26eabb
tags: fbb0d17656682115ca4d033fb2f83ba1 tags: fbb0d17656682115ca4d033fb2f83ba1

View File

@ -277,6 +277,17 @@ These values are then passed to converse.js's ``initialize`` method.
**bosh_service_url** values. **bosh_service_url** values.
Example code for server-side prebinding
---------------------------------------
* PHP:
See `xmpp-prebind-php <https://github.com/candy-chat/xmpp-prebind-php>`_ by
Michael Weibel and the folks from Candy chat.
* Python:
See this `example Django application`_ by Jack Moffitt.
Setting up a BOSH server Setting up a BOSH server
------------------------ ------------------------
@ -295,7 +306,6 @@ Facebook integration
this myself. Feedback and patches from people who have succesfully done this this myself. Feedback and patches from people who have succesfully done this
will be appreciated. will be appreciated.
Converse.js uses `Strophe.js <http://strophe.im/strophejs>`_ to connect and Converse.js uses `Strophe.js <http://strophe.im/strophejs>`_ to connect and
communicate with the XMPP server. One nice thing about Strophe.js is that it communicate with the XMPP server. One nice thing about Strophe.js is that it
can be extended via `plugins <http://github.com/strophe/strophejs-plugins>`_. can be extended via `plugins <http://github.com/strophe/strophejs-plugins>`_.
@ -339,6 +349,39 @@ The connection is already created inside Converse.js, so the
If someone submits a sane patch that does the above, I'll be happy to merge it. If someone submits a sane patch that does the above, I'll be happy to merge it.
Until then, people will have to do this themselves. Until then, people will have to do this themselves.
========
Features
========
Off-the-record encryption
=========================
Converse.js supports `Off-the-record (OTR) <https://otr.cypherpunks.ca/>`_
encrypted messaging.
The OTR protocol not only **encrypts your messages**, it provides ways to
**verify the identity** of the person you are talking to,
**plausible deniability** and **perfect forward secrecy** by generating
new encryption keys for each conversation.
In its current state, Javascript cryptography is fraught with dangers and
challenges that make it impossible to reach the same standard of security that
is available with native "desktop" software.
This is due to its runtime malleability, the way it is "installed" (e.g.
served) and the browser's lack of cryptographic primitives needed to implement
secure crypto.
For harsh but fairly valid criticism of Javascript cryptography, read:
`Javascript Cryptography Considered Harmful <http://www.matasano.com/articles/javascript-cryptography/>`_.
To get an idea on how this applies to OTR support in Converse.js, please read
`my thoughts on it <https://opkode.com/media/blog/2013/11/11/conversejs-otr-support>`_.
For now, suffice to say that although its useful to have OTR support in
Converse.js in order to avoid most eavesdroppers, if you need serious
communications privacy, then you're much better off using native software.
=========== ===========
Development Development
=========== ===========
@ -387,6 +430,7 @@ If you don't have grunt installed globally, you need to specify the relative
path: path:
:: ::
./node_modules/.bin/grunt fetch ./node_modules/.bin/grunt fetch
This will call Bower in the background to fetch all the front-end This will call Bower in the background to fetch all the front-end
@ -467,6 +511,137 @@ You can run both the tests and jshint in one go by calling:
grunt check grunt check
Minification
============
Minifying Javascript and CSS
----------------------------
Please make sure to read the section `Development`_ and that you have installed
all development dependencies (long story short, you can run ``npm install``
and then ``grunt fetch``).
We use `require.js`_ to keep track of *Converse.js* and its dependencies and to
to bundle them together in a single minified file fit for deployment to a
production site.
To minify the Javascript and CSS, run the following command:
::
grunt minify
Javascript will be bundled and minified with `require.js`_'s optimization tool,
using `almond <https://github.com/jrburke/almond>`_.
You can `read more about require.js's optimizer here`_.
CSS is minified via `cssmin <https://github.com/gruntjs/grunt-contrib-cssmin>`_.
Translations
============
.. Note ::
Translations take up a lot of space and will bloat your minified file.
At the time of writing, all the translations add about 50KB of extra data to
the minified javascript file. Therefore, make sure to only
include those languages that you intend to support and remove from
./locale/locales.js those which you don't need. Remember to rebuild the
minified file afterwards.
The gettext POT file located in ./locale/converse.pot is the template
containing all translations and from which for each language an individual PO
file is generated.
The POT file contains all translateable strings extracted from converse.js.
To make a user facing string translateable, wrap it in the double underscore helper
function like so:
::
__('This string will be translated at runtime');
After adding the string, you'll need to regenerate the POT file, like so:
::
make pot
You can then create or update the PO file for a specific language by doing the following:
::
msgmerge ./locale/de/LC_MESSAGES/converse.po ./locale/converse.pot -U
To do this for ALL languages, run:
::
make merge
The resulting PO file is then what gets translated.
If you've created a new PO file, please make sure to add the following
attributes at the top of the file (under *Content-Transfer-Encoding*). They are
required as configuration settings for Jed, the Javascript translations library
that we're using.
::
"domain: converse\n"
"lang: de\n"
"plural_forms: nplurals=2; plural=(n != 1);\n"
Unfortunately `Jed <http://slexaxton.github.io/Jed>`_ cannot use the PO files directly. We have to generate from it
a file in JSON format and then put that in a .js file for the specific
language.
To generate JSON from a PO file, you'll need po2json for node.js. Run the
following command to install it (npm being the node.js package manager):
::
npm install po2json
You can then convert the translations into JSON format:
::
po2json locale/de/LC_MESSAGES/converse.po locale/de/LC_MESSAGES/converse.json
Now from converse.json paste the data as a value for the "locale_data" key in the
object in the language's .js file.
So, if you are for example translating into German (language code 'de'), you'll
create or update the file ./locale/LC_MESSAGES/de.js with the following code:
::
(function (root, factory) {
define("de", ['jed'], function () {
return factory(new Jed({
"domain": "converse",
"locale_data": {
// Paste the JSON data from converse.json here
}
})
}
}(this, function (i18n) {
return i18n;
}));
making sure to also paste the JSON data as value to the "locale_data" key.
.. Note ::
If you are adding translations for a new language that is not already supported,
you'll have to make one more edit in ./locale/locales.js to make sure the
language is loaded by require.js.
Congratulations, you've now succesfully added your translations. Sorry for all
those hoops you had to jump through.
=============== ===============
Troubleshooting Troubleshooting
@ -736,6 +911,14 @@ For each room on the server a query is made to fetch further details (e.g.
features, number of occupants etc.), so on servers with many rooms this features, number of occupants etc.), so on servers with many rooms this
option will create lots of extra connection traffic. option will create lots of extra connection traffic.
auto_reconnect
--------------
Default = ``true``
Automatically reconnect to the XMPP server if the connection drops
unexpectedly.
auto_subscribe auto_subscribe
-------------- --------------
@ -751,6 +934,30 @@ a middle man between HTTP and XMPP.
See `here <http://metajack.im/2008/09/08/which-bosh-server-do-you-need>`_ for more information. See `here <http://metajack.im/2008/09/08/which-bosh-server-do-you-need>`_ for more information.
cache_otr_key
-------------
Default = ``false``
Let the `OTR (Off-the-record encryption) <https://otr.cypherpunks.ca>`_ private
key be cached in your browser's session storage.
The browser's session storage persists across page loads but is deleted once
the tab or window is closed.
If this option is set to ``false``, a new OTR private key will be generated
for each page load. While more inconvenient, this is a much more secure option.
This setting can only be used together with ``allow_otr = true``.
.. Note ::
A browser window's session storage is accessible by all javascript that
is served from the same domain. So if there is malicious javascript served by
the same server (or somehow injected via an attacker), then they will be able
to retrieve your private key and read your all the chat messages in your
current session. Previous sessions however cannot be decrypted.
debug debug
----- -----
@ -758,6 +965,16 @@ Default = ``false``
If set to true, debugging output will be logged to the browser console. If set to true, debugging output will be logged to the browser console.
expose_rid_and_sid
------------------
Allow the prebind tokens, RID (request ID) and SID (session ID), to be exposed
globally via the API. This allows other scripts served on the same page to use
these values.
*Beware*: a malicious script could use these tokens to assume your identity
and inject fake chat messages.
fullname fullname
-------- --------
@ -813,6 +1030,28 @@ the page with class *toggle-online-users*.
If this options is set to true, the controlbox will by default be shown upon If this options is set to true, the controlbox will by default be shown upon
page load. page load.
show_call_button
----------------
Default = ``false``
Enable to display a call button on the chatbox toolbar.
When the call button is pressed, it will emit an event that can be used by a third-party library to initiate a call.
::
converse.on('onCallButtonClicked', function(event, data) {
console.log('Call button was clicked.');
console.log('Strophe connection is', data.connection);
console.log('Bare buddy JID is', data.model.get('jid'));
// ... Third-party library code ...
});
show_only_online_users show_only_online_users
---------------------- ----------------------
@ -821,6 +1060,14 @@ Default = ``false``
If set to ``true``, only online users will be shown in the contacts roster. If set to ``true``, only online users will be shown in the contacts roster.
Users with any other status (e.g. away, busy etc.) will not be shown. Users with any other status (e.g. away, busy etc.) will not be shown.
use_otr_by_default
------------------
Default = ``false``
If set to ``true``, Converse.js will automatically try to initiate an OTR (off-the-record)
encrypted chat session every time you open a chat box.
use_vcards use_vcards
---------- ----------
@ -889,140 +1136,6 @@ Used only in conjunction with ``xhr_user_search``.
This is the URL to which an AJAX GET request will be made to fetch user data from your remote server. This is the URL to which an AJAX GET request will be made to fetch user data from your remote server.
The query string will be included in the request with ``q`` as its key. The query string will be included in the request with ``q`` as its key.
============
Minification
============
Minifying Javascript and CSS
============================
Please make sure to read the section `Development`_ and that you have installed
all development dependencies (long story short, you can run ``npm install``
and then ``grunt fetch``).
We use `require.js`_ to keep track of *Converse.js* and its dependencies and to
to bundle them together in a single minified file fit for deployment to a
production site.
To minify the Javascript and CSS, run the following command:
::
grunt minify
Javascript will be bundled and minified with `require.js`_'s optimization tool,
using `almond <https://github.com/jrburke/almond>`_.
You can `read more about require.js's optimizer here`_.
CSS is minified via `cssmin <https://github.com/gruntjs/grunt-contrib-cssmin>`_.
============
Translations
============
.. Note ::
Translations take up a lot of space and will bloat your minified file.
At the time of writing, all the translations add about 50KB of extra data to
the minified javascript file. Therefore, make sure to only
include those languages that you intend to support and remove from
./locale/locales.js those which you don't need. Remember to rebuild the
minified file afterwards.
The gettext POT file located in ./locale/converse.pot is the template
containing all translations and from which for each language an individual PO
file is generated.
The POT file contains all translateable strings extracted from converse.js.
To make a user facing string translateable, wrap it in the double underscore helper
function like so:
::
__('This string will be translated at runtime');
After adding the string, you'll need to regenerate the POT file, like so:
::
make pot
You can then create or update the PO file for a specific language by doing the following:
::
msgmerge ./locale/de/LC_MESSAGES/converse.po ./locale/converse.pot -U
To do this for ALL languages, run:
::
make merge
The resulting PO file is then what gets translated.
If you've created a new PO file, please make sure to add the following
attributes at the top of the file (under *Content-Transfer-Encoding*). They are
required as configuration settings for Jed, the Javascript translations library
that we're using.
::
"domain: converse\n"
"lang: de\n"
"plural_forms: nplurals=2; plural=(n != 1);\n"
Unfortunately `Jed <http://slexaxton.github.io/Jed>`_ cannot use the PO files directly. We have to generate from it
a file in JSON format and then put that in a .js file for the specific
language.
To generate JSON from a PO file, you'll need po2json for node.js. Run the
following command to install it (npm being the node.js package manager):
::
npm install po2json
You can then convert the translations into JSON format:
::
po2json locale/de/LC_MESSAGES/converse.po locale/de/LC_MESSAGES/converse.json
Now from converse.json paste the data as a value for the "locale_data" key in the
object in the language's .js file.
So, if you are for example translating into German (language code 'de'), you'll
create or update the file ./locale/LC_MESSAGES/de.js with the following code:
::
(function (root, factory) {
define("de", ['jed'], function () {
return factory(new Jed({
"domain": "converse",
"locale_data": {
// Paste the JSON data from converse.json here
}
})
}
}(this, function (i18n) {
return i18n;
}));
making sure to also paste the JSON data as value to the "locale_data" key.
.. Note ::
If you are adding translations for a new language that is not already supported,
you'll have to make one more edit in ./locale/locales.js to make sure the
language is loaded by require.js.
Congratulations, you've now succesfully added your translations. Sorry for all
those hoops you had to jump through.
.. _`read more about require.js's optimizer here`: http://requirejs.org/docs/optimization.html .. _`read more about require.js's optimizer here`: http://requirejs.org/docs/optimization.html
.. _`HTTP`: https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol .. _`HTTP`: https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol
.. _`XMPP`: https://en.wikipedia.org/wiki/Xmpp .. _`XMPP`: https://en.wikipedia.org/wiki/Xmpp

View File

@ -9,7 +9,7 @@
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Index &mdash; Converse.js 0.7.1 documentation</title> <title>Index &mdash; Converse.js 0.7.3 documentation</title>
<link rel="stylesheet" href="_static/stylesheet.css" type="text/css" /> <link rel="stylesheet" href="_static/stylesheet.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" /> <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
@ -17,7 +17,7 @@
<script type="text/javascript"> <script type="text/javascript">
var DOCUMENTATION_OPTIONS = { var DOCUMENTATION_OPTIONS = {
URL_ROOT: '', URL_ROOT: '',
VERSION: '0.7.1', VERSION: '0.7.3',
COLLAPSE_INDEX: false, COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html', FILE_SUFFIX: '.html',
HAS_SOURCE: true HAS_SOURCE: true
@ -26,7 +26,7 @@
<script type="text/javascript" src="_static/jquery.js"></script> <script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script> <script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script> <script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="Converse.js 0.7.1 documentation" href="index.html" /> <link rel="top" title="Converse.js 0.7.3 documentation" href="index.html" />
</head> </head>
<body> <body>
<div id="header_wrap" class="outer"> <div id="header_wrap" class="outer">
@ -51,7 +51,7 @@
<li class="right" style="margin-right: 10px"> <li class="right" style="margin-right: 10px">
<a href="#" title="General Index" <a href="#" title="General Index"
accesskey="I">index</a></li> accesskey="I">index</a></li>
<li><a href="index.html">Converse.js 0.7.1 documentation</a> &raquo;</li> <li><a href="index.html">Converse.js 0.7.3 documentation</a> &raquo;</li>
</ul> </ul>
</div> </div>
<section id="main_content" class="inner"> <section id="main_content" class="inner">
@ -80,7 +80,7 @@
<li class="right" style="margin-right: 10px"> <li class="right" style="margin-right: 10px">
<a href="#" title="General Index" <a href="#" title="General Index"
>index</a></li> >index</a></li>
<li><a href="index.html">Converse.js 0.7.1 documentation</a> &raquo;</li> <li><a href="index.html">Converse.js 0.7.3 documentation</a> &raquo;</li>
</ul> </ul>
</div> </div>
</div> </div>

View File

@ -7,7 +7,7 @@
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Quickstart (to get a demo up and running) &mdash; Converse.js 0.7.1 documentation</title> <title>Quickstart (to get a demo up and running) &mdash; Converse.js 0.7.3 documentation</title>
<link rel="stylesheet" href="_static/stylesheet.css" type="text/css" /> <link rel="stylesheet" href="_static/stylesheet.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" /> <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
@ -15,7 +15,7 @@
<script type="text/javascript"> <script type="text/javascript">
var DOCUMENTATION_OPTIONS = { var DOCUMENTATION_OPTIONS = {
URL_ROOT: '', URL_ROOT: '',
VERSION: '0.7.1', VERSION: '0.7.3',
COLLAPSE_INDEX: false, COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html', FILE_SUFFIX: '.html',
HAS_SOURCE: true HAS_SOURCE: true
@ -24,7 +24,7 @@
<script type="text/javascript" src="_static/jquery.js"></script> <script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script> <script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script> <script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="Converse.js 0.7.1 documentation" href="#" /> <link rel="top" title="Converse.js 0.7.3 documentation" href="#" />
</head> </head>
<body> <body>
<div id="header_wrap" class="outer"> <div id="header_wrap" class="outer">
@ -49,7 +49,7 @@
<li class="right" style="margin-right: 10px"> <li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index" <a href="genindex.html" title="General Index"
accesskey="I">index</a></li> accesskey="I">index</a></li>
<li><a href="#">Converse.js 0.7.1 documentation</a> &raquo;</li> <li><a href="#">Converse.js 0.7.3 documentation</a> &raquo;</li>
</ul> </ul>
</div> </div>
<section id="main_content" class="inner"> <section id="main_content" class="inner">
@ -75,67 +75,77 @@
</li> </li>
<li><a class="reference internal" href="#server-side-authentication" id="id9">Server-side authentication</a><ul> <li><a class="reference internal" href="#server-side-authentication" id="id9">Server-side authentication</a><ul>
<li><a class="reference internal" href="#prebinding-and-single-session-support" id="id10">Prebinding and Single Session Support</a></li> <li><a class="reference internal" href="#prebinding-and-single-session-support" id="id10">Prebinding and Single Session Support</a></li>
<li><a class="reference internal" href="#setting-up-a-bosh-server" id="id11">Setting up a BOSH server</a></li> <li><a class="reference internal" href="#example-code-for-server-side-prebinding" id="id11">Example code for server-side prebinding</a></li>
<li><a class="reference internal" href="#setting-up-a-bosh-server" id="id12">Setting up a BOSH server</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#facebook-integration" id="id12">Facebook integration</a></li> <li><a class="reference internal" href="#facebook-integration" id="id13">Facebook integration</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#development" id="id13">Development</a><ul> <li><a class="reference internal" href="#features" id="id14">Features</a><ul>
<li><a class="reference internal" href="#install-node-js-and-development-dependencies" id="id14">Install Node.js and development dependencies</a></li> <li><a class="reference internal" href="#off-the-record-encryption" id="id15">Off-the-record encryption</a></li>
<li><a class="reference internal" href="#install-3rd-party-dependencies" id="id15">Install 3rd party dependencies</a></li> </ul>
<li><a class="reference internal" href="#with-amd-and-require-js-recommended" id="id16">With AMD and require.js (recommended)</a></li> </li>
<li><a class="reference internal" href="#without-amd-and-require-js" id="id17">Without AMD and require.js</a></li> <li><a class="reference internal" href="#development" id="id16">Development</a><ul>
<li><a class="reference internal" href="#before-submitting-a-pull-request" id="id18">Before submitting a pull request</a><ul> <li><a class="reference internal" href="#install-node-js-and-development-dependencies" id="id17">Install Node.js and development dependencies</a></li>
<li><a class="reference internal" href="#add-tests-for-your-bugfix-or-feature" id="id19">Add tests for your bugfix or feature</a></li> <li><a class="reference internal" href="#install-3rd-party-dependencies" id="id18">Install 3rd party dependencies</a></li>
<li><a class="reference internal" href="#check-that-the-tests-pass" id="id20">Check that the tests pass</a></li> <li><a class="reference internal" href="#with-amd-and-require-js-recommended" id="id19">With AMD and require.js (recommended)</a></li>
<li><a class="reference internal" href="#check-your-code-for-errors-or-bad-habits-by-running-jshint" id="id21">Check your code for errors or bad habits by running JSHint</a></li> <li><a class="reference internal" href="#without-amd-and-require-js" id="id20">Without AMD and require.js</a></li>
<li><a class="reference internal" href="#before-submitting-a-pull-request" id="id21">Before submitting a pull request</a><ul>
<li><a class="reference internal" href="#add-tests-for-your-bugfix-or-feature" id="id22">Add tests for your bugfix or feature</a></li>
<li><a class="reference internal" href="#check-that-the-tests-pass" id="id23">Check that the tests pass</a></li>
<li><a class="reference internal" href="#check-your-code-for-errors-or-bad-habits-by-running-jshint" id="id24">Check your code for errors or bad habits by running JSHint</a></li>
</ul>
</li>
<li><a class="reference internal" href="#minification" id="id25">Minification</a><ul>
<li><a class="reference internal" href="#minifying-javascript-and-css" id="id26">Minifying Javascript and CSS</a></li>
</ul>
</li>
<li><a class="reference internal" href="#translations" id="id27">Translations</a></li>
</ul>
</li>
<li><a class="reference internal" href="#troubleshooting" id="id28">Troubleshooting</a><ul>
<li><a class="reference internal" href="#conflicts-with-other-javascript-libraries" id="id29">Conflicts with other Javascript libraries</a><ul>
<li><a class="reference internal" href="#problem" id="id30">Problem:</a></li>
<li><a class="reference internal" href="#solution" id="id31">Solution:</a></li>
</ul> </ul>
</li> </li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#troubleshooting" id="id22">Troubleshooting</a><ul> <li><a class="reference internal" href="#events" id="id32">Events</a><ul>
<li><a class="reference internal" href="#conflicts-with-other-javascript-libraries" id="id23">Conflicts with other Javascript libraries</a><ul> <li><a class="reference internal" href="#event-methods" id="id33">Event Methods</a></li>
<li><a class="reference internal" href="#problem" id="id24">Problem:</a></li> <li><a class="reference internal" href="#event-types" id="id34">Event Types</a></li>
<li><a class="reference internal" href="#solution" id="id25">Solution:</a></li> </ul>
</li>
<li><a class="reference internal" href="#configuration" id="id35">Configuration</a><ul>
<li><a class="reference internal" href="#configuration-variables" id="id36">Configuration variables</a><ul>
<li><a class="reference internal" href="#allow-contact-requests" id="id37">allow_contact_requests</a></li>
<li><a class="reference internal" href="#allow-muc" id="id38">allow_muc</a></li>
<li><a class="reference internal" href="#animate" id="id39">animate</a></li>
<li><a class="reference internal" href="#auto-list-rooms" id="id40">auto_list_rooms</a></li>
<li><a class="reference internal" href="#auto-reconnect" id="id41">auto_reconnect</a></li>
<li><a class="reference internal" href="#auto-subscribe" id="id42">auto_subscribe</a></li>
<li><a class="reference internal" href="#bosh-service-url" id="id43">bosh_service_url</a></li>
<li><a class="reference internal" href="#cache-otr-key" id="id44">cache_otr_key</a></li>
<li><a class="reference internal" href="#debug" id="id45">debug</a></li>
<li><a class="reference internal" href="#expose-rid-and-sid" id="id46">expose_rid_and_sid</a></li>
<li><a class="reference internal" href="#fullname" id="id47">fullname</a></li>
<li><a class="reference internal" href="#hide-muc-server" id="id48">hide_muc_server</a></li>
<li><a class="reference internal" href="#i18n" id="id49">i18n</a></li>
<li><a class="reference internal" href="#prebind" id="id50">prebind</a></li>
<li><a class="reference internal" href="#show-controlbox-by-default" id="id51">show_controlbox_by_default</a></li>
<li><a class="reference internal" href="#show-call-button" id="id52">show_call_button</a></li>
<li><a class="reference internal" href="#show-only-online-users" id="id53">show_only_online_users</a></li>
<li><a class="reference internal" href="#use-otr-by-default" id="id54">use_otr_by_default</a></li>
<li><a class="reference internal" href="#use-vcards" id="id55">use_vcards</a></li>
<li><a class="reference internal" href="#xhr-custom-status" id="id56">xhr_custom_status</a></li>
<li><a class="reference internal" href="#xhr-custom-status-url" id="id57">xhr_custom_status_url</a></li>
<li><a class="reference internal" href="#xhr-user-search" id="id58">xhr_user_search</a></li>
<li><a class="reference internal" href="#xhr-user-search-url" id="id59">xhr_user_search_url</a></li>
</ul> </ul>
</li> </li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#events" id="id26">Events</a><ul>
<li><a class="reference internal" href="#event-methods" id="id27">Event Methods</a></li>
<li><a class="reference internal" href="#event-types" id="id28">Event Types</a></li>
</ul>
</li>
<li><a class="reference internal" href="#configuration" id="id29">Configuration</a><ul>
<li><a class="reference internal" href="#configuration-variables" id="id30">Configuration variables</a><ul>
<li><a class="reference internal" href="#allow-contact-requests" id="id31">allow_contact_requests</a></li>
<li><a class="reference internal" href="#allow-muc" id="id32">allow_muc</a></li>
<li><a class="reference internal" href="#animate" id="id33">animate</a></li>
<li><a class="reference internal" href="#auto-list-rooms" id="id34">auto_list_rooms</a></li>
<li><a class="reference internal" href="#auto-subscribe" id="id35">auto_subscribe</a></li>
<li><a class="reference internal" href="#bosh-service-url" id="id36">bosh_service_url</a></li>
<li><a class="reference internal" href="#debug" id="id37">debug</a></li>
<li><a class="reference internal" href="#fullname" id="id38">fullname</a></li>
<li><a class="reference internal" href="#hide-muc-server" id="id39">hide_muc_server</a></li>
<li><a class="reference internal" href="#i18n" id="id40">i18n</a></li>
<li><a class="reference internal" href="#prebind" id="id41">prebind</a></li>
<li><a class="reference internal" href="#show-controlbox-by-default" id="id42">show_controlbox_by_default</a></li>
<li><a class="reference internal" href="#show-only-online-users" id="id43">show_only_online_users</a></li>
<li><a class="reference internal" href="#use-vcards" id="id44">use_vcards</a></li>
<li><a class="reference internal" href="#xhr-custom-status" id="id45">xhr_custom_status</a></li>
<li><a class="reference internal" href="#xhr-custom-status-url" id="id46">xhr_custom_status_url</a></li>
<li><a class="reference internal" href="#xhr-user-search" id="id47">xhr_user_search</a></li>
<li><a class="reference internal" href="#xhr-user-search-url" id="id48">xhr_user_search_url</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#minification" id="id49">Minification</a><ul>
<li><a class="reference internal" href="#minifying-javascript-and-css" id="id50">Minifying Javascript and CSS</a></li>
</ul>
</li>
<li><a class="reference internal" href="#translations" id="id51">Translations</a></li>
</ul> </ul>
</div> </div>
<div class="section" id="quickstart-to-get-a-demo-up-and-running"> <div class="section" id="quickstart-to-get-a-demo-up-and-running">
@ -180,7 +190,7 @@ practical.</p>
<p>You&#8217;ll most likely want to implement some kind of single-signon solution for <p>You&#8217;ll most likely want to implement some kind of single-signon solution for
your website, where users authenticate once in your website and then stay your website, where users authenticate once in your website and then stay
logged into their XMPP session upon page reload.</p> logged into their XMPP session upon page reload.</p>
<p>For more info on this, read: <a href="#id52"><span class="problematic" id="id53">`Pre-binding and Single Session Support`_</span></a>.</p> <p>For more info on this, read: <a href="#id60"><span class="problematic" id="id61">`Pre-binding and Single Session Support`_</span></a>.</p>
<p>You might also want to have more fine-grained control of what gets included in <p>You might also want to have more fine-grained control of what gets included in
the minified Javascript file. Read <a class="reference internal" href="#configuration">Configuration</a> and <a class="reference internal" href="#minification">Minification</a> for more info on how to do the minified Javascript file. Read <a class="reference internal" href="#configuration">Configuration</a> and <a class="reference internal" href="#minification">Minification</a> for more info on how to do
that.</p> that.</p>
@ -338,15 +348,33 @@ Additionally you need to pass in valid <strong>jid</strong>, <strong>sid</strong
<strong>bosh_service_url</strong> values.</p> <strong>bosh_service_url</strong> values.</p>
</div> </div>
</div> </div>
<div class="section" id="example-code-for-server-side-prebinding">
<h3><a class="toc-backref" href="#id11">Example code for server-side prebinding</a><a class="headerlink" href="#example-code-for-server-side-prebinding" title="Permalink to this headline"></a></h3>
<ul>
<li><dl class="first docutils">
<dt>PHP:</dt>
<dd><p class="first last">See <a class="reference external" href="https://github.com/candy-chat/xmpp-prebind-php">xmpp-prebind-php</a> by
Michael Weibel and the folks from Candy chat.</p>
</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt>Python:</dt>
<dd><p class="first last">See this <a class="reference external" href="https://github.com/metajack/strophejs/tree/master/examples/attach">example Django application</a> by Jack Moffitt.</p>
</dd>
</dl>
</li>
</ul>
</div>
<div class="section" id="setting-up-a-bosh-server"> <div class="section" id="setting-up-a-bosh-server">
<h3><a class="toc-backref" href="#id11">Setting up a BOSH server</a><a class="headerlink" href="#setting-up-a-bosh-server" title="Permalink to this headline"></a></h3> <h3><a class="toc-backref" href="#id12">Setting up a BOSH server</a><a class="headerlink" href="#setting-up-a-bosh-server" title="Permalink to this headline"></a></h3>
<p>The <a class="reference external" href="http://movim.eu/">Movim</a> project wiki has a very thorough page on setting up a BOSH server for <p>The <a class="reference external" href="http://movim.eu/">Movim</a> project wiki has a very thorough page on setting up a BOSH server for
a wide variety of standalone or XMPP servers.</p> a wide variety of standalone or XMPP servers.</p>
<p><a class="reference external" href="http://wiki.movim.eu/manual:bosh_servers">http://wiki.movim.eu/manual:bosh_servers</a></p> <p><a class="reference external" href="http://wiki.movim.eu/manual:bosh_servers">http://wiki.movim.eu/manual:bosh_servers</a></p>
</div> </div>
</div> </div>
<div class="section" id="facebook-integration"> <div class="section" id="facebook-integration">
<h2><a class="toc-backref" href="#id12">Facebook integration</a><a class="headerlink" href="#facebook-integration" title="Permalink to this headline"></a></h2> <h2><a class="toc-backref" href="#id13">Facebook integration</a><a class="headerlink" href="#facebook-integration" title="Permalink to this headline"></a></h2>
<div class="admonition note"> <div class="admonition note">
<p class="first admonition-title">Note</p> <p class="first admonition-title">Note</p>
<p class="last">It should be possible to integrate Converse.js with Facebook chat, and <p class="last">It should be possible to integrate Converse.js with Facebook chat, and
@ -388,14 +416,39 @@ connection.facebookConnect(
Until then, people will have to do this themselves.</p> Until then, people will have to do this themselves.</p>
</div> </div>
</div> </div>
<div class="section" id="features">
<h1><a class="toc-backref" href="#id14">Features</a><a class="headerlink" href="#features" title="Permalink to this headline"></a></h1>
<div class="section" id="off-the-record-encryption">
<h2><a class="toc-backref" href="#id15">Off-the-record encryption</a><a class="headerlink" href="#off-the-record-encryption" title="Permalink to this headline"></a></h2>
<p>Converse.js supports <a class="reference external" href="https://otr.cypherpunks.ca/">Off-the-record (OTR)</a>
encrypted messaging.</p>
<p>The OTR protocol not only <strong>encrypts your messages</strong>, it provides ways to
<strong>verify the identity</strong> of the person you are talking to,
<strong>plausible deniability</strong> and <strong>perfect forward secrecy</strong> by generating
new encryption keys for each conversation.</p>
<p>In its current state, Javascript cryptography is fraught with dangers and
challenges that make it impossible to reach the same standard of security that
is available with native &#8220;desktop&#8221; software.</p>
<p>This is due to its runtime malleability, the way it is &#8220;installed&#8221; (e.g.
served) and the browser&#8217;s lack of cryptographic primitives needed to implement
secure crypto.</p>
<p>For harsh but fairly valid criticism of Javascript cryptography, read:
<a class="reference external" href="http://www.matasano.com/articles/javascript-cryptography/">Javascript Cryptography Considered Harmful</a>.</p>
<p>To get an idea on how this applies to OTR support in Converse.js, please read
<a class="reference external" href="https://opkode.com/media/blog/2013/11/11/conversejs-otr-support">my thoughts on it</a>.</p>
<p>For now, suffice to say that although its useful to have OTR support in
Converse.js in order to avoid most eavesdroppers, if you need serious
communications privacy, then you&#8217;re much better off using native software.</p>
</div>
</div>
<div class="section" id="development"> <div class="section" id="development">
<h1><a class="toc-backref" href="#id13">Development</a><a class="headerlink" href="#development" title="Permalink to this headline"></a></h1> <h1><a class="toc-backref" href="#id16">Development</a><a class="headerlink" href="#development" title="Permalink to this headline"></a></h1>
<p>If you want to work with the non-minified Javascript and CSS files you&#8217;ll soon <p>If you want to work with the non-minified Javascript and CSS files you&#8217;ll soon
notice that there are references to a missing <em>components</em> folder. Please notice that there are references to a missing <em>components</em> folder. Please
follow the instructions below to create this folder and fetch Converse&#8217;s follow the instructions below to create this folder and fetch Converse&#8217;s
3rd-party dependencies.</p> 3rd-party dependencies.</p>
<div class="section" id="install-node-js-and-development-dependencies"> <div class="section" id="install-node-js-and-development-dependencies">
<h2><a class="toc-backref" href="#id14">Install Node.js and development dependencies</a><a class="headerlink" href="#install-node-js-and-development-dependencies" title="Permalink to this headline"></a></h2> <h2><a class="toc-backref" href="#id17">Install Node.js and development dependencies</a><a class="headerlink" href="#install-node-js-and-development-dependencies" title="Permalink to this headline"></a></h2>
<p>We use development tools (<a class="reference external" href="http://gruntjs.com">Grunt</a> and <a class="reference external" href="http://bower.io">Bower</a>) <p>We use development tools (<a class="reference external" href="http://gruntjs.com">Grunt</a> and <a class="reference external" href="http://bower.io">Bower</a>)
which depend on Node.js and npm (the Node package manager).</p> which depend on Node.js and npm (the Node package manager).</p>
<p>If you don&#8217;t have Node.js installed, you can download and install the latest <p>If you don&#8217;t have Node.js installed, you can download and install the latest
@ -409,7 +462,7 @@ curious to know what these are, take a look at whats under the <em>devDependenci
<cite>package.json &lt;https://github.com/jcbrand/converse.js/blob/master/package.json&gt;</cite>.</p> <cite>package.json &lt;https://github.com/jcbrand/converse.js/blob/master/package.json&gt;</cite>.</p>
</div> </div>
<div class="section" id="install-3rd-party-dependencies"> <div class="section" id="install-3rd-party-dependencies">
<h2><a class="toc-backref" href="#id15">Install 3rd party dependencies</a><a class="headerlink" href="#install-3rd-party-dependencies" title="Permalink to this headline"></a></h2> <h2><a class="toc-backref" href="#id18">Install 3rd party dependencies</a><a class="headerlink" href="#install-3rd-party-dependencies" title="Permalink to this headline"></a></h2>
<p>After running <tt class="docutils literal"><span class="pre">npm</span> <span class="pre">install</span></tt>, you will now have Grunt and Bower installed.</p> <p>After running <tt class="docutils literal"><span class="pre">npm</span> <span class="pre">install</span></tt>, you will now have Grunt and Bower installed.</p>
<p>We use Bower to manage Converse&#8217;s front-end dependencies (e.g. Javascript that <p>We use Bower to manage Converse&#8217;s front-end dependencies (e.g. Javascript that
should get loaded in the browser).</p> should get loaded in the browser).</p>
@ -418,16 +471,14 @@ should get loaded in the browser).</p>
</div> </div>
<p>If you don&#8217;t have grunt installed globally, you need to specify the relative <p>If you don&#8217;t have grunt installed globally, you need to specify the relative
path:</p> path:</p>
<dl class="docutils"> <div class="highlight-python"><pre>./node_modules/.bin/grunt fetch</pre>
<dt>::</dt> </div>
<dd>./node_modules/.bin/grunt fetch</dd>
</dl>
<p>This will call Bower in the background to fetch all the front-end <p>This will call Bower in the background to fetch all the front-end
dependencies (like backbone.js, strophe.js etc.) and then put them in the dependencies (like backbone.js, strophe.js etc.) and then put them in the
<em>components</em> folder.</p> <em>components</em> folder.</p>
</div> </div>
<div class="section" id="with-amd-and-require-js-recommended"> <div class="section" id="with-amd-and-require-js-recommended">
<h2><a class="toc-backref" href="#id16">With AMD and require.js (recommended)</a><a class="headerlink" href="#with-amd-and-require-js-recommended" title="Permalink to this headline"></a></h2> <h2><a class="toc-backref" href="#id19">With AMD and require.js (recommended)</a><a class="headerlink" href="#with-amd-and-require-js-recommended" title="Permalink to this headline"></a></h2>
<p>Converse.js uses <a class="reference external" href="http://requirejs.org">require.js</a> to asynchronously load dependencies.</p> <p>Converse.js uses <a class="reference external" href="http://requirejs.org">require.js</a> to asynchronously load dependencies.</p>
<p>If you want to develop or customize converse.js, you&#8217;ll want to load the <p>If you want to develop or customize converse.js, you&#8217;ll want to load the
non-minified javascript files.</p> non-minified javascript files.</p>
@ -440,7 +491,7 @@ attribute on the <em>script</em> tag), which will in turn cause converse.js to b
parsed.</p> parsed.</p>
</div> </div>
<div class="section" id="without-amd-and-require-js"> <div class="section" id="without-amd-and-require-js">
<h2><a class="toc-backref" href="#id17">Without AMD and require.js</a><a class="headerlink" href="#without-amd-and-require-js" title="Permalink to this headline"></a></h2> <h2><a class="toc-backref" href="#id20">Without AMD and require.js</a><a class="headerlink" href="#without-amd-and-require-js" title="Permalink to this headline"></a></h2>
<p>Converse.js can also be used without require.js. If you for some reason prefer <p>Converse.js can also be used without require.js. If you for some reason prefer
to use it this way, please refer to to use it this way, please refer to
<a class="reference external" href="https://github.com/jcbrand/converse.js/blob/master/non_amd.html">non_amd.html</a> <a class="reference external" href="https://github.com/jcbrand/converse.js/blob/master/non_amd.html">non_amd.html</a>
@ -448,9 +499,9 @@ for an example of how and in what order all the Javascript files that converse.j
depends on need to be loaded.</p> depends on need to be loaded.</p>
</div> </div>
<div class="section" id="before-submitting-a-pull-request"> <div class="section" id="before-submitting-a-pull-request">
<h2><a class="toc-backref" href="#id18">Before submitting a pull request</a><a class="headerlink" href="#before-submitting-a-pull-request" title="Permalink to this headline"></a></h2> <h2><a class="toc-backref" href="#id21">Before submitting a pull request</a><a class="headerlink" href="#before-submitting-a-pull-request" title="Permalink to this headline"></a></h2>
<div class="section" id="add-tests-for-your-bugfix-or-feature"> <div class="section" id="add-tests-for-your-bugfix-or-feature">
<h3><a class="toc-backref" href="#id19">Add tests for your bugfix or feature</a><a class="headerlink" href="#add-tests-for-your-bugfix-or-feature" title="Permalink to this headline"></a></h3> <h3><a class="toc-backref" href="#id22">Add tests for your bugfix or feature</a><a class="headerlink" href="#add-tests-for-your-bugfix-or-feature" title="Permalink to this headline"></a></h3>
<p>Add a test for any bug fixed or feature added. We use Jasmine <p>Add a test for any bug fixed or feature added. We use Jasmine
for testing.</p> for testing.</p>
<p>Take a look at <tt class="docutils literal"><span class="pre">tests.html</span></tt> and <tt class="docutils literal"><span class="pre">spec/MainSpec.js</span></tt> to see how <p>Take a look at <tt class="docutils literal"><span class="pre">tests.html</span></tt> and <tt class="docutils literal"><span class="pre">spec/MainSpec.js</span></tt> to see how
@ -459,7 +510,7 @@ the tests are implemented.</p>
<a class="reference external" href="http://opkode.com/contact">contact me</a> and I&#8217;ll be happy to help.</p> <a class="reference external" href="http://opkode.com/contact">contact me</a> and I&#8217;ll be happy to help.</p>
</div> </div>
<div class="section" id="check-that-the-tests-pass"> <div class="section" id="check-that-the-tests-pass">
<h3><a class="toc-backref" href="#id20">Check that the tests pass</a><a class="headerlink" href="#check-that-the-tests-pass" title="Permalink to this headline"></a></h3> <h3><a class="toc-backref" href="#id23">Check that the tests pass</a><a class="headerlink" href="#check-that-the-tests-pass" title="Permalink to this headline"></a></h3>
<p>Check that the Jasmine tests complete sucessfully. Open <p>Check that the Jasmine tests complete sucessfully. Open
<a class="reference external" href="https://github.com/jcbrand/converse.js/blob/master/tests.html">tests.html</a> <a class="reference external" href="https://github.com/jcbrand/converse.js/blob/master/tests.html">tests.html</a>
in your browser, and the tests will run automatically.</p> in your browser, and the tests will run automatically.</p>
@ -468,7 +519,7 @@ in your browser, and the tests will run automatically.</p>
</div> </div>
</div> </div>
<div class="section" id="check-your-code-for-errors-or-bad-habits-by-running-jshint"> <div class="section" id="check-your-code-for-errors-or-bad-habits-by-running-jshint">
<h3><a class="toc-backref" href="#id21">Check your code for errors or bad habits by running JSHint</a><a class="headerlink" href="#check-your-code-for-errors-or-bad-habits-by-running-jshint" title="Permalink to this headline"></a></h3> <h3><a class="toc-backref" href="#id24">Check your code for errors or bad habits by running JSHint</a><a class="headerlink" href="#check-your-code-for-errors-or-bad-habits-by-running-jshint" title="Permalink to this headline"></a></h3>
<p><a class="reference external" href="http://jshint.com">JSHint</a> will do a static analysis of your code and hightlight potential errors <p><a class="reference external" href="http://jshint.com">JSHint</a> will do a static analysis of your code and hightlight potential errors
and/or bad habits.</p> and/or bad habits.</p>
<div class="highlight-python"><pre>grunt jshint</pre> <div class="highlight-python"><pre>grunt jshint</pre>
@ -478,20 +529,115 @@ and/or bad habits.</p>
</div> </div>
</div> </div>
</div> </div>
<div class="section" id="minification">
<h2><a class="toc-backref" href="#id25">Minification</a><a class="headerlink" href="#minification" title="Permalink to this headline"></a></h2>
<div class="section" id="minifying-javascript-and-css">
<h3><a class="toc-backref" href="#id26">Minifying Javascript and CSS</a><a class="headerlink" href="#minifying-javascript-and-css" title="Permalink to this headline"></a></h3>
<p>Please make sure to read the section <a class="reference internal" href="#development">Development</a> and that you have installed
all development dependencies (long story short, you can run <tt class="docutils literal"><span class="pre">npm</span> <span class="pre">install</span></tt>
and then <tt class="docutils literal"><span class="pre">grunt</span> <span class="pre">fetch</span></tt>).</p>
<p>We use <a class="reference external" href="http://requirejs.org">require.js</a> to keep track of <em>Converse.js</em> and its dependencies and to
to bundle them together in a single minified file fit for deployment to a
production site.</p>
<p>To minify the Javascript and CSS, run the following command:</p>
<div class="highlight-python"><pre>grunt minify</pre>
</div>
<p>Javascript will be bundled and minified with <a class="reference external" href="http://requirejs.org">require.js</a>&#8216;s optimization tool,
using <a class="reference external" href="https://github.com/jrburke/almond">almond</a>.</p>
<p>You can <a class="reference external" href="http://requirejs.org/docs/optimization.html">read more about require.js&#8217;s optimizer here</a>.</p>
<p>CSS is minified via <a class="reference external" href="https://github.com/gruntjs/grunt-contrib-cssmin">cssmin</a>.</p>
</div>
</div>
<div class="section" id="translations">
<h2><a class="toc-backref" href="#id27">Translations</a><a class="headerlink" href="#translations" title="Permalink to this headline"></a></h2>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Translations take up a lot of space and will bloat your minified file.
At the time of writing, all the translations add about 50KB of extra data to
the minified javascript file. Therefore, make sure to only
include those languages that you intend to support and remove from
./locale/locales.js those which you don&#8217;t need. Remember to rebuild the
minified file afterwards.</p>
</div>
<p>The gettext POT file located in ./locale/converse.pot is the template
containing all translations and from which for each language an individual PO
file is generated.</p>
<p>The POT file contains all translateable strings extracted from converse.js.</p>
<p>To make a user facing string translateable, wrap it in the double underscore helper
function like so:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">__</span><span class="p">(</span><span class="s">&#39;This string will be translated at runtime&#39;</span><span class="p">);</span>
</pre></div>
</div>
<p>After adding the string, you&#8217;ll need to regenerate the POT file, like so:</p>
<div class="highlight-python"><pre>make pot</pre>
</div>
<p>You can then create or update the PO file for a specific language by doing the following:</p>
<div class="highlight-python"><pre>msgmerge ./locale/de/LC_MESSAGES/converse.po ./locale/converse.pot -U</pre>
</div>
<p>To do this for ALL languages, run:</p>
<div class="highlight-python"><pre>make merge</pre>
</div>
<p>The resulting PO file is then what gets translated.</p>
<p>If you&#8217;ve created a new PO file, please make sure to add the following
attributes at the top of the file (under <em>Content-Transfer-Encoding</em>). They are
required as configuration settings for Jed, the Javascript translations library
that we&#8217;re using.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="s">&quot;domain: converse</span><span class="se">\n</span><span class="s">&quot;</span>
<span class="s">&quot;lang: de</span><span class="se">\n</span><span class="s">&quot;</span>
<span class="s">&quot;plural_forms: nplurals=2; plural=(n != 1);</span><span class="se">\n</span><span class="s">&quot;</span>
</pre></div>
</div>
<p>Unfortunately <a class="reference external" href="http://slexaxton.github.io/Jed">Jed</a> cannot use the PO files directly. We have to generate from it
a file in JSON format and then put that in a .js file for the specific
language.</p>
<p>To generate JSON from a PO file, you&#8217;ll need po2json for node.js. Run the
following command to install it (npm being the node.js package manager):</p>
<div class="highlight-python"><pre>npm install po2json</pre>
</div>
<p>You can then convert the translations into JSON format:</p>
<div class="highlight-python"><pre>po2json locale/de/LC_MESSAGES/converse.po locale/de/LC_MESSAGES/converse.json</pre>
</div>
<p>Now from converse.json paste the data as a value for the &#8220;locale_data&#8221; key in the
object in the language&#8217;s .js file.</p>
<p>So, if you are for example translating into German (language code &#8216;de&#8217;), you&#8217;ll
create or update the file ./locale/LC_MESSAGES/de.js with the following code:</p>
<div class="highlight-python"><pre>(function (root, factory) {
define("de", ['jed'], function () {
return factory(new Jed({
"domain": "converse",
"locale_data": {
// Paste the JSON data from converse.json here
}
})
}
}(this, function (i18n) {
return i18n;
}));</pre>
</div>
<p>making sure to also paste the JSON data as value to the &#8220;locale_data&#8221; key.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">If you are adding translations for a new language that is not already supported,
you&#8217;ll have to make one more edit in ./locale/locales.js to make sure the
language is loaded by require.js.</p>
</div>
<p>Congratulations, you&#8217;ve now succesfully added your translations. Sorry for all
those hoops you had to jump through.</p>
</div>
</div> </div>
<div class="section" id="troubleshooting"> <div class="section" id="troubleshooting">
<h1><a class="toc-backref" href="#id22">Troubleshooting</a><a class="headerlink" href="#troubleshooting" title="Permalink to this headline"></a></h1> <h1><a class="toc-backref" href="#id28">Troubleshooting</a><a class="headerlink" href="#troubleshooting" title="Permalink to this headline"></a></h1>
<div class="section" id="conflicts-with-other-javascript-libraries"> <div class="section" id="conflicts-with-other-javascript-libraries">
<h2><a class="toc-backref" href="#id23">Conflicts with other Javascript libraries</a><a class="headerlink" href="#conflicts-with-other-javascript-libraries" title="Permalink to this headline"></a></h2> <h2><a class="toc-backref" href="#id29">Conflicts with other Javascript libraries</a><a class="headerlink" href="#conflicts-with-other-javascript-libraries" title="Permalink to this headline"></a></h2>
<div class="section" id="problem"> <div class="section" id="problem">
<h3><a class="toc-backref" href="#id24">Problem:</a><a class="headerlink" href="#problem" title="Permalink to this headline"></a></h3> <h3><a class="toc-backref" href="#id30">Problem:</a><a class="headerlink" href="#problem" title="Permalink to this headline"></a></h3>
<p>You are using other Javascript libraries (like JQuery plugins), and <p>You are using other Javascript libraries (like JQuery plugins), and
get errors like these in your browser console:</p> get errors like these in your browser console:</p>
<div class="highlight-python"><pre>Uncaught TypeError: Object [object Object] has no method 'xxx' from example.js</pre> <div class="highlight-python"><pre>Uncaught TypeError: Object [object Object] has no method 'xxx' from example.js</pre>
</div> </div>
</div> </div>
<div class="section" id="solution"> <div class="section" id="solution">
<h3><a class="toc-backref" href="#id25">Solution:</a><a class="headerlink" href="#solution" title="Permalink to this headline"></a></h3> <h3><a class="toc-backref" href="#id31">Solution:</a><a class="headerlink" href="#solution" title="Permalink to this headline"></a></h3>
<p>First, find out which object is referred to by <tt class="docutils literal"><span class="pre">Object</span> <span class="pre">[object</span> <span class="pre">Object]</span></tt>.</p> <p>First, find out which object is referred to by <tt class="docutils literal"><span class="pre">Object</span> <span class="pre">[object</span> <span class="pre">Object]</span></tt>.</p>
<p>It will probably be the jQuery object <tt class="docutils literal"><span class="pre">$</span></tt> or perhaps the underscore.js object <tt class="docutils literal"><span class="pre">_</span></tt>.</p> <p>It will probably be the jQuery object <tt class="docutils literal"><span class="pre">$</span></tt> or perhaps the underscore.js object <tt class="docutils literal"><span class="pre">_</span></tt>.</p>
<p>For the purpose of demonstration, I&#8217;m going to assume its <tt class="docutils literal"><span class="pre">$</span></tt>, but the same <p>For the purpose of demonstration, I&#8217;m going to assume its <tt class="docutils literal"><span class="pre">$</span></tt>, but the same
@ -533,11 +679,11 @@ jQuery plugins must load after jQuery).</p>
</div> </div>
</div> </div>
<div class="section" id="events"> <div class="section" id="events">
<h1><a class="toc-backref" href="#id26">Events</a><a class="headerlink" href="#events" title="Permalink to this headline"></a></h1> <h1><a class="toc-backref" href="#id32">Events</a><a class="headerlink" href="#events" title="Permalink to this headline"></a></h1>
<p>Converse.js emits events to which you can subscribe from your own Javascript.</p> <p>Converse.js emits events to which you can subscribe from your own Javascript.</p>
<p>Concerning events, the following methods are available:</p> <p>Concerning events, the following methods are available:</p>
<div class="section" id="event-methods"> <div class="section" id="event-methods">
<h2><a class="toc-backref" href="#id27">Event Methods</a><a class="headerlink" href="#event-methods" title="Permalink to this headline"></a></h2> <h2><a class="toc-backref" href="#id33">Event Methods</a><a class="headerlink" href="#event-methods" title="Permalink to this headline"></a></h2>
<ul> <ul>
<li><p class="first"><strong>on(eventName, callback)</strong>:</p> <li><p class="first"><strong>on(eventName, callback)</strong>:</p>
<blockquote> <blockquote>
@ -581,7 +727,7 @@ exactly once.</p>
</ul> </ul>
</div> </div>
<div class="section" id="event-types"> <div class="section" id="event-types">
<h2><a class="toc-backref" href="#id28">Event Types</a><a class="headerlink" href="#event-types" title="Permalink to this headline"></a></h2> <h2><a class="toc-backref" href="#id34">Event Types</a><a class="headerlink" href="#event-types" title="Permalink to this headline"></a></h2>
<p>Here are the different events that are emitted:</p> <p>Here are the different events that are emitted:</p>
<ul> <ul>
<li><p class="first"><strong>onInitialized</strong></p> <li><p class="first"><strong>onInitialized</strong></p>
@ -667,7 +813,7 @@ got all its ducks in a row.</p>
</div> </div>
</div> </div>
<div class="section" id="configuration"> <div class="section" id="configuration">
<h1><a class="toc-backref" href="#id29">Configuration</a><a class="headerlink" href="#configuration" title="Permalink to this headline"></a></h1> <h1><a class="toc-backref" href="#id35">Configuration</a><a class="headerlink" href="#configuration" title="Permalink to this headline"></a></h1>
<p>The included minified JS and CSS files can be used for demoing or testing, but <p>The included minified JS and CSS files can be used for demoing or testing, but
you&#8217;ll want to configure <em>Converse.js</em> to suit your needs before you deploy it you&#8217;ll want to configure <em>Converse.js</em> to suit your needs before you deploy it
on your website.</p> on your website.</p>
@ -681,9 +827,9 @@ all the available configuration settings.</p>
JS file so that it will include the new settings. Please refer to the JS file so that it will include the new settings. Please refer to the
<a class="reference internal" href="#minification">Minification</a> section for more info on how to do this.</p> <a class="reference internal" href="#minification">Minification</a> section for more info on how to do this.</p>
<div class="section" id="configuration-variables"> <div class="section" id="configuration-variables">
<h2><a class="toc-backref" href="#id30">Configuration variables</a><a class="headerlink" href="#configuration-variables" title="Permalink to this headline"></a></h2> <h2><a class="toc-backref" href="#id36">Configuration variables</a><a class="headerlink" href="#configuration-variables" title="Permalink to this headline"></a></h2>
<div class="section" id="allow-contact-requests"> <div class="section" id="allow-contact-requests">
<h3><a class="toc-backref" href="#id31">allow_contact_requests</a><a class="headerlink" href="#allow-contact-requests" title="Permalink to this headline"></a></h3> <h3><a class="toc-backref" href="#id37">allow_contact_requests</a><a class="headerlink" href="#allow-contact-requests" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">true</span></tt></p> <p>Default = <tt class="docutils literal"><span class="pre">true</span></tt></p>
<p>Allow users to add one another as contacts. If this is set to false, the <p>Allow users to add one another as contacts. If this is set to false, the
<strong>Add a contact</strong> widget, <strong>Contact Requests</strong> and <strong>Pending Contacts</strong> roster <strong>Add a contact</strong> widget, <strong>Contact Requests</strong> and <strong>Pending Contacts</strong> roster
@ -691,18 +837,18 @@ sections will all not appear. Additionally, all incoming contact requests will b
ignored.</p> ignored.</p>
</div> </div>
<div class="section" id="allow-muc"> <div class="section" id="allow-muc">
<h3><a class="toc-backref" href="#id32">allow_muc</a><a class="headerlink" href="#allow-muc" title="Permalink to this headline"></a></h3> <h3><a class="toc-backref" href="#id38">allow_muc</a><a class="headerlink" href="#allow-muc" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">true</span></tt></p> <p>Default = <tt class="docutils literal"><span class="pre">true</span></tt></p>
<p>Allow multi-user chat (muc) in chatrooms. Setting this to <tt class="docutils literal"><span class="pre">false</span></tt> will remove <p>Allow multi-user chat (muc) in chatrooms. Setting this to <tt class="docutils literal"><span class="pre">false</span></tt> will remove
the <tt class="docutils literal"><span class="pre">Chatrooms</span></tt> tab from the control box.</p> the <tt class="docutils literal"><span class="pre">Chatrooms</span></tt> tab from the control box.</p>
</div> </div>
<div class="section" id="animate"> <div class="section" id="animate">
<h3><a class="toc-backref" href="#id33">animate</a><a class="headerlink" href="#animate" title="Permalink to this headline"></a></h3> <h3><a class="toc-backref" href="#id39">animate</a><a class="headerlink" href="#animate" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">true</span></tt></p> <p>Default = <tt class="docutils literal"><span class="pre">true</span></tt></p>
<p>Show animations, for example when opening and closing chat boxes.</p> <p>Show animations, for example when opening and closing chat boxes.</p>
</div> </div>
<div class="section" id="auto-list-rooms"> <div class="section" id="auto-list-rooms">
<h3><a class="toc-backref" href="#id34">auto_list_rooms</a><a class="headerlink" href="#auto-list-rooms" title="Permalink to this headline"></a></h3> <h3><a class="toc-backref" href="#id40">auto_list_rooms</a><a class="headerlink" href="#auto-list-rooms" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p> <p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p>
<p>If true, and the XMPP server on which the current user is logged in supports <p>If true, and the XMPP server on which the current user is logged in supports
multi-user chat, then a list of rooms on that server will be fetched.</p> multi-user chat, then a list of rooms on that server will be fetched.</p>
@ -711,41 +857,74 @@ multi-user chat, then a list of rooms on that server will be fetched.</p>
features, number of occupants etc.), so on servers with many rooms this features, number of occupants etc.), so on servers with many rooms this
option will create lots of extra connection traffic.</p> option will create lots of extra connection traffic.</p>
</div> </div>
<div class="section" id="auto-reconnect">
<h3><a class="toc-backref" href="#id41">auto_reconnect</a><a class="headerlink" href="#auto-reconnect" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">true</span></tt></p>
<p>Automatically reconnect to the XMPP server if the connection drops
unexpectedly.</p>
</div>
<div class="section" id="auto-subscribe"> <div class="section" id="auto-subscribe">
<h3><a class="toc-backref" href="#id35">auto_subscribe</a><a class="headerlink" href="#auto-subscribe" title="Permalink to this headline"></a></h3> <h3><a class="toc-backref" href="#id42">auto_subscribe</a><a class="headerlink" href="#auto-subscribe" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p> <p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p>
<p>If true, the user will automatically subscribe back to any contact requests.</p> <p>If true, the user will automatically subscribe back to any contact requests.</p>
</div> </div>
<div class="section" id="bosh-service-url"> <div class="section" id="bosh-service-url">
<h3><a class="toc-backref" href="#id36">bosh_service_url</a><a class="headerlink" href="#bosh-service-url" title="Permalink to this headline"></a></h3> <h3><a class="toc-backref" href="#id43">bosh_service_url</a><a class="headerlink" href="#bosh-service-url" title="Permalink to this headline"></a></h3>
<p>Connections to an XMPP server depend on a BOSH connection manager which acts as <p>Connections to an XMPP server depend on a BOSH connection manager which acts as
a middle man between HTTP and XMPP.</p> a middle man between HTTP and XMPP.</p>
<p>See <a class="reference external" href="http://metajack.im/2008/09/08/which-bosh-server-do-you-need">here</a> for more information.</p> <p>See <a class="reference external" href="http://metajack.im/2008/09/08/which-bosh-server-do-you-need">here</a> for more information.</p>
</div> </div>
<div class="section" id="cache-otr-key">
<h3><a class="toc-backref" href="#id44">cache_otr_key</a><a class="headerlink" href="#cache-otr-key" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p>
<p>Let the <a class="reference external" href="https://otr.cypherpunks.ca">OTR (Off-the-record encryption)</a> private
key be cached in your browser&#8217;s session storage.</p>
<p>The browser&#8217;s session storage persists across page loads but is deleted once
the tab or window is closed.</p>
<p>If this option is set to <tt class="docutils literal"><span class="pre">false</span></tt>, a new OTR private key will be generated
for each page load. While more inconvenient, this is a much more secure option.</p>
<p>This setting can only be used together with <tt class="docutils literal"><span class="pre">allow_otr</span> <span class="pre">=</span> <span class="pre">true</span></tt>.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">A browser window&#8217;s session storage is accessible by all javascript that
is served from the same domain. So if there is malicious javascript served by
the same server (or somehow injected via an attacker), then they will be able
to retrieve your private key and read your all the chat messages in your
current session. Previous sessions however cannot be decrypted.</p>
</div>
</div>
<div class="section" id="debug"> <div class="section" id="debug">
<h3><a class="toc-backref" href="#id37">debug</a><a class="headerlink" href="#debug" title="Permalink to this headline"></a></h3> <h3><a class="toc-backref" href="#id45">debug</a><a class="headerlink" href="#debug" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p> <p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p>
<p>If set to true, debugging output will be logged to the browser console.</p> <p>If set to true, debugging output will be logged to the browser console.</p>
</div> </div>
<div class="section" id="expose-rid-and-sid">
<h3><a class="toc-backref" href="#id46">expose_rid_and_sid</a><a class="headerlink" href="#expose-rid-and-sid" title="Permalink to this headline"></a></h3>
<p>Allow the prebind tokens, RID (request ID) and SID (session ID), to be exposed
globally via the API. This allows other scripts served on the same page to use
these values.</p>
<p><em>Beware</em>: a malicious script could use these tokens to assume your identity
and inject fake chat messages.</p>
</div>
<div class="section" id="fullname"> <div class="section" id="fullname">
<h3><a class="toc-backref" href="#id38">fullname</a><a class="headerlink" href="#fullname" title="Permalink to this headline"></a></h3> <h3><a class="toc-backref" href="#id47">fullname</a><a class="headerlink" href="#fullname" title="Permalink to this headline"></a></h3>
<p>If you are using prebinding, can specify the fullname of the currently <p>If you are using prebinding, can specify the fullname of the currently
logged in user, otherwise the user&#8217;s vCard will be fetched.</p> logged in user, otherwise the user&#8217;s vCard will be fetched.</p>
</div> </div>
<div class="section" id="hide-muc-server"> <div class="section" id="hide-muc-server">
<h3><a class="toc-backref" href="#id39">hide_muc_server</a><a class="headerlink" href="#hide-muc-server" title="Permalink to this headline"></a></h3> <h3><a class="toc-backref" href="#id48">hide_muc_server</a><a class="headerlink" href="#hide-muc-server" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p> <p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p>
<p>Hide the <tt class="docutils literal"><span class="pre">server</span></tt> input field of the form inside the <tt class="docutils literal"><span class="pre">Room</span></tt> panel of the <p>Hide the <tt class="docutils literal"><span class="pre">server</span></tt> input field of the form inside the <tt class="docutils literal"><span class="pre">Room</span></tt> panel of the
controlbox. Useful if you want to restrict users to a specific XMPP server of controlbox. Useful if you want to restrict users to a specific XMPP server of
your choosing.</p> your choosing.</p>
</div> </div>
<div class="section" id="i18n"> <div class="section" id="i18n">
<h3><a class="toc-backref" href="#id40">i18n</a><a class="headerlink" href="#i18n" title="Permalink to this headline"></a></h3> <h3><a class="toc-backref" href="#id49">i18n</a><a class="headerlink" href="#i18n" title="Permalink to this headline"></a></h3>
<p>Specify the locale/language. The language must be in the <tt class="docutils literal"><span class="pre">locales</span></tt> object. Refer to <p>Specify the locale/language. The language must be in the <tt class="docutils literal"><span class="pre">locales</span></tt> object. Refer to
<tt class="docutils literal"><span class="pre">./locale/locales.js</span></tt> to see which locales are supported.</p> <tt class="docutils literal"><span class="pre">./locale/locales.js</span></tt> to see which locales are supported.</p>
</div> </div>
<div class="section" id="prebind"> <div class="section" id="prebind">
<h3><a class="toc-backref" href="#id41">prebind</a><a class="headerlink" href="#prebind" title="Permalink to this headline"></a></h3> <h3><a class="toc-backref" href="#id50">prebind</a><a class="headerlink" href="#prebind" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p> <p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p>
<p>Use this option when you want to attach to an existing XMPP connection that was <p>Use this option when you want to attach to an existing XMPP connection that was
already authenticated (usually on the backend before page load).</p> already authenticated (usually on the backend before page load).</p>
@ -758,7 +937,7 @@ values as <tt class="docutils literal"><span class="pre">jid</span></tt>, <tt cl
<p>Additionally, you have to specify <tt class="docutils literal"><span class="pre">bosh_service_url</span></tt>.</p> <p>Additionally, you have to specify <tt class="docutils literal"><span class="pre">bosh_service_url</span></tt>.</p>
</div> </div>
<div class="section" id="show-controlbox-by-default"> <div class="section" id="show-controlbox-by-default">
<h3><a class="toc-backref" href="#id42">show_controlbox_by_default</a><a class="headerlink" href="#show-controlbox-by-default" title="Permalink to this headline"></a></h3> <h3><a class="toc-backref" href="#id51">show_controlbox_by_default</a><a class="headerlink" href="#show-controlbox-by-default" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p> <p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p>
<p>The &#8220;controlbox&#8221; refers to the special chatbox containing your contacts roster, <p>The &#8220;controlbox&#8221; refers to the special chatbox containing your contacts roster,
status widget, chatrooms and other controls.</p> status widget, chatrooms and other controls.</p>
@ -767,21 +946,41 @@ the page with class <em>toggle-online-users</em>.</p>
<p>If this options is set to true, the controlbox will by default be shown upon <p>If this options is set to true, the controlbox will by default be shown upon
page load.</p> page load.</p>
</div> </div>
<div class="section" id="show-call-button">
<h3><a class="toc-backref" href="#id52">show_call_button</a><a class="headerlink" href="#show-call-button" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p>
<p>Enable to display a call button on the chatbox toolbar.</p>
<p>When the call button is pressed, it will emit an event that can be used by a third-party library to initiate a call.</p>
<div class="highlight-python"><pre>converse.on('onCallButtonClicked', function(event, data) {
console.log('Call button was clicked.');
console.log('Strophe connection is', data.connection);
console.log('Bare buddy JID is', data.model.get('jid'));
// ... Third-party library code ...
});</pre>
</div>
</div>
<div class="section" id="show-only-online-users"> <div class="section" id="show-only-online-users">
<h3><a class="toc-backref" href="#id43">show_only_online_users</a><a class="headerlink" href="#show-only-online-users" title="Permalink to this headline"></a></h3> <h3><a class="toc-backref" href="#id53">show_only_online_users</a><a class="headerlink" href="#show-only-online-users" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p> <p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p>
<p>If set to <tt class="docutils literal"><span class="pre">true</span></tt>, only online users will be shown in the contacts roster. <p>If set to <tt class="docutils literal"><span class="pre">true</span></tt>, only online users will be shown in the contacts roster.
Users with any other status (e.g. away, busy etc.) will not be shown.</p> Users with any other status (e.g. away, busy etc.) will not be shown.</p>
</div> </div>
<div class="section" id="use-otr-by-default">
<h3><a class="toc-backref" href="#id54">use_otr_by_default</a><a class="headerlink" href="#use-otr-by-default" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p>
<p>If set to <tt class="docutils literal"><span class="pre">true</span></tt>, Converse.js will automatically try to initiate an OTR (off-the-record)
encrypted chat session every time you open a chat box.</p>
</div>
<div class="section" id="use-vcards"> <div class="section" id="use-vcards">
<h3><a class="toc-backref" href="#id44">use_vcards</a><a class="headerlink" href="#use-vcards" title="Permalink to this headline"></a></h3> <h3><a class="toc-backref" href="#id55">use_vcards</a><a class="headerlink" href="#use-vcards" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">true</span></tt></p> <p>Default = <tt class="docutils literal"><span class="pre">true</span></tt></p>
<p>Determines whether the XMPP server will be queried for roster contacts&#8217; VCards <p>Determines whether the XMPP server will be queried for roster contacts&#8217; VCards
or not. VCards contain extra personal information such as your fullname and or not. VCards contain extra personal information such as your fullname and
avatar image.</p> avatar image.</p>
</div> </div>
<div class="section" id="xhr-custom-status"> <div class="section" id="xhr-custom-status">
<h3><a class="toc-backref" href="#id45">xhr_custom_status</a><a class="headerlink" href="#xhr-custom-status" title="Permalink to this headline"></a></h3> <h3><a class="toc-backref" href="#id56">xhr_custom_status</a><a class="headerlink" href="#xhr-custom-status" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p> <p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p>
<div class="admonition note"> <div class="admonition note">
<p class="first admonition-title">Note</p> <p class="first admonition-title">Note</p>
@ -791,7 +990,7 @@ avatar image.</p>
remote server.</p> remote server.</p>
</div> </div>
<div class="section" id="xhr-custom-status-url"> <div class="section" id="xhr-custom-status-url">
<h3><a class="toc-backref" href="#id46">xhr_custom_status_url</a><a class="headerlink" href="#xhr-custom-status-url" title="Permalink to this headline"></a></h3> <h3><a class="toc-backref" href="#id57">xhr_custom_status_url</a><a class="headerlink" href="#xhr-custom-status-url" title="Permalink to this headline"></a></h3>
<div class="admonition note"> <div class="admonition note">
<p class="first admonition-title">Note</p> <p class="first admonition-title">Note</p>
<p class="last">XHR stands for XMLHTTPRequest, and is meant here in the AJAX sense (Asynchronous Javascript and XML).</p> <p class="last">XHR stands for XMLHTTPRequest, and is meant here in the AJAX sense (Asynchronous Javascript and XML).</p>
@ -803,7 +1002,7 @@ message will be made.</p>
<p>The message itself is sent in the request under the key <tt class="docutils literal"><span class="pre">msg</span></tt>.</p> <p>The message itself is sent in the request under the key <tt class="docutils literal"><span class="pre">msg</span></tt>.</p>
</div> </div>
<div class="section" id="xhr-user-search"> <div class="section" id="xhr-user-search">
<h3><a class="toc-backref" href="#id47">xhr_user_search</a><a class="headerlink" href="#xhr-user-search" title="Permalink to this headline"></a></h3> <h3><a class="toc-backref" href="#id58">xhr_user_search</a><a class="headerlink" href="#xhr-user-search" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p> <p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p>
<div class="admonition note"> <div class="admonition note">
<p class="first admonition-title">Note</p> <p class="first admonition-title">Note</p>
@ -820,7 +1019,7 @@ message will be made.</p>
corresponds to a matched user and needs the keys <tt class="docutils literal"><span class="pre">id</span></tt> and <tt class="docutils literal"><span class="pre">fullname</span></tt>.</p> corresponds to a matched user and needs the keys <tt class="docutils literal"><span class="pre">id</span></tt> and <tt class="docutils literal"><span class="pre">fullname</span></tt>.</p>
</div> </div>
<div class="section" id="xhr-user-search-url"> <div class="section" id="xhr-user-search-url">
<h3><a class="toc-backref" href="#id48">xhr_user_search_url</a><a class="headerlink" href="#xhr-user-search-url" title="Permalink to this headline"></a></h3> <h3><a class="toc-backref" href="#id59">xhr_user_search_url</a><a class="headerlink" href="#xhr-user-search-url" title="Permalink to this headline"></a></h3>
<div class="admonition note"> <div class="admonition note">
<p class="first admonition-title">Note</p> <p class="first admonition-title">Note</p>
<p class="last">XHR stands for XMLHTTPRequest, and is meant here in the AJAX sense (Asynchronous Javascript and XML).</p> <p class="last">XHR stands for XMLHTTPRequest, and is meant here in the AJAX sense (Asynchronous Javascript and XML).</p>
@ -831,101 +1030,6 @@ corresponds to a matched user and needs the keys <tt class="docutils literal"><s
The query string will be included in the request with <tt class="docutils literal"><span class="pre">q</span></tt> as its key.</p> The query string will be included in the request with <tt class="docutils literal"><span class="pre">q</span></tt> as its key.</p>
</div> </div>
</div> </div>
</div>
<div class="section" id="minification">
<h1><a class="toc-backref" href="#id49">Minification</a><a class="headerlink" href="#minification" title="Permalink to this headline"></a></h1>
<div class="section" id="minifying-javascript-and-css">
<h2><a class="toc-backref" href="#id50">Minifying Javascript and CSS</a><a class="headerlink" href="#minifying-javascript-and-css" title="Permalink to this headline"></a></h2>
<p>Please make sure to read the section <a class="reference internal" href="#development">Development</a> and that you have installed
all development dependencies (long story short, you can run <tt class="docutils literal"><span class="pre">npm</span> <span class="pre">install</span></tt>
and then <tt class="docutils literal"><span class="pre">grunt</span> <span class="pre">fetch</span></tt>).</p>
<p>We use <a class="reference external" href="http://requirejs.org">require.js</a> to keep track of <em>Converse.js</em> and its dependencies and to
to bundle them together in a single minified file fit for deployment to a
production site.</p>
<p>To minify the Javascript and CSS, run the following command:</p>
<div class="highlight-python"><pre>grunt minify</pre>
</div>
<p>Javascript will be bundled and minified with <a class="reference external" href="http://requirejs.org">require.js</a>&#8216;s optimization tool,
using <a class="reference external" href="https://github.com/jrburke/almond">almond</a>.</p>
<p>You can <a class="reference external" href="http://requirejs.org/docs/optimization.html">read more about require.js&#8217;s optimizer here</a>.</p>
<p>CSS is minified via <a class="reference external" href="https://github.com/gruntjs/grunt-contrib-cssmin">cssmin</a>.</p>
</div>
</div>
<div class="section" id="translations">
<h1><a class="toc-backref" href="#id51">Translations</a><a class="headerlink" href="#translations" title="Permalink to this headline"></a></h1>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Translations take up a lot of space and will bloat your minified file.
At the time of writing, all the translations add about 50KB of extra data to
the minified javascript file. Therefore, make sure to only
include those languages that you intend to support and remove from
./locale/locales.js those which you don&#8217;t need. Remember to rebuild the
minified file afterwards.</p>
</div>
<p>The gettext POT file located in ./locale/converse.pot is the template
containing all translations and from which for each language an individual PO
file is generated.</p>
<p>The POT file contains all translateable strings extracted from converse.js.</p>
<p>To make a user facing string translateable, wrap it in the double underscore helper
function like so:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">__</span><span class="p">(</span><span class="s">&#39;This string will be translated at runtime&#39;</span><span class="p">);</span>
</pre></div>
</div>
<p>After adding the string, you&#8217;ll need to regenerate the POT file, like so:</p>
<div class="highlight-python"><pre>make pot</pre>
</div>
<p>You can then create or update the PO file for a specific language by doing the following:</p>
<div class="highlight-python"><pre>msgmerge ./locale/de/LC_MESSAGES/converse.po ./locale/converse.pot -U</pre>
</div>
<p>To do this for ALL languages, run:</p>
<div class="highlight-python"><pre>make merge</pre>
</div>
<p>The resulting PO file is then what gets translated.</p>
<p>If you&#8217;ve created a new PO file, please make sure to add the following
attributes at the top of the file (under <em>Content-Transfer-Encoding</em>). They are
required as configuration settings for Jed, the Javascript translations library
that we&#8217;re using.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="s">&quot;domain: converse</span><span class="se">\n</span><span class="s">&quot;</span>
<span class="s">&quot;lang: de</span><span class="se">\n</span><span class="s">&quot;</span>
<span class="s">&quot;plural_forms: nplurals=2; plural=(n != 1);</span><span class="se">\n</span><span class="s">&quot;</span>
</pre></div>
</div>
<p>Unfortunately <a class="reference external" href="http://slexaxton.github.io/Jed">Jed</a> cannot use the PO files directly. We have to generate from it
a file in JSON format and then put that in a .js file for the specific
language.</p>
<p>To generate JSON from a PO file, you&#8217;ll need po2json for node.js. Run the
following command to install it (npm being the node.js package manager):</p>
<div class="highlight-python"><pre>npm install po2json</pre>
</div>
<p>You can then convert the translations into JSON format:</p>
<div class="highlight-python"><pre>po2json locale/de/LC_MESSAGES/converse.po locale/de/LC_MESSAGES/converse.json</pre>
</div>
<p>Now from converse.json paste the data as a value for the &#8220;locale_data&#8221; key in the
object in the language&#8217;s .js file.</p>
<p>So, if you are for example translating into German (language code &#8216;de&#8217;), you&#8217;ll
create or update the file ./locale/LC_MESSAGES/de.js with the following code:</p>
<div class="highlight-python"><pre>(function (root, factory) {
define("de", ['jed'], function () {
return factory(new Jed({
"domain": "converse",
"locale_data": {
// Paste the JSON data from converse.json here
}
})
}
}(this, function (i18n) {
return i18n;
}));</pre>
</div>
<p>making sure to also paste the JSON data as value to the &#8220;locale_data&#8221; key.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">If you are adding translations for a new language that is not already supported,
you&#8217;ll have to make one more edit in ./locale/locales.js to make sure the
language is loaded by require.js.</p>
</div>
<p>Congratulations, you&#8217;ve now succesfully added your translations. Sorry for all
those hoops you had to jump through.</p>
</div> </div>
@ -941,7 +1045,7 @@ those hoops you had to jump through.</p>
<li class="right" style="margin-right: 10px"> <li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index" <a href="genindex.html" title="General Index"
>index</a></li> >index</a></li>
<li><a href="#">Converse.js 0.7.1 documentation</a> &raquo;</li> <li><a href="#">Converse.js 0.7.3 documentation</a> &raquo;</li>
</ul> </ul>
</div> </div>
</div> </div>

View File

@ -1,6 +1,6 @@
# Sphinx inventory version 2 # Sphinx inventory version 2
# Project: Converse.js # Project: Converse.js
# Version: 0.7.1 # Version: 0.7.3
# The remainder of this file is compressed using zlib. # The remainder of this file is compressed using zlib.
xÚmÎÁ xÚmÎÁ
à à{Ÿ"°³ƒ]÷; à à{Ÿ"°³ƒ]÷;

View File

@ -7,7 +7,7 @@
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Search &mdash; Converse.js 0.7.1 documentation</title> <title>Search &mdash; Converse.js 0.7.3 documentation</title>
<link rel="stylesheet" href="_static/stylesheet.css" type="text/css" /> <link rel="stylesheet" href="_static/stylesheet.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" /> <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
@ -15,7 +15,7 @@
<script type="text/javascript"> <script type="text/javascript">
var DOCUMENTATION_OPTIONS = { var DOCUMENTATION_OPTIONS = {
URL_ROOT: '', URL_ROOT: '',
VERSION: '0.7.1', VERSION: '0.7.3',
COLLAPSE_INDEX: false, COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html', FILE_SUFFIX: '.html',
HAS_SOURCE: true HAS_SOURCE: true
@ -25,7 +25,7 @@
<script type="text/javascript" src="_static/underscore.js"></script> <script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script> <script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/searchtools.js"></script> <script type="text/javascript" src="_static/searchtools.js"></script>
<link rel="top" title="Converse.js 0.7.1 documentation" href="index.html" /> <link rel="top" title="Converse.js 0.7.3 documentation" href="index.html" />
<script type="text/javascript"> <script type="text/javascript">
jQuery(function() { Search.loadIndex("searchindex.js"); }); jQuery(function() { Search.loadIndex("searchindex.js"); });
</script> </script>
@ -55,7 +55,7 @@
<li class="right" style="margin-right: 10px"> <li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index" <a href="genindex.html" title="General Index"
accesskey="I">index</a></li> accesskey="I">index</a></li>
<li><a href="index.html">Converse.js 0.7.1 documentation</a> &raquo;</li> <li><a href="index.html">Converse.js 0.7.3 documentation</a> &raquo;</li>
</ul> </ul>
</div> </div>
<section id="main_content" class="inner"> <section id="main_content" class="inner">
@ -100,7 +100,7 @@
<li class="right" style="margin-right: 10px"> <li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index" <a href="genindex.html" title="General Index"
>index</a></li> >index</a></li>
<li><a href="index.html">Converse.js 0.7.1 documentation</a> &raquo;</li> <li><a href="index.html">Converse.js 0.7.3 documentation</a> &raquo;</li>
</ul> </ul>
</div> </div>
</div> </div>

File diff suppressed because one or more lines are too long

View File

@ -48,9 +48,9 @@ copyright = u'2013, JC Brand'
# built documents. # built documents.
# #
# The short X.Y version. # The short X.Y version.
version = '0.7.2' version = '0.7.3'
# The full version, including alpha/beta/rc tags. # The full version, including alpha/beta/rc tags.
release = '0.7.2' release = '0.7.3'
# The language for content autogenerated by Sphinx. Refer to documentation # The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages. # for a list of supported languages.

View File

@ -277,6 +277,17 @@ These values are then passed to converse.js's ``initialize`` method.
**bosh_service_url** values. **bosh_service_url** values.
Example code for server-side prebinding
---------------------------------------
* PHP:
See `xmpp-prebind-php <https://github.com/candy-chat/xmpp-prebind-php>`_ by
Michael Weibel and the folks from Candy chat.
* Python:
See this `example Django application`_ by Jack Moffitt.
Setting up a BOSH server Setting up a BOSH server
------------------------ ------------------------
@ -295,7 +306,6 @@ Facebook integration
this myself. Feedback and patches from people who have succesfully done this this myself. Feedback and patches from people who have succesfully done this
will be appreciated. will be appreciated.
Converse.js uses `Strophe.js <http://strophe.im/strophejs>`_ to connect and Converse.js uses `Strophe.js <http://strophe.im/strophejs>`_ to connect and
communicate with the XMPP server. One nice thing about Strophe.js is that it communicate with the XMPP server. One nice thing about Strophe.js is that it
can be extended via `plugins <http://github.com/strophe/strophejs-plugins>`_. can be extended via `plugins <http://github.com/strophe/strophejs-plugins>`_.
@ -339,6 +349,39 @@ The connection is already created inside Converse.js, so the
If someone submits a sane patch that does the above, I'll be happy to merge it. If someone submits a sane patch that does the above, I'll be happy to merge it.
Until then, people will have to do this themselves. Until then, people will have to do this themselves.
========
Features
========
Off-the-record encryption
=========================
Converse.js supports `Off-the-record (OTR) <https://otr.cypherpunks.ca/>`_
encrypted messaging.
The OTR protocol not only **encrypts your messages**, it provides ways to
**verify the identity** of the person you are talking to,
**plausible deniability** and **perfect forward secrecy** by generating
new encryption keys for each conversation.
In its current state, Javascript cryptography is fraught with dangers and
challenges that make it impossible to reach the same standard of security that
is available with native "desktop" software.
This is due to its runtime malleability, the way it is "installed" (e.g.
served) and the browser's lack of cryptographic primitives needed to implement
secure crypto.
For harsh but fairly valid criticism of Javascript cryptography, read:
`Javascript Cryptography Considered Harmful <http://www.matasano.com/articles/javascript-cryptography/>`_.
To get an idea on how this applies to OTR support in Converse.js, please read
`my thoughts on it <https://opkode.com/media/blog/2013/11/11/conversejs-otr-support>`_.
For now, suffice to say that although its useful to have OTR support in
Converse.js in order to avoid most eavesdroppers, if you need serious
communications privacy, then you're much better off using native software.
=========== ===========
Development Development
=========== ===========
@ -387,6 +430,7 @@ If you don't have grunt installed globally, you need to specify the relative
path: path:
:: ::
./node_modules/.bin/grunt fetch ./node_modules/.bin/grunt fetch
This will call Bower in the background to fetch all the front-end This will call Bower in the background to fetch all the front-end
@ -467,6 +511,137 @@ You can run both the tests and jshint in one go by calling:
grunt check grunt check
Minification
============
Minifying Javascript and CSS
----------------------------
Please make sure to read the section `Development`_ and that you have installed
all development dependencies (long story short, you can run ``npm install``
and then ``grunt fetch``).
We use `require.js`_ to keep track of *Converse.js* and its dependencies and to
to bundle them together in a single minified file fit for deployment to a
production site.
To minify the Javascript and CSS, run the following command:
::
grunt minify
Javascript will be bundled and minified with `require.js`_'s optimization tool,
using `almond <https://github.com/jrburke/almond>`_.
You can `read more about require.js's optimizer here`_.
CSS is minified via `cssmin <https://github.com/gruntjs/grunt-contrib-cssmin>`_.
Translations
============
.. Note ::
Translations take up a lot of space and will bloat your minified file.
At the time of writing, all the translations add about 50KB of extra data to
the minified javascript file. Therefore, make sure to only
include those languages that you intend to support and remove from
./locale/locales.js those which you don't need. Remember to rebuild the
minified file afterwards.
The gettext POT file located in ./locale/converse.pot is the template
containing all translations and from which for each language an individual PO
file is generated.
The POT file contains all translateable strings extracted from converse.js.
To make a user facing string translateable, wrap it in the double underscore helper
function like so:
::
__('This string will be translated at runtime');
After adding the string, you'll need to regenerate the POT file, like so:
::
make pot
You can then create or update the PO file for a specific language by doing the following:
::
msgmerge ./locale/de/LC_MESSAGES/converse.po ./locale/converse.pot -U
To do this for ALL languages, run:
::
make merge
The resulting PO file is then what gets translated.
If you've created a new PO file, please make sure to add the following
attributes at the top of the file (under *Content-Transfer-Encoding*). They are
required as configuration settings for Jed, the Javascript translations library
that we're using.
::
"domain: converse\n"
"lang: de\n"
"plural_forms: nplurals=2; plural=(n != 1);\n"
Unfortunately `Jed <http://slexaxton.github.io/Jed>`_ cannot use the PO files directly. We have to generate from it
a file in JSON format and then put that in a .js file for the specific
language.
To generate JSON from a PO file, you'll need po2json for node.js. Run the
following command to install it (npm being the node.js package manager):
::
npm install po2json
You can then convert the translations into JSON format:
::
po2json locale/de/LC_MESSAGES/converse.po locale/de/LC_MESSAGES/converse.json
Now from converse.json paste the data as a value for the "locale_data" key in the
object in the language's .js file.
So, if you are for example translating into German (language code 'de'), you'll
create or update the file ./locale/LC_MESSAGES/de.js with the following code:
::
(function (root, factory) {
define("de", ['jed'], function () {
return factory(new Jed({
"domain": "converse",
"locale_data": {
// Paste the JSON data from converse.json here
}
})
}
}(this, function (i18n) {
return i18n;
}));
making sure to also paste the JSON data as value to the "locale_data" key.
.. Note ::
If you are adding translations for a new language that is not already supported,
you'll have to make one more edit in ./locale/locales.js to make sure the
language is loaded by require.js.
Congratulations, you've now succesfully added your translations. Sorry for all
those hoops you had to jump through.
=============== ===============
Troubleshooting Troubleshooting
@ -736,6 +911,14 @@ For each room on the server a query is made to fetch further details (e.g.
features, number of occupants etc.), so on servers with many rooms this features, number of occupants etc.), so on servers with many rooms this
option will create lots of extra connection traffic. option will create lots of extra connection traffic.
auto_reconnect
--------------
Default = ``true``
Automatically reconnect to the XMPP server if the connection drops
unexpectedly.
auto_subscribe auto_subscribe
-------------- --------------
@ -751,6 +934,30 @@ a middle man between HTTP and XMPP.
See `here <http://metajack.im/2008/09/08/which-bosh-server-do-you-need>`_ for more information. See `here <http://metajack.im/2008/09/08/which-bosh-server-do-you-need>`_ for more information.
cache_otr_key
-------------
Default = ``false``
Let the `OTR (Off-the-record encryption) <https://otr.cypherpunks.ca>`_ private
key be cached in your browser's session storage.
The browser's session storage persists across page loads but is deleted once
the tab or window is closed.
If this option is set to ``false``, a new OTR private key will be generated
for each page load. While more inconvenient, this is a much more secure option.
This setting can only be used together with ``allow_otr = true``.
.. Note ::
A browser window's session storage is accessible by all javascript that
is served from the same domain. So if there is malicious javascript served by
the same server (or somehow injected via an attacker), then they will be able
to retrieve your private key and read your all the chat messages in your
current session. Previous sessions however cannot be decrypted.
debug debug
----- -----
@ -758,6 +965,16 @@ Default = ``false``
If set to true, debugging output will be logged to the browser console. If set to true, debugging output will be logged to the browser console.
expose_rid_and_sid
------------------
Allow the prebind tokens, RID (request ID) and SID (session ID), to be exposed
globally via the API. This allows other scripts served on the same page to use
these values.
*Beware*: a malicious script could use these tokens to assume your identity
and inject fake chat messages.
fullname fullname
-------- --------
@ -843,6 +1060,14 @@ Default = ``false``
If set to ``true``, only online users will be shown in the contacts roster. If set to ``true``, only online users will be shown in the contacts roster.
Users with any other status (e.g. away, busy etc.) will not be shown. Users with any other status (e.g. away, busy etc.) will not be shown.
use_otr_by_default
------------------
Default = ``false``
If set to ``true``, Converse.js will automatically try to initiate an OTR (off-the-record)
encrypted chat session every time you open a chat box.
use_vcards use_vcards
---------- ----------
@ -911,140 +1136,6 @@ Used only in conjunction with ``xhr_user_search``.
This is the URL to which an AJAX GET request will be made to fetch user data from your remote server. This is the URL to which an AJAX GET request will be made to fetch user data from your remote server.
The query string will be included in the request with ``q`` as its key. The query string will be included in the request with ``q`` as its key.
============
Minification
============
Minifying Javascript and CSS
============================
Please make sure to read the section `Development`_ and that you have installed
all development dependencies (long story short, you can run ``npm install``
and then ``grunt fetch``).
We use `require.js`_ to keep track of *Converse.js* and its dependencies and to
to bundle them together in a single minified file fit for deployment to a
production site.
To minify the Javascript and CSS, run the following command:
::
grunt minify
Javascript will be bundled and minified with `require.js`_'s optimization tool,
using `almond <https://github.com/jrburke/almond>`_.
You can `read more about require.js's optimizer here`_.
CSS is minified via `cssmin <https://github.com/gruntjs/grunt-contrib-cssmin>`_.
============
Translations
============
.. Note ::
Translations take up a lot of space and will bloat your minified file.
At the time of writing, all the translations add about 50KB of extra data to
the minified javascript file. Therefore, make sure to only
include those languages that you intend to support and remove from
./locale/locales.js those which you don't need. Remember to rebuild the
minified file afterwards.
The gettext POT file located in ./locale/converse.pot is the template
containing all translations and from which for each language an individual PO
file is generated.
The POT file contains all translateable strings extracted from converse.js.
To make a user facing string translateable, wrap it in the double underscore helper
function like so:
::
__('This string will be translated at runtime');
After adding the string, you'll need to regenerate the POT file, like so:
::
make pot
You can then create or update the PO file for a specific language by doing the following:
::
msgmerge ./locale/de/LC_MESSAGES/converse.po ./locale/converse.pot -U
To do this for ALL languages, run:
::
make merge
The resulting PO file is then what gets translated.
If you've created a new PO file, please make sure to add the following
attributes at the top of the file (under *Content-Transfer-Encoding*). They are
required as configuration settings for Jed, the Javascript translations library
that we're using.
::
"domain: converse\n"
"lang: de\n"
"plural_forms: nplurals=2; plural=(n != 1);\n"
Unfortunately `Jed <http://slexaxton.github.io/Jed>`_ cannot use the PO files directly. We have to generate from it
a file in JSON format and then put that in a .js file for the specific
language.
To generate JSON from a PO file, you'll need po2json for node.js. Run the
following command to install it (npm being the node.js package manager):
::
npm install po2json
You can then convert the translations into JSON format:
::
po2json locale/de/LC_MESSAGES/converse.po locale/de/LC_MESSAGES/converse.json
Now from converse.json paste the data as a value for the "locale_data" key in the
object in the language's .js file.
So, if you are for example translating into German (language code 'de'), you'll
create or update the file ./locale/LC_MESSAGES/de.js with the following code:
::
(function (root, factory) {
define("de", ['jed'], function () {
return factory(new Jed({
"domain": "converse",
"locale_data": {
// Paste the JSON data from converse.json here
}
})
}
}(this, function (i18n) {
return i18n;
}));
making sure to also paste the JSON data as value to the "locale_data" key.
.. Note ::
If you are adding translations for a new language that is not already supported,
you'll have to make one more edit in ./locale/locales.js to make sure the
language is loaded by require.js.
Congratulations, you've now succesfully added your translations. Sorry for all
those hoops you had to jump through.
.. _`read more about require.js's optimizer here`: http://requirejs.org/docs/optimization.html .. _`read more about require.js's optimizer here`: http://requirejs.org/docs/optimization.html
.. _`HTTP`: https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol .. _`HTTP`: https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol
.. _`XMPP`: https://en.wikipedia.org/wiki/Xmpp .. _`XMPP`: https://en.wikipedia.org/wiki/Xmpp

View File

@ -7,8 +7,8 @@
<meta name="description" content="Converse.js: Open Source Browser-Based Instant Messaging" /> <meta name="description" content="Converse.js: Open Source Browser-Based Instant Messaging" />
<link rel="stylesheet" type="text/css" media="screen" href="stylesheets/stylesheet.css"> <link rel="stylesheet" type="text/css" media="screen" href="stylesheets/stylesheet.css">
<link rel="stylesheet" type="text/css" media="screen" href="converse.css"> <link rel="stylesheet" type="text/css" media="screen" href="converse.css">
<script data-main="main" src="components/requirejs/require.js"></script> <!--<script data-main="main" src="components/requirejs/require.js"></script>-->
<!--<script src="builds/converse.min.js"></script>--> <script src="builds/converse.min.js"></script>
<title>Converse.js</title> <title>Converse.js</title>
</head> </head>
@ -54,7 +54,7 @@
<li>Custom status messages</li> <li>Custom status messages</li>
<li>Typing notifications</li> <li>Typing notifications</li>
<li>Third person messages (/me )</li> <li>Third person messages (/me )</li>
<li>Translated into multiple languages (af, de, es, fr, hu, it, nl, pt-BR, ru)</li> <li>Translated into multiple languages (af, de, en, es, fr, he, hu, id, it, ja, nl, pt_BR, ru)</li>
<li>Off-the-record encryption (via <a href="http://arlolra.github.io/otr/" target="_blank">OTR.js</a>)</li> <li>Off-the-record encryption (via <a href="http://arlolra.github.io/otr/" target="_blank">OTR.js</a>)</li>
</ul> </ul>
@ -159,9 +159,17 @@
You can: You can:
<ul> <ul>
<li>Follow me on <a href="http://twitter.com/jcopkode" target="_blank">Twitter</a></li> <li>Follow me on <a href="http://twitter.com/jcopkode" target="_blank">Twitter</a></li>
<li>Chat via <a href="xmpp:jc@opkode.com" class="xmpp JSnocheck" title="XMPP/Jabber">XMPP/Jabber</a></li> <li>Chat with me via XMPP: <a href="xmpp:jc@opkode.com" class="xmpp JSnocheck" title="XMPP/Jabber">jc@opkode.com</a></li>
<li>Send me an email via this <a href="http://opkode.com/contact" target="_blank">contact form</a>.</li>
<ul> <ul>
<p>
For <strong>support queries</strong>, please write to the mailing list: <a href="mailto:conversejs@librelist.com">conversejs@librelist.com</a>
</p>
<p>
Please <a target="_blank" href="https://github.com/jcbrand/converse.js/issues">file <strong>bugs</strong> on Github</a>.
</p>
<p>
I'm available for special features and consulting work. Please <a href="http://opkode.com/contact" target="_blank">contact me here</a>.
</p>
</section> </section>
</div> </div>
@ -186,7 +194,7 @@
allow_otr: true, allow_otr: true,
auto_list_rooms: false, auto_list_rooms: false,
auto_subscribe: false, auto_subscribe: false,
bosh_service_url: 'http://devbox:8890/http-bind', // Please use this connection manager only for testing purposes bosh_service_url: 'https://bind.opkode.im', // Please use this connection manager only for testing purposes
debug: true , debug: true ,
hide_muc_server: false, hide_muc_server: false,
i18n: locales['en'], // Refer to ./locale/locales.js to see which locales are supported i18n: locales['en'], // Refer to ./locale/locales.js to see which locales are supported

View File

@ -6,9 +6,9 @@
#, fuzzy #, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Converse.js 0.4\n" "Project-Id-Version: Converse.js 0.7.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-09-15 22:06+0200\n" "POT-Creation-Date: 2014-01-28 03:50+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -17,66 +17,94 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n" "Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: converse.js:125 #: converse.js:217
msgid "unencrypted" msgid "unencrypted"
msgstr "" msgstr ""
#: converse.js:126 #: converse.js:218
msgid "unverified" msgid "unverified"
msgstr "" msgstr ""
#: converse.js:127 #: converse.js:219
msgid "verified" msgid "verified"
msgstr "" msgstr ""
#: converse.js:128 #: converse.js:220
msgid "finished" msgid "finished"
msgstr "" msgstr ""
#: converse.js:161 #: converse.js:223
msgid "This contact is busy"
msgstr ""
#: converse.js:224
msgid "This contact is online"
msgstr ""
#: converse.js:225
msgid "This contact is offline"
msgstr ""
#: converse.js:226
msgid "This contact is unavailable"
msgstr ""
#: converse.js:227
msgid "This contact is away for an extended period"
msgstr ""
#: converse.js:228
msgid "This contact is away"
msgstr ""
#: converse.js:321
msgid "Disconnected" msgid "Disconnected"
msgstr "" msgstr ""
#: converse.js:165 #: converse.js:331
msgid "Error" msgid "Error"
msgstr "" msgstr ""
#: converse.js:167 #: converse.js:333
msgid "Connecting" msgid "Connecting"
msgstr "" msgstr ""
#: converse.js:170 #: converse.js:336
msgid "Connection Failed" msgid "Connection Failed"
msgstr "" msgstr ""
#: converse.js:172 #: converse.js:338
msgid "Authenticating" msgid "Authenticating"
msgstr "" msgstr ""
#: converse.js:175 #: converse.js:341
msgid "Authentication Failed" msgid "Authentication Failed"
msgstr "" msgstr ""
#: converse.js:177 #: converse.js:343
msgid "Disconnecting" msgid "Disconnecting"
msgstr "" msgstr ""
#: converse.js:332 #: converse.js:479
msgid "Online Contacts"
msgstr ""
#: converse.js:540
msgid "Re-establishing encrypted session" msgid "Re-establishing encrypted session"
msgstr "" msgstr ""
#: converse.js:340 #: converse.js:548
msgid "" msgid ""
"Your browser needs to generate a private key, which will be used in your " "Your browser needs to generate a private key, which will be used in your "
"encrypted chat session. This can take up to 30 seconds during which your " "encrypted chat session. This can take up to 30 seconds during which your "
"browser might freeze and become unresponsive." "browser might freeze and become unresponsive."
msgstr "" msgstr ""
#: converse.js:349 #: converse.js:557
msgid "Private key generated." msgid "Private key generated."
msgstr "" msgstr ""
#: converse.js:380 #: converse.js:588
msgid "" msgid ""
"Authentication request from %1$s\n" "Authentication request from %1$s\n"
"\n" "\n"
@ -86,71 +114,71 @@ msgid ""
"%2$s" "%2$s"
msgstr "" msgstr ""
#: converse.js:389 #: converse.js:597
msgid "Could not verify this user's identify." msgid "Could not verify this user's identify."
msgstr "" msgstr ""
#: converse.js:537 #: converse.js:750
msgid "Personal message" msgid "Personal message"
msgstr "" msgstr ""
#: converse.js:559 #: converse.js:795
msgid "Start encrypted conversation" msgid "Start encrypted conversation"
msgstr "" msgstr ""
#: converse.js:562 #: converse.js:798
msgid "Refresh encrypted conversation" msgid "Refresh encrypted conversation"
msgstr "" msgstr ""
#: converse.js:563 #: converse.js:799
msgid "End encrypted conversation" msgid "End encrypted conversation"
msgstr "" msgstr ""
#: converse.js:564 #: converse.js:800
msgid "Verify with SMP" msgid "Verify with SMP"
msgstr "" msgstr ""
#: converse.js:567 #: converse.js:803
msgid "Verify with fingerprints" msgid "Verify with fingerprints"
msgstr "" msgstr ""
#: converse.js:569 #: converse.js:805
msgid "What's this?" msgid "What's this?"
msgstr "" msgstr ""
#: converse.js:641 #: converse.js:906
msgid "me" msgid "me"
msgstr "" msgstr ""
#: converse.js:757 converse.js:1552 #: converse.js:1022 converse.js:1864
msgid "Show this menu" msgid "Show this menu"
msgstr "" msgstr ""
#: converse.js:758 converse.js:1553 #: converse.js:1023 converse.js:1865
msgid "Write in the third person" msgid "Write in the third person"
msgstr "" msgstr ""
#: converse.js:759 converse.js:1557 #: converse.js:1024 converse.js:1869
msgid "Remove messages" msgid "Remove messages"
msgstr "" msgstr ""
#: converse.js:830 #: converse.js:1110
msgid "Your message could not be sent" msgid "Your message could not be sent"
msgstr "" msgstr ""
#: converse.js:833 #: converse.js:1113
msgid "We received an unencrypted message" msgid "We received an unencrypted message"
msgstr "" msgstr ""
#: converse.js:836 #: converse.js:1116
msgid "We received an unreadable encrypted message" msgid "We received an unreadable encrypted message"
msgstr "" msgstr ""
#: converse.js:845 #: converse.js:1125
msgid "This user has requested an encrypted session." msgid "This user has requested an encrypted session."
msgstr "" msgstr ""
#: converse.js:863 #: converse.js:1147
msgid "" msgid ""
"Here are the fingerprints, please confirm them with %1$s, outside of this " "Here are the fingerprints, please confirm them with %1$s, outside of this "
"chat.\n" "chat.\n"
@ -163,480 +191,452 @@ msgid ""
"Cancel." "Cancel."
msgstr "" msgstr ""
#: converse.js:876 #: converse.js:1160
msgid "" msgid ""
"You will be prompted to provide a security question and then an answer to " "You will be prompted to provide a security question and then an answer to "
"that question.\n" "that question.\n"
"\n" "\n"
"Your buddy will then be prompted the same question and if they type the " "Your buddy will then be prompted the same question and if they type the "
"exact same answer (case sensitive), their identity will have been verified." "exact same answer (case sensitive), their identity will be verified."
msgstr "" msgstr ""
#: converse.js:877 #: converse.js:1161
msgid "What is your security question?" msgid "What is your security question?"
msgstr "" msgstr ""
#: converse.js:879 #: converse.js:1163
msgid "What is the answer to the security question?" msgid "What is the answer to the security question?"
msgstr "" msgstr ""
#: converse.js:883 #: converse.js:1167
msgid "Invalid authentication scheme provided" msgid "Invalid authentication scheme provided"
msgstr "" msgstr ""
#: converse.js:953 #: converse.js:1248
msgid "Your messages are not encrypted anymore" msgid "Your messages are not encrypted anymore"
msgstr "" msgstr ""
#: converse.js:955 #: converse.js:1250
msgid "" msgid ""
"Your messages are now encrypted but your buddy's identity has not been " "Your messages are now encrypted but your buddy's identity has not been "
"verified." "verified."
msgstr "" msgstr ""
#: converse.js:957 #: converse.js:1252
msgid "Your buddy's identify has been verified." msgid "Your buddy's identify has been verified."
msgstr "" msgstr ""
#: converse.js:959 #: converse.js:1254
msgid "Your buddy has ended encryption on their end, you should do the same." msgid "Your buddy has ended encryption on their end, you should do the same."
msgstr "" msgstr ""
#: converse.js:968 #: converse.js:1263
msgid "Your messages are not encrypted. Click here to enable OTR encryption." msgid "Your messages are not encrypted. Click here to enable OTR encryption."
msgstr "" msgstr ""
#: converse.js:970 #: converse.js:1265
msgid "Your messages are encrypted, but your buddy has not been verified." msgid "Your messages are encrypted, but your buddy has not been verified."
msgstr "" msgstr ""
#: converse.js:972 #: converse.js:1267
msgid "Your messages are encrypted and your buddy verified." msgid "Your messages are encrypted and your buddy verified."
msgstr "" msgstr ""
#: converse.js:974 #: converse.js:1269
msgid "" msgid ""
"Your buddy has closed their end of the private session, you should do the " "Your buddy has closed their end of the private session, you should do the "
"same" "same"
msgstr "" msgstr ""
#: converse.js:1049 #: converse.js:1354
msgid "Contacts" msgid "Contacts"
msgstr "" msgstr ""
#: converse.js:1054 #: converse.js:1359
msgid "Online" msgid "Online"
msgstr "" msgstr ""
#: converse.js:1055 #: converse.js:1360
msgid "Busy" msgid "Busy"
msgstr "" msgstr ""
#: converse.js:1056 #: converse.js:1361
msgid "Away" msgid "Away"
msgstr "" msgstr ""
#: converse.js:1057 #: converse.js:1362
msgid "Offline" msgid "Offline"
msgstr "" msgstr ""
#: converse.js:1064 #: converse.js:1372
msgid "Click to add new chat contacts" msgid "Click to add new chat contacts"
msgstr "" msgstr ""
#: converse.js:1065 #: converse.js:1373
msgid "Add a contact" msgid "Add a contact"
msgstr "" msgstr ""
#: converse.js:1074 #: converse.js:1382
msgid "Contact username" msgid "Contact username"
msgstr "" msgstr ""
#: converse.js:1075 #: converse.js:1383
msgid "Add" msgid "Add"
msgstr "" msgstr ""
#: converse.js:1083 #: converse.js:1391
msgid "Contact name" msgid "Contact name"
msgstr "" msgstr ""
#: converse.js:1084 #: converse.js:1392
msgid "Search" msgid "Search"
msgstr "" msgstr ""
#: converse.js:1124 #: converse.js:1439
msgid "No users found" msgid "No users found"
msgstr "" msgstr ""
#: converse.js:1131 #: converse.js:1446
msgid "Click to add as a chat contact" msgid "Click to add as a chat contact"
msgstr "" msgstr ""
#: converse.js:1191 #: converse.js:1498
msgid "Click to open this room" msgid "Click to open this room"
msgstr "" msgstr ""
#: converse.js:1193 #: converse.js:1500
msgid "Show more information on this room" msgid "Show more information on this room"
msgstr "" msgstr ""
#: converse.js:1199 #: converse.js:1506
msgid "Description:" msgid "Description:"
msgstr "" msgstr ""
#: converse.js:1200 #: converse.js:1507
msgid "Occupants:" msgid "Occupants:"
msgstr "" msgstr ""
#: converse.js:1201 #: converse.js:1508
msgid "Features:" msgid "Features:"
msgstr "" msgstr ""
#: converse.js:1203 #: converse.js:1510
msgid "Requires authentication" msgid "Requires authentication"
msgstr "" msgstr ""
#: converse.js:1206 #: converse.js:1513
msgid "Hidden" msgid "Hidden"
msgstr "" msgstr ""
#: converse.js:1209 #: converse.js:1516
msgid "Requires an invitation" msgid "Requires an invitation"
msgstr "" msgstr ""
#: converse.js:1212 #: converse.js:1519
msgid "Moderated" msgid "Moderated"
msgstr "" msgstr ""
#: converse.js:1215 #: converse.js:1522
msgid "Non-anonymous" msgid "Non-anonymous"
msgstr "" msgstr ""
#: converse.js:1218 #: converse.js:1525
msgid "Open room" msgid "Open room"
msgstr "" msgstr ""
#: converse.js:1221 #: converse.js:1528
msgid "Permanent room" msgid "Permanent room"
msgstr "" msgstr ""
#: converse.js:1224 #: converse.js:1531
msgid "Public" msgid "Public"
msgstr "" msgstr ""
#: converse.js:1227 #: converse.js:1534
msgid "Semi-anonymous" msgid "Semi-anonymous"
msgstr "" msgstr ""
#: converse.js:1230 #: converse.js:1537
msgid "Temporary room" msgid "Temporary room"
msgstr "" msgstr ""
#: converse.js:1233 #: converse.js:1540
msgid "Unmoderated" msgid "Unmoderated"
msgstr "" msgstr ""
#: converse.js:1239 #: converse.js:1546
msgid "Rooms" msgid "Rooms"
msgstr "" msgstr ""
#: converse.js:1243 #: converse.js:1550
msgid "Room name" msgid "Room name"
msgstr "" msgstr ""
#: converse.js:1244 #: converse.js:1551
msgid "Nickname" msgid "Nickname"
msgstr "" msgstr ""
#: converse.js:1245 #: converse.js:1552
msgid "Server" msgid "Server"
msgstr "" msgstr ""
#: converse.js:1246 #: converse.js:1553
msgid "Join" msgid "Join"
msgstr "" msgstr ""
#: converse.js:1247 #: converse.js:1554
msgid "Show rooms" msgid "Show rooms"
msgstr "" msgstr ""
#. For translators: %1$s is a variable and will be replaced with the XMPP server name #. For translators: %1$s is a variable and will be replaced with the XMPP server name
#: converse.js:1282 #: converse.js:1589
msgid "No rooms on %1$s" msgid "No rooms on %1$s"
msgstr "" msgstr ""
#. For translators: %1$s is a variable and will be #. For translators: %1$s is a variable and will be
#. replaced with the XMPP server name #. replaced with the XMPP server name
#: converse.js:1297 #: converse.js:1604
msgid "Rooms on %1$s" msgid "Rooms on %1$s"
msgstr "" msgstr ""
#: converse.js:1554 #: converse.js:1866
msgid "Set chatroom topic" msgid "Set chatroom topic"
msgstr "" msgstr ""
#: converse.js:1555 #: converse.js:1867
msgid "Kick user from chatroom" msgid "Kick user from chatroom"
msgstr "" msgstr ""
#: converse.js:1556 #: converse.js:1868
msgid "Ban user from chatroom" msgid "Ban user from chatroom"
msgstr "" msgstr ""
#: converse.js:1583 #: converse.js:1898
msgid "Message" msgid "Message"
msgstr "" msgstr ""
#: converse.js:1697 converse.js:2783 #: converse.js:2013 converse.js:3168
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: converse.js:1698 #: converse.js:2014
msgid "Cancel" msgid "Cancel"
msgstr "" msgstr ""
#: converse.js:1745 #: converse.js:2061
msgid "An error occurred while trying to save the form." msgid "An error occurred while trying to save the form."
msgstr "" msgstr ""
#: converse.js:1791 #: converse.js:2107
msgid "This chatroom requires a password" msgid "This chatroom requires a password"
msgstr "" msgstr ""
#: converse.js:1792 #: converse.js:2108
msgid "Password: " msgid "Password: "
msgstr "" msgstr ""
#: converse.js:1793 #: converse.js:2109
msgid "Submit" msgid "Submit"
msgstr "" msgstr ""
#: converse.js:1807 #: converse.js:2123
msgid "This room is not anonymous" msgid "This room is not anonymous"
msgstr "" msgstr ""
#: converse.js:1808 #: converse.js:2124
msgid "This room now shows unavailable members" msgid "This room now shows unavailable members"
msgstr "" msgstr ""
#: converse.js:1809 #: converse.js:2125
msgid "This room does not show unavailable members" msgid "This room does not show unavailable members"
msgstr "" msgstr ""
#: converse.js:1810 #: converse.js:2126
msgid "Non-privacy-related room configuration has changed" msgid "Non-privacy-related room configuration has changed"
msgstr "" msgstr ""
#: converse.js:1811 #: converse.js:2127
msgid "Room logging is now enabled" msgid "Room logging is now enabled"
msgstr "" msgstr ""
#: converse.js:1812 #: converse.js:2128
msgid "Room logging is now disabled" msgid "Room logging is now disabled"
msgstr "" msgstr ""
#: converse.js:1813 #: converse.js:2129
msgid "This room is now non-anonymous" msgid "This room is now non-anonymous"
msgstr "" msgstr ""
#: converse.js:1814 #: converse.js:2130
msgid "This room is now semi-anonymous" msgid "This room is now semi-anonymous"
msgstr "" msgstr ""
#: converse.js:1815 #: converse.js:2131
msgid "This room is now fully-anonymous" msgid "This room is now fully-anonymous"
msgstr "" msgstr ""
#: converse.js:1816 #: converse.js:2132
msgid "A new room has been created" msgid "A new room has been created"
msgstr "" msgstr ""
#: converse.js:1817 #: converse.js:2133
msgid "Your nickname has been changed" msgid "Your nickname has been changed"
msgstr "" msgstr ""
#: converse.js:1831 #: converse.js:2147
msgid "<strong>%1$s</strong> has been banned" msgid "<strong>%1$s</strong> has been banned"
msgstr "" msgstr ""
#: converse.js:1832 #: converse.js:2148
msgid "<strong>%1$s</strong> has been kicked out" msgid "<strong>%1$s</strong> has been kicked out"
msgstr "" msgstr ""
#: converse.js:1833 #: converse.js:2149
msgid "<strong>%1$s</strong> has been removed because of an affiliation change" msgid "<strong>%1$s</strong> has been removed because of an affiliation change"
msgstr "" msgstr ""
#: converse.js:1834 #: converse.js:2150
msgid "<strong>%1$s</strong> has been removed for not being a member" msgid "<strong>%1$s</strong> has been removed for not being a member"
msgstr "" msgstr ""
#: converse.js:1838 converse.js:1898 #: converse.js:2154 converse.js:2214
msgid "You have been banned from this room" msgid "You have been banned from this room"
msgstr "" msgstr ""
#: converse.js:1839 #: converse.js:2155
msgid "You have been kicked from this room" msgid "You have been kicked from this room"
msgstr "" msgstr ""
#: converse.js:1840 #: converse.js:2156
msgid "You have been removed from this room because of an affiliation change" msgid "You have been removed from this room because of an affiliation change"
msgstr "" msgstr ""
#: converse.js:1841 #: converse.js:2157
msgid "" msgid ""
"You have been removed from this room because the room has changed to members-" "You have been removed from this room because the room has changed to members-"
"only and you're not a member" "only and you're not a member"
msgstr "" msgstr ""
#: converse.js:1842 #: converse.js:2158
msgid "" msgid ""
"You have been removed from this room because the MUC (Multi-user chat) " "You have been removed from this room because the MUC (Multi-user chat) "
"service is being shut down." "service is being shut down."
msgstr "" msgstr ""
#: converse.js:1896 #: converse.js:2212
msgid "You are not on the member list of this room" msgid "You are not on the member list of this room"
msgstr "" msgstr ""
#: converse.js:1902 #: converse.js:2218
msgid "No nickname was specified" msgid "No nickname was specified"
msgstr "" msgstr ""
#: converse.js:1906 #: converse.js:2222
msgid "You are not allowed to create new rooms" msgid "You are not allowed to create new rooms"
msgstr "" msgstr ""
#: converse.js:1908 #: converse.js:2224
msgid "Your nickname doesn't conform to this room's policies" msgid "Your nickname doesn't conform to this room's policies"
msgstr "" msgstr ""
#: converse.js:1910 #: converse.js:2226
msgid "Your nickname is already taken" msgid "Your nickname is already taken"
msgstr "" msgstr ""
#: converse.js:1912 #: converse.js:2228
msgid "This room does not (yet) exist" msgid "This room does not (yet) exist"
msgstr "" msgstr ""
#: converse.js:1914 #: converse.js:2230
msgid "This room has reached it's maximum number of occupants" msgid "This room has reached it's maximum number of occupants"
msgstr "" msgstr ""
#: converse.js:1993 #: converse.js:2309
msgid "Topic set by %1$s to: %2$s" msgid "Topic set by %1$s to: %2$s"
msgstr "" msgstr ""
#: converse.js:2009 #: converse.js:2330
msgid "This user is a moderator" msgid "This user is a moderator"
msgstr "" msgstr ""
#: converse.js:2012 #: converse.js:2333
msgid "This user can send messages in this room" msgid "This user can send messages in this room"
msgstr "" msgstr ""
#: converse.js:2015 #: converse.js:2336
msgid "This user can NOT send messages in this room" msgid "This user can NOT send messages in this room"
msgstr "" msgstr ""
#: converse.js:2225 #: converse.js:2562
msgid "Click to chat with this contact" msgid "Click to chat with this contact"
msgstr "" msgstr ""
#: converse.js:2228 converse.js:2232 #: converse.js:2565 converse.js:2569
msgid "Click to remove this contact" msgid "Click to remove this contact"
msgstr "" msgstr ""
#: converse.js:2263 #: converse.js:2919
msgid "This contact is busy"
msgstr ""
#: converse.js:2264
msgid "This contact is online"
msgstr ""
#: converse.js:2265
msgid "This contact is offline"
msgstr ""
#: converse.js:2266
msgid "This contact is unavailable"
msgstr ""
#: converse.js:2267
msgid "This contact is away for an extended period"
msgstr ""
#: converse.js:2268
msgid "This contact is away"
msgstr ""
#: converse.js:2622
msgid "Contact requests" msgid "Contact requests"
msgstr "" msgstr ""
#: converse.js:2623 #: converse.js:2922
msgid "My contacts" msgid "My contacts"
msgstr "" msgstr ""
#: converse.js:2624 #: converse.js:2925
msgid "Pending contacts" msgid "Pending contacts"
msgstr "" msgstr ""
#: converse.js:2782 #: converse.js:3167
msgid "Custom status" msgid "Custom status"
msgstr "" msgstr ""
#: converse.js:2788 #: converse.js:3173
msgid "Click to change your chat status" msgid "Click to change your chat status"
msgstr "" msgstr ""
#: converse.js:2792 #: converse.js:3177
msgid "Click here to write a custom status message" msgid "Click here to write a custom status message"
msgstr "" msgstr ""
#: converse.js:2821 converse.js:2829 #: converse.js:3206 converse.js:3214
msgid "online" msgid "online"
msgstr "" msgstr ""
#: converse.js:2823 #: converse.js:3208
msgid "busy" msgid "busy"
msgstr "" msgstr ""
#: converse.js:2825 #: converse.js:3210
msgid "away for long" msgid "away for long"
msgstr "" msgstr ""
#: converse.js:2827 #: converse.js:3212
msgid "away" msgid "away"
msgstr "" msgstr ""
#. For translators: the %1$s part gets replaced with the status #. For translators: the %1$s part gets replaced with the status
#. Example, I am online #. Example, I am online
#: converse.js:2841 converse.js:2878 #: converse.js:3226 converse.js:3263
msgid "I am %1$s" msgid "I am %1$s"
msgstr "" msgstr ""
#: converse.js:2949 #: converse.js:3334
msgid "Sign in" msgid "Sign in"
msgstr "" msgstr ""
#: converse.js:2952 #: converse.js:3338
msgid "XMPP/Jabber Username:" msgid "XMPP/Jabber Username:"
msgstr "" msgstr ""
#: converse.js:2954 #: converse.js:3340
msgid "Password:" msgid "Password:"
msgstr "" msgstr ""
#: converse.js:2956 #: converse.js:3342
msgid "Log In" msgid "Log In"
msgstr "" msgstr ""
#: converse.js:2960 #: converse.js:3346
msgid "BOSH Service URL:" msgid "BOSH Service URL:"
msgstr "" msgstr ""
#: converse.js:3113
msgid "Online Contacts"
msgstr ""

View File

@ -0,0 +1,605 @@
{
"converse": {
"": {
"Project-Id-Version": "Converse.js 0.7.0",
"Report-Msgid-Bugs-To": "",
"POT-Creation-Date": "2014-01-28 03:50+0200",
"PO-Revision-Date": "2014-02-21 06:07+0200",
"Last-Translator": "GreenLunar <GreenLunar@github.com>",
"Language-Team": "Rahut <http://sourceforge.net/projects/rahut/>",
"Language": "he",
"MIME-Version": "1.0",
"Content-Type": "text/plain; charset=UTF-8",
"Content-Transfer-Encoding": "8bit",
"X-Generator": "Poedit 1.5.1"
},
"unencrypted": [
null,
"לא מוצפנת"
],
"unverified": [
null,
"לא מאומתת"
],
"verified": [
null,
"מאומתת"
],
"finished": [
null,
"מוגמרת"
],
"This contact is busy": [
null,
"איש קשר זה עסוק"
],
"This contact is online": [
null,
"איש קשר זה מקוון"
],
"This contact is offline": [
null,
"איש קשר זה לא מקוון"
],
"This contact is unavailable": [
null,
"איש קשר זה לא זמין"
],
"This contact is away for an extended period": [
null,
"איש קשר זה נעדר למשך זמן ממושך"
],
"This contact is away": [
null,
"איש קשר זה הינו נעדר"
],
"Disconnected": [
null,
"מנותק"
],
"Error": [
null,
"שגיאה"
],
"Connecting": [
null,
"כעת מתחבר"
],
"Connection Failed": [
null,
"חיבור נכשל"
],
"Authenticating": [
null,
"כעת מאמת"
],
"Authentication Failed": [
null,
"אימות נכשל"
],
"Disconnecting": [
null,
"כעת מתנתק"
],
"Online Contacts": [
null,
"אנשי קשר מקוונים"
],
"Re-establishing encrypted session": [
null,
"בסס מחדש ישיבה מוצפנת"
],
"Your browser needs to generate a private key, which will be used in your encrypted chat session. This can take up to 30 seconds during which your browser might freeze and become unresponsive.": [
null,
"על הדפדפן שלך להפיק מפתח פרטי, אשר ישמש אותך בישיבות שיחה מוצפנות. פעולה זו יכולה לקחת למעלה מן 30 שניות אשר במהלכה הדפדפן שלך עשוי לקפוא ולהפוך לחסר תגובה."
],
"Private key generated.": [
null,
"מפתח פרטי הופק."
],
"Authentication request from %1$s\n\nYour buddy is attempting to verify your identity, by asking you the question below.\n\n%2$s": [
null,
"בקשת אימות מאת %1$s\n\nהאישיות שכנגד מנסה לאמת את הזהות שלך, בעזרת שאילת שאלה להלן.\n\n%2$s"
],
"Could not verify this user's identify.": [
null,
"לא היתה אפשרות לאמת את זהות משתמש זה."
],
"Personal message": [
null,
"הודעה אישית"
],
"Start encrypted conversation": [
null,
"התחל ישיבה מוצפנת"
],
"Refresh encrypted conversation": [
null,
"רענן ישיבה מוצפנת"
],
"End encrypted conversation": [
null,
"סיים ישיבה מוצפנת"
],
"Verify with SMP": [
null,
"אמת בעזרת SMP"
],
"Verify with fingerprints": [
null,
"אמת בעזרת טביעות אצבע"
],
"What's this?": [
null,
"מה זה?"
],
"me": [
null,
"אני"
],
"Show this menu": [
null,
"הצג את תפריט זה"
],
"Write in the third person": [
null,
"כתוב בגוף השלישי"
],
"Remove messages": [
null,
"הסר הודעות"
],
"Your message could not be sent": [
null,
"ההודעה שלך לא היתה יכולה להישלח"
],
"We received an unencrypted message": [
null,
"אנחנו קיבלנו הודעה לא מוצפנת"
],
"We received an unreadable encrypted message": [
null,
"אנחנו קיבלנו הודעה מוצפנת לא קריאה"
],
"This user has requested an encrypted session.": [
null,
"משתמש זה ביקש ישיבה מוצפנת."
],
"Here are the fingerprints, please confirm them with %1$s, outside of this chat.\n\nFingerprint for you, %2$s: %3$s\n\nFingerprint for %1$s: %4$s\n\nIf you have confirmed that the fingerprints match, click OK, otherwise click Cancel.": [
null,
"הרי טביעות האצבע, אנא אמת אותן עם %1$s, מחוץ לשיחה זו.\n\nטביעת אצבע עבורך, %2$s: %3$s\n\nטביעת אצבע עבור %1$s: %4$s\n\nהיה ואימתת כי טביעות האצבע תואמות, לחץ אישור (OK), אחרת לחץ ביטול (Cancel)."
],
"You will be prompted to provide a security question and then an answer to that question.\n\nYour buddy will then be prompted the same question and if they type the exact same answer (case sensitive), their identity will be verified.": [
null,
"אתה תתבקש לספק שאלת אבטחה ולאחריה תשובה לשאלה הזו.\n\nהאישיות שכנגד תתבקש עובר זאת לאותה שאלת אבטחה ואם זו תקלידו את את אותה התשובה במדויק (case sensitive), זהותה תאומת."
],
"What is your security question?": [
null,
"מהי שאלת האבטחה שלך?"
],
"What is the answer to the security question?": [
null,
"מהי התשובה לשאלת האבטחה?"
],
"Invalid authentication scheme provided": [
null,
"סופקה סכימת אימות שגויה"
],
"Your messages are not encrypted anymore": [
null,
"ההודעות שלך אינן מוצפנות עוד"
],
"Your messages are now encrypted but your buddy's identity has not been verified.": [
null,
"ההודעות שלך מוצפנות כעת אך זהות האישיות שכנגד טרם אומתה."
],
"Your buddy's identify has been verified.": [
null,
"זהות האישיות שכנגד אומתה."
],
"Your buddy has ended encryption on their end, you should do the same.": [
null,
"האישיות שכנגד סיימה הצפנה בקצה שלה, עליך לעשות את אותו הדבר."
],
"Your messages are not encrypted. Click here to enable OTR encryption.": [
null,
"ההודעות שלך אינן וצפנות. לחץ כאן כדי לאפשר OTR."
],
"Your messages are encrypted, but your buddy has not been verified.": [
null,
"ההודעות שלך מוצפנות כעת, אך האישיות שכנגד טרם אומתה."
],
"Your messages are encrypted and your buddy verified.": [
null,
"ההודעות שלך מוצפנות כעת והאישיות שכנגד אומתה."
],
"Your buddy has closed their end of the private session, you should do the same": [
null,
"האישיות שכנגד סגרה את קצה הישיבה הפרטית שלה, עליך לעשות את אותו הדבר."
],
"Contacts": [
null,
"אנשי קשר"
],
"Online": [
null,
"מקוון"
],
"Busy": [
null,
"עסוק"
],
"Away": [
null,
"נעדר"
],
"Offline": [
null,
"בלתי מקוון"
],
"Click to add new chat contacts": [
null,
"לחץ כדי להוסיף אנשי קשר שיחה חדשים"
],
"Add a contact": [
null,
"הוסף איש קשר"
],
"Contact username": [
null,
"שם משתמש איש קשר"
],
"Add": [
null,
"הוסף"
],
"Contact name": [
null,
"שם איש קשר"
],
"Search": [
null,
"חיפוש"
],
"No users found": [
null,
"לא נמצאו משתמשים"
],
"Click to add as a chat contact": [
null,
"לחץ כדי להוסיף בתור איש קשר שיחה"
],
"Click to open this room": [
null,
"לחץ כדי לפתוח את חדר זה"
],
"Show more information on this room": [
null,
"הצג עוד מידע אודות חדר זה"
],
"Description:": [
null,
"תיאור:"
],
"Occupants:": [
null,
"נוכחים:"
],
"Features:": [
null,
"תכונות:"
],
"Requires authentication": [
null,
"מצריך אישור"
],
"Hidden": [
null,
"נסתר"
],
"Requires an invitation": [
null,
"מצריך הזמנה"
],
"Moderated": [
null,
"מבוקר"
],
"Non-anonymous": [
null,
"לא אנונימי"
],
"Open room": [
null,
"חדר פתוח"
],
"Permanent room": [
null,
"חדר צמיתה"
],
"Public": [
null,
"פומבי"
],
"Semi-anonymous": [
null,
"אנונימי למחצה"
],
"Temporary room": [
null,
"חדר זמני"
],
"Unmoderated": [
null,
"לא מבוקר"
],
"Rooms": [
null,
"חדרים"
],
"Room name": [
null,
"שם חדר"
],
"Nickname": [
null,
"שם כינוי"
],
"Server": [
null,
"שרת"
],
"Join": [
null,
"הצטרף"
],
"Show rooms": [
null,
"הצג חדרים"
],
"No rooms on %1$s": [
null,
"אין חדרים על %1$s"
],
"Rooms on %1$s": [
null,
"חדרים על %1$s"
],
"Set chatroom topic": [
null,
"קבע נושא חדר שיחה"
],
"Kick user from chatroom": [
null,
"בעט משתמש מתוך חדר שיחה"
],
"Ban user from chatroom": [
null,
"אסור משתמש מתוך חדר שיחה"
],
"Message": [
null,
"הודעה"
],
"Save": [
null,
"שמור"
],
"Cancel": [
null,
"ביטול"
],
"An error occurred while trying to save the form.": [
null,
"אירעה שגיאה במהלך ניסיון שמירת הטופס."
],
"This chatroom requires a password": [
null,
"חדר שיחה זה מצריך סיסמה"
],
"Password: ": [
null,
"סיסמה: "
],
"Submit": [
null,
"שלח"
],
"This room is not anonymous": [
null,
"חדר זה אינו אנונימי"
],
"This room now shows unavailable members": [
null,
"חדר זה כעת מציג חברים לא זמינים"
],
"This room does not show unavailable members": [
null,
"חדר זה לא מציג חברים לא זמינים"
],
"Non-privacy-related room configuration has changed": [
null,
"תצורת חדר אשר לא-קשורה-בפרטיות שונתה"
],
"Room logging is now enabled": [
null,
"יומן חדר הינו מופעל כעת"
],
"Room logging is now disabled": [
null,
"יומן חדר הינו מנוטרל כעת"
],
"This room is now non-anonymous": [
null,
"חדר זה אינו אנונימי כעת"
],
"This room is now semi-anonymous": [
null,
"חדר זה הינו אנונימי למחצה כעת"
],
"This room is now fully-anonymous": [
null,
"חדר זה הינו אנונימי לחלוטין כעת"
],
"A new room has been created": [
null,
"חדר חדש נוצר"
],
"Your nickname has been changed": [
null,
"שם הכינוי שלך שונה"
],
"<strong>%1$s</strong> has been banned": [
null,
"<strong>%1$s</strong> נאסר(ה)"
],
"<strong>%1$s</strong> has been kicked out": [
null,
"<strong>%1$s</strong> נבעט(ה)"
],
"<strong>%1$s</strong> has been removed because of an affiliation change": [
null,
"<strong>%1$s</strong> הוסרה(ה) משום שינוי שיוך"
],
"<strong>%1$s</strong> has been removed for not being a member": [
null,
"<strong>%1$s</strong> הוסר(ה) משום אי הימצאות במסגרת מעמד של חבר"
],
"You have been banned from this room": [
null,
"נאסרת מתוך חדר זה"
],
"You have been kicked from this room": [
null,
"נבעטת מתוך חדר זה"
],
"You have been removed from this room because of an affiliation change": [
null,
"הוסרת מתוך חדר זה משום שינוי שיוך"
],
"You have been removed from this room because the room has changed to members-only and you're not a member": [
null,
"הוסרת מתוך חדר זה משום שהחדר שונה לחברים-בלבד ואינך במעמד של חבר"
],
"You have been removed from this room because the MUC (Multi-user chat) service is being shut down.": [
null,
"הוסרת מתוך חדר זה משום ששירות שמ״מ (שיחה מרובת משתמשים) זה כעת מצוי בהליכי סגירה."
],
"You are not on the member list of this room": [
null,
"אינך ברשימת החברים של חדר זה"
],
"No nickname was specified": [
null,
"לא צוין שום שם כינוי"
],
"You are not allowed to create new rooms": [
null,
"אין לך רשות ליצור חדרים חדשים"
],
"Your nickname doesn't conform to this room's policies": [
null,
"שם הכינוי שלך לא תואם את המדינויות של חדר זה"
],
"Your nickname is already taken": [
null,
"שם הכינוי שלך הינו תפוס"
],
"This room does not (yet) exist": [
null,
"חדר זה (עדיין) לא קיים"
],
"This room has reached it's maximum number of occupants": [
null,
"חדר זה הגיע לסף הנוכחים המרבי שלו"
],
"Topic set by %1$s to: %2$s": [
null,
"נושא חדר זה נקבע על ידי %1$s אל: %2$s"
],
"This user is a moderator": [
null,
"משתמש זה הינו אחראי"
],
"This user can send messages in this room": [
null,
"משתמש זה מסוגל לשלוח הודעות בתוך חדר זה"
],
"This user can NOT send messages in this room": [
null,
"משתמש זה ﬥﬡ מסוגל לשלוח הודעות בתוך חדר זה"
],
"Click to chat with this contact": [
null,
"לחץ כדי לשוחח עם איש קשר זה"
],
"Click to remove this contact": [
null,
"לחץ כדי להסיר את איש קשר זה"
],
"Contact requests": [
null,
"בקשות איש קשר"
],
"My contacts": [
null,
"אנשי הקשר שלי"
],
"Pending contacts": [
null,
"אנשי קשר ממתינים"
],
"Custom status": [
null,
"מצב מותאם"
],
"Click to change your chat status": [
null,
"לחץ כדי לשנות את הודעת השיחה שלך"
],
"Click here to write a custom status message": [
null,
"לחץ כאן כדי לכתוב הודעת מצב מותאמת"
],
"online": [
null,
"מקוון"
],
"busy": [
null,
"עסוק"
],
"away for long": [
null,
"נעדר לזמן מה"
],
"away": [
null,
"נעדר"
],
"I am %1$s": [
null,
"מצבי כעת הינו %1$s"
],
"Sign in": [
null,
"התחברות"
],
"XMPP/Jabber Username:": [
null,
"שם משתמש XMPP/Jabber:"
],
"Password:": [
null,
"סיסמה:"
],
"Log In": [
null,
"כניסה"
],
"BOSH Service URL:": [
null,
"כתובת שירות BOSH:"
]
}
}

View File

@ -0,0 +1,672 @@
# Language HE translations for Converse.js package.
# Copyright (C) 2013 Jan-Carel Brand
# This file is distributed under the same license as the Converse.js package.
# GreenLunar <GreenLunar@github.com>, 2014.
#
msgid ""
msgstr ""
"Project-Id-Version: Converse.js 0.7.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-01-28 03:50+0200\n"
"PO-Revision-Date: 2014-02-21 06:07+0200\n"
"Last-Translator: GreenLunar <GreenLunar@github.com>\n"
"Language-Team: Rahut <http://sourceforge.net/projects/rahut/>\n"
"Language: he\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.5.1\n"
#: converse.js:217
msgid "unencrypted"
msgstr "לא מוצפנת"
#: converse.js:218
msgid "unverified"
msgstr "לא מאומתת"
#: converse.js:219
msgid "verified"
msgstr "מאומתת"
#: converse.js:220
msgid "finished"
msgstr "מוגמרת"
# איש קשר זה הינו
#: converse.js:223
msgid "This contact is busy"
msgstr "איש קשר זה עסוק"
#: converse.js:224
msgid "This contact is online"
msgstr "איש קשר זה מקוון"
# איש קשר זה אינו
#: converse.js:225
msgid "This contact is offline"
msgstr "איש קשר זה לא מקוון"
#: converse.js:226
msgid "This contact is unavailable"
msgstr "איש קשר זה לא זמין"
#: converse.js:227
msgid "This contact is away for an extended period"
msgstr "איש קשר זה נעדר למשך זמן ממושך"
#: converse.js:228
msgid "This contact is away"
msgstr "איש קשר זה הינו נעדר"
#: converse.js:321
msgid "Disconnected"
msgstr "מנותק"
#: converse.js:331
msgid "Error"
msgstr "שגיאה"
#: converse.js:333
msgid "Connecting"
msgstr "כעת מתחבר"
#: converse.js:336
msgid "Connection Failed"
msgstr "חיבור נכשל"
#: converse.js:338
msgid "Authenticating"
msgstr "כעת מאמת"
#: converse.js:341
msgid "Authentication Failed"
msgstr "אימות נכשל"
#: converse.js:343
msgid "Disconnecting"
msgstr "כעת מתנתק"
#: converse.js:479
msgid "Online Contacts"
msgstr "אנשי קשר מקוונים"
#: converse.js:540
msgid "Re-establishing encrypted session"
msgstr "בסס מחדש ישיבה מוצפנת"
#: converse.js:548
msgid ""
"Your browser needs to generate a private key, which will be used in your "
"encrypted chat session. This can take up to 30 seconds during which your "
"browser might freeze and become unresponsive."
msgstr ""
"על הדפדפן שלך להפיק מפתח פרטי, אשר ישמש אותך בישיבות שיחה מוצפנות. פעולה זו "
"יכולה לקחת למעלה מן 30 שניות אשר במהלכה הדפדפן שלך עשוי לקפוא ולהפוך לחסר "
"תגובה."
#: converse.js:557
msgid "Private key generated."
msgstr "מפתח פרטי הופק."
#: converse.js:588
msgid ""
"Authentication request from %1$s\n"
"\n"
"Your buddy is attempting to verify your identity, by asking you the question "
"below.\n"
"\n"
"%2$s"
msgstr ""
"בקשת אימות מאת %1$s\n"
"\n"
"האישיות שכנגד מנסה לאמת את הזהות שלך, בעזרת שאילת שאלה להלן.\n"
"\n"
"%2$s"
#: converse.js:597
msgid "Could not verify this user's identify."
msgstr "לא היתה אפשרות לאמת את זהות משתמש זה."
#: converse.js:750
msgid "Personal message"
msgstr "הודעה אישית"
#: converse.js:795
msgid "Start encrypted conversation"
msgstr "התחל ישיבה מוצפנת"
#: converse.js:798
msgid "Refresh encrypted conversation"
msgstr "רענן ישיבה מוצפנת"
#: converse.js:799
msgid "End encrypted conversation"
msgstr "סיים ישיבה מוצפנת"
#: converse.js:800
msgid "Verify with SMP"
msgstr "אמת בעזרת SMP"
#: converse.js:803
msgid "Verify with fingerprints"
msgstr "אמת בעזרת טביעות אצבע"
#: converse.js:805
msgid "What's this?"
msgstr "מה זה?"
#: converse.js:906
msgid "me"
msgstr "אני"
#: converse.js:1022 converse.js:1864
msgid "Show this menu"
msgstr "הצג את תפריט זה"
#: converse.js:1023 converse.js:1865
msgid "Write in the third person"
msgstr "כתוב בגוף השלישי"
#: converse.js:1024 converse.js:1869
msgid "Remove messages"
msgstr "הסר הודעות"
#: converse.js:1110
msgid "Your message could not be sent"
msgstr "ההודעה שלך לא היתה יכולה להישלח"
#: converse.js:1113
msgid "We received an unencrypted message"
msgstr "אנחנו קיבלנו הודעה לא מוצפנת"
#: converse.js:1116
msgid "We received an unreadable encrypted message"
msgstr "אנחנו קיבלנו הודעה מוצפנת לא קריאה"
#: converse.js:1125
msgid "This user has requested an encrypted session."
msgstr "משתמש זה ביקש ישיבה מוצפנת."
#: converse.js:1147
msgid ""
"Here are the fingerprints, please confirm them with %1$s, outside of this "
"chat.\n"
"\n"
"Fingerprint for you, %2$s: %3$s\n"
"\n"
"Fingerprint for %1$s: %4$s\n"
"\n"
"If you have confirmed that the fingerprints match, click OK, otherwise click "
"Cancel."
msgstr ""
"הרי טביעות האצבע, אנא אמת אותן עם %1$s, מחוץ לשיחה זו.\n"
"\n"
"טביעת אצבע עבורך, %2$s: %3$s\n"
"\n"
"טביעת אצבע עבור %1$s: %4$s\n"
"\n"
"היה ואימתת כי טביעות האצבע תואמות, לחץ אישור (OK), אחרת לחץ ביטול (Cancel)."
# הקצה השני
#: converse.js:1160
msgid ""
"You will be prompted to provide a security question and then an answer to "
"that question.\n"
"\n"
"Your buddy will then be prompted the same question and if they type the "
"exact same answer (case sensitive), their identity will be verified."
msgstr ""
"אתה תתבקש לספק שאלת אבטחה ולאחריה תשובה לשאלה הזו.\n"
"\n"
"האישיות שכנגד תתבקש עובר זאת לאותה שאלת אבטחה ואם זו תקלידו את את אותה "
"התשובה במדויק (case sensitive), זהותה תאומת."
#: converse.js:1161
msgid "What is your security question?"
msgstr "מהי שאלת האבטחה שלך?"
#: converse.js:1163
msgid "What is the answer to the security question?"
msgstr "מהי התשובה לשאלת האבטחה?"
# תרשים
#: converse.js:1167
msgid "Invalid authentication scheme provided"
msgstr "סופקה סכימת אימות שגויה"
#: converse.js:1248
msgid "Your messages are not encrypted anymore"
msgstr "ההודעות שלך אינן מוצפנות עוד"
#: converse.js:1250
msgid ""
"Your messages are now encrypted but your buddy's identity has not been "
"verified."
msgstr "ההודעות שלך מוצפנות כעת אך זהות האישיות שכנגד טרם אומתה."
#: converse.js:1252
msgid "Your buddy's identify has been verified."
msgstr "זהות האישיות שכנגד אומתה."
#: converse.js:1254
msgid "Your buddy has ended encryption on their end, you should do the same."
msgstr "האישיות שכנגד סיימה הצפנה בקצה שלה, עליך לעשות את אותו הדבר."
#: converse.js:1263
msgid "Your messages are not encrypted. Click here to enable OTR encryption."
msgstr "ההודעות שלך אינן וצפנות. לחץ כאן כדי לאפשר OTR."
#: converse.js:1265
msgid "Your messages are encrypted, but your buddy has not been verified."
msgstr "ההודעות שלך מוצפנות כעת, אך האישיות שכנגד טרם אומתה."
#: converse.js:1267
msgid "Your messages are encrypted and your buddy verified."
msgstr "ההודעות שלך מוצפנות כעת והאישיות שכנגד אומתה."
#: converse.js:1269
msgid ""
"Your buddy has closed their end of the private session, you should do the "
"same"
msgstr "האישיות שכנגד סגרה את קצה הישיבה הפרטית שלה, עליך לעשות את אותו הדבר."
#: converse.js:1354
msgid "Contacts"
msgstr "אנשי קשר"
#: converse.js:1359
msgid "Online"
msgstr "מקוון"
#: converse.js:1360
msgid "Busy"
msgstr "עסוק"
#: converse.js:1361
msgid "Away"
msgstr "נעדר"
#: converse.js:1362
msgid "Offline"
msgstr "בלתי מקוון"
#: converse.js:1372
msgid "Click to add new chat contacts"
msgstr "לחץ כדי להוסיף אנשי קשר שיחה חדשים"
#: converse.js:1373
msgid "Add a contact"
msgstr "הוסף איש קשר"
#: converse.js:1382
msgid "Contact username"
msgstr "שם משתמש איש קשר"
#: converse.js:1383
msgid "Add"
msgstr "הוסף"
#: converse.js:1391
msgid "Contact name"
msgstr "שם איש קשר"
#: converse.js:1392
msgid "Search"
msgstr "חיפוש"
#: converse.js:1439
msgid "No users found"
msgstr "לא נמצאו משתמשים"
#: converse.js:1446
msgid "Click to add as a chat contact"
msgstr "לחץ כדי להוסיף בתור איש קשר שיחה"
#: converse.js:1498
msgid "Click to open this room"
msgstr "לחץ כדי לפתוח את חדר זה"
#: converse.js:1500
msgid "Show more information on this room"
msgstr "הצג עוד מידע אודות חדר זה"
#: converse.js:1506
msgid "Description:"
msgstr "תיאור:"
#: converse.js:1507
msgid "Occupants:"
msgstr "נוכחים:"
#: converse.js:1508
msgid "Features:"
msgstr "תכונות:"
#: converse.js:1510
msgid "Requires authentication"
msgstr "מצריך אישור"
#: converse.js:1513
msgid "Hidden"
msgstr "נסתר"
#: converse.js:1516
msgid "Requires an invitation"
msgstr "מצריך הזמנה"
#: converse.js:1519
msgid "Moderated"
msgstr "מבוקר"
#: converse.js:1522
msgid "Non-anonymous"
msgstr "לא אנונימי"
#: converse.js:1525
msgid "Open room"
msgstr "חדר פתוח"
#: converse.js:1528
msgid "Permanent room"
msgstr "חדר צמיתה"
#: converse.js:1531
msgid "Public"
msgstr "פומבי"
#: converse.js:1534
msgid "Semi-anonymous"
msgstr "אנונימי למחצה"
#: converse.js:1537
msgid "Temporary room"
msgstr "חדר זמני"
#: converse.js:1540
msgid "Unmoderated"
msgstr "לא מבוקר"
#: converse.js:1546
msgid "Rooms"
msgstr "חדרים"
#: converse.js:1550
msgid "Room name"
msgstr "שם חדר"
#: converse.js:1551
msgid "Nickname"
msgstr "שם כינוי"
#: converse.js:1552
msgid "Server"
msgstr "שרת"
#: converse.js:1553
msgid "Join"
msgstr "הצטרף"
#: converse.js:1554
msgid "Show rooms"
msgstr "הצג חדרים"
#. For translators: %1$s is a variable and will be replaced with the XMPP server name
#: converse.js:1589
msgid "No rooms on %1$s"
msgstr "אין חדרים על %1$s"
#. For translators: %1$s is a variable and will be
#. replaced with the XMPP server name
#: converse.js:1604
msgid "Rooms on %1$s"
msgstr "חדרים על %1$s"
#: converse.js:1866
msgid "Set chatroom topic"
msgstr "קבע נושא חדר שיחה"
#: converse.js:1867
msgid "Kick user from chatroom"
msgstr "בעט משתמש מתוך חדר שיחה"
#: converse.js:1868
msgid "Ban user from chatroom"
msgstr "אסור משתמש מתוך חדר שיחה"
#: converse.js:1898
msgid "Message"
msgstr "הודעה"
#: converse.js:2013 converse.js:3168
msgid "Save"
msgstr "שמור"
#: converse.js:2014
msgid "Cancel"
msgstr "ביטול"
#: converse.js:2061
msgid "An error occurred while trying to save the form."
msgstr "אירעה שגיאה במהלך ניסיון שמירת הטופס."
#: converse.js:2107
msgid "This chatroom requires a password"
msgstr "חדר שיחה זה מצריך סיסמה"
#: converse.js:2108
msgid "Password: "
msgstr "סיסמה: "
#: converse.js:2109
msgid "Submit"
msgstr "שלח"
#: converse.js:2123
msgid "This room is not anonymous"
msgstr "חדר זה אינו אנונימי"
#: converse.js:2124
msgid "This room now shows unavailable members"
msgstr "חדר זה כעת מציג חברים לא זמינים"
#: converse.js:2125
msgid "This room does not show unavailable members"
msgstr "חדר זה לא מציג חברים לא זמינים"
#: converse.js:2126
msgid "Non-privacy-related room configuration has changed"
msgstr "תצורת חדר אשר לא-קשורה-בפרטיות שונתה"
#: converse.js:2127
msgid "Room logging is now enabled"
msgstr "יומן חדר הינו מופעל כעת"
#: converse.js:2128
msgid "Room logging is now disabled"
msgstr "יומן חדר הינו מנוטרל כעת"
#: converse.js:2129
msgid "This room is now non-anonymous"
msgstr "חדר זה אינו אנונימי כעת"
#: converse.js:2130
msgid "This room is now semi-anonymous"
msgstr "חדר זה הינו אנונימי למחצה כעת"
#: converse.js:2131
msgid "This room is now fully-anonymous"
msgstr "חדר זה הינו אנונימי לחלוטין כעת"
#: converse.js:2132
msgid "A new room has been created"
msgstr "חדר חדש נוצר"
#: converse.js:2133
msgid "Your nickname has been changed"
msgstr "שם הכינוי שלך שונה"
#: converse.js:2147
msgid "<strong>%1$s</strong> has been banned"
msgstr "<strong>%1$s</strong> נאסר(ה)"
#: converse.js:2148
msgid "<strong>%1$s</strong> has been kicked out"
msgstr "<strong>%1$s</strong> נבעט(ה)"
#: converse.js:2149
msgid "<strong>%1$s</strong> has been removed because of an affiliation change"
msgstr "<strong>%1$s</strong> הוסרה(ה) משום שינוי שיוך"
# היותו(ה)
#: converse.js:2150
msgid "<strong>%1$s</strong> has been removed for not being a member"
msgstr "<strong>%1$s</strong> הוסר(ה) משום אי הימצאות במסגרת מעמד של חבר"
#: converse.js:2154 converse.js:2214
msgid "You have been banned from this room"
msgstr "נאסרת מתוך חדר זה"
#: converse.js:2155
msgid "You have been kicked from this room"
msgstr "נבעטת מתוך חדר זה"
#: converse.js:2156
msgid "You have been removed from this room because of an affiliation change"
msgstr "הוסרת מתוך חדר זה משום שינוי שיוך"
#: converse.js:2157
msgid ""
"You have been removed from this room because the room has changed to members-"
"only and you're not a member"
msgstr "הוסרת מתוך חדר זה משום שהחדר שונה לחברים-בלבד ואינך במעמד של חבר"
#: converse.js:2158
msgid ""
"You have been removed from this room because the MUC (Multi-user chat) "
"service is being shut down."
msgstr ""
"הוסרת מתוך חדר זה משום ששירות שמ״מ (שיחה מרובת משתמשים) זה כעת מצוי בהליכי "
"סגירה."
#: converse.js:2212
msgid "You are not on the member list of this room"
msgstr "אינך ברשימת החברים של חדר זה"
# אף שם כינוי לא צוין
#: converse.js:2218
msgid "No nickname was specified"
msgstr "לא צוין שום שם כינוי"
# אינך מורשה
#: converse.js:2222
msgid "You are not allowed to create new rooms"
msgstr "אין לך רשות ליצור חדרים חדשים"
#: converse.js:2224
msgid "Your nickname doesn't conform to this room's policies"
msgstr "שם הכינוי שלך לא תואם את המדינויות של חדר זה"
# נלקח כבר
#: converse.js:2226
msgid "Your nickname is already taken"
msgstr "שם הכינוי שלך הינו תפוס"
#: converse.js:2228
msgid "This room does not (yet) exist"
msgstr "חדר זה (עדיין) לא קיים"
#: converse.js:2230
msgid "This room has reached it's maximum number of occupants"
msgstr "חדר זה הגיע לסף הנוכחים המרבי שלו"
#: converse.js:2309
msgid "Topic set by %1$s to: %2$s"
msgstr "נושא חדר זה נקבע על ידי %1$s אל: %2$s"
#: converse.js:2330
msgid "This user is a moderator"
msgstr "משתמש זה הינו אחראי"
#: converse.js:2333
msgid "This user can send messages in this room"
msgstr "משתמש זה מסוגל לשלוח הודעות בתוך חדר זה"
#: converse.js:2336
msgid "This user can NOT send messages in this room"
msgstr "משתמש זה ﬥﬡ מסוגל לשלוח הודעות בתוך חדר זה"
#: converse.js:2562
msgid "Click to chat with this contact"
msgstr "לחץ כדי לשוחח עם איש קשר זה"
#: converse.js:2565 converse.js:2569
msgid "Click to remove this contact"
msgstr "לחץ כדי להסיר את איש קשר זה"
#: converse.js:2919
msgid "Contact requests"
msgstr "בקשות איש קשר"
#: converse.js:2922
msgid "My contacts"
msgstr "אנשי הקשר שלי"
#: converse.js:2925
msgid "Pending contacts"
msgstr "אנשי קשר ממתינים"
#: converse.js:3167
msgid "Custom status"
msgstr "מצב מותאם"
#: converse.js:3173
msgid "Click to change your chat status"
msgstr "לחץ כדי לשנות את הודעת השיחה שלך"
#: converse.js:3177
msgid "Click here to write a custom status message"
msgstr "לחץ כאן כדי לכתוב הודעת מצב מותאמת"
#: converse.js:3206 converse.js:3214
msgid "online"
msgstr "מקוון"
#: converse.js:3208
msgid "busy"
msgstr "עסוק"
#: converse.js:3210
msgid "away for long"
msgstr "נעדר לזמן מה"
#: converse.js:3212
msgid "away"
msgstr "נעדר"
# אני במצב
#. For translators: the %1$s part gets replaced with the status
#. Example, I am online
#: converse.js:3226 converse.js:3263
msgid "I am %1$s"
msgstr "מצבי כעת הינו %1$s"
#: converse.js:3334
msgid "Sign in"
msgstr "התחברות"
#: converse.js:3338
msgid "XMPP/Jabber Username:"
msgstr "שם משתמש XMPP/Jabber:"
#: converse.js:3340
msgid "Password:"
msgstr "סיסמה:"
#: converse.js:3342
msgid "Log In"
msgstr "כניסה"
#: converse.js:3346
msgid "BOSH Service URL:"
msgstr "כתובת שירות BOSH:"

622
locale/he/LC_MESSAGES/he.js Normal file
View File

@ -0,0 +1,622 @@
(function (root, factory) {
var translations = {
"domain": "converse",
"locale_data": {
"converse": {
"": {
"Project-Id-Version": "Converse.js 0.7.0",
"Report-Msgid-Bugs-To": "",
"POT-Creation-Date": "2014-01-28 03:50+0200",
"PO-Revision-Date": "2014-02-21 06:07+0200",
"Last-Translator": "GreenLunar <GreenLunar@github.com>",
"Language-Team": "Rahut <http://sourceforge.net/projects/rahut/>",
"Language": "he",
"MIME-Version": "1.0",
"Content-Type": "text/plain; charset=UTF-8",
"Content-Transfer-Encoding": "8bit",
"X-Generator": "Poedit 1.5.1"
},
"unencrypted": [
null,
"לא מוצפנת"
],
"unverified": [
null,
"לא מאומתת"
],
"verified": [
null,
"מאומתת"
],
"finished": [
null,
"מוגמרת"
],
"This contact is busy": [
null,
"איש קשר זה עסוק"
],
"This contact is online": [
null,
"איש קשר זה מקוון"
],
"This contact is offline": [
null,
"איש קשר זה לא מקוון"
],
"This contact is unavailable": [
null,
"איש קשר זה לא זמין"
],
"This contact is away for an extended period": [
null,
"איש קשר זה נעדר למשך זמן ממושך"
],
"This contact is away": [
null,
"איש קשר זה הינו נעדר"
],
"Disconnected": [
null,
"מנותק"
],
"Error": [
null,
"שגיאה"
],
"Connecting": [
null,
"כעת מתחבר"
],
"Connection Failed": [
null,
"חיבור נכשל"
],
"Authenticating": [
null,
"כעת מאמת"
],
"Authentication Failed": [
null,
"אימות נכשל"
],
"Disconnecting": [
null,
"כעת מתנתק"
],
"Online Contacts": [
null,
"אנשי קשר מקוונים"
],
"Re-establishing encrypted session": [
null,
"בסס מחדש ישיבה מוצפנת"
],
"Your browser needs to generate a private key, which will be used in your encrypted chat session. This can take up to 30 seconds during which your browser might freeze and become unresponsive.": [
null,
"על הדפדפן שלך להפיק מפתח פרטי, אשר ישמש אותך בישיבות שיחה מוצפנות. פעולה זו יכולה לקחת למעלה מן 30 שניות אשר במהלכה הדפדפן שלך עשוי לקפוא ולהפוך לחסר תגובה."
],
"Private key generated.": [
null,
"מפתח פרטי הופק."
],
"Authentication request from %1$s\n\nYour buddy is attempting to verify your identity, by asking you the question below.\n\n%2$s": [
null,
"בקשת אימות מאת %1$s\n\nהאישיות שכנגד מנסה לאמת את הזהות שלך, בעזרת שאילת שאלה להלן.\n\n%2$s"
],
"Could not verify this user's identify.": [
null,
"לא היתה אפשרות לאמת את זהות משתמש זה."
],
"Personal message": [
null,
"הודעה אישית"
],
"Start encrypted conversation": [
null,
"התחל ישיבה מוצפנת"
],
"Refresh encrypted conversation": [
null,
"רענן ישיבה מוצפנת"
],
"End encrypted conversation": [
null,
"סיים ישיבה מוצפנת"
],
"Verify with SMP": [
null,
"אמת בעזרת SMP"
],
"Verify with fingerprints": [
null,
"אמת בעזרת טביעות אצבע"
],
"What's this?": [
null,
"מה זה?"
],
"me": [
null,
"אני"
],
"Show this menu": [
null,
"הצג את תפריט זה"
],
"Write in the third person": [
null,
"כתוב בגוף השלישי"
],
"Remove messages": [
null,
"הסר הודעות"
],
"Your message could not be sent": [
null,
"ההודעה שלך לא היתה יכולה להישלח"
],
"We received an unencrypted message": [
null,
"אנחנו קיבלנו הודעה לא מוצפנת"
],
"We received an unreadable encrypted message": [
null,
"אנחנו קיבלנו הודעה מוצפנת לא קריאה"
],
"This user has requested an encrypted session.": [
null,
"משתמש זה ביקש ישיבה מוצפנת."
],
"Here are the fingerprints, please confirm them with %1$s, outside of this chat.\n\nFingerprint for you, %2$s: %3$s\n\nFingerprint for %1$s: %4$s\n\nIf you have confirmed that the fingerprints match, click OK, otherwise click Cancel.": [
null,
"הרי טביעות האצבע, אנא אמת אותן עם %1$s, מחוץ לשיחה זו.\n\nטביעת אצבע עבורך, %2$s: %3$s\n\nטביעת אצבע עבור %1$s: %4$s\n\nהיה ואימתת כי טביעות האצבע תואמות, לחץ אישור (OK), אחרת לחץ ביטול (Cancel)."
],
"You will be prompted to provide a security question and then an answer to that question.\n\nYour buddy will then be prompted the same question and if they type the exact same answer (case sensitive), their identity will be verified.": [
null,
"אתה תתבקש לספק שאלת אבטחה ולאחריה תשובה לשאלה הזו.\n\nהאישיות שכנגד תתבקש עובר זאת לאותה שאלת אבטחה ואם זו תקלידו את את אותה התשובה במדויק (case sensitive), זהותה תאומת."
],
"What is your security question?": [
null,
"מהי שאלת האבטחה שלך?"
],
"What is the answer to the security question?": [
null,
"מהי התשובה לשאלת האבטחה?"
],
"Invalid authentication scheme provided": [
null,
"סופקה סכימת אימות שגויה"
],
"Your messages are not encrypted anymore": [
null,
"ההודעות שלך אינן מוצפנות עוד"
],
"Your messages are now encrypted but your buddy's identity has not been verified.": [
null,
"ההודעות שלך מוצפנות כעת אך זהות האישיות שכנגד טרם אומתה."
],
"Your buddy's identify has been verified.": [
null,
"זהות האישיות שכנגד אומתה."
],
"Your buddy has ended encryption on their end, you should do the same.": [
null,
"האישיות שכנגד סיימה הצפנה בקצה שלה, עליך לעשות את אותו הדבר."
],
"Your messages are not encrypted. Click here to enable OTR encryption.": [
null,
"ההודעות שלך אינן וצפנות. לחץ כאן כדי לאפשר OTR."
],
"Your messages are encrypted, but your buddy has not been verified.": [
null,
"ההודעות שלך מוצפנות כעת, אך האישיות שכנגד טרם אומתה."
],
"Your messages are encrypted and your buddy verified.": [
null,
"ההודעות שלך מוצפנות כעת והאישיות שכנגד אומתה."
],
"Your buddy has closed their end of the private session, you should do the same": [
null,
"האישיות שכנגד סגרה את קצה הישיבה הפרטית שלה, עליך לעשות את אותו הדבר."
],
"Contacts": [
null,
"אנשי קשר"
],
"Online": [
null,
"מקוון"
],
"Busy": [
null,
"עסוק"
],
"Away": [
null,
"נעדר"
],
"Offline": [
null,
"בלתי מקוון"
],
"Click to add new chat contacts": [
null,
"לחץ כדי להוסיף אנשי קשר שיחה חדשים"
],
"Add a contact": [
null,
"הוסף איש קשר"
],
"Contact username": [
null,
"שם משתמש איש קשר"
],
"Add": [
null,
"הוסף"
],
"Contact name": [
null,
"שם איש קשר"
],
"Search": [
null,
"חיפוש"
],
"No users found": [
null,
"לא נמצאו משתמשים"
],
"Click to add as a chat contact": [
null,
"לחץ כדי להוסיף בתור איש קשר שיחה"
],
"Click to open this room": [
null,
"לחץ כדי לפתוח את חדר זה"
],
"Show more information on this room": [
null,
"הצג עוד מידע אודות חדר זה"
],
"Description:": [
null,
"תיאור:"
],
"Occupants:": [
null,
"נוכחים:"
],
"Features:": [
null,
"תכונות:"
],
"Requires authentication": [
null,
"מצריך אישור"
],
"Hidden": [
null,
"נסתר"
],
"Requires an invitation": [
null,
"מצריך הזמנה"
],
"Moderated": [
null,
"מבוקר"
],
"Non-anonymous": [
null,
"לא אנונימי"
],
"Open room": [
null,
"חדר פתוח"
],
"Permanent room": [
null,
"חדר צמיתה"
],
"Public": [
null,
"פומבי"
],
"Semi-anonymous": [
null,
"אנונימי למחצה"
],
"Temporary room": [
null,
"חדר זמני"
],
"Unmoderated": [
null,
"לא מבוקר"
],
"Rooms": [
null,
"חדרים"
],
"Room name": [
null,
"שם חדר"
],
"Nickname": [
null,
"שם כינוי"
],
"Server": [
null,
"שרת"
],
"Join": [
null,
"הצטרף"
],
"Show rooms": [
null,
"הצג חדרים"
],
"No rooms on %1$s": [
null,
"אין חדרים על %1$s"
],
"Rooms on %1$s": [
null,
"חדרים על %1$s"
],
"Set chatroom topic": [
null,
"קבע נושא חדר שיחה"
],
"Kick user from chatroom": [
null,
"בעט משתמש מתוך חדר שיחה"
],
"Ban user from chatroom": [
null,
"אסור משתמש מתוך חדר שיחה"
],
"Message": [
null,
"הודעה"
],
"Save": [
null,
"שמור"
],
"Cancel": [
null,
"ביטול"
],
"An error occurred while trying to save the form.": [
null,
"אירעה שגיאה במהלך ניסיון שמירת הטופס."
],
"This chatroom requires a password": [
null,
"חדר שיחה זה מצריך סיסמה"
],
"Password: ": [
null,
"סיסמה: "
],
"Submit": [
null,
"שלח"
],
"This room is not anonymous": [
null,
"חדר זה אינו אנונימי"
],
"This room now shows unavailable members": [
null,
"חדר זה כעת מציג חברים לא זמינים"
],
"This room does not show unavailable members": [
null,
"חדר זה לא מציג חברים לא זמינים"
],
"Non-privacy-related room configuration has changed": [
null,
"תצורת חדר אשר לא-קשורה-בפרטיות שונתה"
],
"Room logging is now enabled": [
null,
"יומן חדר הינו מופעל כעת"
],
"Room logging is now disabled": [
null,
"יומן חדר הינו מנוטרל כעת"
],
"This room is now non-anonymous": [
null,
"חדר זה אינו אנונימי כעת"
],
"This room is now semi-anonymous": [
null,
"חדר זה הינו אנונימי למחצה כעת"
],
"This room is now fully-anonymous": [
null,
"חדר זה הינו אנונימי לחלוטין כעת"
],
"A new room has been created": [
null,
"חדר חדש נוצר"
],
"Your nickname has been changed": [
null,
"שם הכינוי שלך שונה"
],
"<strong>%1$s</strong> has been banned": [
null,
"<strong>%1$s</strong> נאסר(ה)"
],
"<strong>%1$s</strong> has been kicked out": [
null,
"<strong>%1$s</strong> נבעט(ה)"
],
"<strong>%1$s</strong> has been removed because of an affiliation change": [
null,
"<strong>%1$s</strong> הוסרה(ה) משום שינוי שיוך"
],
"<strong>%1$s</strong> has been removed for not being a member": [
null,
"<strong>%1$s</strong> הוסר(ה) משום אי הימצאות במסגרת מעמד של חבר"
],
"You have been banned from this room": [
null,
"נאסרת מתוך חדר זה"
],
"You have been kicked from this room": [
null,
"נבעטת מתוך חדר זה"
],
"You have been removed from this room because of an affiliation change": [
null,
"הוסרת מתוך חדר זה משום שינוי שיוך"
],
"You have been removed from this room because the room has changed to members-only and you're not a member": [
null,
"הוסרת מתוך חדר זה משום שהחדר שונה לחברים-בלבד ואינך במעמד של חבר"
],
"You have been removed from this room because the MUC (Multi-user chat) service is being shut down.": [
null,
"הוסרת מתוך חדר זה משום ששירות שמ״מ (שיחה מרובת משתמשים) זה כעת מצוי בהליכי סגירה."
],
"You are not on the member list of this room": [
null,
"אינך ברשימת החברים של חדר זה"
],
"No nickname was specified": [
null,
"לא צוין שום שם כינוי"
],
"You are not allowed to create new rooms": [
null,
"אין לך רשות ליצור חדרים חדשים"
],
"Your nickname doesn't conform to this room's policies": [
null,
"שם הכינוי שלך לא תואם את המדינויות של חדר זה"
],
"Your nickname is already taken": [
null,
"שם הכינוי שלך הינו תפוס"
],
"This room does not (yet) exist": [
null,
"חדר זה (עדיין) לא קיים"
],
"This room has reached it's maximum number of occupants": [
null,
"חדר זה הגיע לסף הנוכחים המרבי שלו"
],
"Topic set by %1$s to: %2$s": [
null,
"נושא חדר זה נקבע על ידי %1$s אל: %2$s"
],
"This user is a moderator": [
null,
"משתמש זה הינו אחראי"
],
"This user can send messages in this room": [
null,
"משתמש זה מסוגל לשלוח הודעות בתוך חדר זה"
],
"This user can NOT send messages in this room": [
null,
"משתמש זה ﬥﬡ מסוגל לשלוח הודעות בתוך חדר זה"
],
"Click to chat with this contact": [
null,
"לחץ כדי לשוחח עם איש קשר זה"
],
"Click to remove this contact": [
null,
"לחץ כדי להסיר את איש קשר זה"
],
"Contact requests": [
null,
"בקשות איש קשר"
],
"My contacts": [
null,
"אנשי הקשר שלי"
],
"Pending contacts": [
null,
"אנשי קשר ממתינים"
],
"Custom status": [
null,
"מצב מותאם"
],
"Click to change your chat status": [
null,
"לחץ כדי לשנות את הודעת השיחה שלך"
],
"Click here to write a custom status message": [
null,
"לחץ כאן כדי לכתוב הודעת מצב מותאמת"
],
"online": [
null,
"מקוון"
],
"busy": [
null,
"עסוק"
],
"away for long": [
null,
"נעדר לזמן מה"
],
"away": [
null,
"נעדר"
],
"I am %1$s": [
null,
"מצבי כעת הינו %1$s"
],
"Sign in": [
null,
"התחברות"
],
"XMPP/Jabber Username:": [
null,
"שם משתמש XMPP/Jabber:"
],
"Password:": [
null,
"סיסמה:"
],
"Log In": [
null,
"כניסה"
],
"BOSH Service URL:": [
null,
"כתובת שירות BOSH:"
]
}
}
};
if (typeof define === 'function' && define.amd) {
define("he", ['jed'], function () {
return factory(new Jed(translations));
});
} else {
if (!window.locales) {
window.locales = {};
}
window.locales.he = factory(new Jed(translations));
}
}(this, function (he) {
return he;
}));

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,677 @@
# Bahasa Indonesia translations for Converse.js package.
# Copyright (C) 2014 Jan-Carel Brand
# Copyright (C) 2014 Priyadi Iman Nurcahyo
# This file is distributed under the same license as the Converse.js package.
# Priyadi Iman Nurcahyo <priyadi@priyadi.net>, 2014.
#
msgid ""
msgstr ""
"Project-Id-Version: Converse.js 0.7.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-01-22 17:07+0200\n"
"PO-Revision-Date: 2014-01-25 21:30+0700\n"
"Last-Translator: Priyadi Iman Nurcahyo <priyadi@priyadi.net>\n"
"Language-Team: Bahasa Indonesia\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: id\n"
#: converse.js:217
msgid "unencrypted"
msgstr "tak dienkripsi"
#: converse.js:218
msgid "unverified"
msgstr "tak diverifikasi"
#: converse.js:219
msgid "verified"
msgstr "diverifikasi"
#: converse.js:220
msgid "finished"
msgstr "selesai"
#: converse.js:223
msgid "This contact is busy"
msgstr "Teman ini sedang sibuk"
#: converse.js:224
msgid "This contact is online"
msgstr "Teman ini terhubung"
#: converse.js:225
msgid "This contact is offline"
msgstr "Teman ini tidak terhubung"
#: converse.js:226
msgid "This contact is unavailable"
msgstr "Teman ini tidak tersedia"
#: converse.js:227
msgid "This contact is away for an extended period"
msgstr "Teman ini tidak di tempat untuk waktu yang lama"
#: converse.js:228
msgid "This contact is away"
msgstr "Teman ini tidak di tempat"
#: converse.js:321
msgid "Disconnected"
msgstr "Terputus"
#: converse.js:331
msgid "Error"
msgstr "Kesalahan"
#: converse.js:333
msgid "Connecting"
msgstr "Menyambung"
#: converse.js:336
msgid "Connection Failed"
msgstr "Gagal Menyambung"
#: converse.js:338
msgid "Authenticating"
msgstr "Melakukan otentikasi"
#: converse.js:341
msgid "Authentication Failed"
msgstr "Otentikasi gagal"
#: converse.js:343
msgid "Disconnecting"
msgstr "Memutuskan hubungan"
#: converse.js:479
msgid "Online Contacts"
msgstr "Teman yang Terhubung"
#: converse.js:540
msgid "Re-establishing encrypted session"
msgstr "Menyambung kembali sesi terenkripsi"
#: converse.js:548
msgid ""
"Your browser needs to generate a private key, which will be used in your "
"encrypted chat session. This can take up to 30 seconds during which your "
"browser might freeze and become unresponsive."
msgstr ""
"Perambah anda perlu membuat kunci privat, yang akan digunakan pada sesi "
"perbincangan anda. Ini akan membutuhkan waktu sampai 30 detik, dan selama "
"itu perambah mungkin akan tidak responsif."
#: converse.js:557
msgid "Private key generated."
msgstr "Kunci privat berhasil dibuat."
#: converse.js:588
msgid ""
"Authentication request from %1$s\n"
"\n"
"Your buddy is attempting to verify your identity, by asking you the question "
"below.\n"
"\n"
"%2$s"
msgstr ""
"Permintaan otentikasi dari %1$s\n"
"\n"
"Teman anda mencoba untuk melakukan verifikasi identitas anda dengan cara "
"menanyakan pertanyaan di bawah ini.\n"
"\n"
"%2$s"
#: converse.js:597
msgid "Could not verify this user's identify."
msgstr "Tak dapat melakukan verifikasi identitas pengguna ini."
#: converse.js:750
msgid "Personal message"
msgstr "Pesan pribadi"
#: converse.js:795
msgid "Start encrypted conversation"
msgstr "Mulai sesi terenkripsi"
#: converse.js:798
msgid "Refresh encrypted conversation"
msgstr "Setel ulang percakapan terenkripsi"
#: converse.js:799
msgid "End encrypted conversation"
msgstr "Sudahi percakapan terenkripsi"
#: converse.js:800
msgid "Verify with SMP"
msgstr "Verifikasi menggunakan SMP"
#: converse.js:803
msgid "Verify with fingerprints"
msgstr "Verifikasi menggunakan sidik jari"
#: converse.js:805
msgid "What's this?"
msgstr "Apakah ini?"
#: converse.js:906
msgid "me"
msgstr "saya"
#: converse.js:1022 converse.js:1864
msgid "Show this menu"
msgstr "Tampilkan menu ini"
#: converse.js:1023 converse.js:1865
msgid "Write in the third person"
msgstr "Tulis ini menggunakan bahasa pihak ketiga"
#: converse.js:1024 converse.js:1869
msgid "Remove messages"
msgstr "Hapus pesan"
#: converse.js:1110
msgid "Your message could not be sent"
msgstr "Pesan anda tak dapat dikirim"
#: converse.js:1113
msgid "We received an unencrypted message"
msgstr "Kami menerima pesan terenkripsi"
#: converse.js:1116
msgid "We received an unreadable encrypted message"
msgstr "Kami menerima pesan terenkripsi yang gagal dibaca"
#: converse.js:1125
msgid "This user has requested an encrypted session."
msgstr "Pengguna ini meminta sesi terenkripsi"
#: converse.js:1147
msgid ""
"Here are the fingerprints, please confirm them with %1$s, outside of this "
"chat.\n"
"\n"
"Fingerprint for you, %2$s: %3$s\n"
"\n"
"Fingerprint for %1$s: %4$s\n"
"\n"
"If you have confirmed that the fingerprints match, click OK, otherwise click "
"Cancel."
msgstr ""
"Ini adalah sidik jari anda, konfirmasikan bersama mereka dengan %1$s, di "
"luar percakapan ini.\n"
"\n"
"Sidik jari untuk anda, %2$s: %3$s\n"
"\n"
"Sidik jari untuk %1$s: %4$s\n"
"\n"
"Jika anda bisa mengkonfirmasi sidik jadi cocok, klik Lanjutkan, jika tidak "
"klik Batal."
#: converse.js:1160
msgid ""
"You will be prompted to provide a security question and then an answer to "
"that question.\n"
"\n"
"Your buddy will then be prompted the same question and if they type the "
"exact same answer (case sensitive), their identity will have been verified."
msgstr ""
"Anda akan ditanyakan pertanyaan untuk keamanan beserta jawaban untuk "
"pertanyaan tersebut.\n"
"\n"
"Teman anda akan ditanyakan pertanyaan yang sama dan jika dia memberikan "
"jawaban yang sama (huruf kapital diperhatikan), identitas mereka "
"diverifikasi."
#: converse.js:1161
msgid "What is your security question?"
msgstr "Apakah pertanyaan keamanan anda?"
#: converse.js:1163
msgid "What is the answer to the security question?"
msgstr "Apa jawaban dari pertanyaan keamanan tersebut?"
#: converse.js:1167
msgid "Invalid authentication scheme provided"
msgstr "Skema otentikasi salah"
#: converse.js:1248
msgid "Your messages are not encrypted anymore"
msgstr "Pesan anda tidak lagi terenkripsi"
#: converse.js:1250
msgid ""
"Your messages are now encrypted but your buddy's identity has not been "
"verified."
msgstr ""
"Pesan anda sekarang terenkripsi, namun identitas teman anda belum dapat "
"diverifikasi."
#: converse.js:1252
msgid "Your buddy's identify has been verified."
msgstr "Identitas teman anda telah diverifikasi."
#: converse.js:1254
msgid "Your buddy has ended encryption on their end, you should do the same."
msgstr ""
"Teman anda menghentikan percakapan terenkripsi, anda sebaiknya melakukan hal "
"yang sama."
#: converse.js:1263
msgid "Your messages are not encrypted. Click here to enable OTR encryption."
msgstr ""
"Pesan anda tak terenkripsi. Klik di sini untuk menyalakan enkripsi OTR."
#: converse.js:1265
msgid "Your messages are encrypted, but your buddy has not been verified."
msgstr "Pesan anda terenkripsi, tetapi teman anda belum diverifikasi."
#: converse.js:1267
msgid "Your messages are encrypted and your buddy verified."
msgstr "Pesan anda terenkripsi dan teman anda telah diverifikasi."
#: converse.js:1269
msgid ""
"Your buddy has closed their end of the private session, you should do the "
"same"
msgstr ""
"Teman anda telah mematikan sesi terenkripsi, dan anda juga sebaiknya "
"melakukan hal yang sama"
#: converse.js:1354
msgid "Contacts"
msgstr "Teman"
#: converse.js:1359
msgid "Online"
msgstr "Terhubung"
#: converse.js:1360
msgid "Busy"
msgstr "Sibuk"
#: converse.js:1361
msgid "Away"
msgstr "Pergi"
#: converse.js:1362
msgid "Offline"
msgstr "Tak Terhubung"
#: converse.js:1372
msgid "Click to add new chat contacts"
msgstr "Klik untuk menambahkan teman baru"
#: converse.js:1373
msgid "Add a contact"
msgstr "Tambah teman"
#: converse.js:1382
msgid "Contact username"
msgstr "Username teman"
#: converse.js:1383
msgid "Add"
msgstr "Tambah"
#: converse.js:1391
msgid "Contact name"
msgstr "Nama teman"
#: converse.js:1392
msgid "Search"
msgstr "Cari"
#: converse.js:1439
msgid "No users found"
msgstr "Pengguna tak ditemukan"
#: converse.js:1446
msgid "Click to add as a chat contact"
msgstr "Klik untuk menambahkan sebagai teman"
#: converse.js:1498
msgid "Click to open this room"
msgstr "Klik untuk membuka ruangan ini"
#: converse.js:1500
msgid "Show more information on this room"
msgstr "Tampilkan informasi ruangan ini"
#: converse.js:1506
msgid "Description:"
msgstr "Keterangan:"
#: converse.js:1507
msgid "Occupants:"
msgstr "Penghuni:"
#: converse.js:1508
msgid "Features:"
msgstr "Fitur:"
#: converse.js:1510
msgid "Requires authentication"
msgstr "Membutuhkan otentikasi"
#: converse.js:1513
msgid "Hidden"
msgstr "Tersembunyi"
#: converse.js:1516
msgid "Requires an invitation"
msgstr "Membutuhkan undangan"
#: converse.js:1519
msgid "Moderated"
msgstr "Dimoderasi"
#: converse.js:1522
msgid "Non-anonymous"
msgstr "Tidak anonim"
#: converse.js:1525
msgid "Open room"
msgstr "Ruangan terbuka"
#: converse.js:1528
msgid "Permanent room"
msgstr "Ruangan permanen"
#: converse.js:1531
msgid "Public"
msgstr "Umum"
#: converse.js:1534
msgid "Semi-anonymous"
msgstr "Semi-anonim"
#: converse.js:1537
msgid "Temporary room"
msgstr "Ruangan sementara"
#: converse.js:1540
msgid "Unmoderated"
msgstr "Tak dimoderasi"
#: converse.js:1546
msgid "Rooms"
msgstr "Ruangan"
#: converse.js:1550
msgid "Room name"
msgstr "Nama ruangan"
#: converse.js:1551
msgid "Nickname"
msgstr "Nama panggilan"
#: converse.js:1552
msgid "Server"
msgstr "Server"
#: converse.js:1553
msgid "Join"
msgstr "Ikuti"
#: converse.js:1554
msgid "Show rooms"
msgstr "Perlihatkan ruangan"
#. For translators: %1$s is a variable and will be replaced with the XMPP server name
#: converse.js:1589
msgid "No rooms on %1$s"
msgstr "Tak ada ruangan di %1$s"
#. For translators: %1$s is a variable and will be
#. replaced with the XMPP server name
#: converse.js:1604
msgid "Rooms on %1$s"
msgstr "Ruangan di %1$s"
#: converse.js:1866
msgid "Set chatroom topic"
msgstr "Setel topik ruangan"
#: converse.js:1867
msgid "Kick user from chatroom"
msgstr "Tendang pengguna dari ruangan"
#: converse.js:1868
msgid "Ban user from chatroom"
msgstr "Larang pengguna dari ruangan"
#: converse.js:1898
msgid "Message"
msgstr "Pesan"
#: converse.js:2013 converse.js:3168
msgid "Save"
msgstr "Simpan"
#: converse.js:2014
msgid "Cancel"
msgstr "Batal"
#: converse.js:2061
msgid "An error occurred while trying to save the form."
msgstr "Kesalahan terjadi saat menyimpan formulir ini."
#: converse.js:2107
msgid "This chatroom requires a password"
msgstr "Ruangan ini membutuhkan kata sandi"
#: converse.js:2108
msgid "Password: "
msgstr "Kata sandi: "
#: converse.js:2109
msgid "Submit"
msgstr "Kirim"
#: converse.js:2123
msgid "This room is not anonymous"
msgstr "Ruangan ini tidak anonim"
#: converse.js:2124
msgid "This room now shows unavailable members"
msgstr "Ruangan ini menampilkan anggota yang tak tersedia"
#: converse.js:2125
msgid "This room does not show unavailable members"
msgstr "Ruangan ini tidak menampilkan anggota yang tak tersedia"
#: converse.js:2126
msgid "Non-privacy-related room configuration has changed"
msgstr "Konfigurasi ruangan yang tak berhubungan dengan privasi telah diubah"
#: converse.js:2127
msgid "Room logging is now enabled"
msgstr "Pencatatan di ruangan ini sekarang dinyalakan"
#: converse.js:2128
msgid "Room logging is now disabled"
msgstr "Pencatatan di ruangan ini sekarang dimatikan"
#: converse.js:2129
msgid "This room is now non-anonymous"
msgstr "Ruangan ini sekarang tak-anonim"
#: converse.js:2130
msgid "This room is now semi-anonymous"
msgstr "Ruangan ini sekarang semi-anonim"
#: converse.js:2131
msgid "This room is now fully-anonymous"
msgstr "Ruangan ini sekarang anonim"
#: converse.js:2132
msgid "A new room has been created"
msgstr "Ruangan baru telah dibuat"
#: converse.js:2133
msgid "Your nickname has been changed"
msgstr "Nama panggilan anda telah diubah"
#: converse.js:2147
msgid "<strong>%1$s</strong> has been banned"
msgstr "<strong>%1$s</strong> telah dicekal"
#: converse.js:2148
msgid "<strong>%1$s</strong> has been kicked out"
msgstr "<strong>%1$s</strong> telah ditendang keluar"
#: converse.js:2149
msgid "<strong>%1$s</strong> has been removed because of an affiliation change"
msgstr "<strong>%1$s</strong> telah dihapus karena perubahan afiliasi"
#: converse.js:2150
msgid "<strong>%1$s</strong> has been removed for not being a member"
msgstr "<strong>%1$s</strong> telah dihapus karena bukan anggota"
#: converse.js:2154 converse.js:2214
msgid "You have been banned from this room"
msgstr "Anda telah dicekal dari ruangan ini"
#: converse.js:2155
msgid "You have been kicked from this room"
msgstr "Anda telah ditendang dari ruangan ini"
#: converse.js:2156
msgid "You have been removed from this room because of an affiliation change"
msgstr "Anda telah dihapus dari ruangan ini karena perubahan afiliasi"
#: converse.js:2157
msgid ""
"You have been removed from this room because the room has changed to members-"
"only and you're not a member"
msgstr ""
"Anda telah dihapus dari ruangan ini karena ruangan ini hanya terbuka untuk "
"anggota dan anda bukan anggota"
#: converse.js:2158
msgid ""
"You have been removed from this room because the MUC (Multi-user chat) "
"service is being shut down."
msgstr ""
"Anda telah dihapus dari ruangan ini karena layanan MUC (Multi-user chat) "
"telah dimatikan."
#: converse.js:2212
msgid "You are not on the member list of this room"
msgstr "Anda bukan anggota dari ruangan ini"
#: converse.js:2218
msgid "No nickname was specified"
msgstr "Nama panggilan belum ditentukan"
#: converse.js:2222
msgid "You are not allowed to create new rooms"
msgstr "Anda tak diizinkan untuk membuat ruangan baru"
#: converse.js:2224
msgid "Your nickname doesn't conform to this room's policies"
msgstr "Nama panggilan anda tidak sesuai aturan ruangan ini"
#: converse.js:2226
msgid "Your nickname is already taken"
msgstr "Nama panggilan anda telah digunakan orang lain"
#: converse.js:2228
msgid "This room does not (yet) exist"
msgstr "Ruangan ini belum dibuat"
#: converse.js:2230
msgid "This room has reached it's maximum number of occupants"
msgstr "Ruangan ini telah mencapai jumlah penghuni maksimum"
#: converse.js:2309
msgid "Topic set by %1$s to: %2$s"
msgstr "Topik diganti oleh %1$s menjadi: %2$s"
#: converse.js:2330
msgid "This user is a moderator"
msgstr "Pengguna ini adalah moderator"
#: converse.js:2333
msgid "This user can send messages in this room"
msgstr "Pengguna ini dapat mengirim pesan di ruangan ini"
#: converse.js:2336
msgid "This user can NOT send messages in this room"
msgstr "Pengguna ini tak dapat mengirim pesan di ruangan ini"
#: converse.js:2562
msgid "Click to chat with this contact"
msgstr "Klik untuk mulai perbinjangan dengan teman ini"
#: converse.js:2565 converse.js:2569
msgid "Click to remove this contact"
msgstr "Klik untuk menghapus teman ini"
#: converse.js:2919
msgid "Contact requests"
msgstr "Permintaan pertemanan"
#: converse.js:2922
msgid "My contacts"
msgstr "Teman saya"
#: converse.js:2925
msgid "Pending contacts"
msgstr "Teman yang menunggu"
#: converse.js:3167
msgid "Custom status"
msgstr "Status kustom"
#: converse.js:3173
msgid "Click to change your chat status"
msgstr "Klik untuk mengganti status"
#: converse.js:3177
msgid "Click here to write a custom status message"
msgstr "Klik untuk menulis status kustom"
#: converse.js:3206 converse.js:3214
msgid "online"
msgstr "terhubung"
#: converse.js:3208
msgid "busy"
msgstr "sibuk"
#: converse.js:3210
msgid "away for long"
msgstr "lama tak di tempat"
#: converse.js:3212
msgid "away"
msgstr "tak di tempat"
#. For translators: the %1$s part gets replaced with the status
#. Example, I am online
#: converse.js:3226 converse.js:3263
msgid "I am %1$s"
msgstr "Saya %1$s"
#: converse.js:3334
msgid "Sign in"
msgstr "Masuk"
#: converse.js:3338
msgid "XMPP/Jabber Username:"
msgstr "Nama pengguna XMPP/Jabber:"
#: converse.js:3340
msgid "Password:"
msgstr "Kata sandi:"
#: converse.js:3342
msgid "Log In"
msgstr "Masuk"
#: converse.js:3346
msgid "BOSH Service URL:"
msgstr "URL Layanan BOSH:"

180
locale/id/LC_MESSAGES/id.js Normal file
View File

@ -0,0 +1,180 @@
(function(root, factory) {
var translations = {
"domain": "converse",
"locale_data": {
"converse": {
"": {
"project-id-version": "Converse.js 0.7.0",
"report-msgid-bugs-to": "",
"pot-creation-date": "2014-01-22 17:07+0200",
"po-revision-date": "2014-01-25 21:30+0700",
"last-translator": "Priyadi Iman Nurcahyo <priyadi@priyadi.net>",
"language-team": "Bahasa Indonesia",
"mime-version": "1.0",
"content-type": "text/plain; charset=UTF-8",
"content-transfer-encoding": "8bit",
"language": "id"
},
"unencrypted": [null, "tak dienkripsi"],
"unverified": [null, "tak diverifikasi"],
"verified": [null, "diverifikasi"],
"finished": [null, "selesai"],
"This contact is busy": [null, "Teman ini sedang sibuk"],
"This contact is online": [null, "Teman ini terhubung"],
"This contact is offline": [null, "Teman ini tidak terhubung"],
"This contact is unavailable": [null, "Teman ini tidak tersedia"],
"This contact is away for an extended period": [null, "Teman ini tidak di tempat untuk waktu yang lama"],
"This contact is away": [null, "Teman ini tidak di tempat"],
"Disconnected": [null, "Terputus"],
"Error": [null, "Kesalahan"],
"Connecting": [null, "Menyambung"],
"Connection Failed": [null, "Gagal Menyambung"],
"Authenticating": [null, "Melakukan otentikasi"],
"Authentication Failed": [null, "Otentikasi gagal"],
"Disconnecting": [null, "Memutuskan hubungan"],
"Online Contacts": [null, "Teman yang Terhubung"],
"Re-establishing encrypted session": [null, "Menyambung kembali sesi terenkripsi"],
"Your browser needs to generate a private key, which will be used in your encrypted chat session. This can take up to 30 seconds during which your browser might freeze and become unresponsive.": [null, "Perambah anda perlu membuat kunci privat, yang akan digunakan pada sesi perbincangan anda. Ini akan membutuhkan waktu sampai 30 detik, dan selama itu perambah mungkin akan tidak responsif."],
"Private key generated.": [null, "Kunci privat berhasil dibuat."],
"Authentication request from %1$s\n\nYour buddy is attempting to verify your identity, by asking you the question below.\n\n%2$s": [null, "Permintaan otentikasi dari %1$s\n\nTeman anda mencoba untuk melakukan verifikasi identitas anda dengan cara menanyakan pertanyaan di bawah ini.\n\n%2$s"],
"Could not verify this user's identify.": [null, "Tak dapat melakukan verifikasi identitas pengguna ini."],
"Personal message": [null, "Pesan pribadi"],
"Start encrypted conversation": [null, "Mulai sesi terenkripsi"],
"Refresh encrypted conversation": [null, "Setel ulang percakapan terenkripsi"],
"End encrypted conversation": [null, "Sudahi percakapan terenkripsi"],
"Verify with SMP": [null, "Verifikasi menggunakan SMP"],
"Verify with fingerprints": [null, "Verifikasi menggunakan sidik jari"],
"What's this?": [null, "Apakah ini?"],
"me": [null, "saya"],
"Show this menu": [null, "Tampilkan menu ini"],
"Write in the third person": [null, "Tulis ini menggunakan bahasa pihak ketiga"],
"Remove messages": [null, "Hapus pesan"],
"Your message could not be sent": [null, "Pesan anda tak dapat dikirim"],
"We received an unencrypted message": [null, "Kami menerima pesan terenkripsi"],
"We received an unreadable encrypted message": [null, "Kami menerima pesan terenkripsi yang gagal dibaca"],
"This user has requested an encrypted session.": [null, "Pengguna ini meminta sesi terenkripsi"],
"Here are the fingerprints, please confirm them with %1$s, outside of this chat.\n\nFingerprint for you, %2$s: %3$s\n\nFingerprint for %1$s: %4$s\n\nIf you have confirmed that the fingerprints match, click OK, otherwise click Cancel.": [null, "Ini adalah sidik jari anda, konfirmasikan bersama mereka dengan %1$s, di luar percakapan ini.\n\nSidik jari untuk anda, %2$s: %3$s\n\nSidik jari untuk %1$s: %4$s\n\nJika anda bisa mengkonfirmasi sidik jadi cocok, klik Lanjutkan, jika tidak klik Batal."],
"You will be prompted to provide a security question and then an answer to that question.\n\nYour buddy will then be prompted the same question and if they type the exact same answer (case sensitive), their identity will have been verified.": [null, "Anda akan ditanyakan pertanyaan untuk keamanan beserta jawaban untuk pertanyaan tersebut.\n\nTeman anda akan ditanyakan pertanyaan yang sama dan jika dia memberikan jawaban yang sama (huruf kapital diperhatikan), identitas mereka diverifikasi."],
"What is your security question?": [null, "Apakah pertanyaan keamanan anda?"],
"What is the answer to the security question?": [null, "Apa jawaban dari pertanyaan keamanan tersebut?"],
"Invalid authentication scheme provided": [null, "Skema otentikasi salah"],
"Your messages are not encrypted anymore": [null, "Pesan anda tidak lagi terenkripsi"],
"Your messages are now encrypted but your buddy's identity has not been verified.": [null, "Pesan anda sekarang terenkripsi, namun identitas teman anda belum dapat diverifikasi."],
"Your buddy's identify has been verified.": [null, "Identitas teman anda telah diverifikasi."],
"Your buddy has ended encryption on their end, you should do the same.": [null, "Teman anda menghentikan percakapan terenkripsi, anda sebaiknya melakukan hal yang sama."],
"Your messages are not encrypted. Click here to enable OTR encryption.": [null, "Pesan anda tak terenkripsi. Klik di sini untuk menyalakan enkripsi OTR."],
"Your messages are encrypted, but your buddy has not been verified.": [null, "Pesan anda terenkripsi, tetapi teman anda belum diverifikasi."],
"Your messages are encrypted and your buddy verified.": [null, "Pesan anda terenkripsi dan teman anda telah diverifikasi."],
"Your buddy has closed their end of the private session, you should do the same": [null, "Teman anda telah mematikan sesi terenkripsi, dan anda juga sebaiknya melakukan hal yang sama"],
"Contacts": [null, "Teman"],
"Online": [null, "Terhubung"],
"Busy": [null, "Sibuk"],
"Away": [null, "Pergi"],
"Offline": [null, "Tak Terhubung"],
"Click to add new chat contacts": [null, "Klik untuk menambahkan teman baru"],
"Add a contact": [null, "Tambah teman"],
"Contact username": [null, "Username teman"],
"Add": [null, "Tambah"],
"Contact name": [null, "Nama teman"],
"Search": [null, "Cari"],
"No users found": [null, "Pengguna tak ditemukan"],
"Click to add as a chat contact": [null, "Klik untuk menambahkan sebagai teman"],
"Click to open this room": [null, "Klik untuk membuka ruangan ini"],
"Show more information on this room": [null, "Tampilkan informasi ruangan ini"],
"Description:": [null, "Keterangan:"],
"Occupants:": [null, "Penghuni:"],
"Features:": [null, "Fitur:"],
"Requires authentication": [null, "Membutuhkan otentikasi"],
"Hidden": [null, "Tersembunyi"],
"Requires an invitation": [null, "Membutuhkan undangan"],
"Moderated": [null, "Dimoderasi"],
"Non-anonymous": [null, "Tidak anonim"],
"Open room": [null, "Ruangan terbuka"],
"Permanent room": [null, "Ruangan permanen"],
"Public": [null, "Umum"],
"Semi-anonymous": [null, "Semi-anonim"],
"Temporary room": [null, "Ruangan sementara"],
"Unmoderated": [null, "Tak dimoderasi"],
"Rooms": [null, "Ruangan"],
"Room name": [null, "Nama ruangan"],
"Nickname": [null, "Nama panggilan"],
"Server": [null, "Server"],
"Join": [null, "Ikuti"],
"Show rooms": [null, "Perlihatkan ruangan"],
"No rooms on %1$s": [null, "Tak ada ruangan di %1$s"],
"Rooms on %1$s": [null, "Ruangan di %1$s"],
"Set chatroom topic": [null, "Setel topik ruangan"],
"Kick user from chatroom": [null, "Tendang pengguna dari ruangan"],
"Ban user from chatroom": [null, "Larang pengguna dari ruangan"],
"Message": [null, "Pesan"],
"Save": [null, "Simpan"],
"Cancel": [null, "Batal"],
"An error occurred while trying to save the form.": [null, "Kesalahan terjadi saat menyimpan formulir ini."],
"This chatroom requires a password": [null, "Ruangan ini membutuhkan kata sandi"],
"Password: ": [null, "Kata sandi: "],
"Submit": [null, "Kirim"],
"This room is not anonymous": [null, "Ruangan ini tidak anonim"],
"This room now shows unavailable members": [null, "Ruangan ini menampilkan anggota yang tak tersedia"],
"This room does not show unavailable members": [null, "Ruangan ini tidak menampilkan anggota yang tak tersedia"],
"Non-privacy-related room configuration has changed": [null, "Konfigurasi ruangan yang tak berhubungan dengan privasi telah diubah"],
"Room logging is now enabled": [null, "Pencatatan di ruangan ini sekarang dinyalakan"],
"Room logging is now disabled": [null, "Pencatatan di ruangan ini sekarang dimatikan"],
"This room is now non-anonymous": [null, "Ruangan ini sekarang tak-anonim"],
"This room is now semi-anonymous": [null, "Ruangan ini sekarang semi-anonim"],
"This room is now fully-anonymous": [null, "Ruangan ini sekarang anonim"],
"A new room has been created": [null, "Ruangan baru telah dibuat"],
"Your nickname has been changed": [null, "Nama panggilan anda telah diubah"],
"<strong>%1$s</strong> has been banned": [null, "<strong>%1$s</strong> telah dicekal"],
"<strong>%1$s</strong> has been kicked out": [null, "<strong>%1$s</strong> telah ditendang keluar"],
"<strong>%1$s</strong> has been removed because of an affiliation change": [null, "<strong>%1$s</strong> telah dihapus karena perubahan afiliasi"],
"<strong>%1$s</strong> has been removed for not being a member": [null, "<strong>%1$s</strong> telah dihapus karena bukan anggota"],
"You have been banned from this room": [null, "Anda telah dicekal dari ruangan ini"],
"You have been kicked from this room": [null, "Anda telah ditendang dari ruangan ini"],
"You have been removed from this room because of an affiliation change": [null, "Anda telah dihapus dari ruangan ini karena perubahan afiliasi"],
"You have been removed from this room because the room has changed to members-only and you're not a member": [null, "Anda telah dihapus dari ruangan ini karena ruangan ini hanya terbuka untuk anggota dan anda bukan anggota"],
"You have been removed from this room because the MUC (Multi-user chat) service is being shut down.": [null, "Anda telah dihapus dari ruangan ini karena layanan MUC (Multi-user chat) telah dimatikan."],
"You are not on the member list of this room": [null, "Anda bukan anggota dari ruangan ini"],
"No nickname was specified": [null, "Nama panggilan belum ditentukan"],
"You are not allowed to create new rooms": [null, "Anda tak diizinkan untuk membuat ruangan baru"],
"Your nickname doesn't conform to this room's policies": [null, "Nama panggilan anda tidak sesuai aturan ruangan ini"],
"Your nickname is already taken": [null, "Nama panggilan anda telah digunakan orang lain"],
"This room does not (yet) exist": [null, "Ruangan ini belum dibuat"],
"This room has reached it's maximum number of occupants": [null, "Ruangan ini telah mencapai jumlah penghuni maksimum"],
"Topic set by %1$s to: %2$s": [null, "Topik diganti oleh %1$s menjadi: %2$s"],
"This user is a moderator": [null, "Pengguna ini adalah moderator"],
"This user can send messages in this room": [null, "Pengguna ini dapat mengirim pesan di ruangan ini"],
"This user can NOT send messages in this room": [null, "Pengguna ini tak dapat mengirim pesan di ruangan ini"],
"Click to chat with this contact": [null, "Klik untuk mulai perbinjangan dengan teman ini"],
"Click to remove this contact": [null, "Klik untuk menghapus teman ini"],
"Contact requests": [null, "Permintaan pertemanan"],
"My contacts": [null, "Teman saya"],
"Pending contacts": [null, "Teman yang menunggu"],
"Custom status": [null, "Status kustom"],
"Click to change your chat status": [null, "Klik untuk mengganti status"],
"Click here to write a custom status message": [null, "Klik untuk menulis status kustom"],
"online": [null, "terhubung"],
"busy": [null, "sibuk"],
"away for long": [null, "lama tak di tempat"],
"away": [null, "tak di tempat"],
"I am %1$s": [null, "Saya %1$s"],
"Sign in": [null, "Masuk"],
"XMPP/Jabber Username:": [null, "Nama pengguna XMPP/Jabber:"],
"Password:": [null, "Kata sandi:"],
"Log In": [null, "Masuk"],
"BOSH Service URL:": [null, "URL Layanan BOSH:"]
}
}
};
if (typeof define === 'function' && define.amd) {
define("id", ['jed'], function () {
return factory(new Jed(translations));
});
} else {
if (!window.locales) {
window.locales = {};
}
window.locales.id = factory(new Jed(translations));
}
}(this, function (id) {
return id;
}));

View File

@ -14,7 +14,9 @@
"en": "locale/en/LC_MESSAGES/en", "en": "locale/en/LC_MESSAGES/en",
"es": "locale/es/LC_MESSAGES/es", "es": "locale/es/LC_MESSAGES/es",
"fr": "locale/fr/LC_MESSAGES/fr", "fr": "locale/fr/LC_MESSAGES/fr",
"he": "locale/he/LC_MESSAGES/he",
"hu": "locale/hu/LC_MESSAGES/hu", "hu": "locale/hu/LC_MESSAGES/hu",
"id": "locale/id/LC_MESSAGES/id",
"it": "locale/it/LC_MESSAGES/it", "it": "locale/it/LC_MESSAGES/it",
"ja": "locale/ja/LC_MESSAGES/ja", "ja": "locale/ja/LC_MESSAGES/ja",
"nl": "locale/nl/LC_MESSAGES/nl", "nl": "locale/nl/LC_MESSAGES/nl",
@ -30,20 +32,24 @@
'en', 'en',
'es', 'es',
'fr', 'fr',
'he',
'hu', 'hu',
'id',
'it', 'it',
'ja', 'ja',
'nl', 'nl',
'pt_BR', 'pt_BR',
'ru' 'ru'
], function (jed, af, de, en, es, fr, hu, it, ja, nl, pt_BR, ru) { ], function (jed, af, de, en, es, fr, he, hu, id, it, ja, nl, pt_BR, ru) {
root.locales = { root.locales = {
'af': af, 'af': af,
'de': de, 'de': de,
'en': en, 'en': en,
'es': es, 'es': es,
'fr': fr, 'fr': fr,
'he': he,
'hu': hu, 'hu': hu,
'id': id,
'it': it, 'it': it,
'ja': ja, 'ja': ja,
'nl': nl, 'nl': nl,

View File

@ -1,6 +1,6 @@
{ {
"name": "converse.js", "name": "converse.js",
"version": "0.7.2", "version": "0.7.3",
"description": "Browser based XMPP instant messaging client", "description": "Browser based XMPP instant messaging client",
"main": "main.js", "main": "main.js",
"directories": { "directories": {

View File

@ -8,60 +8,40 @@
); );
} (this, function (mock, utils) { } (this, function (mock, utils) {
return describe("Converse", $.proxy(function(mock, utils) { return describe("Converse", $.proxy(function(mock, utils) {
window.localStorage.clear();
it("allows you to subscribe to emitted events", function () { beforeEach($.proxy(function () {
this.callback = function () {}; window.localStorage.clear();
spyOn(this, 'callback'); window.sessionStorage.clear();
converse.on('onInitialized', this.callback); }, converse));
converse.emit('onInitialized');
expect(this.callback).toHaveBeenCalled();
converse.emit('onInitialized');
expect(this.callback.callCount, 2);
converse.emit('onInitialized');
expect(this.callback.callCount, 3);
});
it("allows you to listen once for an emitted event", function () { it("has an API method for retrieving the next RID", $.proxy(function () {
this.callback = function () {}; var old_connection = converse.connection;
spyOn(this, 'callback'); converse.connection.rid = '1234';
converse.once('onInitialized', this.callback); converse.expose_rid_and_sid = false;
converse.emit('onInitialized'); expect(converse_api.getRID()).toBe(null);
expect(this.callback).toHaveBeenCalled();
converse.emit('onInitialized');
expect(this.callback.callCount, 1);
converse.emit('onInitialized');
expect(this.callback.callCount, 1);
});
it("allows you to stop listening or subscribing to an event", function () { converse.expose_rid_and_sid = true;
this.callback = function () {}; expect(converse_api.getRID()).toBe('1234');
this.anotherCallback = function () {};
this.neverCalled = function () {};
spyOn(this, 'callback'); converse.connection = undefined;
spyOn(this, 'anotherCallback'); expect(converse_api.getRID()).toBe(null);
spyOn(this, 'neverCalled'); // Restore the connection
converse.on('onInitialized', this.callback); converse.connection = old_connection;
converse.on('onInitialized', this.anotherCallback); }, converse));
converse.emit('onInitialized'); it("has an API method for retrieving the SID", $.proxy(function () {
expect(this.callback).toHaveBeenCalled(); var old_connection = converse.connection;
expect(this.anotherCallback).toHaveBeenCalled(); converse.connection.sid = '1234';
converse.expose_rid_and_sid = false;
expect(converse_api.getSID()).toBe(null);
converse.off('onInitialized', this.callback); converse.expose_rid_and_sid = true;
expect(converse_api.getSID()).toBe('1234');
converse.emit('onInitialized'); converse.connection = undefined;
expect(this.callback.callCount, 1); expect(converse_api.getSID()).toBe(null);
expect(this.anotherCallback.callCount, 2); // Restore the connection
converse.connection = old_connection;
converse.once('onInitialized', this.neverCalled); }, converse));
converse.off('onInitialized', this.neverCalled);
converse.emit('onInitialized');
expect(this.callback.callCount, 1);
expect(this.anotherCallback.callCount, 3);
expect(this.neverCalled).not.toHaveBeenCalled();
});
}, converse, mock, utils)); }, converse, mock, utils));
})); }));

67
spec/eventemitter.js Normal file
View File

@ -0,0 +1,67 @@
(function (root, factory) {
define([
"mock",
"utils"
], function (mock, utils) {
return factory(mock, utils);
}
);
} (this, function (mock, utils) {
return describe("The Converse Event Emitter", $.proxy(function(mock, utils) {
window.localStorage.clear();
it("allows you to subscribe to emitted events", function () {
this.callback = function () {};
spyOn(this, 'callback');
converse.on('onInitialized', this.callback);
converse.emit('onInitialized');
expect(this.callback).toHaveBeenCalled();
converse.emit('onInitialized');
expect(this.callback.callCount, 2);
converse.emit('onInitialized');
expect(this.callback.callCount, 3);
});
it("allows you to listen once for an emitted event", function () {
this.callback = function () {};
spyOn(this, 'callback');
converse.once('onInitialized', this.callback);
converse.emit('onInitialized');
expect(this.callback).toHaveBeenCalled();
converse.emit('onInitialized');
expect(this.callback.callCount, 1);
converse.emit('onInitialized');
expect(this.callback.callCount, 1);
});
it("allows you to stop listening or subscribing to an event", function () {
this.callback = function () {};
this.anotherCallback = function () {};
this.neverCalled = function () {};
spyOn(this, 'callback');
spyOn(this, 'anotherCallback');
spyOn(this, 'neverCalled');
converse.on('onInitialized', this.callback);
converse.on('onInitialized', this.anotherCallback);
converse.emit('onInitialized');
expect(this.callback).toHaveBeenCalled();
expect(this.anotherCallback).toHaveBeenCalled();
converse.off('onInitialized', this.callback);
converse.emit('onInitialized');
expect(this.callback.callCount, 1);
expect(this.anotherCallback.callCount, 2);
converse.once('onInitialized', this.neverCalled);
converse.off('onInitialized', this.neverCalled);
converse.emit('onInitialized');
expect(this.callback.callCount, 1);
expect(this.anotherCallback.callCount, 3);
expect(this.neverCalled).not.toHaveBeenCalled();
});
}, converse, mock, utils));
}));

40
spec/otr.js Normal file
View File

@ -0,0 +1,40 @@
(function (root, factory) {
define([
"mock",
"utils"
], function (mock, utils) {
return factory(mock, utils);
}
);
} (this, function (mock, utils) {
return describe("The OTR module", $.proxy(function(mock, utils) {
beforeEach($.proxy(function () {
window.localStorage.clear();
window.sessionStorage.clear();
}, converse));
it("can store a session passphrase in session storage", $.proxy(function () {
var pp;
// With no prebind, the user's XMPP password is used and nothing is
// stored in session storage.
this.prebind = false;
this.connection.pass = 's3cr3t!';
expect(this.otr.getSessionPassphrase()).toBe(this.connection.pass);
expect(window.sessionStorage.length).toBe(0);
expect(window.localStorage.length).toBe(0);
// With prebind, a random passphrase is generated and stored in
// session storage.
this.prebind = true;
pp = this.otr.getSessionPassphrase();
expect(pp).not.toBe(this.connection.pass);
expect(window.sessionStorage.length).toBe(1);
expect(window.localStorage.length).toBe(0);
expect(pp).toBe(window.sessionStorage[hex_sha1(converse.connection.jid)]);
// Clean up
this.prebind = false;
}, converse));
}, converse, mock, utils));
}));

View File

@ -7,8 +7,6 @@
"jquery": "components/jquery/jquery", "jquery": "components/jquery/jquery",
"jed": "components/jed/jed", "jed": "components/jed/jed",
"locales": "locale/nolocales", "locales": "locale/nolocales",
"pt_BR": "locale/pt_BR/LC_MESSAGES/pt_BR",
"ru": "locale/ru/LC_MESSAGES/ru",
"jquery.tinysort": "components/tinysort/src/jquery.tinysort", "jquery.tinysort": "components/tinysort/src/jquery.tinysort",
"underscore": "components/underscore/underscore", "underscore": "components/underscore/underscore",
"backbone": "components/backbone/backbone", "backbone": "components/backbone/backbone",

View File

@ -12,8 +12,11 @@
"en": "locale/en/LC_MESSAGES/en", "en": "locale/en/LC_MESSAGES/en",
"es": "locale/es/LC_MESSAGES/es", "es": "locale/es/LC_MESSAGES/es",
"fr": "locale/fr/LC_MESSAGES/fr", "fr": "locale/fr/LC_MESSAGES/fr",
"he": "locale/he/LC_MESSAGES/he",
"hu": "locale/hu/LC_MESSAGES/hu", "hu": "locale/hu/LC_MESSAGES/hu",
"it": "locale/it/LC_MESSAGES/it", "it": "locale/it/LC_MESSAGES/it",
"id": "locale/id/LC_MESSAGES/id",
"ja": "locale/ja/LC_MESSAGES/ja",
"nl": "locale/nl/LC_MESSAGES/nl", "nl": "locale/nl/LC_MESSAGES/nl",
"pt_BR": "locale/pt_BR/LC_MESSAGES/pt_BR", "pt_BR": "locale/pt_BR/LC_MESSAGES/pt_BR",
"ru": "locale/ru/LC_MESSAGES/ru", "ru": "locale/ru/LC_MESSAGES/ru",

View File

@ -12,8 +12,11 @@
"en": "locale/en/LC_MESSAGES/en", "en": "locale/en/LC_MESSAGES/en",
"es": "locale/es/LC_MESSAGES/es", "es": "locale/es/LC_MESSAGES/es",
"fr": "locale/fr/LC_MESSAGES/fr", "fr": "locale/fr/LC_MESSAGES/fr",
"he": "locale/he/LC_MESSAGES/he",
"hu": "locale/hu/LC_MESSAGES/hu", "hu": "locale/hu/LC_MESSAGES/hu",
"id": "locale/id/LC_MESSAGES/id",
"it": "locale/it/LC_MESSAGES/it", "it": "locale/it/LC_MESSAGES/it",
"ja": "locale/ja/LC_MESSAGES/ja",
"nl": "locale/nl/LC_MESSAGES/nl", "nl": "locale/nl/LC_MESSAGES/nl",
"pt_BR": "locale/pt_BR/LC_MESSAGES/pt_BR", "pt_BR": "locale/pt_BR/LC_MESSAGES/pt_BR",
"ru": "locale/ru/LC_MESSAGES/ru", "ru": "locale/ru/LC_MESSAGES/ru",

View File

@ -47,6 +47,7 @@ require([
"jasmine-html" "jasmine-html"
], function($, converse, mock, jasmine) { ], function($, converse, mock, jasmine) {
// Set up converse.js // Set up converse.js
window.converse_api = converse;
window.localStorage.clear(); window.localStorage.clear();
converse.initialize({ converse.initialize({
prebind: false, prebind: false,
@ -58,10 +59,20 @@ require([
testing: true testing: true
}, function (converse) { }, function (converse) {
window.converse = converse; window.converse = converse;
window.crypto = {
getRandomValues: function (buf) {
var i;
for (i=0, len=buf.length; i<len; i++) {
buf[i] = Math.floor(Math.random()*256);
}
}
};
require([ require([
"jasmine-console-reporter", "jasmine-console-reporter",
"jasmine-junit-reporter", "jasmine-junit-reporter",
"spec/converse", "spec/converse",
"spec/otr",
"spec/eventemitter",
"spec/controlbox", "spec/controlbox",
"spec/chatbox", "spec/chatbox",
"spec/chatroom" "spec/chatroom"