Commit 7f842c42 authored by JC Brand's avatar JC Brand

Update some bower dependencies and rebuilt dist files

fixes #437
parent f55ab176
......@@ -25,6 +25,9 @@ JSHINTEXCEPTIONS = $(GENERATED) \
src/bigint.js
CHECKSOURCES = $(filter-out $(JSHINTEXCEPTIONS),$(SOURCES))
.PHONY: all
all: dev
.PHONY: help
help:
@echo "Please use \`make <target>' where <target> is one of the following:"
......@@ -50,8 +53,6 @@ help:
@echo " stamp-bundler Install Bundler (Ruby) dependencies and create the guard file stamp-bundler which will prevent those dependencies from being installed again."
@echo " watch Tells Sass to watch the .scss files for changes and then automatically update the CSS files."
.PHONY: all
all: dev
########################################################################
## Miscellaneous
......
......@@ -8,29 +8,31 @@
"sinon": "^1.17.3"
},
"dependencies": {
"requirejs": "~2.1.15",
"jquery": "1.11.0",
"jed": "0.5.4",
"requirejs": "~2.2.0",
"jquery": "1.12.2",
"jed": "1.1.0",
"underscore": "~1.8.3",
"backbone": "1.1.2",
"backbone.browserStorage": "0.0.2",
"backbone.overview": "0.0.2",
"otr": "0.2.12",
"otr": "0.2.16",
"crypto-js-evanvosberg": "https://github.com/evanvosberg/crypto-js.git#release-3.1.2-5",
"almond": "~0.3.0",
"requirejs-text": "~2.0.12",
"almond": "~0.3.1",
"requirejs-text": "~2.0.14",
"requirejs-tpl-jcbrand": "*",
"momentjs": "~2.10.6",
"jquery.browser": ">=0.0.7",
"momentjs": "~2.12.0",
"jquery.browser": ">=0.1.0",
"bootstrap": "~3.2.0",
"fontawesome": "~4.1.0",
"typeahead.js": "https://raw.githubusercontent.com/jcbrand/typeahead.js/eedfb10505dd3a20123d1fafc07c1352d83f0ab3/dist/typeahead.jquery.js",
"strophejs": "1.2.4",
"strophejs": "1.2.5",
"strophejs-plugins": "https://github.com/strophe/strophejs-plugins.git#amd",
"bourbon": "~4.2.3"
"bourbon": "~4.2.6"
},
"resolutions": {
"backbone": "1.1.2"
"backbone": "1.1.2",
"requirejs": "~2.2.0",
"jquery": "1.12.2"
},
"exportsOverride": {},
"ignore": [
......
......@@ -27,4 +27,4 @@
Copyright 2014 Yahoo! Inc. All rights reserved.
Licensed under the BSD License.
https://github.com/yahoo/pure/blob/master/LICENSE.md
*/-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#conversejs html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}#conversejs body{margin:0}#conversejs article,#conversejs aside,#conversejs details,#conversejs figcaption,#conversejs figure,#conversejs footer,#conversejs header,#conversejs hgroup,#conversejs main,#conversejs menu,#conversejs nav,#conversejs section,#conversejs summary{display:block}#conversejs audio,#conversejs canvas,#conversejs progress,#conversejs video{display:inline-block;vertical-align:baseline}#conversejs audio:not([controls]){display:none;height:0}#conversejs [hidden],#conversejs template{display:none}#conversejs a{background-color:transparent}#conversejs a:active,#conversejs a:hover{outline:0}#conversejs abbr[title]{border-bottom:1px dotted}#conversejs b,#conversejs strong{font-weight:700}#conversejs dfn{font-style:italic}#conversejs mark{background:#ff0;color:#000}#conversejs small{font-size:80%}#conversejs sub,#conversejs sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}#conversejs sup{top:-.5em}#conversejs sub{bottom:-.25em}#conversejs svg:not(:root){overflow:hidden}#conversejs hr{box-sizing:content-box;height:0}#conversejs pre{overflow:auto}#conversejs code,#conversejs kbd,#conversejs pre,#conversejs samp{font-family:monospace,monospace;font-size:1em}#conversejs button,#conversejs input,#conversejs optgroup,#conversejs select,#conversejs textarea{color:inherit;font:inherit;margin:0}#conversejs button{overflow:visible}#conversejs button,#conversejs select{text-transform:none}#conversejs button,#conversejs html input[type=button],#conversejs input[type=reset],#conversejs input[type=submit]{-webkit-appearance:button;cursor:pointer}#conversejs button[disabled],#conversejs html input[disabled]{cursor:default}#conversejs button::-moz-focus-inner,#conversejs input::-moz-focus-inner{border:0;padding:0}#conversejs input{line-height:normal}#conversejs input[type=checkbox],#conversejs input[type=radio]{box-sizing:border-box;padding:0}#conversejs input[type=number]::-webkit-inner-spin-button,#conversejs input[type=number]::-webkit-outer-spin-button{height:auto}#conversejs input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}#conversejs input[type=search]::-webkit-search-cancel-button,#conversejs input[type=search]::-webkit-search-decoration{-webkit-appearance:none}#conversejs textarea{overflow:auto}#conversejs optgroup{font-weight:700}#conversejs table{border-collapse:collapse;border-spacing:0}#conversejs .hidden,#conversejs [hidden]{display:none!important}#conversejs .pure-img{max-width:100%;height:auto;display:block}#conversejs .pure-form input[type=color],#conversejs .pure-form input[type=date],#conversejs .pure-form input[type=datetime-local],#conversejs .pure-form input[type=datetime],#conversejs .pure-form input[type=email],#conversejs .pure-form input[type=month],#conversejs .pure-form input[type=number],#conversejs .pure-form input[type=password],#conversejs .pure-form input[type=search],#conversejs .pure-form input[type=tel],#conversejs .pure-form input[type=text],#conversejs .pure-form input[type=time],#conversejs .pure-form input[type=url],#conversejs .pure-form input[type=week],#conversejs .pure-form select,#conversejs .pure-form textarea{padding:.5em .6em;display:inline-block;border:1px solid #ccc;box-shadow:inset 0 1px 3px #ddd;border-radius:4px;vertical-align:middle;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#conversejs .pure-form input:not([type]){padding:.5em .6em;display:inline-block;border:1px solid #ccc;box-shadow:inset 0 1px 3px #ddd;border-radius:4px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#conversejs .pure-form input[type=color]{padding:.2em .5em}#conversejs .pure-form input:not([type]):focus,#conversejs .pure-form input[type=color]:focus,#conversejs .pure-form input[type=date]:focus,#conversejs .pure-form input[type=datetime-local]:focus,#conversejs .pure-form input[type=datetime]:focus,#conversejs .pure-form input[type=email]:focus,#conversejs .pure-form input[type=month]:focus,#conversejs .pure-form input[type=number]:focus,#conversejs .pure-form input[type=password]:focus,#conversejs .pure-form input[type=search]:focus,#conversejs .pure-form input[type=tel]:focus,#conversejs .pure-form input[type=text]:focus,#conversejs .pure-form input[type=time]:focus,#conversejs .pure-form input[type=url]:focus,#conversejs .pure-form input[type=week]:focus,#conversejs .pure-form select:focus,#conversejs .pure-form textarea:focus{outline:0;border-color:#1A9707}#conversejs .pure-form input[type=checkbox]:focus,#conversejs .pure-form input[type=file]:focus,#conversejs .pure-form input[type=radio]:focus{outline:thin solid #1A9707;outline:1px auto #1A9707}#conversejs .pure-form .pure-checkbox,#conversejs .pure-form .pure-radio{margin:.5em 0;display:block}#conversejs .pure-form input:not([type])[disabled],#conversejs .pure-form input[type=color][disabled],#conversejs .pure-form input[type=date][disabled],#conversejs .pure-form input[type=datetime-local][disabled],#conversejs .pure-form input[type=datetime][disabled],#conversejs .pure-form input[type=email][disabled],#conversejs .pure-form input[type=month][disabled],#conversejs .pure-form input[type=number][disabled],#conversejs .pure-form input[type=password][disabled],#conversejs .pure-form input[type=search][disabled],#conversejs .pure-form input[type=tel][disabled],#conversejs .pure-form input[type=text][disabled],#conversejs .pure-form input[type=time][disabled],#conversejs .pure-form input[type=url][disabled],#conversejs .pure-form input[type=week][disabled],#conversejs .pure-form select[disabled],#conversejs .pure-form textarea[disabled]{cursor:not-allowed;background-color:#eaeded;color:#cad2d3}#conversejs .pure-form input[readonly],#conversejs .pure-form select[readonly],#conversejs .pure-form textarea[readonly]{background-color:#eee;color:#777;border-color:#ccc}#conversejs .pure-form input:focus:invalid,#conversejs .pure-form select:focus:invalid,#conversejs .pure-form textarea:focus:invalid{color:#b94a48;border-color:#e9322d}#conversejs .pure-form input[type=checkbox]:focus:invalid:focus,#conversejs .pure-form input[type=file]:focus:invalid:focus,#conversejs .pure-form input[type=radio]:focus:invalid:focus{outline-color:#e9322d}#conversejs .pure-form select{height:2.25em;border:1px solid #ccc;background-color:#fff}#conversejs .pure-form select[multiple]{height:auto}#conversejs .pure-form label{margin:.5em 0 .2em}#conversejs .pure-form fieldset{margin:0;padding:.35em 0 .75em;border:0}#conversejs .pure-form legend{display:block;width:100%;padding:.3em 0;margin-bottom:.3em;color:#333;border-bottom:1px solid #e5e5e5}#conversejs .pure-form-stacked input:not([type]),#conversejs .pure-form-stacked input[type=color],#conversejs .pure-form-stacked input[type=date],#conversejs .pure-form-stacked input[type=datetime-local],#conversejs .pure-form-stacked input[type=datetime],#conversejs .pure-form-stacked input[type=email],#conversejs .pure-form-stacked input[type=file],#conversejs .pure-form-stacked input[type=month],#conversejs .pure-form-stacked input[type=number],#conversejs .pure-form-stacked input[type=password],#conversejs .pure-form-stacked input[type=search],#conversejs .pure-form-stacked input[type=tel],#conversejs .pure-form-stacked input[type=text],#conversejs .pure-form-stacked input[type=time],#conversejs .pure-form-stacked input[type=url],#conversejs .pure-form-stacked input[type=week],#conversejs .pure-form-stacked label,#conversejs .pure-form-stacked select,#conversejs .pure-form-stacked textarea{display:block;margin:.25em 0}#conversejs .pure-form-aligned .pure-help-inline,#conversejs .pure-form-aligned input,#conversejs .pure-form-aligned select,#conversejs .pure-form-aligned textarea,#conversejs .pure-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}#conversejs .pure-form-aligned textarea{vertical-align:top}#conversejs .pure-form-aligned .pure-control-group{margin-bottom:.5em}#conversejs .pure-form-aligned .pure-control-group label{text-align:right;display:inline-block;vertical-align:middle;width:10em;margin:0 1em 0 0}#conversejs .pure-form-aligned .pure-controls{margin:1.5em 0 0 11em}#conversejs .pure-form .pure-input-rounded,#conversejs .pure-form input.pure-input-rounded{border-radius:2em;padding:.5em 1em}#conversejs .pure-form .pure-group fieldset{margin-bottom:10px}#conversejs .pure-form .pure-group input,#conversejs .pure-form .pure-group textarea{display:block;padding:10px;margin:0 0 -1px;border-radius:0;position:relative;top:-1px}#conversejs .pure-form .pure-group input:focus,#conversejs .pure-form .pure-group textarea:focus{z-index:3}#conversejs .pure-form .pure-group input:first-child,#conversejs .pure-form .pure-group textarea:first-child{top:1px;border-radius:4px 4px 0 0;margin:0}#conversejs .pure-form .pure-group input:first-child:last-child,#conversejs .pure-form .pure-group textarea:first-child:last-child{top:1px;border-radius:4px;margin:0}#conversejs .pure-form .pure-group input:last-child,#conversejs .pure-form .pure-group textarea:last-child{top:-2px;border-radius:0 0 4px 4px;margin:0}#conversejs .pure-form .pure-group button{margin:.35em 0}#conversejs .pure-form .pure-input-1{width:100%}#conversejs .pure-form .pure-input-3-4{width:75%}#conversejs .pure-form .pure-input-2-3{width:66%}#conversejs .pure-form .pure-input-1-2{width:50%}#conversejs .pure-form .pure-input-1-3{width:33%}#conversejs .pure-form .pure-input-1-4{width:25%}#conversejs .pure-form .pure-help-inline,#conversejs .pure-form-message-inline{display:inline-block;padding-left:.3em;color:#666;vertical-align:middle;font-size:.875em}#conversejs .pure-form-message{display:block;color:#666;font-size:.875em}@media only screen and (max-width:480px){#conversejs .pure-form button[type=submit]{margin:.7em 0 0}#conversejs .pure-form input:not([type]),#conversejs .pure-form input[type=color],#conversejs .pure-form input[type=date],#conversejs .pure-form input[type=datetime-local],#conversejs .pure-form input[type=datetime],#conversejs .pure-form input[type=email],#conversejs .pure-form input[type=month],#conversejs .pure-form input[type=number],#conversejs .pure-form input[type=password],#conversejs .pure-form input[type=search],#conversejs .pure-form input[type=tel],#conversejs .pure-form input[type=text],#conversejs .pure-form input[type=time],#conversejs .pure-form input[type=url],#conversejs .pure-form input[type=week],#conversejs .pure-form label{margin-bottom:.3em;display:block}#conversejs .pure-group input:not([type]),#conversejs .pure-group input[type=color],#conversejs .pure-group input[type=date],#conversejs .pure-group input[type=datetime-local],#conversejs .pure-group input[type=datetime],#conversejs .pure-group input[type=email],#conversejs .pure-group input[type=month],#conversejs .pure-group input[type=number],#conversejs .pure-group input[type=password],#conversejs .pure-group input[type=search],#conversejs .pure-group input[type=tel],#conversejs .pure-group input[type=text],#conversejs .pure-group input[type=time],#conversejs .pure-group input[type=url],#conversejs .pure-group input[type=week]{margin-bottom:0}#conversejs .pure-form-aligned .pure-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}#conversejs .pure-form-aligned .pure-controls{margin:1.5em 0 0}#conversejs .pure-form .pure-help-inline,#conversejs .pure-form-message,#conversejs .pure-form-message-inline{display:block;font-size:.75em;padding:.2em 0 .8em}}#conversejs .pure-button{display:inline-block;zoom:1;line-height:normal;white-space:nowrap;vertical-align:middle;text-align:center;cursor:pointer;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;font-family:inherit;font-size:100%;padding:.5em 1em;color:#444;color:rgba(0,0,0,.8);border:1px solid #999;border:none transparent;background-color:#E6E6E6;text-decoration:none}#conversejs .pure-button-hover,#conversejs .pure-button:focus,#conversejs .pure-button:hover{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#1a000000', GradientType=0);background-image:-webkit-gradient(linear,0 0,0 100%,from(transparent),color-stop(40%,rgba(0,0,0,.05)),to(rgba(0,0,0,.1)));background-image:-webkit-linear-gradient(transparent,rgba(0,0,0,.05)40%,rgba(0,0,0,.1));background-image:-moz-linear-gradient(top,rgba(0,0,0,.05)0,rgba(0,0,0,.1));background-image:-o-linear-gradient(transparent,rgba(0,0,0,.05)40%,rgba(0,0,0,.1));background-image:linear-gradient(transparent,rgba(0,0,0,.05)40%,rgba(0,0,0,.1))}#conversejs .pure-button:focus{outline:0}#conversejs .pure-button-active,#conversejs .pure-button:active{box-shadow:0 0 0 1px rgba(0,0,0,.15)inset,0 0 6px rgba(0,0,0,.2)inset}#conversejs .pure-button-disabled,#conversejs .pure-button-disabled:active,#conversejs .pure-button-disabled:focus,#conversejs .pure-button-disabled:hover,#conversejs .pure-button[disabled]{border:none;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);filter:alpha(opacity=40);-khtml-opacity:.4;-moz-opacity:.4;opacity:.4;cursor:not-allowed;box-shadow:none}#conversejs .pure-button-hidden{display:none}#conversejs .pure-button::-moz-focus-inner{padding:0;border:0}#conversejs .pure-button-primary,#conversejs .pure-button-selected,#conversejs a.pure-button-primary,#conversejs a.pure-button-selected{background-color:#0078e7;color:#fff}#conversejs *,#conversejs :after,#conversejs :before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}@media screen and (max-width:480px){#conversejs{margin:0;right:10px;left:10px;bottom:5px}}#conversejs ul li{height:auto}#conversejs a,#conversejs article,#conversejs aside,#conversejs audio,#conversejs blockquote,#conversejs canvas,#conversejs caption,#conversejs dd,#conversejs details,#conversejs div,#conversejs dl,#conversejs dt,#conversejs em,#conversejs embed,#conversejs fieldset,#conversejs figcaption,#conversejs figure,#conversejs footer,#conversejs form,#conversejs h1,#conversejs h2,#conversejs h3,#conversejs h4,#conversejs h5,#conversejs h6,#conversejs header,#conversejs hgroup,#conversejs img,#conversejs label,#conversejs legend,#conversejs li,#conversejs mark,#conversejs menu,#conversejs nav,#conversejs ol,#conversejs output,#conversejs p,#conversejs pre,#conversejs ruby,#conversejs section,#conversejs span,#conversejs strong,#conversejs summary,#conversejs table,#conversejs tbody,#conversejs td,#conversejs tfoot,#conversejs th,#conversejs thead,#conversejs time,#conversejs tr,#conversejs ul,#conversejs video{margin:0;padding:0;border:0;font:inherit;vertical-align:baseline}#conversejs button,#conversejs input[type=button],#conversejs input[type=password],#conversejs input[type=submit],#conversejs input[type=text],#conversejs textarea{font-size:14px;padding:.25em;min-height:0}#conversejs strong{font-weight:700}#conversejs ol,#conversejs ul{list-style:none}#conversejs li{height:10px}#conversejs dl,#conversejs ol,#conversejs ul{font:inherit;margin:0}#conversejs a,#conversejs a:visited{text-decoration:none;color:#2A9D8F;text-shadow:none}#conversejs{bottom:0;color:#818479;direction:ltr;display:block;font-size:14px;height:35px;position:fixed;left:0;right:0;width:auto;z-index:30}@media screen and (max-width:480px){#conversejs{width:100%;width:100vw}}#conversejs ::selection{background-color:#DCF9F6}#conversejs ::-moz-selection{background-color:#DCF9F6}#conversejs .no-text-select{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}#conversejs .emoticon{font-size:14px}#conversejs .left{float:left}#conversejs .right{float:right}#conversejs .centered{text-align:center;display:block;margin:5em auto}#conversejs .hor_centered{text-align:center;display:block;margin:0 auto;clear:both}#conversejs .locked{padding-right:22px}@-webkit-keyframes spin{from{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(359deg)}}@-moz-keyframes spin{from{-moz-transform:rotate(0deg)}to{-moz-transform:rotate(359deg)}}@keyframes spin{from{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);-o-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);-moz-transform:rotate(359deg);-ms-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}#conversejs .spinner{-webkit-animation:spin 2s infinite,linear;-moz-animation:spin 2s infinite,linear;animation:spin 2s infinite,linear;display:block;text-align:center;margin:5px}#conversejs .spinner:before{font-size:24px;font-family:Converse-js!important;content:"\231b"}#conversejs .button-group,#conversejs .input-button-group{display:table}#conversejs .button-group{width:100%}#conversejs .input-button-group button,#conversejs .input-button-group input{display:table-cell}#conversejs .error{color:red}#conversejs .reg-feedback{font-size:85%}#conversejs #converse-login .conn-feedback,#conversejs .reg-feedback{display:block;text-align:center;width:100%}#conversejs a.restore-chat{padding:1px 0 1px 5px;color:#fff;line-height:15px;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#conversejs a.restore-chat:visited{color:#fff}#conversejs .activated{display:block!important}#conversejs .pure-button{border-radius:4px}#conversejs .button-primary{color:#fff;background-color:#2AC611}#conversejs .button-secondary{color:#fff;background-color:#83A0D6}#conversejs .button-cancel{color:#fff;background-color:#D24E2B}#conversejs form.pure-form.converse-form{background:#fff;margin:1em}#conversejs form.pure-form.converse-form legend{color:#818479}#conversejs form.pure-form.converse-form label{margin-top:1em}#conversejs form.pure-form.converse-form input[type=button],#conversejs form.pure-form.converse-form input[type=number],#conversejs form.pure-form.converse-form input[type=password],#conversejs form.pure-form.converse-form input[type=submit],#conversejs form.pure-form.converse-form input[type=text]{height:2.2em}#conversejs form.pure-form.converse-form input[type=button],#conversejs form.pure-form.converse-form input[type=submit]{padding-left:1em;padding-right:1em;margin-right:1em}#conversejs form.pure-form.converse-form input.error{border:1px solid red;color:#818479}#conversejs form.pure-form.converse-form .form-help{color:gray;font-size:85%;padding-top:.5em}#conversejs form.pure-form.converse-form .form-help:hover{color:#818479}#conversejs .chat-textarea-chatbox-selected{border:1px solid #578308;margin:0}#conversejs .chat-textarea-chatroom-selected{border:2px solid #2A9D8F;margin:0}#conversejs .dropdown dt,#conversejs .dropdown ul{margin:0;padding:0}#conversejs .flyout{border-radius:4px;bottom:6px;display:block;position:absolute}#conversejs .chat-head{border-top-left-radius:4px;border-top-right-radius:4px;color:#fff;font-size:100%;height:55px;margin:0;padding:5px;position:relative}#conversejs .chat-head .avatar{margin-right:.5em;border-radius:50%;float:left}#conversejs .chat-head.chat-head-chatbox{background-color:#F4A261}#conversejs .chat-head .user-custom-message{clear:left;color:#fff;font-size:80%;font-style:italic;height:1.3em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin:0;padding-top:.2em}#conversejs .chatbox-btn{border-radius:50%;border:1px solid #fff;color:#fff;cursor:pointer;display:inline-block;float:right;font-size:9px;margin:0;margin-right:.2em;padding:.5em .5em .3em;text-decoration:none}#conversejs .chatbox-btn:active{position:relative;top:1px}#conversejs .chatbox{display:block;float:right;height:35px;margin:0 .5em;width:200px}@media screen and (max-width:480px){#conversejs .chatbox{margin:0;width:100%}}#conversejs .chatbox .box-flyout{background-color:#fff;box-shadow:1px 3px 5px 3px rgba(0,0,0,.4);height:450px;min-height:225px;min-width:200px;width:200px;z-index:1}@media screen and (max-width:480px){#conversejs .chatbox .box-flyout{width:100%;height:99vh}}#conversejs .chatbox .chat-title{color:#fff;line-height:15px;display:block;text-overflow:ellipsis;overflow:hidden;height:2em}#conversejs .chatbox .chat-title a{color:#fff;width:100%}#conversejs .chatbox .chat-body{background-color:#fff;border-bottom-left-radius:4px;border-bottom-right-radius:4px;border-top:0;height:289px;height:-webkit-calc(100% - 55px);height:calc(100% - 55px)}#conversejs .chatbox .chat-body p{color:#818479;font-size:14px;margin:0;padding:5px}#conversejs .chatbox .chat-body .chat-info{color:#D24E2B;margin:.3em}#conversejs .chatbox .chat-body .chat-info.chat-event{clear:left;font-style:italic}#conversejs .chatbox .chat-body .chat-info.chat-error{color:#D24E2B;font-weight:700}#conversejs .chatbox .chat-body .chat-info.chat-date{display:inline-block;margin-top:2em}#conversejs .chatbox .chat-body .chat-message{margin:.3em}#conversejs .chatbox .chat-body .chat-message span{display:inline-block}#conversejs .chatbox .chat-body .chat-message span.chat-msg-author{max-width:100%;font-weight:700;white-space:nowrap;float:left;text-overflow:ellipsis;overflow:hidden}#conversejs .chatbox .chat-body .chat-message span.chat-msg-them{color:#1A9707}#conversejs .chatbox .chat-body .chat-message span.chat-msg-me{color:#2A9D8F}#conversejs .chatbox .chat-body .chat-message span.chat-msg-content{max-width:100%;word-wrap:break-word}#conversejs .chatbox .chat-body .delayed .chat-msg-them{color:#FB5D50}#conversejs .chatbox .chat-body .delayed .chat-msg-me{color:#7EABBB}#conversejs .chatbox .chat-content{position:relative;padding:.5em;font-size:13px;color:#818479;overflow-y:auto;border:0;background-color:#fff;line-height:1.3em;height:206px;height:calc(100% - 96px)}#conversejs .chatbox .dropdown{background-color:#FCFDFD}#conversejs .chatbox .dropdown dd{margin:0;padding:0;position:relative}#conversejs .chatbox form.sendXMPPMessage{-moz-background-clip:padding;-webkit-background-clip:padding-box;border-bottom-left-radius:4px;border-bottom-right-radius:4px;background:#fff;border:0;margin:0;padding:0;position:relative;height:95px;min-width:200px}@media screen and (max-width:480px){#conversejs .chatbox form.sendXMPPMessage{width:100%}}#conversejs .chatbox form.sendXMPPMessage .chat-textarea{border-bottom-left-radius:4px;border-bottom-right-radius:4px;border:0;height:70px;padding:.5em;width:100%;resize:none}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar{font-size:14px;margin:0;padding:5px;height:25px;display:block;background-color:#FFF5EE}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar a{color:#2A9D8F}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .chat-toolbar-text{font-size:12px;padding-right:3px;text-shadow:0 1px 0 #fff}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .unencrypted,#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .unencrypted a{color:#D24E2B}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .unverified,#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .unverified a{color:#cf5300}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .private,#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .private a{color:#4b7003}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-clear,#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-occupants,#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-otr{float:right}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li{display:inline-block;list-style:none;padding:0 3px;cursor:pointer;margin-top:1px}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li:hover{cursor:pointer}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar ul{background:#fff;bottom:100%;box-shadow:-1px -1px 2px 0 rgba(0,0,0,.4);display:none;font-size:12px;margin:0 0 1px;position:absolute;right:0}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar ul li{cursor:pointer;list-style:none;position:relative}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar ul li a:hover{color:#8f2831}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley{color:#2A9D8F;padding-left:5px}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul li{font-size:14px;padding:5px;z-index:98}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul li:hover{background-color:#DCF9F6}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-otr ul li{padding:7px;background-color:#fff;display:block;z-index:99}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-otr ul li a{-moz-transition:background-color .2s ease-in-out;-webkit-transition:background-color .2s ease-in-out;transition:background-color .2s ease-in-out;display:block;padding:1px;text-decoration:none}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-otr ul li:hover{background-color:#DCF9F6}#conversejs .chatbox .dragresize{background:0 0;border:0;margin:0;position:absolute;top:0;z-index:20}#conversejs .chatbox .dragresize-top{cursor:n-resize;height:5px;width:100%}#conversejs .chatbox .dragresize-left{cursor:w-resize;width:5px;height:100%;left:0}#conversejs .chatbox .dragresize-topleft{cursor:nw-resize;width:15px;height:15px;top:0;left:0}#conversejs #controlbox{display:none;margin-right:1em}@media screen and (max-width:480px){#conversejs #controlbox{margin:0}}#conversejs #controlbox .controlbox-head{background-color:#577BDD;border-top-left-radius:4px;border-top-right-radius:4px;color:#fff;height:55px;margin:0;padding:6px 6px 6px 0}#conversejs #controlbox form.search-xmpp-contact{margin:0;padding:0 0 5px 5px}#conversejs #controlbox form.search-xmpp-contact input{width:8em}#conversejs #controlbox a.subscribe-to-user{padding-left:2em;font-weight:700}#conversejs #controlbox #converse-register{background:#fff}#conversejs #controlbox #converse-register .title{font-weight:700}#conversejs #controlbox #converse-register .info{font-style:italic;color:green;font-size:85%;margin:5px 0}#conversejs #controlbox #converse-register .form-errors{color:red;display:none}#conversejs #controlbox #converse-register .provider-title{font-size:22px}#conversejs #controlbox #converse-register .provider-score{width:178px;margin-bottom:8px}#conversejs #controlbox #converse-register .form-help .url{font-weight:700;color:#2A9D8F}#conversejs #controlbox #converse-register .input-group{display:table;margin:auto;width:100%}#conversejs #controlbox #converse-register .input-group span{overflow-x:hidden;text-overflow:ellipsis;max-width:110px}#conversejs #controlbox #converse-register .input-group input[name=username],#conversejs #controlbox #converse-register .input-group span{display:table-cell;text-align:left}#conversejs #controlbox #converse-register .instructions{color:gray;font-size:85%}#conversejs #controlbox #converse-register .instructions:hover{color:#818479}#conversejs #controlbox #converse-login,#conversejs #controlbox #converse-register{margin-top:2em}#conversejs #controlbox #converse-login .login-anon,#conversejs #controlbox #converse-register .login-anon{height:auto;white-space:normal}#conversejs #controlbox #converse-login .save-submit,#conversejs #controlbox #converse-register .save-submit{color:#436F64}#conversejs #controlbox #converse-login input,#conversejs #controlbox #converse-register input{width:100%;margin:.5em 0}#conversejs #controlbox #users .add-converse-contact{margin:0 1em .75em}#conversejs #controlbox #chatrooms form.add-chatroom input[type=button],#conversejs #controlbox #chatrooms form.add-chatroom input[type=submit],#conversejs #controlbox #chatrooms form.add-chatroom input[type=text]{width:100%}#conversejs #controlbox #chatrooms #available-chatrooms{padding:0 1em 2em;text-align:left}#conversejs #controlbox #chatrooms #available-chatrooms dt{border:none;color:#818479;font-weight:400;padding:0;padding-bottom:.5em;text-shadow:0 1px 0 #FAFAFA}#conversejs #controlbox #chatrooms #available-chatrooms dd.available-chatroom{border:none;clear:both;color:#818479;display:block;overflow:hidden;padding:.4em;text-shadow:0 1px 0 #FAFAFA;word-wrap:break-word}#conversejs #controlbox #chatrooms #available-chatrooms dd.available-chatroom:hover{background-color:#DCF9F6}#conversejs #controlbox #chatrooms #available-chatrooms dd.available-chatroom a.room-info{clear:right;display:block}#conversejs #controlbox #chatrooms #available-chatrooms dd.available-chatroom a.room-info:before{font-size:15px}#conversejs #controlbox #chatrooms #available-chatrooms dd.available-chatroom a.open-room{float:left;width:85%}#conversejs #controlbox #chatrooms #available-chatrooms dd.available-chatroom .room-info{font-size:11px;font-style:normal;font-weight:400}#conversejs #controlbox #chatrooms #available-chatrooms dd.available-chatroom li.room-info{display:block;margin-left:5px}#conversejs #controlbox #chatrooms #available-chatrooms dd.available-chatroom p.room-info{margin:0;padding:0;display:block;white-space:normal}#conversejs #controlbox #chatrooms #available-chatrooms dd.available-chatroom div.room-info{clear:left;width:100%}#conversejs #controlbox .dropdown a{width:148px;display:inline-block;line-height:25px}#conversejs #controlbox .dropdown li{list-style:none;padding-left:0}#conversejs #controlbox .dropdown dd ul{padding:0;list-style:none;position:absolute;left:0;top:0;border:1px solid #B1BFC4;width:100%;z-index:21;background-color:#FCFDFD}#conversejs #controlbox .dropdown dd ul li:hover{background-color:#DCF9F6}#conversejs #controlbox .dropdown dd.search-xmpp ul{box-shadow:1px 4px 10px 1px rgba(0,0,0,.4)}#conversejs #controlbox .dropdown dd.search-xmpp ul li:hover{background-color:#FCFDFD}#conversejs #controlbox .dropdown dt a span{cursor:pointer;display:block;padding:4px 7px 0 5px}#conversejs #controlbox #select-xmpp-status{float:right;margin-right:.5em}#conversejs #controlbox #set-custom-xmpp-status{float:left;padding:0}#conversejs #controlbox #set-custom-xmpp-status fieldset{padding:0;margin-top:-1px}#conversejs #controlbox #set-custom-xmpp-status input{height:26px;width:-webkit-calc(100% - 40px);width:calc(100% - 40px);padding:0 0 0 .5em}#conversejs #controlbox #set-custom-xmpp-status input[type=submit]{height:26px;width:40px;padding:1px;float:right}#conversejs #controlbox #controlbox-tabs{text-align:center;display:inline;overflow:hidden;font-size:12px;list-style-type:none}#conversejs #controlbox #controlbox-tabs li{float:left;list-style:none;padding-left:0;text-shadow:#fff 0 1px 0;width:38%}#conversejs #controlbox #controlbox-tabs li a{background-color:#fff;border-bottom:1px solid #CCC;border-top-left-radius:4px;border-top-right-radius:4px;box-shadow:inset 2px -2px 20px rgba(0,0,0,.3);color:#818479;display:block;font-size:12px;height:54px;line-height:54px;margin:0;text-align:center;text-decoration:none}#conversejs #controlbox #controlbox-tabs li a:hover{color:#818479}#conversejs #controlbox #controlbox-tabs li a.current,#conversejs #controlbox #controlbox-tabs li a.current:hover{box-shadow:none;border-bottom:0;height:55px;cursor:default;color:#818479}#conversejs #controlbox .fancy-dropdown{border:1px solid #B1BFC4;height:25px;border-radius:4px;text-align:left;padding:0;padding-left:.3em}#conversejs #controlbox .fancy-dropdown .choose-xmpp-status{width:155px}#conversejs #controlbox .fancy-dropdown .choose-xmpp-status,#conversejs #controlbox .fancy-dropdown .toggle-xmpp-contact-form{text-shadow:0 1px 0 #fff;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline}#conversejs #controlbox .fancy-dropdown.no-border{border:0}#conversejs #controlbox #fancy-xmpp-status-select{padding-left:0}#conversejs #controlbox #fancy-xmpp-status-select .xmpp-status{margin-left:.3em;display:inline}#conversejs #controlbox #fancy-xmpp-status-select a.change-xmpp-status-message{float:right;clear:right;width:12px;margin-right:.3em;color:#2A9D8F}#conversejs #controlbox .controlbox-pane{background-color:#fff;border-bottom-left-radius:4px;border-bottom-right-radius:4px;border:0;font-size:14px;position:absolute;text-align:center;width:100%;height:289px;height:-webkit-calc(100% - 55px);height:calc(100% - 55px);overflow-y:auto;overflow-x:hidden}#conversejs #controlbox .controlbox-pane label{font-size:14px;font-weight:700;height:auto;margin:4px}#conversejs #controlbox .controlbox-pane dd{margin-left:0;margin-bottom:0}#conversejs #controlbox .controlbox-pane dd.odd{background-color:#DCEAC5}#conversejs #controlbox #users{overflow-y:hidden}#conversejs #controlbox .add-xmpp-contact{background:0 0;padding:1em}#conversejs #controlbox .add-xmpp-contact input{margin:0 0 1rem;width:100%}#conversejs #controlbox .add-xmpp-contact button{width:100%}#conversejs #controlbox .xmpp-status-menu{text-align:left;box-shadow:1px 4px 10px 1px rgba(0,0,0,.4)}#conversejs #controlbox .xmpp-status-menu li{padding:2px}#conversejs #controlbox .xmpp-status-menu li a{width:100%;padding:0 8px}#conversejs #controlbox .xmpp-status-menu li a.logout,#conversejs #controlbox .xmpp-status-menu li a.logout span{color:#D24E2B}#conversejs #controlbox .set-xmpp-status{background:0 0;margin:1em 1em .5em}#conversejs #controlbox .set-xmpp-status .dropdown dd ul{z-index:22}#conversejs .toggle-controlbox{background-color:#2A9D8F;border-top-left-radius:4px;border-top-right-radius:4px;color:#0a0a0a;float:right;height:100%;margin:0 .5em;padding:10px 8px 0}#conversejs .toggle-controlbox span{color:#fff}#conversejs #converse-roster{text-align:left;width:100%;position:relative;margin:1em 0 0;height:194px;height:calc(100% - 50px - 20px);overflow:hidden;padding:0;padding-bottom:3em}#conversejs #converse-roster.no-contact-requests{height:calc(100% - 25px - 20px)}#conversejs #converse-roster .search-xmpp ul li.chat-info{padding-left:10px}#conversejs #converse-roster .roster-filter-group{margin:0 1em;width:100%;padding-right:2em}#conversejs #converse-roster .roster-filter-group .roster-filter{float:left;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAABNSURBVHjaXI7BDcAwCAMvyQjMyQ6dAbZiKfqoUK34g2zJh1dENIC7M8pMAPYdzAVY3d0ajNz9aypS/b5R6o+ZPdqoKgCq6h80KH3xDgBqNR97p8oAGQAAAABJRU5ErkJggg==) no-repeat right -20px center;border:1px solid #999;font-size:14px;height:25px;margin:0;padding:0;padding-left:.4em;width:53%}#conversejs #converse-roster .roster-filter-group .roster-filter.x{background-position:right 3px center}#conversejs #converse-roster .roster-filter-group .roster-filter.onX{cursor:pointer}#conversejs #converse-roster .roster-filter-group .filter-type{display:table-cell;float:right;font-size:calc(14px - 2px);height:25px;padding:0;width:47%;border-radius:0;border:1px solid}#conversejs #converse-roster .roster-contacts{margin:0;height:100%;overflow-x:hidden;overflow-y:auto}#conversejs #converse-roster .roster-contacts dt.roster-group{border:none;color:#818479;display:none;font-weight:400;margin-top:.5em;padding:.5em 1em;text-shadow:0 1px 0 #FAFAFA}#conversejs #converse-roster .roster-contacts dt.roster-group:hover{background-color:#DCF9F6}#conversejs #converse-roster .roster-contacts dt.roster-group .group-toggle{color:#818479;display:block;width:100%}#conversejs #converse-roster .roster-contacts dd{border:none;clear:both;color:#818479;display:block;height:24px;overflow-y:hidden;padding:.3em 0 .3em 1em;text-shadow:0 1px 0 #FAFAFA;line-height:14px;width:100%}#conversejs #converse-roster .roster-contacts dd .open-chat{max-width:90%}#conversejs #converse-roster .roster-contacts dd:hover{background-color:#DCF9F6}#conversejs #converse-roster .roster-contacts dd:hover .remove-xmpp-contact{display:inline-block}#conversejs #converse-roster .roster-contacts dd:hover .open-chat{width:80%}#conversejs #converse-roster .roster-contacts dd.requesting-xmpp-contact.request-actions{margin-left:.5em;margin-bottom:.3em;float:right}#conversejs #converse-roster .roster-contacts dd.requesting-xmpp-contact .req-contact-name{width:69%;padding:0}#conversejs #converse-roster .roster-contacts dd.current-xmpp-contact span{font-size:16px;float:left;color:#2A9D8F}#conversejs #converse-roster .roster-contacts dd.odd{background-color:#DCEAC5}#conversejs #converse-roster .roster-contacts dd a,#conversejs #converse-roster .roster-contacts dd span{text-shadow:0 1px 0 #FAFAFA;display:inline-block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}#conversejs #converse-roster .roster-contacts dd span{padding:0 .5em 0 0;height:100%}#conversejs #converse-roster .roster-contacts dd a.decline-xmpp-request{margin-left:5px}#conversejs #converse-roster .roster-contacts dd a.remove-xmpp-contact{float:right;margin-right:1em;display:none;color:#818479}#conversejs #converse-roster span.pending-contact-name{width:80%}#conversejs .chat-head-chatroom{background-color:#E76F51}#conversejs .chat-head-chatroom .chatroom-topic{color:#fff;font-size:80%;font-style:italic;height:1.3em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin:0;margin-top:.3em}#conversejs .chatroom{width:300px}@media screen and (max-width:480px){#conversejs .chatroom{width:100%}#conversejs .chatroom .box-flyout{min-width:100%;width:100%}}#conversejs .chatroom .box-flyout{min-width:300px;width:300px}#conversejs .chatroom .box-flyout .chatroom-body{border-bottom-left-radius:4px;border-bottom-right-radius:4px;height:-webkit-calc(100% - 55px);height:calc(100% - 55px);background-color:#fff;border-top:0;width:100%}#conversejs .chatroom .box-flyout .chatroom-body .chat-area{word-wrap:break-word;height:100%;max-width:70%;float:left;min-width:200px}#conversejs .chatroom .box-flyout .chatroom-body .chat-area .chat-content{padding:0 .5em}#conversejs .chatroom .box-flyout .chatroom-body .chat-area.full{max-width:100%}#conversejs .chatroom .box-flyout .chatroom-body .mentioned{font-weight:700}#conversejs .chatroom .box-flyout .chatroom-body .chat-msg-room{color:#1A9707}#conversejs .chatroom .box-flyout .chatroom-body .occupants{vertical-align:top;background-color:#fff;overflow:hidden;border-left:1px solid #818479;border-bottom-right-radius:4px;min-width:30%;height:100%}#conversejs .chatroom .box-flyout .chatroom-body .occupants.hidden{display:none}#conversejs .chatroom .box-flyout .chatroom-body .occupants .occupants-heading{padding:.3em;font-weight:700}#conversejs .chatroom .box-flyout .chatroom-body .occupants .occupant-list{height:85%;height:calc(100% - 70px);overflow-x:hidden;overflow-y:auto;list-style:none}#conversejs .chatroom .box-flyout .chatroom-body .occupants .occupant-list li{cursor:default;display:block;font-size:12px;overflow:hidden;padding:2px 5px;text-overflow:ellipsis;white-space:nowrap;width:100px}#conversejs .chatroom .box-flyout .chatroom-body .occupants .occupant-list li.moderator{color:#D24E2B}#conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container{background-color:#fff;border-bottom-left-radius:4px;border-bottom-right-radius:4px;border:0;color:#818479;font-size:14px;height:289px;height:-webkit-calc(100% - 55px);height:calc(100% - 55px);overflow-y:auto;position:absolute}#conversejs .chatroom .chat-textarea{border-bottom-right-radius:0}#conversejs .chatroom .room-invite{margin:.3em}#conversejs .chatroom .room-invite .invited-contact{margin:-1px 0 0 -1px;width:100%;border:1px solid #999}#conversejs .chatroom .room-invite .invited-contact.tt-input{width:100%;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gkBCjE0uzKkOgAAAidJREFUKM+N0k+IEnEUB/D3cyscdagkWpHV0WGWREXm0AgOGkSJ07kh2UXYU5cOewm6Bp0KXG/tpSCv6hyEFQIhMEaE3yERYfwTOoqKGLQxDAbqYadLgu7J7/XxeY/3ez8EACDLsgljfMfj8ZxUKhXXYDAAnueBoqgyAMipVOovXAuSZdnUaDQeDofDs16vFyUIAjRNUwmCoG02G1AUdZ5IJN7GYrHfm3AvEAjcnUwmX0ajUdRqtV74fL6sruufKYoa6bp+fzabPUMI7ZfL5eImNHk8npNerxc1m80XHMe98fv9H3K5XDkSibxjWfb1arWaYoyPMMbCFqxUKi6CIODw8LDmdDq7oigaAACiKK5omv7KcdylpmlIkiTHFlRVFTRNUxVFqa/ROqIoGoqi5A3DgFartfU4Jp7ngSAI2uVyPZIk6dZmUZKk2w6H4xghBPF4HK7vWLbZbDCdTp+rqvpUkiS0RvV6/bTf7x8wDHMViURqm/AGAMgURZ232+1X1Wr102KxuEwmk3lZlo/7/f7BcrkkSZKs2e12tHXH/x/gHsY4jTE+0jQNGYYBCCFgGOaKJMkfjUaDZximGQ6HXzSbzZ+ZTMbY6oIxFgqFgqPT6YAgCMBxXM1ut6N0Op0fj8chi8XyjWXZ98Fg8DuCHZLNZh+USqWP8/n8idvt/hUKhV7u7QK9Xu8fmqanAJBQVXUfAGY7TQQAKBaLN8fjsdDtdh/run72Dzhf7XLe2UevAAAAAElFTkSuQmCC) no-repeat right 3px center}#conversejs .chatroom .room-invite .invited-contact.tt-input:focus{border-color:#E76F51}#conversejs .chatroom .room-invite .invited-contact.tt-hint{color:transparent;background-color:#fff}#conversejs .chatroom .room-invite .tt-dropdown-menu{width:96%;max-height:250px;background:#E76F51;border-bottom-right-radius:4px;border-bottom-left-radius:4px;overflow-y:auto}#conversejs .chatroom .room-invite .tt-dropdown-menu .tt-suggestion p{color:#fff;cursor:pointer;font-size:11px;text-overflow:ellipsis;overflow-x:hidden}#conversejs .chatroom .room-invite .tt-dropdown-menu .tt-suggestion p:hover{background-color:#FF977C}#conversejs .chatroom .room-invite .tt-dropdown-menu .tt-suggestion .tt-highlight{background-color:#D24E2B}#conversejs #minimized-chats{border-top-left-radius:4px;border-top-right-radius:4px;color:#fff;display:none;float:right;font-weight:700;height:100%;margin:0 .5em;padding:0;width:130px}#conversejs #minimized-chats #toggle-minimized-chats{border-top-left-radius:4px;border-top-right-radius:4px;background-color:#2A9D8F;color:#fff;position:relative;padding:10px 0 0;display:block;width:100%;height:100%;text-align:center}#conversejs #minimized-chats .minimized-chats-flyout{height:auto;bottom:35px}#conversejs #minimized-chats .minimized-chats-flyout .chat-head{padding:.3em;border-radius:4px;width:130px;height:35px;margin-bottom:.2em;box-shadow:1px 3px 5px 3px rgba(0,0,0,.4)}#conversejs #minimized-chats .minimized-chats-flyout.minimized{height:auto}#conversejs #minimized-chats .chat-head-message-count,#conversejs #minimized-chats .unread-message-count{font-weight:700;background-color:#fff;border:1px solid;text-shadow:1px 1px 0 #FAFAFA;color:#D24E2B;border-radius:5px;padding:2px 4px;font-size:16px;text-align:center;position:absolute;right:116px;bottom:10px}
\ No newline at end of file
*/-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#conversejs html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}#conversejs body{margin:0}#conversejs article,#conversejs aside,#conversejs details,#conversejs figcaption,#conversejs figure,#conversejs footer,#conversejs header,#conversejs hgroup,#conversejs main,#conversejs menu,#conversejs nav,#conversejs section,#conversejs summary{display:block}#conversejs audio,#conversejs canvas,#conversejs progress,#conversejs video{display:inline-block;vertical-align:baseline}#conversejs audio:not([controls]){display:none;height:0}#conversejs [hidden],#conversejs template{display:none}#conversejs a{background-color:transparent}#conversejs a:active,#conversejs a:hover{outline:0}#conversejs abbr[title]{border-bottom:1px dotted}#conversejs b,#conversejs strong{font-weight:700}#conversejs dfn{font-style:italic}#conversejs mark{background:#ff0;color:#000}#conversejs small{font-size:80%}#conversejs sub,#conversejs sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}#conversejs sup{top:-.5em}#conversejs sub{bottom:-.25em}#conversejs svg:not(:root){overflow:hidden}#conversejs hr{box-sizing:content-box;height:0}#conversejs pre{overflow:auto}#conversejs code,#conversejs kbd,#conversejs pre,#conversejs samp{font-family:monospace,monospace;font-size:1em}#conversejs button,#conversejs input,#conversejs optgroup,#conversejs select,#conversejs textarea{color:inherit;font:inherit;margin:0}#conversejs button{overflow:visible}#conversejs button,#conversejs select{text-transform:none}#conversejs button,#conversejs html input[type=button],#conversejs input[type=reset],#conversejs input[type=submit]{-webkit-appearance:button;cursor:pointer}#conversejs button[disabled],#conversejs html input[disabled]{cursor:default}#conversejs button::-moz-focus-inner,#conversejs input::-moz-focus-inner{border:0;padding:0}#conversejs input{line-height:normal}#conversejs input[type=checkbox],#conversejs input[type=radio]{box-sizing:border-box;padding:0}#conversejs input[type=number]::-webkit-inner-spin-button,#conversejs input[type=number]::-webkit-outer-spin-button{height:auto}#conversejs input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}#conversejs input[type=search]::-webkit-search-cancel-button,#conversejs input[type=search]::-webkit-search-decoration{-webkit-appearance:none}#conversejs textarea{overflow:auto}#conversejs optgroup{font-weight:700}#conversejs table{border-collapse:collapse;border-spacing:0}#conversejs .hidden,#conversejs [hidden]{display:none!important}#conversejs .pure-img{max-width:100%;height:auto;display:block}#conversejs .pure-form input[type=color],#conversejs .pure-form input[type=date],#conversejs .pure-form input[type=datetime-local],#conversejs .pure-form input[type=datetime],#conversejs .pure-form input[type=email],#conversejs .pure-form input[type=month],#conversejs .pure-form input[type=number],#conversejs .pure-form input[type=password],#conversejs .pure-form input[type=search],#conversejs .pure-form input[type=tel],#conversejs .pure-form input[type=text],#conversejs .pure-form input[type=time],#conversejs .pure-form input[type=url],#conversejs .pure-form input[type=week],#conversejs .pure-form select,#conversejs .pure-form textarea{padding:.5em .6em;display:inline-block;border:1px solid #ccc;box-shadow:inset 0 1px 3px #ddd;border-radius:4px;vertical-align:middle;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#conversejs .pure-form input:not([type]){padding:.5em .6em;display:inline-block;border:1px solid #ccc;box-shadow:inset 0 1px 3px #ddd;border-radius:4px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#conversejs .pure-form input[type=color]{padding:.2em .5em}#conversejs .pure-form input:not([type]):focus,#conversejs .pure-form input[type=color]:focus,#conversejs .pure-form input[type=date]:focus,#conversejs .pure-form input[type=datetime-local]:focus,#conversejs .pure-form input[type=datetime]:focus,#conversejs .pure-form input[type=email]:focus,#conversejs .pure-form input[type=month]:focus,#conversejs .pure-form input[type=number]:focus,#conversejs .pure-form input[type=password]:focus,#conversejs .pure-form input[type=search]:focus,#conversejs .pure-form input[type=tel]:focus,#conversejs .pure-form input[type=text]:focus,#conversejs .pure-form input[type=time]:focus,#conversejs .pure-form input[type=url]:focus,#conversejs .pure-form input[type=week]:focus,#conversejs .pure-form select:focus,#conversejs .pure-form textarea:focus{outline:0;border-color:#1A9707}#conversejs .pure-form input[type=checkbox]:focus,#conversejs .pure-form input[type=file]:focus,#conversejs .pure-form input[type=radio]:focus{outline:thin solid #1A9707;outline:1px auto #1A9707}#conversejs .pure-form .pure-checkbox,#conversejs .pure-form .pure-radio{margin:.5em 0;display:block}#conversejs .pure-form input:not([type])[disabled],#conversejs .pure-form input[type=color][disabled],#conversejs .pure-form input[type=date][disabled],#conversejs .pure-form input[type=datetime-local][disabled],#conversejs .pure-form input[type=datetime][disabled],#conversejs .pure-form input[type=email][disabled],#conversejs .pure-form input[type=month][disabled],#conversejs .pure-form input[type=number][disabled],#conversejs .pure-form input[type=password][disabled],#conversejs .pure-form input[type=search][disabled],#conversejs .pure-form input[type=tel][disabled],#conversejs .pure-form input[type=text][disabled],#conversejs .pure-form input[type=time][disabled],#conversejs .pure-form input[type=url][disabled],#conversejs .pure-form input[type=week][disabled],#conversejs .pure-form select[disabled],#conversejs .pure-form textarea[disabled]{cursor:not-allowed;background-color:#eaeded;color:#cad2d3}#conversejs .pure-form input[readonly],#conversejs .pure-form select[readonly],#conversejs .pure-form textarea[readonly]{background-color:#eee;color:#777;border-color:#ccc}#conversejs .pure-form input:focus:invalid,#conversejs .pure-form select:focus:invalid,#conversejs .pure-form textarea:focus:invalid{color:#b94a48;border-color:#e9322d}#conversejs .pure-form input[type=checkbox]:focus:invalid:focus,#conversejs .pure-form input[type=file]:focus:invalid:focus,#conversejs .pure-form input[type=radio]:focus:invalid:focus{outline-color:#e9322d}#conversejs .pure-form select{height:2.25em;border:1px solid #ccc;background-color:#fff}#conversejs .pure-form select[multiple]{height:auto}#conversejs .pure-form label{margin:.5em 0 .2em}#conversejs .pure-form fieldset{margin:0;padding:.35em 0 .75em;border:0}#conversejs .pure-form legend{display:block;width:100%;padding:.3em 0;margin-bottom:.3em;color:#333;border-bottom:1px solid #e5e5e5}#conversejs .pure-form-stacked input:not([type]),#conversejs .pure-form-stacked input[type=color],#conversejs .pure-form-stacked input[type=date],#conversejs .pure-form-stacked input[type=datetime-local],#conversejs .pure-form-stacked input[type=datetime],#conversejs .pure-form-stacked input[type=email],#conversejs .pure-form-stacked input[type=file],#conversejs .pure-form-stacked input[type=month],#conversejs .pure-form-stacked input[type=number],#conversejs .pure-form-stacked input[type=password],#conversejs .pure-form-stacked input[type=search],#conversejs .pure-form-stacked input[type=tel],#conversejs .pure-form-stacked input[type=text],#conversejs .pure-form-stacked input[type=time],#conversejs .pure-form-stacked input[type=url],#conversejs .pure-form-stacked input[type=week],#conversejs .pure-form-stacked label,#conversejs .pure-form-stacked select,#conversejs .pure-form-stacked textarea{display:block;margin:.25em 0}#conversejs .pure-form-aligned .pure-help-inline,#conversejs .pure-form-aligned input,#conversejs .pure-form-aligned select,#conversejs .pure-form-aligned textarea,#conversejs .pure-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}#conversejs .pure-form-aligned textarea{vertical-align:top}#conversejs .pure-form-aligned .pure-control-group{margin-bottom:.5em}#conversejs .pure-form-aligned .pure-control-group label{text-align:right;display:inline-block;vertical-align:middle;width:10em;margin:0 1em 0 0}#conversejs .pure-form-aligned .pure-controls{margin:1.5em 0 0 11em}#conversejs .pure-form .pure-input-rounded,#conversejs .pure-form input.pure-input-rounded{border-radius:2em;padding:.5em 1em}#conversejs .pure-form .pure-group fieldset{margin-bottom:10px}#conversejs .pure-form .pure-group input,#conversejs .pure-form .pure-group textarea{display:block;padding:10px;margin:0 0 -1px;border-radius:0;position:relative;top:-1px}#conversejs .pure-form .pure-group input:focus,#conversejs .pure-form .pure-group textarea:focus{z-index:3}#conversejs .pure-form .pure-group input:first-child,#conversejs .pure-form .pure-group textarea:first-child{top:1px;border-radius:4px 4px 0 0;margin:0}#conversejs .pure-form .pure-group input:first-child:last-child,#conversejs .pure-form .pure-group textarea:first-child:last-child{top:1px;border-radius:4px;margin:0}#conversejs .pure-form .pure-group input:last-child,#conversejs .pure-form .pure-group textarea:last-child{top:-2px;border-radius:0 0 4px 4px;margin:0}#conversejs .pure-form .pure-group button{margin:.35em 0}#conversejs .pure-form .pure-input-1{width:100%}#conversejs .pure-form .pure-input-3-4{width:75%}#conversejs .pure-form .pure-input-2-3{width:66%}#conversejs .pure-form .pure-input-1-2{width:50%}#conversejs .pure-form .pure-input-1-3{width:33%}#conversejs .pure-form .pure-input-1-4{width:25%}#conversejs .pure-form .pure-help-inline,#conversejs .pure-form-message-inline{display:inline-block;padding-left:.3em;color:#666;vertical-align:middle;font-size:.875em}#conversejs .pure-form-message{display:block;color:#666;font-size:.875em}@media only screen and (max-width:480px){#conversejs .pure-form button[type=submit]{margin:.7em 0 0}#conversejs .pure-form input:not([type]),#conversejs .pure-form input[type=color],#conversejs .pure-form input[type=date],#conversejs .pure-form input[type=datetime-local],#conversejs .pure-form input[type=datetime],#conversejs .pure-form input[type=email],#conversejs .pure-form input[type=month],#conversejs .pure-form input[type=number],#conversejs .pure-form input[type=password],#conversejs .pure-form input[type=search],#conversejs .pure-form input[type=tel],#conversejs .pure-form input[type=text],#conversejs .pure-form input[type=time],#conversejs .pure-form input[type=url],#conversejs .pure-form input[type=week],#conversejs .pure-form label{margin-bottom:.3em;display:block}#conversejs .pure-group input:not([type]),#conversejs .pure-group input[type=color],#conversejs .pure-group input[type=date],#conversejs .pure-group input[type=datetime-local],#conversejs .pure-group input[type=datetime],#conversejs .pure-group input[type=email],#conversejs .pure-group input[type=month],#conversejs .pure-group input[type=number],#conversejs .pure-group input[type=password],#conversejs .pure-group input[type=search],#conversejs .pure-group input[type=tel],#conversejs .pure-group input[type=text],#conversejs .pure-group input[type=time],#conversejs .pure-group input[type=url],#conversejs .pure-group input[type=week]{margin-bottom:0}#conversejs .pure-form-aligned .pure-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}#conversejs .pure-form-aligned .pure-controls{margin:1.5em 0 0}#conversejs .pure-form .pure-help-inline,#conversejs .pure-form-message,#conversejs .pure-form-message-inline{display:block;font-size:.75em;padding:.2em 0 .8em}}#conversejs .pure-button{display:inline-block;zoom:1;line-height:normal;white-space:nowrap;vertical-align:middle;text-align:center;cursor:pointer;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;font-family:inherit;font-size:100%;padding:.5em 1em;color:#444;color:rgba(0,0,0,.8);border:1px solid #999;border:none transparent;background-color:#E6E6E6;text-decoration:none}#conversejs .pure-button-hover,#conversejs .pure-button:focus,#conversejs .pure-button:hover{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#1a000000', GradientType=0);background-image:-webkit-gradient(linear,0 0,0 100%,from(transparent),color-stop(40%,rgba(0,0,0,.05)),to(rgba(0,0,0,.1)));background-image:-webkit-linear-gradient(transparent,rgba(0,0,0,.05)40%,rgba(0,0,0,.1));background-image:-moz-linear-gradient(top,rgba(0,0,0,.05)0,rgba(0,0,0,.1));background-image:-o-linear-gradient(transparent,rgba(0,0,0,.05)40%,rgba(0,0,0,.1));background-image:linear-gradient(transparent,rgba(0,0,0,.05)40%,rgba(0,0,0,.1))}#conversejs .pure-button:focus{outline:0}#conversejs .pure-button-active,#conversejs .pure-button:active{box-shadow:0 0 0 1px rgba(0,0,0,.15)inset,0 0 6px rgba(0,0,0,.2)inset}#conversejs .pure-button-disabled,#conversejs .pure-button-disabled:active,#conversejs .pure-button-disabled:focus,#conversejs .pure-button-disabled:hover,#conversejs .pure-button[disabled]{border:none;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);filter:alpha(opacity=40);-khtml-opacity:.4;-moz-opacity:.4;opacity:.4;cursor:not-allowed;box-shadow:none}#conversejs .pure-button-hidden{display:none}#conversejs .pure-button::-moz-focus-inner{padding:0;border:0}#conversejs .pure-button-primary,#conversejs .pure-button-selected,#conversejs a.pure-button-primary,#conversejs a.pure-button-selected{background-color:#0078e7;color:#fff}#conversejs *,#conversejs :after,#conversejs :before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}@media screen and (max-width:480px){#conversejs{margin:0;right:10px;left:10px;bottom:5px}}#conversejs ul li{height:auto}#conversejs a,#conversejs article,#conversejs aside,#conversejs audio,#conversejs blockquote,#conversejs canvas,#conversejs caption,#conversejs dd,#conversejs details,#conversejs div,#conversejs dl,#conversejs dt,#conversejs em,#conversejs embed,#conversejs fieldset,#conversejs figcaption,#conversejs figure,#conversejs footer,#conversejs form,#conversejs h1,#conversejs h2,#conversejs h3,#conversejs h4,#conversejs h5,#conversejs h6,#conversejs header,#conversejs hgroup,#conversejs img,#conversejs label,#conversejs legend,#conversejs li,#conversejs mark,#conversejs menu,#conversejs nav,#conversejs ol,#conversejs output,#conversejs p,#conversejs pre,#conversejs ruby,#conversejs section,#conversejs span,#conversejs strong,#conversejs summary,#conversejs table,#conversejs tbody,#conversejs td,#conversejs tfoot,#conversejs th,#conversejs thead,#conversejs time,#conversejs tr,#conversejs ul,#conversejs video{margin:0;padding:0;border:0;font:inherit;vertical-align:baseline}#conversejs button,#conversejs input[type=button],#conversejs input[type=password],#conversejs input[type=submit],#conversejs input[type=text],#conversejs textarea{font-size:14px;padding:.25em;min-height:0}#conversejs strong{font-weight:700}#conversejs ol,#conversejs ul{list-style:none}#conversejs li{height:10px}#conversejs dl,#conversejs ol,#conversejs ul{font:inherit;margin:0}#conversejs a,#conversejs a:visited{text-decoration:none;color:#2A9D8F;text-shadow:none}#conversejs{bottom:0;color:#818479;direction:ltr;display:block;font-size:14px;height:35px;position:fixed;left:0;right:0;width:auto;z-index:30}@media screen and (max-width:480px){#conversejs{width:100%;width:100vw}}#conversejs ::selection{background-color:#DCF9F6}#conversejs ::-moz-selection{background-color:#DCF9F6}#conversejs .no-text-select{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}#conversejs .emoticon{font-size:14px}#conversejs .left{float:left}#conversejs .right{float:right}#conversejs .centered{text-align:center;display:block;margin:5em auto}#conversejs .hor_centered{text-align:center;display:block;margin:0 auto;clear:both}#conversejs .locked{padding-right:22px}@-webkit-keyframes spin{from{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(359deg)}}@-moz-keyframes spin{from{-moz-transform:rotate(0deg)}to{-moz-transform:rotate(359deg)}}@keyframes spin{from{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);-o-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);-moz-transform:rotate(359deg);-ms-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}#conversejs .spinner{-webkit-animation:spin 2s infinite,linear;-moz-animation:spin 2s infinite,linear;animation:spin 2s infinite,linear;display:block;text-align:center;margin:5px}#conversejs .spinner:before{font-size:24px;font-family:Converse-js!important;content:"\231b"}#conversejs .button-group,#conversejs .input-button-group{display:table}#conversejs .button-group{width:100%}#conversejs .input-button-group button,#conversejs .input-button-group input{display:table-cell}#conversejs .error{color:red}#conversejs .reg-feedback{font-size:85%}#conversejs #converse-login .conn-feedback,#conversejs .reg-feedback{display:block;text-align:center;width:100%}#conversejs a.restore-chat{padding:1px 0 1px 5px;color:#fff;line-height:15px;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#conversejs a.restore-chat:visited{color:#fff}#conversejs .activated{display:block!important}#conversejs .pure-button{border-radius:4px}#conversejs .button-primary{color:#fff;background-color:#2AC611}#conversejs .button-secondary{color:#fff;background-color:#83A0D6}#conversejs .button-cancel{color:#fff;background-color:#D24E2B}#conversejs form.pure-form.converse-form{background:#fff;margin:1em}#conversejs form.pure-form.converse-form legend{color:#818479}#conversejs form.pure-form.converse-form label{margin-top:1em}#conversejs form.pure-form.converse-form input[type=button],#conversejs form.pure-form.converse-form input[type=number],#conversejs form.pure-form.converse-form input[type=password],#conversejs form.pure-form.converse-form input[type=submit],#conversejs form.pure-form.converse-form input[type=text]{height:2.2em}#conversejs form.pure-form.converse-form input[type=button],#conversejs form.pure-form.converse-form input[type=submit]{padding-left:1em;padding-right:1em;margin-right:1em}#conversejs form.pure-form.converse-form input.error{border:1px solid red;color:#818479}#conversejs form.pure-form.converse-form .form-help{color:gray;font-size:85%;padding-top:.5em}#conversejs form.pure-form.converse-form .form-help:hover{color:#818479}#conversejs .chat-textarea-chatbox-selected{border:1px solid #578308;margin:0}#conversejs .chat-textarea-chatroom-selected{border:2px solid #2A9D8F;margin:0}#conversejs .dropdown dt,#conversejs .dropdown ul{margin:0;padding:0}#conversejs .flyout{border-radius:4px;bottom:6px;display:block;position:absolute}#conversejs .chat-head{border-top-left-radius:4px;border-top-right-radius:4px;color:#fff;font-size:100%;height:55px;margin:0;padding:5px;position:relative}#conversejs .chat-head .avatar{margin-right:.5em;border-radius:50%;float:left}#conversejs .chat-head.chat-head-chatbox{background-color:#F4A261}#conversejs .chat-head .user-custom-message{clear:left;color:#fff;font-size:80%;font-style:italic;height:1.3em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin:0;padding-top:.2em}#conversejs .chatbox-btn{border-radius:50%;border:1px solid #fff;color:#fff;cursor:pointer;display:inline-block;float:right;font-size:9px;margin:0;margin-right:.2em;padding:.5em .5em .3em;text-decoration:none}#conversejs .chatbox-btn:active{position:relative;top:1px}#conversejs .chatbox{display:block;float:right;height:35px;margin:0 .5em;width:200px}@media screen and (max-width:480px){#conversejs .chatbox{margin:0;width:100%}}#conversejs .chatbox .box-flyout{background-color:#fff;box-shadow:1px 3px 5px 3px rgba(0,0,0,.4);height:450px;min-height:225px;min-width:200px;width:200px;z-index:1}@media screen and (max-width:480px){#conversejs .chatbox .box-flyout{width:100%;height:99vh}}#conversejs .chatbox .chat-title{color:#fff;line-height:15px;display:block;text-overflow:ellipsis;overflow:hidden;height:2em}#conversejs .chatbox .chat-title a{color:#fff;width:100%}#conversejs .chatbox .chat-body{background-color:#fff;border-bottom-left-radius:4px;border-bottom-right-radius:4px;border-top:0;height:289px;height:-webkit-calc(100% - 55px);height:calc(100% - 55px)}#conversejs .chatbox .chat-body p{color:#818479;font-size:14px;margin:0;padding:5px}#conversejs .chatbox .chat-body .chat-info{color:#D24E2B;margin:.3em}#conversejs .chatbox .chat-body .chat-info.chat-event{clear:left;font-style:italic}#conversejs .chatbox .chat-body .chat-info.chat-error{color:#D24E2B;font-weight:700}#conversejs .chatbox .chat-body .chat-info.chat-date{display:inline-block;margin-top:2em}#conversejs .chatbox .chat-body .chat-message{margin:.3em}#conversejs .chatbox .chat-body .chat-message span{display:inline-block}#conversejs .chatbox .chat-body .chat-message span.chat-msg-author{max-width:100%;font-weight:700;white-space:nowrap;float:left;text-overflow:ellipsis;overflow:hidden}#conversejs .chatbox .chat-body .chat-message span.chat-msg-them{color:#1A9707}#conversejs .chatbox .chat-body .chat-message span.chat-msg-me{color:#2A9D8F}#conversejs .chatbox .chat-body .chat-message span.chat-msg-content{max-width:100%;word-wrap:break-word}#conversejs .chatbox .chat-body .delayed .chat-msg-them{color:#FB5D50}#conversejs .chatbox .chat-body .delayed .chat-msg-me{color:#7EABBB}#conversejs .chatbox .chat-content{position:relative;padding:.5em;font-size:13px;color:#818479;overflow-y:auto;border:0;background-color:#fff;line-height:1.3em;height:206px;height:calc(100% - 96px)}#conversejs .chatbox .dropdown{background-color:#FCFDFD}#conversejs .chatbox .dropdown dd{margin:0;padding:0;position:relative}#conversejs .chatbox form.sendXMPPMessage{-moz-background-clip:padding;-webkit-background-clip:padding-box;border-bottom-left-radius:4px;border-bottom-right-radius:4px;background:#fff;border:0;margin:0;padding:0;position:relative;height:95px;min-width:200px}@media screen and (max-width:480px){#conversejs .chatbox form.sendXMPPMessage{width:100%}}#conversejs .chatbox form.sendXMPPMessage .chat-textarea{border-bottom-left-radius:4px;border-bottom-right-radius:4px;border:0;height:70px;padding:.5em;width:100%;resize:none}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar{font-size:14px;margin:0;padding:5px;height:25px;display:block;background-color:#FFF5EE}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar a{color:#2A9D8F}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .chat-toolbar-text{font-size:12px;padding-right:3px;text-shadow:0 1px 0 #fff}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .unencrypted,#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .unencrypted a{color:#D24E2B}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .unverified,#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .unverified a{color:#cf5300}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .private,#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .private a{color:#4b7003}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-clear,#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-occupants,#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-otr{float:right}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li{display:inline-block;list-style:none;padding:0 3px;cursor:pointer;margin-top:1px}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar li:hover{cursor:pointer}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar ul{background:#fff;bottom:100%;box-shadow:-1px -1px 2px 0 rgba(0,0,0,.4);display:none;font-size:12px;margin:0 0 1px;position:absolute;right:0}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar ul li{cursor:pointer;list-style:none;position:relative}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar ul li a:hover{color:#8f2831}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley{color:#2A9D8F;padding-left:5px}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul li{font-size:14px;padding:5px;z-index:98}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-smiley ul li:hover{background-color:#DCF9F6}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-otr ul li{padding:7px;background-color:#fff;display:block;z-index:99}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-otr ul li a{-moz-transition:background-color .2s ease-in-out;-webkit-transition:background-color .2s ease-in-out;transition:background-color .2s ease-in-out;display:block;padding:1px;text-decoration:none}#conversejs .chatbox form.sendXMPPMessage .chat-toolbar .toggle-otr ul li:hover{background-color:#DCF9F6}#conversejs .chatbox .dragresize{background:0 0;border:0;margin:0;position:absolute;top:0;z-index:20}#conversejs .chatbox .dragresize-top{cursor:n-resize;height:5px;width:100%}#conversejs .chatbox .dragresize-left{cursor:w-resize;width:5px;height:100%;left:0}#conversejs .chatbox .dragresize-topleft{cursor:nw-resize;width:15px;height:15px;top:0;left:0}#conversejs #controlbox{display:none;margin-right:1em}@media screen and (max-width:480px){#conversejs #controlbox{margin:0}}#conversejs #controlbox .controlbox-head{background-color:#577BDD;border-top-left-radius:4px;border-top-right-radius:4px;color:#fff;height:55px;margin:0;padding:6px 6px 6px 0}#conversejs #controlbox form.search-xmpp-contact{margin:0;padding:0 0 5px 5px}#conversejs #controlbox form.search-xmpp-contact input{width:8em}#conversejs #controlbox a.subscribe-to-user{padding-left:2em;font-weight:700}#conversejs #controlbox #converse-register{background:#fff}#conversejs #controlbox #converse-register .title{font-weight:700}#conversejs #controlbox #converse-register .info{font-style:italic;color:green;font-size:85%;margin:5px 0}#conversejs #controlbox #converse-register .form-errors{color:red;display:none}#conversejs #controlbox #converse-register .provider-title{font-size:22px}#conversejs #controlbox #converse-register .provider-score{width:178px;margin-bottom:8px}#conversejs #controlbox #converse-register .form-help .url{font-weight:700;color:#2A9D8F}#conversejs #controlbox #converse-register .input-group{display:table;margin:auto;width:100%}#conversejs #controlbox #converse-register .input-group span{overflow-x:hidden;text-overflow:ellipsis;max-width:110px}#conversejs #controlbox #converse-register .input-group input[name=username],#conversejs #controlbox #converse-register .input-group span{display:table-cell;text-align:left}#conversejs #controlbox #converse-register .instructions{color:gray;font-size:85%}#conversejs #controlbox #converse-register .instructions:hover{color:#818479}#conversejs #controlbox #converse-login,#conversejs #controlbox #converse-register{margin-top:2em}#conversejs #controlbox #converse-login .login-anon,#conversejs #controlbox #converse-register .login-anon{height:auto;white-space:normal}#conversejs #controlbox #converse-login .save-submit,#conversejs #controlbox #converse-register .save-submit{color:#436F64}#conversejs #controlbox #converse-login input,#conversejs #controlbox #converse-register input{width:100%;margin:.5em 0}#conversejs #controlbox #users .add-converse-contact{margin:0 1em .75em}#conversejs #controlbox #chatrooms form.add-chatroom input[type=button],#conversejs #controlbox #chatrooms form.add-chatroom input[type=submit],#conversejs #controlbox #chatrooms form.add-chatroom input[type=text]{width:100%}#conversejs #controlbox #chatrooms #available-chatrooms{padding:0 1em 2em;text-align:left}#conversejs #controlbox #chatrooms #available-chatrooms dt{border:none;color:#818479;font-weight:400;padding:0;padding-bottom:.5em;text-shadow:0 1px 0 #FAFAFA}#conversejs #controlbox #chatrooms #available-chatrooms dd.available-chatroom{border:none;clear:both;color:#818479;display:block;overflow:hidden;padding:.4em;text-shadow:0 1px 0 #FAFAFA;word-wrap:break-word}#conversejs #controlbox #chatrooms #available-chatrooms dd.available-chatroom:hover{background-color:#DCF9F6}#conversejs #controlbox #chatrooms #available-chatrooms dd.available-chatroom a.room-info{clear:right;display:block}#conversejs #controlbox #chatrooms #available-chatrooms dd.available-chatroom a.room-info:before{font-size:15px}#conversejs #controlbox #chatrooms #available-chatrooms dd.available-chatroom a.open-room{float:left;width:85%}#conversejs #controlbox #chatrooms #available-chatrooms dd.available-chatroom .room-info{font-size:11px;font-style:normal;font-weight:400}#conversejs #controlbox #chatrooms #available-chatrooms dd.available-chatroom li.room-info{display:block;margin-left:5px}#conversejs #controlbox #chatrooms #available-chatrooms dd.available-chatroom p.room-info{margin:0;padding:0;display:block;white-space:normal}#conversejs #controlbox #chatrooms #available-chatrooms dd.available-chatroom div.room-info{clear:left;width:100%}#conversejs #controlbox .dropdown a{width:148px;display:inline-block;line-height:25px}#conversejs #controlbox .dropdown li{list-style:none;padding-left:0}#conversejs #controlbox .dropdown dd ul{padding:0;list-style:none;position:absolute;left:0;top:0;border:1px solid #B1BFC4;width:100%;z-index:21;background-color:#FCFDFD}#conversejs #controlbox .dropdown dd ul li:hover{background-color:#DCF9F6}#conversejs #controlbox .dropdown dd.search-xmpp ul{box-shadow:1px 4px 10px 1px rgba(0,0,0,.4)}#conversejs #controlbox .dropdown dd.search-xmpp ul li:hover{background-color:#FCFDFD}#conversejs #controlbox .dropdown dt a span{cursor:pointer;display:block;padding:4px 7px 0 5px}#conversejs #controlbox #select-xmpp-status{float:right;margin-right:.5em}#conversejs #controlbox #set-custom-xmpp-status{float:left;padding:0}#conversejs #controlbox #set-custom-xmpp-status fieldset{padding:0;margin-top:-1px}#conversejs #controlbox #set-custom-xmpp-status input{height:26px;width:-webkit-calc(100% - 40px);width:calc(100% - 40px);padding:0 0 0 .5em}#conversejs #controlbox #set-custom-xmpp-status input[type=submit]{height:26px;width:40px;padding:1px;float:right}#conversejs #controlbox #controlbox-tabs{text-align:center;display:inline;overflow:hidden;font-size:12px;list-style-type:none}#conversejs #controlbox #controlbox-tabs li{float:left;list-style:none;padding-left:0;text-shadow:#fff 0 1px 0;width:38%}#conversejs #controlbox #controlbox-tabs li a{background-color:#fff;border-bottom:1px solid #CCC;border-top-left-radius:4px;border-top-right-radius:4px;box-shadow:inset 2px -2px 20px rgba(0,0,0,.3);color:#818479;display:block;font-size:12px;height:54px;line-height:54px;margin:0;text-align:center;text-decoration:none}#conversejs #controlbox #controlbox-tabs li a:hover{color:#818479}#conversejs #controlbox #controlbox-tabs li a.current,#conversejs #controlbox #controlbox-tabs li a.current:hover{box-shadow:none;border-bottom:0;height:55px;cursor:default;color:#818479}#conversejs #controlbox .fancy-dropdown{border:1px solid #B1BFC4;height:25px;border-radius:4px;text-align:left;padding:0;padding-left:.3em}#conversejs #controlbox .fancy-dropdown .choose-xmpp-status{width:155px}#conversejs #controlbox .fancy-dropdown .choose-xmpp-status,#conversejs #controlbox .fancy-dropdown .toggle-xmpp-contact-form{text-shadow:0 1px 0 #fff;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline}#conversejs #controlbox .fancy-dropdown.no-border{border:0}#conversejs #controlbox #fancy-xmpp-status-select{padding-left:0}#conversejs #controlbox #fancy-xmpp-status-select .xmpp-status{margin-left:.3em;display:inline}#conversejs #controlbox #fancy-xmpp-status-select a.change-xmpp-status-message{float:right;clear:right;width:12px;margin-right:.3em;color:#2A9D8F}#conversejs #controlbox .controlbox-pane{background-color:#fff;border-bottom-left-radius:4px;border-bottom-right-radius:4px;border:0;font-size:14px;position:absolute;text-align:center;width:100%;height:289px;height:-webkit-calc(100% - 55px);height:calc(100% - 55px);overflow-y:auto;overflow-x:hidden}#conversejs #controlbox .controlbox-pane label{font-size:14px;font-weight:700;height:auto;margin:4px}#conversejs #controlbox .controlbox-pane dd{margin-left:0;margin-bottom:0}#conversejs #controlbox .controlbox-pane dd.odd{background-color:#DCEAC5}#conversejs #controlbox #users{overflow-y:hidden}#conversejs #controlbox .add-xmpp-contact{background:0 0;padding:1em}#conversejs #controlbox .add-xmpp-contact input{margin:0 0 1rem;width:100%}#conversejs #controlbox .add-xmpp-contact button{width:100%}#conversejs #controlbox .xmpp-status-menu{text-align:left;box-shadow:1px 4px 10px 1px rgba(0,0,0,.4)}#conversejs #controlbox .xmpp-status-menu li{padding:2px}#conversejs #controlbox .xmpp-status-menu li a{width:100%;padding:0 8px}#conversejs #controlbox .xmpp-status-menu li a.logout,#conversejs #controlbox .xmpp-status-menu li a.logout span{color:#D24E2B}#conversejs #controlbox .set-xmpp-status{background:0 0;margin:1em 1em .5em}#conversejs #controlbox .set-xmpp-status .dropdown dd ul{z-index:22}#conversejs .toggle-controlbox{background-color:#2A9D8F;border-top-left-radius:4px;border-top-right-radius:4px;color:#0a0a0a;float:right;height:100%;margin:0 .5em;padding:10px 8px 0}#conversejs .toggle-controlbox span{color:#fff}#conversejs #converse-roster{text-align:left;width:100%;position:relative;margin:1em 0 0;height:194px;height:calc(100% - 50px - 20px);overflow:hidden;padding:0;padding-bottom:3em}#conversejs #converse-roster.no-contact-requests{height:calc(100% - 25px - 20px)}#conversejs #converse-roster .search-xmpp ul li.chat-info{padding-left:10px}#conversejs #converse-roster .roster-filter-group{margin:0 1em;width:100%;padding-right:2em}#conversejs #converse-roster .roster-filter-group .roster-filter{float:left;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAABNSURBVHjaXI7BDcAwCAMvyQjMyQ6dAbZiKfqoUK34g2zJh1dENIC7M8pMAPYdzAVY3d0ajNz9aypS/b5R6o+ZPdqoKgCq6h80KH3xDgBqNR97p8oAGQAAAABJRU5ErkJggg==) no-repeat right -20px center;border:1px solid #999;font-size:14px;height:25px;margin:0;padding:0;padding-left:.4em;width:53%}#conversejs #converse-roster .roster-filter-group .roster-filter.x{background-position:right 3px center}#conversejs #converse-roster .roster-filter-group .roster-filter.onX{cursor:pointer}#conversejs #converse-roster .roster-filter-group .filter-type{display:table-cell;float:right;font-size:calc(14px - 2px);height:25px;padding:0;width:47%;border-radius:0;border:1px solid}#conversejs #converse-roster .roster-contacts{margin:0;height:100%;overflow-x:hidden;overflow-y:auto}#conversejs #converse-roster .roster-contacts dt.roster-group{border:none;color:#818479;display:none;font-weight:400;margin-top:.5em;padding:.5em 1em;text-shadow:0 1px 0 #FAFAFA}#conversejs #converse-roster .roster-contacts dt.roster-group:hover{background-color:#DCF9F6}#conversejs #converse-roster .roster-contacts dt.roster-group .group-toggle{color:#818479;display:block;width:100%}#conversejs #converse-roster .roster-contacts dd{border:none;clear:both;color:#818479;display:block;height:24px;overflow-y:hidden;padding:.3em 0 .3em 1em;text-shadow:0 1px 0 #FAFAFA;line-height:14px;width:100%}#conversejs #converse-roster .roster-contacts dd .open-chat{max-width:90%}#conversejs #converse-roster .roster-contacts dd:hover{background-color:#DCF9F6}#conversejs #converse-roster .roster-contacts dd:hover .remove-xmpp-contact{display:inline-block}#conversejs #converse-roster .roster-contacts dd:hover .open-chat{width:80%}#conversejs #converse-roster .roster-contacts dd.requesting-xmpp-contact.request-actions{margin-left:.5em;margin-bottom:.3em;float:right}#conversejs #converse-roster .roster-contacts dd.requesting-xmpp-contact .req-contact-name{width:69%;padding:0}#conversejs #converse-roster .roster-contacts dd.current-xmpp-contact span{font-size:16px;float:left;color:#2A9D8F}#conversejs #converse-roster .roster-contacts dd.odd{background-color:#DCEAC5}#conversejs #converse-roster .roster-contacts dd a,#conversejs #converse-roster .roster-contacts dd span{text-shadow:0 1px 0 #FAFAFA;display:inline-block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}#conversejs #converse-roster .roster-contacts dd span{padding:0 .5em 0 0;height:100%}#conversejs #converse-roster .roster-contacts dd a.decline-xmpp-request{margin-left:5px}#conversejs #converse-roster .roster-contacts dd a.remove-xmpp-contact{float:right;margin-right:1em;display:none;color:#818479}#conversejs #converse-roster span.pending-contact-name{width:80%}#conversejs .chat-head-chatroom{background-color:#E76F51}#conversejs .chat-head-chatroom .chatroom-topic{color:#fff;font-size:80%;font-style:italic;height:1.3em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin:0;margin-top:.3em}#conversejs .chatroom{width:300px}@media screen and (max-width:480px){#conversejs .chatroom{width:100%}#conversejs .chatroom .box-flyout{min-width:100%;width:100%}}#conversejs .chatroom .box-flyout{min-width:300px;width:300px}#conversejs .chatroom .box-flyout .chatroom-body{border-bottom-left-radius:4px;border-bottom-right-radius:4px;height:-webkit-calc(100% - 55px);height:calc(100% - 55px);background-color:#fff;border-top:0;width:100%}#conversejs .chatroom .box-flyout .chatroom-body .chat-area{word-wrap:break-word;height:100%;max-width:70%;float:left;min-width:200px}#conversejs .chatroom .box-flyout .chatroom-body .chat-area .chat-content{padding:0 .5em}#conversejs .chatroom .box-flyout .chatroom-body .chat-area.full{max-width:100%}#conversejs .chatroom .box-flyout .chatroom-body .mentioned{font-weight:700}#conversejs .chatroom .box-flyout .chatroom-body .chat-msg-room{color:#1A9707}#conversejs .chatroom .box-flyout .chatroom-body .occupants{vertical-align:top;background-color:#fff;overflow:hidden;border-left:1px solid #818479;border-bottom-right-radius:4px;min-width:30%;height:100%}#conversejs .chatroom .box-flyout .chatroom-body .occupants.hidden{display:none}#conversejs .chatroom .box-flyout .chatroom-body .occupants .occupants-heading{padding:.3em;font-weight:700}#conversejs .chatroom .box-flyout .chatroom-body .occupants .occupant-list{height:85%;height:calc(100% - 70px);overflow-x:hidden;overflow-y:auto;list-style:none}#conversejs .chatroom .box-flyout .chatroom-body .occupants .occupant-list li{cursor:default;display:block;font-size:12px;overflow:hidden;padding:2px 5px;text-overflow:ellipsis;white-space:nowrap;width:100px}#conversejs .chatroom .box-flyout .chatroom-body .occupants .occupant-list li.moderator{color:#D24E2B}#conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container{background-color:#fff;border-bottom-left-radius:4px;border-bottom-right-radius:4px;border:0;color:#818479;font-size:14px;height:289px;height:-webkit-calc(100% - 55px);height:calc(100% - 55px);overflow-y:auto;position:absolute}#conversejs .chatroom .chat-textarea{border-bottom-right-radius:0}#conversejs .chatroom .room-invite{margin:.3em}#conversejs .chatroom .room-invite .invited-contact{margin:-1px 0 0 -1px;width:100%;border:1px solid #999}#conversejs .chatroom .room-invite .invited-contact.tt-input{width:100%;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gkBCjE0uzKkOgAAAidJREFUKM+N0k+IEnEUB/D3cyscdagkWpHV0WGWREXm0AgOGkSJ07kh2UXYU5cOewm6Bp0KXG/tpSCv6hyEFQIhMEaE3yERYfwTOoqKGLQxDAbqYadLgu7J7/XxeY/3ez8EACDLsgljfMfj8ZxUKhXXYDAAnueBoqgyAMipVOovXAuSZdnUaDQeDofDs16vFyUIAjRNUwmCoG02G1AUdZ5IJN7GYrHfm3AvEAjcnUwmX0ajUdRqtV74fL6sruufKYoa6bp+fzabPUMI7ZfL5eImNHk8npNerxc1m80XHMe98fv9H3K5XDkSibxjWfb1arWaYoyPMMbCFqxUKi6CIODw8LDmdDq7oigaAACiKK5omv7KcdylpmlIkiTHFlRVFTRNUxVFqa/ROqIoGoqi5A3DgFartfU4Jp7ngSAI2uVyPZIk6dZmUZKk2w6H4xghBPF4HK7vWLbZbDCdTp+rqvpUkiS0RvV6/bTf7x8wDHMViURqm/AGAMgURZ232+1X1Wr102KxuEwmk3lZlo/7/f7BcrkkSZKs2e12tHXH/x/gHsY4jTE+0jQNGYYBCCFgGOaKJMkfjUaDZximGQ6HXzSbzZ+ZTMbY6oIxFgqFgqPT6YAgCMBxXM1ut6N0Op0fj8chi8XyjWXZ98Fg8DuCHZLNZh+USqWP8/n8idvt/hUKhV7u7QK9Xu8fmqanAJBQVXUfAGY7TQQAKBaLN8fjsdDtdh/run72Dzhf7XLe2UevAAAAAElFTkSuQmCC) no-repeat right 3px center}#conversejs .chatroom .room-invite .invited-contact.tt-input:focus{border-color:#E76F51}#conversejs .chatroom .room-invite .invited-contact.tt-hint{color:transparent;background-color:#fff}#conversejs .chatroom .room-invite .tt-dropdown-menu{width:96%;max-height:250px;background:#E76F51;border-bottom-right-radius:4px;border-bottom-left-radius:4px;overflow-y:auto}#conversejs .chatroom .room-invite .tt-dropdown-menu .tt-suggestion p{color:#fff;cursor:pointer;font-size:11px;text-overflow:ellipsis;overflow-x:hidden}#conversejs .chatroom .room-invite .tt-dropdown-menu .tt-suggestion p:hover{background-color:#FF977C}#conversejs .chatroom .room-invite .tt-dropdown-menu .tt-suggestion .tt-highlight{background-color:#D24E2B}#conversejs .chatbox.headlines .chat-head.chat-head-chatbox{background-color:#2A9D8F}#conversejs #minimized-chats{border-top-left-radius:4px;border-top-right-radius:4px;color:#fff;display:none;float:right;font-weight:700;height:100%;margin:0 .5em;padding:0;width:130px}#conversejs #minimized-chats #toggle-minimized-chats{border-top-left-radius:4px;border-top-right-radius:4px;background-color:#2A9D8F;color:#fff;position:relative;padding:10px 0 0;display:block;width:100%;height:100%;text-align:center}#conversejs #minimized-chats .minimized-chats-flyout{height:auto;bottom:35px}#conversejs #minimized-chats .minimized-chats-flyout .chat-head{padding:.3em;border-radius:4px;width:130px;height:35px;margin-bottom:.2em;box-shadow:1px 3px 5px 3px rgba(0,0,0,.4)}#conversejs #minimized-chats .minimized-chats-flyout.minimized{height:auto}#conversejs #minimized-chats .chat-head-message-count,#conversejs #minimized-chats .unread-message-count{font-weight:700;background-color:#fff;border:1px solid;text-shadow:1px 1px 0 #FAFAFA;color:#D24E2B;border-radius:5px;padding:2px 4px;font-size:16px;text-align:center;position:absolute;right:116px;bottom:10px}
\ No newline at end of file
......@@ -2232,6 +2232,21 @@ define("converse-templates", [
return str;
},
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.
(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.
......@@ -3036,6 +3051,7 @@ define("polyfill", function(){});
this.afterReconnected();
deferred.resolve();
}.bind(this));
converse.emit('reconnected');
return deferred.promise();
};
......@@ -3651,7 +3667,9 @@ define("polyfill", function(){});
} else {
from = Strophe.getBareJidFromJid($message.attr('from'));
}
fullname = (_.isEmpty(fullname) ? from: fullname).split(' ')[0];
if (_.isEmpty(fullname)) {
fullname = from;
}
if (delayed) {
stamp = $delay.attr('stamp');
time = stamp;
......@@ -3674,8 +3692,7 @@ define("polyfill", function(){});
});
}
});
this.ChatBoxes = Backbone.Collection.extend({
model: converse.ChatBox,
comparator: 'time_opened',
......@@ -3716,22 +3733,39 @@ define("polyfill", function(){});
},
onMessage: function (message) {
/* Handler method for all incoming single-user chat "message" stanzas.
/* Handler method for all incoming single-user chat "message"
* stanzas.
*/
var $message = $(message),
contact_jid, $forwarded, $delay, from_bare_jid, from_resource, is_me, msgid,
contact_jid, $forwarded, $delay, from_bare_jid,
from_resource, is_me, msgid,
chatbox, resource,
from_jid = $message.attr('from'),
to_jid = $message.attr('to'),
to_resource = Strophe.getResourceFromJid(to_jid);
if (to_resource && to_resource !== converse.resource) {
converse.log('Ignore incoming message intended for a different resource: '+to_jid, 'info');
converse.log(
'onMessage: Ignoring incoming message intended for a different resource: '+to_jid,
'info'
);
return true;
}
if (from_jid === converse.connection.jid) {
// FIXME: Forwarded messages should be sent to specific resources, not broadcasted
converse.log("Ignore incoming message sent from this client's JID: "+from_jid, 'info');
} else if (from_jid === converse.connection.jid) {
// FIXME: Forwarded messages should be sent to specific
// resources, not broadcasted
converse.log(
"onMessage: Ignoring incoming message sent from this client's JID: "+from_jid,
'info'
);
return true;
} else if (utils.isHeadlineMessage(message)) {
// XXX: Ideally we wouldn't have to check for headline
// messages, but Prosody sends headline messages with the
// wrong type ('chat'), so we need to filter them out here.
converse.log(
"onMessage: Ignoring incoming headline message sent with type 'chat' from JID: "+from_jid,
'info'
);
return true;
}
$forwarded = $message.find('forwarded');
......@@ -3802,6 +3836,7 @@ define("polyfill", function(){});
initialize: function () {
this.model.on("add", this.onChatBoxAdded, this);
this.model.on("destroy", this.removeChat, this);
},
_ensureElement: function () {
......@@ -3823,7 +3858,12 @@ define("polyfill", function(){});
onChatBoxAdded: function (item) {
var view = this.get(item.get('id'));
// Views aren't created here, since the core code doesn't have
// contain any views. Instead, they're created in overrides in
// converse-chatiew.js and/or converse-muc.js
if (view) {
// This is an optimization. We don't remove older views, so
// when one is available, we reuse it.
delete view.model; // Remove ref to old model to help garbage collection
view.model = item;
view.initialize();
......@@ -3831,6 +3871,10 @@ define("polyfill", function(){});
return view;
},
removeChat: function (item) {
this.remove(item.get('id'));
},
closeAllChatBoxes: function () {
/* This method gets overridden in src/converse-controlbox.js if
* the controlbox plugin is active.
......@@ -4488,11 +4532,10 @@ define("polyfill", function(){});
};
}));
/**
* @preserve jed.js https://github.com/SlexAxton/Jed
*/
/*
jed.js
v0.5.0beta
https://github.com/SlexAxton/Jed
-----------
A gettext compatible i18n library for modern JavaScript Applications
......@@ -4581,7 +4624,9 @@ in order to offer easy upgrades -- jsgettext.berlios.de
}
},
// The default domain if one is missing
"domain" : "messages"
"domain" : "messages",
// enable debug mode to log untranslated strings to the console
"debug" : false
};
// Mix in the sent options with the default options
......@@ -4626,7 +4671,7 @@ in order to offer easy upgrades -- jsgettext.berlios.de
},
fetch : function ( sArr ) {
if ( {}.toString.call( sArr ) != '[object Array]' ) {
sArr = [].slice.call(arguments);
sArr = [].slice.call(arguments, 0);
}
return ( sArr && sArr.length ? Jed.sprintf : function(x){ return x; } )(
this._i18n.dcnpgettext(this._domain, this._context, this._key, this._pkey, this._val),
......@@ -4711,9 +4756,6 @@ in order to offer easy upgrades -- jsgettext.berlios.de
// isn't explicitly passed in
domain = domain || this._textdomain;
// Default the value to the singular case
val = typeof val == 'undefined' ? 1 : val;
var fallback;
// Handle special cases
......@@ -4747,23 +4789,34 @@ in order to offer easy upgrades -- jsgettext.berlios.de
throw new Error('No translation key found.');
}
// Handle invalid numbers, but try casting strings for good measure
if ( typeof val != 'number' ) {
val = parseInt( val, 10 );
if ( isNaN( val ) ) {
throw new Error('The number that was passed in is not a number.');
}
}
var key = context ? context + Jed.context_delimiter + singular_key : singular_key,
locale_data = this.options.locale_data,
dict = locale_data[ domain ],
pluralForms = dict[""].plural_forms || (locale_data.messages || this.defaults.locale_data.messages)[""].plural_forms,
val_idx = getPluralFormFunc(pluralForms)(val) + 1,
defaultConf = (locale_data.messages || this.defaults.locale_data.messages)[""],
pluralForms = dict[""].plural_forms || dict[""]["Plural-Forms"] || dict[""]["plural-forms"] || defaultConf.plural_forms || defaultConf["Plural-Forms"] || defaultConf["plural-forms"],
val_list,
res;
var val_idx;
if (val === undefined) {
// No value passed in; assume singular key lookup.
val_idx = 0;
} else {
// Value has been passed in; use plural-forms calculations.
// Handle invalid numbers, but try casting strings for good measure
if ( typeof val != 'number' ) {
val = parseInt( val, 10 );
if ( isNaN( val ) ) {
throw new Error('The number that was passed in is not a number.');
}
}
val_idx = getPluralFormFunc(pluralForms)(val);
}
// Throw an error if a domain isn't found
if ( ! dict ) {
throw new Error('No domain named `' + domain + '` could be found.');
......@@ -4773,20 +4826,25 @@ in order to offer easy upgrades -- jsgettext.berlios.de
// If there is no match, then revert back to
// english style singular/plural with the keys passed in.
if ( ! val_list || val_idx >= val_list.length ) {
if ( ! val_list || val_idx > val_list.length ) {
if (this.options.missing_key_callback) {
this.options.missing_key_callback(key);
this.options.missing_key_callback(key, domain);
}
res = [ singular_key, plural_key ];
// collect untranslated strings
if (this.options.debug===true) {
console.log(res[ getPluralFormFunc(pluralForms)( val ) ]);
}
res = [ null, singular_key, plural_key ];
return res[ getPluralFormFunc(pluralForms)( val ) + 1 ];
return res[ getPluralFormFunc()( val ) ];
}
res = val_list[ val_idx ];
// This includes empty strings on purpose
if ( ! res ) {
res = [ null, singular_key, plural_key ];
return res[ getPluralFormFunc(pluralForms)( val ) + 1 ];
res = [ singular_key, plural_key ];
return res[ getPluralFormFunc()( val ) ];
}
return res;
}
......@@ -5090,15 +5148,15 @@ performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
var $0 = $$.length - 1;
switch (yystate) {
case 1: return { type : 'GROUP', expr: $$[$0-1] };
case 1: return { type : 'GROUP', expr: $$[$0-1] };
break;
case 2:this.$ = { type: 'TERNARY', expr: $$[$0-4], truthy : $$[$0-2], falsey: $$[$0] };
case 2:this.$ = { type: 'TERNARY', expr: $$[$0-4], truthy : $$[$0-2], falsey: $$[$0] };
break;
case 3:this.$ = { type: "OR", left: $$[$0-2], right: $$[$0] };
break;
case 4:this.$ = { type: "AND", left: $$[$0-2], right: $$[$0] };
break;
case 5:this.$ = { type: 'LT', left: $$[$0-2], right: $$[$0] };
case 5:this.$ = { type: 'LT', left: $$[$0-2], right: $$[$0] };
break;
case 6:this.$ = { type: 'LTE', left: $$[$0-2], right: $$[$0] };
break;
......@@ -5112,11 +5170,11 @@ case 10:this.$ = { type: 'EQ', left: $$[$0-2], right: $$[$0] };
break;
case 11:this.$ = { type: 'MOD', left: $$[$0-2], right: $$[$0] };
break;
case 12:this.$ = { type: 'GROUP', expr: $$[$0-1] };
case 12:this.$ = { type: 'GROUP', expr: $$[$0-1] };
break;
case 13:this.$ = { type: 'VAR' };
case 13:this.$ = { type: 'VAR' };
break;
case 14:this.$ = { type: 'NUM', val: Number(yytext) };
case 14:this.$ = { type: 'NUM', val: Number(yytext) };
break;
}
},
......@@ -5402,7 +5460,7 @@ next:function () {
if (this._input === "") {
return this.EOF;
} else {
this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
{text: "", token: null, line: this.yylineno});
}
},
......@@ -5535,15 +5593,12 @@ return parser;
ChatBoxViews: {
onChatBoxAdded: function (item) {
var view = this.get(item.get('id'));
// FIXME: leaky abstraction from chatroom here, need to
// come up with a nicer solution for this.
// Perhaps change 'chatroom' to more generic non-boolean
if (!view && !item.get('chatroom')) {
if (!view) {
view = new converse.ChatBoxView({model: item});
this.add(item.get('id'), view);
this.trimChats(view);
return view;
} else {
this._super.onChatBoxAdded.apply(this, arguments);
return this._super.onChatBoxAdded.apply(this, arguments);
}
}
}
......@@ -5566,7 +5621,6 @@ return parser;
events: {
'click .close-chatbox-button': 'close',
'click .toggle-chatbox-button': 'minimize',
'keypress textarea.chat-textarea': 'keyPressed',
'click .toggle-smiley': 'toggleEmoticonMenu',
'click .toggle-smiley ul li': 'insertEmoticon',
......@@ -5586,7 +5640,6 @@ return parser;
this.model.on('change:chat_state', this.sendChatState, this);
this.model.on('change:chat_status', this.onChatStatusChanged, this);
this.model.on('change:image', this.renderAvatar, this);
this.model.on('change:minimized', this.onMinimizedChanged, this);
this.model.on('change:status', this.onStatusChanged, this);
this.model.on('showHelpMessages', this.showHelpMessages, this);
this.model.on('sendMessage', this.sendMessage, this);
......@@ -5602,6 +5655,7 @@ return parser;
show_textarea: true,
title: this.model.get('fullname'),
info_close: __('Close this chat box'),
// FIXME: leaky-abstraction from converse-minimize
info_minimize: __('Minimize this chat box'),
label_personal_message: __('Personal message')
}
......@@ -5661,10 +5715,10 @@ return parser;
fetchArchivedMessages: function (options) {
/* Fetch archived chat messages from the XMPP server.
*
* Then, upon receiving them, call onMessage on the chat box,
* so that they are displayed inside it.
*/
*
* Then, upon receiving them, call onMessage on the chat box,
* so that they are displayed inside it.
*/
if (!converse.features.findWhere({'var': Strophe.NS.MAM})) {
converse.log("Attempted to fetch archived messages but this user's server doesn't support XEP-0313");
return;
......@@ -5685,16 +5739,16 @@ return parser;
insertIntoPage: function () {
/* This method gets overridden in src/converse-controlbox.js if
* the controlbox plugin is active.
*/
* the controlbox plugin is active.
*/
$('#conversejs').prepend(this.$el);
return this;
},
adjustToViewport: function () {
/* Event handler called when viewport gets resized. We remove
* custom width/height from chat boxes.
*/
* custom width/height from chat boxes.
*/
var viewport_width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
var viewport_height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
if (viewport_width <= 480) {
......@@ -5709,8 +5763,8 @@ return parser;
initDragResize: function () {
/* Determine and store the default box size.
* We need this information for the drag-resizing feature.
*/
* We need this information for the drag-resizing feature.
*/
var $flyout = this.$el.find('.box-flyout');
if (typeof this.model.get('height') === 'undefined') {
var height = $flyout.height();
......@@ -5770,11 +5824,11 @@ return parser;
prependDayIndicator: function (date) {
/* Prepends an indicator into the chat area, showing the day as
* given by the passed in date.
*
* Parameters:
* (String) date - An ISO8601 date string.
*/
* given by the passed in date.
*
* Parameters:
* (String) date - An ISO8601 date string.
*/
var day_date = moment(date).startOf('day');
this.$content.prepend(converse.templates.new_day({
isodate: day_date.format(),
......@@ -5784,11 +5838,11 @@ return parser;
appendMessage: function (attrs) {
/* Helper method which appends a message to the end of the chat
* box's content area.
*
* Parameters:
* (Object) attrs: An object containing the message attributes.
*/
* box's content area.
*
* Parameters:
* (Object) attrs: An object containing the message attributes.
*/
_.compose(
_.debounce(this.scrollDown.bind(this), 50),
this.$content.append.bind(this.$content)
......@@ -5797,15 +5851,15 @@ return parser;
showMessage: function (attrs) {
/* Inserts a chat message into the content area of the chat box.
* Will also insert a new day indicator if the message is on a
* different day.
*
* The message to show may either be newer than the newest
* message, or older than the oldest message.
*
* Parameters:
* (Object) attrs: An object containing the message attributes.
*/
* Will also insert a new day indicator if the message is on a
* different day.
*
* The message to show may either be newer than the newest
* message, or older than the oldest message.
*
* Parameters:
* (Object) attrs: An object containing the message attributes.
*/
var $first_msg = this.$content.children('.chat-message:first'),
first_msg_date = $first_msg.data('isodate'),
last_msg_date, current_msg_date, day_date, $msgs, msg_dates, idx;
......@@ -5883,13 +5937,13 @@ return parser;
renderMessage: function (attrs) {
/* Renders a chat message based on the passed in attributes.
*
* Parameters:
* (Object) attrs: An object containing the message attributes.
*
* Returns:
* The DOM element representing the message.
*/
*
* Parameters:
* (Object) attrs: An object containing the message attributes.
*
* Returns:
* The DOM element representing the message.
*/
var msg_time = moment(attrs.time) || moment,
text = attrs.message,
match = text.match(/^\/(.*?)(?: (.*))?$/),
......@@ -5952,22 +6006,26 @@ return parser;
}
},
shouldShowOnTextMessage: function () {
return !this.$el.is(':visible');
},
handleTextMessage: function (message) {
this.showMessage(_.clone(message.attributes));
if ((message.get('sender') !== 'me') && (converse.windowState === 'blur')) {
converse.incrementMsgCounter();
}
if (!this.model.get('minimized') && !this.$el.is(':visible')) {
if (this.shouldShowOnTextMessage()) {
this.show();
}
},
onMessageAdded: function (message) {
/* Handler that gets called when a new message object is created.
*
* Parameters:
* (Object) message - The message Backbone object that was added.
*/
*
* Parameters:
* (Object) message - The message Backbone object that was added.
*/
if (typeof this.clear_status_timeout !== 'undefined') {
window.clearTimeout(this.clear_status_timeout);
delete this.clear_status_timeout;
......@@ -5991,10 +6049,10 @@ return parser;
sendMessage: function (message) {
/* Responsible for sending off a text message.
*
* Parameters:
* (Message) message - The chat message
*/
*
* Parameters:
* (Message) message - The chat message
*/
// TODO: We might want to send to specfic resources.
// Especially in the OTR case.
var messageStanza = this.createMessageStanza(message);
......@@ -6012,11 +6070,11 @@ return parser;
onMessageSubmitted: function (text) {
/* This method gets called once the user has typed a message
* and then pressed enter in a chat box.
*
* Parameters:
* (string) text - The chat message text.
*/
* and then pressed enter in a chat box.
*
* Parameters:
* (string) text - The chat message text.
*/
if (!converse.connection.authenticated) {
return this.showHelpMessages(
['Sorry, the connection has been lost, '+
......@@ -6052,9 +6110,9 @@ return parser;
sendChatState: function () {
/* Sends a message with the status of the user in this chat session
* as taken from the 'chat_state' attribute of the chat box.
* See XEP-0085 Chat State Notifications.
*/
* as taken from the 'chat_state' attribute of the chat box.
* See XEP-0085 Chat State Notifications.
*/
converse.connection.send(
$msg({'to':this.model.get('jid'), 'type': 'chat'})
.c(this.model.get('chat_state'), {'xmlns': Strophe.NS.CHATSTATES})
......@@ -6063,16 +6121,16 @@ return parser;
setChatState: function (state, no_save) {
/* Mutator for setting the chat state of this chat session.
* Handles clearing of any chat state notification timeouts and
* setting new ones if necessary.
* Timeouts are set when the state being set is COMPOSING or PAUSED.
* After the timeout, COMPOSING will become PAUSED and PAUSED will become INACTIVE.
* See XEP-0085 Chat State Notifications.
*
* Parameters:
* (string) state - The chat state (consts ACTIVE, COMPOSING, PAUSED, INACTIVE, GONE)
* (Boolean) no_save - Just do the cleanup or setup but don't actually save the state.
*/
* Handles clearing of any chat state notification timeouts and
* setting new ones if necessary.
* Timeouts are set when the state being set is COMPOSING or PAUSED.
* After the timeout, COMPOSING will become PAUSED and PAUSED will become INACTIVE.
* See XEP-0085 Chat State Notifications.
*
* Parameters:
* (string) state - The chat state (consts ACTIVE, COMPOSING, PAUSED, INACTIVE, GONE)
* (Boolean) no_save - Just do the cleanup or setup but don't actually save the state.
*/
if (typeof this.chat_state_timeout !== 'undefined') {
window.clearTimeout(this.chat_state_timeout);
delete this.chat_state_timeout;
......@@ -6092,14 +6150,15 @@ return parser;
keyPressed: function (ev) {
/* Event handler for when a key is pressed in a chat box textarea.
*/
*/
var $textarea = $(ev.target), message;
if (ev.keyCode === KEY.ENTER) {
ev.preventDefault();
message = $textarea.val();
$textarea.val('').focus();
if (message !== '') {
if (this.model.get('chatroom')) {
// XXX: leaky abstraction from MUC
if (this.model.get('type') === 'chatroom') {
this.onChatRoomMessageSubmitted(message);
} else {
this.onMessageSubmitted(message);
......@@ -6107,7 +6166,8 @@ return parser;
converse.emit('messageSend', message);
}
this.setChatState(converse.ACTIVE);
} else if (!this.model.get('chatroom')) { // chat state data is currently only for single user chat
// XXX: leaky abstraction from MUC
} else if (this.model.get('type') !== 'chatroom') { // chat state data is currently only for single user chat
// Set chat state to composing if keyCode is not a forward-slash
// (which would imply an internal command and not a message).
this.setChatState(converse.COMPOSING, ev.keyCode === KEY.FORWARD_SLASH);
......@@ -6142,26 +6202,22 @@ return parser;
},
setChatBoxHeight: function (height) {
if (!this.model.get('minimized')) {
if (height) {
height = converse.applyDragResistance(height, this.model.get('default_height'))+'px';
} else {
height = "";
}
this.$el.children('.box-flyout')[0].style.height = height;
if (height) {
height = converse.applyDragResistance(height, this.model.get('default_height'))+'px';
} else {
height = "";
}
this.$el.children('.box-flyout')[0].style.height = height;
},
setChatBoxWidth: function (width) {
if (!this.model.get('minimized')) {
if (width) {
width = converse.applyDragResistance(width, this.model.get('default_width'))+'px';
} else {
width = "";
}
this.$el[0].style.width = width;
this.$el.children('.box-flyout')[0].style.width = width;
if (width) {
width = converse.applyDragResistance(width, this.model.get('default_width'))+'px';
} else {
width = "";
}
this.$el[0].style.width = width;
this.$el.children('.box-flyout')[0].style.width = width;
},
resizeChatBox: function (ev) {
......@@ -6246,14 +6302,6 @@ return parser;
});
},
onMinimizedChanged: function (item) {
if (item.get('minimized')) {
this.minimize();
} else {
this.maximize();
}
},
showStatusMessage: function (msg) {
msg = msg || this.model.get('status');
if (typeof msg === "string") {
......@@ -6265,43 +6313,18 @@ return parser;
close: function (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
if (converse.connection.connected) {
// Immediately sending the chat state, because the
// model is going to be destroyed afterwards.
this.model.set('chat_state', converse.INACTIVE);
this.sendChatState();
this.model.destroy();
this.setChatState(converse.INACTIVE);
} else {
this.hide();
}
this.remove();
converse.emit('chatBoxClosed', this);
return this;
},
onMaximized: function () {
converse.chatboxviews.trimChats(this);
utils.refreshWebkit();
this.$content.scrollTop(this.model.get('scroll'));
this.setChatState(converse.ACTIVE).focus();
converse.emit('chatBoxMaximized', this);
},
onMinimized: function () {
utils.refreshWebkit();
converse.emit('chatBoxMinimized', this);
},
maximize: function () {
// Restore a minimized chat box
$('#conversejs').prepend(this.$el);
this.$el.show('fast', this.onMaximized.bind(this));
return this;
},
minimize: function (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
// save the scroll position to restore it on maximize
this.model.save({'scroll': this.$content.scrollTop()});
this.setChatState(converse.INACTIVE).model.minimize();
this.$el.hide('fast', this.onMinimized.bind(this));
},
renderToolbar: function (options) {
if (!converse.show_toolbar) {
return;
......@@ -6361,31 +6384,32 @@ return parser;
return this;
},
afterShown: function () {
if (converse.connection.connected) {
// Without a connection, we haven't yet initialized
// localstorage
this.model.save();
}
this.setChatState(converse.ACTIVE);
this.scrollDown();
if (focus) {
this.focus();
}
},
show: function (focus) {
if (typeof this.debouncedShow === 'undefined') {
/* We wrap the method in a debouncer and set it on the
* instance, so that we have it debounced per instance.
* Debouncing it on the class-level is too broad.
*/
* instance, so that we have it debounced per instance.
* Debouncing it on the class-level is too broad.
*/
this.debouncedShow = _.debounce(function (focus) {
if (this.$el.is(':visible') && this.$el.css('opacity') === "1") {
if (focus) { this.focus(); }
return;
}
this.initDragResize().setDimensions();
this.$el.fadeIn(function () {
if (converse.connection.connected) {
// Without a connection, we haven't yet initialized
// localstorage
this.model.save();
}
converse.chatboxviews.trimChats(this);
this.setChatState(converse.ACTIVE);
this.scrollDown();
if (focus) {
this.focus();
}
}.bind(this));
this.$el.fadeIn(this.afterShown.bind(this));
}, 250, true);
}
this.debouncedShow.apply(this, arguments);
......@@ -6473,7 +6497,6 @@ return parser;
/* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery.
*/
this.updateSettings({
archived_messages_page_size: '20',
message_archiving: 'never', // Supported values are 'always', 'never', 'roster' (https://xmpp.org/extensions/xep-0313.html#prefs)
......@@ -6482,22 +6505,22 @@ return parser;
converse.queryForArchivedMessages = function (options, callback, errback) {
/* Do a MAM (XEP-0313) query for archived messages.
*
* Parameters:
* (Object) options - Query parameters, either MAM-specific or also for Result Set Management.
* (Function) callback - A function to call whenever we receive query-relevant stanza.
* (Function) errback - A function to call when an error stanza is received.
*
* The options parameter can also be an instance of
* Strophe.RSM to enable easy querying between results pages.
*
* The callback function may be called multiple times, first
* for the initial IQ result and then for each message
* returned. The last time the callback is called, a
* Strophe.RSM object is returned on which "next" or "previous"
* can be called before passing it in again to this method, to
* get the next or previous page in the result set.
*/
*
* Parameters:
* (Object) options - Query parameters, either MAM-specific or also for Result Set Management.
* (Function) callback - A function to call whenever we receive query-relevant stanza.
* (Function) errback - A function to call when an error stanza is received.
*
* The options parameter can also be an instance of
* Strophe.RSM to enable easy querying between results pages.
*
* The callback function may be called multiple times, first
* for the initial IQ result and then for each message
* returned. The last time the callback is called, a
* Strophe.RSM object is returned on which "next" or "previous"
* can be called before passing it in again to this method, to
* get the next or previous page in the result set.
*/
var date, messages = [];
if (typeof options === "function") {
callback = options;
......@@ -6565,7 +6588,7 @@ return parser;
_.extend(converse_api, {
/* Extend default converse.js API to add methods specific to MAM
*/
*/
'archive': {
'query': converse.queryForArchivedMessages.bind(converse)
}
......@@ -6771,20 +6794,20 @@ return parser;
success: function (collection) {
if (collection.length === 0) {
/* We don't have any roster contacts stored in sessionStorage,
* so lets fetch the roster from the XMPP server. We pass in
* 'sendPresence' as callback method, because after initially
* fetching the roster we are ready to receive presence
* updates from our contacts.
*/
* so lets fetch the roster from the XMPP server. We pass in
* 'sendPresence' as callback method, because after initially
* fetching the roster we are ready to receive presence
* updates from our contacts.
*/
converse.roster.fetchFromServer(function () {
converse.xmppstatus.sendPresence();
});
} else if (converse.send_initial_presence) {
/* We're not going to fetch the roster again because we have
* it already cached in sessionStorage, but we still need to
* send out a presence stanza because this is a new session.
* See: https://github.com/jcbrand/converse.js/issues/536
*/
* it already cached in sessionStorage, but we still need to
* send out a presence stanza because this is a new session.
* See: https://github.com/jcbrand/converse.js/issues/536
*/
converse.xmppstatus.sendPresence();
}
}
......@@ -6957,13 +6980,13 @@ return parser;
positionFetchedGroups: function (model, resp, options) {
/* Instead of throwing an add event for each group
* fetched, we wait until they're all fetched and then
* we position them.
* Works around the problem of positionGroup not
* working when all groups besides the one being
* positioned aren't already in inserted into the
* roster DOM element.
*/
* fetched, we wait until they're all fetched and then
* we position them.
* Works around the problem of positionGroup not
* working when all groups besides the one being
* positioned aren't already in inserted into the
* roster DOM element.
*/
model.sort();
model.each(function (group, idx) {
var view = this.get(group.get('name'));
......@@ -6981,8 +7004,8 @@ return parser;
positionGroup: function (view) {
/* Place the group's DOM element in the correct alphabetical
* position amongst the other groups in the roster.
*/
* position amongst the other groups in the roster.
*/
var $groups = this.$roster.find('.roster-group'),
index = $groups.length ? this.model.indexOf(view.model) : 0;
if (index === 0) {
......@@ -6997,7 +7020,7 @@ return parser;
appendGroup: function (view) {
/* Add the group at the bottom of the roster
*/
*/
var $last = this.$roster.find('.roster-group').last();
var $siblings = $last.siblings('dd');
if ($siblings.length > 0) {
......@@ -7010,8 +7033,8 @@ return parser;
getGroup: function (name) {
/* Returns the group as specified by name.
* Creates the group if it doesn't exist.
*/
* Creates the group if it doesn't exist.
*/
var view = this.get(name);
if (view) {
return view.model;
......@@ -7097,16 +7120,16 @@ return parser;
if ((ask === 'subscribe') || (subscription === 'from')) {
/* ask === 'subscribe'
* Means we have asked to subscribe to them.
*
* subscription === 'from'
* They are subscribed to use, but not vice versa.
* We assume that there is a pending subscription
* from us to them (otherwise we're in a state not
* supported by converse.js).
*
* So in both cases the user is a "pending" contact.
*/
* Means we have asked to subscribe to them.
*
* subscription === 'from'
* They are subscribed to use, but not vice versa.
* We assume that there is a pending subscription
* from us to them (otherwise we're in a state not
* supported by converse.js).
*
* So in both cases the user is a "pending" contact.
*/
this.$el.addClass('pending-xmpp-contact');
this.$el.html(converse.templates.pending_contact(
_.extend(item.toJSON(), {
......@@ -7249,8 +7272,8 @@ return parser;
positionContact: function (contact) {
/* Place the contact's DOM element in the correct alphabetical
* position amongst the other contacts in this group.
*/
* position amongst the other contacts in this group.
*/
var view = this.get(contact.get('id'));
var index = this.model.contacts.indexOf(contact);
view.$el.detach();
......@@ -7279,10 +7302,10 @@ return parser;
filter: function (q) {
/* Filter the group's contacts based on the query "q".
* The query is matched against the contact's full name.
* If all contacts are filtered out (i.e. hidden), then the
* group must be filtered out as well.
*/
* The query is matched against the contact's full name.
* If all contacts are filtered out (i.e. hidden), then the
* group must be filtered out as well.
*/
var matches;
if (q.length === 0) {
if (this.model.get('state') === converse.OPENED) {
......@@ -7369,8 +7392,8 @@ return parser;
model: converse.RosterGroup,
comparator: function (a, b) {
/* Groups are sorted alphabetically, ignoring case.
* However, Ungrouped, Requesting Contacts and Pending Contacts
* appear last and in that order. */
* However, Ungrouped, Requesting Contacts and Pending Contacts
* appear last and in that order. */
a = a.get('name');
b = b.get('name');
var special_groups = _.keys(HEADER_WEIGHTS);
......@@ -7481,9 +7504,9 @@ return parser;
var view = this.get(item.get('id'));
if (!view && item.get('box_id') === 'controlbox') {
view = new converse.ControlBoxView({model: item});
this.add(item.get('id'), view);
return this.add(item.get('id'), view);
} else {
this._super.onChatBoxAdded.apply(this, arguments);
return this._super.onChatBoxAdded.apply(this, arguments);
}
},
......@@ -7640,8 +7663,8 @@ return parser;
initRoster: function () {
/* We initialize the roster, which will appear inside the
* Contacts Panel.
*/
* Contacts Panel.
*/
var rostergroups = new converse.RosterGroups();
rostergroups.browserStorage = new Backbone.BrowserStorage[converse.storage](
b64_sha1('converse.roster.groups'+converse.bare_jid));
......@@ -8135,7 +8158,7 @@ return parser;
// Copyright (c) 2012-2016, Jan-Carel Brand <jc@opkode.com>
// Licensed under the Mozilla Public License (MPLv2)
//
/*global Backbone, define, window, setTimeout */
/*global Backbone, define, window */
/* This is a Converse.js plugin which add support for multi-user chat rooms, as
* specified in XEP-0045 Multi-user chat.
......@@ -8145,8 +8168,8 @@ return parser;
"converse-core",
"converse-api",
"typeahead",
// TODO remove next two dependencies
"converse-chatview",
// XXX: should we remove this dependency?
"converse-controlbox"
], factory);
}(this, function (converse, converse_api) {
......@@ -8228,6 +8251,8 @@ return parser;
},
onConnected: function () {
// TODO: This can probably be refactored to be an event
// handler (and therefore removed from overrides)
var converse = this._super.converse;
this._super.onConnected.apply(this, arguments);
......@@ -8257,73 +8282,14 @@ return parser;
}
},
ChatBoxes: {
registerMessageHandler: function () {
/* Override so that we can register a handler
* for chat room invites.
*/
this._super.registerMessageHandler.apply(this, arguments); // First call the original
this._super.converse.connection.addHandler(
function (message) {
this.onInvite(message);
return true;
}.bind(this), 'jabber:x:conference', 'message');
},
onInvite: function (message) {
/* An invitation to join a chat room has been received */
var converse = this._super.converse,
$message = $(message),
$x = $message.children('x[xmlns="jabber:x:conference"]'),
from = Strophe.getBareJidFromJid($message.attr('from')),
room_jid = $x.attr('jid'),
reason = $x.attr('reason'),
contact = converse.roster.get(from),
result;
if (converse.auto_join_on_invite) {
result = true;
} else {
contact = contact? contact.get('fullname'): Strophe.getNodeFromJid(from); // Invite request might come from someone not your roster list
if (!reason) {
result = confirm(
__(___("%1$s has invited you to join a chat room: %2$s"), contact, room_jid)
);
} else {
result = confirm(
__(___('%1$s has invited you to join a chat room: %2$s, and left the following reason: "%3$s"'), contact, room_jid, reason)
);
}
}
if (result === true) {
var chatroom = converse.chatboxviews.showChat({
'id': room_jid,
'jid': room_jid,
'name': Strophe.unescapeNode(Strophe.getNodeFromJid(room_jid)),
'nick': Strophe.unescapeNode(Strophe.getNodeFromJid(converse.connection.jid)),
'chatroom': true,
'box_id': b64_sha1(room_jid),
'password': $x.attr('password')
});
if (!_.contains(
[Strophe.Status.CONNECTING, Strophe.Status.CONNECTED],
chatroom.get('connection_status'))
) {
converse.chatboxviews.get(room_jid).join(null);
}
}
}
},
ChatBoxViews: {
onChatBoxAdded: function (item) {
var view = this.get(item.get('id'));
if (!view && item.get('chatroom')) {
if (!view && item.get('type') === 'chatroom') {
view = new converse.ChatRoomView({'model': item});
this.add(item.get('id'), view);
return this.add(item.get('id'), view);
} else {
this._super.onChatBoxAdded.apply(this, arguments);
return this._super.onChatBoxAdded.apply(this, arguments);
}
}
}
......@@ -8338,6 +8304,8 @@ return parser;
this.updateSettings({
allow_muc: true,
auto_join_on_invite: false, // Auto-join chatroom on invite
auto_join_rooms: [], // List of maps {'jid': 'room@example.org', 'nick': 'WizardKing69' },
// providing room jids and nicks or simply a list JIDs.
auto_list_rooms: false,
hide_muc_server: false,
muc_history_max_stanzas: undefined, // Takes an integer, limits the amount of messages to fetch from chat room's history
......@@ -8347,11 +8315,12 @@ return parser;
converse.ChatRoomView = converse.ChatBoxView.extend({
/* Backbone View which renders a chat room, based upon the view
* for normal one-on-one chat boxes.
*/
* for normal one-on-one chat boxes.
*/
length: 300,
tagName: 'div',
className: 'chatbox chatroom',
is_chatroom: true,
events: {
'click .close-chatbox-button': 'close',
'click .toggle-chatbox-button': 'minimize',
......@@ -8366,7 +8335,6 @@ return parser;
'mousedown .dragresize-left': 'onStartHorizontalResize',
'mousedown .dragresize-topleft': 'onStartDiagonalResize'
},
is_chatroom: true,
initialize: function () {
$(window).on('resize', _.debounce(this.setDimensions.bind(this), 100));
......@@ -8378,9 +8346,6 @@ return parser;
this.maximize();
}
}, this);
this.model.on('destroy', function () {
this.hide().leave();
}, this);
this.occupantsview = new converse.ChatRoomOccupantsView({
model: new converse.ChatRoomOccupants({nick: this.model.get('nick')})
......@@ -8409,7 +8374,7 @@ return parser;
this.renderChatArea();
this.$content.on('scroll', _.debounce(this.onScroll.bind(this), 100));
this.setWidth();
setTimeout(converse.refreshWebkit, 50);
window.setTimeout(converse.refreshWebkit, 50);
return this;
},
......@@ -8429,6 +8394,12 @@ return parser;
return this;
},
close: function (ev) {
converse.connection.deleteHandler(this.handler);
this.leave();
converse.ChatBoxView.prototype.close.apply(this, arguments);
},
toggleOccupants: function (ev, preserve_state) {
if (ev) {
ev.preventDefault();
......@@ -8528,8 +8499,8 @@ return parser;
validateRoleChangeCommand: function (command, args) {
/* Check that a command to change a chat room user's role or
* affiliation has anough arguments.
*/
* affiliation has anough arguments.
*/
// TODO check if first argument is valid
if (args.length < 1 || args.length > 2) {
this.showStatusNotification(
......@@ -8552,11 +8523,11 @@ return parser;
onChatRoomMessageSubmitted: function (text) {
/* Gets called when the user presses enter to send off a
* message in a chat room.
*
* Parameters:
* (String) text - The message text.
*/
* message in a chat room.
*
* Parameters:
* (String) text - The message text.
*/
var match = text.replace(/^\s*/, "").match(/^\/(.*?)(?: (.*))?$/) || [false, '', ''],
args = match[2] && match[2].splitOnce(' ') || [];
switch (match[1]) {
......@@ -8731,7 +8702,9 @@ return parser;
presence.c("status", exit_msg);
}
converse.connection.addHandler(
function () { this.model.set('connection_status', Strophe.Status.DISCONNECTED); }.bind(this),
function () {
this.model.set('connection_status', Strophe.Status.DISCONNECTED);
}.bind(this),
null, "presence", null, presenceid);
converse.connection.send(presence);
},
......@@ -8854,27 +8827,27 @@ return parser;
},
/* http://xmpp.org/extensions/xep-0045.html
* ----------------------------------------
* 100 message Entering a room Inform user that any occupant is allowed to see the user's full JID
* 101 message (out of band) Affiliation change Inform user that his or her affiliation changed while not in the room
* 102 message Configuration change Inform occupants that room now shows unavailable members
* 103 message Configuration change Inform occupants that room now does not show unavailable members
* 104 message Configuration change Inform occupants that a non-privacy-related room configuration change has occurred
* 110 presence Any room presence Inform user that presence refers to one of its own room occupants
* 170 message or initial presence Configuration change Inform occupants that room logging is now enabled
* 171 message Configuration change Inform occupants that room logging is now disabled
* 172 message Configuration change Inform occupants that the room is now non-anonymous
* 173 message Configuration change Inform occupants that the room is now semi-anonymous
* 174 message Configuration change Inform occupants that the room is now fully-anonymous
* 201 presence Entering a room Inform user that a new room has been created
* 210 presence Entering a room Inform user that the service has assigned or modified the occupant's roomnick
* 301 presence Removal from room Inform user that he or she has been banned from the room
* 303 presence Exiting a room Inform all occupants of new room nickname
* 307 presence Removal from room Inform user that he or she has been kicked from the room
* 321 presence Removal from room Inform user that he or she is being removed from the room because of an affiliation change
* 322 presence Removal from room Inform user that he or she is being removed from the room because the room has been changed to members-only and the user is not a member
* 332 presence Removal from room Inform user that he or she is being removed from the room because of a system shutdown
*/
* ----------------------------------------
* 100 message Entering a room Inform user that any occupant is allowed to see the user's full JID
* 101 message (out of band) Affiliation change Inform user that his or her affiliation changed while not in the room
* 102 message Configuration change Inform occupants that room now shows unavailable members
* 103 message Configuration change Inform occupants that room now does not show unavailable members
* 104 message Configuration change Inform occupants that a non-privacy-related room configuration change has occurred
* 110 presence Any room presence Inform user that presence refers to one of its own room occupants
* 170 message or initial presence Configuration change Inform occupants that room logging is now enabled
* 171 message Configuration change Inform occupants that room logging is now disabled
* 172 message Configuration change Inform occupants that the room is now non-anonymous
* 173 message Configuration change Inform occupants that the room is now semi-anonymous
* 174 message Configuration change Inform occupants that the room is now fully-anonymous
* 201 presence Entering a room Inform user that a new room has been created
* 210 presence Entering a room Inform user that the service has assigned or modified the occupant's roomnick
* 301 presence Removal from room Inform user that he or she has been banned from the room
* 303 presence Exiting a room Inform all occupants of new room nickname
* 307 presence Removal from room Inform user that he or she has been kicked from the room
* 321 presence Removal from room Inform user that he or she is being removed from the room because of an affiliation change
* 322 presence Removal from room Inform user that he or she is being removed from the room because the room has been changed to members-only and the user is not a member
* 332 presence Removal from room Inform user that he or she is being removed from the room because of a system shutdown
*/
infoMessages: {
100: __('This room is not anonymous'),
102: __('This room now shows unavailable members'),
......@@ -8898,15 +8871,15 @@ return parser;
actionInfoMessages: {
/* XXX: Note the triple underscore function and not double
* underscore.
*
* This is a hack. We can't pass the strings to __ because we
* don't yet know what the variable to interpolate is.
*
* Triple underscore will just return the string again, but we
* can then at least tell gettext to scan for it so that these
* strings are picked up by the translation machinery.
*/
* underscore.
*
* This is a hack. We can't pass the strings to __ because we
* don't yet know what the variable to interpolate is.
*
* Triple underscore will just return the string again, but we
* can then at least tell gettext to scan for it so that these
* strings are picked up by the translation machinery.
*/
301: ___("<strong>%1$s</strong> has been banned"),
303: ___("<strong>%1$s</strong>'s nickname has changed"),
307: ___("<strong>%1$s</strong> has been kicked out"),
......@@ -8921,9 +8894,9 @@ return parser;
showStatusMessages: function (el, is_self) {
/* Check for status codes and communicate their purpose to the user.
* Allow user to configure chat room if they are the owner.
* See: http://xmpp.org/registrar/mucstatus.html
*/
* Allow user to configure chat room if they are the owner.
* See: http://xmpp.org/registrar/mucstatus.html
*/
var $el = $(el),
i, disconnect_msgs = [], msgs = [], reasons = [];
......@@ -9066,10 +9039,10 @@ return parser;
fetchArchivedMessages: function (options) {
/* Fetch archived chat messages from the XMPP server.
*
* Then, upon receiving them, call onChatRoomMessage
* so that they are displayed inside it.
*/
*
* Then, upon receiving them, call onChatRoomMessage
* so that they are displayed inside it.
*/
if (!converse.features.findWhere({'var': Strophe.NS.MAM})) {
converse.log("Attempted to fetch archived messages but this user's server doesn't support XEP-0313");
return;
......@@ -9243,11 +9216,11 @@ return parser;
converse.RoomsPanel = Backbone.View.extend({
/* Backbone View which renders the "Rooms" tab and accompanying
* panel in the control box.
*
* In this panel, chat rooms can be listed, joined and new rooms
* can be created.
*/
* panel in the control box.
*
* In this panel, chat rooms can be listed, joined and new rooms
* can be created.
*/
tagName: 'div',
className: 'controlbox-pane',
id: 'chatrooms',
......@@ -9306,8 +9279,8 @@ return parser;
onRoomsFound: function (iq) {
/* Handle the IQ stanza returned from the server, containing
* all its public rooms.
*/
* all its public rooms.
*/
var name, jid, i, fragment,
$available_chatrooms = this.$el.find('#available-chatrooms');
this.rooms = $(iq).find('query').find('item');
......@@ -9338,7 +9311,7 @@ return parser;
updateRoomsList: function () {
/* Send and IQ stanza to the server asking for all rooms
*/
*/
converse.connection.sendIQ(
$iq({
to: this.model.get('muc_domain'),
......@@ -9453,7 +9426,7 @@ return parser;
'jid': jid,
'name': name || Strophe.unescapeNode(Strophe.getNodeFromJid(jid)),
'nick': nick,
'chatroom': true,
'type': 'chatroom',
'box_id': b64_sha1(jid)
});
},
......@@ -9467,10 +9440,78 @@ return parser;
}
});
/* Support for XEP-0249: Direct MUC invitations */
/* ------------------------------------------------------------ */
converse.onDirectMUCInvitation = function (message) {
/* A direct MUC invitation to join a room has been received */
var $message = $(message),
$x = $message.children('x[xmlns="jabber:x:conference"]'),
from = Strophe.getBareJidFromJid($message.attr('from')),
room_jid = $x.attr('jid'),
reason = $x.attr('reason'),
contact = converse.roster.get(from),
result;
if (converse.auto_join_on_invite) {
result = true;
} else {
// Invite request might come from someone not your roster list
contact = contact? contact.get('fullname'): Strophe.getNodeFromJid(from);
if (!reason) {
result = confirm(
__(___("%1$s has invited you to join a chat room: %2$s"),
contact, room_jid)
);
} else {
result = confirm(
__(___('%1$s has invited you to join a chat room: %2$s, and left the following reason: "%3$s"'),
contact, room_jid, reason)
);
}
}
if (result === true) {
var chatroom = converse.chatboxviews.showChat({
'id': room_jid,
'jid': room_jid,
'name': Strophe.unescapeNode(Strophe.getNodeFromJid(room_jid)),
'nick': Strophe.unescapeNode(Strophe.getNodeFromJid(converse.connection.jid)),
'type': 'chatroom',
'box_id': b64_sha1(room_jid),
'password': $x.attr('password')
});
if (!_.contains(
[Strophe.Status.CONNECTING, Strophe.Status.CONNECTED],
chatroom.get('connection_status'))
) {
converse.chatboxviews.get(room_jid).join(null);
}
}
};
var onConnected = function () {
converse.connection.addHandler(
function (message) {
converse.onDirectMUCInvitation(message);
return true;
}, 'jabber:x:conference', 'message');
_.each(converse.auto_join_rooms, function (room) {
if (typeof room === 'string') {
converse_api.rooms.open(room);
} else if (typeof room === 'object') {
converse_api.rooms.open(room.jid, room.nick);
} else {
converse.log('Invalid room criteria specified for "auto_join_rooms"', 'error');
}
});
};
converse.on('connected', onConnected);
converse.on('reconnected', onConnected);
/* ------------------------------------------------------------ */
/* We extend the default converse.js API to add methods specific to MUC
* chat rooms.
*/
_.extend(converse_api, {
/* We extend the default converse.js API to add methods specific to MUC
* chat rooms.
*/
'rooms': {
'open': function (jids, nick) {
if (!nick) {
......@@ -9489,7 +9530,7 @@ return parser;
'jid': jid,
'name': Strophe.unescapeNode(Strophe.getNodeFromJid(jid)),
'nick': nick,
'chatroom': true,
'type': 'chatroom',
'box_id': b64_sha1(jid)
});
}
......@@ -9509,7 +9550,6 @@ return parser;
return converse.wrappedChatBox(converse.chatboxes.getChatBox(jids, true));
}
return _.map(jids, _.partial(converse.wrappedChatBox, _.bind(converse.chatboxes.getChatBox, converse.chatboxes, _, true)));
}
}
});
......@@ -9716,6 +9756,7 @@ return parser;
define("converse-minimize", [
"converse-core",
"converse-api",
"converse-chatview"
], factory);
}(this, function (converse, converse_api) {
"use strict";
......@@ -9757,7 +9798,9 @@ return parser;
this._super.registerGlobalEventHandlers.apply(this, arguments);
$(window).on("resize", _.debounce(function (ev) {
converse.chatboxviews.trimChats();
if (converse.connection.connected) {
converse.chatboxviews.trimChats();
}
}, 200));
},
......@@ -9799,15 +9842,86 @@ return parser;
},
},
ChatBoxView: {
events: {
'click .toggle-chatbox-button': 'minimize',
},
initialize: function () {
this.model.on('change:minimized', this.onMinimizedChanged, this);
return this._super.initialize.apply(this, arguments);
},
afterShown: function () {
this._super.afterShown.apply(this, arguments);
if (!this.model.get('minimized')) {
converse.chatboxviews.trimChats(this);
}
},
shouldShowOnTextMessage: function () {
return !this.model.get('minimized') &&
this._super.shouldShowOnTextMessage.apply(this, arguments);
},
setChatBoxHeight: function (height) {
if (!this.model.get('minimized')) {
return this._super.setChatBoxHeight.apply(this, arguments);
}
},
setChatBoxWidth: function (width) {
if (!this.model.get('minimized')) {
return this._super.setChatBoxWidth.apply(this, arguments);
}
},
onMinimizedChanged: function (item) {
if (item.get('minimized')) {
this.minimize();
} else {
this.maximize();
}
},
onMaximized: function () {
converse.chatboxviews.trimChats(this);
utils.refreshWebkit();
this.$content.scrollTop(this.model.get('scroll'));
this.setChatState(converse.ACTIVE).focus();
converse.emit('chatBoxMaximized', this);
},
onMinimized: function () {
utils.refreshWebkit();
converse.emit('chatBoxMinimized', this);
},
maximize: function () {
// Restore a minimized chat box
$('#conversejs').prepend(this.$el);
this.$el.show('fast', this.onMaximized.bind(this));
return this;
},
minimize: function (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
// save the scroll position to restore it on maximize
this.model.save({'scroll': this.$content.scrollTop()});
this.setChatState(converse.INACTIVE).model.minimize();
this.$el.hide('fast', this.onMinimized.bind(this));
},
},
ChatBoxes: {
chatBoxShouldBeShown: function (chatbox) {
return this._super.chatBoxShouldBeShown.apply(this, arguments) &&
return this._super.chatBoxShouldBeShown.apply(this, arguments) &&
!chatbox.get('minimized');
},
},
ChatBoxViews: {
showChat: function (attrs) {
/* Find the chat box and show it. If it doesn't exist, create it.
*/
......@@ -9831,16 +9945,16 @@ return parser;
trimChats: function (newchat) {
/* This method is called when a newly created chat box will
* be shown.
*
* It checks whether there is enough space on the page to show
* another chat box. Otherwise it minimizes the oldest chat box
* to create space.
*/
* be shown.
*
* It checks whether there is enough space on the page to show
* another chat box. Otherwise it minimizes the oldest chat box
* to create space.
*/
if (converse.no_trimming || (this.model.length <= 1)) {
return;
}
var oldest_chat, boxes_width,
var oldest_chat, boxes_width, view,
$minimized = converse.minimized_chats.$el,
minimized_width = _.contains(this.model.pluck('minimized'), true) ? $minimized.outerWidth(true) : 0,
new_id = newchat ? newchat.model.get('id') : null;
......@@ -9852,6 +9966,14 @@ return parser;
if ((minimized_width + boxes_width) > $('body').outerWidth(true)) {
oldest_chat = this.getOldestMaximizedChat([new_id]);
if (oldest_chat) {
// We hide the chat immediately, because waiting
// for the event to fire (and letting the
// ChatBoxView hide it then) causes race
// conditions.
view = this.get(oldest_chat.get('id'));
if (view) {
view.$el.hide();
}
oldest_chat.minimize();
}
}
......@@ -9906,7 +10028,7 @@ return parser;
this.model.toJSON(),
{ 'tooltip': __('Click to restore this chat') }
);
if (this.model.get('chatroom')) {
if (this.model.get('type') === 'chatroom') {
data.title = this.model.get('name');
this.$el.addClass('chat-head-chatroom');
} else {
......@@ -9929,8 +10051,15 @@ return parser;
close: function (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
this.remove();
this.model.destroy();
converse.emit('chatBoxClosed', this);
var view = converse.chatboxviews.get(this.model.get('id'));
if (view) {
// This will call model.destroy(), removing it from the
// collection and will also emit 'chatBoxClosed'
view.close();
} else {
this.model.destroy();
converse.emit('chatBoxClosed', this);
}
return this;
},
......@@ -10068,7 +10197,9 @@ return parser;
converse.on('controlBoxOpened', function (evt, chatbox) {
// Wrapped in anon method because at scan time, chatboxviews
// attr not set yet.
converse.chatboxviews.trimChats(chatbox);
if (converse.connection.connected) {
converse.chatboxviews.trimChats(chatbox);
}
});
}
});
......@@ -10740,8 +10871,8 @@ return parser;
registerHooks: function () {
/* Hook into Strophe's _connect_cb, so that we can send an IQ
* requesting the registration fields.
*/
* requesting the registration fields.
*/
var conn = converse.connection;
var connect_cb = conn._connect_cb.bind(conn);
conn._connect_cb = function (req, callback, raw) {
......@@ -10757,11 +10888,11 @@ return parser;
getRegistrationFields: function (req, _callback, raw) {
/* Send an IQ stanza to the XMPP server asking for the
* registration fields.
* Parameters:
* (Strophe.Request) req - The current request
* (Function) callback
*/
* registration fields.
* Parameters:
* (Strophe.Request) req - The current request
* (Function) callback
*/
converse.log("sendQueryStanza was called");
var conn = converse.connection;
conn.connected = true;
......@@ -10792,10 +10923,10 @@ return parser;
onRegistrationFields: function (stanza) {
/* Handler for Registration Fields Request.
*
* Parameters:
* (XMLElement) elem - The query stanza.
*/
*
* Parameters:
* (XMLElement) elem - The query stanza.
*/
if (stanza.getElementsByTagName("query").length !== 1) {
converse.connection._changeConnectStatus(Strophe.Status.REGIFAIL, "unknown");
return false;
......@@ -10824,11 +10955,11 @@ return parser;
onProviderChosen: function (ev) {
/* Callback method that gets called when the user has chosen an
* XMPP provider.
*
* Parameters:
* (Submit Event) ev - Form submission event.
*/
* XMPP provider.
*
* Parameters:
* (Submit Event) ev - Form submission event.
*/
if (ev && ev.preventDefault) { ev.preventDefault(); }
var $form = $(ev.target),
$domain_input = $form.find('input[name=domain]'),
......@@ -10907,11 +11038,11 @@ return parser;
renderRegistrationForm: function (stanza) {
/* Renders the registration form based on the XForm fields
* received from the XMPP server.
*
* Parameters:
* (XMLElement) stanza - The IQ stanza received from the XMPP server.
*/
* received from the XMPP server.
*
* Parameters:
* (XMLElement) stanza - The IQ stanza received from the XMPP server.
*/
var $form= this.$('form'),
$stanza = $(stanza),
$fields, $input;
......@@ -10964,12 +11095,12 @@ return parser;
reportErrors: function (stanza) {
/* Report back to the user any error messages received from the
* XMPP server after attempted registration.
*
* Parameters:
* (XMLElement) stanza - The IQ stanza received from the
* XMPP server.
*/
* XMPP server after attempted registration.
*
* Parameters:
* (XMLElement) stanza - The IQ stanza received from the
* XMPP server.
*/
var $form= this.$('form'), flash;
var $errmsgs = $(stanza).find('error text');
var $flash = $form.find('.form-errors');
......@@ -10997,7 +11128,7 @@ return parser;
cancelRegistration: function (ev) {
/* Handler, when the user cancels the registration form.
*/
*/
if (ev && ev.preventDefault) { ev.preventDefault(); }
converse.connection.reset();
this.render();
......@@ -11005,12 +11136,12 @@ return parser;
submitRegistrationForm : function (ev) {
/* Handler, when the user submits the registration form.
* Provides form error feedback or starts the registration
* process.
*
* Parameters:
* (Event) ev - the submit event.
*/
* Provides form error feedback or starts the registration
* process.
*
* Parameters:
* (Event) ev - the submit event.
*/
if (ev && ev.preventDefault) { ev.preventDefault(); }
var $empty_inputs = this.$('input.required:emptyVal');
if ($empty_inputs.length) {
......@@ -11038,11 +11169,11 @@ return parser;
setFields: function (stanza) {
/* Stores the values that will be sent to the XMPP server
* during attempted registration.
*
* Parameters:
* (XMLElement) stanza - the IQ stanza that will be sent to the XMPP server.
*/
* during attempted registration.
*
* Parameters:
* (XMLElement) stanza - the IQ stanza that will be sent to the XMPP server.
*/
var $query = $(stanza).find('query'), $xform;
if ($query.length > 0) {
$xform = $query.find('x[xmlns="'+Strophe.NS.XFORM+'"]');
......@@ -11090,12 +11221,12 @@ return parser;
_onRegisterIQ: function (stanza) {
/* Callback method that gets called when a return IQ stanza
* is received from the XMPP server, after attempting to
* register a new user.
*
* Parameters:
* (XMLElement) stanza - The IQ stanza.
*/
* is received from the XMPP server, after attempting to
* register a new user.
*
* Parameters:
* (XMLElement) stanza - The IQ stanza.
*/
var error = null,
query = stanza.getElementsByTagName("query");
if (query.length > 0) {
......@@ -11158,27 +11289,6 @@ return parser;
converse_api.plugins.add('ping', {
overrides: {
// Overrides mentioned here will be picked up by converse.js's
// plugin architecture they will replace existing methods on the
// relevant objects or classes.
//
// New functions which don't exist yet can also be added.
onConnected: function () {
var promise = this._super.onConnected();
promise.done(converse.registerPingHandler);
return promise;
},
onReconnected: function () {
// We need to re-register the ping event handler on the newly
// created connection.
var promise = this._super.onReconnected();
promise.done(converse.registerPingHandler);
return promise;
}
},
initialize: function () {
/* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery.
......@@ -11252,6 +11362,13 @@ return parser;
converse.ping(jid);
}
});
var onConnected = function () {
// Wrapper so that we can spy on registerPingHandler in tests
converse.registerPingHandler();
};
converse.on('connected', onConnected);
converse.on('reconnected', onConnected);
}
});
}));
......@@ -11326,15 +11443,18 @@ return parser;
return true;
};
converse.shouldNotifyOfMessage = function ($message) {
converse.shouldNotifyOfMessage = function (message) {
/* Is this a message worthy of notification?
*/
var $forwarded = $message.find('forwarded');
var $message = $(message),
$forwarded = $message.find('forwarded');
if ($forwarded.length) {
return false;
}
if ($message.attr('type') === 'groupchat') {
} else if ($message.attr('type') === 'groupchat') {
return converse.shouldNotifyOfGroupMessage($message);
} else if (utils.isHeadlineMessage(message)) {
// We want to show notifications for headline messages.
return true;
}
var is_me = Strophe.getBareJidFromJid($message.attr('from')) === converse.bare_jid;
return !converse.isOnlyChatStateNotification($message) && !is_me;
......@@ -11373,9 +11493,22 @@ return parser;
/* Shows an HTML5 Notification to indicate that a new chat
* message was received.
*/
var contact_jid = Strophe.getBareJidFromJid($message.attr('from'));
var roster_item = converse.roster.get(contact_jid);
var n = new Notification(__(___("%1$s says"), roster_item.get('fullname')), {
var n, title, contact_jid, roster_item,
from_jid = $message.attr('from');
if ($message.attr('type') === 'headline' || from_jid.indexOf('@') === -1) {
// XXX: 2nd check is workaround for Prosody which doesn't
// give type "headline"
title = __(___("Notification from %1$s"), from_jid);
} else {
if (typeof converse.roster === 'undefined') {
converse.log("Could not send notification, because roster is undefined", "error");
return;
}
contact_jid = Strophe.getBareJidFromJid($message.attr('from'));
roster_item = converse.roster.get(contact_jid);
title = __(___("%1$s says"), roster_item.get('fullname'));
}
n = new Notification(title, {
body: $message.children('body').text(),
lang: converse.i18n.locale_data.converse[""].lang,
icon: converse.notification_icon
......@@ -11387,7 +11520,7 @@ return parser;
/* Creates an HTML5 Notification to inform of a change in a
* contact's chat state.
*/
if (_.contains(converse.chatstate_notification_blacklist, contact.get('jid'))) {
if (_.contains(converse.chatstate_notification_blacklist, contact.jid)) {
// Don't notify if the user is being ignored.
return;
}
......@@ -11437,7 +11570,7 @@ return parser;
* to play sounds and show HTML5 notifications.
*/
var $message = $(message);
if (!converse.shouldNotifyOfMessage($message)) {
if (!converse.shouldNotifyOfMessage(message)) {
return false;
}
converse.playSoundNotification($message);
......@@ -11474,25 +11607,115 @@ return parser;
// Copyright (c) 2012-2016, Jan-Carel Brand <jc@opkode.com>
// Licensed under the Mozilla Public License (MPLv2)
//
/*global define */
/*global define, window */
(function (root, factory) {
define("converse-headline", [
"converse-core",
"converse-api",
// TODO: remove this dependency
"converse-chatview"
], factory);
}(this, function (converse, converse_api) {
"use strict";
var $ = converse_api.env.jQuery,
_ = converse_api.env._,
utils = converse_api.env.utils,
__ = utils.__.bind(converse);
var onHeadlineMessage = function (message) {
/* Handler method for all incoming messages of type "headline".
*/
var $message = $(message),
from_jid = $message.attr('from');
if (utils.isHeadlineMessage(message)) {
converse.chatboxes.create({
'id': from_jid,
'jid': from_jid,
'fullname': from_jid,
'type': 'headline'
}).createMessage($message);
converse.emit('message', message);
}
return true;
};
converse_api.plugins.add('headline', {
overrides: {
// Overrides mentioned here will be picked up by converse.js's
// plugin architecture they will replace existing methods on the
// relevant objects or classes.
//
// New functions which don't exist yet can also be added.
ChatBoxViews: {
onChatBoxAdded: function (item) {
var view = this.get(item.get('id'));
if (!view && item.get('type') === 'headline') {
view = new converse.HeadlinesBoxView({model: item});
this.add(item.get('id'), view);
return view;
} else {
return this._super.onChatBoxAdded.apply(this, arguments);
}
}
}
},
initialize: function () {
/* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery.
*/
// TODO
converse.HeadlinesBoxView = converse.ChatBoxView.extend({
className: 'chatbox headlines',
events: {
'click .close-chatbox-button': 'close',
'click .toggle-chatbox-button': 'minimize',
'keypress textarea.chat-textarea': 'keyPressed',
'mousedown .dragresize-top': 'onStartVerticalResize',
'mousedown .dragresize-left': 'onStartHorizontalResize',
'mousedown .dragresize-topleft': 'onStartDiagonalResize'
},
initialize: function () {
$(window).on('resize', _.debounce(this.setDimensions.bind(this), 100));
this.model.messages.on('add', this.onMessageAdded, this);
this.model.on('show', this.show, this);
this.model.on('destroy', this.hide, this);
this.model.on('change:minimized', this.onMinimizedChanged, this);
this.render().fetchMessages().insertIntoPage().hide();
converse.emit('chatBoxInitialized', this);
},
render: function () {
this.$el.attr('id', this.model.get('box_id'))
.html(converse.templates.chatbox(
_.extend(this.model.toJSON(), {
show_toolbar: converse.show_toolbar,
show_textarea: false,
title: this.model.get('fullname'),
info_close: __('Close this box'),
info_minimize: __('Minimize this box'),
label_personal_message: ''
}
)
)
);
this.setWidth();
this.$content = this.$el.find('.chat-content');
converse.emit('chatBoxOpened', this);
window.setTimeout(utils.refreshWebkit, 50);
return this;
},
});
var registerHeadlineHandler = function () {
converse.connection.addHandler(
onHeadlineMessage, null, 'message');
};
converse.on('connected', registerHeadlineHandler);
converse.on('reconnected', registerHeadlineHandler);
}
});
}));
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment