From d1c1486a6f4e1bbb12fd66001529e37e356ec011 Mon Sep 17 00:00:00 2001 From: sualko Date: Tue, 14 Feb 2017 14:18:13 +0100 Subject: [PATCH] build v3.1.0 --- appinfo/info.xml | 2 +- appinfo/version | 2 +- build/ajax/getSettings.php | 21 +- build/ajax/setAdminSettings.php | 8 + build/appinfo/app.php | 7 + build/appinfo/info.xml | 2 +- build/appinfo/version | 2 +- build/css/jsxc.oc.css | 263 +- build/js/admin.js | 50 +- build/js/eof.js | 4 +- build/js/jsxc/css/jsxc.css | 197 - build/js/jsxc/jsxc.js | 108 +- build/js/jsxc/jsxc.min.js | 18 +- build/js/jsxc/jsxc.min.js.map | 2 +- build/js/jsxc/lib/dsa-ww.js | 50 - build/js/jsxc/lib/emojione/lib/js/emojione.js | 515 - .../jsxc/lib/emojione/lib/js/emojione.min.js | 10 - build/js/jsxc/lib/favico.js/favico.js | 857 - build/js/jsxc/lib/i18next/i18next.min.js | 2 - .../lib/jquery-i18next/jquery-i18next.min.js | 1 - build/js/jsxc/lib/jquery.min.js | 4 - build/js/jsxc/lib/jquery.ui.min.js | 7 - build/js/jsxc/lib/jsxc.dep.js | 2946 +- build/js/jsxc/lib/jsxc.dep.min.js | 26 +- build/js/jsxc/lib/jsxc.dep.min.js.map | 2 +- .../dist/jquery.magnific-popup.js | 1860 - .../dist/jquery.magnific-popup.min.js | 4 - build/js/jsxc/lib/otr/lib/ake.js | 399 + build/js/jsxc/lib/otr/lib/otr.js | 746 + build/js/jsxc/lib/otr/lib/parse.js | 206 + build/js/jsxc/lib/otr/lib/sm.js | 436 + build/js/jsxc/lib/strophe.bookmarks/index.js | 116 - build/js/jsxc/lib/strophe.chatstates/index.js | 80 - .../strophe.jinglejs-bundle.js | 31668 ---------------- build/js/jsxc/lib/strophe.js/strophe.js | 5828 --- build/js/jsxc/lib/strophe.vcard/index.js | 76 - build/js/jsxc/lib/strophe.x/index.js | 845 - build/js/jsxc/lib/translation.js | 2 +- build/js/ojsxc.js | 23 +- build/settings.php | 4 + build/templates/settings.php | 133 +- package.json | 2 +- 42 files changed, 2846 insertions(+), 44688 deletions(-) delete mode 100644 build/js/jsxc/lib/dsa-ww.js delete mode 100644 build/js/jsxc/lib/emojione/lib/js/emojione.js delete mode 100644 build/js/jsxc/lib/emojione/lib/js/emojione.min.js delete mode 100644 build/js/jsxc/lib/favico.js/favico.js delete mode 100644 build/js/jsxc/lib/i18next/i18next.min.js delete mode 100644 build/js/jsxc/lib/jquery-i18next/jquery-i18next.min.js delete mode 100644 build/js/jsxc/lib/jquery.min.js delete mode 100644 build/js/jsxc/lib/jquery.ui.min.js delete mode 100644 build/js/jsxc/lib/magnific-popup/dist/jquery.magnific-popup.js delete mode 100644 build/js/jsxc/lib/magnific-popup/dist/jquery.magnific-popup.min.js create mode 100644 build/js/jsxc/lib/otr/lib/ake.js create mode 100644 build/js/jsxc/lib/otr/lib/otr.js create mode 100644 build/js/jsxc/lib/otr/lib/parse.js create mode 100644 build/js/jsxc/lib/otr/lib/sm.js delete mode 100644 build/js/jsxc/lib/strophe.bookmarks/index.js delete mode 100644 build/js/jsxc/lib/strophe.chatstates/index.js delete mode 100644 build/js/jsxc/lib/strophe.jinglejs/strophe.jinglejs-bundle.js delete mode 100644 build/js/jsxc/lib/strophe.js/strophe.js delete mode 100644 build/js/jsxc/lib/strophe.vcard/index.js delete mode 100644 build/js/jsxc/lib/strophe.x/index.js diff --git a/appinfo/info.xml b/appinfo/info.xml index 9d52ec79..9606d9b6 100755 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -3,7 +3,7 @@ ojsxc JavaScript XMPP Chat Facebook-like chat with end-to-end encrypted conversation, video calls, multi-user rooms, XMPP and internal server backend. - 3.1.0-beta + 3.1.0 MIT Klaus Herberth, Tobia De Koninck 8.0 diff --git a/appinfo/version b/appinfo/version index 0889be44..a0cd9f0c 100755 --- a/appinfo/version +++ b/appinfo/version @@ -1 +1 @@ -3.1.0-beta \ No newline at end of file +3.1.0 \ No newline at end of file diff --git a/build/ajax/getSettings.php b/build/ajax/getSettings.php index 4a03d395..c02754cb 100644 --- a/build/ajax/getSettings.php +++ b/build/ajax/getSettings.php @@ -9,20 +9,23 @@ function validateBoolean($val) OCP\JSON::callCheck(); -$username = $_POST ['username']; -$password = $_POST ['password']; +$currentUser = false; -$ocUser = new OCP\User(); - -$auth = ($password !== null) ? $ocUser->checkPassword($username, $password) : OCP\User::isLoggedIn(); +if(!empty($_POST['password']) && !empty($_POST['username'])) { + $currentUser = \OC::$server->getUserManager()->checkPassword($_POST['username'], $_POST['password']); +} else if (OCP\User::isLoggedIn()) { + $currentUser = \OC::$server->getUserSession()->getUser(); +} -if (!$auth) { +if (!$currentUser) { echo json_encode(array( 'result' => 'noauth', )); exit(); } +$currentUID = $currentUser->getUID(); + $config = \OC::$server->getConfig(); $data = array(); @@ -46,10 +49,10 @@ function validateBoolean($val) $data ['xmpp'] ['domain'] = trim($config->getAppValue('ojsxc', 'xmppDomain')); $data ['xmpp'] ['resource'] = trim($config->getAppValue('ojsxc', 'xmppResource')); $data ['xmpp'] ['overwrite'] = validateBoolean($config->getAppValue('ojsxc', 'xmppOverwrite')); -$data ['xmpp'] ['onlogin'] = true; +$data ['xmpp'] ['onlogin'] = null; if (validateBoolean($config->getAppValue('ojsxc', 'xmppPreferMail'))) { - $mail = $config->getUserValue($username,'settings','email'); + $mail = $config->getUserValue($currentUID,'settings','email'); if ($mail !== null) { list($u, $d) = explode("@", $mail, 2); @@ -60,7 +63,7 @@ function validateBoolean($val) } } -$options = $config->getUserValue($username, 'ojsxc', 'options'); +$options = $config->getUserValue($currentUID, 'ojsxc', 'options'); if ($options !== null) { $options = (array) json_decode($options, true); diff --git a/build/ajax/setAdminSettings.php b/build/ajax/setAdminSettings.php index 7a098f15..c7f32726 100644 --- a/build/ajax/setAdminSettings.php +++ b/build/ajax/setAdminSettings.php @@ -22,4 +22,12 @@ $config->setAppValue('ojsxc', 'firefoxExtension', $_POST ['firefoxExtension']); $config->setAppValue('ojsxc', 'chromeExtension', $_POST ['chromeExtension']); +$externalServices = array(); +foreach($_POST['externalServices'] as $es) { + if (preg_match('/^(https:\/\/)?([\w\d*][\w\d-]*)(\.[\w\d-]+)+(:[\d]+)?$/', $es)) { + $externalServices[] = $es; + } +} +$config->setAppValue('ojsxc', 'externalServices', implode('|', $externalServices)); + echo 'true'; diff --git a/build/appinfo/app.php b/build/appinfo/app.php index 869ad8d3..969b8355 100644 --- a/build/appinfo/app.php +++ b/build/appinfo/app.php @@ -48,6 +48,13 @@ $policy->addAllowedConnectDomain($boshDomain); } + $externalServices = \OC::$server->getConfig()->getAppValue('ojsxc', 'externalServices'); + $externalServices = explode("|", $externalServices); + + foreach($externalServices as $es) { + $policy->addAllowedConnectDomain($es); + } + $manager->addDefaultPolicy($policy); } diff --git a/build/appinfo/info.xml b/build/appinfo/info.xml index 9d52ec79..9606d9b6 100644 --- a/build/appinfo/info.xml +++ b/build/appinfo/info.xml @@ -3,7 +3,7 @@ ojsxc JavaScript XMPP Chat Facebook-like chat with end-to-end encrypted conversation, video calls, multi-user rooms, XMPP and internal server backend. - 3.1.0-beta + 3.1.0 MIT Klaus Herberth, Tobia De Koninck 8.0 diff --git a/build/appinfo/version b/build/appinfo/version index 0889be44..a0cd9f0c 100644 --- a/build/appinfo/version +++ b/build/appinfo/version @@ -1 +1 @@ -3.1.0-beta \ No newline at end of file +3.1.0 \ No newline at end of file diff --git a/build/css/jsxc.oc.css b/build/css/jsxc.oc.css index 3be492e0..cb7b2926 100644 --- a/build/css/jsxc.oc.css +++ b/build/css/jsxc.oc.css @@ -1,5 +1,5 @@ /*! - * ojsxc v3.1.0-beta - 2017-01-23 + * ojsxc v3.1.0 - 2017-02-14 * * Copyright (c) 2017 Klaus Herberth
* Released under the MIT license @@ -7,208 +7,11 @@ * Please see http://www.jsxc.org/ * * @author Klaus Herberth - * @version 3.1.0-beta + * @version 3.1.0 * @license MIT */ @charset "UTF-8"; -/* basic scrollbar styling */ -/* vertical scrollbar */ -.mCSB_container { - width: auto; - margin-right: 30px; - overflow: hidden; } - -.mCSB_container.mCS_no_scrollbar { - margin-right: 0; } - -.mCS_disabled .mCSB_container.mCS_no_scrollbar, .mCS_destroyed .mCSB_container.mCS_no_scrollbar { - margin-right: 30px; } - -.mCustomScrollBox .mCSB_scrollTools { - width: 16px; - height: 100%; - top: 0; - right: 0; } - -.mCSB_scrollTools .mCSB_draggerContainer { - height: 100%; - box-sizing: border-box; } - -.mCSB_scrollTools .mCSB_buttonUp + .mCSB_draggerContainer { - padding-bottom: 40px; } - -.mCSB_scrollTools .mCSB_draggerRail { - width: 2px; - height: 100%; - margin: 0 auto; - border-radius: 10px; } - -.mCSB_scrollTools .mCSB_dragger { - cursor: pointer; - width: 100%; - height: 30px; } - -.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - width: 4px; - height: 100%; - margin: 0 auto; - border-radius: 10px; - text-align: center; } - -.mCSB_scrollTools .mCSB_buttonUp, .mCSB_scrollTools .mCSB_buttonDown { - height: 20px; - overflow: hidden; - margin: 0 auto; - cursor: pointer; } - -.mCSB_scrollTools .mCSB_buttonDown { - bottom: 0; - margin-top: -40px; } - -/* horizontal scrollbar */ -.mCSB_horizontal .mCSB_container { - height: auto; - margin-right: 0; - margin-bottom: 30px; - overflow: hidden; } - -.mCSB_horizontal .mCSB_container.mCS_no_scrollbar { - margin-bottom: 0; } - -.mCS_disabled .mCSB_horizontal .mCSB_container.mCS_no_scrollbar, .mCS_destroyed .mCSB_horizontal .mCSB_container.mCS_no_scrollbar { - margin-right: 0; - margin-bottom: 30px; } - -.mCSB_horizontal.mCustomScrollBox .mCSB_scrollTools { - width: 100%; - height: 16px; - top: auto; - right: auto; - bottom: 0; - left: 0; - overflow: hidden; } - -.mCSB_horizontal .mCSB_scrollTools .mCSB_draggerContainer { - height: 100%; - width: auto; - box-sizing: border-box; - overflow: hidden; } - -.mCSB_horizontal .mCSB_scrollTools .mCSB_buttonLeft + .mCSB_draggerContainer { - padding-bottom: 0; - padding-right: 20px; } - -.mCSB_horizontal .mCSB_scrollTools .mCSB_draggerRail { - width: 100%; - height: 2px; - margin: 7px 0; - border-radius: 10px; } - -.mCSB_horizontal .mCSB_scrollTools .mCSB_dragger { - width: 30px; - height: 100%; } - -.mCSB_horizontal .mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - width: 100%; - height: 4px; - margin: 6px auto; - border-radius: 10px; } - -.mCSB_horizontal .mCSB_scrollTools .mCSB_buttonLeft, .mCSB_horizontal .mCSB_scrollTools .mCSB_buttonRight { - width: 20px; - height: 100%; - overflow: hidden; - margin: 0 auto; - cursor: pointer; - float: left; } - -.mCSB_horizontal .mCSB_scrollTools .mCSB_buttonRight { - right: 0; - bottom: auto; - margin-left: -40px; - margin-top: -16px; - float: right; } - -/* default scrollbar colors and backgrounds */ -.mCustomScrollBox .mCSB_scrollTools { - opacity: 0.75; } - -.mCustomScrollBox:hover .mCSB_scrollTools { - opacity: 1; } - -.mCSB_scrollTools .mCSB_draggerRail { - background: #000; - /* rgba fallback */ - background: rgba(0, 0, 0, 0.4); - filter: "alpha(opacity=40)"; - -ms-filter: "alpha(opacity=40)"; - /* old ie */ } - -.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background: #fff; - /* rgba fallback */ - background: rgba(255, 255, 255, 0.75); - filter: "alpha(opacity=75)"; - -ms-filter: "alpha(opacity=75)"; - /* old ie */ } - -.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background: rgba(255, 255, 255, 0.85); - filter: "alpha(opacity=85)"; - -ms-filter: "alpha(opacity=85)"; - /* old ie */ } - -.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, .mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background: rgba(255, 255, 255, 0.9); - filter: "alpha(opacity=90)"; - -ms-filter: "alpha(opacity=90)"; - /* old ie */ } - -.mCSB_scrollTools .mCSB_buttonUp, .mCSB_scrollTools .mCSB_buttonDown, .mCSB_scrollTools .mCSB_buttonLeft, .mCSB_scrollTools .mCSB_buttonRight { - background-image: url(mCSB_buttons.png); - background-repeat: no-repeat; - opacity: 0.4; - filter: "alpha(opacity=40)"; - -ms-filter: "alpha(opacity=40)"; - /* old ie */ } - -.mCSB_scrollTools .mCSB_buttonUp { - background-position: 0 0; - /* - sprites locations are 0 0/-16px 0/-32px 0/-48px 0 (light) and -80px 0/-96px 0/-112px 0/-128px 0 (dark) - */ } - -.mCSB_scrollTools .mCSB_buttonDown { - background-position: 0 -20px; - /* - sprites locations are 0 -20px/-16px -20px/-32px -20px/-48px -20px (light) and -80px -20px/-96px -20px/-112px -20px/-128px -20px (dark) - */ } - -.mCSB_scrollTools .mCSB_buttonLeft { - background-position: 0 -40px; - /* - sprites locations are 0 -40px/-20px -40px/-40px -40px/-60px -40px (light) and -80px -40px/-100px -40px/-120px -40px/-140px -40px (dark) - */ } - -.mCSB_scrollTools .mCSB_buttonRight { - background-position: 0 -56px; - /* - sprites locations are 0 -56px/-20px -56px/-40px -56px/-60px -56px (light) and -80px -56px/-100px -56px/-120px -56px/-140px -56px (dark) - */ } - -.mCSB_scrollTools .mCSB_buttonUp:hover, .mCSB_scrollTools .mCSB_buttonDown:hover, .mCSB_scrollTools .mCSB_buttonLeft:hover, .mCSB_scrollTools .mCSB_buttonRight:hover { - opacity: 0.75; - filter: "alpha(opacity=75)"; - -ms-filter: "alpha(opacity=75)"; - /* old ie */ } - -.mCSB_scrollTools .mCSB_buttonUp:active, .mCSB_scrollTools .mCSB_buttonDown:active, .mCSB_scrollTools .mCSB_buttonLeft:active, .mCSB_scrollTools .mCSB_buttonRight:active { - opacity: 0.9; - filter: "alpha(opacity=90)"; - -ms-filter: "alpha(opacity=90)"; - /* old ie */ } - /* Magnific Popup CSS */ .mfp-bg { top: 0; @@ -4620,47 +4423,63 @@ div.jsxc_video { opacity: 0.8; } #ojsxc .form-group { - margin-bottom: 0.8em; } - -@media (min-width: 768px) { - #ojsxc .form-offset-label { - padding-left: 280px; } } - -@media (min-width: 768px) { - #ojsxc h3 { - margin-left: 285px; } } + overflow: hidden; } + #ojsxc .form-group > label, #ojsxc .form-group > .form-col { + float: left; } #ojsxc label { box-sizing: border-box; - padding-right: 15px; - display: inline-block; } + padding: 6px 15px 6px 0; + width: 100%; + margin: 3px 0; } @media (min-width: 768px) { #ojsxc label { - width: 280px; + width: 33%; text-align: right; } } +#ojsxc .form-no-padding { + padding: 0; } + +#ojsxc .form-col { + width: 100%; + overflow: hidden; } + @media (min-width: 768px) { + #ojsxc .form-col { + width: 66%; } } + #ojsxc .form-col input { + display: block; } + +@media (min-width: 768px) { + #ojsxc .form-col-offset { + padding-left: 33%; } } + #ojsxc input { box-sizing: border-box; padding-right: 15px; - display: inline-block; width: 100%; } #ojsxc input[type='checkbox'] { + margin: 13px 0; width: auto; } #ojsxc input[type='radio'] { width: auto; } - @media (min-width: 768px) { - #ojsxc input { - width: auto; } } - #ojsxc input + label { - width: auto; } - #ojsxc input + label + em { - padding-left: 20px; } + #ojsxc input:invalid { + border: 1px solid red; + position: relative; } #ojsxc em, #ojsxc .boshUrl-msg { - display: block; } + display: block; + clear: left; + margin-bottom: 0.8em; } + +#ojsxc .text-left { + text-align: left; } + +#ojsxc h3 { + width: 100%; } @media (min-width: 768px) { - #ojsxc em, #ojsxc .boshUrl-msg { - padding-left: 280px; } } + #ojsxc h3 { + width: 33%; + border-bottom: 1px solid #e1e1e1; } } .jsxc_success, .jsxc_fail { border: 1px solid #fff; diff --git a/build/js/admin.js b/build/js/admin.js index d9c8fa19..006208e4 100644 --- a/build/js/admin.js +++ b/build/js/admin.js @@ -1,5 +1,5 @@ /*! - * ojsxc v3.1.0-beta - 2017-01-23 + * ojsxc v3.1.0 - 2017-02-14 * * Copyright (c) 2017 Klaus Herberth
* Released under the MIT license @@ -7,7 +7,7 @@ * Please see http://www.jsxc.org/ * * @author Klaus Herberth - * @version 3.1.0-beta + * @version 3.1.0 * @license MIT */ @@ -16,7 +16,7 @@ $(document).ready(function() { /** * Test if bosh server is up and running. - * + * * @param {string} url BOSH url * @param {string} domain host domain for BOSH server * @param {Function} cb called if test is done @@ -166,4 +166,48 @@ $(document).ready(function() { }, 3000); }); }); + + $('#ojsxc .add-input').click(function(ev) { + ev.preventDefault(); + + var clone = $(this).prev().clone(); + clone.val(''); + + $(this).before(clone); + }); + + $('#insert-upload-service').click(function(ev) { + ev.preventDefault(); + + if (!jsxc.xmpp.conn || !jsxc.xmpp.conn.connected) { + console.warn('Not connected to any XMPP server.'); + return; + } + + var options = jsxc.options.get('httpUpload') || {}; + + var services = $('[name="externalServices[]"]').map(function(){ + var inputField = $(this); + + return inputField.val() || null; + }); + + if (options.server && services.toArray().indexOf(options.server) < 0) { + // insert service + var emptyInputFields = $('[name="externalServices[]"]').filter(function(){ + return $(this).val() === ''; + }); + + var targetInputField; + + if(emptyInputFields.length === 0) { + $(this).parents('.form-group').find('.add-input').click(); + targetInputField = $('[name="externalServices[]"]').last(); + } else { + targetInputField = $(emptyInputFields[0]); + } + + targetInputField.val(options.server); + } + }); }); diff --git a/build/js/eof.js b/build/js/eof.js index 9e624c25..0eb30d84 100644 --- a/build/js/eof.js +++ b/build/js/eof.js @@ -1,5 +1,5 @@ /*! - * ojsxc v3.1.0-beta - 2017-01-23 + * ojsxc v3.1.0 - 2017-02-14 * * Copyright (c) 2017 Klaus Herberth
* Released under the MIT license @@ -7,7 +7,7 @@ * Please see http://www.jsxc.org/ * * @author Klaus Herberth - * @version 3.1.0-beta + * @version 3.1.0 * @license MIT */ diff --git a/build/js/jsxc/css/jsxc.css b/build/js/jsxc/css/jsxc.css index f8619eeb..8178aebc 100644 --- a/build/js/jsxc/css/jsxc.css +++ b/build/js/jsxc/css/jsxc.css @@ -1,201 +1,4 @@ @charset "UTF-8"; -/* basic scrollbar styling */ -/* vertical scrollbar */ -.mCSB_container { - width: auto; - margin-right: 30px; - overflow: hidden; } - -.mCSB_container.mCS_no_scrollbar { - margin-right: 0; } - -.mCS_disabled .mCSB_container.mCS_no_scrollbar, .mCS_destroyed .mCSB_container.mCS_no_scrollbar { - margin-right: 30px; } - -.mCustomScrollBox .mCSB_scrollTools { - width: 16px; - height: 100%; - top: 0; - right: 0; } - -.mCSB_scrollTools .mCSB_draggerContainer { - height: 100%; - box-sizing: border-box; } - -.mCSB_scrollTools .mCSB_buttonUp + .mCSB_draggerContainer { - padding-bottom: 40px; } - -.mCSB_scrollTools .mCSB_draggerRail { - width: 2px; - height: 100%; - margin: 0 auto; - border-radius: 10px; } - -.mCSB_scrollTools .mCSB_dragger { - cursor: pointer; - width: 100%; - height: 30px; } - -.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - width: 4px; - height: 100%; - margin: 0 auto; - border-radius: 10px; - text-align: center; } - -.mCSB_scrollTools .mCSB_buttonUp, .mCSB_scrollTools .mCSB_buttonDown { - height: 20px; - overflow: hidden; - margin: 0 auto; - cursor: pointer; } - -.mCSB_scrollTools .mCSB_buttonDown { - bottom: 0; - margin-top: -40px; } - -/* horizontal scrollbar */ -.mCSB_horizontal .mCSB_container { - height: auto; - margin-right: 0; - margin-bottom: 30px; - overflow: hidden; } - -.mCSB_horizontal .mCSB_container.mCS_no_scrollbar { - margin-bottom: 0; } - -.mCS_disabled .mCSB_horizontal .mCSB_container.mCS_no_scrollbar, .mCS_destroyed .mCSB_horizontal .mCSB_container.mCS_no_scrollbar { - margin-right: 0; - margin-bottom: 30px; } - -.mCSB_horizontal.mCustomScrollBox .mCSB_scrollTools { - width: 100%; - height: 16px; - top: auto; - right: auto; - bottom: 0; - left: 0; - overflow: hidden; } - -.mCSB_horizontal .mCSB_scrollTools .mCSB_draggerContainer { - height: 100%; - width: auto; - box-sizing: border-box; - overflow: hidden; } - -.mCSB_horizontal .mCSB_scrollTools .mCSB_buttonLeft + .mCSB_draggerContainer { - padding-bottom: 0; - padding-right: 20px; } - -.mCSB_horizontal .mCSB_scrollTools .mCSB_draggerRail { - width: 100%; - height: 2px; - margin: 7px 0; - border-radius: 10px; } - -.mCSB_horizontal .mCSB_scrollTools .mCSB_dragger { - width: 30px; - height: 100%; } - -.mCSB_horizontal .mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - width: 100%; - height: 4px; - margin: 6px auto; - border-radius: 10px; } - -.mCSB_horizontal .mCSB_scrollTools .mCSB_buttonLeft, .mCSB_horizontal .mCSB_scrollTools .mCSB_buttonRight { - width: 20px; - height: 100%; - overflow: hidden; - margin: 0 auto; - cursor: pointer; - float: left; } - -.mCSB_horizontal .mCSB_scrollTools .mCSB_buttonRight { - right: 0; - bottom: auto; - margin-left: -40px; - margin-top: -16px; - float: right; } - -/* default scrollbar colors and backgrounds */ -.mCustomScrollBox .mCSB_scrollTools { - opacity: 0.75; } - -.mCustomScrollBox:hover .mCSB_scrollTools { - opacity: 1; } - -.mCSB_scrollTools .mCSB_draggerRail { - background: #000; - /* rgba fallback */ - background: rgba(0, 0, 0, 0.4); - filter: "alpha(opacity=40)"; - -ms-filter: "alpha(opacity=40)"; - /* old ie */ } - -.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar { - background: #fff; - /* rgba fallback */ - background: rgba(255, 255, 255, 0.75); - filter: "alpha(opacity=75)"; - -ms-filter: "alpha(opacity=75)"; - /* old ie */ } - -.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar { - background: rgba(255, 255, 255, 0.85); - filter: "alpha(opacity=85)"; - -ms-filter: "alpha(opacity=85)"; - /* old ie */ } - -.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, .mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar { - background: rgba(255, 255, 255, 0.9); - filter: "alpha(opacity=90)"; - -ms-filter: "alpha(opacity=90)"; - /* old ie */ } - -.mCSB_scrollTools .mCSB_buttonUp, .mCSB_scrollTools .mCSB_buttonDown, .mCSB_scrollTools .mCSB_buttonLeft, .mCSB_scrollTools .mCSB_buttonRight { - background-image: url(mCSB_buttons.png); - background-repeat: no-repeat; - opacity: 0.4; - filter: "alpha(opacity=40)"; - -ms-filter: "alpha(opacity=40)"; - /* old ie */ } - -.mCSB_scrollTools .mCSB_buttonUp { - background-position: 0 0; - /* - sprites locations are 0 0/-16px 0/-32px 0/-48px 0 (light) and -80px 0/-96px 0/-112px 0/-128px 0 (dark) - */ } - -.mCSB_scrollTools .mCSB_buttonDown { - background-position: 0 -20px; - /* - sprites locations are 0 -20px/-16px -20px/-32px -20px/-48px -20px (light) and -80px -20px/-96px -20px/-112px -20px/-128px -20px (dark) - */ } - -.mCSB_scrollTools .mCSB_buttonLeft { - background-position: 0 -40px; - /* - sprites locations are 0 -40px/-20px -40px/-40px -40px/-60px -40px (light) and -80px -40px/-100px -40px/-120px -40px/-140px -40px (dark) - */ } - -.mCSB_scrollTools .mCSB_buttonRight { - background-position: 0 -56px; - /* - sprites locations are 0 -56px/-20px -56px/-40px -56px/-60px -56px (light) and -80px -56px/-100px -56px/-120px -56px/-140px -56px (dark) - */ } - -.mCSB_scrollTools .mCSB_buttonUp:hover, .mCSB_scrollTools .mCSB_buttonDown:hover, .mCSB_scrollTools .mCSB_buttonLeft:hover, .mCSB_scrollTools .mCSB_buttonRight:hover { - opacity: 0.75; - filter: "alpha(opacity=75)"; - -ms-filter: "alpha(opacity=75)"; - /* old ie */ } - -.mCSB_scrollTools .mCSB_buttonUp:active, .mCSB_scrollTools .mCSB_buttonDown:active, .mCSB_scrollTools .mCSB_buttonLeft:active, .mCSB_scrollTools .mCSB_buttonRight:active { - opacity: 0.9; - filter: "alpha(opacity=90)"; - -ms-filter: "alpha(opacity=90)"; - /* old ie */ } - /* Magnific Popup CSS */ .mfp-bg { top: 0; diff --git a/build/js/jsxc/jsxc.js b/build/js/jsxc/jsxc.js index 935bc122..ec94be22 100644 --- a/build/js/jsxc/jsxc.js +++ b/build/js/jsxc/jsxc.js @@ -1,5 +1,5 @@ /*! - * jsxc v3.1.0-beta - 2017-01-23 + * jsxc v3.1.0 - 2017-02-14 * * Copyright (c) 2017 Klaus Herberth
* Released under the MIT license @@ -7,7 +7,7 @@ * Please see http://www.jsxc.org/ * * @author Klaus Herberth - * @version 3.1.0-beta + * @version 3.1.0 * @license MIT */ @@ -25,7 +25,7 @@ var jsxc = null, RTC = null, RTCPeerconnection = null; */ jsxc = { /** Version of jsxc */ - version: '3.1.0-beta', + version: '3.1.0', /** True if i'm the master */ master: false, @@ -378,10 +378,12 @@ jsxc = { jsxc.options.loginForm.triggered = true; jsxc.xmpp.login(jsxc.options.xmpp.jid, jsxc.options.xmpp.password); + + return; } - } else { - jsxc.submitLoginForm(); } + + jsxc.submitLoginForm(); }); // Trigger submit in jsxc.xmpp.connected() @@ -1544,13 +1546,18 @@ jsxc.xmpp = { * @private */ onRosterChanged: function(iq) { - /* - * - */ + + var iqSender = $(iq).attr('from'); + var ownBareJid = Strophe.getBareJidFromJid(jsxc.xmpp.conn.jid); + + if (iqSender && iqSender !== ownBareJid) { + return true; + } jsxc.debug('onRosterChanged', iq); + // @REVIEW there should be only one item, according to RFC6121 + // https://xmpp.org/rfcs/rfc6121.html#roster-syntax-actions-push $(iq).find('item').each(function() { var jid = $(this).attr('jid'); var name = $(this).attr('name') || jid; @@ -1772,6 +1779,7 @@ jsxc.xmpp = { onChatMessage: function(stanza) { var forwarded = $(stanza).find('forwarded[xmlns="' + jsxc.CONST.NS.FORWARD + '"]'); var message, carbon; + var originalSender = $(stanza).attr('from'); if (forwarded.length > 0) { message = forwarded.find('> message'); @@ -1780,6 +1788,9 @@ jsxc.xmpp = { if (carbon.length === 0) { carbon = false; + } else if (originalSender !== Strophe.getBareJidFromJid(jsxc.xmpp.conn.jid)) { + // ignore this carbon copy + return true; } jsxc.debug('Incoming forwarded message', message); @@ -5298,6 +5309,11 @@ jsxc.gui.window = { msg = msg.replace(/^\/me /, '' + jsxc.removeHTML(bidData.name || bid) + ' '); } + // hide unprocessed otr messages + if (msg.match(/^\?OTR([:,|?]|[?v0-9x]+)/)) { + msg = '' + $.t('Unreadable_OTR_message') + ''; + } + var msgDiv = $("
"), msgTsDiv = $("
"); msgDiv.addClass('jsxc_chatmessage jsxc_' + direction); @@ -5675,7 +5691,8 @@ jsxc.gui.template.get = function(name, bid, msg) { // prevent 404 ret = ret.replace(/\{\{root\}\}/g, ph.root); - ret = $(ret); + // encapsulate template to find all desired elements in the next step + ret = $('
' + ret + '
'); ret.find('[data-var]').each(function() { var key = $(this).attr('data-var'); @@ -5688,6 +5705,9 @@ jsxc.gui.template.get = function(name, bid, msg) { } }); + // remove encapsulation + ret = ret.find('>*'); + ret.localize(ph); return ret; @@ -6078,7 +6098,9 @@ jsxc.muc = { li.click(jsxc.muc.showJoinChat); - $('#jsxc_menu ul .jsxc_about').before(li); + if ($('#jsxc_menu .jsxc_joinChat').length === 0) { + $('#jsxc_menu ul .jsxc_about').before(li); + } }, /** @@ -11087,7 +11109,7 @@ jsxc.xmpp.bookmarks = {}; /** * Determines if server is able to store bookmarks. - * + * * @return {boolean} True: Server supports bookmark storage */ jsxc.xmpp.bookmarks.remote = function() { @@ -11150,7 +11172,7 @@ jsxc.xmpp.bookmarks.loadFromLocal = function() { /** * Load bookmarks from remote storage. - * + * * @private */ jsxc.xmpp.bookmarks.loadFromRemote = function() { @@ -11208,7 +11230,11 @@ jsxc.xmpp.bookmarks.loadFromRemote = function() { if (err.reasons[0] === 'item-not-found') { jsxc.debug('create bookmark node'); - bookmarks.createBookmarksNode(); + bookmarks.createBookmarksNode(function() { + jsxc.debug('Bookmark node created.'); + }, function() { + jsxc.debug('Could not create bookmark node.'); + }); } else { jsxc.debug('[XMPP] Could not create bookmark: ' + err.type, err.reasons); } @@ -11751,31 +11777,53 @@ jsxc.xmpp.httpUpload.discoverUploadService = function() { jsxc.debug('discover http upload service'); + self.queryItemForUploadService(self.conn.domain); + self.conn.disco.items(self.conn.domain, null, function(items) { $(items).find('item').each(function() { var jid = $(this).attr('jid'); - var discovered = false; - self.conn.disco.info(jid, null, function(info) { - var httpUploadFeature = $(info).find('feature[var="' + self.CONST.NS.HTTPUPLOAD + '"]'); - var httpUploadMaxSize = $(info).find('field[var="max-file-size"]'); + if (self.ready) { + // abort, because we already found a service + return false; + } - if (httpUploadFeature.length > 0) { - jsxc.debug('http upload service found', jid); + self.queryItemForUploadService(jid); + }); + }); +}; - jsxc.options.set('httpUpload', { - server: jid, - name: $(info).find('identity').attr('name'), - maxSize: parseInt(httpUploadMaxSize.text()) - }); +/** + * Query item for upload service. + * + * @param {String} jid + * @param {Function} cb Callback on success + * @memberOf jsxc.xmpp.httpUpload + */ +jsxc.xmpp.httpUpload.queryItemForUploadService = function(jid, cb) { + var self = jsxc.xmpp.httpUpload; - discovered = true; - self.ready = true; - } + jsxc.debug('query ' + jid + ' for upload service'); + + self.conn.disco.info(jid, null, function(info) { + var httpUploadFeature = $(info).find('feature[var="' + self.CONST.NS.HTTPUPLOAD + '"]'); + var httpUploadMaxSize = $(info).find('field[var="max-file-size"]'); + + if (httpUploadFeature.length > 0) { + jsxc.debug('http upload service found on ' + jid); + + jsxc.options.set('httpUpload', { + server: jid, + name: $(info).find('identity').attr('name'), + maxSize: parseInt(httpUploadMaxSize.text()) }); - return !discovered; - }); + self.ready = true; + + if (typeof cb === 'function') { + cb.call(info); + } + } }); }; diff --git a/build/js/jsxc/jsxc.min.js b/build/js/jsxc/jsxc.min.js index 26244139..a189dc32 100644 --- a/build/js/jsxc/jsxc.min.js +++ b/build/js/jsxc/jsxc.min.js @@ -1,5 +1,5 @@ /*! - * jsxc v3.1.0-beta - 2017-01-23 + * jsxc v3.1.0 - 2017-02-14 * * Copyright (c) 2017 Klaus Herberth
* Released under the MIT license @@ -7,14 +7,14 @@ * Please see http://www.jsxc.org/ * * @author Klaus Herberth - * @version 3.1.0-beta + * @version 3.1.0 * @license MIT */ -var jsxc=null,RTC=null,RTCPeerconnection=null;!function($){"use strict";jsxc={version:"3.1.0-beta",master:!1,role_allocation:!1,to:[],toBusy:null,toNotification:null,toNotificationDelay:500,keepaliveInterval:null,reconnect:!1,restoreCompleted:!1,triggeredFromBox:!1,triggeredFromElement:!1,triggeredFromLogout:!1,ls:[],storageNotConform:null,toSNC:null,bid:null,currentState:null,currentUIState:null,CONST:{NOTIFICATION_DEFAULT:"default",NOTIFICATION_GRANTED:"granted",NOTIFICATION_DENIED:"denied",STATUS:["offline","dnd","xa","away","chat","online"],SOUNDS:{MSG:"incomingMessage.wav",CALL:"Rotary-Phone6.mp3",NOTICE:"Ping1.mp3"},REGEX:{JID:new RegExp("\\b[^\"&'\\/:<>@\\s]+@[\\w-_.]+\\b","ig"),URL:new RegExp(/(https?:\/\/|www\.)[^\s<>'"]+/gi)},NS:{CARBONS:"urn:xmpp:carbons:2",FORWARD:"urn:xmpp:forward:0"},HIDDEN:"hidden",SHOWN:"shown",STATE:{INITIATING:0,PREVCONFOUND:1,SUSPEND:2,TRYTOINTERCEPT:3,INTERCEPTED:4,ESTABLISHING:5,READY:6},UISTATE:{INITIATING:0,READY:1}},getFormattedTime:function(unixtime){var msgDate=new Date(parseInt(unixtime)),day=("0"+msgDate.getDate()).slice(-2),month=("0"+(msgDate.getMonth()+1)).slice(-2),year=msgDate.getFullYear(),hours=("0"+msgDate.getHours()).slice(-2),minutes=("0"+msgDate.getMinutes()).slice(-2),dateNow=new Date,date="function"==typeof msgDate.toLocaleDateString?msgDate.toLocaleDateString():day+"."+month+"."+year,time="function"==typeof msgDate.toLocaleTimeString?msgDate.toLocaleTimeString():hours+":"+minutes;return dateNow.setHours(0,0,0,0),msgDate.setHours(0,0,0,0),dateNow.getTime()!==msgDate.getTime()?date+" "+time:time},debug:function(msg,data,level){if(level&&(msg="["+level+"] "+msg),data){jsxc.storage.getItem("debug")===!0&&console.log(msg,data);var d;try{d=$("").prepend($(data).clone()).html()}catch(err){try{d=JSON.stringify(data)}catch(err2){d="see js console"}}jsxc.log=jsxc.log+"$ "+msg+": "+d+"\n"}else console.log(msg),jsxc.log=jsxc.log+"$ "+msg+"\n"},warn:function(msg,data){jsxc.debug(msg,data,"WARN")},error:function(msg,data){jsxc.debug(msg,data,"ERROR")},log:"",init:function(options){if(jsxc.changeState(jsxc.CONST.STATE.INITIATING),options&&options.loginForm&&"boolean"==typeof options.loginForm.attachIfFound&&!options.loginForm.ifFound&&(options.loginForm.ifFound=options.loginForm.attachIfFound?"attach":"pause"),options&&$.extend(!0,jsxc.options,options),"undefined"==typeof localStorage)return void jsxc.warn("Browser doesn't support localStorage.");jsxc.options.get=function(key){if(jsxc.bid){var local=jsxc.storage.getUserItem("options")||{};return"undefined"!=typeof local[key]?local[key]:jsxc.options[key]}return jsxc.options[key]},jsxc.options.set=function(key,value){jsxc.storage.updateItem("options",key,value,!0)},jsxc.storageNotConform=jsxc.storage.getItem("storageNotConform"),null===jsxc.storageNotConform&&(jsxc.storageNotConform=2);var lang;lang=null!==jsxc.storage.getItem("lang")?jsxc.storage.getItem("lang"):jsxc.options.autoLang&&navigator.languages&&navigator.languages.length>0?navigator.languages[0].substr(0,2):jsxc.options.autoLang&&navigator.language?navigator.language.substr(0,2):jsxc.options.defaultLang,window.i18next.init({lng:lang,fallbackLng:"en",resources:I18next,debug:jsxc.storage.getItem("debug")===!0,interpolation:{prefix:"__",suffix:"__"}},function(){window.jqueryI18next.init(window.i18next,$,{tName:"t",i18nName:"i18next",handleName:"localize"})}),jsxc.storage.getItem("debug")===!0&&(jsxc.options.otr.debug=!0),window.addEventListener("storage",jsxc.storage.onStorage,!1),$(document).on("attached.jsxc",jsxc.registerLogout);var isStorageAttachParameters=jsxc.storage.getItem("rid")&&jsxc.storage.getItem("sid")&&jsxc.storage.getItem("jid"),isOptionsAttachParameters=jsxc.options.xmpp.rid&&jsxc.options.xmpp.sid&&jsxc.options.xmpp.jid,isForceLoginForm=jsxc.options.loginForm&&"force"===jsxc.options.loginForm.ifFound&&jsxc.isLoginForm();if(!isStorageAttachParameters&&!isOptionsAttachParameters||isForceLoginForm){if(jsxc.storage.removeItem("rid"),jsxc.storage.removeItem("sid"),!jsxc.isLoginForm())return jsxc.changeState(jsxc.CONST.STATE.SUSPEND),void(jsxc.options.displayRosterMinimized()&&(jsxc.storage.setUserItem("roster","hidden"),jsxc.gui.roster.init(),jsxc.gui.roster.noConnection()));jsxc.changeState(jsxc.CONST.STATE.TRYTOINTERCEPT),"function"==typeof jsxc.options.formFound&&jsxc.options.formFound.call();var form=jsxc.options.loginForm.form=$(jsxc.options.loginForm.form),events=form.data("events")||{submit:[]},submits=[];$.each(events.submit,function(index,val){submits.push(val.handler)}),form.data("submits",submits),form.off("submit"),form.submit(function(ev){return ev.preventDefault(),jsxc.prepareLogin(function(settings){if(settings!==!1){var enabled=settings.loginForm&&settings.loginForm.enable||settings.xmpp&&settings.xmpp.onlogin;enabled="true"===enabled||enabled===!0,enabled&&(jsxc.options.loginForm.triggered=!0,jsxc.xmpp.login(jsxc.options.xmpp.jid,jsxc.options.xmpp.password))}else jsxc.submitLoginForm()}),!1}),jsxc.changeState(jsxc.CONST.STATE.INTERCEPTED)}else(!jsxc.isLoginForm()||jsxc.options.loginForm&&"attach"===jsxc.options.loginForm.ifFound)&&(jsxc.changeState(jsxc.CONST.STATE.PREVCONFOUND),"undefined"==typeof jsxc.storage.getItem("alive")?jsxc.onMaster():jsxc.checkMaster())},start:function(){var args=arguments;return jsxc.role_allocation&&!jsxc.master?(jsxc.debug("There is an other master tab"),!1):jsxc.xmpp.conn&&jsxc.xmpp.connected?(jsxc.debug("We are already connected"),!1):(3===args.length&&$(document).one("attached.jsxc",function(){jsxc.xmpp.onRidChange(jsxc.xmpp.conn._proto.rid),jsxc.onMaster()}),void jsxc.checkMaster(function(){jsxc.xmpp.login.apply(this,args)}))},registerLogout:function(){if(null!==jsxc.options.logoutElement&&$(jsxc.options.logoutElement).length>0){var logout=function(ev){ev.stopPropagation(),ev.preventDefault(),jsxc.options.logoutElement=$(this),jsxc.triggeredFromLogout=!0,jsxc.xmpp.logout()};jsxc.options.logoutElement=$(jsxc.options.logoutElement),jsxc.options.logoutElement.off("click",null,logout).one("click",logout)}},isLoginForm:function(){return jsxc.options.loginForm.form&&jsxc.el_exists(jsxc.options.loginForm.form)&&jsxc.el_exists(jsxc.options.loginForm.jid)&&jsxc.el_exists(jsxc.options.loginForm.pass)},prepareLogin:function(username,password,cb){"function"==typeof username&&(cb=username,username=null),username=username||$(jsxc.options.loginForm.jid).val(),password=password||$(jsxc.options.loginForm.pass).val(),jsxc.triggeredFromBox||"dialog"!==jsxc.options.loginForm.onConnecting&&"undefined"!=typeof jsxc.options.loginForm.onConnecting||jsxc.gui.showWaitAlert($.t("Logging_in"));var settings;"function"==typeof jsxc.options.loadSettings?(settings=jsxc.options.loadSettings.call(this,username,password,function(s){jsxc._prepareLogin(username,password,cb,s)}),"undefined"!=typeof settings&&jsxc._prepareLogin(username,password,cb,settings)):jsxc._prepareLogin(username,password,cb)},_prepareLogin:function(username,password,cb,loadedSettings){if(loadedSettings===!1)return jsxc.warn("No settings provided"),void cb(!1);var settings=$.extend(!0,{},jsxc.options);loadedSettings?settings=$.extend(!0,settings,loadedSettings):loadedSettings={},"string"==typeof settings.xmpp.username&&(username=settings.xmpp.username);var jid,resource=settings.xmpp.resource?"/"+settings.xmpp.resource:"",domain=settings.xmpp.domain;jid=username.match(/@(.*)$/)?username.match(/\/(.*)$/)?username:username+resource:username+"@"+domain+resource,"function"==typeof jsxc.options.loginForm.preJid&&(jid=jsxc.options.loginForm.preJid(jid)),jsxc.bid=jsxc.jidToBid(jid),settings.xmpp.username=jid.split("@")[0],settings.xmpp.domain=jid.split("@")[1].split("/")[0],settings.xmpp.resource=jid.split("@")[1].split("/")[1]||"",loadedSettings.xmpp||(loadedSettings.xmpp={}),$.each(loadedSettings,function(key){var old=jsxc.options.get(key),val=settings[key];val=$.extend(!0,old,val),jsxc.options.set(key,val)}),jsxc.options.xmpp.jid=jid,jsxc.options.xmpp.password=password,cb(settings)},onSlave:function(){jsxc.debug("I am the slave."),jsxc.role_allocation=!0,jsxc.bid=jsxc.jidToBid(jsxc.storage.getItem("jid")),jsxc.gui.init(),$("#jsxc_roster").removeClass("jsxc_noConnection"),jsxc.registerLogout(),jsxc.gui.updateAvatar($("#jsxc_roster > .jsxc_bottom"),jsxc.jidToBid(jsxc.storage.getItem("jid")),"own"),jsxc.gui.restore()},onMaster:function(){jsxc.debug("I am master."),jsxc.master=!0,jsxc.storage.setItem("alive",0),jsxc.storage.setItem("alive_busy",0),jsxc.startKeepAlive(),jsxc.role_allocation=!0,jsxc.xmpp.login()},checkMaster:function(cb){jsxc.debug("check master"),cb=cb&&"function"==typeof cb?cb:jsxc.onMaster,"undefined"==typeof jsxc.storage.getItem("alive")?cb.call():(jsxc.to.push(window.setTimeout(cb,1e3)),jsxc.keepAlive("slave"))},masterActions:function(){if(jsxc.xmpp.conn&&jsxc.xmpp.conn.authenticated){var noti=jsxc.storage.getUserItem("notification");noti="number"==typeof noti?noti:2,jsxc.options.notification&¬i>0&&jsxc.notification.hasSupport()?jsxc.notification.hasPermission()?jsxc.notification.init():jsxc.notification.prepareRequest():jsxc.options.notification=!1,jsxc.options.get("otr").enable&&jsxc.otr.createDSA(),jsxc.gui.updateAvatar($("#jsxc_roster > .jsxc_bottom"),jsxc.jidToBid(jsxc.storage.getItem("jid")),"own")}},startKeepAlive:function(){jsxc.keepaliveInterval=window.setInterval(jsxc.keepAlive,jsxc.options.timeout-1e3)},keepAlive:function(role){var next=parseInt(jsxc.storage.getItem("alive"))+1;role=role||"master",jsxc.storage.setItem("alive",next+":"+role)},keepBusyAlive:function(){jsxc.toBusy&&window.clearTimeout(jsxc.toBusy),jsxc.keepaliveInterval&&window.clearInterval(jsxc.keepaliveInterval),jsxc.storage.ink("alive_busy"),jsxc.toBusy=window.setTimeout(jsxc.startKeepAlive,jsxc.options.busyTimeout-1e3)},random:function(max){return Math.floor(Math.random()*max)},el_exists:function(selector){return $(selector).length>0},jidToCid:function(jid){jsxc.warn("jsxc.jidToCid is deprecated!");var cid=Strophe.getBareJidFromJid(jid).replace("@","-").replace(/\./g,"-").toLowerCase();return cid},jidToBid:function(jid){return Strophe.unescapeNode(Strophe.getBareJidFromJid(jid).toLowerCase())},restoreRoster:function(){var buddies=jsxc.storage.getUserItem("buddylist");return buddies&&0!==buddies.length?($.each(buddies,function(index,value){jsxc.gui.roster.add(value)}),jsxc.gui.roster.loaded=!0,void $(document).trigger("cloaded.roster.jsxc")):(jsxc.debug("No saved buddylist."),void jsxc.gui.roster.empty())},restoreWindows:function(){var windows=jsxc.storage.getUserItem("windowlist");null!==windows&&$.each(windows,function(index,bid){var win=jsxc.storage.getUserItem("window",bid);return win?(jsxc.gui.window.init(bid),win.minimize?jsxc.gui.window.hide(bid):jsxc.gui.window.show(bid),void jsxc.gui.window.setText(bid,win.text)):(jsxc.debug("Associated window-element is missing: "+bid),!0)})},submitLoginForm:function(){var form=$(jsxc.options.loginForm.form).off("submit"),submits=form.data("submits")||[];$.each(submits,function(index,val){form.submit(val)}),form.find("#submit").length>0?form.find("#submit").click():form.get(0)&&"function"==typeof form.get(0).submit?form.submit():form.find('[type="submit"]').length>0?form.find('[type="submit"]').click():jsxc.warn("Could not submit login form.")},escapeHTML:function(text){return text=text.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),text.replace(/&/g,"&").replace(//g,">")},removeHTML:function(text){return $("").html(text).text()},switchEvents:function(obj){var ns=Math.random().toString(36).substr(2,12),self=this;return $.each(obj,function(key,val){$(document).one(key+"."+ns,function(){$(document).off("."+ns),val.apply(self,arguments)})}),ns},isHidden:function(){var hidden=!1;return"undefined"!=typeof document.hidden?hidden=document.hidden:"undefined"!=typeof document.webkitHidden?hidden=document.webkitHidden:"undefined"!=typeof document.mozHidden?hidden=document.mozHidden:"undefined"!=typeof document.msHidden&&(hidden=document.msHidden),hidden&&jsxc.master?jsxc.storage.ink("hidden",0):hidden||jsxc.master||jsxc.storage.ink("hidden"),hidden},hasFocus:function(){var focus=!0;return"function"==typeof document.hasFocus&&(focus=document.hasFocus()),!focus&&jsxc.master?jsxc.storage.ink("focus",0):focus&&!jsxc.master&&jsxc.storage.ink("focus"),focus},exec:function(fnName,fnParams){var i,fnList=fnName.split("."),fn=jsxc[fnList[0]];for(i=1;i",data)}),jsxc.xmpp.conn.nextValidRid=jsxc.xmpp.onRidChange;var callback=function(status,condition){switch(jsxc.debug(Object.getOwnPropertyNames(Strophe.Status)[status]+": "+condition),status){case Strophe.Status.CONNECTING:$(document).trigger("connecting.jsxc");break;case Strophe.Status.CONNECTED:jsxc.bid=jsxc.jidToBid(jsxc.xmpp.conn.jid.toLowerCase()),$(document).trigger("connected.jsxc");break;case Strophe.Status.ATTACHED:$(document).trigger("attached.jsxc");break;case Strophe.Status.DISCONNECTED:$(document).trigger("disconnected.jsxc");break;case Strophe.Status.CONNFAIL:$(document).trigger("connfail.jsxc");break;case Strophe.Status.AUTHFAIL:$(document).trigger("authfail.jsxc")}};jsxc.xmpp.conn.caps&&(jsxc.xmpp.conn.caps.node="http://jsxc.org/"),jsxc.changeState(jsxc.CONST.STATE.ESTABLISHING),sid&&rid?(jsxc.debug("Try to attach"),jsxc.debug("SID: "+sid),jsxc.reconnect=!0,jsxc.xmpp.conn.attach(jid,sid,rid,callback)):(jsxc.debug("New connection"),jsxc.xmpp.conn.caps&&jsxc.xmpp.conn._addSysHandler(function(stanza){var from=jsxc.xmpp.conn.domain,c=stanza.querySelector("c"),ver=c.getAttribute("ver"),node=c.getAttribute("node"),_jidNodeIndex=JSON.parse(localStorage.getItem("strophe.caps._jidNodeIndex"))||{};jsxc.xmpp.conn.caps._jidVerIndex[from]=ver,_jidNodeIndex[from]=node,localStorage.setItem("strophe.caps._jidVerIndex",JSON.stringify(jsxc.xmpp.conn.caps._jidVerIndex)),localStorage.setItem("strophe.caps._jidNodeIndex",JSON.stringify(_jidNodeIndex))},Strophe.NS.CAPS),jsxc.xmpp.conn.connect(jid,password||jsxc.options.xmpp.password,callback))},logout:function(complete){if(jsxc.triggeredFromElement="boolean"!=typeof complete||complete,!jsxc.master)return jsxc.storage.removeItem("sid"),!0;if(jsxc.storage.removeUserItem("buddylist"),jsxc.storage.removeUserItem("windowlist"),jsxc.storage.removeUserItem("unreadMsg"),$("body").click(),!jsxc.xmpp.conn||!jsxc.xmpp.conn.authenticated)return!0;$.each(jsxc.storage.getUserItem("otrlist")||{},function(i,val){jsxc.otr.create(val)});var numOtr=Object.keys(jsxc.otr.objects||{}).length+1,disReady=function(){--numOtr<=0&&(jsxc.xmpp.conn.flush(),setTimeout(function(){jsxc.xmpp.conn.disconnect()},600))};return $.each(jsxc.otr.objects||{},function(key,obj){obj.msgstate===OTR.CONST.MSGSTATE_ENCRYPTED?obj.endOtr.call(obj,function(){obj.init.call(obj),jsxc.otr.backup(key),disReady()}):disReady()}),disReady(),!1},connected:function(){if(jsxc.xmpp.conn.pause(),jsxc.xmpp.initNewConnection(),jsxc.xmpp.saveSessionParameter(),jsxc.options.loginForm.triggered)switch(jsxc.options.loginForm.onConnected||"submit"){case"submit":return void jsxc.submitLoginForm();case!1:return}jsxc.gui.dialog.close(),jsxc.xmpp.conn.resume(),jsxc.onMaster(),jsxc.changeState(jsxc.CONST.STATE.READY),$(document).trigger("attached.jsxc")},attached:function(){$("#jsxc_roster").removeClass("jsxc_noConnection"),jsxc.xmpp.conn.addHandler(jsxc.xmpp.onRosterChanged,"jabber:iq:roster","iq","set"),jsxc.xmpp.conn.addHandler(jsxc.xmpp.onChatMessage,null,"message","chat"),jsxc.xmpp.conn.addHandler(jsxc.xmpp.onHeadlineMessage,null,"message","headline"),jsxc.xmpp.conn.addHandler(jsxc.xmpp.onReceived,null,"message"),jsxc.xmpp.conn.addHandler(jsxc.xmpp.onPresence,null,"presence"),jsxc.gui.init();var caps=jsxc.xmpp.conn.caps,domain=jsxc.xmpp.conn.domain;if(caps){var conditionalEnable=function(){};if(jsxc.options.get("carbons").enable&&(conditionalEnable=function(){jsxc.xmpp.conn.caps.hasFeatureByJid(domain,jsxc.CONST.NS.CARBONS)&&jsxc.xmpp.carbons.enable()},$(document).on("caps.strophe",function onCaps(ev,from){from===domain&&(conditionalEnable(),$(document).off("caps.strophe",onCaps))})),"undefined"==typeof caps._knownCapabilities[caps._jidVerIndex[domain]]){var _jidNodeIndex=JSON.parse(localStorage.getItem("strophe.caps._jidNodeIndex"))||{};jsxc.debug("Request server capabilities"),caps._requestCapabilities(jsxc.xmpp.conn.domain,_jidNodeIndex[domain],caps._jidVerIndex[domain])}else conditionalEnable()}if(jsxc.reconnect&&jsxc.storage.getUserItem("buddylist"))jsxc.xmpp.sendPres(),jsxc.restoreCompleted||jsxc.gui.restore();else{$(document).one("cloaded.roster.jsxc",jsxc.xmpp.sendPres),$("#jsxc_roster > p:first").remove();var iq=$iq({type:"get"}).c("query",{xmlns:"jabber:iq:roster"});jsxc.xmpp.conn.sendIQ(iq,jsxc.xmpp.onRoster)}jsxc.xmpp.saveSessionParameter(),jsxc.masterActions(),jsxc.changeState(jsxc.CONST.STATE.READY)},saveSessionParameter:function(){var nomJid=Strophe.getBareJidFromJid(jsxc.xmpp.conn.jid).toLowerCase()+"/"+Strophe.getResourceFromJid(jsxc.xmpp.conn.jid);jsxc.storage.setItem("sid",jsxc.xmpp.conn._proto.sid),jsxc.storage.setItem("jid",nomJid)},initNewConnection:function(){jsxc.storage.removeUserItem("buddylist"),jsxc.storage.removeUserItem("windowlist"),jsxc.storage.removeUserItem("own"),jsxc.storage.removeUserItem("avatar","own"),jsxc.storage.removeUserItem("otrlist"),jsxc.storage.removeUserItem("unreadMsg"),jsxc.storage.removeUserElement("options","RTCPeerConfig")},sendPres:function(){jsxc.xmpp.conn.disco&&(jsxc.xmpp.conn.disco.addIdentity("client","web","JSXC"),jsxc.xmpp.conn.disco.addFeature(Strophe.NS.DISCO_INFO),jsxc.xmpp.conn.disco.addFeature(Strophe.NS.RECEIPTS));var pres=$pres();jsxc.xmpp.conn.caps&&pres.c("c",jsxc.xmpp.conn.caps.generateCapsAttrs()).up();var presState=jsxc.storage.getUserItem("presence")||"online";"online"!==presState&&pres.c("show").t(presState).up();var priority=jsxc.options.get("priority");priority&&"undefined"!=typeof priority[presState]&&0!==parseInt(priority[presState])&&pres.c("priority").t(priority[presState]).up(),jsxc.debug("Send presence",pres.toString()),jsxc.xmpp.conn.send(pres)},disconnected:function(){jsxc.debug("disconnected"),jsxc.storage.removeItem("jid"),jsxc.storage.removeItem("sid"),jsxc.storage.removeItem("rid"),jsxc.storage.removeItem("hidden"),jsxc.storage.removeUserItem("avatar","own"),jsxc.storage.removeUserItem("otrlist"),$(document).off("connected.jsxc",jsxc.xmpp.connected),$(document).off("attached.jsxc",jsxc.xmpp.attached),$(document).off("disconnected.jsxc",jsxc.xmpp.disconnected),$(document).off("connfail.jsxc",jsxc.xmpp.onConnfail),$(document).off("authfail.jsxc",jsxc.xmpp.onAuthFail),jsxc.xmpp.conn=null,$("#jsxc_windowList").remove(),jsxc.triggeredFromElement?($(document).trigger("toggle.roster.jsxc",["hidden",0]),jsxc.gui.roster.ready=!1,$("#jsxc_roster").remove(),jsxc.triggeredFromLogout&&(window.location=jsxc.options.logoutElement.attr("href"))):jsxc.gui.roster.noConnection(),window.clearInterval(jsxc.keepaliveInterval),jsxc.role_allocation=!1,jsxc.master=!1,jsxc.storage.removeItem("alive"),jsxc.changeState(jsxc.CONST.STATE.SUSPEND)},onConnfail:function(ev,condition){jsxc.debug("XMPP connection failed: "+condition),jsxc.options.loginForm.triggered&&jsxc.submitLoginForm()},onAuthFail:function(){if(jsxc.options.loginForm.triggered)switch(jsxc.options.loginForm.onAuthFail||"ask"){case"ask":jsxc.gui.showAuthFail();break;case"submit":jsxc.submitLoginForm();break;case"quiet":case!1:return}},onRoster:function(iq){jsxc.debug("Load roster",iq);var buddies=[];$(iq).find("item").each(function(){var jid=$(this).attr("jid"),name=$(this).attr("name")||jid,bid=jsxc.jidToBid(jid),sub=$(this).attr("subscription");buddies.push(bid),jsxc.storage.removeUserItem("res",bid),jsxc.storage.saveBuddy(bid,{jid:jid,name:name,status:0,sub:sub,res:[],rnd:Math.random()}),jsxc.gui.roster.add(bid)}),0===buddies.length&&jsxc.gui.roster.empty(),jsxc.storage.setUserItem("buddylist",buddies),jsxc.xmpp.bookmarks.load(),jsxc.gui.roster.loaded=!0,jsxc.debug("Roster loaded"),$(document).trigger("cloaded.roster.jsxc"),jsxc.changeUIState(jsxc.CONST.UISTATE.READY)},onRosterChanged:function(iq){return jsxc.debug("onRosterChanged",iq),$(iq).find("item").each(function(){var jid=$(this).attr("jid"),name=$(this).attr("name")||jid,bid=jsxc.jidToBid(jid),sub=$(this).attr("subscription");if("remove"===sub)jsxc.gui.roster.purge(bid);else{var bl=jsxc.storage.getUserItem("buddylist");bl.indexOf(bid)<0&&(bl.push(bid),jsxc.storage.setUserItem("buddylist",bl));var temp=jsxc.storage.saveBuddy(bid,{jid:jid,name:name,sub:sub});"updated"===temp?(jsxc.gui.update(bid),jsxc.gui.roster.reorder(bid)):jsxc.gui.roster.add(bid)}if("from"===sub||"both"===sub){var notice,notices=jsxc.storage.getUserItem("notices"),noticeKey=null;for(noticeKey in notices)notice=notices[noticeKey],"gui.showApproveDialog"===notice.fnName&¬ice.fnParams[0]===jid&&(jsxc.debug("Remove notice with key "+noticeKey),jsxc.notice.remove(noticeKey))}}),jsxc.storage.getUserItem("buddylist")&&0!==jsxc.storage.getUserItem("buddylist").length?$("#jsxc_roster > p:first").remove():jsxc.gui.roster.empty(),!0},onPresence:function(presence){jsxc.debug("onPresence",presence);var ptype=$(presence).attr("type"),from=$(presence).attr("from"),jid=Strophe.getBareJidFromJid(from).toLowerCase(),r=Strophe.getResourceFromJid(from),bid=jsxc.jidToBid(jid),data=jsxc.storage.getUserItem("buddy",bid)||{},res=jsxc.storage.getUserItem("res",bid)||{},status=null,xVCard=$(presence).find('x[xmlns="vcard-temp:x:update"]');if(jid===Strophe.getBareJidFromJid(jsxc.storage.getItem("jid")))return!0;if("error"===ptype){$(document).trigger("error.presence.jsxc",[from,presence]);var error=$(presence).find("error");return jsxc.error("[XMPP] "+error.attr("code")+" "+error.find(">:first-child").prop("tagName")),!0}if("subscribe"===ptype){var bl=jsxc.storage.getUserItem("buddylist");return bl.indexOf(bid)>-1?(jsxc.debug("Auto approve contact request, because he is already in our contact list."),jsxc.xmpp.resFriendReq(jid,!0),"to"!==data.sub&&jsxc.xmpp.addBuddy(jid,data.name),!0):(jsxc.storage.setUserItem("friendReq",{jid:jid,approve:-1}),jsxc.notice.add({msg:$.t("Friendship_request"),description:$.t("from")+" "+jid,type:"contact"},"gui.showApproveDialog",[jid]),!0)}if("unavailable"===ptype||"unsubscribed"===ptype)status=jsxc.CONST.STATUS.indexOf("offline");else{var show=$(presence).find("show").text();status=""===show?jsxc.CONST.STATUS.indexOf("online"):jsxc.CONST.STATUS.indexOf(show)}0===status?delete res[r]:r&&(res[r]=status);var maxVal=[],max=0,prop=null;for(prop in res)res.hasOwnProperty(prop)&&max<=res[prop]&&(max!==res[prop]&&(maxVal=[],max=res[prop]),maxVal.push(prop));if(0===data.status&&max>0&&jsxc.notification.notify({title:data.name,msg:$.t("has_come_online"),source:bid}),"groupchat"===data.type?data.status=status:data.status=max,data.res=maxVal,data.jid=jid,xVCard.length>0&&"groupchat"!==data.type){var photo=xVCard.find("photo");photo.length>0&&photo.text()!==data.avatar&&(jsxc.storage.removeUserItem("avatar",data.avatar),data.avatar=photo.text())}return jsxc.gui.window.get(bid).length>0&&jsxc.gui.window.get(bid).data("jid",jid),jsxc.storage.setUserItem("buddy",bid,data),jsxc.storage.setUserItem("res",bid,res),jsxc.debug("Presence ("+from+"): "+jsxc.CONST.STATUS[status]),jsxc.gui.update(bid),jsxc.gui.roster.reorder(bid),$(document).trigger("presence.jsxc",[from,status,presence]),!0},onChatMessage:function(stanza){var message,carbon,forwarded=$(stanza).find('forwarded[xmlns="'+jsxc.CONST.NS.FORWARD+'"]');forwarded.length>0?(message=forwarded.find("> message"),forwarded=!0,carbon=$(stanza).find('> [xmlns="'+jsxc.CONST.NS.CARBONS+'"]'),0===carbon.length&&(carbon=!1),jsxc.debug("Incoming forwarded message",message)):(message=stanza,forwarded=!1,carbon=!1,jsxc.debug("Incoming message",message));var body=$(message).find("body:first").text(),htmlBody=$(message).find('body[xmlns="'+Strophe.NS.XHTML+'"]');if(!body||body.match(/\?OTR/i)&&forwarded)return!0;var bid,type=$(message).attr("type"),from=$(message).attr("from"),mid=$(message).attr("id"),delay=$(message).find('delay[xmlns="urn:xmpp:delay"]'),stamp=delay.length>0?new Date(delay.attr("stamp")):new Date;if(stamp=stamp.getTime(),carbon){var direction="sent"===carbon.prop("tagName")?jsxc.Message.OUT:jsxc.Message.IN;return bid=jsxc.jidToBid("out"===direction?$(message).attr("to"):from),jsxc.gui.window.postMessage({bid:bid,direction:direction,msg:body,encrypted:!1,forwarded:forwarded,stamp:stamp}),!0}forwarded&&(body=from+" "+$.t("to")+" "+$(stanza).attr("to")+'"'+body+'"',from=$(stanza).attr("from"));var jid=Strophe.getBareJidFromJid(from);bid=jsxc.jidToBid(jid);var data=jsxc.storage.getUserItem("buddy",bid),request=$(message).find("request[xmlns='urn:xmpp:receipts']");if(null===data){var chat=jsxc.storage.getUserItem("chat",bid)||[];0===chat.length&&jsxc.notice.add({msg:$.t("Unknown_sender"),description:$.t("You_received_a_message_from_an_unknown_sender")+" ("+bid+")."},"gui.showUnknownSender",[bid]);var msg=jsxc.removeHTML(body);return msg=jsxc.escapeHTML(msg),jsxc.storage.saveMessage(bid,"in",msg,!1,forwarded,stamp),!0}var win=jsxc.gui.window.init(bid);"chat"===type&&(win.data("jid",from),jsxc.storage.updateUserItem("buddy",bid,{jid:from})),$(document).trigger("message.jsxc",[from,body]),jsxc.master&&!jsxc.otr.objects[bid]&&jsxc.otr.create(bid),forwarded||null===mid||!request.length||null===data||"both"!==data.sub&&"from"!==data.sub||"chat"!==type||jsxc.xmpp.conn.send($msg({to:from}).c("received",{xmlns:"urn:xmpp:receipts",id:mid}));var attachment;if(1===htmlBody.length){var httpUploadElement=htmlBody.find("a[data-type][data-name][data-size]");1===httpUploadElement.length&&(attachment={type:httpUploadElement.attr("data-type"),name:httpUploadElement.attr("data-name"),size:httpUploadElement.attr("data-size")},httpUploadElement.attr("data-thumbnail")&&httpUploadElement.attr("data-thumbnail").match(/^\s*data:[a-z]+\/[a-z0-9-+.*]+;base64,[a-z0-9=+\/]+$/i)&&(attachment.thumbnail=httpUploadElement.attr("data-thumbnail")),httpUploadElement.attr("href")&&httpUploadElement.attr("href").match(/^https:\/\//)&&(attachment.data=httpUploadElement.attr("href"),body=null),attachment.type.match(/^[a-z]+\/[a-z0-9-+.*]+$/i)&&attachment.name.match(/^[\s\w.,-]+$/i)&&attachment.size.match(/^\d+$/i)||(attachment=void 0,jsxc.warn("Invalid file type, name or size.")))}return jsxc.otr.objects.hasOwnProperty(bid)&&body?jsxc.otr.objects[bid].receiveMsg(body,{stamp:stamp,forwarded:forwarded,attachment:attachment}):jsxc.gui.window.postMessage({bid:bid,direction:jsxc.Message.IN,msg:body,encrypted:!1,forwarded:forwarded,stamp:stamp,attachment:attachment}),!0},onHeadlineMessage:function(stanza){stanza=$(stanza);var from=stanza.attr("from"),domain=Strophe.getDomainFromJid(from);if(domain!==from){if(!jsxc.storage.getUserItem("buddy",jsxc.jidToBid(from)))return!0}else if(domain!==Strophe.getDomainFromJid(jsxc.xmpp.conn.jid))return!0;var subject=stanza.find("subject:first").text()||$.t("Notification"),body=stanza.find("body:first").text();return jsxc.notice.add({msg:subject,description:body,type:domain===from?"announcement":null},"gui.showNotification",[subject,body,from]),!0},onRidChange:function(rid){jsxc.storage.setItem("rid",rid)},resFriendReq:function(from,approve){jsxc.master?(jsxc.xmpp.conn.send($pres({to:from,type:approve?"subscribed":"unsubscribed"})),jsxc.storage.removeUserItem("friendReq"),jsxc.gui.dialog.close()):jsxc.storage.updateUserItem("friendReq","approve",approve)},addBuddy:function(username,alias){var bid=jsxc.jidToBid(username);if(jsxc.master){var iq=$iq({type:"set"}).c("query",{xmlns:"jabber:iq:roster"}).c("item",{jid:username,name:alias||""});jsxc.xmpp.conn.sendIQ(iq),jsxc.xmpp.conn.send($pres({to:username,type:"subscribe"})),jsxc.storage.removeUserItem("add_"+bid)}else jsxc.storage.setUserItem("add_"+bid,{username:username,alias:alias||null})},removeBuddy:function(jid){var bid=jsxc.jidToBid(jid),iq=$iq({type:"set"}).c("query",{xmlns:"jabber:iq:roster"}).c("item",{jid:Strophe.getBareJidFromJid(jid),subscription:"remove"});jsxc.xmpp.conn.sendIQ(iq),jsxc.gui.roster.purge(bid)},onReceived:function(stanza){var received=$(stanza).find("received[xmlns='urn:xmpp:receipts']");if(received.length){var receivedId=received.attr("id"),message=new jsxc.Message(receivedId);message.received()}return!0},sendMessage:function(message){var bid=message.bid,msg=message.htmlMsg,mucRoomNames=jsxc.xmpp.conn.muc&&jsxc.xmpp.conn.muc.roomNames?jsxc.xmpp.conn.muc.roomNames:[],isMucBid=mucRoomNames.indexOf(bid)>=0;jsxc.otr.objects.hasOwnProperty(bid)&&!isMucBid?jsxc.otr.objects[bid].sendMsg(msg,message):jsxc.xmpp._sendMessage(jsxc.gui.window.get(bid).data("jid"),msg,message)},_sendMessage:function(jid,msg,message){var data=jsxc.storage.getUserItem("buddy",jsxc.jidToBid(jid))||{},isBar=Strophe.getBareJidFromJid(jid)===jid,type=data.type||"chat";message=message||{};var xmlMsg=$msg({to:jid,type:type,id:message._uid});if(message.type===jsxc.Message.HTML){xmlMsg.c("html",{xmlns:Strophe.NS.XHTML_IM});var body=Strophe.xmlElement("body",{xmlns:Strophe.NS.XHTML});body.innerHTML=msg,xmlMsg.node.appendChild(body)}else xmlMsg.c("body").t(msg);jsxc.xmpp.carbons.enabled&&msg.match(/^\?OTR/)&&xmlMsg.up().c("private",{xmlns:jsxc.CONST.NS.CARBONS}),"chat"===type&&(isBar||jsxc.xmpp.conn.caps.hasFeatureByJid(jid,Strophe.NS.RECEIPTS))&&xmlMsg.up().c("request",{xmlns:"urn:xmpp:receipts"}),jsxc.xmpp.conn.chatstates&&!jsxc.xmpp.chatState.isDisabled()&&xmlMsg.up().c("active",{xmlns:Strophe.NS.CHATSTATES}),jsxc.xmpp.conn.send(xmlMsg)},loadVcard:function(bid,cb,error_cb){jsxc.master?jsxc.xmpp.conn.vcard.get(cb,bid,error_cb):(jsxc.storage.setUserItem("vcard",bid,"request:"+(new Date).getTime()),$(document).one("loaded.vcard.jsxc",function(ev,result){result&&"success"===result.state?cb($(result.data).get(0)):error_cb()}))},getCapabilitiesByJid:function(jid){if(jsxc.xmpp.conn)return jsxc.xmpp.conn.caps.getCapabilitiesByJid(jid);var jidVerIndex=JSON.parse(localStorage.getItem("strophe.caps._jidVerIndex"))||{},knownCapabilities=JSON.parse(localStorage.getItem("strophe.caps._knownCapabilities"))||{}; -return jidVerIndex[jid]?knownCapabilities[jidVerIndex[jid]]:null},hasFeatureByJid:function(jid,feature,cb){var conn=jsxc.xmpp.conn;if(cb=cb||function(){},!feature)return!1;$.isArray(feature)||(feature=$.makeArray(feature));var check=function(knownCapabilities){if(!knownCapabilities)return null;var i;for(i=0;i=0?success_cb(bid+"/"+res):fileCapableRes.indexOf(res)<0&&jsxc.gui.window.selectResource(bid,$.t("Your_contact_uses_multiple_clients_"),function(data){"unavailable"===data.status?(jsxc.gui.window.hideOverlay(bid),"function"==typeof error_cb&&error_cb()):"selected"===data.status&&success_cb(bid+"/"+data.result)},fileCapableRes)},jsxc.fileTransfer.showFileSelection=function(jid){var bid=jsxc.jidToBid(jid),msg=$('
');msg.addClass("jsxc_chatmessage"),jsxc.gui.window.showOverlay(bid,msg,!0),msg.find("label").click(),msg.find('[type="file"]').change(function(ev){var file=ev.target.files[0];file&&jsxc.fileTransfer.fileSelected(jid,msg,file)})},jsxc.fileTransfer.fileSelected=function(jid,msg,file){var bid=jsxc.jidToBid(jid);if("webrtc"!==file.transportMethod&&jsxc.xmpp.httpUpload.ready&&file.size>jsxc.options.get("httpUpload").maxSize)return jsxc.debug("File too large for http upload."),file.transportMethod="webrtc",void jsxc.fileTransfer.selectResource(bid,function(jid){jsxc.fileTransfer.fileSelected(jid,msg,file)},function(){var maxSize=jsxc.fileTransfer.formatByte(jsxc.options.get("httpUpload").maxSize),fileSize=jsxc.fileTransfer.formatByte(file.size);jsxc.gui.window.postMessage({bid:bid,direction:jsxc.Message.SYS,msg:$.t("File_too_large")+" ("+fileSize+" > "+maxSize+")"}),jsxc.gui.window.hideOverlay(bid)});!jsxc.xmpp.httpUpload.ready&&Strophe.getResourceFromJid(jid)&&(file.transportMethod="webrtc");var attachment=$("
");if(attachment.addClass("jsxc_attachment"),attachment.addClass("jsxc_"+file.type.replace(/\//,"-")),attachment.addClass("jsxc_"+file.type.replace(/^([^\/]+)\/.*/,"$1")),msg.empty().append(attachment),FileReader&&file.type.match(/^image\//)){var img=$('preview').attr("title",file.name);img.attr("src",jsxc.options.get("root")+"/img/loading.gif"),img.appendTo(attachment);var reader=new FileReader;reader.onload=function(){img.attr("src",reader.result)},reader.readAsDataURL(file)}else attachment.text(file.name+" ("+file.size+" byte)");$("