/*global escape, locales, Jed */ (function (root, factory) { define([ "jquery", "jquery.browser", "underscore", "converse-templates" ], factory); }(this, function ($, dummy, _, templates) { "use strict"; var XFORM_TYPE_MAP = { 'text-private': 'password', 'text-single': 'text', 'fixed': 'label', 'boolean': 'checkbox', 'hidden': 'hidden', 'jid-multi': 'textarea', 'list-single': 'dropdown', 'list-multi': 'dropdown' }; var isImage = function (url) { var deferred = new $.Deferred(); $("", { src: url, error: deferred.reject, load: deferred.resolve }); return deferred.promise(); }; $.expr[':'].emptyVal = function(obj){ return obj.value === ''; }; $.fn.hasScrollBar = function() { if (!$.contains(document, this.get(0))) { return false; } if(this.parent().height() < this.get(0).scrollHeight) { return true; } return false; }; $.fn.throttledHTML = _.throttle($.fn.html, 500); $.fn.addHyperlinks = function () { if (this.length > 0) { this.each(function (i, obj) { var prot, escaped_url; var $obj = $(obj); var x = $obj.html(); var list = x.match(/\b(https?:\/\/|www\.|https?:\/\/www\.)[^\s<]{2,200}\b/g ); if (list) { for (i=0; i'+ list[i] + '' ); } } $obj.html(x); _.each(list, function (url) { isImage(url).then(function () { var prot = url.indexOf('http://') === 0 || url.indexOf('https://') === 0 ? '' : 'http://'; var escaped_url = encodeURI(decodeURI(url)).replace(/[!'()]/g, escape).replace(/\*/g, "%2A"); var new_url = ''+ url + ''; event.target.className = 'chat-image'; x = x.replace(new_url, event.target.outerHTML); $obj.throttledHTML(x); }); }); }); } return this; }; $.fn.addEmoticons = function (allowed) { if (allowed) { if (this.length > 0) { this.each(function (i, obj) { var text = $(obj).html(); text = text.replace(/>:\)/g, ''); text = text.replace(/:\)/g, ''); text = text.replace(/:\-\)/g, ''); text = text.replace(/;\)/g, ''); text = text.replace(/;\-\)/g, ''); text = text.replace(/:D/g, ''); text = text.replace(/:\-D/g, ''); text = text.replace(/:P/g, ''); text = text.replace(/:\-P/g, ''); text = text.replace(/:p/g, ''); text = text.replace(/:\-p/g, ''); text = text.replace(/8\)/g, ''); text = text.replace(/:S/g, ''); text = text.replace(/:\\/g, ''); text = text.replace(/:\/ /g, ''); text = text.replace(/>:\(/g, ''); text = text.replace(/:\(/g, ''); text = text.replace(/:\-\(/g, ''); text = text.replace(/:O/g, ''); text = text.replace(/:\-O/g, ''); text = text.replace(/\=\-O/g, ''); text = text.replace(/\(\^.\^\)b/g, ''); text = text.replace(/<3/g, ''); $(obj).html(text); }); } } return this; }; var utils = { // Translation machinery // --------------------- __: function (str) { if (typeof Jed === "undefined") { return str; } // FIXME: this can be refactored to take the i18n obj as a // parameter. // Translation factory if (typeof this.i18n === "undefined") { this.i18n = locales.en; } if (typeof this.i18n === "string") { this.i18n = $.parseJSON(this.i18n); } if (typeof this.jed === "undefined") { this.jed = new Jed(this.i18n); } var t = this.jed.translate(str); if (arguments.length>1) { return t.fetch.apply(t, [].slice.call(arguments,1)); } else { return t.fetch(); } }, ___: function (str) { /* XXX: This is part of a hack to get gettext to scan strings to be * translated. Strings we cannot send to the function above because * they require variable interpolation and we don't yet have the * variables at scan time. * * See actionInfoMessages in src/converse-muc.js */ return str; }, isLocaleAvailable: function (locale, available) { /* Check whether the locale or sub locale (e.g. en-US, en) is supported. * * Parameters: * (Function) available - returns a boolean indicating whether the locale is supported */ if (available(locale)) { return locale; } else { var sublocale = locale.split("-")[0]; if (sublocale !== locale && available(sublocale)) { return sublocale; } } }, detectLocale: function (library_check) { /* Determine which locale is supported by the user's system as well * as by the relevant library (e.g. converse.js or moment.js). * * Parameters: * (Function) library_check - returns a boolean indicating whether the locale is supported */ var locale, i; if (window.navigator.userLanguage) { locale = utils.isLocaleAvailable(window.navigator.userLanguage, library_check); } if (window.navigator.languages && !locale) { for (i=0; i 0 ? $body.text() : undefined); return text && !!text.match(/^\?OTR/); }, isHeadlineMessage: function (message) { var $message = $(message), from_jid = $message.attr('from'); if ($message.attr('type') === 'headline' || // Some servers (I'm looking at you Prosody) don't set the message // type to "headline" when sending server messages. For now we // check if an @ signal is included, and if not, we assume it's // a headline message. ( $message.attr('type') !== 'error' && typeof from_jid !== 'undefined' && from_jid.indexOf('@') === -1 )) { return true; } return false; }, refreshWebkit: function () { /* This works around a webkit bug. Refreshes the browser's viewport, * otherwise chatboxes are not moved along when one is closed. */ if ($.browser.webkit) { var conversejs = document.getElementById('conversejs'); conversejs.style.display = 'none'; var tmp = conversejs.offsetHeight; // jshint ignore:line conversejs.style.display = 'block'; } }, webForm2xForm: function (field) { /* Takes an HTML DOM and turns it into an XForm field. * * Parameters: * (DOMElement) field - the field to convert */ var $input = $(field), value; if ($input.is('[type=checkbox]')) { value = $input.is(':checked') && 1 || 0; } else if ($input.is('textarea')) { value = []; var lines = $input.val().split('\n'); for( var vk=0; vk into consideration var options = [], j, $options, $values, value, values; if ($field.attr('type') === 'list-single' || $field.attr('type') === 'list-multi') { values = []; $values = $field.children('value'); for (j=0; j<$values.length; j++) { values.push($($values[j]).text()); } $options = $field.children('option'); for (j=0; j<$options.length; j++) { value = $($options[j]).find('value').text(); options.push(templates.select_option({ value: value, label: $($options[j]).attr('label'), selected: (values.indexOf(value) >= 0), required: $field.find('required').length })); } return templates.form_select({ name: $field.attr('var'), label: $field.attr('label'), options: options.join(''), multiple: ($field.attr('type') === 'list-multi'), required: $field.find('required').length }); } else if ($field.attr('type') === 'fixed') { return $('

').text($field.find('value').text()); } else if ($field.attr('type') === 'jid-multi') { return templates.form_textarea({ name: $field.attr('var'), label: $field.attr('label') || '', value: $field.find('value').text(), required: $field.find('required').length }); } else if ($field.attr('type') === 'boolean') { return templates.form_checkbox({ name: $field.attr('var'), type: XFORM_TYPE_MAP[$field.attr('type')], label: $field.attr('label') || '', checked: $field.find('value').text() === "1" && 'checked="1"' || '', required: $field.find('required').length }); } else if ($field.attr('type') && $field.attr('var') === 'username') { return templates.form_username({ domain: ' @'+this.domain, name: $field.attr('var'), type: XFORM_TYPE_MAP[$field.attr('type')], label: $field.attr('label') || '', value: $field.find('value').text(), required: $field.find('required').length }); } else if ($field.attr('type')) { return templates.form_input({ name: $field.attr('var'), type: XFORM_TYPE_MAP[$field.attr('type')], label: $field.attr('label') || '', value: $field.find('value').text(), required: $field.find('required').length }); } else { if ($field.attr('var') === 'ocr') { // Captcha return _.reduce(_.map($field.find('uri'), $.proxy(function (uri) { return templates.form_captcha({ label: this.$field.attr('label'), name: this.$field.attr('var'), data: this.$stanza.find('data[cid="'+uri.textContent.replace(/^cid:/, '')+'"]').text(), type: uri.getAttribute('type'), required: this.$field.find('required').length }); }, {'$stanza': $stanza, '$field': $field}) ), function (memo, num) { return memo + num; }, '' ); } } } }; utils.contains.not = function (attr, query) { return function (item) { return !(utils.contains(attr, query)(item)); }; }; return utils; }));