diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..f02c9f24 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +# EditorConfig is awesome: http://EditorConfig.org + +root = true + +[*] +end_of_line = lf +insert_final_newline = true +indent_style = tab +indent_size = 4 +charset = utf-8 +trim_trailing_whitespace = true diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..6915f9e6 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +res/notify.m4a binary +res/notify.ogg binary +res/notify.mp3 binary diff --git a/.gitignore b/.gitignore index d2809c08..3a9bb327 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,12 @@ example/.htaccess .idea .ndproj/Data .ndproj/Menu.txt -node_modules \ No newline at end of file +node_modules +bower_components +candy.bundle.* +candy.min.* +libs.bundle.* +libs.min.* +.vagrant +*.log +lcov.info diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index fe85dab3..00000000 --- a/.gitmodules +++ /dev/null @@ -1,12 +0,0 @@ -[submodule "libs/jquery-i18n"] - path = libs/jquery-i18n - url = git://github.com/recurser/jquery-i18n.git -[submodule "libs/strophejs"] - path = libs/strophejs - url = git://github.com/strophe/strophejs.git -[submodule "libs/strophejs-plugins"] - path = libs/strophejs-plugins - url = git://github.com/strophe/strophejs-plugins.git -[submodule "libs/mustache.js"] - path = libs/mustache.js - url = git://github.com/janl/mustache.js.git diff --git a/.jshintrc b/.jshintrc index d2f32adb..6a2ea00e 100644 --- a/.jshintrc +++ b/.jshintrc @@ -8,5 +8,7 @@ "undef": true, "unused": true, "trailing": true, - "maxdepth": 4 -} \ No newline at end of file + "maxdepth": 5, + "laxcomma": true, + "browser": true +} diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..e8b54cf7 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,22 @@ +language: node_js +node_js: +- '0.10' +env: + global: + - SAUCE_USERNAME: candy-chat-ci + - SAUCE_ACCESS_KEY: 6c3e7f58-b230-4b91-8bcb-290cf28c1457 + - CANDY_VAGRANT: false +before_script: +- sudo apt-get update +- sudo apt-get install -y nginx +- sudo mkdir -p /usr/share/nginx/html +- sudo cp ${TRAVIS_BUILD_DIR}/devbox/nginx-default.conf /etc/nginx/sites-available/default +- sudo /etc/init.d/nginx restart +- sudo ln -fs ${TRAVIS_BUILD_DIR} /usr/share/nginx/html/candy +- sudo ln -fs ${TRAVIS_BUILD_DIR}/devbox/index.html /usr/share/nginx/html/index.html +- sudo apt-get install -y naturaldocs +- npm install -g grunt-cli bower +- npm install +- bower install +script: +- grunt ci diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md old mode 100644 new mode 100755 index 870ce22a..0679f06d --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,6 +7,8 @@ ## Learn & listen +[![Gitter chat](https://badges.gitter.im/candy-chat.png)](https://gitter.im/candy-chat) + * [Mailing list](http://groups.google.com/group/candy-chat) * yes, non-gmail users can signup as well * [FAQ](https://github.com/candy-chat/candy/wiki/Frequently-Asked-Questions) @@ -21,8 +23,7 @@ A few hopefully helpful hints to contributing to Candy #### Using vagrant 1. [Fork](https://help.github.com/articles/fork-a-repo) Candy 2. [Install Vagrant](http://vagrantup.com/) -3. Follow instructions [for Candy Vagrant](https://github.com/candy-chat/vagrant) -4. Change the remote in the `candy` and `candy-plugins` repos: `git remote set-url origin git://github.com/YOURNAME/candy` (or candy-plugins) +3. Run `vagrant up`. 5. Create a branch based on the `dev` branch (`git checkout -B my-awesome-feature`) 6. Run `grunt watch` to automatically run jshint (syntax checker) and the build of `candy.bundle.js` and `candy.min.js` while developing. 7. Make your changes, fix eventual *jshint* errors & push them back to your fork @@ -34,13 +35,22 @@ Please note that you should have a working XMPP server to test your changes (the 1. [Fork](https://help.github.com/articles/fork-a-repo) Candy 2. Clone your fork -2. Checkout out `dev` branch (`git checkout dev`) & Update git submodules `git submodule update --init` -3. Install [Node.js](http://nodejs.org/) -4. Install [Grunt](http://gruntjs.com/) (`npm install -g grunt-cli`) -5. Install npm dependencies (`npm install` in candy root directory) -6. Create a branch based on the `dev` branch (`git checkout -B my-awesome-feature`) -7. Run `grunt watch` to automatically run jshint (syntax checker) and the build of `candy.bundle.js` and `candy.min.js` while developing. -8. Make your changes, fix eventual *jshint* errors & push them back to your fork -9. Create a [pull request](https://help.github.com/articles/using-pull-requests) +3. Checkout out `dev` branch (`git checkout dev`) +4. Install [Node.js](http://nodejs.org/) +5. Install [Grunt](http://gruntjs.com/) (`npm install -g grunt-cli`) +6. Install [Bower](http://bower.io/) (`npm install -g bower`) +7. Install npm dependencies (`npm install` in candy root directory) +8. Install bower dependencies (`bower install` in candy root directory) +9. Create a branch based on the `dev` branch (`git checkout -B my-awesome-feature`) +10. Run `grunt watch` to automatically run jshint (syntax checker) and the build of `candy.bundle.js` and `candy.min.js` while developing. +11. Make your changes, fix eventual *jshint* errors & push them back to your fork +12. Create a [pull request](https://help.github.com/articles/using-pull-requests) In case you have any questions, don't hesitate to ask on the [Mailing list](http://groups.google.com/group/candy-chat). + +### Running tests + +* Tests are run using [Intern](http://theintern.io). +* `grunt` and `grunt watch` will each run unit tests in Chrome on Linux (for fast feedback). +* `grunt test` will run both unit and integration tests in a variety of environments. Tests are run using Selenium Standalone and Phantom.JS while developing, and on Sauce Labs in CI or using `grunt test`. +* If you don't want to use the Vagrant box to run Selenium/PhantomJS, set `CANDY_VAGRANT='false'` to run tests. diff --git a/Gruntfile.js b/Gruntfile.js index 1934f5ff..70057cad 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,13 +1,14 @@ 'use strict'; +var localInternConfig = process.env.CANDY_VAGRANT === 'false' ? 'tests/intern.local' : 'tests/intern.vagrant'; + module.exports = function(grunt) { // Project configuration. grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), - jshint: { - all: ['Gruntfile.js', './src/**/*.js'], + all: ['Gruntfile.js', './src/**/*.js', './tests/**/*.js'], options: { jshintrc: "./.jshintrc", reporter: require('jshint-stylish') @@ -30,8 +31,11 @@ module.exports = function(grunt) { 'src/candy.js', 'src/core.js', 'src/view.js', 'src/util.js', 'src/core/action.js', 'src/core/chatRoom.js', 'src/core/chatRoster.js', - 'src/core/chatUser.js', 'src/core/event.js', - 'src/view/observer.js', 'src/view/pane.js', + 'src/core/chatUser.js', 'src/core/contact.js', + 'src/core/event.js', 'src/view/observer.js', + 'src/view/pane/chat.js', 'src/view/pane/message.js', + 'src/view/pane/privateRoom.js', 'src/view/pane/room.js', + 'src/view/pane/roster.js', 'src/view/pane/window.js', 'src/view/template.js', 'src/view/translation.js' ] }, @@ -53,14 +57,15 @@ module.exports = function(grunt) { }, libs: { files: { - 'libs/libs.bundle.js': [ - 'libs/strophejs/strophe.js', - 'libs/strophejs-plugins/muc/strophe.muc.js', - 'libs/strophejs-plugins/disco/strophe.disco.js', - 'libs/strophejs-plugins/caps/strophe.caps.jsonly.js', - 'libs/mustache.js/mustache.js', - 'libs/jquery-i18n/jquery.i18n.js', - 'libs/dateformat/dateFormat.js' + 'libs.bundle.js': [ + 'bower_components/strophe/strophe.js', + 'bower_components/strophejs-plugins/muc/strophe.muc.js', + 'bower_components/strophejs-plugins/roster/strophe.roster.js', + 'bower_components/strophejs-plugins/disco/strophe.disco.js', + 'bower_components/strophejs-plugins/caps/strophe.caps.jsonly.js', + 'bower_components/mustache/mustache.js', + 'bower_components/jquery-i18n/jquery.i18n.js', + 'vendor_libs/dateformat/dateFormat.js' ] }, options: { @@ -73,23 +78,38 @@ module.exports = function(grunt) { }, 'libs-min': { files: { - 'libs/libs.min.js': ['libs/libs.bundle.js'] + 'libs.min.js': ['libs.bundle.js'] } } }, watch: { + clear: { + files: ['src/*.js', 'src/**/*.js', 'tests/**/*.js'], + tasks: ['clear'] + }, + grunt: { + files: ['Gruntfile.js'] + }, bundle: { - files: ['src/*.js', 'src/**/*.js'], - tasks: ['jshint', 'uglify:bundle', 'uglify:min', 'notify:bundle'] + files: ['src/**/*.js'], + tasks: ['todo:src', 'jshint', 'uglify:bundle', 'uglify:min', 'notify:bundle', 'intern:unit'] }, libs: { - files: ['libs/*/**/*.js'], + files: ['bower_components/*/**/*.js', 'vendor_libs/*/**/*.js'], tasks: ['uglify:libs', 'uglify:libs-min', 'notify:libs'] + }, + tests: { + files: ['tests/candy/unit/**/*.js'], + tasks: ['todo:tests', 'jshint', 'intern:unit'] + }, + functional_tests: { + files: ['tests/candy/functional/**/*.js'], + tasks: ['todo:tests', 'jshint', 'intern:functional'] } }, natural_docs: { all: { - bin: process.env.NATURALDOCS_DIR + '/NaturalDocs', + bin: process.env.NATURALDOCS_DIR ? process.env.NATURALDOCS_DIR + '/NaturalDocs' : 'naturaldocs', flags: ['-r'], inputs: ['./src'], output: './docs', @@ -98,7 +118,7 @@ module.exports = function(grunt) { }, clean: { bundle: ['./candy.bundle.js', './candy.bundle.map', './candy.min.js'], - libs: ['./libs/libs.bundle.js', './libs/libs.bundle.map', './libs/libs.min.js'], + libs: ['./libs.bundle.js', './libs.bundle.map', './libs.min.js'], docs: ['./docs'] }, mkdir: { @@ -129,6 +149,41 @@ module.exports = function(grunt) { message: 'JsHint & bundling done' } } + }, + intern: { + all: { + options: { + runType: 'runner', + config: 'tests/intern' + } + }, + unit: { + options: { + runType: 'runner', + config: localInternConfig, + functionalSuites: [] + } + }, + functional: { + options: { + runType: 'runner', + config: localInternConfig, + suites: [] + } + } + }, + coveralls: { + options: { + force: true // prevent from failing CI build if coveralls is down etc. + }, + all: { + src: 'lcov.info', + } + }, + todo: { + options: {}, + src: ['src/**/*.js'], + tests: ['tests/**/*.js'] } }); @@ -140,10 +195,16 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-mkdir'); grunt.loadNpmTasks('grunt-notify'); grunt.loadNpmTasks('grunt-sync-pkg'); + grunt.loadNpmTasks('intern'); + grunt.loadNpmTasks('grunt-clear'); + grunt.loadNpmTasks('grunt-coveralls'); + grunt.loadNpmTasks('grunt-todo'); + grunt.registerTask('test', ['intern:all']); + grunt.registerTask('ci', ['todo', 'jshint', 'build', 'intern:all', 'coveralls:all', 'docs']); + grunt.registerTask('build', ['uglify:libs', 'uglify:libs-min', 'uglify:bundle', 'uglify:min']); grunt.registerTask('default', [ - 'jshint', 'uglify:libs', 'uglify:libs-min', - 'uglify:bundle', 'uglify:min', 'notify:default' + 'jshint', 'build', 'notify:default', 'intern:unit' ]); grunt.registerTask('docs', ['mkdir:docs', 'natural_docs', 'notify:docs']); -}; \ No newline at end of file +}; diff --git a/README.md b/README.md index ee31a9ee..de47635d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ Candy — a JavaScript-based multi-user chat client ================================================== +[![Build Status](https://travis-ci.org/candy-chat/candy.png?branch=dev)](https://travis-ci.org/candy-chat/candy) +[![Coverage Status](https://coveralls.io/repos/candy-chat/candy/badge.png?branch=dev)](https://coveralls.io/r/candy-chat/candy) + Visit the official project page: http://candy-chat.github.io/candy Features @@ -11,7 +14,7 @@ Features - 100% well-documented JavaScript source code - Built for Jabber (XMPP), using famous technologies - Used and approved in a productive environment with up to 400 concurrent users -- Works with all major web browsers including IE7 +- Works with all major web browsers including IE9 Plugins ------- @@ -20,6 +23,6 @@ If you wish to add new functionality (to your candy installation) or contribute Support & Community ------------------- Take a look at our [FAQ](https://github.com/candy-chat/candy/wiki/Frequently-Asked-Questions). If it doesn't solve your questions, you're welcome to join our [Mailinglist on Google Groups](http://groups.google.com/group/candy-chat). -You don't need to have a Gmail account for it. +You don't need to have a Gmail account for it. [![githalytics.com alpha](https://cruel-carlota.pagodabox.com/a41a8075608abeaf99db685d7ef29cf6 "githalytics.com")](http://githalytics.com/candy-chat/candy) diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 00000000..8f277b1c --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,20 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# Vagrantfile API/syntax version. Don't touch unless you know what you're doing! +VAGRANTFILE_API_VERSION = "2" + +Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| + config.vm.box = "ubuntu/trusty64" + config.vm.network :forwarded_port, guest: 80, host: 8080 + config.vm.network :forwarded_port, guest: 5280, host: 5280 + config.vm.network :forwarded_port, guest: 4444, host: 4444 + config.vm.network :private_network, ip: '192.168.88.4' + + config.vm.provision :shell, :path => "devbox/provisioning.sh" + + config.vm.provider "virtualbox" do |v| + v.name = "candy" + v.customize ["modifyvm", :id, "--memory", 768] + end +end diff --git a/bower.json b/bower.json index 54714143..b4f50d23 100644 --- a/bower.json +++ b/bower.json @@ -29,5 +29,12 @@ "bower_components", "test", "tests" - ] -} \ No newline at end of file + ], + "dependencies": { + "jquery": "~1.10.2", + "strophe": "1.1.3", + "strophejs-plugins": "benlangfeld/strophejs-plugins#30fb089457addc37e01d69c3536dee868a90a9ad", + "mustache": "0.3.0", + "jquery-i18n": "1.1.1" + } +} diff --git a/candy.bundle.js b/candy.bundle.js deleted file mode 100644 index 713a8b5a..00000000 --- a/candy.bundle.js +++ /dev/null @@ -1,5694 +0,0 @@ -/** File: candy.js - * Candy - Chats are not dead yet. - * - * Authors: - * - Patrick Stadler - * - Michael Weibel - * - * Copyright: - * (c) 2011 Amiado Group AG. All rights reserved. - * (c) 2012-2014 Patrick Stadler & Michael Weibel. All rights reserved. - */ -"use strict"; - -/* global jQuery */ -/** Class: Candy - * Candy base class for initalizing the view and the core - * - * Parameters: - * (Candy) self - itself - * (jQuery) $ - jQuery - */ -var Candy = function(self, $) { - /** Object: about - * About candy - * - * Contains: - * (String) name - Candy - * (Float) version - Candy version - */ - self.about = { - name: "Candy", - version: "1.7.1" - }; - /** Function: init - * Init view & core - * - * Parameters: - * (String) service - URL to the BOSH interface - * (Object) options - Options for candy - * - * Options: - * (Boolean) debug - Debug (Default: false) - * (Array|Boolean) autojoin - Autojoin these channels. When boolean true, do not autojoin, wait if the server sends something. - */ - self.init = function(service, options) { - if (!options.viewClass) { - options.viewClass = self.View; - } - options.viewClass.init($("#candy"), options.view); - self.Core.init(service, options.core); - }; - return self; -}(Candy || {}, jQuery); - -/** File: core.js - * Candy - Chats are not dead yet. - * - * Authors: - * - Patrick Stadler - * - Michael Weibel - * - * Copyright: - * (c) 2011 Amiado Group AG. All rights reserved. - * (c) 2012-2014 Patrick Stadler & Michael Weibel. All rights reserved. - */ -"use strict"; - -/* global Candy, window, Strophe, jQuery */ -/** Class: Candy.Core - * Candy Chat Core - * - * Parameters: - * (Candy.Core) self - itself - * (Strophe) Strophe - Strophe JS - * (jQuery) $ - jQuery - */ -Candy.Core = function(self, Strophe, $) { - /** PrivateVariable: _connection - * Strophe connection - */ - var _connection = null, /** PrivateVariable: _service - * URL of BOSH service - */ - _service = null, /** PrivateVariable: _user - * Current user (me) - */ - _user = null, /** PrivateVariable: _rooms - * Opened rooms, containing instances of Candy.Core.ChatRooms - */ - _rooms = {}, /** PrivateVariable: _anonymousConnection - * Set in when jidOrHost doesn't contain a @-char. - */ - _anonymousConnection = false, /** PrivateVariable: _status - * Current Strophe connection state - */ - _status, /** PrivateVariable: _options - * Options: - * (Boolean) debug - Debug (Default: false) - * (Array|Boolean) autojoin - Autojoin these channels. When boolean true, do not autojoin, wait if the server sends something. - */ - _options = { - /** Boolean: autojoin - * If set to `true` try to get the bookmarks and autojoin the rooms (supported by ejabberd, Openfire). - * You may want to define an array of rooms to autojoin: `['room1@conference.host.tld', 'room2...]` (ejabberd, Openfire, ...) - */ - autojoin: undefined, - debug: false, - disableWindowUnload: false, - /** Integer: presencePriority - * Default priority for presence messages in order to receive messages across different resources - */ - presencePriority: 1, - /** String: resource - * JID resource to use when connecting to the server. - * Specify `''` (an empty string) to request a random resource. - */ - resource: Candy.about.name - }, /** PrivateFunction: _addNamespace - * Adds a namespace. - * - * Parameters: - * (String) name - namespace name (will become a constant living in Strophe.NS.*) - * (String) value - XML Namespace - */ - _addNamespace = function(name, value) { - Strophe.addNamespace(name, value); - }, /** PrivateFunction: _addNamespaces - * Adds namespaces needed by Candy. - */ - _addNamespaces = function() { - _addNamespace("PRIVATE", "jabber:iq:private"); - _addNamespace("BOOKMARKS", "storage:bookmarks"); - _addNamespace("PRIVACY", "jabber:iq:privacy"); - _addNamespace("DELAY", "jabber:x:delay"); - _addNamespace("PUBSUB", "http://jabber.org/protocol/pubsub"); - }, _getEscapedJidFromJid = function(jid) { - var node = Strophe.getNodeFromJid(jid), domain = Strophe.getDomainFromJid(jid); - return node ? Strophe.escapeNode(node) + "@" + domain : domain; - }; - /** Function: init - * Initialize Core. - * - * Parameters: - * (String) service - URL of BOSH/Websocket service - * (Object) options - Options for candy - */ - self.init = function(service, options) { - _service = service; - // Apply options - $.extend(true, _options, options); - // Enable debug logging - if (_options.debug) { - if (typeof window.console !== undefined && typeof window.console.log !== undefined) { - // Strophe has a polyfill for bind which doesn't work in IE8. - if (Function.prototype.bind && Candy.Util.getIeVersion() > 8) { - self.log = Function.prototype.bind.call(console.log, console); - } else { - self.log = function() { - Function.prototype.apply.call(console.log, console, arguments); - }; - } - } - self.log("[Init] Debugging enabled"); - } - _addNamespaces(); - // Connect to BOSH/Websocket service - _connection = new Strophe.Connection(_service); - _connection.rawInput = self.rawInput.bind(self); - _connection.rawOutput = self.rawOutput.bind(self); - // set caps node - _connection.caps.node = "https://candy-chat.github.io/candy/"; - // Window unload handler... works on all browsers but Opera. There is NO workaround. - // Opera clients getting disconnected 1-2 minutes delayed. - if (!_options.disableWindowUnload) { - window.onbeforeunload = self.onWindowUnload; - } - }; - /** Function: registerEventHandlers - * Adds listening handlers to the connection. - * - * Use with caution from outside of Candy. - */ - self.registerEventHandlers = function() { - self.addHandler(self.Event.Jabber.Version, Strophe.NS.VERSION, "iq"); - self.addHandler(self.Event.Jabber.Presence, null, "presence"); - self.addHandler(self.Event.Jabber.Message, null, "message"); - self.addHandler(self.Event.Jabber.Bookmarks, Strophe.NS.PRIVATE, "iq"); - self.addHandler(self.Event.Jabber.Room.Disco, Strophe.NS.DISCO_INFO, "iq", "result"); - self.addHandler(_connection.disco._onDiscoInfo.bind(_connection.disco), Strophe.NS.DISCO_INFO, "iq", "get"); - self.addHandler(_connection.disco._onDiscoItems.bind(_connection.disco), Strophe.NS.DISCO_ITEMS, "iq", "get"); - self.addHandler(_connection.caps._delegateCapabilities.bind(_connection.caps), Strophe.NS.CAPS); - }; - /** Function: connect - * Connect to the jabber host. - * - * There are four different procedures to login: - * connect('JID', 'password') - Connect a registered user - * connect('domain') - Connect anonymously to the domain. The user should receive a random JID. - * connect('domain', null, 'nick') - Connect anonymously to the domain. The user should receive a random JID but with a nick set. - * connect('JID') - Show login form and prompt for password. JID input is hidden. - * connect() - Show login form and prompt for JID and password. - * - * See: - * for attaching an already established session. - * - * Parameters: - * (String) jidOrHost - JID or Host - * (String) password - Password of the user - * (String) nick - Nick of the user. Set one if you want to anonymously connect but preset a nick. If jidOrHost is a domain - * and this param is not set, Candy will prompt for a nick. - */ - self.connect = function(jidOrHost, password, nick) { - // Reset before every connection attempt to make sure reconnections work after authfail, alltabsclosed, ... - _connection.reset(); - self.registerEventHandlers(); - /** Event: candy:core.before-connect - * Triggered before a connection attempt is made. - * - * Plugins should register their stanza handlers using this event - * to ensure that they are set. - * - * See also <#84 at https://github.com/candy-chat/candy/issues/84>. - * - * Parameters: - * (Strophe.Connection) conncetion - Strophe connection - */ - $(Candy).triggerHandler("candy:core.before-connect", { - connection: _connection - }); - _anonymousConnection = !_anonymousConnection ? jidOrHost && jidOrHost.indexOf("@") < 0 : true; - if (jidOrHost && password) { - // authentication - _connection.connect(_getEscapedJidFromJid(jidOrHost) + "/" + _options.resource, password, Candy.Core.Event.Strophe.Connect); - if (nick) { - _user = new self.ChatUser(jidOrHost, nick); - } else { - _user = new self.ChatUser(jidOrHost, Strophe.getNodeFromJid(jidOrHost)); - } - } else if (jidOrHost && nick) { - // anonymous connect - _connection.connect(_getEscapedJidFromJid(jidOrHost) + "/" + _options.resource, null, Candy.Core.Event.Strophe.Connect); - _user = new self.ChatUser(null, nick); - } else if (jidOrHost) { - Candy.Core.Event.Login(jidOrHost); - } else { - // display login modal - Candy.Core.Event.Login(); - } - }; - /** Function: attach - * Attach an already binded & connected session to the server - * - * _See_ Strophe.Connection.attach - * - * Parameters: - * (String) jid - Jabber ID - * (Integer) sid - Session ID - * (Integer) rid - rid - */ - self.attach = function(jid, sid, rid) { - _user = new self.ChatUser(jid, Strophe.getNodeFromJid(jid)); - self.registerEventHandlers(); - _connection.attach(jid, sid, rid, Candy.Core.Event.Strophe.Connect); - }; - /** Function: disconnect - * Leave all rooms and disconnect - */ - self.disconnect = function() { - if (_connection.connected) { - $.each(self.getRooms(), function() { - Candy.Core.Action.Jabber.Room.Leave(this.getJid()); - }); - _connection.disconnect(); - } - }; - /** Function: addHandler - * Wrapper for Strophe.Connection.addHandler() to add a stanza handler for the connection. - * - * Parameters: - * (Function) handler - The user callback. - * (String) ns - The namespace to match. - * (String) name - The stanza name to match. - * (String) type - The stanza type attribute to match. - * (String) id - The stanza id attribute to match. - * (String) from - The stanza from attribute to match. - * (String) options - The handler options - * - * Returns: - * A reference to the handler that can be used to remove it. - */ - self.addHandler = function(handler, ns, name, type, id, from, options) { - return _connection.addHandler(handler, ns, name, type, id, from, options); - }; - /** Function: getUser - * Gets current user - * - * Returns: - * Instance of Candy.Core.ChatUser - */ - self.getUser = function() { - return _user; - }; - /** Function: setUser - * Set current user. Needed when anonymous login is used, as jid gets retrieved later. - * - * Parameters: - * (Candy.Core.ChatUser) user - User instance - */ - self.setUser = function(user) { - _user = user; - }; - /** Function: getConnection - * Gets Strophe connection - * - * Returns: - * Instance of Strophe.Connection - */ - self.getConnection = function() { - return _connection; - }; - /** Function: removeRoom - * Removes a room from the rooms list - * - * Parameters: - * (String) roomJid - roomJid - */ - self.removeRoom = function(roomJid) { - delete _rooms[roomJid]; - }; - /** Function: getRooms - * Gets all joined rooms - * - * Returns: - * Object containing instances of Candy.Core.ChatRoom - */ - self.getRooms = function() { - return _rooms; - }; - /** Function: getStropheStatus - * Get the status set by Strophe. - * - * Returns: - * (Strophe.Status.*) - one of Strophe's statuses - */ - self.getStropheStatus = function() { - return _status; - }; - /** Function: setStropheStatus - * Set the strophe status - * - * Called by: - * Candy.Core.Event.Strophe.Connect - * - * Parameters: - * (Strophe.Status.*) status - Strophe's status - */ - self.setStropheStatus = function(status) { - _status = status; - }; - /** Function: isAnonymousConnection - * Returns true if was first called with a domain instead of a jid as the first param. - * - * Returns: - * (Boolean) - */ - self.isAnonymousConnection = function() { - return _anonymousConnection; - }; - /** Function: getOptions - * Gets options - * - * Returns: - * Object - */ - self.getOptions = function() { - return _options; - }; - /** Function: getRoom - * Gets a specific room - * - * Parameters: - * (String) roomJid - JID of the room - * - * Returns: - * If the room is joined, instance of Candy.Core.ChatRoom, otherwise null. - */ - self.getRoom = function(roomJid) { - if (_rooms[roomJid]) { - return _rooms[roomJid]; - } - return null; - }; - /** Function: onWindowUnload - * window.onbeforeunload event which disconnects the client from the Jabber server. - */ - self.onWindowUnload = function() { - // Enable synchronous requests because Safari doesn't send asynchronous requests within unbeforeunload events. - // Only works properly when following patch is applied to strophejs: https://github.com/metajack/strophejs/issues/16/#issuecomment-600266 - _connection.options.sync = true; - self.disconnect(); - _connection.flush(); - }; - /** Function: rawInput - * (Overridden from Strophe.Connection.rawInput) - * - * Logs all raw input if debug is set to true. - */ - self.rawInput = function(data) { - this.log("RECV: " + data); - }; - /** Function rawOutput - * (Overridden from Strophe.Connection.rawOutput) - * - * Logs all raw output if debug is set to true. - */ - self.rawOutput = function(data) { - this.log("SENT: " + data); - }; - /** Function: log - * Overridden to do something useful if debug is set to true. - * - * See: Candy.Core#init - */ - self.log = function() {}; - return self; -}(Candy.Core || {}, Strophe, jQuery); - -/** File: view.js - * Candy - Chats are not dead yet. - * - * Authors: - * - Patrick Stadler - * - Michael Weibel - * - * Copyright: - * (c) 2011 Amiado Group AG. All rights reserved. - * (c) 2012-2014 Patrick Stadler & Michael Weibel. All rights reserved. - */ -"use strict"; - -/* global jQuery, Candy, window, Mustache, document */ -/** Class: Candy.View - * The Candy View Class - * - * Parameters: - * (Candy.View) self - itself - * (jQuery) $ - jQuery - */ -Candy.View = function(self, $) { - /** PrivateObject: _current - * Object containing current container & roomJid which the client sees. - */ - var _current = { - container: null, - roomJid: null - }, /** PrivateObject: _options - * - * Options: - * (String) language - language to use - * (String) assets - path to assets (res) directory (with trailing slash) - * (Object) messages - limit: clean up message pane when n is reached / remove: remove n messages after limit has been reached - * (Object) crop - crop if longer than defined: message.nickname=15, message.body=1000, roster.nickname=15 - * (Bool) enableXHTML - [default: false] enables XHTML messages sending & displaying - */ - _options = { - language: "en", - assets: "res/", - messages: { - limit: 2e3, - remove: 500 - }, - crop: { - message: { - nickname: 15, - body: 1e3 - }, - roster: { - nickname: 15 - } - }, - enableXHTML: false - }, /** PrivateFunction: _setupTranslation - * Set dictionary using jQuery.i18n plugin. - * - * See: view/translation.js - * See: libs/jquery-i18n/jquery.i18n.js - * - * Parameters: - * (String) language - Language identifier - */ - _setupTranslation = function(language) { - $.i18n.load(self.Translation[language]); - }, /** PrivateFunction: _registerObservers - * Register observers. Candy core will now notify the View on changes. - */ - _registerObservers = function() { - $(Candy).on("candy:core.chat.connection", self.Observer.Chat.Connection); - $(Candy).on("candy:core.chat.message", self.Observer.Chat.Message); - $(Candy).on("candy:core.login", self.Observer.Login); - $(Candy).on("candy:core.autojoin-missing", self.Observer.AutojoinMissing); - $(Candy).on("candy:core.presence", self.Observer.Presence.update); - $(Candy).on("candy:core.presence.leave", self.Observer.Presence.update); - $(Candy).on("candy:core.presence.room", self.Observer.Presence.update); - $(Candy).on("candy:core.presence.error", self.Observer.PresenceError); - $(Candy).on("candy:core.message", self.Observer.Message); - }, /** PrivateFunction: _registerWindowHandlers - * Register window focus / blur / resize handlers. - * - * jQuery.focus()/.blur() <= 1.5.1 do not work for IE < 9. Fortunately onfocusin/onfocusout will work for them. - */ - _registerWindowHandlers = function() { - if (Candy.Util.getIeVersion() < 9) { - $(document).focusin(Candy.View.Pane.Window.onFocus).focusout(Candy.View.Pane.Window.onBlur); - } else { - $(window).focus(Candy.View.Pane.Window.onFocus).blur(Candy.View.Pane.Window.onBlur); - } - $(window).resize(Candy.View.Pane.Chat.fitTabs); - }, /** PrivateFunction: _initToolbar - * Initialize toolbar. - */ - _initToolbar = function() { - self.Pane.Chat.Toolbar.init(); - }, /** PrivateFunction: _delegateTooltips - * Delegate mouseenter on tooltipified element to . - */ - _delegateTooltips = function() { - $("body").delegate("li[data-tooltip]", "mouseenter", Candy.View.Pane.Chat.Tooltip.show); - }; - /** Function: init - * Initialize chat view (setup DOM, register handlers & observers) - * - * Parameters: - * (jQuery.element) container - Container element of the whole chat view - * (Object) options - Options: see _options field (value passed here gets extended by the default value in _options field) - */ - self.init = function(container, options) { - // #216 - // Rename `resources` to `assets` but prevent installations from failing - // after upgrade - if (options.resources) { - options.assets = options.resources; - } - delete options.resources; - $.extend(true, _options, options); - _setupTranslation(_options.language); - // Set path to emoticons - Candy.Util.Parser.setEmoticonPath(this.getOptions().assets + "img/emoticons/"); - // Start DOMination... - _current.container = container; - _current.container.html(Mustache.to_html(Candy.View.Template.Chat.pane, { - tooltipEmoticons: $.i18n._("tooltipEmoticons"), - tooltipSound: $.i18n._("tooltipSound"), - tooltipAutoscroll: $.i18n._("tooltipAutoscroll"), - tooltipStatusmessage: $.i18n._("tooltipStatusmessage"), - tooltipAdministration: $.i18n._("tooltipAdministration"), - tooltipUsercount: $.i18n._("tooltipUsercount"), - assetsPath: this.getOptions().assets - }, { - tabs: Candy.View.Template.Chat.tabs, - rooms: Candy.View.Template.Chat.rooms, - modal: Candy.View.Template.Chat.modal, - toolbar: Candy.View.Template.Chat.toolbar, - soundcontrol: Candy.View.Template.Chat.soundcontrol - })); - // ... and let the elements dance. - _registerWindowHandlers(); - _initToolbar(); - _registerObservers(); - _delegateTooltips(); - }; - /** Function: getCurrent - * Get current container & roomJid in an object. - * - * Returns: - * Object containing container & roomJid - */ - self.getCurrent = function() { - return _current; - }; - /** Function: getOptions - * Gets options - * - * Returns: - * Object - */ - self.getOptions = function() { - return _options; - }; - return self; -}(Candy.View || {}, jQuery); - -/** File: util.js - * Candy - Chats are not dead yet. - * - * Authors: - * - Patrick Stadler - * - Michael Weibel - * - * Copyright: - * (c) 2011 Amiado Group AG. All rights reserved. - * (c) 2012-2014 Patrick Stadler & Michael Weibel. All rights reserved. - */ -"use strict"; - -/* global Candy, MD5, Strophe, document, escape, jQuery */ -/** Class: Candy.Util - * Candy utils - * - * Parameters: - * (Candy.Util) self - itself - * (jQuery) $ - jQuery - */ -Candy.Util = function(self, $) { - /** Function: jidToId - * Translates a jid to a MD5-Id - * - * Parameters: - * (String) jid - Jid - * - * Returns: - * MD5-ified jid - */ - self.jidToId = function(jid) { - return MD5.hexdigest(jid); - }; - /** Function: escapeJid - * Escapes a jid (node & resource get escaped) - * - * See: - * XEP-0106 - * - * Parameters: - * (String) jid - Jid - * - * Returns: - * (String) - escaped jid - */ - self.escapeJid = function(jid) { - var node = Strophe.escapeNode(Strophe.getNodeFromJid(jid)), domain = Strophe.getDomainFromJid(jid), resource = Strophe.getResourceFromJid(jid); - jid = node + "@" + domain; - if (resource) { - jid += "/" + resource; - } - return jid; - }; - /** Function: unescapeJid - * Unescapes a jid (node & resource get unescaped) - * - * See: - * XEP-0106 - * - * Parameters: - * (String) jid - Jid - * - * Returns: - * (String) - unescaped Jid - */ - self.unescapeJid = function(jid) { - var node = Strophe.unescapeNode(Strophe.getNodeFromJid(jid)), domain = Strophe.getDomainFromJid(jid), resource = Strophe.getResourceFromJid(jid); - jid = node + "@" + domain; - if (resource) { - jid += "/" + resource; - } - return jid; - }; - /** Function: crop - * Crop a string with the specified length - * - * Parameters: - * (String) str - String to crop - * (Integer) len - Max length - */ - self.crop = function(str, len) { - if (str.length > len) { - str = str.substr(0, len - 3) + "..."; - } - return str; - }; - /** Function: parseAndCropXhtml - * Parses the XHTML and applies various Candy related filters to it. - * - * - Ensures it contains only valid XHTML - * - Crops text to a max length - * - Parses the text in order to display html - * - * Parameters: - * (String) str - String containing XHTML - * (Integer) len - Max text length - */ - self.parseAndCropXhtml = function(str, len) { - return $("
").append(self.createHtml($(str).get(0), len)).html(); - }; - /** Function: setCookie - * Sets a new cookie - * - * Parameters: - * (String) name - cookie name - * (String) value - Value - * (Integer) lifetime_days - Lifetime in days - */ - self.setCookie = function(name, value, lifetime_days) { - var exp = new Date(); - exp.setDate(new Date().getDate() + lifetime_days); - document.cookie = name + "=" + value + ";expires=" + exp.toUTCString() + ";path=/"; - }; - /** Function: cookieExists - * Tests if a cookie with the given name exists - * - * Parameters: - * (String) name - Cookie name - * - * Returns: - * (Boolean) - true/false - */ - self.cookieExists = function(name) { - return document.cookie.indexOf(name) > -1; - }; - /** Function: getCookie - * Returns the cookie value if there's one with this name, otherwise returns undefined - * - * Parameters: - * (String) name - Cookie name - * - * Returns: - * Cookie value or undefined - */ - self.getCookie = function(name) { - if (document.cookie) { - var regex = new RegExp(escape(name) + "=([^;]*)", "gm"), matches = regex.exec(document.cookie); - if (matches) { - return matches[1]; - } - } - }; - /** Function: deleteCookie - * Deletes a cookie with the given name - * - * Parameters: - * (String) name - cookie name - */ - self.deleteCookie = function(name) { - document.cookie = name + "=;expires=Thu, 01-Jan-70 00:00:01 GMT;path=/"; - }; - /** Function: getPosLeftAccordingToWindowBounds - * Fetches the window width and element width - * and checks if specified position + element width is bigger - * than the window width. - * - * If this evaluates to true, the position gets substracted by the element width. - * - * Parameters: - * (jQuery.Element) elem - Element to position - * (Integer) pos - Position left - * - * Returns: - * Object containing `px` (calculated position in pixel) and `alignment` (alignment of the element in relation to pos, either 'left' or 'right') - */ - self.getPosLeftAccordingToWindowBounds = function(elem, pos) { - var windowWidth = $(document).width(), elemWidth = elem.outerWidth(), marginDiff = elemWidth - elem.outerWidth(true), backgroundPositionAlignment = "left"; - if (pos + elemWidth >= windowWidth) { - pos -= elemWidth - marginDiff; - backgroundPositionAlignment = "right"; - } - return { - px: pos, - backgroundPositionAlignment: backgroundPositionAlignment - }; - }; - /** Function: getPosTopAccordingToWindowBounds - * Fetches the window height and element height - * and checks if specified position + element height is bigger - * than the window height. - * - * If this evaluates to true, the position gets substracted by the element height. - * - * Parameters: - * (jQuery.Element) elem - Element to position - * (Integer) pos - Position top - * - * Returns: - * Object containing `px` (calculated position in pixel) and `alignment` (alignment of the element in relation to pos, either 'top' or 'bottom') - */ - self.getPosTopAccordingToWindowBounds = function(elem, pos) { - var windowHeight = $(document).height(), elemHeight = elem.outerHeight(), marginDiff = elemHeight - elem.outerHeight(true), backgroundPositionAlignment = "top"; - if (pos + elemHeight >= windowHeight) { - pos -= elemHeight - marginDiff; - backgroundPositionAlignment = "bottom"; - } - return { - px: pos, - backgroundPositionAlignment: backgroundPositionAlignment - }; - }; - /** Function: localizedTime - * Localizes ISO-8610 Date with the time/dateformat specified in the translation. - * - * See: libs/dateformat/dateFormat.js - * See: src/view/translation.js - * See: jquery-i18n/jquery.i18n.js - * - * Parameters: - * (String) dateTime - ISO-8610 Datetime - * - * Returns: - * If current date is equal to the date supplied, format with timeFormat, otherwise with dateFormat - */ - self.localizedTime = function(dateTime) { - if (dateTime === undefined) { - return undefined; - } - var date = self.iso8601toDate(dateTime); - if (date.toDateString() === new Date().toDateString()) { - return date.format($.i18n._("timeFormat")); - } else { - return date.format($.i18n._("dateFormat")); - } - }; - /** Function: iso8610toDate - * Parses a ISO-8610 Date to a Date-Object. - * - * Uses a fallback if the client's browser doesn't support it. - * - * Quote: - * ECMAScript revision 5 adds native support for ISO-8601 dates in the Date.parse method, - * but many browsers currently on the market (Safari 4, Chrome 4, IE 6-8) do not support it. - * - * Credits: - * - * - * Parameters: - * (String) date - ISO-8610 Date - * - * Returns: - * Date-Object - */ - self.iso8601toDate = function(date) { - var timestamp = Date.parse(date); - if (isNaN(timestamp)) { - var struct = /^(\d{4}|[+\-]\d{6})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3,}))?)?(?:(Z)|([+\-])(\d{2})(?::?(\d{2}))?))?/.exec(date); - if (struct) { - var minutesOffset = 0; - if (struct[8] !== "Z") { - minutesOffset = +struct[10] * 60 + +struct[11]; - if (struct[9] === "+") { - minutesOffset = -minutesOffset; - } - } - minutesOffset -= new Date().getTimezoneOffset(); - return new Date(+struct[1], +struct[2] - 1, +struct[3], +struct[4], +struct[5] + minutesOffset, +struct[6], struct[7] ? +struct[7].substr(0, 3) : 0); - } else { - // XEP-0091 date - timestamp = Date.parse(date.replace(/^(\d{4})(\d{2})(\d{2})/, "$1-$2-$3") + "Z"); - } - } - return new Date(timestamp); - }; - /** Function: isEmptyObject - * IE7 doesn't work with jQuery.isEmptyObject (<=1.5.1), workaround. - * - * Parameters: - * (Object) obj - the object to test for - * - * Returns: - * Boolean true or false. - */ - self.isEmptyObject = function(obj) { - var prop; - for (prop in obj) { - if (obj.hasOwnProperty(prop)) { - return false; - } - } - return true; - }; - /** Function: forceRedraw - * Fix IE7 not redrawing under some circumstances. - * - * Parameters: - * (jQuery.element) elem - jQuery element to redraw - */ - self.forceRedraw = function(elem) { - elem.css({ - display: "none" - }); - setTimeout(function() { - this.css({ - display: "block" - }); - }.bind(elem), 1); - }; - /** PrivateVariable: ie - * Checks for IE version - * - * From: http://stackoverflow.com/a/5574871/315242 - */ - var ie = function() { - var undef, v = 3, div = document.createElement("div"), all = div.getElementsByTagName("i"); - while (// adds innerhtml and continues as long as all[0] is truthy - div.innerHTML = "", all[0]) {} - return v > 4 ? v : undef; - }(); - /** Function: getIeVersion - * Returns local variable `ie` which you can use to detect which IE version - * is available. - * - * Use e.g. like this: if(Candy.Util.getIeVersion() < 9) alert('kaboom'); - */ - self.getIeVersion = function() { - return ie; - }; - /** Class: Candy.Util.Parser - * Parser for emoticons, links and also supports escaping. - */ - self.Parser = { - /** PrivateVariable: _emoticonPath - * Path to emoticons. - * - * Use setEmoticonPath() to change it - */ - _emoticonPath: "", - /** Function: setEmoticonPath - * Set emoticons location. - * - * Parameters: - * (String) path - location of emoticons with trailing slash - */ - setEmoticonPath: function(path) { - this._emoticonPath = path; - }, - /** Array: emoticons - * Array containing emoticons to be replaced by their images. - * - * Can be overridden/extended. - */ - emoticons: [ { - plain: ":)", - regex: /((\s):-?\)|:-?\)(\s|$))/gm, - image: "Smiling.png" - }, { - plain: ";)", - regex: /((\s);-?\)|;-?\)(\s|$))/gm, - image: "Winking.png" - }, { - plain: ":D", - regex: /((\s):-?D|:-?D(\s|$))/gm, - image: "Grinning.png" - }, { - plain: ";D", - regex: /((\s);-?D|;-?D(\s|$))/gm, - image: "Grinning_Winking.png" - }, { - plain: ":(", - regex: /((\s):-?\(|:-?\((\s|$))/gm, - image: "Unhappy.png" - }, { - plain: "^^", - regex: /((\s)\^\^|\^\^(\s|$))/gm, - image: "Happy_3.png" - }, { - plain: ":P", - regex: /((\s):-?P|:-?P(\s|$))/gim, - image: "Tongue_Out.png" - }, { - plain: ";P", - regex: /((\s);-?P|;-?P(\s|$))/gim, - image: "Tongue_Out_Winking.png" - }, { - plain: ":S", - regex: /((\s):-?S|:-?S(\s|$))/gim, - image: "Confused.png" - }, { - plain: ":/", - regex: /((\s):-?\/|:-?\/(\s|$))/gm, - image: "Uncertain.png" - }, { - plain: "8)", - regex: /((\s)8-?\)|8-?\)(\s|$))/gm, - image: "Sunglasses.png" - }, { - plain: "$)", - regex: /((\s)\$-?\)|\$-?\)(\s|$))/gm, - image: "Greedy.png" - }, { - plain: "oO", - regex: /((\s)oO|oO(\s|$))/gm, - image: "Huh.png" - }, { - plain: ":x", - regex: /((\s):x|:x(\s|$))/gm, - image: "Lips_Sealed.png" - }, { - plain: ":666:", - regex: /((\s):666:|:666:(\s|$))/gm, - image: "Devil.png" - }, { - plain: "<3", - regex: /((\s)<3|<3(\s|$))/gm, - image: "Heart.png" - } ], - /** Function: emotify - * Replaces text-emoticons with their image equivalent. - * - * Parameters: - * (String) text - Text to emotify - * - * Returns: - * Emotified text - */ - emotify: function(text) { - var i; - for (i = this.emoticons.length - 1; i >= 0; i--) { - text = text.replace(this.emoticons[i].regex, '$2$1$3'); - } - return text; - }, - /** Function: linkify - * Replaces URLs with a HTML-link. - * - * Parameters: - * (String) text - Text to linkify - * - * Returns: - * Linkified text - */ - linkify: function(text) { - text = text.replace(/(^|[^\/])(www\.[^\.]+\.[\S]+(\b|$))/gi, "$1http://$2"); - return text.replace(/(\b(https?|ftp|file):\/\/[\-A-Z0-9+&@#\/%?=~_|!:,.;]*[\-A-Z0-9+&@#\/%=~_|])/gi, '$1'); - }, - /** Function: escape - * Escapes a text using a jQuery function (like htmlspecialchars in PHP) - * - * Parameters: - * (String) text - Text to escape - * - * Returns: - * Escaped text - */ - escape: function(text) { - return $("
").text(text).html(); - }, - /** Function: nl2br - * replaces newline characters with a
to make multi line messages look nice - * - * Parameters: - * (String) text - Text to process - * - * Returns: - * Processed text - */ - nl2br: function(text) { - return text.replace(/\r\n|\r|\n/g, "
"); - }, - /** Function: all - * Does everything of the parser: escaping, linkifying and emotifying. - * - * Parameters: - * (String) text - Text to parse - * - * Returns: - * (String) Parsed text - */ - all: function(text) { - if (text) { - text = this.escape(text); - text = this.linkify(text); - text = this.emotify(text); - text = this.nl2br(text); - } - return text; - } - }; - /** Function: createHtml - * Copy an HTML DOM element into an XML DOM. - * - * This function copies a DOM element and all its descendants and returns - * the new copy. - * - * It's a function copied & adapted from [Strophe.js core.js](https://github.com/strophe/strophejs/blob/master/src/core.js). - * - * Parameters: - * (HTMLElement) elem - A DOM element. - * (Integer) maxLength - Max length of text - * (Integer) currentLength - Current accumulated text length - * - * Returns: - * A new, copied DOM element tree. - */ - self.createHtml = function(elem, maxLength, currentLength) { - /* jshint -W073 */ - currentLength = currentLength || 0; - var i, el, j, tag, attribute, value, css, cssAttrs, attr, cssName, cssValue; - if (elem.nodeType === Strophe.ElementType.NORMAL) { - tag = elem.nodeName.toLowerCase(); - if (Strophe.XHTML.validTag(tag)) { - try { - el = $("<" + tag + "/>"); - for (i = 0; i < Strophe.XHTML.attributes[tag].length; i++) { - attribute = Strophe.XHTML.attributes[tag][i]; - value = elem.getAttribute(attribute); - if (typeof value === "undefined" || value === null || value === "" || value === false || value === 0) { - continue; - } - if (attribute === "style" && typeof value === "object") { - if (typeof value.cssText !== "undefined") { - value = value.cssText; - } - } - // filter out invalid css styles - if (attribute === "style") { - css = []; - cssAttrs = value.split(";"); - for (j = 0; j < cssAttrs.length; j++) { - attr = cssAttrs[j].split(":"); - cssName = attr[0].replace(/^\s*/, "").replace(/\s*$/, "").toLowerCase(); - if (Strophe.XHTML.validCSS(cssName)) { - cssValue = attr[1].replace(/^\s*/, "").replace(/\s*$/, ""); - css.push(cssName + ": " + cssValue); - } - } - if (css.length > 0) { - value = css.join("; "); - el.attr(attribute, value); - } - } else { - el.attr(attribute, value); - } - } - for (i = 0; i < elem.childNodes.length; i++) { - el.append(self.createHtml(elem.childNodes[i], maxLength, currentLength)); - } - } catch (e) { - // invalid elements - Candy.Core.log("[Util:createHtml] Error while parsing XHTML:"); - Candy.Core.log(e); - el = Strophe.xmlTextNode(""); - } - } else { - el = Strophe.xmlGenerator().createDocumentFragment(); - for (i = 0; i < elem.childNodes.length; i++) { - el.appendChild(self.createHtml(elem.childNodes[i], maxLength, currentLength)); - } - } - } else if (elem.nodeType === Strophe.ElementType.FRAGMENT) { - el = Strophe.xmlGenerator().createDocumentFragment(); - for (i = 0; i < elem.childNodes.length; i++) { - el.appendChild(self.createHtml(elem.childNodes[i], maxLength, currentLength)); - } - } else if (elem.nodeType === Strophe.ElementType.TEXT) { - var text = elem.nodeValue; - currentLength += text.length; - if (maxLength && currentLength > maxLength) { - text = text.substring(0, maxLength); - } - text = Candy.Util.Parser.all(text); - el = $.parseHTML(text); - } - return el; - }; - return self; -}(Candy.Util || {}, jQuery); - -/** File: action.js - * Candy - Chats are not dead yet. - * - * Authors: - * - Patrick Stadler - * - Michael Weibel - * - * Copyright: - * (c) 2011 Amiado Group AG. All rights reserved. - * (c) 2012-2014 Patrick Stadler & Michael Weibel. All rights reserved. - */ -"use strict"; - -/* global Candy, $iq, navigator, Candy, $pres, Strophe, jQuery, $msg */ -/** Class: Candy.Core.Action - * Chat Actions (basicly a abstraction of Jabber commands) - * - * Parameters: - * (Candy.Core.Action) self - itself - * (Strophe) Strophe - Strophe - * (jQuery) $ - jQuery - */ -Candy.Core.Action = function(self, Strophe, $) { - /** Class: Candy.Core.Action.Jabber - * Jabber actions - */ - self.Jabber = { - /** Function: Version - * Replies to a version request - * - * Parameters: - * (jQuery.element) msg - jQuery element - */ - Version: function(msg) { - Candy.Core.getConnection().sendIQ($iq({ - type: "result", - to: Candy.Util.escapeJid(msg.attr("from")), - from: Candy.Util.escapeJid(msg.attr("to")), - id: msg.attr("id") - }).c("query", { - name: Candy.about.name, - version: Candy.about.version, - os: navigator.userAgent - })); - }, - /** Function: SetNickname - * Sets the supplied nickname for all rooms (if parameter "room" is not specified) or - * sets it only for the specified rooms - * - * Parameters: - * (String) nickname - New nickname - * (Array) rooms - Rooms - */ - SetNickname: function(nickname, rooms) { - rooms = rooms instanceof Array ? rooms : Candy.Core.getRooms(); - var roomNick, presence, conn = Candy.Core.getConnection(); - $.each(rooms, function(roomJid) { - roomNick = Candy.Util.escapeJid(roomJid + "/" + nickname); - presence = $pres({ - to: roomNick, - from: conn.jid, - id: "pres:" + conn.getUniqueId() - }); - Candy.Core.getConnection().send(presence); - }); - }, - /** Function: Roster - * Sends a request for a roster - */ - Roster: function() { - Candy.Core.getConnection().sendIQ($iq({ - type: "get", - xmlns: Strophe.NS.CLIENT - }).c("query", { - xmlns: Strophe.NS.ROSTER - }).tree()); - }, - /** Function: Presence - * Sends a request for presence - * - * Parameters: - * (Object) attr - Optional attributes - * (Strophe.Builder) el - Optional element to include in presence stanza - */ - Presence: function(attr, el) { - var conn = Candy.Core.getConnection(); - attr = attr || {}; - if (!attr.id) { - attr.id = "pres:" + conn.getUniqueId(); - } - var pres = $pres(attr).c("priority").t(Candy.Core.getOptions().presencePriority.toString()).up().c("c", conn.caps.generateCapsAttrs()).up(); - if (el) { - pres.node.appendChild(el.node); - } - conn.send(pres.tree()); - }, - /** Function: Services - * Sends a request for disco items - */ - Services: function() { - Candy.Core.getConnection().sendIQ($iq({ - type: "get", - xmlns: Strophe.NS.CLIENT - }).c("query", { - xmlns: Strophe.NS.DISCO_ITEMS - }).tree()); - }, - /** Function: Autojoin - * When Candy.Core.getOptions().autojoin is true, request autojoin bookmarks (OpenFire) - * - * Otherwise, if Candy.Core.getOptions().autojoin is an array, join each channel specified. - * Channel can be in jid:password format to pass room password if needed. - - * Triggers: - * candy:core.autojoin-missing in case no autojoin info has been found - */ - Autojoin: function() { - // Request bookmarks - if (Candy.Core.getOptions().autojoin === true) { - Candy.Core.getConnection().sendIQ($iq({ - type: "get", - xmlns: Strophe.NS.CLIENT - }).c("query", { - xmlns: Strophe.NS.PRIVATE - }).c("storage", { - xmlns: Strophe.NS.BOOKMARKS - }).tree()); - var pubsubBookmarkRequest = Candy.Core.getConnection().getUniqueId("pubsub"); - Candy.Core.addHandler(Candy.Core.Event.Jabber.Bookmarks, Strophe.NS.PUBSUB, "iq", "result", pubsubBookmarkRequest); - Candy.Core.getConnection().sendIQ($iq({ - type: "get", - id: pubsubBookmarkRequest - }).c("pubsub", { - xmlns: Strophe.NS.PUBSUB - }).c("items", { - node: Strophe.NS.BOOKMARKS - }).tree()); - } else if ($.isArray(Candy.Core.getOptions().autojoin)) { - $.each(Candy.Core.getOptions().autojoin, function() { - self.Jabber.Room.Join.apply(null, this.valueOf().split(":", 2)); - }); - } else { - /** Event: candy:core.autojoin-missing - * Triggered when no autojoin information has been found - */ - $(Candy).triggerHandler("candy:core.autojoin-missing"); - } - }, - /** Function: ResetIgnoreList - * Create new ignore privacy list (and reset the previous one, if it exists). - */ - ResetIgnoreList: function() { - Candy.Core.getConnection().sendIQ($iq({ - type: "set", - from: Candy.Core.getUser().getEscapedJid() - }).c("query", { - xmlns: Strophe.NS.PRIVACY - }).c("list", { - name: "ignore" - }).c("item", { - action: "allow", - order: "0" - }).tree()); - }, - /** Function: RemoveIgnoreList - * Remove an existing ignore list. - */ - RemoveIgnoreList: function() { - Candy.Core.getConnection().sendIQ($iq({ - type: "set", - from: Candy.Core.getUser().getEscapedJid() - }).c("query", { - xmlns: Strophe.NS.PRIVACY - }).c("list", { - name: "ignore" - }).tree()); - }, - /** Function: GetIgnoreList - * Get existing ignore privacy list when connecting. - */ - GetIgnoreList: function() { - var iq = $iq({ - type: "get", - from: Candy.Core.getUser().getEscapedJid() - }).c("query", { - xmlns: Strophe.NS.PRIVACY - }).c("list", { - name: "ignore" - }).tree(); - var iqId = Candy.Core.getConnection().sendIQ(iq); - // add handler (<#200 at https://github.com/candy-chat/candy/issues/200>) - Candy.Core.addHandler(Candy.Core.Event.Jabber.PrivacyList, null, "iq", null, iqId); - }, - /** Function: SetIgnoreListActive - * Set ignore privacy list active - */ - SetIgnoreListActive: function() { - Candy.Core.getConnection().sendIQ($iq({ - type: "set", - from: Candy.Core.getUser().getEscapedJid() - }).c("query", { - xmlns: Strophe.NS.PRIVACY - }).c("active", { - name: "ignore" - }).tree()); - }, - /** Function: GetJidIfAnonymous - * On anonymous login, initially we don't know the jid and as a result, Candy.Core._user doesn't have a jid. - * Check if user doesn't have a jid and get it if necessary from the connection. - */ - GetJidIfAnonymous: function() { - if (!Candy.Core.getUser().getJid()) { - Candy.Core.log("[Jabber] Anonymous login"); - Candy.Core.getUser().data.jid = Candy.Core.getConnection().jid; - } - }, - /** Class: Candy.Core.Action.Jabber.Room - * Room-specific commands - */ - Room: { - /** Function: Join - * Requests disco of specified room and joins afterwards. - * - * TODO: - * maybe we should wait for disco and later join the room? - * but what if we send disco but don't want/can join the room - * - * Parameters: - * (String) roomJid - Room to join - * (String) password - [optional] Password for the room - */ - Join: function(roomJid, password) { - self.Jabber.Room.Disco(roomJid); - roomJid = Candy.Util.escapeJid(roomJid); - var conn = Candy.Core.getConnection(), roomNick = roomJid + "/" + Candy.Core.getUser().getNick(), pres = $pres({ - to: roomNick, - id: "pres:" + conn.getUniqueId() - }).c("x", { - xmlns: Strophe.NS.MUC - }); - if (password) { - pres.c("password").t(password); - } - pres.up().c("c", conn.caps.generateCapsAttrs()); - conn.send(pres.tree()); - }, - /** Function: Leave - * Leaves a room. - * - * Parameters: - * (String) roomJid - Room to leave - */ - Leave: function(roomJid) { - var user = Candy.Core.getRoom(roomJid).getUser(); - roomJid = Candy.Util.escapeJid(roomJid); - if (user) { - Candy.Core.getConnection().muc.leave(roomJid, user.getNick(), function() {}); - } - }, - /** Function: Disco - * Requests . - * - * Parameters: - * (String) roomJid - Room to get info for - */ - Disco: function(roomJid) { - Candy.Core.getConnection().sendIQ($iq({ - type: "get", - from: Candy.Core.getUser().getEscapedJid(), - to: Candy.Util.escapeJid(roomJid) - }).c("query", { - xmlns: Strophe.NS.DISCO_INFO - }).tree()); - }, - /** Function: Message - * Send message - * - * Parameters: - * (String) roomJid - Room to which send the message into - * (String) msg - Message - * (String) type - "groupchat" or "chat" ("chat" is for private messages) - * (String) xhtmlMsg - XHTML formatted message [optional] - * - * Returns: - * (Boolean) - true if message is not empty after trimming, false otherwise. - */ - Message: function(roomJid, msg, type, xhtmlMsg) { - // Trim message - msg = $.trim(msg); - if (msg === "") { - return false; - } - var nick = null; - if (type === "chat") { - nick = Strophe.getResourceFromJid(roomJid); - roomJid = Strophe.getBareJidFromJid(roomJid); - } - // muc takes care of the escaping now. - Candy.Core.getConnection().muc.message(roomJid, nick, msg, xhtmlMsg, type); - return true; - }, - /** Function: Invite - * Sends an invite stanza to multiple JIDs - * - * Parameters: - * (String) roomJid - Room to which send the message into - * (Array) invitees - Array of JIDs to be invited to the room - * (String) reason - Message to include with the invitation [optional] - * (String) password - Password for the MUC, if required [optional] - */ - Invite: function(roomJid, invitees, reason, password) { - reason = $.trim(reason); - var message = $msg({ - to: roomJid - }); - var x = message.c("x", { - xmlns: Strophe.NS.MUC_USER - }); - $.each(invitees, function(i, invitee) { - invitee = Strophe.getBareJidFromJid(invitee); - x.c("invite", { - to: invitee - }); - if (typeof reason !== "undefined" && reason !== "") { - x.c("reason", reason); - } - }); - if (typeof password !== "undefined" && password !== "") { - x.c("password", password); - } - Candy.Core.getConnection().send(message); - }, - /** Function: IgnoreUnignore - * Checks if the user is already ignoring the target user, if yes: unignore him, if no: ignore him. - * - * Uses the ignore privacy list set on connecting. - * - * Parameters: - * (String) userJid - Target user jid - */ - IgnoreUnignore: function(userJid) { - Candy.Core.getUser().addToOrRemoveFromPrivacyList("ignore", userJid); - Candy.Core.Action.Jabber.Room.UpdatePrivacyList(); - }, - /** Function: UpdatePrivacyList - * Updates privacy list according to the privacylist in the currentUser - */ - UpdatePrivacyList: function() { - var currentUser = Candy.Core.getUser(), iq = $iq({ - type: "set", - from: currentUser.getEscapedJid() - }).c("query", { - xmlns: "jabber:iq:privacy" - }).c("list", { - name: "ignore" - }), privacyList = currentUser.getPrivacyList("ignore"); - if (privacyList.length > 0) { - $.each(privacyList, function(index, jid) { - iq.c("item", { - type: "jid", - value: Candy.Util.escapeJid(jid), - action: "deny", - order: index - }).c("message").up().up(); - }); - } else { - iq.c("item", { - action: "allow", - order: "0" - }); - } - Candy.Core.getConnection().sendIQ(iq.tree()); - }, - /** Class: Candy.Core.Action.Jabber.Room.Admin - * Room administration commands - */ - Admin: { - /** Function: UserAction - * Kick or ban a user - * - * Parameters: - * (String) roomJid - Room in which the kick/ban should be done - * (String) userJid - Victim - * (String) type - "kick" or "ban" - * (String) msg - Reason - * - * Returns: - * (Boolean) - true if sent successfully, false if type is not one of "kick" or "ban". - */ - UserAction: function(roomJid, userJid, type, reason) { - roomJid = Candy.Util.escapeJid(roomJid); - userJid = Candy.Util.escapeJid(userJid); - var itemObj = { - nick: Strophe.getResourceFromJid(userJid) - }; - switch (type) { - case "kick": - itemObj.role = "none"; - break; - - case "ban": - itemObj.affiliation = "outcast"; - break; - - default: - return false; - } - Candy.Core.getConnection().sendIQ($iq({ - type: "set", - from: Candy.Core.getUser().getEscapedJid(), - to: roomJid - }).c("query", { - xmlns: Strophe.NS.MUC_ADMIN - }).c("item", itemObj).c("reason").t(reason).tree()); - return true; - }, - /** Function: SetSubject - * Sets subject (topic) of a room. - * - * Parameters: - * (String) roomJid - Room - * (String) subject - Subject to set - */ - SetSubject: function(roomJid, subject) { - Candy.Core.getConnection().muc.setTopic(Candy.Util.escapeJid(roomJid), subject); - } - } - } - }; - return self; -}(Candy.Core.Action || {}, Strophe, jQuery); - -/** File: chatRoom.js - * Candy - Chats are not dead yet. - * - * Authors: - * - Patrick Stadler - * - Michael Weibel - * - * Copyright: - * (c) 2011 Amiado Group AG. All rights reserved. - * (c) 2012-2014 Patrick Stadler & Michael Weibel. All rights reserved. - */ -"use strict"; - -/* global Candy, Strophe */ -/** Class: Candy.Core.ChatRoom - * Candy Chat Room - * - * Parameters: - * (String) roomJid - Room jid - */ -Candy.Core.ChatRoom = function(roomJid) { - /** Object: room - * Object containing roomJid and name. - */ - this.room = { - jid: roomJid, - name: Strophe.getNodeFromJid(roomJid) - }; - /** Variable: user - * Current local user of this room. - */ - this.user = null; - /** Variable: Roster - * Candy.Core.ChatRoster instance - */ - this.roster = new Candy.Core.ChatRoster(); - /** Function: setUser - * Set user of this room. - * - * Parameters: - * (Candy.Core.ChatUser) user - Chat user - */ - this.setUser = function(user) { - this.user = user; - }; - /** Function: getUser - * Get current local user - * - * Returns: - * (Object) - Candy.Core.ChatUser instance or null - */ - this.getUser = function() { - return this.user; - }; - /** Function: getJid - * Get room jid - * - * Returns: - * (String) - Room jid - */ - this.getJid = function() { - return this.room.jid; - }; - /** Function: setName - * Set room name - * - * Parameters: - * (String) name - Room name - */ - this.setName = function(name) { - this.room.name = name; - }; - /** Function: getName - * Get room name - * - * Returns: - * (String) - Room name - */ - this.getName = function() { - return this.room.name; - }; - /** Function: setRoster - * Set roster of room - * - * Parameters: - * (Candy.Core.ChatRoster) roster - Chat roster - */ - this.setRoster = function(roster) { - this.roster = roster; - }; - /** Function: getRoster - * Get roster - * - * Returns - * (Candy.Core.ChatRoster) - instance - */ - this.getRoster = function() { - return this.roster; - }; -}; - -/** File: chatRoster.js - * Candy - Chats are not dead yet. - * - * Authors: - * - Patrick Stadler - * - Michael Weibel - * - * Copyright: - * (c) 2011 Amiado Group AG. All rights reserved. - * (c) 2012-2014 Patrick Stadler & Michael Weibel. All rights reserved. - */ -"use strict"; - -/* global Candy */ -/** Class: Candy.Core.ChatRoster - * Chat Roster - */ -Candy.Core.ChatRoster = function() { - /** Object: items - * Roster items - */ - this.items = {}; - /** Function: add - * Add user to roster - * - * Parameters: - * (Candy.Core.ChatUser) user - User to add - */ - this.add = function(user) { - this.items[user.getJid()] = user; - }; - /** Function: remove - * Remove user from roster - * - * Parameters: - * (String) jid - User jid - */ - this.remove = function(jid) { - delete this.items[jid]; - }; - /** Function: get - * Get user from roster - * - * Parameters: - * (String) jid - User jid - * - * Returns: - * (Candy.Core.ChatUser) - User - */ - this.get = function(jid) { - return this.items[jid]; - }; - /** Function: getAll - * Get all items - * - * Returns: - * (Object) - all roster items - */ - this.getAll = function() { - return this.items; - }; -}; - -/** File: chatUser.js - * Candy - Chats are not dead yet. - * - * Authors: - * - Patrick Stadler - * - Michael Weibel - * - * Copyright: - * (c) 2011 Amiado Group AG. All rights reserved. - * (c) 2012-2014 Patrick Stadler & Michael Weibel. All rights reserved. - */ -"use strict"; - -/* global Candy, Strophe */ -/** Class: Candy.Core.ChatUser - * Chat User - */ -Candy.Core.ChatUser = function(jid, nick, affiliation, role) { - /** Constant: ROLE_MODERATOR - * Moderator role - */ - this.ROLE_MODERATOR = "moderator"; - /** Constant: AFFILIATION_OWNER - * Affiliation owner - */ - this.AFFILIATION_OWNER = "owner"; - /** Object: data - * User data containing: - * - jid - * - nick - * - affiliation - * - role - * - privacyLists - * - customData to be used by e.g. plugins - */ - this.data = { - jid: jid, - nick: Strophe.unescapeNode(nick), - affiliation: affiliation, - role: role, - privacyLists: {}, - customData: {}, - previousNick: undefined - }; - /** Function: getJid - * Gets an unescaped user jid - * - * See: - * - * - * Returns: - * (String) - jid - */ - this.getJid = function() { - if (this.data.jid) { - return Candy.Util.unescapeJid(this.data.jid); - } - return; - }; - /** Function: getEscapedJid - * Escapes the user's jid (node & resource get escaped) - * - * See: - * - * - * Returns: - * (String) - escaped jid - */ - this.getEscapedJid = function() { - return Candy.Util.escapeJid(this.data.jid); - }; - /** Function: setJid - * Sets a user's jid - * - * Parameters: - * (String) jid - New Jid - */ - this.setJid = function(jid) { - this.data.jid = jid; - }; - /** Function: getNick - * Gets user nick - * - * Returns: - * (String) - nick - */ - this.getNick = function() { - return Strophe.unescapeNode(this.data.nick); - }; - /** Function: setNick - * Sets a user's nick - * - * Parameters: - * (String) nick - New nick - */ - this.setNick = function(nick) { - this.data.nick = nick; - }; - /** Function: getRole - * Gets user role - * - * Returns: - * (String) - role - */ - this.getRole = function() { - return this.data.role; - }; - /** Function: setRole - * Sets user role - * - * Parameters: - * (String) role - Role - */ - this.setRole = function(role) { - this.data.role = role; - }; - /** Function: setAffiliation - * Sets user affiliation - * - * Parameters: - * (String) affiliation - new affiliation - */ - this.setAffiliation = function(affiliation) { - this.data.affiliation = affiliation; - }; - /** Function: getAffiliation - * Gets user affiliation - * - * Returns: - * (String) - affiliation - */ - this.getAffiliation = function() { - return this.data.affiliation; - }; - /** Function: isModerator - * Check if user is moderator. Depends on the room. - * - * Returns: - * (Boolean) - true if user has role moderator or affiliation owner - */ - this.isModerator = function() { - return this.getRole() === this.ROLE_MODERATOR || this.getAffiliation() === this.AFFILIATION_OWNER; - }; - /** Function: addToOrRemoveFromPrivacyList - * Convenience function for adding/removing users from ignore list. - * - * Check if user is already in privacy list. If yes, remove it. If no, add it. - * - * Parameters: - * (String) list - To which privacy list the user should be added / removed from. Candy supports curently only the "ignore" list. - * (String) jid - User jid to add/remove - * - * Returns: - * (Array) - Current privacy list. - */ - this.addToOrRemoveFromPrivacyList = function(list, jid) { - if (!this.data.privacyLists[list]) { - this.data.privacyLists[list] = []; - } - var index = -1; - if ((index = this.data.privacyLists[list].indexOf(jid)) !== -1) { - this.data.privacyLists[list].splice(index, 1); - } else { - this.data.privacyLists[list].push(jid); - } - return this.data.privacyLists[list]; - }; - /** Function: getPrivacyList - * Returns the privacy list of the listname of the param. - * - * Parameters: - * (String) list - To which privacy list the user should be added / removed from. Candy supports curently only the "ignore" list. - * - * Returns: - * (Array) - Privacy List - */ - this.getPrivacyList = function(list) { - if (!this.data.privacyLists[list]) { - this.data.privacyLists[list] = []; - } - return this.data.privacyLists[list]; - }; - /** Function: setPrivacyLists - * Sets privacy lists. - * - * Parameters: - * (Object) lists - List object - */ - this.setPrivacyLists = function(lists) { - this.data.privacyLists = lists; - }; - /** Function: isInPrivacyList - * Tests if this user ignores the user provided by jid. - * - * Parameters: - * (String) list - Privacy list - * (String) jid - Jid to test for - * - * Returns: - * (Boolean) - */ - this.isInPrivacyList = function(list, jid) { - if (!this.data.privacyLists[list]) { - return false; - } - return this.data.privacyLists[list].indexOf(jid) !== -1; - }; - /** Function: setCustomData - * Stores custom data - * - * Parameter: - * (Object) data - Object containing custom data - */ - this.setCustomData = function(data) { - this.data.customData = data; - }; - /** Function: getCustomData - * Retrieve custom data - * - * Returns: - * (Object) - Object containing custom data - */ - this.getCustomData = function() { - return this.data.customData; - }; - /** Function: setPreviousNick - * If user has nickname changed, set previous nickname. - * - * Parameters: - * (String) previousNick - the previous nickname - */ - this.setPreviousNick = function(previousNick) { - this.data.previousNick = previousNick; - }; - /** Function: hasNicknameChanged - * Gets the previous nickname if available. - * - * Returns: - * (String) - previous nickname - */ - this.getPreviousNick = function() { - return this.data.previousNick; - }; -}; - -/** File: event.js - * Candy - Chats are not dead yet. - * - * Authors: - * - Patrick Stadler - * - Michael Weibel - * - * Copyright: - * (c) 2011 Amiado Group AG. All rights reserved. - * (c) 2012-2014 Patrick Stadler & Michael Weibel. All rights reserved. - */ -"use strict"; - -/* global Candy, Strophe, jQuery */ -/** Class: Candy.Core.Event - * Chat Events - * - * Parameters: - * (Candy.Core.Event) self - itself - * (Strophe) Strophe - Strophe - * (jQuery) $ - jQuery - */ -Candy.Core.Event = function(self, Strophe, $) { - /** Function: Login - * Notify view that the login window should be displayed - * - * Parameters: - * (String) presetJid - Preset user JID - * - * Triggers: - * candy:core.login using {presetJid} - */ - self.Login = function(presetJid) { - /** Event: candy:core.login - * Triggered when the login window should be displayed - * - * Parameters: - * (String) presetJid - Preset user JID - */ - $(Candy).triggerHandler("candy:core.login", { - presetJid: presetJid - }); - }; - /** Class: Candy.Core.Event.Strophe - * Strophe-related events - */ - self.Strophe = { - /** Function: Connect - * Acts on strophe status events and notifies view. - * - * Parameters: - * (Strophe.Status) status - Strophe statuses - * - * Triggers: - * candy:core.chat.connection using {status} - */ - Connect: function(status) { - Candy.Core.setStropheStatus(status); - switch (status) { - case Strophe.Status.CONNECTED: - Candy.Core.log("[Connection] Connected"); - Candy.Core.Action.Jabber.GetJidIfAnonymous(); - - /* falls through */ - case Strophe.Status.ATTACHED: - Candy.Core.log("[Connection] Attached"); - Candy.Core.Action.Jabber.Presence(); - Candy.Core.Action.Jabber.Autojoin(); - Candy.Core.Action.Jabber.GetIgnoreList(); - break; - - case Strophe.Status.DISCONNECTED: - Candy.Core.log("[Connection] Disconnected"); - break; - - case Strophe.Status.AUTHFAIL: - Candy.Core.log("[Connection] Authentication failed"); - break; - - case Strophe.Status.CONNECTING: - Candy.Core.log("[Connection] Connecting"); - break; - - case Strophe.Status.DISCONNECTING: - Candy.Core.log("[Connection] Disconnecting"); - break; - - case Strophe.Status.AUTHENTICATING: - Candy.Core.log("[Connection] Authenticating"); - break; - - case Strophe.Status.ERROR: - case Strophe.Status.CONNFAIL: - Candy.Core.log("[Connection] Failed (" + status + ")"); - break; - - default: - Candy.Core.log("[Connection] What?!"); - break; - } - /** Event: candy:core.chat.connection - * Connection status updates - * - * Parameters: - * (Strophe.Status) status - Strophe status - */ - $(Candy).triggerHandler("candy:core.chat.connection", { - status: status - }); - } - }; - /** Class: Candy.Core.Event.Jabber - * Jabber related events - */ - self.Jabber = { - /** Function: Version - * Responds to a version request - * - * Parameters: - * (String) msg - Raw XML Message - * - * Returns: - * (Boolean) - true - */ - Version: function(msg) { - Candy.Core.log("[Jabber] Version"); - Candy.Core.Action.Jabber.Version($(msg)); - return true; - }, - /** Function: Presence - * Acts on a presence event - * - * Parameters: - * (String) msg - Raw XML Message - * - * Triggers: - * candy:core.presence using {from, stanza} - * - * Returns: - * (Boolean) - true - */ - Presence: function(msg) { - Candy.Core.log("[Jabber] Presence"); - msg = $(msg); - if (msg.children('x[xmlns^="' + Strophe.NS.MUC + '"]').length > 0) { - if (msg.attr("type") === "error") { - self.Jabber.Room.PresenceError(msg); - } else { - self.Jabber.Room.Presence(msg); - } - } else { - /** Event: candy:core.presence - * Presence updates. Emitted only when not a muc presence. - * - * Parameters: - * (JID) from - From Jid - * (String) stanza - Stanza - */ - $(Candy).triggerHandler("candy:core.presence", { - from: msg.attr("from"), - stanza: msg - }); - } - return true; - }, - /** Function: Bookmarks - * Acts on a bookmarks event. When a bookmark has the attribute autojoin set, joins this room. - * - * Parameters: - * (String) msg - Raw XML Message - * - * Returns: - * (Boolean) - true - */ - Bookmarks: function(msg) { - Candy.Core.log("[Jabber] Bookmarks"); - // Autojoin bookmarks - $("conference", msg).each(function() { - var item = $(this); - if (item.attr("autojoin")) { - Candy.Core.Action.Jabber.Room.Join(item.attr("jid")); - } - }); - return true; - }, - /** Function: PrivacyList - * Acts on a privacy list event and sets up the current privacy list of this user. - * - * If no privacy list has been added yet, create the privacy list and listen again to this event. - * - * Parameters: - * (String) msg - Raw XML Message - * - * Returns: - * (Boolean) - false to disable the handler after first call. - */ - PrivacyList: function(msg) { - Candy.Core.log("[Jabber] PrivacyList"); - var currentUser = Candy.Core.getUser(); - msg = $(msg); - if (msg.attr("type") === "result") { - $('list[name="ignore"] item', msg).each(function() { - var item = $(this); - if (item.attr("action") === "deny") { - currentUser.addToOrRemoveFromPrivacyList("ignore", item.attr("value")); - } - }); - Candy.Core.Action.Jabber.SetIgnoreListActive(); - return false; - } - return self.Jabber.PrivacyListError(msg); - }, - /** Function: PrivacyListError - * Acts when a privacy list error has been received. - * - * Currently only handles the case, when a privacy list doesn't exist yet and creates one. - * - * Parameters: - * (String) msg - Raw XML Message - * - * Returns: - * (Boolean) - false to disable the handler after first call. - */ - PrivacyListError: function(msg) { - Candy.Core.log("[Jabber] PrivacyListError"); - // check if msg says that privacyList doesn't exist - if ($('error[code="404"][type="cancel"] item-not-found', msg)) { - Candy.Core.Action.Jabber.ResetIgnoreList(); - Candy.Core.Action.Jabber.SetIgnoreListActive(); - } - return false; - }, - /** Function: Message - * Acts on room, admin and server messages and notifies the view if required. - * - * Parameters: - * (String) msg - Raw XML Message - * - * Triggers: - * candy:core.chat.message.admin using {type, message} - * candy:core.chat.message.server {type, subject, message} - * - * Returns: - * (Boolean) - true - */ - Message: function(msg) { - Candy.Core.log("[Jabber] Message"); - msg = $(msg); - var fromJid = msg.attr("from"), type = msg.attr("type") || "undefined", toJid = msg.attr("to"); - // Inspect the message type. - if (type === "normal" || type === "undefined") { - var mediatedInvite = msg.find("invite"), directInvite = msg.find('x[xmlns="jabber:x:conference"]'); - if (mediatedInvite.length > 0) { - var passwordNode = msg.find("password"), password = null, continueNode = mediatedInvite.find("continue"), continuedThread = null; - if (passwordNode) { - password = passwordNode.text(); - } - if (continueNode) { - continuedThread = continueNode.attr("thread"); - } - /** Event: candy:core:chat:invite - * Incoming chat invite for a MUC. - * - * Parameters: - * (String) roomJid - The room the invite is to - * (String) from - User JID that invite is from text - * (String) reason - Reason for invite [default: ''] - * (String) password - Password for the room [default: null] - * (String) continuedThread - The thread ID if this is a continuation of a 1-on-1 chat [default: null] - */ - $(Candy).triggerHandler("candy:core:chat:invite", { - roomJid: fromJid, - from: mediatedInvite.attr("from") || "undefined", - reason: mediatedInvite.find("reason").html() || "", - password: password, - continuedThread: continuedThread - }); - } - if (directInvite.length > 0) { - /** Event: candy:core:chat:invite - * Incoming chat invite for a MUC. - * - * Parameters: - * (String) roomJid - The room the invite is to - * (String) from - User JID that invite is from text - * (String) reason - Reason for invite [default: ''] - * (String) password - Password for the room [default: null] - * (String) continuedThread - The thread ID if this is a continuation of a 1-on-1 chat [default: null] - */ - $(Candy).triggerHandler("candy:core:chat:invite", { - roomJid: directInvite.attr("jid"), - from: fromJid, - reason: directInvite.attr("reason") || "", - password: directInvite.attr("password"), - continuedThread: directInvite.attr("thread") - }); - } - /** Event: candy:core:chat:message:normal - * Messages with the type attribute of normal or those - * that do not have the optional type attribute. - * - * Parameters: - * (String) type - Type of the message [default: message] - * (Object) message - Message object. - */ - // Detect message with type normal or with no type. - $(Candy).triggerHandler("candy:core:chat:message:normal", { - type: type || "normal", - message: msg - }); - return true; - } else if (type !== "groupchat" && type !== "chat" && type !== "error" && type !== "headline") { - /** Event: candy:core:chat:message:other - * Messages with a type other than the ones listed in RFC3921 - * section 2.1.1. This allows plugins to catch custom message - * types. - * - * Parameters: - * (String) type - Type of the message [default: message] - * (Object) message - Message object. - */ - // Detect message with type normal or with no type. - $(Candy).triggerHandler("candy:core:chat:message:other", { - type: type, - message: msg - }); - return true; - } - // Room message - if (fromJid !== Strophe.getDomainFromJid(fromJid) && (type === "groupchat" || type === "chat" || type === "error")) { - self.Jabber.Room.Message(msg); - } else if (!toJid && fromJid === Strophe.getDomainFromJid(fromJid)) { - /** Event: candy:core.chat.message.admin - * Admin message - * - * Parameters: - * (String) type - Type of the message [default: message] - * (String) message - Message text - */ - $(Candy).triggerHandler("candy:core.chat.message.admin", { - type: type || "message", - message: msg.children("body").text() - }); - } else if (toJid && fromJid === Strophe.getDomainFromJid(fromJid)) { - /** Event: candy:core.chat.message.server - * Server message (e.g. subject) - * - * Parameters: - * (String) type - Message type [default: message] - * (String) subject - Subject text - * (String) message - Message text - */ - $(Candy).triggerHandler("candy:core.chat.message.server", { - type: type || "message", - subject: msg.children("subject").text(), - message: msg.children("body").text() - }); - } - return true; - }, - /** Class: Candy.Core.Event.Jabber.Room - * Room specific events - */ - Room: { - /** Function: Leave - * Leaves a room and cleans up related data and notifies view. - * - * Parameters: - * (String) msg - Raw XML Message - * - * Triggers: - * candy:core.presence.leave using {roomJid, roomName, type, reason, actor, user} - * - * Returns: - * (Boolean) - true - */ - Leave: function(msg) { - Candy.Core.log("[Jabber:Room] Leave"); - msg = $(msg); - var from = Candy.Util.unescapeJid(msg.attr("from")), roomJid = Strophe.getBareJidFromJid(from); - // if room is not joined yet, ignore. - if (!Candy.Core.getRoom(roomJid)) { - return true; - } - var roomName = Candy.Core.getRoom(roomJid).getName(), item = msg.find("item"), type = "leave", reason, actor; - delete Candy.Core.getRooms()[roomJid]; - // if user gets kicked, role is none and there's a status code 307 - if (item.attr("role") === "none") { - var code = msg.find("status").attr("code"); - if (code === "307") { - type = "kick"; - } else if (code === "301") { - type = "ban"; - } - reason = item.find("reason").text(); - actor = item.find("actor").attr("jid"); - } - var user = new Candy.Core.ChatUser(from, Strophe.getResourceFromJid(from), item.attr("affiliation"), item.attr("role")); - /** Event: candy:core.presence.leave - * When the local client leaves a room - * - * Also triggered when the local client gets kicked or banned from a room. - * - * Parameters: - * (String) roomJid - Room - * (String) roomName - Name of room - * (String) type - Presence type [kick, ban, leave] - * (String) reason - When type equals kick|ban, this is the reason the moderator has supplied. - * (String) actor - When type equals kick|ban, this is the moderator which did the kick - * (Candy.Core.ChatUser) user - user which leaves the room - */ - $(Candy).triggerHandler("candy:core.presence.leave", { - roomJid: roomJid, - roomName: roomName, - type: type, - reason: reason, - actor: actor, - user: user - }); - return true; - }, - /** Function: Disco - * Sets informations to rooms according to the disco info received. - * - * Parameters: - * (String) msg - Raw XML Message - * - * Returns: - * (Boolean) - true - */ - Disco: function(msg) { - Candy.Core.log("[Jabber:Room] Disco"); - msg = $(msg); - // Temp fix for #219 - // Don't go further if it's no conference disco reply - // FIXME: Do this in a more beautiful way - if (!msg.find('identity[category="conference"]').length) { - return true; - } - var roomJid = Strophe.getBareJidFromJid(Candy.Util.unescapeJid(msg.attr("from"))); - // Client joined a room - if (!Candy.Core.getRooms()[roomJid]) { - Candy.Core.getRooms()[roomJid] = new Candy.Core.ChatRoom(roomJid); - } - // Room existed but room name was unknown - var identity = msg.find("identity"); - if (identity.length) { - var roomName = identity.attr("name"), room = Candy.Core.getRoom(roomJid); - if (room.getName() === null) { - room.setName(Strophe.unescapeNode(roomName)); - } - } - return true; - }, - /** Function: Presence - * Acts on various presence messages (room leaving, room joining, error presence) and notifies view. - * - * Parameters: - * (Object) msg - jQuery object of XML message - * - * Triggers: - * candy:core.presence.room using {roomJid, roomName, user, action, currentUser} - * - * Returns: - * (Boolean) - true - */ - Presence: function(msg) { - Candy.Core.log("[Jabber:Room] Presence"); - var from = Candy.Util.unescapeJid(msg.attr("from")), roomJid = Strophe.getBareJidFromJid(from), presenceType = msg.attr("type"), status = msg.find("status"), nickAssign = false, nickChange = false; - if (status.length) { - // check if status code indicates a nick assignment or nick change - for (var i = 0, l = status.length; i < l; i++) { - var $status = $(status[i]), code = $status.attr("code"); - if (code === "303") { - nickChange = true; - } else if (code === "210") { - nickAssign = true; - } - } - } - // Current User joined a room - var room = Candy.Core.getRoom(roomJid); - if (!room) { - Candy.Core.getRooms()[roomJid] = new Candy.Core.ChatRoom(roomJid); - room = Candy.Core.getRoom(roomJid); - } - // Current User left a room - var currentUser = room.getUser() ? room.getUser() : Candy.Core.getUser(); - if (Strophe.getResourceFromJid(from) === currentUser.getNick() && presenceType === "unavailable" && nickChange === false) { - self.Jabber.Room.Leave(msg); - return true; - } - var roster = room.getRoster(), action, user, nick, item = msg.find("item"); - // User joined a room - if (presenceType !== "unavailable") { - if (roster.get(from)) { - // role/affiliation change - user = roster.get(from); - var role = item.attr("role"), affiliation = item.attr("affiliation"); - user.setRole(role); - user.setAffiliation(affiliation); - // FIXME: currently role/affilation changes are handled with this action - action = "join"; - } else { - nick = Strophe.getResourceFromJid(from); - user = new Candy.Core.ChatUser(from, nick, item.attr("affiliation"), item.attr("role")); - // Room existed but client (myself) is not yet registered - if (room.getUser() === null && (Candy.Core.getUser().getNick() === nick || nickAssign)) { - room.setUser(user); - currentUser = user; - } - roster.add(user); - action = "join"; - } - } else { - user = roster.get(from); - roster.remove(from); - if (nickChange) { - // user changed nick - nick = item.attr("nick"); - action = "nickchange"; - user.setPreviousNick(user.getNick()); - user.setNick(nick); - user.setJid(Strophe.getBareJidFromJid(from) + "/" + nick); - roster.add(user); - } else { - action = "leave"; - if (item.attr("role") === "none") { - if (msg.find("status").attr("code") === "307") { - action = "kick"; - } else if (msg.find("status").attr("code") === "301") { - action = "ban"; - } - } - } - } - /** Event: candy:core.presence.room - * Room presence updates - * - * Parameters: - * (String) roomJid - Room JID - * (String) roomName - Room name - * (Candy.Core.ChatUser) user - User which does the presence update - * (String) action - Action [kick, ban, leave, join] - * (Candy.Core.ChatUser) currentUser - Current local user - */ - $(Candy).triggerHandler("candy:core.presence.room", { - roomJid: roomJid, - roomName: room.getName(), - user: user, - action: action, - currentUser: currentUser - }); - return true; - }, - /** Function: PresenceError - * Acts when a presence of type error has been retrieved. - * - * Parameters: - * (Object) msg - jQuery object of XML message - * - * Triggers: - * candy:core.presence.error using {msg, type, roomJid, roomName} - * - * Returns: - * (Boolean) - true - */ - PresenceError: function(msg) { - Candy.Core.log("[Jabber:Room] Presence Error"); - var from = Candy.Util.unescapeJid(msg.attr("from")), roomJid = Strophe.getBareJidFromJid(from), room = Candy.Core.getRooms()[roomJid], roomName = room.getName(); - // Presence error: Remove room from array to prevent error when disconnecting - Candy.Core.removeRoom(roomJid); - room = undefined; - /** Event: candy:core.presence.error - * Triggered when a presence error happened - * - * Parameters: - * (Object) msg - jQuery object of XML message - * (String) type - Error type - * (String) roomJid - Room jid - * (String) roomName - Room name - */ - $(Candy).triggerHandler("candy:core.presence.error", { - msg: msg, - type: msg.children("error").children()[0].tagName.toLowerCase(), - roomJid: roomJid, - roomName: roomName - }); - return true; - }, - /** Function: Message - * Acts on various message events (subject changed, private chat message, multi-user chat message) - * and notifies view. - * - * Parameters: - * (String) msg - jQuery object of XML message - * - * Triggers: - * candy:core.message using {roomJid, message, timestamp} - * - * Returns: - * (Boolean) - true - */ - Message: function(msg) { - Candy.Core.log("[Jabber:Room] Message"); - // Room subject - var roomJid, message, name; - if (msg.children("subject").length > 0 && msg.children("subject").text().length > 0 && msg.attr("type") === "groupchat") { - roomJid = Candy.Util.unescapeJid(Strophe.getBareJidFromJid(msg.attr("from"))); - message = { - name: Strophe.getNodeFromJid(roomJid), - body: msg.children("subject").text(), - type: "subject" - }; - } else if (msg.attr("type") === "error") { - var error = msg.children("error"); - if (error.children("text").length > 0) { - roomJid = msg.attr("from"); - message = { - type: "info", - body: error.children("text").text() - }; - } - } else if (msg.children("body").length > 0) { - // Private chat message - if (msg.attr("type") === "chat" || msg.attr("type") === "normal") { - roomJid = Candy.Util.unescapeJid(msg.attr("from")); - var bareRoomJid = Strophe.getBareJidFromJid(roomJid), // if a 3rd-party client sends a direct message to this user (not via the room) then the username is the node and not the resource. - isNoConferenceRoomJid = !Candy.Core.getRoom(bareRoomJid); - name = isNoConferenceRoomJid ? Strophe.getNodeFromJid(roomJid) : Strophe.getResourceFromJid(roomJid); - message = { - name: name, - body: msg.children("body").text(), - type: msg.attr("type"), - isNoConferenceRoomJid: isNoConferenceRoomJid - }; - } else { - roomJid = Candy.Util.unescapeJid(Strophe.getBareJidFromJid(msg.attr("from"))); - var resource = Strophe.getResourceFromJid(msg.attr("from")); - // Message from a user - if (resource) { - resource = Strophe.unescapeNode(resource); - message = { - name: resource, - body: msg.children("body").text(), - type: msg.attr("type") - }; - } else { - // we are not yet present in the room, let's just drop this message (issue #105) - if (!Candy.View.Pane.Chat.rooms[msg.attr("from")]) { - return true; - } - message = { - name: "", - body: msg.children("body").text(), - type: "info" - }; - } - } - var xhtmlChild = msg.children('html[xmlns="' + Strophe.NS.XHTML_IM + '"]'); - if (Candy.View.getOptions().enableXHTML === true && xhtmlChild.length > 0) { - var xhtmlMessage = xhtmlChild.children('body[xmlns="' + Strophe.NS.XHTML + '"]').first().html(); - message.xhtmlMessage = xhtmlMessage; - } - } else if (msg.children("composing").length > 0 || msg.children("inactive").length > 0 || msg.children("paused").length > 0) { - roomJid = Candy.Util.unescapeJid(msg.attr("from")); - name = Strophe.getResourceFromJid(roomJid); - var chatstate; - if (msg.children("composing").length > 0) { - chatstate = "composing"; - } else if (msg.children("paused").length > 0) { - chatstate = "paused"; - } else if (msg.children("inactive").length > 0) { - chatstate = "inactive"; - } else if (msg.children("gone").length > 0) { - chatstate = "gone"; - } - /** Event: candy:core.message.chatstate - * Triggers on any recieved chatstate notification. - * - * The resulting message object contains the name of the person, the roomJid, and the indicated chatstate. - * - * The following lists explain those parameters: - * - * Message Object Parameters: - * (String) name - User name - * (String) roomJid - Room jid - * (String) chatstate - Chatstate being indicated. ("paused", "inactive", "composing", "gone") - * - * TODO: - * Perhaps handle blank "active" as specified by XEP-0085? - */ - $(Candy).triggerHandler("candy:core.message.chatstate", { - name: name, - roomJid: roomJid, - chatstate: chatstate - }); - return true; - } else { - return true; - } - // besides the delayed delivery (XEP-0203), there exists also XEP-0091 which is the legacy delayed delivery. - // the x[xmlns=jabber:x:delay] is the format in XEP-0091. - var delay = msg.children("delay") ? msg.children("delay") : msg.children('x[xmlns="' + Strophe.NS.DELAY + '"]'), timestamp = delay !== undefined ? delay.attr("stamp") : null; - /** Event: candy:core.message - * Triggers on various message events (subject changed, private chat message, multi-user chat message). - * - * The resulting message object can contain different key-value pairs as stated in the documentation - * of the parameters itself. - * - * The following lists explain those parameters: - * - * Message Object Parameters: - * (String) name - Room name - * (String) body - Message text - * (String) type - Message type ([normal, chat, groupchat]) - * or 'info' which is used internally for displaying informational messages - * (Boolean) isNoConferenceRoomJid - if a 3rd-party client sends a direct message to - * this user (not via the room) then the username is the node - * and not the resource. - * This flag tells if this is the case. - * - * Parameters: - * (String) roomJid - Room jid - * (Object) message - Depending on what kind of message, the object consists of different key-value pairs: - * - Room Subject: {name, body, type} - * - Error message: {type = 'info', body} - * - Private chat message: {name, body, type, isNoConferenceRoomJid} - * - MUC msg from a user: {name, body, type} - * - MUC msg from server: {name = '', body, type = 'info'} - * (String) timestamp - Timestamp, only when it's an offline message - * - * TODO: - * Streamline those events sent and rename the parameters. - */ - $(Candy).triggerHandler("candy:core.message", { - roomJid: roomJid, - message: message, - timestamp: timestamp - }); - return true; - } - } - }; - return self; -}(Candy.Core.Event || {}, Strophe, jQuery); - -/** File: observer.js - * Candy - Chats are not dead yet. - * - * Authors: - * - Patrick Stadler - * - Michael Weibel - * - * Copyright: - * (c) 2011 Amiado Group AG. All rights reserved. - * (c) 2012-2014 Patrick Stadler & Michael Weibel - */ -"use strict"; - -/* global Candy, Strophe, Mustache, jQuery */ -/** Class: Candy.View.Observer - * Observes Candy core events - * - * Parameters: - * (Candy.View.Observer) self - itself - * (jQuery) $ - jQuery - */ -Candy.View.Observer = function(self, $) { - /** PrivateVariable: _showConnectedMessageModal - * Ugly way to determine if the 'connected' modal should be shown. - * Is set to false in case no autojoin param is set. - */ - var _showConnectedMessageModal = true; - /** Class: Candy.View.Observer.Chat - * Chat events - */ - self.Chat = { - /** Function: Connection - * The update method gets called whenever an event to which "Chat" is subscribed. - * - * Currently listens for connection status updates - * - * Parameters: - * (jQuery.Event) event - jQuery Event object - * (Object) args - {status (Strophe.Status.*)} - */ - Connection: function(event, args) { - var eventName = "candy:view.connection.status-" + args.status; - /** Event: candy:view.connection.status- - * Using this event, you can alter the default Candy (View) behaviour when reacting - * to connection updates. - * - * STROPHE-STATUS has to be replaced by one of : - * - ERROR: 0, - * - CONNECTING: 1, - * - CONNFAIL: 2, - * - AUTHENTICATING: 3, - * - AUTHFAIL: 4, - * - CONNECTED: 5, - * - DISCONNECTED: 6, - * - DISCONNECTING: 7, - * - ATTACHED: 8 - * - * - * If your event handler returns `false`, no View changes will take place. - * You can, of course, also return `true` and do custom things but still - * let Candy (View) do it's job. - * - * This event has been implemented due to - * and here's an example use-case for it: - * - * (start code) - * // react to DISCONNECTED event - * $(Candy).on('candy:view.connection.status-6', function() { - * // on next browser event loop - * setTimeout(function() { - * // reload page to automatically reattach on disconnect - * window.location.reload(); - * }, 0); - * // stop view changes right here. - * return false; - * }); - * (end code) - */ - if ($(Candy).triggerHandler(eventName) === false) { - return false; - } - switch (args.status) { - case Strophe.Status.CONNECTING: - case Strophe.Status.AUTHENTICATING: - Candy.View.Pane.Chat.Modal.show($.i18n._("statusConnecting"), false, true); - break; - - case Strophe.Status.ATTACHED: - case Strophe.Status.CONNECTED: - if (_showConnectedMessageModal === true) { - // only show 'connected' if the autojoin error is not shown - // which is determined by having a visible modal in this stage. - Candy.View.Pane.Chat.Modal.show($.i18n._("statusConnected")); - Candy.View.Pane.Chat.Modal.hide(); - } - break; - - case Strophe.Status.DISCONNECTING: - Candy.View.Pane.Chat.Modal.show($.i18n._("statusDisconnecting"), false, true); - break; - - case Strophe.Status.DISCONNECTED: - var presetJid = Candy.Core.isAnonymousConnection() ? Strophe.getDomainFromJid(Candy.Core.getUser().getJid()) : null; - Candy.View.Pane.Chat.Modal.showLoginForm($.i18n._("statusDisconnected"), presetJid); - break; - - case Strophe.Status.AUTHFAIL: - Candy.View.Pane.Chat.Modal.showLoginForm($.i18n._("statusAuthfail")); - break; - - default: - Candy.View.Pane.Chat.Modal.show($.i18n._("status", args.status)); - break; - } - }, - /** Function: Message - * Dispatches admin and info messages - * - * Parameters: - * (jQuery.Event) event - jQuery Event object - * (Object) args - {type (message/chat/groupchat), subject (if type = message), message} - */ - Message: function(event, args) { - if (args.type === "message") { - Candy.View.Pane.Chat.adminMessage(args.subject || "", args.message); - } else if (args.type === "chat" || args.type === "groupchat") { - // use onInfoMessage as infos from the server shouldn't be hidden by the infoMessage switch. - Candy.View.Pane.Chat.onInfoMessage(Candy.View.getCurrent().roomJid, args.subject || "", args.message); - } - } - }; - /** Class: Candy.View.Observer.Presence - * Presence update events - */ - self.Presence = { - /** Function: update - * Every presence update gets dispatched from this method. - * - * Parameters: - * (jQuery.Event) event - jQuery.Event object - * (Object) args - Arguments differ on each type - * - * Uses: - * - - */ - update: function(event, args) { - // Client left - if (args.type === "leave") { - var user = Candy.View.Pane.Room.getUser(args.roomJid); - Candy.View.Pane.Room.close(args.roomJid); - self.Presence.notifyPrivateChats(user, args.type); - } else if (args.type === "kick" || args.type === "ban") { - var actorName = args.actor ? Strophe.getNodeFromJid(args.actor) : null, actionLabel, translationParams = [ args.roomName ]; - if (actorName) { - translationParams.push(actorName); - } - switch (args.type) { - case "kick": - actionLabel = $.i18n._(actorName ? "youHaveBeenKickedBy" : "youHaveBeenKicked", translationParams); - break; - - case "ban": - actionLabel = $.i18n._(actorName ? "youHaveBeenBannedBy" : "youHaveBeenBanned", translationParams); - break; - } - Candy.View.Pane.Chat.Modal.show(Mustache.to_html(Candy.View.Template.Chat.Context.adminMessageReason, { - reason: args.reason, - _action: actionLabel, - _reason: $.i18n._("reasonWas", [ args.reason ]) - })); - setTimeout(function() { - Candy.View.Pane.Chat.Modal.hide(function() { - Candy.View.Pane.Room.close(args.roomJid); - self.Presence.notifyPrivateChats(args.user, args.type); - }); - }, 5e3); - var evtData = { - type: args.type, - reason: args.reason, - roomJid: args.roomJid, - user: args.user - }; - /** Event: candy:view.presence - * Presence update when kicked or banned - * - * Parameters: - * (String) type - Presence type [kick, ban] - * (String) reason - Reason for the kick|ban [optional] - * (String) roomJid - Room JID - * (Candy.Core.ChatUser) user - User which has been kicked or banned - */ - $(Candy).triggerHandler("candy:view.presence", [ evtData ]); - } else if (args.roomJid) { - args.roomJid = Candy.Util.unescapeJid(args.roomJid); - // Initialize room if not yet existing - if (!Candy.View.Pane.Chat.rooms[args.roomJid]) { - if (Candy.View.Pane.Room.init(args.roomJid, args.roomName) === false) { - return false; - } - Candy.View.Pane.Room.show(args.roomJid); - } - Candy.View.Pane.Roster.update(args.roomJid, args.user, args.action, args.currentUser); - // Notify private user chats if existing, but not in case the action is nickchange - // -- this is because the nickchange presence already contains the new - // user jid - if (Candy.View.Pane.Chat.rooms[args.user.getJid()] && args.action !== "nickchange") { - Candy.View.Pane.Roster.update(args.user.getJid(), args.user, args.action, args.currentUser); - Candy.View.Pane.PrivateRoom.setStatus(args.user.getJid(), args.action); - } - } - }, - /** Function: notifyPrivateChats - * Notify private user chats if existing - * - * Parameters: - * (Candy.Core.ChatUser) user - User which has done the event - * (String) type - Event type (leave, join, kick/ban) - */ - notifyPrivateChats: function(user, type) { - Candy.Core.log("[View:Observer] notify Private Chats"); - var roomJid; - for (roomJid in Candy.View.Pane.Chat.rooms) { - if (Candy.View.Pane.Chat.rooms.hasOwnProperty(roomJid) && Candy.View.Pane.Room.getUser(roomJid) && user.getJid() === Candy.View.Pane.Room.getUser(roomJid).getJid()) { - Candy.View.Pane.Roster.update(roomJid, user, type, user); - Candy.View.Pane.PrivateRoom.setStatus(roomJid, type); - } - } - } - }; - /** Function: Candy.View.Observer.PresenceError - * Presence errors get handled in this method - * - * Parameters: - * (jQuery.Event) event - jQuery.Event object - * (Object) args - {msg, type, roomJid, roomName} - */ - self.PresenceError = function(obj, args) { - switch (args.type) { - case "not-authorized": - var message; - if (args.msg.children("x").children("password").length > 0) { - message = $.i18n._("passwordEnteredInvalid", [ args.roomName ]); - } - Candy.View.Pane.Chat.Modal.showEnterPasswordForm(args.roomJid, args.roomName, message); - break; - - case "conflict": - Candy.View.Pane.Chat.Modal.showNicknameConflictForm(args.roomJid); - break; - - case "registration-required": - Candy.View.Pane.Chat.Modal.showError("errorMembersOnly", [ args.roomName ]); - break; - - case "service-unavailable": - Candy.View.Pane.Chat.Modal.showError("errorMaxOccupantsReached", [ args.roomName ]); - break; - } - }; - /** Function: Candy.View.Observer.Message - * Messages received get dispatched from this method. - * - * Parameters: - * (jQuery.Event) event - jQuery Event object - * (Object) args - {message, roomJid} - */ - self.Message = function(event, args) { - if (args.message.type === "subject") { - if (!Candy.View.Pane.Chat.rooms[args.roomJid]) { - Candy.View.Pane.Room.init(args.roomJid, args.message.name); - Candy.View.Pane.Room.show(args.roomJid); - } - Candy.View.Pane.Room.setSubject(args.roomJid, args.message.body); - } else if (args.message.type === "info") { - Candy.View.Pane.Chat.infoMessage(args.roomJid, args.message.body); - } else { - // Initialize room if it's a message for a new private user chat - if (args.message.type === "chat" && !Candy.View.Pane.Chat.rooms[args.roomJid]) { - Candy.View.Pane.PrivateRoom.open(args.roomJid, args.message.name, false, args.message.isNoConferenceRoomJid); - } - Candy.View.Pane.Message.show(args.roomJid, args.message.name, args.message.body, args.message.xhtmlMessage, args.timestamp); - } - }; - /** Function: Candy.View.Observer.Login - * The login event gets dispatched to this method - * - * Parameters: - * (jQuery.Event) event - jQuery Event object - * (Object) args - {presetJid} - */ - self.Login = function(event, args) { - Candy.View.Pane.Chat.Modal.showLoginForm(null, args.presetJid); - }; - /** Class: Candy.View.Observer.AutojoinMissing - * Displays an error about missing autojoin information - */ - self.AutojoinMissing = function() { - _showConnectedMessageModal = false; - Candy.View.Pane.Chat.Modal.showError("errorAutojoinMissing"); - }; - return self; -}(Candy.View.Observer || {}, jQuery); - -/** File: pane.js - * Candy - Chats are not dead yet. - * - * Authors: - * - Patrick Stadler - * - Michael Weibel - * - * Copyright: - * (c) 2011 Amiado Group AG. All rights reserved. - * (c) 2012-2014 Patrick Stadler & Michael Weibel. All rights reserved. - */ -"use strict"; - -/* global Candy, document, Mustache, Strophe, Audio, jQuery */ -/** Class: Candy.View.Pane - * Candy view pane handles everything regarding DOM updates etc. - * - * Parameters: - * (Candy.View.Pane) self - itself - * (jQuery) $ - jQuery - */ -Candy.View.Pane = function(self, $) { - /** Class: Candy.View.Pane.Window - * Window related view updates - */ - self.Window = { - /** PrivateVariable: _hasFocus - * Window has focus - */ - _hasFocus: true, - /** PrivateVariable: _plainTitle - * Document title - */ - _plainTitle: document.title, - /** PrivateVariable: _unreadMessagesCount - * Unread messages count - */ - _unreadMessagesCount: 0, - /** Variable: autoscroll - * Boolean whether autoscroll is enabled - */ - autoscroll: true, - /** Function: hasFocus - * Checks if window has focus - * - * Returns: - * (Boolean) - */ - hasFocus: function() { - return self.Window._hasFocus; - }, - /** Function: increaseUnreadMessages - * Increases unread message count in window title by one. - */ - increaseUnreadMessages: function() { - self.Window.renderUnreadMessages(++self.Window._unreadMessagesCount); - }, - /** Function: reduceUnreadMessages - * Reduce unread message count in window title by `num`. - * - * Parameters: - * (Integer) num - Unread message count will be reduced by this value - */ - reduceUnreadMessages: function(num) { - self.Window._unreadMessagesCount -= num; - if (self.Window._unreadMessagesCount <= 0) { - self.Window.clearUnreadMessages(); - } else { - self.Window.renderUnreadMessages(self.Window._unreadMessagesCount); - } - }, - /** Function: clearUnreadMessages - * Clear unread message count in window title. - */ - clearUnreadMessages: function() { - self.Window._unreadMessagesCount = 0; - document.title = self.Window._plainTitle; - }, - /** Function: renderUnreadMessages - * Update window title to show message count. - * - * Parameters: - * (Integer) count - Number of unread messages to show in window title - */ - renderUnreadMessages: function(count) { - document.title = Candy.View.Template.Window.unreadmessages.replace("{{count}}", count).replace("{{title}}", self.Window._plainTitle); - }, - /** Function: onFocus - * Window focus event handler. - */ - onFocus: function() { - self.Window._hasFocus = true; - if (Candy.View.getCurrent().roomJid) { - self.Room.setFocusToForm(Candy.View.getCurrent().roomJid); - self.Chat.clearUnreadMessages(Candy.View.getCurrent().roomJid); - } - }, - /** Function: onBlur - * Window blur event handler. - */ - onBlur: function() { - self.Window._hasFocus = false; - } - }; - /** Class: Candy.View.Pane.Chat - * Chat-View related view updates - */ - self.Chat = { - /** Variable: rooms - * Contains opened room elements - */ - rooms: [], - /** Function: addTab - * Add a tab to the chat pane. - * - * Parameters: - * (String) roomJid - JID of room - * (String) roomName - Tab label - * (String) roomType - Type of room: `groupchat` or `chat` - */ - addTab: function(roomJid, roomName, roomType) { - var roomId = Candy.Util.jidToId(roomJid), html = Mustache.to_html(Candy.View.Template.Chat.tab, { - roomJid: roomJid, - roomId: roomId, - name: roomName || Strophe.getNodeFromJid(roomJid), - privateUserChat: function() { - return roomType === "chat"; - }, - roomType: roomType - }), tab = $(html).appendTo("#chat-tabs"); - tab.click(self.Chat.tabClick); - // TODO: maybe we find a better way to get the close element. - $("a.close", tab).click(self.Chat.tabClose); - self.Chat.fitTabs(); - }, - /** Function: getTab - * Get tab by JID. - * - * Parameters: - * (String) roomJid - JID of room - * - * Returns: - * (jQuery object) - Tab element - */ - getTab: function(roomJid) { - return $("#chat-tabs").children('li[data-roomjid="' + roomJid + '"]'); - }, - /** Function: removeTab - * Remove tab element. - * - * Parameters: - * (String) roomJid - JID of room - */ - removeTab: function(roomJid) { - self.Chat.getTab(roomJid).remove(); - self.Chat.fitTabs(); - }, - /** Function: setActiveTab - * Set the active tab. - * - * Add CSS classname `active` to the choosen tab and remove `active` from all other. - * - * Parameters: - * (String) roomJid - JID of room - */ - setActiveTab: function(roomJid) { - $("#chat-tabs").children().each(function() { - var tab = $(this); - if (tab.attr("data-roomjid") === roomJid) { - tab.addClass("active"); - } else { - tab.removeClass("active"); - } - }); - }, - /** Function: increaseUnreadMessages - * Increase unread message count in a tab by one. - * - * Parameters: - * (String) roomJid - JID of room - * - * Uses: - * - - */ - increaseUnreadMessages: function(roomJid) { - var unreadElem = this.getTab(roomJid).find(".unread"); - unreadElem.show().text(unreadElem.text() !== "" ? parseInt(unreadElem.text(), 10) + 1 : 1); - // only increase window unread messages in private chats - if (self.Chat.rooms[roomJid].type === "chat") { - self.Window.increaseUnreadMessages(); - } - }, - /** Function: clearUnreadMessages - * Clear unread message count in a tab. - * - * Parameters: - * (String) roomJid - JID of room - * - * Uses: - * - - */ - clearUnreadMessages: function(roomJid) { - var unreadElem = self.Chat.getTab(roomJid).find(".unread"); - self.Window.reduceUnreadMessages(unreadElem.text()); - unreadElem.hide().text(""); - }, - /** Function: tabClick - * Tab click event: show the room associated with the tab and stops the event from doing the default. - */ - tabClick: function(e) { - // remember scroll position of current room - var currentRoomJid = Candy.View.getCurrent().roomJid; - self.Chat.rooms[currentRoomJid].scrollPosition = self.Room.getPane(currentRoomJid, ".message-pane-wrapper").scrollTop(); - self.Room.show($(this).attr("data-roomjid")); - e.preventDefault(); - }, - /** Function: tabClose - * Tab close (click) event: Leave the room (groupchat) or simply close the tab (chat). - * - * Parameters: - * (DOMEvent) e - Event triggered - * - * Returns: - * (Boolean) - false, this will stop the event from bubbling - */ - tabClose: function() { - var roomJid = $(this).parent().attr("data-roomjid"); - // close private user tab - if (self.Chat.rooms[roomJid].type === "chat") { - self.Room.close(roomJid); - } else { - Candy.Core.Action.Jabber.Room.Leave(roomJid); - } - return false; - }, - /** Function: allTabsClosed - * All tabs closed event: Disconnect from service. Hide sound control. - * - * TODO: Handle window close - * - * Returns: - * (Boolean) - false, this will stop the event from bubbling - */ - allTabsClosed: function() { - Candy.Core.disconnect(); - self.Chat.Toolbar.hide(); - return; - }, - /** Function: fitTabs - * Fit tab size according to window size - */ - fitTabs: function() { - var availableWidth = $("#chat-tabs").innerWidth(), tabsWidth = 0, tabs = $("#chat-tabs").children(); - tabs.each(function() { - tabsWidth += $(this).css({ - width: "auto", - overflow: "visible" - }).outerWidth(true); - }); - if (tabsWidth > availableWidth) { - // tabs.[outer]Width() measures the first element in `tabs`. It's no very readable but nearly two times faster than using :first - var tabDiffToRealWidth = tabs.outerWidth(true) - tabs.width(), tabWidth = Math.floor(availableWidth / tabs.length) - tabDiffToRealWidth; - tabs.css({ - width: tabWidth, - overflow: "hidden" - }); - } - }, - /** Function: adminMessage - * Display admin message - * - * Parameters: - * (String) subject - Admin message subject - * (String) message - Message to be displayed - * - * Triggers: - * candy:view.chat.admin-message using {subject, message} - */ - adminMessage: function(subject, message) { - if (Candy.View.getCurrent().roomJid) { - // Simply dismiss admin message if no room joined so far. TODO: maybe we should show those messages on a dedicated pane? - var html = Mustache.to_html(Candy.View.Template.Chat.adminMessage, { - subject: subject, - message: message, - sender: $.i18n._("administratorMessageSubject"), - time: Candy.Util.localizedTime(new Date().toGMTString()) - }); - $("#chat-rooms").children().each(function() { - self.Room.appendToMessagePane($(this).attr("data-roomjid"), html); - }); - self.Room.scrollToBottom(Candy.View.getCurrent().roomJid); - /** Event: candy:view.chat.admin-message - * After admin message display - * - * Parameters: - * (String) presetJid - Preset user JID - */ - $(Candy).triggerHandler("candy:view.chat.admin-message", { - subject: subject, - message: message - }); - } - }, - /** Function: infoMessage - * Display info message. This is a wrapper for to be able to disable certain info messages. - * - * Parameters: - * (String) roomJid - Room JID - * (String) subject - Subject - * (String) message - Message - */ - infoMessage: function(roomJid, subject, message) { - self.Chat.onInfoMessage(roomJid, subject, message); - }, - /** Function: onInfoMessage - * Display info message. Used by and several other functions which do not wish that their info message - * can be disabled (such as kick/ban message or leave/join message in private chats). - * - * Parameters: - * (String) roomJid - Room JID - * (String) subject - Subject - * (String) message - Message - */ - onInfoMessage: function(roomJid, subject, message) { - if (Candy.View.getCurrent().roomJid) { - // Simply dismiss info message if no room joined so far. TODO: maybe we should show those messages on a dedicated pane? - var html = Mustache.to_html(Candy.View.Template.Chat.infoMessage, { - subject: subject, - message: $.i18n._(message), - time: Candy.Util.localizedTime(new Date().toGMTString()) - }); - self.Room.appendToMessagePane(roomJid, html); - if (Candy.View.getCurrent().roomJid === roomJid) { - self.Room.scrollToBottom(Candy.View.getCurrent().roomJid); - } - } - }, - /** Class: Candy.View.Pane.Toolbar - * Chat toolbar for things like emoticons toolbar, room management etc. - */ - Toolbar: { - _supportsNativeAudio: false, - /** Function: init - * Register handler and enable or disable sound and status messages. - */ - init: function() { - $("#emoticons-icon").click(function(e) { - self.Chat.Context.showEmoticonsMenu(e.currentTarget); - e.stopPropagation(); - }); - $("#chat-autoscroll-control").click(self.Chat.Toolbar.onAutoscrollControlClick); - var a = document.createElement("audio"); - self.Chat.Toolbar._supportsNativeAudio = !!(a.canPlayType && a.canPlayType("audio/mpeg;").replace(/no/, "")); - $("#chat-sound-control").click(self.Chat.Toolbar.onSoundControlClick); - if (Candy.Util.cookieExists("candy-nosound")) { - $("#chat-sound-control").click(); - } - $("#chat-statusmessage-control").click(self.Chat.Toolbar.onStatusMessageControlClick); - if (Candy.Util.cookieExists("candy-nostatusmessages")) { - $("#chat-statusmessage-control").click(); - } - }, - /** Function: show - * Show toolbar. - */ - show: function() { - $("#chat-toolbar").show(); - }, - /** Function: hide - * Hide toolbar. - */ - hide: function() { - $("#chat-toolbar").hide(); - }, - /* Function: update - * Update toolbar for specific room - */ - update: function(roomJid) { - var context = $("#chat-toolbar").find(".context"), me = self.Room.getUser(roomJid); - if (!me || !me.isModerator()) { - context.hide(); - } else { - context.show().click(function(e) { - self.Chat.Context.show(e.currentTarget, roomJid); - e.stopPropagation(); - }); - } - self.Chat.Toolbar.updateUsercount(self.Chat.rooms[roomJid].usercount); - }, - /** Function: playSound - * Play sound (default method). - */ - playSound: function() { - self.Chat.Toolbar.onPlaySound(); - }, - /** Function: onPlaySound - * Sound play event handler. Uses native (HTML5) audio if supported - * - * Don't call this method directly. Call `playSound()` instead. - * `playSound()` will only call this method if sound is enabled. - */ - onPlaySound: function() { - try { - if (self.Chat.Toolbar._supportsNativeAudio) { - new Audio(Candy.View.getOptions().assets + "notify.mp3").play(); - } else { - var chatSoundPlayer = document.getElementById("chat-sound-player"); - chatSoundPlayer.SetVariable("method:stop", ""); - chatSoundPlayer.SetVariable("method:play", ""); - } - } catch (e) {} - }, - /** Function: onSoundControlClick - * Sound control click event handler. - * - * Toggle sound (overwrite `playSound()`) and handle cookies. - */ - onSoundControlClick: function() { - var control = $("#chat-sound-control"); - if (control.hasClass("checked")) { - self.Chat.Toolbar.playSound = function() {}; - Candy.Util.setCookie("candy-nosound", "1", 365); - } else { - self.Chat.Toolbar.playSound = function() { - self.Chat.Toolbar.onPlaySound(); - }; - Candy.Util.deleteCookie("candy-nosound"); - } - control.toggleClass("checked"); - }, - /** Function: onAutoscrollControlClick - * Autoscroll control event handler. - * - * Toggle autoscroll - */ - onAutoscrollControlClick: function() { - var control = $("#chat-autoscroll-control"); - if (control.hasClass("checked")) { - self.Room.scrollToBottom = function(roomJid) { - self.Room.onScrollToStoredPosition(roomJid); - }; - self.Window.autoscroll = false; - } else { - self.Room.scrollToBottom = function(roomJid) { - self.Room.onScrollToBottom(roomJid); - }; - self.Room.scrollToBottom(Candy.View.getCurrent().roomJid); - self.Window.autoscroll = true; - } - control.toggleClass("checked"); - }, - /** Function: onStatusMessageControlClick - * Status message control event handler. - * - * Toggle status message - */ - onStatusMessageControlClick: function() { - var control = $("#chat-statusmessage-control"); - if (control.hasClass("checked")) { - self.Chat.infoMessage = function() {}; - Candy.Util.setCookie("candy-nostatusmessages", "1", 365); - } else { - self.Chat.infoMessage = function(roomJid, subject, message) { - self.Chat.onInfoMessage(roomJid, subject, message); - }; - Candy.Util.deleteCookie("candy-nostatusmessages"); - } - control.toggleClass("checked"); - }, - /** Function: updateUserCount - * Update usercount element with count. - * - * Parameters: - * (Integer) count - Current usercount - */ - updateUsercount: function(count) { - $("#chat-usercount").text(count); - } - }, - /** Class: Candy.View.Pane.Modal - * Modal window - */ - Modal: { - /** Function: show - * Display modal window - * - * Parameters: - * (String) html - HTML code to put into the modal window - * (Boolean) showCloseControl - set to true if a close button should be displayed [default false] - * (Boolean) showSpinner - set to true if a loading spinner should be shown [default false] - */ - show: function(html, showCloseControl, showSpinner) { - if (showCloseControl) { - self.Chat.Modal.showCloseControl(); - } else { - self.Chat.Modal.hideCloseControl(); - } - if (showSpinner) { - self.Chat.Modal.showSpinner(); - } else { - self.Chat.Modal.hideSpinner(); - } - $("#chat-modal").stop(false, true); - $("#chat-modal-body").html(html); - $("#chat-modal").fadeIn("fast"); - $("#chat-modal-overlay").show(); - }, - /** Function: hide - * Hide modal window - * - * Parameters: - * (Function) callback - Calls the specified function after modal window has been hidden. - */ - hide: function(callback) { - $("#chat-modal").fadeOut("fast", function() { - $("#chat-modal-body").text(""); - $("#chat-modal-overlay").hide(); - }); - // restore initial esc handling - $(document).keydown(function(e) { - if (e.which === 27) { - e.preventDefault(); - } - }); - if (callback) { - callback(); - } - }, - /** Function: showSpinner - * Show loading spinner - */ - showSpinner: function() { - $("#chat-modal-spinner").show(); - }, - /** Function: hideSpinner - * Hide loading spinner - */ - hideSpinner: function() { - $("#chat-modal-spinner").hide(); - }, - /** Function: showCloseControl - * Show a close button - */ - showCloseControl: function() { - $("#admin-message-cancel").show().click(function(e) { - self.Chat.Modal.hide(); - // some strange behaviour on IE7 (and maybe other browsers) triggers onWindowUnload when clicking on the close button. - // prevent this. - e.preventDefault(); - }); - // enable esc to close modal - $(document).keydown(function(e) { - if (e.which === 27) { - self.Chat.Modal.hide(); - e.preventDefault(); - } - }); - }, - /** Function: hideCloseControl - * Hide the close button - */ - hideCloseControl: function() { - $("#admin-message-cancel").hide().click(function() {}); - }, - /** Function: showLoginForm - * Show the login form modal - * - * Parameters: - * (String) message - optional message to display above the form - * (String) presetJid - optional user jid. if set, the user will only be prompted for password. - */ - showLoginForm: function(message, presetJid) { - self.Chat.Modal.show((message ? message : "") + Mustache.to_html(Candy.View.Template.Login.form, { - _labelNickname: $.i18n._("labelNickname"), - _labelUsername: $.i18n._("labelUsername"), - _labelPassword: $.i18n._("labelPassword"), - _loginSubmit: $.i18n._("loginSubmit"), - displayPassword: !Candy.Core.isAnonymousConnection(), - displayUsername: !presetJid, - displayNickname: Candy.Core.isAnonymousConnection(), - presetJid: presetJid ? presetJid : false - })); - $("#login-form").children(":input:first").focus(); - // register submit handler - $("#login-form").submit(function() { - var username = $("#username").val(), password = $("#password").val(); - if (!Candy.Core.isAnonymousConnection()) { - // guess the input and create a jid out of it - var jid = Candy.Core.getUser() && username.indexOf("@") < 0 ? username + "@" + Strophe.getDomainFromJid(Candy.Core.getUser().getJid()) : username; - if (jid.indexOf("@") < 0 && !Candy.Core.getUser()) { - Candy.View.Pane.Chat.Modal.showLoginForm($.i18n._("loginInvalid")); - } else { - //Candy.View.Pane.Chat.Modal.hide(); - Candy.Core.connect(jid, password); - } - } else { - // anonymous login - Candy.Core.connect(presetJid, null, username); - } - return false; - }); - }, - /** Function: showEnterPasswordForm - * Shows a form for entering room password - * - * Parameters: - * (String) roomJid - Room jid to join - * (String) roomName - Room name - * (String) message - [optional] Message to show as the label - */ - showEnterPasswordForm: function(roomJid, roomName, message) { - self.Chat.Modal.show(Mustache.to_html(Candy.View.Template.PresenceError.enterPasswordForm, { - roomName: roomName, - _labelPassword: $.i18n._("labelPassword"), - _label: message ? message : $.i18n._("enterRoomPassword", [ roomName ]), - _joinSubmit: $.i18n._("enterRoomPasswordSubmit") - }), true); - $("#password").focus(); - // register submit handler - $("#enter-password-form").submit(function() { - var password = $("#password").val(); - self.Chat.Modal.hide(function() { - Candy.Core.Action.Jabber.Room.Join(roomJid, password); - }); - return false; - }); - }, - /** Function: showNicknameConflictForm - * Shows a form indicating that the nickname is already taken and - * for chosing a new nickname - * - * Parameters: - * (String) roomJid - Room jid to join - */ - showNicknameConflictForm: function(roomJid) { - self.Chat.Modal.show(Mustache.to_html(Candy.View.Template.PresenceError.nicknameConflictForm, { - _labelNickname: $.i18n._("labelNickname"), - _label: $.i18n._("nicknameConflict"), - _loginSubmit: $.i18n._("loginSubmit") - })); - $("#nickname").focus(); - // register submit handler - $("#nickname-conflict-form").submit(function() { - var nickname = $("#nickname").val(); - self.Chat.Modal.hide(function() { - Candy.Core.getUser().data.nick = nickname; - Candy.Core.Action.Jabber.Room.Join(roomJid); - }); - return false; - }); - }, - /** Function: showError - * Show modal containing error message - * - * Parameters: - * (String) message - key of translation to display - * (Array) replacements - array containing replacements for translation (%s) - */ - showError: function(message, replacements) { - self.Chat.Modal.show(Mustache.to_html(Candy.View.Template.PresenceError.displayError, { - _error: $.i18n._(message, replacements) - }), true); - } - }, - /** Class: Candy.View.Pane.Tooltip - * Class to display tooltips over specific elements - */ - Tooltip: { - /** Function: show - * Show a tooltip on event.currentTarget with content specified or content within the target's attribute data-tooltip. - * - * On mouseleave on the target, hide the tooltip. - * - * Parameters: - * (Event) event - Triggered event - * (String) content - Content to display [optional] - */ - show: function(event, content) { - var tooltip = $("#tooltip"), target = $(event.currentTarget); - if (!content) { - content = target.attr("data-tooltip"); - } - if (tooltip.length === 0) { - var html = Mustache.to_html(Candy.View.Template.Chat.tooltip); - $("#chat-pane").append(html); - tooltip = $("#tooltip"); - } - $("#context-menu").hide(); - tooltip.stop(false, true); - tooltip.children("div").html(content); - var pos = target.offset(), posLeft = Candy.Util.getPosLeftAccordingToWindowBounds(tooltip, pos.left), posTop = Candy.Util.getPosTopAccordingToWindowBounds(tooltip, pos.top); - tooltip.css({ - left: posLeft.px, - top: posTop.px - }).removeClass("left-top left-bottom right-top right-bottom").addClass(posLeft.backgroundPositionAlignment + "-" + posTop.backgroundPositionAlignment).fadeIn("fast"); - target.mouseleave(function(event) { - event.stopPropagation(); - $("#tooltip").stop(false, true).fadeOut("fast", function() { - $(this).css({ - top: 0, - left: 0 - }); - }); - }); - } - }, - /** Class: Candy.View.Pane.Context - * Context menu for actions and settings - */ - Context: { - /** Function: init - * Initialize context menu and setup mouseleave handler. - */ - init: function() { - if ($("#context-menu").length === 0) { - var html = Mustache.to_html(Candy.View.Template.Chat.Context.menu); - $("#chat-pane").append(html); - $("#context-menu").mouseleave(function() { - $(this).fadeOut("fast"); - }); - } - }, - /** Function: show - * Show context menu (positions it according to the window height/width) - * - * Parameters: - * (Element) elem - On which element it should be shown - * (String) roomJid - Room Jid of the room it should be shown - * (Candy.Core.chatUser) user - User - * - * Uses: - * for getting menulinks the user has access to - * for positioning - * for positioning - * - * Triggers: - * candy:view.roster.after-context-menu using {roomJid, user, elements} - */ - show: function(elem, roomJid, user) { - elem = $(elem); - var roomId = self.Chat.rooms[roomJid].id, menu = $("#context-menu"), links = $("ul li", menu); - $("#tooltip").hide(); - // add specific context-user class if a user is available (when context menu should be opened next to a user) - if (!user) { - user = Candy.Core.getUser(); - } - links.remove(); - var menulinks = this.getMenuLinks(roomJid, user, elem), id, clickHandler = function(roomJid, user) { - return function(event) { - event.data.callback(event, roomJid, user); - $("#context-menu").hide(); - }; - }; - for (id in menulinks) { - if (menulinks.hasOwnProperty(id)) { - var link = menulinks[id], html = Mustache.to_html(Candy.View.Template.Chat.Context.menulinks, { - roomId: roomId, - "class": link["class"], - id: id, - label: link.label - }); - $("ul", menu).append(html); - $("#context-menu-" + id).bind("click", link, clickHandler(roomJid, user)); - } - } - // if `id` is set the menu is not empty - if (id) { - var pos = elem.offset(), posLeft = Candy.Util.getPosLeftAccordingToWindowBounds(menu, pos.left), posTop = Candy.Util.getPosTopAccordingToWindowBounds(menu, pos.top); - menu.css({ - left: posLeft.px, - top: posTop.px - }).removeClass("left-top left-bottom right-top right-bottom").addClass(posLeft.backgroundPositionAlignment + "-" + posTop.backgroundPositionAlignment).fadeIn("fast"); - /** Event: candy:view.roster.after-context-menu - * After context menu display - * - * Parameters: - * (String) roomJid - room where the context menu has been triggered - * (Candy.Core.ChatUser) user - User - * (jQuery.Element) element - Menu element - */ - $(Candy).triggerHandler("candy:view.roster.after-context-menu", { - roomJid: roomJid, - user: user, - element: menu - }); - return true; - } - }, - /** Function: getMenuLinks - * Extends with menu links gathered from candy:view.roster.contextmenu - * - * Parameters: - * (String) roomJid - Room in which the menu will be displayed - * (Candy.Core.ChatUser) user - User - * (jQuery.Element) elem - Parent element of the context menu - * - * Triggers: - * candy:view.roster.context-menu using {roomJid, user, elem} - * - * Returns: - * (Object) - object containing the extended menulinks. - */ - getMenuLinks: function(roomJid, user, elem) { - var menulinks, id; - var evtData = { - roomJid: roomJid, - user: user, - elem: elem, - menulinks: this.initialMenuLinks(elem) - }; - /** Event: candy:view.roster.context-menu - * Modify existing menu links (add links) - * - * In order to modify the links you need to change the object passed with an additional - * key "menulinks" containing the menulink object. - * - * Parameters: - * (String) roomJid - Room on which the menu should be displayed - * (Candy.Core.ChatUser) user - User - * (jQuery.Element) elem - Parent element of the context menu - */ - $(Candy).triggerHandler("candy:view.roster.context-menu", evtData); - menulinks = evtData.menulinks; - for (id in menulinks) { - if (menulinks.hasOwnProperty(id) && menulinks[id].requiredPermission !== undefined && !menulinks[id].requiredPermission(user, self.Room.getUser(roomJid), elem)) { - delete menulinks[id]; - } - } - return menulinks; - }, - /** Function: initialMenuLinks - * Returns initial menulinks. The following are initial: - * - * - Private Chat - * - Ignore - * - Unignore - * - Kick - * - Ban - * - Change Subject - * - * Returns: - * (Object) - object containing those menulinks - */ - initialMenuLinks: function() { - return { - "private": { - requiredPermission: function(user, me) { - return me.getNick() !== user.getNick() && Candy.Core.getRoom(Candy.View.getCurrent().roomJid) && !Candy.Core.getUser().isInPrivacyList("ignore", user.getJid()); - }, - "class": "private", - label: $.i18n._("privateActionLabel"), - callback: function(e, roomJid, user) { - $("#user-" + Candy.Util.jidToId(roomJid) + "-" + Candy.Util.jidToId(user.getJid())).click(); - } - }, - ignore: { - requiredPermission: function(user, me) { - return me.getNick() !== user.getNick() && !Candy.Core.getUser().isInPrivacyList("ignore", user.getJid()); - }, - "class": "ignore", - label: $.i18n._("ignoreActionLabel"), - callback: function(e, roomJid, user) { - Candy.View.Pane.Room.ignoreUser(roomJid, user.getJid()); - } - }, - unignore: { - requiredPermission: function(user, me) { - return me.getNick() !== user.getNick() && Candy.Core.getUser().isInPrivacyList("ignore", user.getJid()); - }, - "class": "unignore", - label: $.i18n._("unignoreActionLabel"), - callback: function(e, roomJid, user) { - Candy.View.Pane.Room.unignoreUser(roomJid, user.getJid()); - } - }, - kick: { - requiredPermission: function(user, me) { - return me.getNick() !== user.getNick() && me.isModerator() && !user.isModerator(); - }, - "class": "kick", - label: $.i18n._("kickActionLabel"), - callback: function(e, roomJid, user) { - self.Chat.Modal.show(Mustache.to_html(Candy.View.Template.Chat.Context.contextModalForm, { - _label: $.i18n._("reason"), - _submit: $.i18n._("kickActionLabel") - }), true); - $("#context-modal-field").focus(); - $("#context-modal-form").submit(function() { - Candy.Core.Action.Jabber.Room.Admin.UserAction(roomJid, user.getJid(), "kick", $("#context-modal-field").val()); - self.Chat.Modal.hide(); - return false; - }); - } - }, - ban: { - requiredPermission: function(user, me) { - return me.getNick() !== user.getNick() && me.isModerator() && !user.isModerator(); - }, - "class": "ban", - label: $.i18n._("banActionLabel"), - callback: function(e, roomJid, user) { - self.Chat.Modal.show(Mustache.to_html(Candy.View.Template.Chat.Context.contextModalForm, { - _label: $.i18n._("reason"), - _submit: $.i18n._("banActionLabel") - }), true); - $("#context-modal-field").focus(); - $("#context-modal-form").submit(function() { - Candy.Core.Action.Jabber.Room.Admin.UserAction(roomJid, user.getJid(), "ban", $("#context-modal-field").val()); - self.Chat.Modal.hide(); - return false; - }); - } - }, - subject: { - requiredPermission: function(user, me) { - return me.getNick() === user.getNick() && me.isModerator(); - }, - "class": "subject", - label: $.i18n._("setSubjectActionLabel"), - callback: function(e, roomJid) { - self.Chat.Modal.show(Mustache.to_html(Candy.View.Template.Chat.Context.contextModalForm, { - _label: $.i18n._("subject"), - _submit: $.i18n._("setSubjectActionLabel") - }), true); - $("#context-modal-field").focus(); - $("#context-modal-form").submit(function(e) { - Candy.Core.Action.Jabber.Room.Admin.SetSubject(roomJid, $("#context-modal-field").val()); - self.Chat.Modal.hide(); - e.preventDefault(); - }); - } - } - }; - }, - /** Function: showEmoticonsMenu - * Shows the special emoticons menu - * - * Parameters: - * (Element) elem - Element on which it should be positioned to. - * - * Returns: - * (Boolean) - true - */ - showEmoticonsMenu: function(elem) { - elem = $(elem); - var pos = elem.offset(), menu = $("#context-menu"), content = $("ul", menu), emoticons = "", i; - $("#tooltip").hide(); - for (i = Candy.Util.Parser.emoticons.length - 1; i >= 0; i--) { - emoticons = '' + Candy.Util.Parser.emoticons[i].plain + '' + emoticons; - } - content.html('
  • ' + emoticons + "
  • "); - content.find("img").click(function() { - var input = Candy.View.Pane.Room.getPane(Candy.View.getCurrent().roomJid, ".message-form").children(".field"), value = input.val(), emoticon = $(this).attr("alt") + " "; - input.val(value ? value + " " + emoticon : emoticon).focus(); - }); - var posLeft = Candy.Util.getPosLeftAccordingToWindowBounds(menu, pos.left), posTop = Candy.Util.getPosTopAccordingToWindowBounds(menu, pos.top); - menu.css({ - left: posLeft.px, - top: posTop.px - }).removeClass("left-top left-bottom right-top right-bottom").addClass(posLeft.backgroundPositionAlignment + "-" + posTop.backgroundPositionAlignment).fadeIn("fast"); - return true; - } - } - }; - /** Class: Candy.View.Pane.Room - * Everything which belongs to room view things belongs here. - */ - self.Room = { - /** Function: init - * Initialize a new room and inserts the room html into the DOM - * - * Parameters: - * (String) roomJid - Room JID - * (String) roomName - Room name - * (String) roomType - Type: either "groupchat" or "chat" (private chat) - * - * Uses: - * - - * - - * - - * - * Triggers: - * candy:view.room.after-add using {roomJid, type, element} - * - * Returns: - * (String) - the room id of the element created. - */ - init: function(roomJid, roomName, roomType) { - roomType = roomType || "groupchat"; - roomJid = Candy.Util.unescapeJid(roomJid); - var evtData = { - roomJid: roomJid, - type: roomType - }; - /** Event: candy:view.room.before-add - * Before initialising a room - * - * Parameters: - * (String) roomJid - Room JID - * (String) type - Room Type - * - * Returns: - * Boolean - if you don't want to initialise the room, return false. - */ - if ($(Candy).triggerHandler("candy:view.room.before-add", evtData) === false) { - return false; - } - // First room, show sound control - if (Candy.Util.isEmptyObject(self.Chat.rooms)) { - self.Chat.Toolbar.show(); - } - var roomId = Candy.Util.jidToId(roomJid); - self.Chat.rooms[roomJid] = { - id: roomId, - usercount: 0, - name: roomName, - type: roomType, - messageCount: 0, - scrollPosition: -1 - }; - $("#chat-rooms").append(Mustache.to_html(Candy.View.Template.Room.pane, { - roomId: roomId, - roomJid: roomJid, - roomType: roomType, - form: { - _messageSubmit: $.i18n._("messageSubmit") - }, - roster: { - _userOnline: $.i18n._("userOnline") - } - }, { - roster: Candy.View.Template.Roster.pane, - messages: Candy.View.Template.Message.pane, - form: Candy.View.Template.Room.form - })); - self.Chat.addTab(roomJid, roomName, roomType); - self.Room.getPane(roomJid, ".message-form").submit(self.Message.submit); - evtData.element = self.Room.getPane(roomJid); - /** Event: candy:view.room.after-add - * After initialising a room - * - * Parameters: - * (String) roomJid - Room JID - * (String) type - Room Type - * (jQuery.Element) element - Room element - */ - $(Candy).triggerHandler("candy:view.room.after-add", evtData); - return roomId; - }, - /** Function: show - * Show a specific room and hides the other rooms (if there are any) - * - * Parameters: - * (String) roomJid - room jid to show - * - * Triggers: - * candy:view.room.after-show using {roomJid, element} - * candy:view.room.after-hide using {roomJid, element} - */ - show: function(roomJid) { - var roomId = self.Chat.rooms[roomJid].id, evtData; - $(".room-pane").each(function() { - var elem = $(this); - evtData = { - roomJid: elem.attr("data-roomjid"), - element: elem - }; - if (elem.attr("id") === "chat-room-" + roomId) { - elem.show(); - Candy.View.getCurrent().roomJid = roomJid; - self.Chat.setActiveTab(roomJid); - self.Chat.Toolbar.update(roomJid); - self.Chat.clearUnreadMessages(roomJid); - self.Room.setFocusToForm(roomJid); - self.Room.scrollToBottom(roomJid); - /** Event: candy:view.room.after-show - * After showing a room - * - * Parameters: - * (String) roomJid - Room JID - * (jQuery.Element) element - Room element - */ - $(Candy).triggerHandler("candy:view.room.after-show", evtData); - } else { - elem.hide(); - /** Event: candy:view.room.after-hide - * After hiding a room - * - * Parameters: - * (String) roomJid - Room JID - * (jQuery.Element) element - Room element - */ - $(Candy).triggerHandler("candy:view.room.after-hide", evtData); - } - }); - }, - /** Function: setSubject - * Called when someone changes the subject in the channel - * - * Triggers: - * candy:view.room.after-subject-change using {roomJid, element, subject} - * - * Parameters: - * (String) roomJid - Room Jid - * (String) subject - The new subject - */ - setSubject: function(roomJid, subject) { - subject = Candy.Util.Parser.linkify(Candy.Util.Parser.escape(subject)); - var html = Mustache.to_html(Candy.View.Template.Room.subject, { - subject: subject, - roomName: self.Chat.rooms[roomJid].name, - _roomSubject: $.i18n._("roomSubject"), - time: Candy.Util.localizedTime(new Date().toGMTString()) - }); - self.Room.appendToMessagePane(roomJid, html); - self.Room.scrollToBottom(roomJid); - /** Event: candy:view.room.after-subject-change - * After changing the subject of a room - * - * Parameters: - * (String) roomJid - Room JID - * (jQuery.Element) element - Room element - * (String) subject - New subject - */ - $(Candy).triggerHandler("candy:view.room.after-subject-change", { - roomJid: roomJid, - element: self.Room.getPane(roomJid), - subject: subject - }); - }, - /** Function: close - * Close a room and remove everything in the DOM belonging to this room. - * - * NOTICE: There's a rendering bug in Opera when all rooms have been closed. - * (Take a look in the source for a more detailed description) - * - * Triggers: - * candy:view.room.after-close using {roomJid} - * - * Parameters: - * (String) roomJid - Room to close - */ - close: function(roomJid) { - self.Chat.removeTab(roomJid); - self.Window.clearUnreadMessages(); - /* TODO: - There's a rendering bug in Opera which doesn't redraw (remove) the message form. - Only a cosmetical issue (when all tabs are closed) but it's annoying... - This happens when form has no focus too. Maybe it's because of CSS positioning. - */ - self.Room.getPane(roomJid).remove(); - var openRooms = $("#chat-rooms").children(); - if (Candy.View.getCurrent().roomJid === roomJid) { - Candy.View.getCurrent().roomJid = null; - if (openRooms.length === 0) { - self.Chat.allTabsClosed(); - } else { - self.Room.show(openRooms.last().attr("data-roomjid")); - } - } - delete self.Chat.rooms[roomJid]; - /** Event: candy:view.room.after-close - * After closing a room - * - * Parameters: - * (String) roomJid - Room JID - */ - $(Candy).triggerHandler("candy:view.room.after-close", { - roomJid: roomJid - }); - }, - /** Function: appendToMessagePane - * Append a new message to the message pane. - * - * Parameters: - * (String) roomJid - Room JID - * (String) html - rendered message html - */ - appendToMessagePane: function(roomJid, html) { - self.Room.getPane(roomJid, ".message-pane").append(html); - self.Chat.rooms[roomJid].messageCount++; - self.Room.sliceMessagePane(roomJid); - }, - /** Function: sliceMessagePane - * Slices the message pane after the max amount of messages specified in the Candy View options (limit setting). - * - * This is done to hopefully prevent browsers from getting slow after a certain amount of messages in the DOM. - * - * The slice is only done when autoscroll is on, because otherwise someone might lose exactly the message he want to look for. - * - * Parameters: - * (String) roomJid - Room JID - */ - sliceMessagePane: function(roomJid) { - // Only clean if autoscroll is enabled - if (self.Window.autoscroll) { - var options = Candy.View.getOptions().messages; - if (self.Chat.rooms[roomJid].messageCount > options.limit) { - self.Room.getPane(roomJid, ".message-pane").children().slice(0, options.remove).remove(); - self.Chat.rooms[roomJid].messageCount -= options.remove; - } - } - }, - /** Function: scrollToBottom - * Scroll to bottom wrapper for to be able to disable it by overwriting the function. - * - * Parameters: - * (String) roomJid - Room JID - * - * Uses: - * - - */ - scrollToBottom: function(roomJid) { - self.Room.onScrollToBottom(roomJid); - }, - /** Function: onScrollToBottom - * Scrolls to the latest message received/sent. - * - * Parameters: - * (String) roomJid - Room JID - */ - onScrollToBottom: function(roomJid) { - var messagePane = self.Room.getPane(roomJid, ".message-pane-wrapper"); - messagePane.scrollTop(messagePane.prop("scrollHeight")); - }, - /** Function: onScrollToStoredPosition - * When autoscroll is off, the position where the scrollbar is has to be stored for each room, because it otherwise - * goes to the top in the message window. - * - * Parameters: - * (String) roomJid - Room JID - */ - onScrollToStoredPosition: function(roomJid) { - // This should only apply when entering a room... - // ... therefore we set scrollPosition to -1 after execution. - if (self.Chat.rooms[roomJid].scrollPosition > -1) { - var messagePane = self.Room.getPane(roomJid, ".message-pane-wrapper"); - messagePane.scrollTop(self.Chat.rooms[roomJid].scrollPosition); - self.Chat.rooms[roomJid].scrollPosition = -1; - } - }, - /** Function: setFocusToForm - * Set focus to the message input field within the message form. - * - * Parameters: - * (String) roomJid - Room JID - */ - setFocusToForm: function(roomJid) { - var pane = self.Room.getPane(roomJid, ".message-form"); - if (pane) { - // IE8 will fail maybe, because the field isn't there yet. - try { - pane.children(".field")[0].focus(); - } catch (e) {} - } - }, - /** Function: setUser - * Sets or updates the current user in the specified room (called by ) and set specific informations - * (roles and affiliations) on the room tab (chat-pane). - * - * Parameters: - * (String) roomJid - Room in which the user is set to. - * (Candy.Core.ChatUser) user - The user - */ - setUser: function(roomJid, user) { - self.Chat.rooms[roomJid].user = user; - var roomPane = self.Room.getPane(roomJid), chatPane = $("#chat-pane"); - roomPane.attr("data-userjid", user.getJid()); - // Set classes based on user role / affiliation - if (user.isModerator()) { - if (user.getRole() === user.ROLE_MODERATOR) { - chatPane.addClass("role-moderator"); - } - if (user.getAffiliation() === user.AFFILIATION_OWNER) { - chatPane.addClass("affiliation-owner"); - } - } else { - chatPane.removeClass("role-moderator affiliation-owner"); - } - self.Chat.Context.init(); - }, - /** Function: getUser - * Get the current user in the room specified with the jid - * - * Parameters: - * (String) roomJid - Room of which the user should be returned from - * - * Returns: - * (Candy.Core.ChatUser) - user - */ - getUser: function(roomJid) { - return self.Chat.rooms[roomJid].user; - }, - /** Function: ignoreUser - * Ignore specified user and add the ignore icon to the roster item of the user - * - * Parameters: - * (String) roomJid - Room in which the user should be ignored - * (String) userJid - User which should be ignored - */ - ignoreUser: function(roomJid, userJid) { - Candy.Core.Action.Jabber.Room.IgnoreUnignore(userJid); - Candy.View.Pane.Room.addIgnoreIcon(roomJid, userJid); - }, - /** Function: unignoreUser - * Unignore an ignored user and remove the ignore icon of the roster item. - * - * Parameters: - * (String) roomJid - Room in which the user should be unignored - * (String) userJid - User which should be unignored - */ - unignoreUser: function(roomJid, userJid) { - Candy.Core.Action.Jabber.Room.IgnoreUnignore(userJid); - Candy.View.Pane.Room.removeIgnoreIcon(roomJid, userJid); - }, - /** Function: addIgnoreIcon - * Add the ignore icon to the roster item of the specified user - * - * Parameters: - * (String) roomJid - Room in which the roster item should be updated - * (String) userJid - User of which the roster item should be updated - */ - addIgnoreIcon: function(roomJid, userJid) { - if (Candy.View.Pane.Chat.rooms[userJid]) { - $("#user-" + Candy.View.Pane.Chat.rooms[userJid].id + "-" + Candy.Util.jidToId(userJid)).addClass("status-ignored"); - } - if (Candy.View.Pane.Chat.rooms[Strophe.getBareJidFromJid(roomJid)]) { - $("#user-" + Candy.View.Pane.Chat.rooms[Strophe.getBareJidFromJid(roomJid)].id + "-" + Candy.Util.jidToId(userJid)).addClass("status-ignored"); - } - }, - /** Function: removeIgnoreIcon - * Remove the ignore icon to the roster item of the specified user - * - * Parameters: - * (String) roomJid - Room in which the roster item should be updated - * (String) userJid - User of which the roster item should be updated - */ - removeIgnoreIcon: function(roomJid, userJid) { - if (Candy.View.Pane.Chat.rooms[userJid]) { - $("#user-" + Candy.View.Pane.Chat.rooms[userJid].id + "-" + Candy.Util.jidToId(userJid)).removeClass("status-ignored"); - } - if (Candy.View.Pane.Chat.rooms[Strophe.getBareJidFromJid(roomJid)]) { - $("#user-" + Candy.View.Pane.Chat.rooms[Strophe.getBareJidFromJid(roomJid)].id + "-" + Candy.Util.jidToId(userJid)).removeClass("status-ignored"); - } - }, - /** Function: getPane - * Get the chat room pane or a subPane of it (if subPane is specified) - * - * Parameters: - * (String) roomJid - Room in which the pane lies - * (String) subPane - Sub pane of the chat room pane if needed [optional] - */ - getPane: function(roomJid, subPane) { - if (self.Chat.rooms[roomJid]) { - if (subPane) { - if (self.Chat.rooms[roomJid]["pane-" + subPane]) { - return self.Chat.rooms[roomJid]["pane-" + subPane]; - } else { - self.Chat.rooms[roomJid]["pane-" + subPane] = $("#chat-room-" + self.Chat.rooms[roomJid].id).find(subPane); - return self.Chat.rooms[roomJid]["pane-" + subPane]; - } - } else { - return $("#chat-room-" + self.Chat.rooms[roomJid].id); - } - } - }, - /** Function: changeDataUserJidIfUserIsMe - * Changes the room's data-userjid attribute if the specified user is the current user. - * - * Parameters: - * (String) roomId - Id of the room - * (Candy.Core.ChatUser) user - User - */ - changeDataUserJidIfUserIsMe: function(roomId, user) { - if (user.getNick() === Candy.Core.getUser().getNick()) { - var roomElement = $("#chat-room-" + roomId); - roomElement.attr("data-userjid", Strophe.getBareJidFromJid(roomElement.attr("data-userjid")) + "/" + user.getNick()); - } - } - }; - /** Class: Candy.View.Pane.PrivateRoom - * Private room handling - */ - self.PrivateRoom = { - /** Function: open - * Opens a new private room - * - * Parameters: - * (String) roomJid - Room jid to open - * (String) roomName - Room name - * (Boolean) switchToRoom - If true, displayed room switches automatically to this room - * (e.g. when user clicks itself on another user to open a private chat) - * (Boolean) isNoConferenceRoomJid - true if a 3rd-party client sends a direct message to this user (not via the room) - * then the username is the node and not the resource. This param addresses this case. - * - * Triggers: - * candy:view.private-room.after-open using {roomJid, type, element} - */ - open: function(roomJid, roomName, switchToRoom, isNoConferenceRoomJid) { - var user = isNoConferenceRoomJid ? Candy.Core.getUser() : self.Room.getUser(Strophe.getBareJidFromJid(roomJid)), evtData = { - roomJid: roomJid, - roomName: roomName, - type: "chat" - }; - /** Event: candy:view.private-room.before-open - * Before opening a new private room - * - * Parameters: - * (String) roomJid - Room JID - * (String) roomName - Room name - * (String) type - 'chat' - * - * Returns: - * Boolean - if you don't want to open the private room, return false - */ - if ($(Candy).triggerHandler("candy:view.private-room.before-open", evtData) === false) { - return false; - } - // if target user is in privacy list, don't open the private chat. - if (Candy.Core.getUser().isInPrivacyList("ignore", roomJid)) { - return false; - } - if (!self.Chat.rooms[roomJid]) { - if (self.Room.init(roomJid, roomName, "chat") === false) { - return false; - } - } - if (switchToRoom) { - self.Room.show(roomJid); - } - self.Roster.update(roomJid, new Candy.Core.ChatUser(roomJid, roomName), "join", user); - self.Roster.update(roomJid, user, "join", user); - self.PrivateRoom.setStatus(roomJid, "join"); - // We can't track the presence of a user if it's not a conference jid - if (isNoConferenceRoomJid) { - self.Chat.infoMessage(roomJid, $.i18n._("presenceUnknownWarningSubject"), $.i18n._("presenceUnknownWarning")); - } - evtData.element = self.Room.getPane(roomJid); - /** Event: candy:view.private-room.after-open - * After opening a new private room - * - * Parameters: - * (String) roomJid - Room JID - * (String) type - 'chat' - * (jQuery.Element) element - User element - */ - $(Candy).triggerHandler("candy:view.private-room.after-open", evtData); - }, - /** Function: setStatus - * Set offline or online status for private rooms (when one of the participants leaves the room) - * - * Parameters: - * (String) roomJid - Private room jid - * (String) status - "leave"/"join" - */ - setStatus: function(roomJid, status) { - var messageForm = self.Room.getPane(roomJid, ".message-form"); - if (status === "join") { - self.Chat.getTab(roomJid).addClass("online").removeClass("offline"); - messageForm.children(".field").removeAttr("disabled"); - messageForm.children(".submit").removeAttr("disabled"); - self.Chat.getTab(roomJid); - } else if (status === "leave") { - self.Chat.getTab(roomJid).addClass("offline").removeClass("online"); - messageForm.children(".field").attr("disabled", true); - messageForm.children(".submit").attr("disabled", true); - } - }, - /** Function: changeNick - * Changes the nick for every private room opened with this roomJid. - * - * Parameters: - * (String) roomJid - Public room jid - * (Candy.Core.ChatUser) user - User which changes his nick - */ - changeNick: function changeNick(roomJid, user) { - Candy.Core.log("[View:Pane:PrivateRoom] changeNick"); - var previousPrivateRoomJid = roomJid + "/" + user.getPreviousNick(), newPrivateRoomJid = roomJid + "/" + user.getNick(), previousPrivateRoomId = Candy.Util.jidToId(previousPrivateRoomJid), newPrivateRoomId = Candy.Util.jidToId(newPrivateRoomJid), room = self.Chat.rooms[previousPrivateRoomJid], roomElement, roomTabElement; - // it could happen that the new private room is already existing -> close it first. - // if this is not done, errors appear as two rooms would have the same id - if (self.Chat.rooms[newPrivateRoomJid]) { - self.Room.close(newPrivateRoomJid); - } - if (room) { - /* someone I talk with, changed nick */ - room.name = user.getNick(); - room.id = newPrivateRoomId; - self.Chat.rooms[newPrivateRoomJid] = room; - delete self.Chat.rooms[previousPrivateRoomJid]; - roomElement = $("#chat-room-" + previousPrivateRoomId); - if (roomElement) { - roomElement.attr("data-roomjid", newPrivateRoomJid); - roomElement.attr("id", "chat-room-" + newPrivateRoomId); - roomTabElement = $('#chat-tabs li[data-roomjid="' + previousPrivateRoomJid + '"]'); - roomTabElement.attr("data-roomjid", newPrivateRoomJid); - /* TODO: The '@' is defined in the template. Somehow we should - * extract both things into our CSS or do something else to prevent that. - */ - roomTabElement.children("a.label").text("@" + user.getNick()); - if (Candy.View.getCurrent().roomJid === previousPrivateRoomJid) { - Candy.View.getCurrent().roomJid = newPrivateRoomJid; - } - } - } else { - /* I changed the nick */ - roomElement = $('.room-pane.roomtype-chat[data-userjid="' + previousPrivateRoomJid + '"]'); - if (roomElement.length) { - previousPrivateRoomId = Candy.Util.jidToId(roomElement.attr("data-roomjid")); - roomElement.attr("data-userjid", newPrivateRoomJid); - } - } - if (roomElement && roomElement.length) { - self.Roster.changeNick(previousPrivateRoomId, user); - } - } - }; - /** Class Candy.View.Pane.Roster - * Handles everyhing regarding roster updates. - */ - self.Roster = { - /** Function: update - * Called by to update the roster if needed. - * Adds/removes users from the roster list or updates informations on their items (roles, affiliations etc.) - * - * TODO: Refactoring, this method has too much LOC. - * - * Parameters: - * (String) roomJid - Room JID in which the update happens - * (Candy.Core.ChatUser) user - User on which the update happens - * (String) action - one of "join", "leave", "kick" and "ban" - * (Candy.Core.ChatUser) currentUser - Current user - * - * Triggers: - * candy:view.roster.before-update using {roomJid, user, action, element} - * candy:view.roster.after-update using {roomJid, user, action, element} - */ - update: function(roomJid, user, action, currentUser) { - Candy.Core.log("[View:Pane:Roster] " + action); - var roomId = self.Chat.rooms[roomJid].id, userId = Candy.Util.jidToId(user.getJid()), usercountDiff = -1, userElem = $("#user-" + roomId + "-" + userId), evtData = { - roomJid: roomJid, - user: user, - action: action, - element: userElem - }; - /** Event: candy:view.roster.before-update - * Before updating the roster of a room - * - * Parameters: - * (String) roomJid - Room JID - * (Candy.Core.ChatUser) user - User - * (String) action - [join, leave, kick, ban] - * (jQuery.Element) element - User element - */ - $(Candy).triggerHandler("candy:view.roster.before-update", evtData); - // a user joined the room - if (action === "join") { - usercountDiff = 1; - var html = Mustache.to_html(Candy.View.Template.Roster.user, { - roomId: roomId, - userId: userId, - userJid: user.getJid(), - nick: user.getNick(), - displayNick: Candy.Util.crop(user.getNick(), Candy.View.getOptions().crop.roster.nickname), - role: user.getRole(), - affiliation: user.getAffiliation(), - me: currentUser !== undefined && user.getNick() === currentUser.getNick(), - tooltipRole: $.i18n._("tooltipRole"), - tooltipIgnored: $.i18n._("tooltipIgnored") - }); - if (userElem.length < 1) { - var userInserted = false, rosterPane = self.Room.getPane(roomJid, ".roster-pane"); - // there are already users in the roster - if (rosterPane.children().length > 0) { - // insert alphabetically - var userSortCompare = user.getNick().toUpperCase(); - rosterPane.children().each(function() { - var elem = $(this); - if (elem.attr("data-nick").toUpperCase() > userSortCompare) { - elem.before(html); - userInserted = true; - return false; - } - return true; - }); - } - // first user in roster - if (!userInserted) { - rosterPane.append(html); - } - self.Roster.showJoinAnimation(user, userId, roomId, roomJid, currentUser); - } else { - usercountDiff = 0; - userElem.replaceWith(html); - $("#user-" + roomId + "-" + userId).css({ - opacity: 1 - }).show(); - // it's me, update the toolbar - if (currentUser !== undefined && user.getNick() === currentUser.getNick() && self.Room.getUser(roomJid)) { - self.Chat.Toolbar.update(roomJid); - } - } - // Presence of client - if (currentUser !== undefined && currentUser.getNick() === user.getNick()) { - self.Room.setUser(roomJid, user); - } else { - $("#user-" + roomId + "-" + userId).click(self.Roster.userClick); - } - $("#user-" + roomId + "-" + userId + " .context").click(function(e) { - self.Chat.Context.show(e.currentTarget, roomJid, user); - e.stopPropagation(); - }); - // check if current user is ignoring the user who has joined. - if (currentUser !== undefined && currentUser.isInPrivacyList("ignore", user.getJid())) { - Candy.View.Pane.Room.addIgnoreIcon(roomJid, user.getJid()); - } - } else if (action === "leave") { - self.Roster.leaveAnimation("user-" + roomId + "-" + userId); - // always show leave message in private room, even if status messages have been disabled - if (self.Chat.rooms[roomJid].type === "chat") { - self.Chat.onInfoMessage(roomJid, $.i18n._("userLeftRoom", [ user.getNick() ])); - } else { - self.Chat.infoMessage(roomJid, $.i18n._("userLeftRoom", [ user.getNick() ])); - } - } else if (action === "nickchange") { - usercountDiff = 0; - self.Roster.changeNick(roomId, user); - self.Room.changeDataUserJidIfUserIsMe(roomId, user); - self.PrivateRoom.changeNick(roomJid, user); - var infoMessage = $.i18n._("userChangedNick", [ user.getPreviousNick(), user.getNick() ]); - self.Chat.onInfoMessage(roomJid, infoMessage); - } else if (action === "kick") { - self.Roster.leaveAnimation("user-" + roomId + "-" + userId); - self.Chat.onInfoMessage(roomJid, $.i18n._("userHasBeenKickedFromRoom", [ user.getNick() ])); - } else if (action === "ban") { - self.Roster.leaveAnimation("user-" + roomId + "-" + userId); - self.Chat.onInfoMessage(roomJid, $.i18n._("userHasBeenBannedFromRoom", [ user.getNick() ])); - } - // Update user count - Candy.View.Pane.Chat.rooms[roomJid].usercount += usercountDiff; - if (roomJid === Candy.View.getCurrent().roomJid) { - Candy.View.Pane.Chat.Toolbar.updateUsercount(Candy.View.Pane.Chat.rooms[roomJid].usercount); - } - // in case there's been a join, the element is now there (previously not) - evtData.element = $("#user-" + roomId + "-" + userId); - /** Event: candy:view.roster.after-update - * After updating a room's roster - * - * Parameters: - * (String) roomJid - Room JID - * (Candy.Core.ChatUser) user - User - * (String) action - [join, leave, kick, ban] - * (jQuery.Element) element - User element - */ - $(Candy).triggerHandler("candy:view.roster.after-update", evtData); - }, - /** Function: userClick - * Click handler for opening a private room - */ - userClick: function() { - var elem = $(this); - self.PrivateRoom.open(elem.attr("data-jid"), elem.attr("data-nick"), true); - }, - /** Function: showJoinAnimation - * Shows join animation if needed - * - * FIXME: Refactor. Part of this will be done by the big room improvements - */ - showJoinAnimation: function(user, userId, roomId, roomJid, currentUser) { - // don't show if the user has recently changed the nickname. - var rosterUserId = "user-" + roomId + "-" + userId, $rosterUserElem = $("#" + rosterUserId); - if (!user.getPreviousNick() || !$rosterUserElem || $rosterUserElem.is(":visible") === false) { - self.Roster.joinAnimation(rosterUserId); - // only show other users joining & don't show if there's no message in the room. - if (currentUser !== undefined && user.getNick() !== currentUser.getNick() && self.Room.getUser(roomJid)) { - // always show join message in private room, even if status messages have been disabled - if (self.Chat.rooms[roomJid].type === "chat") { - self.Chat.onInfoMessage(roomJid, $.i18n._("userJoinedRoom", [ user.getNick() ])); - } else { - self.Chat.infoMessage(roomJid, $.i18n._("userJoinedRoom", [ user.getNick() ])); - } - } - } - }, - /** Function: joinAnimation - * Animates specified elementId on join - * - * Parameters: - * (String) elementId - Specific element to do the animation on - */ - joinAnimation: function(elementId) { - $("#" + elementId).stop(true).slideDown("normal", function() { - $(this).animate({ - opacity: 1 - }); - }); - }, - /** Function: leaveAnimation - * Leave animation for specified element id and removes the DOM element on completion. - * - * Parameters: - * (String) elementId - Specific element to do the animation on - */ - leaveAnimation: function(elementId) { - $("#" + elementId).stop(true).attr("id", "#" + elementId + "-leaving").animate({ - opacity: 0 - }, { - complete: function() { - $(this).slideUp("normal", function() { - $(this).remove(); - }); - } - }); - }, - /** Function: changeNick - * Change nick of an existing user in the roster - * - * UserId has to be recalculated from the user because at the time of this call, - * the user is already set with the new jid & nick. - * - * Parameters: - * (String) roomId - Id of the room - * (Candy.Core.ChatUser) user - User object - */ - changeNick: function(roomId, user) { - Candy.Core.log("[View:Pane:Roster] changeNick"); - var previousUserJid = Strophe.getBareJidFromJid(user.getJid()) + "/" + user.getPreviousNick(), elementId = "user-" + roomId + "-" + Candy.Util.jidToId(previousUserJid), el = $("#" + elementId); - el.attr("data-nick", user.getNick()); - el.attr("data-jid", user.getJid()); - el.children("div.label").text(user.getNick()); - el.attr("id", "user-" + roomId + "-" + Candy.Util.jidToId(user.getJid())); - } - }; - /** Class: Candy.View.Pane.Message - * Message submit/show handling - */ - self.Message = { - /** Function: submit - * on submit handler for message field sends the message to the server and if it's a private chat, shows the message - * immediately because the server doesn't send back those message. - * - * Parameters: - * (Event) event - Triggered event - * - * Triggers: - * candy:view.message.before-send using {message} - * - * FIXME: as everywhere, `roomJid` might be slightly incorrect in this case - * - maybe rename this as part of a refactoring. - */ - submit: function(event) { - var roomJid = Candy.View.getCurrent().roomJid, roomType = Candy.View.Pane.Chat.rooms[roomJid].type, message = $(this).children(".field").val().substring(0, Candy.View.getOptions().crop.message.body), xhtmlMessage, evtData = { - roomJid: roomJid, - message: message, - xhtmlMessage: xhtmlMessage - }; - /** Event: candy:view.message.before-send - * Before sending a message - * - * Parameters: - * (String) roomJid - room to which the message should be sent - * (String) message - Message text - * (String) xhtmlMessage - XHTML formatted message [default: undefined] - * - * Returns: - * Boolean|undefined - if you like to stop sending the message, return false. - */ - if ($(Candy).triggerHandler("candy:view.message.before-send", evtData) === false) { - event.preventDefault(); - return; - } - message = evtData.message; - xhtmlMessage = evtData.xhtmlMessage; - Candy.Core.Action.Jabber.Room.Message(roomJid, message, roomType, xhtmlMessage); - // Private user chat. Jabber won't notify the user who has sent the message. Just show it as the user hits the button... - if (roomType === "chat" && message) { - self.Message.show(roomJid, self.Room.getUser(roomJid).getNick(), message); - } - // Clear input and set focus to it - $(this).children(".field").val("").focus(); - event.preventDefault(); - }, - /** Function: show - * Show a message in the message pane - * - * Parameters: - * (String) roomJid - room in which the message has been sent to - * (String) name - Name of the user which sent the message - * (String) message - Message - * (String) xhtmlMessage - XHTML formatted message [if options enableXHTML is true] - * (String) timestamp - [optional] Timestamp of the message, if not present, current date. - * - * Triggers: - * candy:view.message.before-show using {roomJid, name, message} - * candy.view.message.before-render using {template, templateData} - * candy:view.message.after-show using {roomJid, name, message, element} - */ - show: function(roomJid, name, message, xhtmlMessage, timestamp) { - message = Candy.Util.Parser.all(message.substring(0, Candy.View.getOptions().crop.message.body)); - if (xhtmlMessage) { - xhtmlMessage = Candy.Util.parseAndCropXhtml(xhtmlMessage, Candy.View.getOptions().crop.message.body); - } - var evtData = { - roomJid: roomJid, - name: name, - message: message, - xhtmlMessage: xhtmlMessage - }; - /** Event: candy:view.message.before-show - * Before showing a new message - * - * Parameters: - * (String) roomJid - Room JID - * (String) name - Name of the sending user - * (String) message - Message text - * - * Returns: - * Boolean - if you don't want to show the message, return false - */ - if ($(Candy).triggerHandler("candy:view.message.before-show", evtData) === false) { - return; - } - message = evtData.message; - xhtmlMessage = evtData.xhtmlMessage; - if (xhtmlMessage !== undefined && xhtmlMessage.length > 0) { - message = xhtmlMessage; - } - if (!message) { - return; - } - var renderEvtData = { - template: Candy.View.Template.Message.item, - templateData: { - name: name, - displayName: Candy.Util.crop(name, Candy.View.getOptions().crop.message.nickname), - message: message, - time: Candy.Util.localizedTime(timestamp || new Date().toGMTString()) - } - }; - /** Event: candy:view.message.before-render - * Before rendering the message element - * - * Parameters: - * (String) template - Template to use - * (Object) templateData - Template data consists of: - * - (String) name - Name of the sending user - * - (String) displayName - Cropped name of the sending user - * - (String) message - Message text - * - (String) time - Localized time - */ - $(Candy).triggerHandler("candy:view.message.before-render", renderEvtData); - var html = Mustache.to_html(renderEvtData.template, renderEvtData.templateData); - self.Room.appendToMessagePane(roomJid, html); - var elem = self.Room.getPane(roomJid, ".message-pane").children().last(); - // click on username opens private chat - elem.find("a.label").click(function(event) { - event.preventDefault(); - // Check if user is online and not myself - var room = Candy.Core.getRoom(roomJid); - if (room && name !== self.Room.getUser(Candy.View.getCurrent().roomJid).getNick() && room.getRoster().get(roomJid + "/" + name)) { - if (Candy.View.Pane.PrivateRoom.open(roomJid + "/" + name, name, true) === false) { - return false; - } - } - }); - // Notify the user about a new private message - if (Candy.View.getCurrent().roomJid !== roomJid || !self.Window.hasFocus()) { - self.Chat.increaseUnreadMessages(roomJid); - if (Candy.View.Pane.Chat.rooms[roomJid].type === "chat" && !self.Window.hasFocus()) { - self.Chat.Toolbar.playSound(); - } - } - if (Candy.View.getCurrent().roomJid === roomJid) { - self.Room.scrollToBottom(roomJid); - } - evtData.element = elem; - /** Event: candy:view.message.after-show - * Triggered after showing a message - * - * Parameters: - * (String) roomJid - Room JID - * (jQuery.Element) element - User element - * (String) name - Name of the sending user - * (String) message - Message text - */ - $(Candy).triggerHandler("candy:view.message.after-show", evtData); - } - }; - return self; -}(Candy.View.Pane || {}, jQuery); - -/** File: template.js - * Candy - Chats are not dead yet. - * - * Authors: - * - Patrick Stadler - * - Michael Weibel - * - * Copyright: - * (c) 2011 Amiado Group AG. All rights reserved. - * (c) 2012-2014 Patrick Stadler & Michael Weibel. All rights reserved. - */ -"use strict"; - -/* global Candy */ -/** Class: Candy.View.Template - * Contains mustache.js templates - */ -Candy.View.Template = function(self) { - self.Window = { - /** - * Unread messages - used to extend the window title - */ - unreadmessages: "({{count}}) {{title}}" - }; - self.Chat = { - pane: '
    {{> tabs}}{{> toolbar}}{{> rooms}}
    {{> modal}}', - rooms: '
    ', - tabs: '
      ', - tab: '
    • ' + '{{#privateUserChat}}@{{/privateUserChat}}{{name}}' + '×' + '
    • ', - modal: '
      ×' + '' + '' + '
      ', - adminMessage: '
    • {{time}}
      ' + '{{sender}}' + '{{subject}} {{message}}
    • ', - infoMessage: '
    • {{time}}
      ' + '{{subject}} {{message}}
    • ', - toolbar: '
        ' + '
      • ' + '
      • {{> soundcontrol}}
      • ' + '
      • ' + '
      • ' + '
      • ' + '
      • ' + '
      ', - soundcontrol: '' + "", - Context: { - menu: '
      ' + '
        ', - menulinks: '
      • {{label}}
      • ', - contextModalForm: '
        ' + '' + '' + '
        ', - adminMessageReason: '×' + "

        {{_action}}

        {{#reason}}

        {{_reason}}

        {{/reason}}" - }, - tooltip: '
        ' + '
        ' - }; - self.Room = { - pane: '
        ' + "{{> roster}}{{> messages}}{{> form}}
        ", - subject: '
      • {{time}}
        ' + '{{roomName}}' + '{{_roomSubject}} {{{subject}}}
      • ', - form: '
        ' + '
        ' + '' + '
        ' - }; - self.Roster = { - pane: '
        ', - user: '
        ' + '
        {{displayNick}}
          ' + '
        • ' + '
        • ' + '
        ' - }; - self.Message = { - pane: '
          ', - item: "
        • {{time}}
          " + '{{displayName}}' + '{{{message}}}
        • ' - }; - self.Login = { - form: '' - }; - self.PresenceError = { - enterPasswordForm: "{{_label}}" + '
          ' + '' + '
          ', - nicknameConflictForm: "{{_label}}" + '
          ' + '' + '
          ', - displayError: "{{_error}}" - }; - return self; -}(Candy.View.Template || {}); - -/** File: translation.js - * Candy - Chats are not dead yet. - * - * Authors: - * - Patrick Stadler - * - Michael Weibel - * - * Copyright: - * (c) 2011 Amiado Group AG. All rights reserved. - * (c) 2012-2014 Patrick Stadler & Michael Weibel. All rights reserved. - */ -"use strict"; - -/* global Candy */ -/** Class: Candy.View.Translation - * Contains translations - */ -Candy.View.Translation = { - en: { - status: "Status: %s", - statusConnecting: "Connecting...", - statusConnected: "Connected", - statusDisconnecting: "Disconnecting...", - statusDisconnected: "Disconnected", - statusAuthfail: "Authentication failed", - roomSubject: "Subject:", - messageSubmit: "Send", - labelUsername: "Username:", - labelNickname: "Nickname:", - labelPassword: "Password:", - loginSubmit: "Login", - loginInvalid: "Invalid JID", - reason: "Reason:", - subject: "Subject:", - reasonWas: "Reason was: %s.", - kickActionLabel: "Kick", - youHaveBeenKickedBy: "You have been kicked from %2$s by %1$s", - youHaveBeenKicked: "You have been kicked from %s", - banActionLabel: "Ban", - youHaveBeenBannedBy: "You have been banned from %1$s by %2$s", - youHaveBeenBanned: "You have been banned from %s", - privateActionLabel: "Private chat", - ignoreActionLabel: "Ignore", - unignoreActionLabel: "Unignore", - setSubjectActionLabel: "Change Subject", - administratorMessageSubject: "Administrator", - userJoinedRoom: "%s joined the room.", - userLeftRoom: "%s left the room.", - userHasBeenKickedFromRoom: "%s has been kicked from the room.", - userHasBeenBannedFromRoom: "%s has been banned from the room.", - userChangedNick: "%1$s has changed his nickname to %2$s.", - presenceUnknownWarningSubject: "Notice:", - presenceUnknownWarning: "This user might be offline. We can't track his presence.", - dateFormat: "dd.mm.yyyy", - timeFormat: "HH:MM:ss", - tooltipRole: "Moderator", - tooltipIgnored: "You ignore this user", - tooltipEmoticons: "Emoticons", - tooltipSound: "Play sound for new private messages", - tooltipAutoscroll: "Autoscroll", - tooltipStatusmessage: "Display status messages", - tooltipAdministration: "Room Administration", - tooltipUsercount: "Room Occupants", - enterRoomPassword: 'Room "%s" is password protected.', - enterRoomPasswordSubmit: "Join room", - passwordEnteredInvalid: 'Invalid password for room "%s".', - nicknameConflict: "Username already in use. Please choose another one.", - errorMembersOnly: 'You can\'t join room "%s": Insufficient rights.', - errorMaxOccupantsReached: 'You can\'t join room "%s": Too many occupants.', - errorAutojoinMissing: "No autojoin parameter set in configuration. Please set one to continue.", - antiSpamMessage: "Please do not spam. You have been blocked for a short-time." - }, - de: { - status: "Status: %s", - statusConnecting: "Verbinden...", - statusConnected: "Verbunden", - statusDisconnecting: "Verbindung trennen...", - statusDisconnected: "Verbindung getrennt", - statusAuthfail: "Authentifizierung fehlgeschlagen", - roomSubject: "Thema:", - messageSubmit: "Senden", - labelUsername: "Benutzername:", - labelNickname: "Spitzname:", - labelPassword: "Passwort:", - loginSubmit: "Anmelden", - loginInvalid: "Ungültige JID", - reason: "Begründung:", - subject: "Titel:", - reasonWas: "Begründung: %s.", - kickActionLabel: "Kick", - youHaveBeenKickedBy: "Du wurdest soeben aus dem Raum %1$s gekickt (%2$s)", - youHaveBeenKicked: "Du wurdest soeben aus dem Raum %s gekickt", - banActionLabel: "Ban", - youHaveBeenBannedBy: "Du wurdest soeben aus dem Raum %1$s verbannt (%2$s)", - youHaveBeenBanned: "Du wurdest soeben aus dem Raum %s verbannt", - privateActionLabel: "Privater Chat", - ignoreActionLabel: "Ignorieren", - unignoreActionLabel: "Nicht mehr ignorieren", - setSubjectActionLabel: "Thema ändern", - administratorMessageSubject: "Administrator", - userJoinedRoom: "%s hat soeben den Raum betreten.", - userLeftRoom: "%s hat soeben den Raum verlassen.", - userHasBeenKickedFromRoom: "%s ist aus dem Raum gekickt worden.", - userHasBeenBannedFromRoom: "%s ist aus dem Raum verbannt worden.", - userChangedNick: "%1$s hat den Nicknamen zu %2$s geändert.", - presenceUnknownWarningSubject: "Hinweis:", - presenceUnknownWarning: "Dieser Benutzer könnte bereits abgemeldet sein. Wir können seine Anwesenheit nicht verfolgen.", - dateFormat: "dd.mm.yyyy", - timeFormat: "HH:MM:ss", - tooltipRole: "Moderator", - tooltipIgnored: "Du ignorierst diesen Benutzer", - tooltipEmoticons: "Smileys", - tooltipSound: "Ton abspielen bei neuen privaten Nachrichten", - tooltipAutoscroll: "Autoscroll", - tooltipStatusmessage: "Statusnachrichten anzeigen", - tooltipAdministration: "Raum Administration", - tooltipUsercount: "Anzahl Benutzer im Raum", - enterRoomPassword: 'Raum "%s" ist durch ein Passwort geschützt.', - enterRoomPasswordSubmit: "Raum betreten", - passwordEnteredInvalid: 'Inkorrektes Passwort für Raum "%s".', - nicknameConflict: "Der Benutzername wird bereits verwendet. Bitte wähle einen anderen.", - errorMembersOnly: 'Du kannst den Raum "%s" nicht betreten: Ungenügende Rechte.', - errorMaxOccupantsReached: 'Du kannst den Raum "%s" nicht betreten: Benutzerlimit erreicht.', - errorAutojoinMissing: 'Keine "autojoin" Konfiguration gefunden. Bitte setze eine konfiguration um fortzufahren.', - antiSpamMessage: "Bitte nicht spammen. Du wurdest für eine kurze Zeit blockiert." - }, - fr: { - status: "Status : %s", - statusConnecting: "Connexion…", - statusConnected: "Connecté.", - statusDisconnecting: "Déconnexion…", - statusDisconnected: "Déconnecté.", - statusAuthfail: "L'authentification a échoué", - roomSubject: "Sujet :", - messageSubmit: "Envoyer", - labelUsername: "Nom d'utilisateur :", - labelPassword: "Mot de passe :", - loginSubmit: "Connexion", - loginInvalid: "JID invalide", - reason: "Motif :", - subject: "Titre :", - reasonWas: "Motif : %s.", - kickActionLabel: "Kick", - youHaveBeenKickedBy: "Vous avez été expulsé du salon %1$s (%2$s)", - youHaveBeenKicked: "Vous avez été expulsé du salon %s", - banActionLabel: "Ban", - youHaveBeenBannedBy: "Vous avez été banni du salon %1$s (%2$s)", - youHaveBeenBanned: "Vous avez été banni du salon %s", - privateActionLabel: "Chat privé", - ignoreActionLabel: "Ignorer", - unignoreActionLabel: "Ne plus ignorer", - setSubjectActionLabel: "Changer le sujet", - administratorMessageSubject: "Administrateur", - userJoinedRoom: "%s vient d'entrer dans le salon.", - userLeftRoom: "%s vient de quitter le salon.", - userHasBeenKickedFromRoom: "%s a été expulsé du salon.", - userHasBeenBannedFromRoom: "%s a été banni du salon.", - presenceUnknownWarningSubject: "Note :", - presenceUnknownWarning: "Cet utilisateur n'est malheureusement plus connecté, le message ne sera pas envoyé.", - dateFormat: "dd/mm/yyyy", - timeFormat: "HH:MM:ss", - tooltipRole: "Modérateur", - tooltipIgnored: "Vous ignorez cette personne", - tooltipEmoticons: "Smileys", - tooltipSound: "Jouer un son lors de la réception de nouveaux messages privés", - tooltipAutoscroll: "Défilement automatique", - tooltipStatusmessage: "Messages d'état", - tooltipAdministration: "Administration du salon", - tooltipUsercount: "Nombre d'utilisateurs dans le salon", - enterRoomPassword: 'Le salon "%s" est protégé par un mot de passe.', - enterRoomPasswordSubmit: "Entrer dans le salon", - passwordEnteredInvalid: 'Le mot de passe pour le salon "%s" est invalide.', - nicknameConflict: "Le nom d'utilisateur est déjà utilisé. Veuillez en choisir un autre.", - errorMembersOnly: 'Vous ne pouvez pas entrer dans le salon "%s" : droits insuffisants.', - errorMaxOccupantsReached: 'Vous ne pouvez pas entrer dans le salon "%s": Limite d\'utilisateur atteint.', - antiSpamMessage: "Merci de ne pas envoyer de spam. Vous avez été bloqué pendant une courte période.." - }, - nl: { - status: "Status: %s", - statusConnecting: "Verbinding maken...", - statusConnected: "Verbinding is gereed", - statusDisconnecting: "Verbinding verbreken...", - statusDisconnected: "Verbinding is verbroken", - statusAuthfail: "Authenticatie is mislukt", - roomSubject: "Onderwerp:", - messageSubmit: "Verstuur", - labelUsername: "Gebruikersnaam:", - labelPassword: "Wachtwoord:", - loginSubmit: "Inloggen", - loginInvalid: "JID is onjuist", - reason: "Reden:", - subject: "Onderwerp:", - reasonWas: "De reden was: %s.", - kickActionLabel: "Verwijderen", - youHaveBeenKickedBy: "Je bent verwijderd van %1$s door %2$s", - youHaveBeenKicked: "Je bent verwijderd van %s", - banActionLabel: "Blokkeren", - youHaveBeenBannedBy: "Je bent geblokkeerd van %1$s door %2$s", - youHaveBeenBanned: "Je bent geblokkeerd van %s", - privateActionLabel: "Prive gesprek", - ignoreActionLabel: "Negeren", - unignoreActionLabel: "Niet negeren", - setSubjectActionLabel: "Onderwerp wijzigen", - administratorMessageSubject: "Beheerder", - userJoinedRoom: "%s komt de chat binnen.", - userLeftRoom: "%s heeft de chat verlaten.", - userHasBeenKickedFromRoom: "%s is verwijderd.", - userHasBeenBannedFromRoom: "%s is geblokkeerd.", - presenceUnknownWarningSubject: "Mededeling:", - presenceUnknownWarning: "Deze gebruiker is waarschijnlijk offline, we kunnen zijn/haar aanwezigheid niet vaststellen.", - dateFormat: "dd.mm.yyyy", - timeFormat: "HH:MM:ss", - tooltipRole: "Moderator", - tooltipIgnored: "Je negeert deze gebruiker", - tooltipEmoticons: "Emotie-iconen", - tooltipSound: "Speel een geluid af bij nieuwe privé berichten.", - tooltipAutoscroll: "Automatisch scrollen", - tooltipStatusmessage: "Statusberichten weergeven", - tooltipAdministration: "Instellingen", - tooltipUsercount: "Gebruikers", - enterRoomPassword: 'De Chatroom "%s" is met een wachtwoord beveiligd.', - enterRoomPasswordSubmit: "Ga naar Chatroom", - passwordEnteredInvalid: 'Het wachtwoord voor de Chatroom "%s" is onjuist.', - nicknameConflict: "De gebruikersnaam is reeds in gebruik. Probeer a.u.b. een andere gebruikersnaam.", - errorMembersOnly: 'Je kunt niet deelnemen aan de Chatroom "%s": Je hebt onvoldoende rechten.', - errorMaxOccupantsReached: 'Je kunt niet deelnemen aan de Chatroom "%s": Het maximum aantal gebruikers is bereikt.', - antiSpamMessage: "Het is niet toegestaan om veel berichten naar de server te versturen. Je bent voor een korte periode geblokkeerd." - }, - es: { - status: "Estado: %s", - statusConnecting: "Conectando...", - statusConnected: "Conectado", - statusDisconnecting: "Desconectando...", - statusDisconnected: "Desconectado", - statusAuthfail: "Falló la autenticación", - roomSubject: "Asunto:", - messageSubmit: "Enviar", - labelUsername: "Usuario:", - labelPassword: "Clave:", - loginSubmit: "Entrar", - loginInvalid: "JID no válido", - reason: "Razón:", - subject: "Asunto:", - reasonWas: "La razón fue: %s.", - kickActionLabel: "Expulsar", - youHaveBeenKickedBy: "Has sido expulsado de %1$s por %2$s", - youHaveBeenKicked: "Has sido expulsado de %s", - banActionLabel: "Prohibir", - youHaveBeenBannedBy: "Has sido expulsado permanentemente de %1$s por %2$s", - youHaveBeenBanned: "Has sido expulsado permanentemente de %s", - privateActionLabel: "Chat privado", - ignoreActionLabel: "Ignorar", - unignoreActionLabel: "No ignorar", - setSubjectActionLabel: "Cambiar asunto", - administratorMessageSubject: "Administrador", - userJoinedRoom: "%s se ha unido a la sala.", - userLeftRoom: "%s ha dejado la sala.", - userHasBeenKickedFromRoom: "%s ha sido expulsado de la sala.", - userHasBeenBannedFromRoom: "%s ha sido expulsado permanentemente de la sala.", - presenceUnknownWarningSubject: "Atención:", - presenceUnknownWarning: "Éste usuario podría estar desconectado..", - dateFormat: "dd.mm.yyyy", - timeFormat: "HH:MM:ss", - tooltipRole: "Moderador", - tooltipIgnored: "Ignoras a éste usuario", - tooltipEmoticons: "Emoticonos", - tooltipSound: "Reproducir un sonido para nuevos mensajes privados", - tooltipAutoscroll: "Desplazamiento automático", - tooltipStatusmessage: "Mostrar mensajes de estado", - tooltipAdministration: "Administración de la sala", - tooltipUsercount: "Usuarios en la sala", - enterRoomPassword: 'La sala "%s" está protegida mediante contraseña.', - enterRoomPasswordSubmit: "Unirse a la sala", - passwordEnteredInvalid: 'Contraseña incorrecta para la sala "%s".', - nicknameConflict: "El nombre de usuario ya está siendo utilizado. Por favor elija otro.", - errorMembersOnly: 'No se puede unir a la sala "%s": no tiene privilegios suficientes.', - errorMaxOccupantsReached: 'No se puede unir a la sala "%s": demasiados participantes.', - antiSpamMessage: "Por favor, no hagas spam. Has sido bloqueado temporalmente." - }, - cn: { - status: "状态: %s", - statusConnecting: "连接中...", - statusConnected: "已连接", - statusDisconnecting: "断开连接中...", - statusDisconnected: "已断开连接", - statusAuthfail: "认证失败", - roomSubject: "主题:", - messageSubmit: "发送", - labelUsername: "用户名:", - labelPassword: "密码:", - loginSubmit: "登录", - loginInvalid: "用户名不合法", - reason: "原因:", - subject: "主题:", - reasonWas: "原因是: %s.", - kickActionLabel: "踢除", - youHaveBeenKickedBy: "你在 %1$s 被管理者 %2$s 请出房间", - banActionLabel: "禁言", - youHaveBeenBannedBy: "你在 %1$s 被管理者 %2$s 禁言", - privateActionLabel: "单独对话", - ignoreActionLabel: "忽略", - unignoreActionLabel: "不忽略", - setSubjectActionLabel: "变更主题", - administratorMessageSubject: "管理员", - userJoinedRoom: "%s 加入房间", - userLeftRoom: "%s 离开房间", - userHasBeenKickedFromRoom: "%s 被请出这个房间", - userHasBeenBannedFromRoom: "%s 被管理者禁言", - presenceUnknownWarningSubject: "注意:", - presenceUnknownWarning: "这个会员可能已经下线,不能追踪到他的连接信息", - dateFormat: "dd.mm.yyyy", - timeFormat: "HH:MM:ss", - tooltipRole: "管理", - tooltipIgnored: "你忽略了这个会员", - tooltipEmoticons: "表情", - tooltipSound: "新消息发音", - tooltipAutoscroll: "滚动条", - tooltipStatusmessage: "禁用状态消息", - tooltipAdministration: "房间管理", - tooltipUsercount: "房间占有者", - enterRoomPassword: '登录房间 "%s" 需要密码.', - enterRoomPasswordSubmit: "加入房间", - passwordEnteredInvalid: '登录房间 "%s" 的密码不正确', - nicknameConflict: "用户名已经存在,请另选一个", - errorMembersOnly: '您的权限不够,不能登录房间 "%s" ', - errorMaxOccupantsReached: '房间 "%s" 的人数已达上限,您不能登录', - antiSpamMessage: "因为您在短时间内发送过多的消息 服务器要阻止您一小段时间。" - }, - ja: { - status: "ステータス: %s", - statusConnecting: "接続中…", - statusConnected: "接続されました", - statusDisconnecting: "ディスコネクト中…", - statusDisconnected: "ディスコネクトされました", - statusAuthfail: "認証に失敗しました", - roomSubject: "トピック:", - messageSubmit: "送信", - labelUsername: "ユーザーネーム:", - labelPassword: "パスワード:", - loginSubmit: "ログイン", - loginInvalid: "ユーザーネームが正しくありません", - reason: "理由:", - subject: "トピック:", - reasonWas: "理由: %s。", - kickActionLabel: "キック", - youHaveBeenKickedBy: "あなたは%2$sにより%1$sからキックされました。", - youHaveBeenKicked: "あなたは%sからキックされました。", - banActionLabel: "アカウントバン", - youHaveBeenBannedBy: "あなたは%2$sにより%1$sからアカウントバンされました。", - youHaveBeenBanned: "あなたは%sからアカウントバンされました。", - privateActionLabel: "プライベートメッセージ", - ignoreActionLabel: "無視する", - unignoreActionLabel: "無視をやめる", - setSubjectActionLabel: "トピックを変える", - administratorMessageSubject: "管理者", - userJoinedRoom: "%sは入室しました。", - userLeftRoom: "%sは退室しました。", - userHasBeenKickedFromRoom: "%sは部屋からキックされました。", - userHasBeenBannedFromRoom: "%sは部屋からアカウントバンされました。", - presenceUnknownWarningSubject: "忠告:", - presenceUnknownWarning: "このユーザーのステータスは不明です。", - dateFormat: "dd.mm.yyyy", - timeFormat: "HH:MM:ss", - tooltipRole: "モデレーター", - tooltipIgnored: "このユーザーを無視設定にしている", - tooltipEmoticons: "絵文字", - tooltipSound: "新しいメッセージが届くたびに音を鳴らす", - tooltipAutoscroll: "オートスクロール", - tooltipStatusmessage: "ステータスメッセージを表示", - tooltipAdministration: "部屋の管理", - tooltipUsercount: "この部屋の参加者の数", - enterRoomPassword: '"%s"の部屋に入るにはパスワードが必要です。', - enterRoomPasswordSubmit: "部屋に入る", - passwordEnteredInvalid: '"%s"のパスワードと異なるパスワードを入力しました。', - nicknameConflict: "このユーザーネームはすでに利用されているため、別のユーザーネームを選んでください。", - errorMembersOnly: '"%s"の部屋に入ることができません: 利用権限を満たしていません。', - errorMaxOccupantsReached: '"%s"の部屋に入ることができません: 参加者の数はすでに上限に達しました。', - antiSpamMessage: "スパムなどの行為はやめてください。あなたは一時的にブロックされました。" - }, - sv: { - status: "Status: %s", - statusConnecting: "Ansluter...", - statusConnected: "Ansluten", - statusDisconnecting: "Kopplar från...", - statusDisconnected: "Frånkopplad", - statusAuthfail: "Autentisering misslyckades", - roomSubject: "Ämne:", - messageSubmit: "Skicka", - labelUsername: "Användarnamn:", - labelPassword: "Lösenord:", - loginSubmit: "Logga in", - loginInvalid: "Ogiltigt JID", - reason: "Anledning:", - subject: "Ämne:", - reasonWas: "Anledningen var: %s.", - kickActionLabel: "Sparka ut", - youHaveBeenKickedBy: "Du har blivit utsparkad från %2$s av %1$s", - youHaveBeenKicked: "Du har blivit utsparkad från %s", - banActionLabel: "Bannlys", - youHaveBeenBannedBy: "Du har blivit bannlyst från %1$s av %2$s", - youHaveBeenBanned: "Du har blivit bannlyst från %s", - privateActionLabel: "Privat chatt", - ignoreActionLabel: "Blockera", - unignoreActionLabel: "Avblockera", - setSubjectActionLabel: "Ändra ämne", - administratorMessageSubject: "Administratör", - userJoinedRoom: "%s kom in i rummet.", - userLeftRoom: "%s har lämnat rummet.", - userHasBeenKickedFromRoom: "%s har blivit utsparkad ur rummet.", - userHasBeenBannedFromRoom: "%s har blivit bannlyst från rummet.", - presenceUnknownWarningSubject: "Notera:", - presenceUnknownWarning: "Denna användare kan vara offline. Vi kan inte följa dennes närvaro.", - dateFormat: "yyyy-mm-dd", - timeFormat: "HH:MM:ss", - tooltipRole: "Moderator", - tooltipIgnored: "Du blockerar denna användare", - tooltipEmoticons: "Smilies", - tooltipSound: "Spela upp ett ljud vid nytt privat meddelande", - tooltipAutoscroll: "Autoskrolla", - tooltipStatusmessage: "Visa statusmeddelanden", - tooltipAdministration: "Rumadministrering", - tooltipUsercount: "Antal användare i rummet", - enterRoomPassword: 'Rummet "%s" är lösenordsskyddat.', - enterRoomPasswordSubmit: "Anslut till rum", - passwordEnteredInvalid: 'Ogiltigt lösenord för rummet "%s".', - nicknameConflict: "Upptaget användarnamn. Var god välj ett annat.", - errorMembersOnly: 'Du kan inte ansluta till rummet "%s": Otillräckliga rättigheter.', - errorMaxOccupantsReached: 'Du kan inte ansluta till rummet "%s": Rummet är fullt.', - antiSpamMessage: "Var god avstå från att spamma. Du har blivit blockerad för en kort stund." - }, - it: { - status: "Stato: %s", - statusConnecting: "Connessione...", - statusConnected: "Connessione", - statusDisconnecting: "Disconnessione...", - statusDisconnected: "Disconnesso", - statusAuthfail: "Autenticazione fallita", - roomSubject: "Oggetto:", - messageSubmit: "Invia", - labelUsername: "Nome utente:", - labelPassword: "Password:", - loginSubmit: "Login", - loginInvalid: "JID non valido", - reason: "Ragione:", - subject: "Oggetto:", - reasonWas: "Ragione precedente: %s.", - kickActionLabel: "Espelli", - youHaveBeenKickedBy: "Sei stato espulso da %2$s da %1$s", - youHaveBeenKicked: "Sei stato espulso da %s", - banActionLabel: "Escluso", - youHaveBeenBannedBy: "Sei stato escluso da %1$s da %2$s", - youHaveBeenBanned: "Sei stato escluso da %s", - privateActionLabel: "Stanza privata", - ignoreActionLabel: "Ignora", - unignoreActionLabel: "Non ignorare", - setSubjectActionLabel: "Cambia oggetto", - administratorMessageSubject: "Amministratore", - userJoinedRoom: "%s si è unito alla stanza.", - userLeftRoom: "%s ha lasciato la stanza.", - userHasBeenKickedFromRoom: "%s è stato espulso dalla stanza.", - userHasBeenBannedFromRoom: "%s è stato escluso dalla stanza.", - presenceUnknownWarningSubject: "Nota:", - presenceUnknownWarning: "Questo utente potrebbe essere offline. Non possiamo tracciare la sua presenza.", - dateFormat: "dd/mm/yyyy", - timeFormat: "HH:MM:ss", - tooltipRole: "Moderatore", - tooltipIgnored: "Stai ignorando questo utente", - tooltipEmoticons: "Emoticons", - tooltipSound: "Riproduci un suono quando arrivano messaggi privati", - tooltipAutoscroll: "Autoscroll", - tooltipStatusmessage: "Mostra messaggi di stato", - tooltipAdministration: "Amministrazione stanza", - tooltipUsercount: "Partecipanti alla stanza", - enterRoomPassword: 'La stanza "%s" è protetta da password.', - enterRoomPasswordSubmit: "Unisciti alla stanza", - passwordEnteredInvalid: 'Password non valida per la stanza "%s".', - nicknameConflict: "Nome utente già in uso. Scegline un altro.", - errorMembersOnly: 'Non puoi unirti alla stanza "%s": Permessi insufficienti.', - errorMaxOccupantsReached: 'Non puoi unirti alla stanza "%s": Troppi partecipanti.', - antiSpamMessage: "Per favore non scrivere messaggi pubblicitari. Sei stato bloccato per un po' di tempo." - }, - pt: { - status: "Status: %s", - statusConnecting: "Conectando...", - statusConnected: "Conectado", - statusDisconnecting: "Desligando...", - statusDisconnected: "Desligado", - statusAuthfail: "Falha na autenticação", - roomSubject: "Assunto:", - messageSubmit: "Enviar", - labelUsername: "Usuário:", - labelPassword: "Senha:", - loginSubmit: "Entrar", - loginInvalid: "JID inválido", - reason: "Motivo:", - subject: "Assunto:", - reasonWas: "O motivo foi: %s.", - kickActionLabel: "Excluir", - youHaveBeenKickedBy: "Você foi excluido de %1$s por %2$s", - youHaveBeenKicked: "Você foi excluido de %s", - banActionLabel: "Bloquear", - youHaveBeenBannedBy: "Você foi excluido permanentemente de %1$s por %2$s", - youHaveBeenBanned: "Você foi excluido permanentemente de %s", - privateActionLabel: "Bate-papo privado", - ignoreActionLabel: "Ignorar", - unignoreActionLabel: "Não ignorar", - setSubjectActionLabel: "Trocar Assunto", - administratorMessageSubject: "Administrador", - userJoinedRoom: "%s entrou na sala.", - userLeftRoom: "%s saiu da sala.", - userHasBeenKickedFromRoom: "%s foi excluido da sala.", - userHasBeenBannedFromRoom: "%s foi excluido permanentemente da sala.", - presenceUnknownWarning: "Este usuário pode estar desconectado. Não é possível determinar o status.", - dateFormat: "dd.mm.yyyy", - timeFormat: "HH:MM:ss", - tooltipRole: "Moderador", - tooltipIgnored: "Você ignora este usuário", - tooltipEmoticons: "Emoticons", - tooltipSound: "Reproduzir o som para novas mensagens privados", - tooltipAutoscroll: "Deslocamento automático", - tooltipStatusmessage: "Mostrar mensagens de status", - tooltipAdministration: "Administração da sala", - tooltipUsercount: "Usuários na sala", - enterRoomPassword: 'A sala "%s" é protegida por senha.', - enterRoomPasswordSubmit: "Junte-se à sala", - passwordEnteredInvalid: 'Senha incorreta para a sala "%s".', - nicknameConflict: "O nome de usuário já está em uso. Por favor, escolha outro.", - errorMembersOnly: 'Você não pode participar da sala "%s": privilégios insuficientes.', - errorMaxOccupantsReached: 'Você não pode participar da sala "%s": muitos participantes.', - antiSpamMessage: "Por favor, não envie spam. Você foi bloqueado temporariamente." - }, - pt_br: { - status: "Estado: %s", - statusConnecting: "Conectando...", - statusConnected: "Conectado", - statusDisconnecting: "Desconectando...", - statusDisconnected: "Desconectado", - statusAuthfail: "Autenticação falhou", - roomSubject: "Assunto:", - messageSubmit: "Enviar", - labelUsername: "Usuário:", - labelPassword: "Senha:", - loginSubmit: "Entrar", - loginInvalid: "JID inválido", - reason: "Motivo:", - subject: "Assunto:", - reasonWas: "Motivo foi: %s.", - kickActionLabel: "Derrubar", - youHaveBeenKickedBy: "Você foi derrubado de %2$s por %1$s", - youHaveBeenKicked: "Você foi derrubado de %s", - banActionLabel: "Banir", - youHaveBeenBannedBy: "Você foi banido de %1$s por %2$s", - youHaveBeenBanned: "Você foi banido de %s", - privateActionLabel: "Conversa privada", - ignoreActionLabel: "Ignorar", - unignoreActionLabel: "Não ignorar", - setSubjectActionLabel: "Mudar Assunto", - administratorMessageSubject: "Administrador", - userJoinedRoom: "%s entrou na sala.", - userLeftRoom: "%s saiu da sala.", - userHasBeenKickedFromRoom: "%s foi derrubado da sala.", - userHasBeenBannedFromRoom: "%s foi banido da sala.", - presenceUnknownWarningSubject: "Aviso:", - presenceUnknownWarning: "Este usuário pode estar desconectado.. Não conseguimos rastrear sua presença..", - dateFormat: "dd.mm.yyyy", - timeFormat: "HH:MM:ss", - tooltipRole: "Moderador", - tooltipIgnored: "Você ignora este usuário", - tooltipEmoticons: "Emoticons", - tooltipSound: "Tocar som para novas mensagens privadas", - tooltipAutoscroll: "Auto-rolagem", - tooltipStatusmessage: "Exibir mensagens de estados", - tooltipAdministration: "Administração de Sala", - tooltipUsercount: "Participantes da Sala", - enterRoomPassword: 'Sala "%s" é protegida por senha.', - enterRoomPasswordSubmit: "Entrar na sala", - passwordEnteredInvalid: 'Senha inváida para sala "%s".', - nicknameConflict: "Nome de usuário já em uso. Por favor escolha outro.", - errorMembersOnly: 'Você não pode entrar na sala "%s": privilégios insuficientes.', - errorMaxOccupantsReached: 'Você não pode entrar na sala "%s": máximo de participantes atingido.', - antiSpamMessage: "Por favor, não faça spam. Você foi bloqueado temporariamente." - }, - ru: { - status: "Статус: %s", - statusConnecting: "Подключение...", - statusConnected: "Подключено", - statusDisconnecting: "Отключение...", - statusDisconnected: "Отключено", - statusAuthfail: "Неверный логин", - roomSubject: "Топик:", - messageSubmit: "Послать", - labelUsername: "Имя:", - labelPassword: "Пароль:", - loginSubmit: "Логин", - loginInvalid: "Неверный JID", - reason: "Причина:", - subject: "Топик:", - reasonWas: "Причина была: %s.", - kickActionLabel: "Выбросить", - youHaveBeenKickedBy: "Пользователь %1$s выбросил вас из чата %2$s", - youHaveBeenKicked: "Вас выбросили из чата %s", - banActionLabel: "Запретить доступ", - youHaveBeenBannedBy: "Пользователь %1$s запретил вам доступ в чат %2$s", - youHaveBeenBanned: "Вам запретили доступ в чат %s", - privateActionLabel: "Один-на-один чат", - ignoreActionLabel: "Игнорировать", - unignoreActionLabel: "Отменить игнорирование", - setSubjectActionLabel: "Изменить топик", - administratorMessageSubject: "Администратор", - userJoinedRoom: "%s вошёл в чат.", - userLeftRoom: "%s вышел из чата.", - userHasBeenKickedFromRoom: "%s выброшен из чата.", - userHasBeenBannedFromRoom: "%s запрещён доступ в чат.", - presenceUnknownWarningSubject: "Уведомление:", - presenceUnknownWarning: "Этот пользователь вероятнее всего оффлайн.", - dateFormat: "mm.dd.yyyy", - timeFormat: "HH:MM:ss", - tooltipRole: "Модератор", - tooltipIgnored: "Вы игнорируете этого пользователя.", - tooltipEmoticons: "Смайлики", - tooltipSound: "Озвучивать новое частное сообщение", - tooltipAutoscroll: "Авто-прокручивание", - tooltipStatusmessage: "Показывать статус сообщения", - tooltipAdministration: "Администрирование чат комнаты", - tooltipUsercount: "Участники чата", - enterRoomPassword: 'Чат комната "%s" защищена паролем.', - enterRoomPasswordSubmit: "Войти в чат", - passwordEnteredInvalid: 'Неверный пароль для комнаты "%s".', - nicknameConflict: "Это имя уже используется. Пожалуйста выберите другое имя.", - errorMembersOnly: 'Вы не можете войти в чат "%s": Недостаточно прав доступа.', - errorMaxOccupantsReached: 'Вы не можете войти в чат "%s": Слишком много участников.', - antiSpamMessage: "Пожалуйста не рассылайте спам. Вас заблокировали на короткое время." - }, - ca: { - status: "Estat: %s", - statusConnecting: "Connectant...", - statusConnected: "Connectat", - statusDisconnecting: "Desconnectant...", - statusDisconnected: "Desconnectat", - statusAuthfail: "Ha fallat la autenticació", - roomSubject: "Assumpte:", - messageSubmit: "Enviar", - labelUsername: "Usuari:", - labelPassword: "Clau:", - loginSubmit: "Entrar", - loginInvalid: "JID no vàlid", - reason: "Raó:", - subject: "Assumpte:", - reasonWas: "La raó ha estat: %s.", - kickActionLabel: "Expulsar", - youHaveBeenKickedBy: "Has estat expulsat de %1$s per %2$s", - youHaveBeenKicked: "Has estat expulsat de %s", - banActionLabel: "Prohibir", - youHaveBeenBannedBy: "Has estat expulsat permanentment de %1$s per %2$s", - youHaveBeenBanned: "Has estat expulsat permanentment de %s", - privateActionLabel: "Xat privat", - ignoreActionLabel: "Ignorar", - unignoreActionLabel: "No ignorar", - setSubjectActionLabel: "Canviar assumpte", - administratorMessageSubject: "Administrador", - userJoinedRoom: "%s ha entrat a la sala.", - userLeftRoom: "%s ha deixat la sala.", - userHasBeenKickedFromRoom: "%s ha estat expulsat de la sala.", - userHasBeenBannedFromRoom: "%s ha estat expulsat permanentment de la sala.", - presenceUnknownWarningSubject: "Atenció:", - presenceUnknownWarning: "Aquest usuari podria estar desconnectat ...", - dateFormat: "dd.mm.yyyy", - timeFormat: "HH:MM:ss", - tooltipRole: "Moderador", - tooltipIgnored: "Estàs ignorant aquest usuari", - tooltipEmoticons: "Emoticones", - tooltipSound: "Reproduir un so per a nous missatges", - tooltipAutoscroll: "Desplaçament automàtic", - tooltipStatusmessage: "Mostrar missatges d'estat", - tooltipAdministration: "Administració de la sala", - tooltipUsercount: "Usuaris dins la sala", - enterRoomPassword: 'La sala "%s" està protegida amb contrasenya.', - enterRoomPasswordSubmit: "Entrar a la sala", - passwordEnteredInvalid: 'Contrasenya incorrecta per a la sala "%s".', - nicknameConflict: "El nom d'usuari ja s'està utilitzant. Si us plau, escolleix-ne un altre.", - errorMembersOnly: 'No pots unir-te a la sala "%s": no tens prous privilegis.', - errorMaxOccupantsReached: 'No pots unir-te a la sala "%s": hi ha masses participants.', - antiSpamMessage: "Si us plau, no facis spam. Has estat bloquejat temporalment." - } -}; -//# sourceMappingURL=candy.bundle.map \ No newline at end of file diff --git a/candy.bundle.map b/candy.bundle.map deleted file mode 100644 index 94dc4bc2..00000000 --- a/candy.bundle.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"candy.bundle.js","sources":["src/candy.js","src/core.js","src/view.js","src/util.js","src/core/action.js","src/core/chatRoom.js","src/core/chatRoster.js","src/core/chatUser.js","src/core/event.js","src/view/observer.js","src/view/pane.js","src/view/template.js","src/view/translation.js"],"names":["Candy","self","$","about","name","version","init","service","options","viewClass","View","view","Core","core","jQuery","Strophe","_connection","_service","_user","_rooms","_anonymousConnection","_status","_options","autojoin","undefined","debug","disableWindowUnload","presencePriority","resource","_addNamespace","value","addNamespace","_addNamespaces","_getEscapedJidFromJid","jid","node","getNodeFromJid","domain","getDomainFromJid","escapeNode","extend","window","console","log","Function","prototype","bind","Util","getIeVersion","call","apply","arguments","Connection","rawInput","rawOutput","caps","onbeforeunload","onWindowUnload","registerEventHandlers","addHandler","Event","Jabber","Version","NS","VERSION","Presence","Message","Bookmarks","PRIVATE","Room","Disco","DISCO_INFO","disco","_onDiscoInfo","_onDiscoItems","DISCO_ITEMS","_delegateCapabilities","CAPS","connect","jidOrHost","password","nick","reset","triggerHandler","connection","indexOf","Connect","ChatUser","Login","attach","sid","rid","disconnect","connected","each","getRooms","Action","Leave","this","getJid","handler","ns","type","id","from","getUser","setUser","user","getConnection","removeRoom","roomJid","getStropheStatus","setStropheStatus","status","isAnonymousConnection","getOptions","getRoom","sync","flush","data","_current","container","language","assets","messages","limit","remove","crop","message","nickname","body","roster","enableXHTML","_setupTranslation","i18n","load","Translation","_registerObservers","on","Observer","Chat","AutojoinMissing","update","PresenceError","_registerWindowHandlers","document","focusin","Pane","Window","onFocus","focusout","onBlur","focus","blur","resize","fitTabs","_initToolbar","Toolbar","_delegateTooltips","delegate","Tooltip","show","resources","Parser","setEmoticonPath","html","Mustache","to_html","Template","pane","tooltipEmoticons","_","tooltipSound","tooltipAutoscroll","tooltipStatusmessage","tooltipAdministration","tooltipUsercount","assetsPath","tabs","rooms","modal","toolbar","soundcontrol","getCurrent","jidToId","MD5","hexdigest","escapeJid","getResourceFromJid","unescapeJid","unescapeNode","str","len","length","substr","parseAndCropXhtml","append","createHtml","get","setCookie","lifetime_days","exp","Date","setDate","getDate","cookie","toUTCString","cookieExists","getCookie","regex","RegExp","escape","matches","exec","deleteCookie","getPosLeftAccordingToWindowBounds","elem","pos","windowWidth","width","elemWidth","outerWidth","marginDiff","backgroundPositionAlignment","px","getPosTopAccordingToWindowBounds","windowHeight","height","elemHeight","outerHeight","localizedTime","dateTime","date","iso8601toDate","toDateString","format","timestamp","parse","isNaN","struct","minutesOffset","getTimezoneOffset","replace","isEmptyObject","obj","prop","hasOwnProperty","forceRedraw","css","display","setTimeout","ie","undef","v","div","createElement","all","getElementsByTagName","innerHTML","_emoticonPath","path","emoticons","plain","image","emotify","text","i","linkify","nl2br","maxLength","currentLength","el","j","tag","attribute","cssAttrs","attr","cssName","cssValue","nodeType","ElementType","NORMAL","nodeName","toLowerCase","XHTML","validTag","attributes","getAttribute","cssText","split","validCSS","push","join","childNodes","e","xmlTextNode","xmlGenerator","createDocumentFragment","appendChild","FRAGMENT","TEXT","nodeValue","substring","parseHTML","msg","sendIQ","$iq","to","c","os","navigator","userAgent","SetNickname","Array","roomNick","presence","conn","$pres","getUniqueId","send","Roster","xmlns","CLIENT","ROSTER","tree","pres","t","toString","up","generateCapsAttrs","Services","Autojoin","BOOKMARKS","pubsubBookmarkRequest","PUBSUB","isArray","Join","valueOf","ResetIgnoreList","getEscapedJid","PRIVACY","action","order","RemoveIgnoreList","GetIgnoreList","iq","iqId","PrivacyList","SetIgnoreListActive","GetJidIfAnonymous","getNick","MUC","muc","leave","xhtmlMsg","trim","getBareJidFromJid","Invite","invitees","reason","$msg","x","MUC_USER","invitee","IgnoreUnignore","userJid","addToOrRemoveFromPrivacyList","UpdatePrivacyList","currentUser","privacyList","getPrivacyList","index","Admin","UserAction","itemObj","role","affiliation","MUC_ADMIN","SetSubject","subject","setTopic","ChatRoom","room","ChatRoster","setName","getName","setRoster","getRoster","items","add","getAll","ROLE_MODERATOR","AFFILIATION_OWNER","privacyLists","customData","previousNick","setJid","setNick","getRole","setRole","setAffiliation","getAffiliation","isModerator","list","splice","setPrivacyLists","lists","isInPrivacyList","setCustomData","getCustomData","setPreviousNick","getPreviousNick","presetJid","Status","CONNECTED","ATTACHED","DISCONNECTED","AUTHFAIL","CONNECTING","DISCONNECTING","AUTHENTICATING","ERROR","CONNFAIL","children","stanza","item","PrivacyListError","fromJid","toJid","mediatedInvite","find","directInvite","passwordNode","continueNode","continuedThread","roomName","actor","code","identity","presenceType","nickAssign","nickChange","l","$status","tagName","error","bareRoomJid","isNoConferenceRoomJid","xhtmlChild","XHTML_IM","xhtmlMessage","first","chatstate","delay","DELAY","_showConnectedMessageModal","event","args","eventName","Modal","hide","showLoginForm","adminMessage","onInfoMessage","close","notifyPrivateChats","actorName","actionLabel","translationParams","Context","adminMessageReason","_action","_reason","evtData","PrivateRoom","setStatus","showEnterPasswordForm","showNicknameConflictForm","showError","setSubject","infoMessage","open","_hasFocus","_plainTitle","title","_unreadMessagesCount","autoscroll","hasFocus","increaseUnreadMessages","renderUnreadMessages","reduceUnreadMessages","num","clearUnreadMessages","count","unreadmessages","setFocusToForm","addTab","roomType","roomId","tab","privateUserChat","appendTo","click","tabClick","tabClose","getTab","removeTab","setActiveTab","addClass","removeClass","unreadElem","parseInt","currentRoomJid","scrollPosition","getPane","scrollTop","preventDefault","parent","allTabsClosed","availableWidth","innerWidth","tabsWidth","overflow","tabDiffToRealWidth","tabWidth","Math","floor","sender","time","toGMTString","appendToMessagePane","scrollToBottom","_supportsNativeAudio","showEmoticonsMenu","currentTarget","stopPropagation","onAutoscrollControlClick","a","canPlayType","onSoundControlClick","onStatusMessageControlClick","context","me","updateUsercount","usercount","playSound","onPlaySound","Audio","play","chatSoundPlayer","getElementById","SetVariable","control","hasClass","toggleClass","onScrollToStoredPosition","onScrollToBottom","showCloseControl","showSpinner","hideCloseControl","hideSpinner","stop","fadeIn","callback","fadeOut","keydown","which","form","_labelNickname","_labelUsername","_labelPassword","_loginSubmit","displayPassword","displayUsername","displayNickname","submit","username","val","enterPasswordForm","_label","_joinSubmit","nicknameConflictForm","replacements","displayError","_error","content","tooltip","target","offset","posLeft","left","posTop","top","mouseleave","menu","links","menulinks","getMenuLinks","clickHandler","link","class","label","element","initialMenuLinks","requiredPermission","private","ignore","ignoreUser","unignore","unignoreUser","kick","contextModalForm","_submit","ban","input","emoticon","messageCount","_messageSubmit","_userOnline","_roomSubject","openRooms","last","sliceMessagePane","slice","messagePane","roomPane","chatPane","addIgnoreIcon","removeIgnoreIcon","subPane","changeDataUserJidIfUserIsMe","roomElement","switchToRoom","messageForm","removeAttr","changeNick","previousPrivateRoomJid","newPrivateRoomJid","previousPrivateRoomId","newPrivateRoomId","roomTabElement","userId","usercountDiff","userElem","displayNick","tooltipRole","tooltipIgnored","userInserted","rosterPane","userSortCompare","toUpperCase","before","showJoinAnimation","replaceWith","opacity","userClick","leaveAnimation","rosterUserId","$rosterUserElem","is","joinAnimation","elementId","slideDown","animate","complete","slideUp","previousUserJid","renderEvtData","template","templateData","displayName","en","statusConnecting","statusConnected","statusDisconnecting","statusDisconnected","statusAuthfail","roomSubject","messageSubmit","labelUsername","labelNickname","labelPassword","loginSubmit","loginInvalid","reasonWas","kickActionLabel","youHaveBeenKickedBy","youHaveBeenKicked","banActionLabel","youHaveBeenBannedBy","youHaveBeenBanned","privateActionLabel","ignoreActionLabel","unignoreActionLabel","setSubjectActionLabel","administratorMessageSubject","userJoinedRoom","userLeftRoom","userHasBeenKickedFromRoom","userHasBeenBannedFromRoom","userChangedNick","presenceUnknownWarningSubject","presenceUnknownWarning","dateFormat","timeFormat","enterRoomPassword","enterRoomPasswordSubmit","passwordEnteredInvalid","nicknameConflict","errorMembersOnly","errorMaxOccupantsReached","errorAutojoinMissing","antiSpamMessage","de","fr","nl","es","cn","ja","sv","it","pt","pt_br","ru","ca"],"mappings":"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"} \ No newline at end of file diff --git a/candy.min.js b/candy.min.js deleted file mode 100644 index 474fc855..00000000 --- a/candy.min.js +++ /dev/null @@ -1,4 +0,0 @@ -"use strict";var Candy=function(a,b){return a.about={name:"Candy",version:"1.7.1"},a.init=function(c,d){d.viewClass||(d.viewClass=a.View),d.viewClass.init(b("#candy"),d.view),a.Core.init(c,d.core)},a}(Candy||{},jQuery);Candy.Core=function(a,b,c){var d,e=null,f=null,g=null,h={},i=!1,j={autojoin:void 0,debug:!1,disableWindowUnload:!1,presencePriority:1,resource:Candy.about.name},k=function(a,c){b.addNamespace(a,c)},l=function(){k("PRIVATE","jabber:iq:private"),k("BOOKMARKS","storage:bookmarks"),k("PRIVACY","jabber:iq:privacy"),k("DELAY","jabber:x:delay"),k("PUBSUB","http://jabber.org/protocol/pubsub")},m=function(a){var c=b.getNodeFromJid(a),d=b.getDomainFromJid(a);return c?b.escapeNode(c)+"@"+d:d};return a.init=function(d,g){f=d,c.extend(!0,j,g),j.debug&&(void 0!==typeof window.console&&void 0!==typeof window.console.log&&(a.log=Function.prototype.bind&&Candy.Util.getIeVersion()>8?Function.prototype.bind.call(console.log,console):function(){Function.prototype.apply.call(console.log,console,arguments)}),a.log("[Init] Debugging enabled")),l(),e=new b.Connection(f),e.rawInput=a.rawInput.bind(a),e.rawOutput=a.rawOutput.bind(a),e.caps.node="https://candy-chat.github.io/candy/",j.disableWindowUnload||(window.onbeforeunload=a.onWindowUnload)},a.registerEventHandlers=function(){a.addHandler(a.Event.Jabber.Version,b.NS.VERSION,"iq"),a.addHandler(a.Event.Jabber.Presence,null,"presence"),a.addHandler(a.Event.Jabber.Message,null,"message"),a.addHandler(a.Event.Jabber.Bookmarks,b.NS.PRIVATE,"iq"),a.addHandler(a.Event.Jabber.Room.Disco,b.NS.DISCO_INFO,"iq","result"),a.addHandler(e.disco._onDiscoInfo.bind(e.disco),b.NS.DISCO_INFO,"iq","get"),a.addHandler(e.disco._onDiscoItems.bind(e.disco),b.NS.DISCO_ITEMS,"iq","get"),a.addHandler(e.caps._delegateCapabilities.bind(e.caps),b.NS.CAPS)},a.connect=function(d,f,h){e.reset(),a.registerEventHandlers(),c(Candy).triggerHandler("candy:core.before-connect",{connection:e}),i=i?!0:d&&d.indexOf("@")<0,d&&f?(e.connect(m(d)+"/"+j.resource,f,Candy.Core.Event.Strophe.Connect),g=h?new a.ChatUser(d,h):new a.ChatUser(d,b.getNodeFromJid(d))):d&&h?(e.connect(m(d)+"/"+j.resource,null,Candy.Core.Event.Strophe.Connect),g=new a.ChatUser(null,h)):d?Candy.Core.Event.Login(d):Candy.Core.Event.Login()},a.attach=function(c,d,f){g=new a.ChatUser(c,b.getNodeFromJid(c)),a.registerEventHandlers(),e.attach(c,d,f,Candy.Core.Event.Strophe.Connect)},a.disconnect=function(){e.connected&&(c.each(a.getRooms(),function(){Candy.Core.Action.Jabber.Room.Leave(this.getJid())}),e.disconnect())},a.addHandler=function(a,b,c,d,f,g,h){return e.addHandler(a,b,c,d,f,g,h)},a.getUser=function(){return g},a.setUser=function(a){g=a},a.getConnection=function(){return e},a.removeRoom=function(a){delete h[a]},a.getRooms=function(){return h},a.getStropheStatus=function(){return d},a.setStropheStatus=function(a){d=a},a.isAnonymousConnection=function(){return i},a.getOptions=function(){return j},a.getRoom=function(a){return h[a]?h[a]:null},a.onWindowUnload=function(){e.options.sync=!0,a.disconnect(),e.flush()},a.rawInput=function(a){this.log("RECV: "+a)},a.rawOutput=function(a){this.log("SENT: "+a)},a.log=function(){},a}(Candy.Core||{},Strophe,jQuery),Candy.View=function(a,b){var c={container:null,roomJid:null},d={language:"en",assets:"res/",messages:{limit:2e3,remove:500},crop:{message:{nickname:15,body:1e3},roster:{nickname:15}},enableXHTML:!1},e=function(c){b.i18n.load(a.Translation[c])},f=function(){b(Candy).on("candy:core.chat.connection",a.Observer.Chat.Connection),b(Candy).on("candy:core.chat.message",a.Observer.Chat.Message),b(Candy).on("candy:core.login",a.Observer.Login),b(Candy).on("candy:core.autojoin-missing",a.Observer.AutojoinMissing),b(Candy).on("candy:core.presence",a.Observer.Presence.update),b(Candy).on("candy:core.presence.leave",a.Observer.Presence.update),b(Candy).on("candy:core.presence.room",a.Observer.Presence.update),b(Candy).on("candy:core.presence.error",a.Observer.PresenceError),b(Candy).on("candy:core.message",a.Observer.Message)},g=function(){Candy.Util.getIeVersion()<9?b(document).focusin(Candy.View.Pane.Window.onFocus).focusout(Candy.View.Pane.Window.onBlur):b(window).focus(Candy.View.Pane.Window.onFocus).blur(Candy.View.Pane.Window.onBlur),b(window).resize(Candy.View.Pane.Chat.fitTabs)},h=function(){a.Pane.Chat.Toolbar.init()},i=function(){b("body").delegate("li[data-tooltip]","mouseenter",Candy.View.Pane.Chat.Tooltip.show)};return a.init=function(a,j){j.resources&&(j.assets=j.resources),delete j.resources,b.extend(!0,d,j),e(d.language),Candy.Util.Parser.setEmoticonPath(this.getOptions().assets+"img/emoticons/"),c.container=a,c.container.html(Mustache.to_html(Candy.View.Template.Chat.pane,{tooltipEmoticons:b.i18n._("tooltipEmoticons"),tooltipSound:b.i18n._("tooltipSound"),tooltipAutoscroll:b.i18n._("tooltipAutoscroll"),tooltipStatusmessage:b.i18n._("tooltipStatusmessage"),tooltipAdministration:b.i18n._("tooltipAdministration"),tooltipUsercount:b.i18n._("tooltipUsercount"),assetsPath:this.getOptions().assets},{tabs:Candy.View.Template.Chat.tabs,rooms:Candy.View.Template.Chat.rooms,modal:Candy.View.Template.Chat.modal,toolbar:Candy.View.Template.Chat.toolbar,soundcontrol:Candy.View.Template.Chat.soundcontrol})),g(),h(),f(),i()},a.getCurrent=function(){return c},a.getOptions=function(){return d},a}(Candy.View||{},jQuery),Candy.Util=function(a,b){a.jidToId=function(a){return MD5.hexdigest(a)},a.escapeJid=function(a){var b=Strophe.escapeNode(Strophe.getNodeFromJid(a)),c=Strophe.getDomainFromJid(a),d=Strophe.getResourceFromJid(a);return a=b+"@"+c,d&&(a+="/"+d),a},a.unescapeJid=function(a){var b=Strophe.unescapeNode(Strophe.getNodeFromJid(a)),c=Strophe.getDomainFromJid(a),d=Strophe.getResourceFromJid(a);return a=b+"@"+c,d&&(a+="/"+d),a},a.crop=function(a,b){return a.length>b&&(a=a.substr(0,b-3)+"..."),a},a.parseAndCropXhtml=function(c,d){return b("
          ").append(a.createHtml(b(c).get(0),d)).html()},a.setCookie=function(a,b,c){var d=new Date;d.setDate((new Date).getDate()+c),document.cookie=a+"="+b+";expires="+d.toUTCString()+";path=/"},a.cookieExists=function(a){return document.cookie.indexOf(a)>-1},a.getCookie=function(a){if(document.cookie){var b=new RegExp(escape(a)+"=([^;]*)","gm"),c=b.exec(document.cookie);if(c)return c[1]}},a.deleteCookie=function(a){document.cookie=a+"=;expires=Thu, 01-Jan-70 00:00:01 GMT;path=/"},a.getPosLeftAccordingToWindowBounds=function(a,c){var d=b(document).width(),e=a.outerWidth(),f=e-a.outerWidth(!0),g="left";return c+e>=d&&(c-=e-f,g="right"),{px:c,backgroundPositionAlignment:g}},a.getPosTopAccordingToWindowBounds=function(a,c){var d=b(document).height(),e=a.outerHeight(),f=e-a.outerHeight(!0),g="top";return c+e>=d&&(c-=e-f,g="bottom"),{px:c,backgroundPositionAlignment:g}},a.localizedTime=function(c){if(void 0===c)return void 0;var d=a.iso8601toDate(c);return d.format(d.toDateString()===(new Date).toDateString()?b.i18n._("timeFormat"):b.i18n._("dateFormat"))},a.iso8601toDate=function(a){var b=Date.parse(a);if(isNaN(b)){var c=/^(\d{4}|[+\-]\d{6})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3,}))?)?(?:(Z)|([+\-])(\d{2})(?::?(\d{2}))?))?/.exec(a);if(c){var d=0;return"Z"!==c[8]&&(d=60*+c[10]+ +c[11],"+"===c[9]&&(d=-d)),d-=(new Date).getTimezoneOffset(),new Date(+c[1],+c[2]-1,+c[3],+c[4],+c[5]+d,+c[6],c[7]?+c[7].substr(0,3):0)}b=Date.parse(a.replace(/^(\d{4})(\d{2})(\d{2})/,"$1-$2-$3")+"Z")}return new Date(b)},a.isEmptyObject=function(a){var b;for(b in a)if(a.hasOwnProperty(b))return!1;return!0},a.forceRedraw=function(a){a.css({display:"none"}),setTimeout(function(){this.css({display:"block"})}.bind(a),1)};var c=function(){for(var a,b=3,c=document.createElement("div"),d=c.getElementsByTagName("i");c.innerHTML="",d[0];);return b>4?b:a}();return a.getIeVersion=function(){return c},a.Parser={_emoticonPath:"",setEmoticonPath:function(a){this._emoticonPath=a},emoticons:[{plain:":)",regex:/((\s):-?\)|:-?\)(\s|$))/gm,image:"Smiling.png"},{plain:";)",regex:/((\s);-?\)|;-?\)(\s|$))/gm,image:"Winking.png"},{plain:":D",regex:/((\s):-?D|:-?D(\s|$))/gm,image:"Grinning.png"},{plain:";D",regex:/((\s);-?D|;-?D(\s|$))/gm,image:"Grinning_Winking.png"},{plain:":(",regex:/((\s):-?\(|:-?\((\s|$))/gm,image:"Unhappy.png"},{plain:"^^",regex:/((\s)\^\^|\^\^(\s|$))/gm,image:"Happy_3.png"},{plain:":P",regex:/((\s):-?P|:-?P(\s|$))/gim,image:"Tongue_Out.png"},{plain:";P",regex:/((\s);-?P|;-?P(\s|$))/gim,image:"Tongue_Out_Winking.png"},{plain:":S",regex:/((\s):-?S|:-?S(\s|$))/gim,image:"Confused.png"},{plain:":/",regex:/((\s):-?\/|:-?\/(\s|$))/gm,image:"Uncertain.png"},{plain:"8)",regex:/((\s)8-?\)|8-?\)(\s|$))/gm,image:"Sunglasses.png"},{plain:"$)",regex:/((\s)\$-?\)|\$-?\)(\s|$))/gm,image:"Greedy.png"},{plain:"oO",regex:/((\s)oO|oO(\s|$))/gm,image:"Huh.png"},{plain:":x",regex:/((\s):x|:x(\s|$))/gm,image:"Lips_Sealed.png"},{plain:":666:",regex:/((\s):666:|:666:(\s|$))/gm,image:"Devil.png"},{plain:"<3",regex:/((\s)<3|<3(\s|$))/gm,image:"Heart.png"}],emotify:function(a){var b;for(b=this.emoticons.length-1;b>=0;b--)a=a.replace(this.emoticons[b].regex,'$2$1$3');return a},linkify:function(a){return a=a.replace(/(^|[^\/])(www\.[^\.]+\.[\S]+(\b|$))/gi,"$1http://$2"),a.replace(/(\b(https?|ftp|file):\/\/[\-A-Z0-9+&@#\/%?=~_|!:,.;]*[\-A-Z0-9+&@#\/%=~_|])/gi,'$1')},escape:function(a){return b("
          ").text(a).html()},nl2br:function(a){return a.replace(/\r\n|\r|\n/g,"
          ")},all:function(a){return a&&(a=this.escape(a),a=this.linkify(a),a=this.emotify(a),a=this.nl2br(a)),a}},a.createHtml=function(c,d,e){e=e||0;var f,g,h,i,j,k,l,m,n,o,p;if(c.nodeType===Strophe.ElementType.NORMAL)if(i=c.nodeName.toLowerCase(),Strophe.XHTML.validTag(i))try{for(g=b("<"+i+"/>"),f=0;f0&&(k=l.join("; "),g.attr(j,k))}else g.attr(j,k);for(f=0;fd&&(r=r.substring(0,d)),r=Candy.Util.Parser.all(r),g=b.parseHTML(r)}return g},a}(Candy.Util||{},jQuery),Candy.Core.Action=function(a,b,c){return a.Jabber={Version:function(a){Candy.Core.getConnection().sendIQ($iq({type:"result",to:Candy.Util.escapeJid(a.attr("from")),from:Candy.Util.escapeJid(a.attr("to")),id:a.attr("id")}).c("query",{name:Candy.about.name,version:Candy.about.version,os:navigator.userAgent}))},SetNickname:function(a,b){b=b instanceof Array?b:Candy.Core.getRooms();var d,e,f=Candy.Core.getConnection();c.each(b,function(b){d=Candy.Util.escapeJid(b+"/"+a),e=$pres({to:d,from:f.jid,id:"pres:"+f.getUniqueId()}),Candy.Core.getConnection().send(e)})},Roster:function(){Candy.Core.getConnection().sendIQ($iq({type:"get",xmlns:b.NS.CLIENT}).c("query",{xmlns:b.NS.ROSTER}).tree())},Presence:function(a,b){var c=Candy.Core.getConnection();a=a||{},a.id||(a.id="pres:"+c.getUniqueId());var d=$pres(a).c("priority").t(Candy.Core.getOptions().presencePriority.toString()).up().c("c",c.caps.generateCapsAttrs()).up();b&&d.node.appendChild(b.node),c.send(d.tree())},Services:function(){Candy.Core.getConnection().sendIQ($iq({type:"get",xmlns:b.NS.CLIENT}).c("query",{xmlns:b.NS.DISCO_ITEMS}).tree())},Autojoin:function(){if(Candy.Core.getOptions().autojoin===!0){Candy.Core.getConnection().sendIQ($iq({type:"get",xmlns:b.NS.CLIENT}).c("query",{xmlns:b.NS.PRIVATE}).c("storage",{xmlns:b.NS.BOOKMARKS}).tree());var d=Candy.Core.getConnection().getUniqueId("pubsub");Candy.Core.addHandler(Candy.Core.Event.Jabber.Bookmarks,b.NS.PUBSUB,"iq","result",d),Candy.Core.getConnection().sendIQ($iq({type:"get",id:d}).c("pubsub",{xmlns:b.NS.PUBSUB}).c("items",{node:b.NS.BOOKMARKS}).tree())}else c.isArray(Candy.Core.getOptions().autojoin)?c.each(Candy.Core.getOptions().autojoin,function(){a.Jabber.Room.Join.apply(null,this.valueOf().split(":",2))}):c(Candy).triggerHandler("candy:core.autojoin-missing")},ResetIgnoreList:function(){Candy.Core.getConnection().sendIQ($iq({type:"set",from:Candy.Core.getUser().getEscapedJid()}).c("query",{xmlns:b.NS.PRIVACY}).c("list",{name:"ignore"}).c("item",{action:"allow",order:"0"}).tree())},RemoveIgnoreList:function(){Candy.Core.getConnection().sendIQ($iq({type:"set",from:Candy.Core.getUser().getEscapedJid()}).c("query",{xmlns:b.NS.PRIVACY}).c("list",{name:"ignore"}).tree())},GetIgnoreList:function(){var a=$iq({type:"get",from:Candy.Core.getUser().getEscapedJid()}).c("query",{xmlns:b.NS.PRIVACY}).c("list",{name:"ignore"}).tree(),c=Candy.Core.getConnection().sendIQ(a);Candy.Core.addHandler(Candy.Core.Event.Jabber.PrivacyList,null,"iq",null,c)},SetIgnoreListActive:function(){Candy.Core.getConnection().sendIQ($iq({type:"set",from:Candy.Core.getUser().getEscapedJid()}).c("query",{xmlns:b.NS.PRIVACY}).c("active",{name:"ignore"}).tree())},GetJidIfAnonymous:function(){Candy.Core.getUser().getJid()||(Candy.Core.log("[Jabber] Anonymous login"),Candy.Core.getUser().data.jid=Candy.Core.getConnection().jid)},Room:{Join:function(c,d){a.Jabber.Room.Disco(c),c=Candy.Util.escapeJid(c);var e=Candy.Core.getConnection(),f=c+"/"+Candy.Core.getUser().getNick(),g=$pres({to:f,id:"pres:"+e.getUniqueId()}).c("x",{xmlns:b.NS.MUC});d&&g.c("password").t(d),g.up().c("c",e.caps.generateCapsAttrs()),e.send(g.tree())},Leave:function(a){var b=Candy.Core.getRoom(a).getUser();a=Candy.Util.escapeJid(a),b&&Candy.Core.getConnection().muc.leave(a,b.getNick(),function(){})},Disco:function(a){Candy.Core.getConnection().sendIQ($iq({type:"get",from:Candy.Core.getUser().getEscapedJid(),to:Candy.Util.escapeJid(a)}).c("query",{xmlns:b.NS.DISCO_INFO}).tree())},Message:function(a,d,e,f){if(d=c.trim(d),""===d)return!1;var g=null;return"chat"===e&&(g=b.getResourceFromJid(a),a=b.getBareJidFromJid(a)),Candy.Core.getConnection().muc.message(a,g,d,f,e),!0},Invite:function(a,d,e,f){e=c.trim(e);var g=$msg({to:a}),h=g.c("x",{xmlns:b.NS.MUC_USER});c.each(d,function(a,c){c=b.getBareJidFromJid(c),h.c("invite",{to:c}),"undefined"!=typeof e&&""!==e&&h.c("reason",e)}),"undefined"!=typeof f&&""!==f&&h.c("password",f),Candy.Core.getConnection().send(g)},IgnoreUnignore:function(a){Candy.Core.getUser().addToOrRemoveFromPrivacyList("ignore",a),Candy.Core.Action.Jabber.Room.UpdatePrivacyList()},UpdatePrivacyList:function(){var a=Candy.Core.getUser(),b=$iq({type:"set",from:a.getEscapedJid()}).c("query",{xmlns:"jabber:iq:privacy"}).c("list",{name:"ignore"}),d=a.getPrivacyList("ignore");d.length>0?c.each(d,function(a,c){b.c("item",{type:"jid",value:Candy.Util.escapeJid(c),action:"deny",order:a}).c("message").up().up()}):b.c("item",{action:"allow",order:"0"}),Candy.Core.getConnection().sendIQ(b.tree())},Admin:{UserAction:function(a,c,d,e){a=Candy.Util.escapeJid(a),c=Candy.Util.escapeJid(c);var f={nick:b.getResourceFromJid(c)};switch(d){case"kick":f.role="none";break;case"ban":f.affiliation="outcast";break;default:return!1}return Candy.Core.getConnection().sendIQ($iq({type:"set",from:Candy.Core.getUser().getEscapedJid(),to:a}).c("query",{xmlns:b.NS.MUC_ADMIN}).c("item",f).c("reason").t(e).tree()),!0},SetSubject:function(a,b){Candy.Core.getConnection().muc.setTopic(Candy.Util.escapeJid(a),b)}}}},a}(Candy.Core.Action||{},Strophe,jQuery),Candy.Core.ChatRoom=function(a){this.room={jid:a,name:Strophe.getNodeFromJid(a)},this.user=null,this.roster=new Candy.Core.ChatRoster,this.setUser=function(a){this.user=a},this.getUser=function(){return this.user},this.getJid=function(){return this.room.jid},this.setName=function(a){this.room.name=a},this.getName=function(){return this.room.name},this.setRoster=function(a){this.roster=a},this.getRoster=function(){return this.roster}},Candy.Core.ChatRoster=function(){this.items={},this.add=function(a){this.items[a.getJid()]=a},this.remove=function(a){delete this.items[a]},this.get=function(a){return this.items[a]},this.getAll=function(){return this.items}},Candy.Core.ChatUser=function(a,b,c,d){this.ROLE_MODERATOR="moderator",this.AFFILIATION_OWNER="owner",this.data={jid:a,nick:Strophe.unescapeNode(b),affiliation:c,role:d,privacyLists:{},customData:{},previousNick:void 0},this.getJid=function(){return this.data.jid?Candy.Util.unescapeJid(this.data.jid):void 0},this.getEscapedJid=function(){return Candy.Util.escapeJid(this.data.jid)},this.setJid=function(a){this.data.jid=a},this.getNick=function(){return Strophe.unescapeNode(this.data.nick)},this.setNick=function(a){this.data.nick=a},this.getRole=function(){return this.data.role},this.setRole=function(a){this.data.role=a},this.setAffiliation=function(a){this.data.affiliation=a},this.getAffiliation=function(){return this.data.affiliation},this.isModerator=function(){return this.getRole()===this.ROLE_MODERATOR||this.getAffiliation()===this.AFFILIATION_OWNER},this.addToOrRemoveFromPrivacyList=function(a,b){this.data.privacyLists[a]||(this.data.privacyLists[a]=[]);var c=-1;return-1!==(c=this.data.privacyLists[a].indexOf(b))?this.data.privacyLists[a].splice(c,1):this.data.privacyLists[a].push(b),this.data.privacyLists[a]},this.getPrivacyList=function(a){return this.data.privacyLists[a]||(this.data.privacyLists[a]=[]),this.data.privacyLists[a]},this.setPrivacyLists=function(a){this.data.privacyLists=a},this.isInPrivacyList=function(a,b){return this.data.privacyLists[a]?-1!==this.data.privacyLists[a].indexOf(b):!1},this.setCustomData=function(a){this.data.customData=a},this.getCustomData=function(){return this.data.customData},this.setPreviousNick=function(a){this.data.previousNick=a},this.getPreviousNick=function(){return this.data.previousNick}},Candy.Core.Event=function(a,b,c){return a.Login=function(a){c(Candy).triggerHandler("candy:core.login",{presetJid:a})},a.Strophe={Connect:function(a){switch(Candy.Core.setStropheStatus(a),a){case b.Status.CONNECTED:Candy.Core.log("[Connection] Connected"),Candy.Core.Action.Jabber.GetJidIfAnonymous();case b.Status.ATTACHED:Candy.Core.log("[Connection] Attached"),Candy.Core.Action.Jabber.Presence(),Candy.Core.Action.Jabber.Autojoin(),Candy.Core.Action.Jabber.GetIgnoreList();break;case b.Status.DISCONNECTED:Candy.Core.log("[Connection] Disconnected");break;case b.Status.AUTHFAIL:Candy.Core.log("[Connection] Authentication failed");break;case b.Status.CONNECTING:Candy.Core.log("[Connection] Connecting");break;case b.Status.DISCONNECTING:Candy.Core.log("[Connection] Disconnecting");break;case b.Status.AUTHENTICATING:Candy.Core.log("[Connection] Authenticating");break;case b.Status.ERROR:case b.Status.CONNFAIL:Candy.Core.log("[Connection] Failed ("+a+")");break;default:Candy.Core.log("[Connection] What?!")}c(Candy).triggerHandler("candy:core.chat.connection",{status:a})}},a.Jabber={Version:function(a){return Candy.Core.log("[Jabber] Version"),Candy.Core.Action.Jabber.Version(c(a)),!0},Presence:function(d){return Candy.Core.log("[Jabber] Presence"),d=c(d),d.children('x[xmlns^="'+b.NS.MUC+'"]').length>0?"error"===d.attr("type")?a.Jabber.Room.PresenceError(d):a.Jabber.Room.Presence(d):c(Candy).triggerHandler("candy:core.presence",{from:d.attr("from"),stanza:d}),!0},Bookmarks:function(a){return Candy.Core.log("[Jabber] Bookmarks"),c("conference",a).each(function(){var a=c(this);a.attr("autojoin")&&Candy.Core.Action.Jabber.Room.Join(a.attr("jid"))}),!0},PrivacyList:function(b){Candy.Core.log("[Jabber] PrivacyList");var d=Candy.Core.getUser();return b=c(b),"result"===b.attr("type")?(c('list[name="ignore"] item',b).each(function(){var a=c(this);"deny"===a.attr("action")&&d.addToOrRemoveFromPrivacyList("ignore",a.attr("value"))}),Candy.Core.Action.Jabber.SetIgnoreListActive(),!1):a.Jabber.PrivacyListError(b)},PrivacyListError:function(a){return Candy.Core.log("[Jabber] PrivacyListError"),c('error[code="404"][type="cancel"] item-not-found',a)&&(Candy.Core.Action.Jabber.ResetIgnoreList(),Candy.Core.Action.Jabber.SetIgnoreListActive()),!1},Message:function(d){Candy.Core.log("[Jabber] Message"),d=c(d);var e=d.attr("from"),f=d.attr("type")||"undefined",g=d.attr("to");if("normal"===f||"undefined"===f){var h=d.find("invite"),i=d.find('x[xmlns="jabber:x:conference"]');if(h.length>0){var j=d.find("password"),k=null,l=h.find("continue"),m=null;j&&(k=j.text()),l&&(m=l.attr("thread")),c(Candy).triggerHandler("candy:core:chat:invite",{roomJid:e,from:h.attr("from")||"undefined",reason:h.find("reason").html()||"",password:k,continuedThread:m})}return i.length>0&&c(Candy).triggerHandler("candy:core:chat:invite",{roomJid:i.attr("jid"),from:e,reason:i.attr("reason")||"",password:i.attr("password"),continuedThread:i.attr("thread")}),c(Candy).triggerHandler("candy:core:chat:message:normal",{type:f||"normal",message:d}),!0}return"groupchat"!==f&&"chat"!==f&&"error"!==f&&"headline"!==f?(c(Candy).triggerHandler("candy:core:chat:message:other",{type:f,message:d}),!0):(e===b.getDomainFromJid(e)||"groupchat"!==f&&"chat"!==f&&"error"!==f?g||e!==b.getDomainFromJid(e)?g&&e===b.getDomainFromJid(e)&&c(Candy).triggerHandler("candy:core.chat.message.server",{type:f||"message",subject:d.children("subject").text(),message:d.children("body").text()}):c(Candy).triggerHandler("candy:core.chat.message.admin",{type:f||"message",message:d.children("body").text()}):a.Jabber.Room.Message(d),!0)},Room:{Leave:function(a){Candy.Core.log("[Jabber:Room] Leave"),a=c(a);var d=Candy.Util.unescapeJid(a.attr("from")),e=b.getBareJidFromJid(d);if(!Candy.Core.getRoom(e))return!0;var f,g,h=Candy.Core.getRoom(e).getName(),i=a.find("item"),j="leave";if(delete Candy.Core.getRooms()[e],"none"===i.attr("role")){var k=a.find("status").attr("code");"307"===k?j="kick":"301"===k&&(j="ban"),f=i.find("reason").text(),g=i.find("actor").attr("jid")}var l=new Candy.Core.ChatUser(d,b.getResourceFromJid(d),i.attr("affiliation"),i.attr("role"));return c(Candy).triggerHandler("candy:core.presence.leave",{roomJid:e,roomName:h,type:j,reason:f,actor:g,user:l}),!0},Disco:function(a){if(Candy.Core.log("[Jabber:Room] Disco"),a=c(a),!a.find('identity[category="conference"]').length)return!0;var d=b.getBareJidFromJid(Candy.Util.unescapeJid(a.attr("from")));Candy.Core.getRooms()[d]||(Candy.Core.getRooms()[d]=new Candy.Core.ChatRoom(d));var e=a.find("identity");if(e.length){var f=e.attr("name"),g=Candy.Core.getRoom(d);null===g.getName()&&g.setName(b.unescapeNode(f))}return!0},Presence:function(d){Candy.Core.log("[Jabber:Room] Presence");var e=Candy.Util.unescapeJid(d.attr("from")),f=b.getBareJidFromJid(e),g=d.attr("type"),h=d.find("status"),i=!1,j=!1;if(h.length)for(var k=0,l=h.length;l>k;k++){var m=c(h[k]),n=m.attr("code");"303"===n?j=!0:"210"===n&&(i=!0)}var o=Candy.Core.getRoom(f);o||(Candy.Core.getRooms()[f]=new Candy.Core.ChatRoom(f),o=Candy.Core.getRoom(f));var p=o.getUser()?o.getUser():Candy.Core.getUser();if(b.getResourceFromJid(e)===p.getNick()&&"unavailable"===g&&j===!1)return a.Jabber.Room.Leave(d),!0;var q,r,s,t=o.getRoster(),u=d.find("item");if("unavailable"!==g)if(t.get(e)){r=t.get(e);var v=u.attr("role"),w=u.attr("affiliation");r.setRole(v),r.setAffiliation(w),q="join"}else s=b.getResourceFromJid(e),r=new Candy.Core.ChatUser(e,s,u.attr("affiliation"),u.attr("role")),null!==o.getUser()||Candy.Core.getUser().getNick()!==s&&!i||(o.setUser(r),p=r),t.add(r),q="join";else r=t.get(e),t.remove(e),j?(s=u.attr("nick"),q="nickchange",r.setPreviousNick(r.getNick()),r.setNick(s),r.setJid(b.getBareJidFromJid(e)+"/"+s),t.add(r)):(q="leave","none"===u.attr("role")&&("307"===d.find("status").attr("code")?q="kick":"301"===d.find("status").attr("code")&&(q="ban")));return c(Candy).triggerHandler("candy:core.presence.room",{roomJid:f,roomName:o.getName(),user:r,action:q,currentUser:p}),!0},PresenceError:function(a){Candy.Core.log("[Jabber:Room] Presence Error");var d=Candy.Util.unescapeJid(a.attr("from")),e=b.getBareJidFromJid(d),f=Candy.Core.getRooms()[e],g=f.getName();return Candy.Core.removeRoom(e),f=void 0,c(Candy).triggerHandler("candy:core.presence.error",{msg:a,type:a.children("error").children()[0].tagName.toLowerCase(),roomJid:e,roomName:g}),!0},Message:function(a){Candy.Core.log("[Jabber:Room] Message");var d,e,f;if(a.children("subject").length>0&&a.children("subject").text().length>0&&"groupchat"===a.attr("type"))d=Candy.Util.unescapeJid(b.getBareJidFromJid(a.attr("from"))),e={name:b.getNodeFromJid(d),body:a.children("subject").text(),type:"subject"};else if("error"===a.attr("type")){var g=a.children("error");g.children("text").length>0&&(d=a.attr("from"),e={type:"info",body:g.children("text").text()})}else{if(!(a.children("body").length>0)){if(a.children("composing").length>0||a.children("inactive").length>0||a.children("paused").length>0){d=Candy.Util.unescapeJid(a.attr("from")),f=b.getResourceFromJid(d);var h;return a.children("composing").length>0?h="composing":a.children("paused").length>0?h="paused":a.children("inactive").length>0?h="inactive":a.children("gone").length>0&&(h="gone"),c(Candy).triggerHandler("candy:core.message.chatstate",{name:f,roomJid:d,chatstate:h}),!0}return!0}if("chat"===a.attr("type")||"normal"===a.attr("type")){d=Candy.Util.unescapeJid(a.attr("from"));var i=b.getBareJidFromJid(d),j=!Candy.Core.getRoom(i);f=j?b.getNodeFromJid(d):b.getResourceFromJid(d),e={name:f,body:a.children("body").text(),type:a.attr("type"),isNoConferenceRoomJid:j}}else{d=Candy.Util.unescapeJid(b.getBareJidFromJid(a.attr("from")));var k=b.getResourceFromJid(a.attr("from"));if(k)k=b.unescapeNode(k),e={name:k,body:a.children("body").text(),type:a.attr("type")};else{if(!Candy.View.Pane.Chat.rooms[a.attr("from")])return!0;e={name:"",body:a.children("body").text(),type:"info"}}}var l=a.children('html[xmlns="'+b.NS.XHTML_IM+'"]');if(Candy.View.getOptions().enableXHTML===!0&&l.length>0){var m=l.children('body[xmlns="'+b.NS.XHTML+'"]').first().html();e.xhtmlMessage=m}}var n=a.children(a.children("delay")?"delay":'x[xmlns="'+b.NS.DELAY+'"]'),o=void 0!==n?n.attr("stamp"):null;return c(Candy).triggerHandler("candy:core.message",{roomJid:d,message:e,timestamp:o}),!0}}},a}(Candy.Core.Event||{},Strophe,jQuery),Candy.View.Observer=function(a,b){var c=!0;return a.Chat={Connection:function(a,d){var e="candy:view.connection.status-"+d.status;if(b(Candy).triggerHandler(e)===!1)return!1;switch(d.status){case Strophe.Status.CONNECTING:case Strophe.Status.AUTHENTICATING:Candy.View.Pane.Chat.Modal.show(b.i18n._("statusConnecting"),!1,!0);break;case Strophe.Status.ATTACHED:case Strophe.Status.CONNECTED:c===!0&&(Candy.View.Pane.Chat.Modal.show(b.i18n._("statusConnected")),Candy.View.Pane.Chat.Modal.hide());break;case Strophe.Status.DISCONNECTING:Candy.View.Pane.Chat.Modal.show(b.i18n._("statusDisconnecting"),!1,!0);break;case Strophe.Status.DISCONNECTED:var f=Candy.Core.isAnonymousConnection()?Strophe.getDomainFromJid(Candy.Core.getUser().getJid()):null;Candy.View.Pane.Chat.Modal.showLoginForm(b.i18n._("statusDisconnected"),f);break;case Strophe.Status.AUTHFAIL:Candy.View.Pane.Chat.Modal.showLoginForm(b.i18n._("statusAuthfail"));break;default:Candy.View.Pane.Chat.Modal.show(b.i18n._("status",d.status))}},Message:function(a,b){"message"===b.type?Candy.View.Pane.Chat.adminMessage(b.subject||"",b.message):("chat"===b.type||"groupchat"===b.type)&&Candy.View.Pane.Chat.onInfoMessage(Candy.View.getCurrent().roomJid,b.subject||"",b.message)}},a.Presence={update:function(c,d){if("leave"===d.type){var e=Candy.View.Pane.Room.getUser(d.roomJid);Candy.View.Pane.Room.close(d.roomJid),a.Presence.notifyPrivateChats(e,d.type)}else if("kick"===d.type||"ban"===d.type){var f,g=d.actor?Strophe.getNodeFromJid(d.actor):null,h=[d.roomName];switch(g&&h.push(g),d.type){case"kick":f=b.i18n._(g?"youHaveBeenKickedBy":"youHaveBeenKicked",h);break;case"ban":f=b.i18n._(g?"youHaveBeenBannedBy":"youHaveBeenBanned",h)}Candy.View.Pane.Chat.Modal.show(Mustache.to_html(Candy.View.Template.Chat.Context.adminMessageReason,{reason:d.reason,_action:f,_reason:b.i18n._("reasonWas",[d.reason])})),setTimeout(function(){Candy.View.Pane.Chat.Modal.hide(function(){Candy.View.Pane.Room.close(d.roomJid),a.Presence.notifyPrivateChats(d.user,d.type)})},5e3);var i={type:d.type,reason:d.reason,roomJid:d.roomJid,user:d.user};b(Candy).triggerHandler("candy:view.presence",[i])}else if(d.roomJid){if(d.roomJid=Candy.Util.unescapeJid(d.roomJid),!Candy.View.Pane.Chat.rooms[d.roomJid]){if(Candy.View.Pane.Room.init(d.roomJid,d.roomName)===!1)return!1;Candy.View.Pane.Room.show(d.roomJid)}Candy.View.Pane.Roster.update(d.roomJid,d.user,d.action,d.currentUser),Candy.View.Pane.Chat.rooms[d.user.getJid()]&&"nickchange"!==d.action&&(Candy.View.Pane.Roster.update(d.user.getJid(),d.user,d.action,d.currentUser),Candy.View.Pane.PrivateRoom.setStatus(d.user.getJid(),d.action))}},notifyPrivateChats:function(a,b){Candy.Core.log("[View:Observer] notify Private Chats");var c;for(c in Candy.View.Pane.Chat.rooms)Candy.View.Pane.Chat.rooms.hasOwnProperty(c)&&Candy.View.Pane.Room.getUser(c)&&a.getJid()===Candy.View.Pane.Room.getUser(c).getJid()&&(Candy.View.Pane.Roster.update(c,a,b,a),Candy.View.Pane.PrivateRoom.setStatus(c,b))}},a.PresenceError=function(a,c){switch(c.type){case"not-authorized":var d;c.msg.children("x").children("password").length>0&&(d=b.i18n._("passwordEnteredInvalid",[c.roomName])),Candy.View.Pane.Chat.Modal.showEnterPasswordForm(c.roomJid,c.roomName,d);break;case"conflict":Candy.View.Pane.Chat.Modal.showNicknameConflictForm(c.roomJid);break;case"registration-required":Candy.View.Pane.Chat.Modal.showError("errorMembersOnly",[c.roomName]);break;case"service-unavailable":Candy.View.Pane.Chat.Modal.showError("errorMaxOccupantsReached",[c.roomName])}},a.Message=function(a,b){"subject"===b.message.type?(Candy.View.Pane.Chat.rooms[b.roomJid]||(Candy.View.Pane.Room.init(b.roomJid,b.message.name),Candy.View.Pane.Room.show(b.roomJid)),Candy.View.Pane.Room.setSubject(b.roomJid,b.message.body)):"info"===b.message.type?Candy.View.Pane.Chat.infoMessage(b.roomJid,b.message.body):("chat"!==b.message.type||Candy.View.Pane.Chat.rooms[b.roomJid]||Candy.View.Pane.PrivateRoom.open(b.roomJid,b.message.name,!1,b.message.isNoConferenceRoomJid),Candy.View.Pane.Message.show(b.roomJid,b.message.name,b.message.body,b.message.xhtmlMessage,b.timestamp))},a.Login=function(a,b){Candy.View.Pane.Chat.Modal.showLoginForm(null,b.presetJid)},a.AutojoinMissing=function(){c=!1,Candy.View.Pane.Chat.Modal.showError("errorAutojoinMissing")},a}(Candy.View.Observer||{},jQuery),Candy.View.Pane=function(a,b){return a.Window={_hasFocus:!0,_plainTitle:document.title,_unreadMessagesCount:0,autoscroll:!0,hasFocus:function(){return a.Window._hasFocus},increaseUnreadMessages:function(){a.Window.renderUnreadMessages(++a.Window._unreadMessagesCount)},reduceUnreadMessages:function(b){a.Window._unreadMessagesCount-=b,a.Window._unreadMessagesCount<=0?a.Window.clearUnreadMessages():a.Window.renderUnreadMessages(a.Window._unreadMessagesCount)},clearUnreadMessages:function(){a.Window._unreadMessagesCount=0,document.title=a.Window._plainTitle},renderUnreadMessages:function(b){document.title=Candy.View.Template.Window.unreadmessages.replace("{{count}}",b).replace("{{title}}",a.Window._plainTitle)},onFocus:function(){a.Window._hasFocus=!0,Candy.View.getCurrent().roomJid&&(a.Room.setFocusToForm(Candy.View.getCurrent().roomJid),a.Chat.clearUnreadMessages(Candy.View.getCurrent().roomJid)) -},onBlur:function(){a.Window._hasFocus=!1}},a.Chat={rooms:[],addTab:function(c,d,e){var f=Candy.Util.jidToId(c),g=Mustache.to_html(Candy.View.Template.Chat.tab,{roomJid:c,roomId:f,name:d||Strophe.getNodeFromJid(c),privateUserChat:function(){return"chat"===e},roomType:e}),h=b(g).appendTo("#chat-tabs");h.click(a.Chat.tabClick),b("a.close",h).click(a.Chat.tabClose),a.Chat.fitTabs()},getTab:function(a){return b("#chat-tabs").children('li[data-roomjid="'+a+'"]')},removeTab:function(b){a.Chat.getTab(b).remove(),a.Chat.fitTabs()},setActiveTab:function(a){b("#chat-tabs").children().each(function(){var c=b(this);c.attr("data-roomjid")===a?c.addClass("active"):c.removeClass("active")})},increaseUnreadMessages:function(b){var c=this.getTab(b).find(".unread");c.show().text(""!==c.text()?parseInt(c.text(),10)+1:1),"chat"===a.Chat.rooms[b].type&&a.Window.increaseUnreadMessages()},clearUnreadMessages:function(b){var c=a.Chat.getTab(b).find(".unread");a.Window.reduceUnreadMessages(c.text()),c.hide().text("")},tabClick:function(c){var d=Candy.View.getCurrent().roomJid;a.Chat.rooms[d].scrollPosition=a.Room.getPane(d,".message-pane-wrapper").scrollTop(),a.Room.show(b(this).attr("data-roomjid")),c.preventDefault()},tabClose:function(){var c=b(this).parent().attr("data-roomjid");return"chat"===a.Chat.rooms[c].type?a.Room.close(c):Candy.Core.Action.Jabber.Room.Leave(c),!1},allTabsClosed:function(){Candy.Core.disconnect(),a.Chat.Toolbar.hide()},fitTabs:function(){var a=b("#chat-tabs").innerWidth(),c=0,d=b("#chat-tabs").children();if(d.each(function(){c+=b(this).css({width:"auto",overflow:"visible"}).outerWidth(!0)}),c>a){var e=d.outerWidth(!0)-d.width(),f=Math.floor(a/d.length)-e;d.css({width:f,overflow:"hidden"})}},adminMessage:function(c,d){if(Candy.View.getCurrent().roomJid){var e=Mustache.to_html(Candy.View.Template.Chat.adminMessage,{subject:c,message:d,sender:b.i18n._("administratorMessageSubject"),time:Candy.Util.localizedTime((new Date).toGMTString())});b("#chat-rooms").children().each(function(){a.Room.appendToMessagePane(b(this).attr("data-roomjid"),e)}),a.Room.scrollToBottom(Candy.View.getCurrent().roomJid),b(Candy).triggerHandler("candy:view.chat.admin-message",{subject:c,message:d})}},infoMessage:function(b,c,d){a.Chat.onInfoMessage(b,c,d)},onInfoMessage:function(c,d,e){if(Candy.View.getCurrent().roomJid){var f=Mustache.to_html(Candy.View.Template.Chat.infoMessage,{subject:d,message:b.i18n._(e),time:Candy.Util.localizedTime((new Date).toGMTString())});a.Room.appendToMessagePane(c,f),Candy.View.getCurrent().roomJid===c&&a.Room.scrollToBottom(Candy.View.getCurrent().roomJid)}},Toolbar:{_supportsNativeAudio:!1,init:function(){b("#emoticons-icon").click(function(b){a.Chat.Context.showEmoticonsMenu(b.currentTarget),b.stopPropagation()}),b("#chat-autoscroll-control").click(a.Chat.Toolbar.onAutoscrollControlClick);var c=document.createElement("audio");a.Chat.Toolbar._supportsNativeAudio=!(!c.canPlayType||!c.canPlayType("audio/mpeg;").replace(/no/,"")),b("#chat-sound-control").click(a.Chat.Toolbar.onSoundControlClick),Candy.Util.cookieExists("candy-nosound")&&b("#chat-sound-control").click(),b("#chat-statusmessage-control").click(a.Chat.Toolbar.onStatusMessageControlClick),Candy.Util.cookieExists("candy-nostatusmessages")&&b("#chat-statusmessage-control").click()},show:function(){b("#chat-toolbar").show()},hide:function(){b("#chat-toolbar").hide()},update:function(c){var d=b("#chat-toolbar").find(".context"),e=a.Room.getUser(c);e&&e.isModerator()?d.show().click(function(b){a.Chat.Context.show(b.currentTarget,c),b.stopPropagation()}):d.hide(),a.Chat.Toolbar.updateUsercount(a.Chat.rooms[c].usercount)},playSound:function(){a.Chat.Toolbar.onPlaySound()},onPlaySound:function(){try{if(a.Chat.Toolbar._supportsNativeAudio)new Audio(Candy.View.getOptions().assets+"notify.mp3").play();else{var b=document.getElementById("chat-sound-player");b.SetVariable("method:stop",""),b.SetVariable("method:play","")}}catch(c){}},onSoundControlClick:function(){var c=b("#chat-sound-control");c.hasClass("checked")?(a.Chat.Toolbar.playSound=function(){},Candy.Util.setCookie("candy-nosound","1",365)):(a.Chat.Toolbar.playSound=function(){a.Chat.Toolbar.onPlaySound()},Candy.Util.deleteCookie("candy-nosound")),c.toggleClass("checked")},onAutoscrollControlClick:function(){var c=b("#chat-autoscroll-control");c.hasClass("checked")?(a.Room.scrollToBottom=function(b){a.Room.onScrollToStoredPosition(b)},a.Window.autoscroll=!1):(a.Room.scrollToBottom=function(b){a.Room.onScrollToBottom(b)},a.Room.scrollToBottom(Candy.View.getCurrent().roomJid),a.Window.autoscroll=!0),c.toggleClass("checked")},onStatusMessageControlClick:function(){var c=b("#chat-statusmessage-control");c.hasClass("checked")?(a.Chat.infoMessage=function(){},Candy.Util.setCookie("candy-nostatusmessages","1",365)):(a.Chat.infoMessage=function(b,c,d){a.Chat.onInfoMessage(b,c,d)},Candy.Util.deleteCookie("candy-nostatusmessages")),c.toggleClass("checked")},updateUsercount:function(a){b("#chat-usercount").text(a)}},Modal:{show:function(c,d,e){d?a.Chat.Modal.showCloseControl():a.Chat.Modal.hideCloseControl(),e?a.Chat.Modal.showSpinner():a.Chat.Modal.hideSpinner(),b("#chat-modal").stop(!1,!0),b("#chat-modal-body").html(c),b("#chat-modal").fadeIn("fast"),b("#chat-modal-overlay").show()},hide:function(a){b("#chat-modal").fadeOut("fast",function(){b("#chat-modal-body").text(""),b("#chat-modal-overlay").hide()}),b(document).keydown(function(a){27===a.which&&a.preventDefault()}),a&&a()},showSpinner:function(){b("#chat-modal-spinner").show()},hideSpinner:function(){b("#chat-modal-spinner").hide()},showCloseControl:function(){b("#admin-message-cancel").show().click(function(b){a.Chat.Modal.hide(),b.preventDefault()}),b(document).keydown(function(b){27===b.which&&(a.Chat.Modal.hide(),b.preventDefault())})},hideCloseControl:function(){b("#admin-message-cancel").hide().click(function(){})},showLoginForm:function(c,d){a.Chat.Modal.show((c?c:"")+Mustache.to_html(Candy.View.Template.Login.form,{_labelNickname:b.i18n._("labelNickname"),_labelUsername:b.i18n._("labelUsername"),_labelPassword:b.i18n._("labelPassword"),_loginSubmit:b.i18n._("loginSubmit"),displayPassword:!Candy.Core.isAnonymousConnection(),displayUsername:!d,displayNickname:Candy.Core.isAnonymousConnection(),presetJid:d?d:!1})),b("#login-form").children(":input:first").focus(),b("#login-form").submit(function(){var a=b("#username").val(),c=b("#password").val();if(Candy.Core.isAnonymousConnection())Candy.Core.connect(d,null,a);else{var e=Candy.Core.getUser()&&a.indexOf("@")<0?a+"@"+Strophe.getDomainFromJid(Candy.Core.getUser().getJid()):a;e.indexOf("@")<0&&!Candy.Core.getUser()?Candy.View.Pane.Chat.Modal.showLoginForm(b.i18n._("loginInvalid")):Candy.Core.connect(e,c)}return!1})},showEnterPasswordForm:function(c,d,e){a.Chat.Modal.show(Mustache.to_html(Candy.View.Template.PresenceError.enterPasswordForm,{roomName:d,_labelPassword:b.i18n._("labelPassword"),_label:e?e:b.i18n._("enterRoomPassword",[d]),_joinSubmit:b.i18n._("enterRoomPasswordSubmit")}),!0),b("#password").focus(),b("#enter-password-form").submit(function(){var d=b("#password").val();return a.Chat.Modal.hide(function(){Candy.Core.Action.Jabber.Room.Join(c,d)}),!1})},showNicknameConflictForm:function(c){a.Chat.Modal.show(Mustache.to_html(Candy.View.Template.PresenceError.nicknameConflictForm,{_labelNickname:b.i18n._("labelNickname"),_label:b.i18n._("nicknameConflict"),_loginSubmit:b.i18n._("loginSubmit")})),b("#nickname").focus(),b("#nickname-conflict-form").submit(function(){var d=b("#nickname").val();return a.Chat.Modal.hide(function(){Candy.Core.getUser().data.nick=d,Candy.Core.Action.Jabber.Room.Join(c)}),!1})},showError:function(c,d){a.Chat.Modal.show(Mustache.to_html(Candy.View.Template.PresenceError.displayError,{_error:b.i18n._(c,d)}),!0)}},Tooltip:{show:function(a,c){var d=b("#tooltip"),e=b(a.currentTarget);if(c||(c=e.attr("data-tooltip")),0===d.length){var f=Mustache.to_html(Candy.View.Template.Chat.tooltip);b("#chat-pane").append(f),d=b("#tooltip")}b("#context-menu").hide(),d.stop(!1,!0),d.children("div").html(c);var g=e.offset(),h=Candy.Util.getPosLeftAccordingToWindowBounds(d,g.left),i=Candy.Util.getPosTopAccordingToWindowBounds(d,g.top);d.css({left:h.px,top:i.px}).removeClass("left-top left-bottom right-top right-bottom").addClass(h.backgroundPositionAlignment+"-"+i.backgroundPositionAlignment).fadeIn("fast"),e.mouseleave(function(a){a.stopPropagation(),b("#tooltip").stop(!1,!0).fadeOut("fast",function(){b(this).css({top:0,left:0})})})}},Context:{init:function(){if(0===b("#context-menu").length){var a=Mustache.to_html(Candy.View.Template.Chat.Context.menu);b("#chat-pane").append(a),b("#context-menu").mouseleave(function(){b(this).fadeOut("fast")})}},show:function(c,d,e){c=b(c);var f=a.Chat.rooms[d].id,g=b("#context-menu"),h=b("ul li",g);b("#tooltip").hide(),e||(e=Candy.Core.getUser()),h.remove();var i,j=this.getMenuLinks(d,e,c),k=function(a,c){return function(d){d.data.callback(d,a,c),b("#context-menu").hide()}};for(i in j)if(j.hasOwnProperty(i)){var l=j[i],m=Mustache.to_html(Candy.View.Template.Chat.Context.menulinks,{roomId:f,"class":l["class"],id:i,label:l.label});b("ul",g).append(m),b("#context-menu-"+i).bind("click",l,k(d,e))}if(i){var n=c.offset(),o=Candy.Util.getPosLeftAccordingToWindowBounds(g,n.left),p=Candy.Util.getPosTopAccordingToWindowBounds(g,n.top);return g.css({left:o.px,top:p.px}).removeClass("left-top left-bottom right-top right-bottom").addClass(o.backgroundPositionAlignment+"-"+p.backgroundPositionAlignment).fadeIn("fast"),b(Candy).triggerHandler("candy:view.roster.after-context-menu",{roomJid:d,user:e,element:g}),!0}},getMenuLinks:function(c,d,e){var f,g,h={roomJid:c,user:d,elem:e,menulinks:this.initialMenuLinks(e)};b(Candy).triggerHandler("candy:view.roster.context-menu",h),f=h.menulinks;for(g in f)f.hasOwnProperty(g)&&void 0!==f[g].requiredPermission&&!f[g].requiredPermission(d,a.Room.getUser(c),e)&&delete f[g];return f},initialMenuLinks:function(){return{"private":{requiredPermission:function(a,b){return b.getNick()!==a.getNick()&&Candy.Core.getRoom(Candy.View.getCurrent().roomJid)&&!Candy.Core.getUser().isInPrivacyList("ignore",a.getJid())},"class":"private",label:b.i18n._("privateActionLabel"),callback:function(a,c,d){b("#user-"+Candy.Util.jidToId(c)+"-"+Candy.Util.jidToId(d.getJid())).click()}},ignore:{requiredPermission:function(a,b){return b.getNick()!==a.getNick()&&!Candy.Core.getUser().isInPrivacyList("ignore",a.getJid())},"class":"ignore",label:b.i18n._("ignoreActionLabel"),callback:function(a,b,c){Candy.View.Pane.Room.ignoreUser(b,c.getJid())}},unignore:{requiredPermission:function(a,b){return b.getNick()!==a.getNick()&&Candy.Core.getUser().isInPrivacyList("ignore",a.getJid())},"class":"unignore",label:b.i18n._("unignoreActionLabel"),callback:function(a,b,c){Candy.View.Pane.Room.unignoreUser(b,c.getJid())}},kick:{requiredPermission:function(a,b){return b.getNick()!==a.getNick()&&b.isModerator()&&!a.isModerator()},"class":"kick",label:b.i18n._("kickActionLabel"),callback:function(c,d,e){a.Chat.Modal.show(Mustache.to_html(Candy.View.Template.Chat.Context.contextModalForm,{_label:b.i18n._("reason"),_submit:b.i18n._("kickActionLabel")}),!0),b("#context-modal-field").focus(),b("#context-modal-form").submit(function(){return Candy.Core.Action.Jabber.Room.Admin.UserAction(d,e.getJid(),"kick",b("#context-modal-field").val()),a.Chat.Modal.hide(),!1})}},ban:{requiredPermission:function(a,b){return b.getNick()!==a.getNick()&&b.isModerator()&&!a.isModerator()},"class":"ban",label:b.i18n._("banActionLabel"),callback:function(c,d,e){a.Chat.Modal.show(Mustache.to_html(Candy.View.Template.Chat.Context.contextModalForm,{_label:b.i18n._("reason"),_submit:b.i18n._("banActionLabel")}),!0),b("#context-modal-field").focus(),b("#context-modal-form").submit(function(){return Candy.Core.Action.Jabber.Room.Admin.UserAction(d,e.getJid(),"ban",b("#context-modal-field").val()),a.Chat.Modal.hide(),!1})}},subject:{requiredPermission:function(a,b){return b.getNick()===a.getNick()&&b.isModerator()},"class":"subject",label:b.i18n._("setSubjectActionLabel"),callback:function(c,d){a.Chat.Modal.show(Mustache.to_html(Candy.View.Template.Chat.Context.contextModalForm,{_label:b.i18n._("subject"),_submit:b.i18n._("setSubjectActionLabel")}),!0),b("#context-modal-field").focus(),b("#context-modal-form").submit(function(c){Candy.Core.Action.Jabber.Room.Admin.SetSubject(d,b("#context-modal-field").val()),a.Chat.Modal.hide(),c.preventDefault()})}}}},showEmoticonsMenu:function(a){a=b(a);var c,d=a.offset(),e=b("#context-menu"),f=b("ul",e),g="";for(b("#tooltip").hide(),c=Candy.Util.Parser.emoticons.length-1;c>=0;c--)g=''+Candy.Util.Parser.emoticons[c].plain+''+g;f.html('
        • '+g+"
        • "),f.find("img").click(function(){var a=Candy.View.Pane.Room.getPane(Candy.View.getCurrent().roomJid,".message-form").children(".field"),c=a.val(),d=b(this).attr("alt")+" ";a.val(c?c+" "+d:d).focus()});var h=Candy.Util.getPosLeftAccordingToWindowBounds(e,d.left),i=Candy.Util.getPosTopAccordingToWindowBounds(e,d.top);return e.css({left:h.px,top:i.px}).removeClass("left-top left-bottom right-top right-bottom").addClass(h.backgroundPositionAlignment+"-"+i.backgroundPositionAlignment).fadeIn("fast"),!0}}},a.Room={init:function(c,d,e){e=e||"groupchat",c=Candy.Util.unescapeJid(c);var f={roomJid:c,type:e};if(b(Candy).triggerHandler("candy:view.room.before-add",f)===!1)return!1;Candy.Util.isEmptyObject(a.Chat.rooms)&&a.Chat.Toolbar.show();var g=Candy.Util.jidToId(c);return a.Chat.rooms[c]={id:g,usercount:0,name:d,type:e,messageCount:0,scrollPosition:-1},b("#chat-rooms").append(Mustache.to_html(Candy.View.Template.Room.pane,{roomId:g,roomJid:c,roomType:e,form:{_messageSubmit:b.i18n._("messageSubmit")},roster:{_userOnline:b.i18n._("userOnline")}},{roster:Candy.View.Template.Roster.pane,messages:Candy.View.Template.Message.pane,form:Candy.View.Template.Room.form})),a.Chat.addTab(c,d,e),a.Room.getPane(c,".message-form").submit(a.Message.submit),f.element=a.Room.getPane(c),b(Candy).triggerHandler("candy:view.room.after-add",f),g},show:function(c){var d,e=a.Chat.rooms[c].id;b(".room-pane").each(function(){var f=b(this);d={roomJid:f.attr("data-roomjid"),element:f},f.attr("id")==="chat-room-"+e?(f.show(),Candy.View.getCurrent().roomJid=c,a.Chat.setActiveTab(c),a.Chat.Toolbar.update(c),a.Chat.clearUnreadMessages(c),a.Room.setFocusToForm(c),a.Room.scrollToBottom(c),b(Candy).triggerHandler("candy:view.room.after-show",d)):(f.hide(),b(Candy).triggerHandler("candy:view.room.after-hide",d))})},setSubject:function(c,d){d=Candy.Util.Parser.linkify(Candy.Util.Parser.escape(d));var e=Mustache.to_html(Candy.View.Template.Room.subject,{subject:d,roomName:a.Chat.rooms[c].name,_roomSubject:b.i18n._("roomSubject"),time:Candy.Util.localizedTime((new Date).toGMTString())});a.Room.appendToMessagePane(c,e),a.Room.scrollToBottom(c),b(Candy).triggerHandler("candy:view.room.after-subject-change",{roomJid:c,element:a.Room.getPane(c),subject:d})},close:function(c){a.Chat.removeTab(c),a.Window.clearUnreadMessages(),a.Room.getPane(c).remove();var d=b("#chat-rooms").children();Candy.View.getCurrent().roomJid===c&&(Candy.View.getCurrent().roomJid=null,0===d.length?a.Chat.allTabsClosed():a.Room.show(d.last().attr("data-roomjid"))),delete a.Chat.rooms[c],b(Candy).triggerHandler("candy:view.room.after-close",{roomJid:c})},appendToMessagePane:function(b,c){a.Room.getPane(b,".message-pane").append(c),a.Chat.rooms[b].messageCount++,a.Room.sliceMessagePane(b)},sliceMessagePane:function(b){if(a.Window.autoscroll){var c=Candy.View.getOptions().messages;a.Chat.rooms[b].messageCount>c.limit&&(a.Room.getPane(b,".message-pane").children().slice(0,c.remove).remove(),a.Chat.rooms[b].messageCount-=c.remove)}},scrollToBottom:function(b){a.Room.onScrollToBottom(b)},onScrollToBottom:function(b){var c=a.Room.getPane(b,".message-pane-wrapper");c.scrollTop(c.prop("scrollHeight"))},onScrollToStoredPosition:function(b){if(a.Chat.rooms[b].scrollPosition>-1){var c=a.Room.getPane(b,".message-pane-wrapper");c.scrollTop(a.Chat.rooms[b].scrollPosition),a.Chat.rooms[b].scrollPosition=-1}},setFocusToForm:function(b){var c=a.Room.getPane(b,".message-form");if(c)try{c.children(".field")[0].focus()}catch(d){}},setUser:function(c,d){a.Chat.rooms[c].user=d;var e=a.Room.getPane(c),f=b("#chat-pane");e.attr("data-userjid",d.getJid()),d.isModerator()?(d.getRole()===d.ROLE_MODERATOR&&f.addClass("role-moderator"),d.getAffiliation()===d.AFFILIATION_OWNER&&f.addClass("affiliation-owner")):f.removeClass("role-moderator affiliation-owner"),a.Chat.Context.init()},getUser:function(b){return a.Chat.rooms[b].user},ignoreUser:function(a,b){Candy.Core.Action.Jabber.Room.IgnoreUnignore(b),Candy.View.Pane.Room.addIgnoreIcon(a,b)},unignoreUser:function(a,b){Candy.Core.Action.Jabber.Room.IgnoreUnignore(b),Candy.View.Pane.Room.removeIgnoreIcon(a,b)},addIgnoreIcon:function(a,c){Candy.View.Pane.Chat.rooms[c]&&b("#user-"+Candy.View.Pane.Chat.rooms[c].id+"-"+Candy.Util.jidToId(c)).addClass("status-ignored"),Candy.View.Pane.Chat.rooms[Strophe.getBareJidFromJid(a)]&&b("#user-"+Candy.View.Pane.Chat.rooms[Strophe.getBareJidFromJid(a)].id+"-"+Candy.Util.jidToId(c)).addClass("status-ignored")},removeIgnoreIcon:function(a,c){Candy.View.Pane.Chat.rooms[c]&&b("#user-"+Candy.View.Pane.Chat.rooms[c].id+"-"+Candy.Util.jidToId(c)).removeClass("status-ignored"),Candy.View.Pane.Chat.rooms[Strophe.getBareJidFromJid(a)]&&b("#user-"+Candy.View.Pane.Chat.rooms[Strophe.getBareJidFromJid(a)].id+"-"+Candy.Util.jidToId(c)).removeClass("status-ignored")},getPane:function(c,d){return a.Chat.rooms[c]?d?a.Chat.rooms[c]["pane-"+d]?a.Chat.rooms[c]["pane-"+d]:(a.Chat.rooms[c]["pane-"+d]=b("#chat-room-"+a.Chat.rooms[c].id).find(d),a.Chat.rooms[c]["pane-"+d]):b("#chat-room-"+a.Chat.rooms[c].id):void 0},changeDataUserJidIfUserIsMe:function(a,c){if(c.getNick()===Candy.Core.getUser().getNick()){var d=b("#chat-room-"+a);d.attr("data-userjid",Strophe.getBareJidFromJid(d.attr("data-userjid"))+"/"+c.getNick())}}},a.PrivateRoom={open:function(c,d,e,f){var g=f?Candy.Core.getUser():a.Room.getUser(Strophe.getBareJidFromJid(c)),h={roomJid:c,roomName:d,type:"chat"};return b(Candy).triggerHandler("candy:view.private-room.before-open",h)===!1?!1:Candy.Core.getUser().isInPrivacyList("ignore",c)?!1:a.Chat.rooms[c]||a.Room.init(c,d,"chat")!==!1?(e&&a.Room.show(c),a.Roster.update(c,new Candy.Core.ChatUser(c,d),"join",g),a.Roster.update(c,g,"join",g),a.PrivateRoom.setStatus(c,"join"),f&&a.Chat.infoMessage(c,b.i18n._("presenceUnknownWarningSubject"),b.i18n._("presenceUnknownWarning")),h.element=a.Room.getPane(c),void b(Candy).triggerHandler("candy:view.private-room.after-open",h)):!1},setStatus:function(b,c){var d=a.Room.getPane(b,".message-form");"join"===c?(a.Chat.getTab(b).addClass("online").removeClass("offline"),d.children(".field").removeAttr("disabled"),d.children(".submit").removeAttr("disabled"),a.Chat.getTab(b)):"leave"===c&&(a.Chat.getTab(b).addClass("offline").removeClass("online"),d.children(".field").attr("disabled",!0),d.children(".submit").attr("disabled",!0))},changeNick:function(c,d){Candy.Core.log("[View:Pane:PrivateRoom] changeNick");var e,f,g=c+"/"+d.getPreviousNick(),h=c+"/"+d.getNick(),i=Candy.Util.jidToId(g),j=Candy.Util.jidToId(h),k=a.Chat.rooms[g];a.Chat.rooms[h]&&a.Room.close(h),k?(k.name=d.getNick(),k.id=j,a.Chat.rooms[h]=k,delete a.Chat.rooms[g],e=b("#chat-room-"+i),e&&(e.attr("data-roomjid",h),e.attr("id","chat-room-"+j),f=b('#chat-tabs li[data-roomjid="'+g+'"]'),f.attr("data-roomjid",h),f.children("a.label").text("@"+d.getNick()),Candy.View.getCurrent().roomJid===g&&(Candy.View.getCurrent().roomJid=h))):(e=b('.room-pane.roomtype-chat[data-userjid="'+g+'"]'),e.length&&(i=Candy.Util.jidToId(e.attr("data-roomjid")),e.attr("data-userjid",h))),e&&e.length&&a.Roster.changeNick(i,d)}},a.Roster={update:function(c,d,e,f){Candy.Core.log("[View:Pane:Roster] "+e);var g=a.Chat.rooms[c].id,h=Candy.Util.jidToId(d.getJid()),i=-1,j=b("#user-"+g+"-"+h),k={roomJid:c,user:d,action:e,element:j};if(b(Candy).triggerHandler("candy:view.roster.before-update",k),"join"===e){i=1;var l=Mustache.to_html(Candy.View.Template.Roster.user,{roomId:g,userId:h,userJid:d.getJid(),nick:d.getNick(),displayNick:Candy.Util.crop(d.getNick(),Candy.View.getOptions().crop.roster.nickname),role:d.getRole(),affiliation:d.getAffiliation(),me:void 0!==f&&d.getNick()===f.getNick(),tooltipRole:b.i18n._("tooltipRole"),tooltipIgnored:b.i18n._("tooltipIgnored")});if(j.length<1){var m=!1,n=a.Room.getPane(c,".roster-pane");if(n.children().length>0){var o=d.getNick().toUpperCase();n.children().each(function(){var a=b(this);return a.attr("data-nick").toUpperCase()>o?(a.before(l),m=!0,!1):!0})}m||n.append(l),a.Roster.showJoinAnimation(d,h,g,c,f)}else i=0,j.replaceWith(l),b("#user-"+g+"-"+h).css({opacity:1}).show(),void 0!==f&&d.getNick()===f.getNick()&&a.Room.getUser(c)&&a.Chat.Toolbar.update(c);void 0!==f&&f.getNick()===d.getNick()?a.Room.setUser(c,d):b("#user-"+g+"-"+h).click(a.Roster.userClick),b("#user-"+g+"-"+h+" .context").click(function(b){a.Chat.Context.show(b.currentTarget,c,d),b.stopPropagation()}),void 0!==f&&f.isInPrivacyList("ignore",d.getJid())&&Candy.View.Pane.Room.addIgnoreIcon(c,d.getJid())}else if("leave"===e)a.Roster.leaveAnimation("user-"+g+"-"+h),"chat"===a.Chat.rooms[c].type?a.Chat.onInfoMessage(c,b.i18n._("userLeftRoom",[d.getNick()])):a.Chat.infoMessage(c,b.i18n._("userLeftRoom",[d.getNick()]));else if("nickchange"===e){i=0,a.Roster.changeNick(g,d),a.Room.changeDataUserJidIfUserIsMe(g,d),a.PrivateRoom.changeNick(c,d);var p=b.i18n._("userChangedNick",[d.getPreviousNick(),d.getNick()]);a.Chat.onInfoMessage(c,p)}else"kick"===e?(a.Roster.leaveAnimation("user-"+g+"-"+h),a.Chat.onInfoMessage(c,b.i18n._("userHasBeenKickedFromRoom",[d.getNick()]))):"ban"===e&&(a.Roster.leaveAnimation("user-"+g+"-"+h),a.Chat.onInfoMessage(c,b.i18n._("userHasBeenBannedFromRoom",[d.getNick()])));Candy.View.Pane.Chat.rooms[c].usercount+=i,c===Candy.View.getCurrent().roomJid&&Candy.View.Pane.Chat.Toolbar.updateUsercount(Candy.View.Pane.Chat.rooms[c].usercount),k.element=b("#user-"+g+"-"+h),b(Candy).triggerHandler("candy:view.roster.after-update",k)},userClick:function(){var c=b(this);a.PrivateRoom.open(c.attr("data-jid"),c.attr("data-nick"),!0)},showJoinAnimation:function(c,d,e,f,g){var h="user-"+e+"-"+d,i=b("#"+h);c.getPreviousNick()&&i&&i.is(":visible")!==!1||(a.Roster.joinAnimation(h),void 0!==g&&c.getNick()!==g.getNick()&&a.Room.getUser(f)&&("chat"===a.Chat.rooms[f].type?a.Chat.onInfoMessage(f,b.i18n._("userJoinedRoom",[c.getNick()])):a.Chat.infoMessage(f,b.i18n._("userJoinedRoom",[c.getNick()]))))},joinAnimation:function(a){b("#"+a).stop(!0).slideDown("normal",function(){b(this).animate({opacity:1})})},leaveAnimation:function(a){b("#"+a).stop(!0).attr("id","#"+a+"-leaving").animate({opacity:0},{complete:function(){b(this).slideUp("normal",function(){b(this).remove()})}})},changeNick:function(a,c){Candy.Core.log("[View:Pane:Roster] changeNick");var d=Strophe.getBareJidFromJid(c.getJid())+"/"+c.getPreviousNick(),e="user-"+a+"-"+Candy.Util.jidToId(d),f=b("#"+e);f.attr("data-nick",c.getNick()),f.attr("data-jid",c.getJid()),f.children("div.label").text(c.getNick()),f.attr("id","user-"+a+"-"+Candy.Util.jidToId(c.getJid()))}},a.Message={submit:function(c){var d,e=Candy.View.getCurrent().roomJid,f=Candy.View.Pane.Chat.rooms[e].type,g=b(this).children(".field").val().substring(0,Candy.View.getOptions().crop.message.body),h={roomJid:e,message:g,xhtmlMessage:d};return b(Candy).triggerHandler("candy:view.message.before-send",h)===!1?void c.preventDefault():(g=h.message,d=h.xhtmlMessage,Candy.Core.Action.Jabber.Room.Message(e,g,f,d),"chat"===f&&g&&a.Message.show(e,a.Room.getUser(e).getNick(),g),b(this).children(".field").val("").focus(),void c.preventDefault())},show:function(c,d,e,f,g){e=Candy.Util.Parser.all(e.substring(0,Candy.View.getOptions().crop.message.body)),f&&(f=Candy.Util.parseAndCropXhtml(f,Candy.View.getOptions().crop.message.body));var h={roomJid:c,name:d,message:e,xhtmlMessage:f};if(b(Candy).triggerHandler("candy:view.message.before-show",h)!==!1&&(e=h.message,f=h.xhtmlMessage,void 0!==f&&f.length>0&&(e=f),e)){var i={template:Candy.View.Template.Message.item,templateData:{name:d,displayName:Candy.Util.crop(d,Candy.View.getOptions().crop.message.nickname),message:e,time:Candy.Util.localizedTime(g||(new Date).toGMTString())}};b(Candy).triggerHandler("candy:view.message.before-render",i);var j=Mustache.to_html(i.template,i.templateData);a.Room.appendToMessagePane(c,j);var k=a.Room.getPane(c,".message-pane").children().last();k.find("a.label").click(function(b){b.preventDefault();var e=Candy.Core.getRoom(c);return e&&d!==a.Room.getUser(Candy.View.getCurrent().roomJid).getNick()&&e.getRoster().get(c+"/"+d)&&Candy.View.Pane.PrivateRoom.open(c+"/"+d,d,!0)===!1?!1:void 0}),Candy.View.getCurrent().roomJid===c&&a.Window.hasFocus()||(a.Chat.increaseUnreadMessages(c),"chat"!==Candy.View.Pane.Chat.rooms[c].type||a.Window.hasFocus()||a.Chat.Toolbar.playSound()),Candy.View.getCurrent().roomJid===c&&a.Room.scrollToBottom(c),h.element=k,b(Candy).triggerHandler("candy:view.message.after-show",h)}}},a}(Candy.View.Pane||{},jQuery),Candy.View.Template=function(a){return a.Window={unreadmessages:"({{count}}) {{title}}"},a.Chat={pane:'
          {{> tabs}}{{> toolbar}}{{> rooms}}
          {{> modal}}',rooms:'
          ',tabs:'
            ',tab:'
          • {{#privateUserChat}}@{{/privateUserChat}}{{name}}×
          • ',modal:'
            ',adminMessage:'
          • {{time}}
            {{sender}}{{subject}} {{message}}
          • ',infoMessage:'
          • {{time}}
            {{subject}} {{message}}
          • ',toolbar:'
            • {{> soundcontrol}}
            ',soundcontrol:'',Context:{menu:'
              ',menulinks:'
            • {{label}}
            • ',contextModalForm:'
              ',adminMessageReason:'×

              {{_action}}

              {{#reason}}

              {{_reason}}

              {{/reason}}'},tooltip:'
              '},a.Room={pane:'
              {{> roster}}{{> messages}}{{> form}}
              ',subject:'
            • {{time}}
              {{roomName}}{{_roomSubject}} {{{subject}}}
            • ',form:'
              '},a.Roster={pane:'
              ',user:'
              {{displayNick}}
              '},a.Message={pane:'
                ',item:'
              • {{time}}
                {{displayName}}{{{message}}}
              • '},a.Login={form:''},a.PresenceError={enterPasswordForm:'{{_label}}
                ',nicknameConflictForm:'{{_label}}
                ',displayError:"{{_error}}"},a}(Candy.View.Template||{}),Candy.View.Translation={en:{status:"Status: %s",statusConnecting:"Connecting...",statusConnected:"Connected",statusDisconnecting:"Disconnecting...",statusDisconnected:"Disconnected",statusAuthfail:"Authentication failed",roomSubject:"Subject:",messageSubmit:"Send",labelUsername:"Username:",labelNickname:"Nickname:",labelPassword:"Password:",loginSubmit:"Login",loginInvalid:"Invalid JID",reason:"Reason:",subject:"Subject:",reasonWas:"Reason was: %s.",kickActionLabel:"Kick",youHaveBeenKickedBy:"You have been kicked from %2$s by %1$s",youHaveBeenKicked:"You have been kicked from %s",banActionLabel:"Ban",youHaveBeenBannedBy:"You have been banned from %1$s by %2$s",youHaveBeenBanned:"You have been banned from %s",privateActionLabel:"Private chat",ignoreActionLabel:"Ignore",unignoreActionLabel:"Unignore",setSubjectActionLabel:"Change Subject",administratorMessageSubject:"Administrator",userJoinedRoom:"%s joined the room.",userLeftRoom:"%s left the room.",userHasBeenKickedFromRoom:"%s has been kicked from the room.",userHasBeenBannedFromRoom:"%s has been banned from the room.",userChangedNick:"%1$s has changed his nickname to %2$s.",presenceUnknownWarningSubject:"Notice:",presenceUnknownWarning:"This user might be offline. We can't track his presence.",dateFormat:"dd.mm.yyyy",timeFormat:"HH:MM:ss",tooltipRole:"Moderator",tooltipIgnored:"You ignore this user",tooltipEmoticons:"Emoticons",tooltipSound:"Play sound for new private messages",tooltipAutoscroll:"Autoscroll",tooltipStatusmessage:"Display status messages",tooltipAdministration:"Room Administration",tooltipUsercount:"Room Occupants",enterRoomPassword:'Room "%s" is password protected.',enterRoomPasswordSubmit:"Join room",passwordEnteredInvalid:'Invalid password for room "%s".',nicknameConflict:"Username already in use. Please choose another one.",errorMembersOnly:'You can\'t join room "%s": Insufficient rights.',errorMaxOccupantsReached:'You can\'t join room "%s": Too many occupants.',errorAutojoinMissing:"No autojoin parameter set in configuration. Please set one to continue.",antiSpamMessage:"Please do not spam. You have been blocked for a short-time."},de:{status:"Status: %s",statusConnecting:"Verbinden...",statusConnected:"Verbunden",statusDisconnecting:"Verbindung trennen...",statusDisconnected:"Verbindung getrennt",statusAuthfail:"Authentifizierung fehlgeschlagen",roomSubject:"Thema:",messageSubmit:"Senden",labelUsername:"Benutzername:",labelNickname:"Spitzname:",labelPassword:"Passwort:",loginSubmit:"Anmelden",loginInvalid:"Ungültige JID",reason:"Begründung:",subject:"Titel:",reasonWas:"Begründung: %s.",kickActionLabel:"Kick",youHaveBeenKickedBy:"Du wurdest soeben aus dem Raum %1$s gekickt (%2$s)",youHaveBeenKicked:"Du wurdest soeben aus dem Raum %s gekickt",banActionLabel:"Ban",youHaveBeenBannedBy:"Du wurdest soeben aus dem Raum %1$s verbannt (%2$s)",youHaveBeenBanned:"Du wurdest soeben aus dem Raum %s verbannt",privateActionLabel:"Privater Chat",ignoreActionLabel:"Ignorieren",unignoreActionLabel:"Nicht mehr ignorieren",setSubjectActionLabel:"Thema ändern",administratorMessageSubject:"Administrator",userJoinedRoom:"%s hat soeben den Raum betreten.",userLeftRoom:"%s hat soeben den Raum verlassen.",userHasBeenKickedFromRoom:"%s ist aus dem Raum gekickt worden.",userHasBeenBannedFromRoom:"%s ist aus dem Raum verbannt worden.",userChangedNick:"%1$s hat den Nicknamen zu %2$s geändert.",presenceUnknownWarningSubject:"Hinweis:",presenceUnknownWarning:"Dieser Benutzer könnte bereits abgemeldet sein. Wir können seine Anwesenheit nicht verfolgen.",dateFormat:"dd.mm.yyyy",timeFormat:"HH:MM:ss",tooltipRole:"Moderator",tooltipIgnored:"Du ignorierst diesen Benutzer",tooltipEmoticons:"Smileys",tooltipSound:"Ton abspielen bei neuen privaten Nachrichten",tooltipAutoscroll:"Autoscroll",tooltipStatusmessage:"Statusnachrichten anzeigen",tooltipAdministration:"Raum Administration",tooltipUsercount:"Anzahl Benutzer im Raum",enterRoomPassword:'Raum "%s" ist durch ein Passwort geschützt.',enterRoomPasswordSubmit:"Raum betreten",passwordEnteredInvalid:'Inkorrektes Passwort für Raum "%s".',nicknameConflict:"Der Benutzername wird bereits verwendet. Bitte wähle einen anderen.",errorMembersOnly:'Du kannst den Raum "%s" nicht betreten: Ungenügende Rechte.',errorMaxOccupantsReached:'Du kannst den Raum "%s" nicht betreten: Benutzerlimit erreicht.',errorAutojoinMissing:'Keine "autojoin" Konfiguration gefunden. Bitte setze eine konfiguration um fortzufahren.',antiSpamMessage:"Bitte nicht spammen. Du wurdest für eine kurze Zeit blockiert."},fr:{status:"Status : %s",statusConnecting:"Connexion…",statusConnected:"Connecté.",statusDisconnecting:"Déconnexion…",statusDisconnected:"Déconnecté.",statusAuthfail:"L'authentification a échoué",roomSubject:"Sujet :",messageSubmit:"Envoyer",labelUsername:"Nom d'utilisateur :",labelPassword:"Mot de passe :",loginSubmit:"Connexion",loginInvalid:"JID invalide",reason:"Motif :",subject:"Titre :",reasonWas:"Motif : %s.",kickActionLabel:"Kick",youHaveBeenKickedBy:"Vous avez été expulsé du salon %1$s (%2$s)",youHaveBeenKicked:"Vous avez été expulsé du salon %s",banActionLabel:"Ban",youHaveBeenBannedBy:"Vous avez été banni du salon %1$s (%2$s)",youHaveBeenBanned:"Vous avez été banni du salon %s",privateActionLabel:"Chat privé",ignoreActionLabel:"Ignorer",unignoreActionLabel:"Ne plus ignorer",setSubjectActionLabel:"Changer le sujet",administratorMessageSubject:"Administrateur",userJoinedRoom:"%s vient d'entrer dans le salon.",userLeftRoom:"%s vient de quitter le salon.",userHasBeenKickedFromRoom:"%s a été expulsé du salon.",userHasBeenBannedFromRoom:"%s a été banni du salon.",presenceUnknownWarningSubject:"Note :",presenceUnknownWarning:"Cet utilisateur n'est malheureusement plus connecté, le message ne sera pas envoyé.",dateFormat:"dd/mm/yyyy",timeFormat:"HH:MM:ss",tooltipRole:"Modérateur",tooltipIgnored:"Vous ignorez cette personne",tooltipEmoticons:"Smileys",tooltipSound:"Jouer un son lors de la réception de nouveaux messages privés",tooltipAutoscroll:"Défilement automatique",tooltipStatusmessage:"Messages d'état",tooltipAdministration:"Administration du salon",tooltipUsercount:"Nombre d'utilisateurs dans le salon",enterRoomPassword:'Le salon "%s" est protégé par un mot de passe.',enterRoomPasswordSubmit:"Entrer dans le salon",passwordEnteredInvalid:'Le mot de passe pour le salon "%s" est invalide.',nicknameConflict:"Le nom d'utilisateur est déjà utilisé. Veuillez en choisir un autre.",errorMembersOnly:'Vous ne pouvez pas entrer dans le salon "%s" : droits insuffisants.',errorMaxOccupantsReached:'Vous ne pouvez pas entrer dans le salon "%s": Limite d\'utilisateur atteint.',antiSpamMessage:"Merci de ne pas envoyer de spam. Vous avez été bloqué pendant une courte période.."},nl:{status:"Status: %s",statusConnecting:"Verbinding maken...",statusConnected:"Verbinding is gereed",statusDisconnecting:"Verbinding verbreken...",statusDisconnected:"Verbinding is verbroken",statusAuthfail:"Authenticatie is mislukt",roomSubject:"Onderwerp:",messageSubmit:"Verstuur",labelUsername:"Gebruikersnaam:",labelPassword:"Wachtwoord:",loginSubmit:"Inloggen",loginInvalid:"JID is onjuist",reason:"Reden:",subject:"Onderwerp:",reasonWas:"De reden was: %s.",kickActionLabel:"Verwijderen",youHaveBeenKickedBy:"Je bent verwijderd van %1$s door %2$s",youHaveBeenKicked:"Je bent verwijderd van %s",banActionLabel:"Blokkeren",youHaveBeenBannedBy:"Je bent geblokkeerd van %1$s door %2$s",youHaveBeenBanned:"Je bent geblokkeerd van %s",privateActionLabel:"Prive gesprek",ignoreActionLabel:"Negeren",unignoreActionLabel:"Niet negeren",setSubjectActionLabel:"Onderwerp wijzigen",administratorMessageSubject:"Beheerder",userJoinedRoom:"%s komt de chat binnen.",userLeftRoom:"%s heeft de chat verlaten.",userHasBeenKickedFromRoom:"%s is verwijderd.",userHasBeenBannedFromRoom:"%s is geblokkeerd.",presenceUnknownWarningSubject:"Mededeling:",presenceUnknownWarning:"Deze gebruiker is waarschijnlijk offline, we kunnen zijn/haar aanwezigheid niet vaststellen.",dateFormat:"dd.mm.yyyy",timeFormat:"HH:MM:ss",tooltipRole:"Moderator",tooltipIgnored:"Je negeert deze gebruiker",tooltipEmoticons:"Emotie-iconen",tooltipSound:"Speel een geluid af bij nieuwe privé berichten.",tooltipAutoscroll:"Automatisch scrollen",tooltipStatusmessage:"Statusberichten weergeven",tooltipAdministration:"Instellingen",tooltipUsercount:"Gebruikers",enterRoomPassword:'De Chatroom "%s" is met een wachtwoord beveiligd.',enterRoomPasswordSubmit:"Ga naar Chatroom",passwordEnteredInvalid:'Het wachtwoord voor de Chatroom "%s" is onjuist.',nicknameConflict:"De gebruikersnaam is reeds in gebruik. Probeer a.u.b. een andere gebruikersnaam.",errorMembersOnly:'Je kunt niet deelnemen aan de Chatroom "%s": Je hebt onvoldoende rechten.',errorMaxOccupantsReached:'Je kunt niet deelnemen aan de Chatroom "%s": Het maximum aantal gebruikers is bereikt.',antiSpamMessage:"Het is niet toegestaan om veel berichten naar de server te versturen. Je bent voor een korte periode geblokkeerd."},es:{status:"Estado: %s",statusConnecting:"Conectando...",statusConnected:"Conectado",statusDisconnecting:"Desconectando...",statusDisconnected:"Desconectado",statusAuthfail:"Falló la autenticación",roomSubject:"Asunto:",messageSubmit:"Enviar",labelUsername:"Usuario:",labelPassword:"Clave:",loginSubmit:"Entrar",loginInvalid:"JID no válido",reason:"Razón:",subject:"Asunto:",reasonWas:"La razón fue: %s.",kickActionLabel:"Expulsar",youHaveBeenKickedBy:"Has sido expulsado de %1$s por %2$s",youHaveBeenKicked:"Has sido expulsado de %s",banActionLabel:"Prohibir",youHaveBeenBannedBy:"Has sido expulsado permanentemente de %1$s por %2$s",youHaveBeenBanned:"Has sido expulsado permanentemente de %s",privateActionLabel:"Chat privado",ignoreActionLabel:"Ignorar",unignoreActionLabel:"No ignorar",setSubjectActionLabel:"Cambiar asunto",administratorMessageSubject:"Administrador",userJoinedRoom:"%s se ha unido a la sala.",userLeftRoom:"%s ha dejado la sala.",userHasBeenKickedFromRoom:"%s ha sido expulsado de la sala.",userHasBeenBannedFromRoom:"%s ha sido expulsado permanentemente de la sala.",presenceUnknownWarningSubject:"Atención:",presenceUnknownWarning:"Éste usuario podría estar desconectado..",dateFormat:"dd.mm.yyyy",timeFormat:"HH:MM:ss",tooltipRole:"Moderador",tooltipIgnored:"Ignoras a éste usuario",tooltipEmoticons:"Emoticonos",tooltipSound:"Reproducir un sonido para nuevos mensajes privados",tooltipAutoscroll:"Desplazamiento automático",tooltipStatusmessage:"Mostrar mensajes de estado",tooltipAdministration:"Administración de la sala",tooltipUsercount:"Usuarios en la sala",enterRoomPassword:'La sala "%s" está protegida mediante contraseña.',enterRoomPasswordSubmit:"Unirse a la sala",passwordEnteredInvalid:'Contraseña incorrecta para la sala "%s".',nicknameConflict:"El nombre de usuario ya está siendo utilizado. Por favor elija otro.",errorMembersOnly:'No se puede unir a la sala "%s": no tiene privilegios suficientes.',errorMaxOccupantsReached:'No se puede unir a la sala "%s": demasiados participantes.',antiSpamMessage:"Por favor, no hagas spam. Has sido bloqueado temporalmente."},cn:{status:"状态: %s",statusConnecting:"连接中...",statusConnected:"已连接",statusDisconnecting:"断开连接中...",statusDisconnected:"已断开连接",statusAuthfail:"认证失败",roomSubject:"主题:",messageSubmit:"发送",labelUsername:"用户名:",labelPassword:"密码:",loginSubmit:"登录",loginInvalid:"用户名不合法",reason:"原因:",subject:"主题:",reasonWas:"原因是: %s.",kickActionLabel:"踢除",youHaveBeenKickedBy:"你在 %1$s 被管理者 %2$s 请出房间",banActionLabel:"禁言",youHaveBeenBannedBy:"你在 %1$s 被管理者 %2$s 禁言",privateActionLabel:"单独对话",ignoreActionLabel:"忽略",unignoreActionLabel:"不忽略",setSubjectActionLabel:"变更主题",administratorMessageSubject:"管理员",userJoinedRoom:"%s 加入房间",userLeftRoom:"%s 离开房间",userHasBeenKickedFromRoom:"%s 被请出这个房间",userHasBeenBannedFromRoom:"%s 被管理者禁言",presenceUnknownWarningSubject:"注意:",presenceUnknownWarning:"这个会员可能已经下线,不能追踪到他的连接信息",dateFormat:"dd.mm.yyyy",timeFormat:"HH:MM:ss",tooltipRole:"管理",tooltipIgnored:"你忽略了这个会员",tooltipEmoticons:"表情",tooltipSound:"新消息发音",tooltipAutoscroll:"滚动条",tooltipStatusmessage:"禁用状态消息",tooltipAdministration:"房间管理",tooltipUsercount:"房间占有者",enterRoomPassword:'登录房间 "%s" 需要密码.',enterRoomPasswordSubmit:"加入房间",passwordEnteredInvalid:'登录房间 "%s" 的密码不正确',nicknameConflict:"用户名已经存在,请另选一个",errorMembersOnly:'您的权限不够,不能登录房间 "%s" ',errorMaxOccupantsReached:'房间 "%s" 的人数已达上限,您不能登录',antiSpamMessage:"因为您在短时间内发送过多的消息 服务器要阻止您一小段时间。"},ja:{status:"ステータス: %s",statusConnecting:"接続中…",statusConnected:"接続されました",statusDisconnecting:"ディスコネクト中…",statusDisconnected:"ディスコネクトされました",statusAuthfail:"認証に失敗しました",roomSubject:"トピック:",messageSubmit:"送信",labelUsername:"ユーザーネーム:",labelPassword:"パスワード:",loginSubmit:"ログイン",loginInvalid:"ユーザーネームが正しくありません",reason:"理由:",subject:"トピック:",reasonWas:"理由: %s。",kickActionLabel:"キック",youHaveBeenKickedBy:"あなたは%2$sにより%1$sからキックされました。",youHaveBeenKicked:"あなたは%sからキックされました。",banActionLabel:"アカウントバン",youHaveBeenBannedBy:"あなたは%2$sにより%1$sからアカウントバンされました。",youHaveBeenBanned:"あなたは%sからアカウントバンされました。",privateActionLabel:"プライベートメッセージ",ignoreActionLabel:"無視する",unignoreActionLabel:"無視をやめる",setSubjectActionLabel:"トピックを変える",administratorMessageSubject:"管理者",userJoinedRoom:"%sは入室しました。",userLeftRoom:"%sは退室しました。",userHasBeenKickedFromRoom:"%sは部屋からキックされました。",userHasBeenBannedFromRoom:"%sは部屋からアカウントバンされました。",presenceUnknownWarningSubject:"忠告:",presenceUnknownWarning:"このユーザーのステータスは不明です。",dateFormat:"dd.mm.yyyy",timeFormat:"HH:MM:ss",tooltipRole:"モデレーター",tooltipIgnored:"このユーザーを無視設定にしている",tooltipEmoticons:"絵文字",tooltipSound:"新しいメッセージが届くたびに音を鳴らす",tooltipAutoscroll:"オートスクロール",tooltipStatusmessage:"ステータスメッセージを表示",tooltipAdministration:"部屋の管理",tooltipUsercount:"この部屋の参加者の数",enterRoomPassword:'"%s"の部屋に入るにはパスワードが必要です。',enterRoomPasswordSubmit:"部屋に入る",passwordEnteredInvalid:'"%s"のパスワードと異なるパスワードを入力しました。',nicknameConflict:"このユーザーネームはすでに利用されているため、別のユーザーネームを選んでください。",errorMembersOnly:'"%s"の部屋に入ることができません: 利用権限を満たしていません。',errorMaxOccupantsReached:'"%s"の部屋に入ることができません: 参加者の数はすでに上限に達しました。',antiSpamMessage:"スパムなどの行為はやめてください。あなたは一時的にブロックされました。"},sv:{status:"Status: %s",statusConnecting:"Ansluter...",statusConnected:"Ansluten",statusDisconnecting:"Kopplar från...",statusDisconnected:"Frånkopplad",statusAuthfail:"Autentisering misslyckades",roomSubject:"Ämne:",messageSubmit:"Skicka",labelUsername:"Användarnamn:",labelPassword:"Lösenord:",loginSubmit:"Logga in",loginInvalid:"Ogiltigt JID",reason:"Anledning:",subject:"Ämne:",reasonWas:"Anledningen var: %s.",kickActionLabel:"Sparka ut",youHaveBeenKickedBy:"Du har blivit utsparkad från %2$s av %1$s",youHaveBeenKicked:"Du har blivit utsparkad från %s",banActionLabel:"Bannlys",youHaveBeenBannedBy:"Du har blivit bannlyst från %1$s av %2$s",youHaveBeenBanned:"Du har blivit bannlyst från %s",privateActionLabel:"Privat chatt",ignoreActionLabel:"Blockera",unignoreActionLabel:"Avblockera",setSubjectActionLabel:"Ändra ämne",administratorMessageSubject:"Administratör",userJoinedRoom:"%s kom in i rummet.",userLeftRoom:"%s har lämnat rummet.",userHasBeenKickedFromRoom:"%s har blivit utsparkad ur rummet.",userHasBeenBannedFromRoom:"%s har blivit bannlyst från rummet.",presenceUnknownWarningSubject:"Notera:",presenceUnknownWarning:"Denna användare kan vara offline. Vi kan inte följa dennes närvaro.",dateFormat:"yyyy-mm-dd",timeFormat:"HH:MM:ss",tooltipRole:"Moderator",tooltipIgnored:"Du blockerar denna användare",tooltipEmoticons:"Smilies",tooltipSound:"Spela upp ett ljud vid nytt privat meddelande",tooltipAutoscroll:"Autoskrolla",tooltipStatusmessage:"Visa statusmeddelanden",tooltipAdministration:"Rumadministrering",tooltipUsercount:"Antal användare i rummet",enterRoomPassword:'Rummet "%s" är lösenordsskyddat.',enterRoomPasswordSubmit:"Anslut till rum",passwordEnteredInvalid:'Ogiltigt lösenord för rummet "%s".',nicknameConflict:"Upptaget användarnamn. Var god välj ett annat.",errorMembersOnly:'Du kan inte ansluta till rummet "%s": Otillräckliga rättigheter.',errorMaxOccupantsReached:'Du kan inte ansluta till rummet "%s": Rummet är fullt.',antiSpamMessage:"Var god avstå från att spamma. Du har blivit blockerad för en kort stund."},it:{status:"Stato: %s",statusConnecting:"Connessione...",statusConnected:"Connessione",statusDisconnecting:"Disconnessione...",statusDisconnected:"Disconnesso",statusAuthfail:"Autenticazione fallita",roomSubject:"Oggetto:",messageSubmit:"Invia",labelUsername:"Nome utente:",labelPassword:"Password:",loginSubmit:"Login",loginInvalid:"JID non valido",reason:"Ragione:",subject:"Oggetto:",reasonWas:"Ragione precedente: %s.",kickActionLabel:"Espelli",youHaveBeenKickedBy:"Sei stato espulso da %2$s da %1$s",youHaveBeenKicked:"Sei stato espulso da %s",banActionLabel:"Escluso",youHaveBeenBannedBy:"Sei stato escluso da %1$s da %2$s",youHaveBeenBanned:"Sei stato escluso da %s",privateActionLabel:"Stanza privata",ignoreActionLabel:"Ignora",unignoreActionLabel:"Non ignorare",setSubjectActionLabel:"Cambia oggetto",administratorMessageSubject:"Amministratore",userJoinedRoom:"%s si è unito alla stanza.",userLeftRoom:"%s ha lasciato la stanza.",userHasBeenKickedFromRoom:"%s è stato espulso dalla stanza.",userHasBeenBannedFromRoom:"%s è stato escluso dalla stanza.",presenceUnknownWarningSubject:"Nota:",presenceUnknownWarning:"Questo utente potrebbe essere offline. Non possiamo tracciare la sua presenza.",dateFormat:"dd/mm/yyyy",timeFormat:"HH:MM:ss",tooltipRole:"Moderatore",tooltipIgnored:"Stai ignorando questo utente",tooltipEmoticons:"Emoticons",tooltipSound:"Riproduci un suono quando arrivano messaggi privati",tooltipAutoscroll:"Autoscroll",tooltipStatusmessage:"Mostra messaggi di stato",tooltipAdministration:"Amministrazione stanza",tooltipUsercount:"Partecipanti alla stanza",enterRoomPassword:'La stanza "%s" è protetta da password.',enterRoomPasswordSubmit:"Unisciti alla stanza",passwordEnteredInvalid:'Password non valida per la stanza "%s".',nicknameConflict:"Nome utente già in uso. Scegline un altro.",errorMembersOnly:'Non puoi unirti alla stanza "%s": Permessi insufficienti.',errorMaxOccupantsReached:'Non puoi unirti alla stanza "%s": Troppi partecipanti.',antiSpamMessage:"Per favore non scrivere messaggi pubblicitari. Sei stato bloccato per un po' di tempo."},pt:{status:"Status: %s",statusConnecting:"Conectando...",statusConnected:"Conectado",statusDisconnecting:"Desligando...",statusDisconnected:"Desligado",statusAuthfail:"Falha na autenticação",roomSubject:"Assunto:",messageSubmit:"Enviar",labelUsername:"Usuário:",labelPassword:"Senha:",loginSubmit:"Entrar",loginInvalid:"JID inválido",reason:"Motivo:",subject:"Assunto:",reasonWas:"O motivo foi: %s.",kickActionLabel:"Excluir",youHaveBeenKickedBy:"Você foi excluido de %1$s por %2$s",youHaveBeenKicked:"Você foi excluido de %s",banActionLabel:"Bloquear",youHaveBeenBannedBy:"Você foi excluido permanentemente de %1$s por %2$s",youHaveBeenBanned:"Você foi excluido permanentemente de %s",privateActionLabel:"Bate-papo privado",ignoreActionLabel:"Ignorar",unignoreActionLabel:"Não ignorar",setSubjectActionLabel:"Trocar Assunto",administratorMessageSubject:"Administrador",userJoinedRoom:"%s entrou na sala.",userLeftRoom:"%s saiu da sala.",userHasBeenKickedFromRoom:"%s foi excluido da sala.",userHasBeenBannedFromRoom:"%s foi excluido permanentemente da sala.",presenceUnknownWarning:"Este usuário pode estar desconectado. Não é possível determinar o status.",dateFormat:"dd.mm.yyyy",timeFormat:"HH:MM:ss",tooltipRole:"Moderador",tooltipIgnored:"Você ignora este usuário",tooltipEmoticons:"Emoticons",tooltipSound:"Reproduzir o som para novas mensagens privados",tooltipAutoscroll:"Deslocamento automático",tooltipStatusmessage:"Mostrar mensagens de status",tooltipAdministration:"Administração da sala",tooltipUsercount:"Usuários na sala",enterRoomPassword:'A sala "%s" é protegida por senha.',enterRoomPasswordSubmit:"Junte-se à sala",passwordEnteredInvalid:'Senha incorreta para a sala "%s".',nicknameConflict:"O nome de usuário já está em uso. Por favor, escolha outro.",errorMembersOnly:'Você não pode participar da sala "%s": privilégios insuficientes.',errorMaxOccupantsReached:'Você não pode participar da sala "%s": muitos participantes.',antiSpamMessage:"Por favor, não envie spam. Você foi bloqueado temporariamente."},pt_br:{status:"Estado: %s",statusConnecting:"Conectando...",statusConnected:"Conectado",statusDisconnecting:"Desconectando...",statusDisconnected:"Desconectado",statusAuthfail:"Autenticação falhou",roomSubject:"Assunto:",messageSubmit:"Enviar",labelUsername:"Usuário:",labelPassword:"Senha:",loginSubmit:"Entrar",loginInvalid:"JID inválido",reason:"Motivo:",subject:"Assunto:",reasonWas:"Motivo foi: %s.",kickActionLabel:"Derrubar",youHaveBeenKickedBy:"Você foi derrubado de %2$s por %1$s",youHaveBeenKicked:"Você foi derrubado de %s",banActionLabel:"Banir",youHaveBeenBannedBy:"Você foi banido de %1$s por %2$s",youHaveBeenBanned:"Você foi banido de %s",privateActionLabel:"Conversa privada",ignoreActionLabel:"Ignorar",unignoreActionLabel:"Não ignorar",setSubjectActionLabel:"Mudar Assunto",administratorMessageSubject:"Administrador",userJoinedRoom:"%s entrou na sala.",userLeftRoom:"%s saiu da sala.",userHasBeenKickedFromRoom:"%s foi derrubado da sala.",userHasBeenBannedFromRoom:"%s foi banido da sala.",presenceUnknownWarningSubject:"Aviso:",presenceUnknownWarning:"Este usuário pode estar desconectado.. Não conseguimos rastrear sua presença..",dateFormat:"dd.mm.yyyy",timeFormat:"HH:MM:ss",tooltipRole:"Moderador",tooltipIgnored:"Você ignora este usuário",tooltipEmoticons:"Emoticons",tooltipSound:"Tocar som para novas mensagens privadas",tooltipAutoscroll:"Auto-rolagem",tooltipStatusmessage:"Exibir mensagens de estados",tooltipAdministration:"Administração de Sala",tooltipUsercount:"Participantes da Sala",enterRoomPassword:'Sala "%s" é protegida por senha.',enterRoomPasswordSubmit:"Entrar na sala",passwordEnteredInvalid:'Senha inváida para sala "%s".',nicknameConflict:"Nome de usuário já em uso. Por favor escolha outro.",errorMembersOnly:'Você não pode entrar na sala "%s": privilégios insuficientes.',errorMaxOccupantsReached:'Você não pode entrar na sala "%s": máximo de participantes atingido.',antiSpamMessage:"Por favor, não faça spam. Você foi bloqueado temporariamente."},ru:{status:"Статус: %s",statusConnecting:"Подключение...",statusConnected:"Подключено",statusDisconnecting:"Отключение...",statusDisconnected:"Отключено",statusAuthfail:"Неверный логин",roomSubject:"Топик:",messageSubmit:"Послать",labelUsername:"Имя:",labelPassword:"Пароль:",loginSubmit:"Логин",loginInvalid:"Неверный JID",reason:"Причина:",subject:"Топик:",reasonWas:"Причина была: %s.",kickActionLabel:"Выбросить",youHaveBeenKickedBy:"Пользователь %1$s выбросил вас из чата %2$s",youHaveBeenKicked:"Вас выбросили из чата %s",banActionLabel:"Запретить доступ",youHaveBeenBannedBy:"Пользователь %1$s запретил вам доступ в чат %2$s",youHaveBeenBanned:"Вам запретили доступ в чат %s",privateActionLabel:"Один-на-один чат",ignoreActionLabel:"Игнорировать",unignoreActionLabel:"Отменить игнорирование",setSubjectActionLabel:"Изменить топик",administratorMessageSubject:"Администратор",userJoinedRoom:"%s вошёл в чат.",userLeftRoom:"%s вышел из чата.",userHasBeenKickedFromRoom:"%s выброшен из чата.",userHasBeenBannedFromRoom:"%s запрещён доступ в чат.",presenceUnknownWarningSubject:"Уведомление:",presenceUnknownWarning:"Этот пользователь вероятнее всего оффлайн.",dateFormat:"mm.dd.yyyy",timeFormat:"HH:MM:ss",tooltipRole:"Модератор",tooltipIgnored:"Вы игнорируете этого пользователя.",tooltipEmoticons:"Смайлики",tooltipSound:"Озвучивать новое частное сообщение",tooltipAutoscroll:"Авто-прокручивание",tooltipStatusmessage:"Показывать статус сообщения",tooltipAdministration:"Администрирование чат комнаты",tooltipUsercount:"Участники чата",enterRoomPassword:'Чат комната "%s" защищена паролем.',enterRoomPasswordSubmit:"Войти в чат",passwordEnteredInvalid:'Неверный пароль для комнаты "%s".',nicknameConflict:"Это имя уже используется. Пожалуйста выберите другое имя.",errorMembersOnly:'Вы не можете войти в чат "%s": Недостаточно прав доступа.',errorMaxOccupantsReached:'Вы не можете войти в чат "%s": Слишком много участников.',antiSpamMessage:"Пожалуйста не рассылайте спам. Вас заблокировали на короткое время."},ca:{status:"Estat: %s",statusConnecting:"Connectant...",statusConnected:"Connectat",statusDisconnecting:"Desconnectant...",statusDisconnected:"Desconnectat",statusAuthfail:"Ha fallat la autenticació",roomSubject:"Assumpte:",messageSubmit:"Enviar",labelUsername:"Usuari:",labelPassword:"Clau:",loginSubmit:"Entrar",loginInvalid:"JID no vàlid",reason:"Raó:",subject:"Assumpte:",reasonWas:"La raó ha estat: %s.",kickActionLabel:"Expulsar",youHaveBeenKickedBy:"Has estat expulsat de %1$s per %2$s",youHaveBeenKicked:"Has estat expulsat de %s",banActionLabel:"Prohibir",youHaveBeenBannedBy:"Has estat expulsat permanentment de %1$s per %2$s",youHaveBeenBanned:"Has estat expulsat permanentment de %s",privateActionLabel:"Xat privat",ignoreActionLabel:"Ignorar",unignoreActionLabel:"No ignorar",setSubjectActionLabel:"Canviar assumpte",administratorMessageSubject:"Administrador",userJoinedRoom:"%s ha entrat a la sala.",userLeftRoom:"%s ha deixat la sala.",userHasBeenKickedFromRoom:"%s ha estat expulsat de la sala.",userHasBeenBannedFromRoom:"%s ha estat expulsat permanentment de la sala.",presenceUnknownWarningSubject:"Atenció:",presenceUnknownWarning:"Aquest usuari podria estar desconnectat ...",dateFormat:"dd.mm.yyyy",timeFormat:"HH:MM:ss",tooltipRole:"Moderador",tooltipIgnored:"Estàs ignorant aquest usuari",tooltipEmoticons:"Emoticones",tooltipSound:"Reproduir un so per a nous missatges",tooltipAutoscroll:"Desplaçament automàtic",tooltipStatusmessage:"Mostrar missatges d'estat",tooltipAdministration:"Administració de la sala",tooltipUsercount:"Usuaris dins la sala",enterRoomPassword:'La sala "%s" està protegida amb contrasenya.',enterRoomPasswordSubmit:"Entrar a la sala",passwordEnteredInvalid:'Contrasenya incorrecta per a la sala "%s".',nicknameConflict:"El nom d'usuari ja s'està utilitzant. Si us plau, escolleix-ne un altre.",errorMembersOnly:'No pots unir-te a la sala "%s": no tens prous privilegis.',errorMaxOccupantsReached:'No pots unir-te a la sala "%s": hi ha masses participants.',antiSpamMessage:"Si us plau, no facis spam. Has estat bloquejat temporalment."}}; - -//# sourceMappingURL=candy.min.map \ No newline at end of file diff --git a/candy.min.map b/candy.min.map deleted file mode 100644 index 46000e80..00000000 --- a/candy.min.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"candy.min.js","sources":["candy.bundle.js"],"names":["Candy","self","$","about","name","version","init","service","options","viewClass","View","view","Core","core","jQuery","Strophe","_status","_connection","_service","_user","_rooms","_anonymousConnection","_options","autojoin","undefined","debug","disableWindowUnload","presencePriority","resource","_addNamespace","value","addNamespace","_addNamespaces","_getEscapedJidFromJid","jid","node","getNodeFromJid","domain","getDomainFromJid","escapeNode","extend","window","console","log","Function","prototype","bind","Util","getIeVersion","call","apply","arguments","Connection","rawInput","rawOutput","caps","onbeforeunload","onWindowUnload","registerEventHandlers","addHandler","Event","Jabber","Version","NS","VERSION","Presence","Message","Bookmarks","PRIVATE","Room","Disco","DISCO_INFO","disco","_onDiscoInfo","_onDiscoItems","DISCO_ITEMS","_delegateCapabilities","CAPS","connect","jidOrHost","password","nick","reset","triggerHandler","connection","indexOf","Connect","ChatUser","Login","attach","sid","rid","disconnect","connected","each","getRooms","Action","Leave","this","getJid","handler","ns","type","id","from","getUser","setUser","user","getConnection","removeRoom","roomJid","getStropheStatus","setStropheStatus","status","isAnonymousConnection","getOptions","getRoom","sync","flush","data","_current","container","language","assets","messages","limit","remove","crop","message","nickname","body","roster","enableXHTML","_setupTranslation","i18n","load","Translation","_registerObservers","on","Observer","Chat","AutojoinMissing","update","PresenceError","_registerWindowHandlers","document","focusin","Pane","Window","onFocus","focusout","onBlur","focus","blur","resize","fitTabs","_initToolbar","Toolbar","_delegateTooltips","delegate","Tooltip","show","resources","Parser","setEmoticonPath","html","Mustache","to_html","Template","pane","tooltipEmoticons","_","tooltipSound","tooltipAutoscroll","tooltipStatusmessage","tooltipAdministration","tooltipUsercount","assetsPath","tabs","rooms","modal","toolbar","soundcontrol","getCurrent","jidToId","MD5","hexdigest","escapeJid","getResourceFromJid","unescapeJid","unescapeNode","str","len","length","substr","parseAndCropXhtml","append","createHtml","get","setCookie","lifetime_days","exp","Date","setDate","getDate","cookie","toUTCString","cookieExists","getCookie","regex","RegExp","escape","matches","exec","deleteCookie","getPosLeftAccordingToWindowBounds","elem","pos","windowWidth","width","elemWidth","outerWidth","marginDiff","backgroundPositionAlignment","px","getPosTopAccordingToWindowBounds","windowHeight","height","elemHeight","outerHeight","localizedTime","dateTime","date","iso8601toDate","format","toDateString","timestamp","parse","isNaN","struct","minutesOffset","getTimezoneOffset","replace","isEmptyObject","obj","prop","hasOwnProperty","forceRedraw","css","display","setTimeout","ie","undef","v","div","createElement","all","getElementsByTagName","innerHTML","_emoticonPath","path","emoticons","plain","image","emotify","text","i","linkify","nl2br","maxLength","currentLength","el","j","tag","attribute","cssAttrs","attr","cssName","cssValue","nodeType","ElementType","NORMAL","nodeName","toLowerCase","XHTML","validTag","attributes","getAttribute","cssText","split","validCSS","push","join","childNodes","e","xmlTextNode","xmlGenerator","createDocumentFragment","appendChild","FRAGMENT","TEXT","nodeValue","substring","parseHTML","msg","sendIQ","$iq","to","c","os","navigator","userAgent","SetNickname","Array","roomNick","presence","conn","$pres","getUniqueId","send","Roster","xmlns","CLIENT","ROSTER","tree","pres","t","toString","up","generateCapsAttrs","Services","Autojoin","BOOKMARKS","pubsubBookmarkRequest","PUBSUB","isArray","Join","valueOf","ResetIgnoreList","getEscapedJid","PRIVACY","action","order","RemoveIgnoreList","GetIgnoreList","iq","iqId","PrivacyList","SetIgnoreListActive","GetJidIfAnonymous","getNick","MUC","muc","leave","xhtmlMsg","trim","getBareJidFromJid","Invite","invitees","reason","$msg","x","MUC_USER","invitee","IgnoreUnignore","userJid","addToOrRemoveFromPrivacyList","UpdatePrivacyList","currentUser","privacyList","getPrivacyList","index","Admin","UserAction","itemObj","role","affiliation","MUC_ADMIN","SetSubject","subject","setTopic","ChatRoom","room","ChatRoster","setName","getName","setRoster","getRoster","items","add","getAll","ROLE_MODERATOR","AFFILIATION_OWNER","privacyLists","customData","previousNick","setJid","setNick","getRole","setRole","setAffiliation","getAffiliation","isModerator","list","splice","setPrivacyLists","lists","isInPrivacyList","setCustomData","getCustomData","setPreviousNick","getPreviousNick","presetJid","Status","CONNECTED","ATTACHED","DISCONNECTED","AUTHFAIL","CONNECTING","DISCONNECTING","AUTHENTICATING","ERROR","CONNFAIL","children","stanza","item","PrivacyListError","fromJid","toJid","mediatedInvite","find","directInvite","passwordNode","continueNode","continuedThread","actor","roomName","code","identity","presenceType","nickAssign","nickChange","l","$status","tagName","error","chatstate","bareRoomJid","isNoConferenceRoomJid","xhtmlChild","XHTML_IM","xhtmlMessage","first","delay","DELAY","_showConnectedMessageModal","event","args","eventName","Modal","hide","showLoginForm","adminMessage","onInfoMessage","close","notifyPrivateChats","actionLabel","actorName","translationParams","Context","adminMessageReason","_action","_reason","evtData","PrivateRoom","setStatus","showEnterPasswordForm","showNicknameConflictForm","showError","setSubject","infoMessage","open","_hasFocus","_plainTitle","title","_unreadMessagesCount","autoscroll","hasFocus","increaseUnreadMessages","renderUnreadMessages","reduceUnreadMessages","num","clearUnreadMessages","count","unreadmessages","setFocusToForm","addTab","roomType","roomId","tab","privateUserChat","appendTo","click","tabClick","tabClose","getTab","removeTab","setActiveTab","addClass","removeClass","unreadElem","parseInt","currentRoomJid","scrollPosition","getPane","scrollTop","preventDefault","parent","allTabsClosed","availableWidth","innerWidth","tabsWidth","overflow","tabDiffToRealWidth","tabWidth","Math","floor","sender","time","toGMTString","appendToMessagePane","scrollToBottom","_supportsNativeAudio","showEmoticonsMenu","currentTarget","stopPropagation","onAutoscrollControlClick","a","canPlayType","onSoundControlClick","onStatusMessageControlClick","context","me","updateUsercount","usercount","playSound","onPlaySound","Audio","play","chatSoundPlayer","getElementById","SetVariable","control","hasClass","toggleClass","onScrollToStoredPosition","onScrollToBottom","showCloseControl","showSpinner","hideCloseControl","hideSpinner","stop","fadeIn","callback","fadeOut","keydown","which","form","_labelNickname","_labelUsername","_labelPassword","_loginSubmit","displayPassword","displayUsername","displayNickname","submit","username","val","enterPasswordForm","_label","_joinSubmit","nicknameConflictForm","replacements","displayError","_error","content","tooltip","target","offset","posLeft","left","posTop","top","mouseleave","menu","links","menulinks","getMenuLinks","clickHandler","link","class","label","element","initialMenuLinks","requiredPermission","private","ignore","ignoreUser","unignore","unignoreUser","kick","contextModalForm","_submit","ban","input","emoticon","messageCount","_messageSubmit","_userOnline","_roomSubject","openRooms","last","sliceMessagePane","slice","messagePane","roomPane","chatPane","addIgnoreIcon","removeIgnoreIcon","subPane","changeDataUserJidIfUserIsMe","roomElement","switchToRoom","messageForm","removeAttr","changeNick","roomTabElement","previousPrivateRoomJid","newPrivateRoomJid","previousPrivateRoomId","newPrivateRoomId","userId","usercountDiff","userElem","displayNick","tooltipRole","tooltipIgnored","userInserted","rosterPane","userSortCompare","toUpperCase","before","showJoinAnimation","replaceWith","opacity","userClick","leaveAnimation","rosterUserId","$rosterUserElem","is","joinAnimation","elementId","slideDown","animate","complete","slideUp","previousUserJid","renderEvtData","template","templateData","displayName","en","statusConnecting","statusConnected","statusDisconnecting","statusDisconnected","statusAuthfail","roomSubject","messageSubmit","labelUsername","labelNickname","labelPassword","loginSubmit","loginInvalid","reasonWas","kickActionLabel","youHaveBeenKickedBy","youHaveBeenKicked","banActionLabel","youHaveBeenBannedBy","youHaveBeenBanned","privateActionLabel","ignoreActionLabel","unignoreActionLabel","setSubjectActionLabel","administratorMessageSubject","userJoinedRoom","userLeftRoom","userHasBeenKickedFromRoom","userHasBeenBannedFromRoom","userChangedNick","presenceUnknownWarningSubject","presenceUnknownWarning","dateFormat","timeFormat","enterRoomPassword","enterRoomPasswordSubmit","passwordEnteredInvalid","nicknameConflict","errorMembersOnly","errorMaxOccupantsReached","errorAutojoinMissing","antiSpamMessage","de","fr","nl","es","cn","ja","sv","it","pt","pt_br","ru","ca"],"mappings":"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"} \ No newline at end of file diff --git a/devbox/index.html b/devbox/index.html new file mode 100644 index 00000000..0881df58 --- /dev/null +++ b/devbox/index.html @@ -0,0 +1,50 @@ + + + + + Candy - Chats are not dead yet + + + + + + + + + +
                + + diff --git a/devbox/nginx-default.conf b/devbox/nginx-default.conf new file mode 100644 index 00000000..6bad8032 --- /dev/null +++ b/devbox/nginx-default.conf @@ -0,0 +1,14 @@ +server { + root /usr/share/nginx/html; + index index.html; + + charset utf-8; + + server_name localhost; + + location /http-bind/ { + proxy_pass http://localhost:5280/http-bind/; + proxy_buffering off; + tcp_nodelay on; + } +} diff --git a/devbox/prosody.cfg.lua b/devbox/prosody.cfg.lua new file mode 100644 index 00000000..5572bcb9 --- /dev/null +++ b/devbox/prosody.cfg.lua @@ -0,0 +1,184 @@ +-- Prosody Example Configuration File +-- +-- Information on configuring Prosody can be found on our +-- website at http://prosody.im/doc/configure +-- +-- Tip: You can check that the syntax of this file is correct +-- when you have finished by running: luac -p prosody.cfg.lua +-- If there are any errors, it will let you know what and where +-- they are, otherwise it will keep quiet. +-- +-- The only thing left to do is rename this file to remove the .dist ending, and fill in the +-- blanks. Good luck, and happy Jabbering! + + +---------- Server-wide settings ---------- +-- Settings in this section apply to the whole server and are the default settings +-- for any virtual hosts + +-- This is a (by default, empty) list of accounts that are admins +-- for the server. Note that you must create the accounts separately +-- (see http://prosody.im/doc/creating_accounts for info) +-- Example: admins = { "user1@example.com", "user2@example.net" } +admins = { } + +-- Enable use of libevent for better performance under high load +-- For more information see: http://prosody.im/doc/libevent +use_libevent = true; + +-- This is the list of modules Prosody will load on startup. +-- It looks for mod_modulename.lua in the plugins folder, so make sure that exists too. +-- Documentation on modules can be found at: http://prosody.im/doc/modules +modules_enabled = { + + -- Generally required + "roster"; -- Allow users to have a roster. Recommended ;) + "saslauth"; -- Authentication for clients and servers. Recommended if you want to log in. + "tls"; -- Add support for secure TLS on c2s/s2s connections + "dialback"; -- s2s dialback support + "disco"; -- Service discovery + + -- Not essential, but recommended + "private"; -- Private XML storage (for room bookmarks, etc.) + --"vcard"; -- Allow users to set vCards + "privacy"; -- Support privacy lists + --"compression"; -- Stream compression + + -- Nice to have + --"legacyauth"; -- Legacy authentication. Only used by some old clients and bots. + "version"; -- Replies to server version requests + "uptime"; -- Report how long server has been running + "time"; -- Let others know the time here on this server + "ping"; -- Replies to XMPP pings with pongs + --"pep"; -- Enables users to publish their mood, activity, playing music and more + "register"; -- Allow users to register on this server using a client and change passwords + "adhoc"; -- Support for "ad-hoc commands" that can be executed with an XMPP client + + -- Admin interfaces + "admin_adhoc"; -- Allows administration via an XMPP client that supports ad-hoc commands + --"admin_telnet"; -- Opens telnet console interface on localhost port 5582 + + -- Other specific functionality + "bosh"; -- Enable BOSH clients, aka "Jabber over HTTP" + "websocket"; -- Websocket support + --"httpserver"; -- Serve static files from a directory over HTTP + --"groups"; -- Shared roster support + --"announce"; -- Send announcement to all online users + --"welcome"; -- Welcome users who register accounts + --"watchregistrations"; -- Alert admins of registrations + --"motd"; -- Send a message to users when they log in + "carbons"; + -- Debian: do not remove this module, or you lose syslog + -- support + "posix"; -- POSIX functionality, sends server to background, enables syslog, etc. +}; + +-- These modules are auto-loaded, should you +-- (for some mad reason) want to disable +-- them then uncomment them below +modules_disabled = { + -- "presence"; -- Route user/contact status information + -- "message"; -- Route messages + -- "iq"; -- Route info queries + -- "offline"; -- Store offline messages +}; + +-- Disable account creation by default, for security +-- For more information see http://prosody.im/doc/creating_accounts +allow_registration = false; + +-- Debian: +-- send the server to background. +-- +daemonize = true; + +-- Debian: +-- Please, don't change this option since /var/run/prosody/ +-- is one of the few directories Prosody is allowed to write to +-- +pidfile = "/var/run/prosody/prosody.pid"; + +-- These are the SSL/TLS-related settings. If you don't want +-- to use SSL/TLS, you may comment or remove this +ssl = { + key = "/etc/prosody/certs/localhost.key"; + certificate = "/etc/prosody/certs/localhost.crt"; +} + +-- Only allow encrypted streams? Encryption is already used when +-- available. These options will cause Prosody to deny connections that +-- are not encrypted. Note that some servers do not support s2s +-- encryption or have it disabled, including gmail.com and Google Apps +-- domains. + +--c2s_require_encryption = false +--s2s_require_encryption = false + +-- Select the authentication backend to use. The 'internal' providers +-- use Prosody's configured data storage to store the authentication data. +-- To allow Prosody to offer secure authentication mechanisms to clients, the +-- default provider stores passwords in plaintext. If you do not trust your +-- server please see http://prosody.im/doc/modules/mod_auth_internal_hashed +-- for information about using the hashed backend. + +authentication = "anonymous" + +-- Select the storage backend to use. By default Prosody uses flat files +-- in its configured data directory, but it also supports more backends +-- through modules. An "sql" backend is included by default, but requires +-- additional dependencies. See http://prosody.im/doc/storage for more info. + +--storage = "sql" -- Default is "internal" + +-- For the "sql" backend, you can uncomment *one* of the below to configure: +--sql = { driver = "SQLite3", database = "prosody.sqlite" } -- Default. 'database' is the filename. +--sql = { driver = "MySQL", database = "prosody", username = "prosody", password = "secret", host = "localhost" } +--sql = { driver = "PostgreSQL", database = "prosody", username = "prosody", password = "secret", host = "localhost" } + +-- Logging configuration +-- For advanced logging see http://prosody.im/doc/logging +-- +-- Debian: +-- Logs info and higher to /var/log +-- Logs errors to syslog also +log = { + -- Log files (change 'info' to 'debug' for debug logs): + info = "/var/log/prosody/prosody.log"; + error = "/var/log/prosody/prosody.err"; + -- Syslog: + { levels = { "error" }; to = "syslog"; }; +} + +----------- Virtual hosts ----------- +-- You need to add a VirtualHost entry for each domain you wish Prosody to serve. +-- Settings under each VirtualHost entry apply *only* to that host. + +-- Setup localhost VirtualHost +VirtualHost "localhost" + +------ Components ------ +-- You can specify components to add hosts that provide special services, +-- like multi-user conferences, and transports. +-- For more information on components, see http://prosody.im/doc/components + +---Set up a MUC (multi-user chat) room server on conference.example.com: +Component "conference.localhost" "muc" + +-- Set up a SOCKS5 bytestream proxy for server-proxied file transfers: +--Component "proxy.example.com" "proxy65" + +---Set up an external component (default component port is 5347) +-- +-- External components allow adding various services, such as gateways/ +-- transports to other networks like ICQ, MSN and Yahoo. For more info +-- see: http://prosody.im/doc/components#adding_an_external_component +-- +--Component "gateway.example.com" +-- component_secret = "password" + +------ Additional config files ------ +-- For organizational purposes you may prefer to add VirtualHost and +-- Component definitions in their own config files. This line includes +-- all config files in /etc/prosody/conf.d/ + +Include "conf.d/*.cfg.lua" diff --git a/devbox/provisioning.sh b/devbox/provisioning.sh new file mode 100644 index 00000000..309050ba --- /dev/null +++ b/devbox/provisioning.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +# +# Vagrant provisioning script +# +# Copyright 2014 Michael Weibel +# License: MIT +# + +# +# Install Prosody XMPP server +# +echo "deb http://packages.prosody.im/debian precise main" > /etc/apt/sources.list.d/prosody.list +wget https://prosody.im/files/prosody-debian-packages.key -O- | sudo apt-key add - +apt-get update + +apt-get install -y liblua5.1-bitop prosody lua-event + +# Place config +cp /vagrant/devbox/prosody.cfg.lua /etc/prosody/prosody.cfg.lua + +/etc/init.d/prosody restart + +# +# Install nginx for static file serving +# +apt-get install -y nginx +cp /vagrant/devbox/nginx-default.conf /etc/nginx/sites-available/default +/etc/init.d/nginx restart + +ln -fs /vagrant /usr/share/nginx/html/candy +ln -fs /vagrant/devbox/index.html /usr/share/nginx/html/index.html + +# +# Candy development dependencies +# +sudo add-apt-repository ppa:chris-lea/node.js +sudo apt-get update +sudo apt-get install -y nodejs git +npm install -g grunt-cli +npm install -g bower + +cd /vagrant +su -u vagrant npm install +su -u vagrant bower install + +# +# Selenium & PhantomJS for testing +# +apt-get install -y openjdk-7-jre +mkdir /usr/lib/selenium/ +wget --no-verbose --output-document=/usr/lib/selenium/selenium-server-standalone-2.42.2.jar -- http://selenium-release.storage.googleapis.com/2.42/selenium-server-standalone-2.42.2.jar +mkdir -p /var/log/selenium/ +chmod a+w /var/log/selenium/ +cp /vagrant/devbox/selenium.init.sh /etc/init.d/selenium +chmod 755 /etc/init.d/selenium +/etc/init.d/selenium start +update-rc.d selenium defaults +apt-get install -y phantomjs diff --git a/devbox/selenium.init.sh b/devbox/selenium.init.sh new file mode 100644 index 00000000..e9841ca4 --- /dev/null +++ b/devbox/selenium.init.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +case "${1:-''}" in + 'start') + if test -f /tmp/selenium.pid + then + echo "Selenium is already running." + else + java -jar /usr/lib/selenium/selenium-server-standalone-2.42.2.jar -port 4444 > /var/log/selenium/selenium-output.log 2> /var/log/selenium/selenium-error.log & echo $! > /tmp/selenium.pid + echo "Starting Selenium..." + + error=$? + if test $error -gt 0 + then + echo "${bon}Error $error! Couldn't start Selenium!${boff}" + fi + fi + ;; + 'stop') + if test -f /tmp/selenium.pid + then + echo "Stopping Selenium..." + PID=`cat /tmp/selenium.pid` + kill -3 $PID + if kill -9 $PID ; + then + sleep 2 + test -f /tmp/selenium.pid && rm -f /tmp/selenium.pid + else + echo "Selenium could not be stopped..." + fi + else + echo "Selenium is not running." + fi + ;; + 'restart') + if test -f /tmp/selenium.pid + then + kill -HUP `cat /tmp/selenium.pid` + test -f /tmp/selenium.pid && rm -f /tmp/selenium.pid + sleep 1 + java -jar /usr/lib/selenium/selenium-server-standalone-2.42.2.jar -port 4444 > /var/log/selenium/selenium-output.log 2> /var/log/selenium/selenium-error.log & echo $! > /tmp/selenium.pid + echo "Reload Selenium..." + else + echo "Selenium isn't running..." + fi + ;; + *) # no parameter specified + echo "Usage: $SELF start|stop|restart|reload|force-reload|status" + exit 1 + ;; +esac diff --git a/example/index.html b/example/index.html index a0012373..6087b499 100644 --- a/example/index.html +++ b/example/index.html @@ -7,7 +7,7 @@ - + ' + - '', Context: { menu: '
                ' + '
                  ', @@ -73,7 +67,7 @@ Candy.View.Template = (function(self){ self.Room = { pane: '
                  ' + '{{> roster}}{{> messages}}{{> form}}
                  ', - subject: '
                • {{time}}
                  ' + + subject: '
                • {{time}}
                  ' + '{{roomName}}' + '{{_roomSubject}} {{{subject}}}
                • ', form: '
                  ' + @@ -85,8 +79,8 @@ Candy.View.Template = (function(self){ self.Roster = { pane: '
                  ', user: '
                  ' + + ' id="user-{{roomId}}-{{userId}}" data-jid="{{userJid}}" data-real-jid="{{realJid}}"' + + ' data-nick="{{nick}}" data-role="{{role}}" data-affiliation="{{affiliation}}" data-status="{{status}}">' + '
                  {{displayNick}}
                    ' + '
                  • ' + '
                  • ' + @@ -95,7 +89,7 @@ Candy.View.Template = (function(self){ self.Message = { pane: '
                      ', - item: '
                    • {{time}}
                      ' + + item: '
                    • {{time}}
                      ' + '{{displayName}}' + '{{{message}}}
                    • ' }; @@ -104,7 +98,11 @@ Candy.View.Template = (function(self){ form: '