(WIP) Wait for promises before opening chats in API methods
This commit is contained in:
parent
4115461409
commit
1443fdd447
272
dist/converse.js
vendored
272
dist/converse.js
vendored
|
@ -36,34 +36,19 @@
|
|||
/******/ // define getter function for harmony exports
|
||||
/******/ __webpack_require__.d = function(exports, name, getter) {
|
||||
/******/ if(!__webpack_require__.o(exports, name)) {
|
||||
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
|
||||
/******/ Object.defineProperty(exports, name, {
|
||||
/******/ configurable: false,
|
||||
/******/ enumerable: true,
|
||||
/******/ get: getter
|
||||
/******/ });
|
||||
/******/ }
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // define __esModule on exports
|
||||
/******/ __webpack_require__.r = function(exports) {
|
||||
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
||||
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
||||
/******/ }
|
||||
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // create a fake namespace object
|
||||
/******/ // mode & 1: value is a module id, require it
|
||||
/******/ // mode & 2: merge all properties of value into the ns
|
||||
/******/ // mode & 4: return value when already ns object
|
||||
/******/ // mode & 8|1: behave like require
|
||||
/******/ __webpack_require__.t = function(value, mode) {
|
||||
/******/ if(mode & 1) value = __webpack_require__(value);
|
||||
/******/ if(mode & 8) return value;
|
||||
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
|
||||
/******/ var ns = Object.create(null);
|
||||
/******/ __webpack_require__.r(ns);
|
||||
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
|
||||
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
|
||||
/******/ return ns;
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
||||
/******/ __webpack_require__.n = function(module) {
|
||||
/******/ var getter = module && module.__esModule ?
|
||||
|
@ -2575,7 +2560,13 @@ backbone.nativeview = __webpack_require__(/*! backbone.nativeview */ "./node_mod
|
|||
if (_.isFunction(this.beforeRender)) {
|
||||
this.beforeRender();
|
||||
}
|
||||
const new_vnode = tovnode.toVNode(parseHTMLToDOM(this.toHTML()));
|
||||
let new_vnode;
|
||||
if (!_.isNil(this.toHTML)) {
|
||||
new_vnode = tovnode.toVNode(parseHTMLToDOM(this.toHTML()));
|
||||
} else {
|
||||
new_vnode = tovnode.toVNode(this.toDOM());
|
||||
}
|
||||
|
||||
new_vnode.data.hook = _.extend({
|
||||
create: this.updateEventListeners.bind(this),
|
||||
update: this.updateEventListeners.bind(this)
|
||||
|
@ -4529,7 +4520,7 @@ backbone.nativeview = __webpack_require__(/*! backbone.nativeview */ "./node_mod
|
|||
/*! no static exports found */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
/* WEBPACK VAR INJECTION */(function(global) {var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// Native Javascript for Bootstrap 4 v2.0.22 | © dnp_theme | MIT-License
|
||||
/* WEBPACK VAR INJECTION */(function(global) {var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// Native Javascript for Bootstrap 4 v2.0.23 | © dnp_theme | MIT-License
|
||||
(function (root, factory) {
|
||||
if (true) {
|
||||
// AMD support:
|
||||
|
@ -4612,7 +4603,7 @@ backbone.nativeview = __webpack_require__(/*! backbone.nativeview */ "./node_mod
|
|||
clickEvent = 'click',
|
||||
hoverEvent = 'hover',
|
||||
keydownEvent = 'keydown',
|
||||
keyupEvent = 'keyup',
|
||||
keyupEvent = 'keyup',
|
||||
resizeEvent = 'resize',
|
||||
scrollEvent = 'scroll',
|
||||
// originalEvents
|
||||
|
@ -4632,18 +4623,20 @@ backbone.nativeview = __webpack_require__(/*! backbone.nativeview */ "./node_mod
|
|||
hasAttribute = 'hasAttribute',
|
||||
createElement = 'createElement',
|
||||
appendChild = 'appendChild',
|
||||
innerHTML = 'innerHTML',
|
||||
innerHTML = 'innerHTML',
|
||||
getElementsByTagName = 'getElementsByTagName',
|
||||
preventDefault = 'preventDefault',
|
||||
getBoundingClientRect = 'getBoundingClientRect',
|
||||
querySelectorAll = 'querySelectorAll',
|
||||
getElementsByCLASSNAME = 'getElementsByClassName',
|
||||
getComputedStyle = 'getComputedStyle',
|
||||
|
||||
indexOf = 'indexOf',
|
||||
parentNode = 'parentNode',
|
||||
length = 'length',
|
||||
toLowerCase = 'toLowerCase',
|
||||
Transition = 'Transition',
|
||||
Duration = 'Duration',
|
||||
Webkit = 'Webkit',
|
||||
style = 'style',
|
||||
push = 'push',
|
||||
|
@ -4663,15 +4656,16 @@ backbone.nativeview = __webpack_require__(/*! backbone.nativeview */ "./node_mod
|
|||
// tooltip / popover
|
||||
mouseHover = ('onmouseleave' in DOC) ? [ 'mouseenter', 'mouseleave'] : [ 'mouseover', 'mouseout' ],
|
||||
tipPositions = /\b(top|bottom|left|right)+/,
|
||||
|
||||
|
||||
// modal
|
||||
modalOverlay = 0,
|
||||
fixedTop = 'fixed-top',
|
||||
fixedBottom = 'fixed-bottom',
|
||||
|
||||
|
||||
// transitionEnd since 2.0.4
|
||||
supportTransitions = Webkit+Transition in HTML[style] || Transition[toLowerCase]() in HTML[style],
|
||||
transitionEndEvent = Webkit+Transition in HTML[style] ? Webkit[toLowerCase]()+Transition+'End' : Transition[toLowerCase]()+'end',
|
||||
transitionDuration = Webkit+Duration in HTML[style] ? Webkit[toLowerCase]()+Transition+Duration : Transition[toLowerCase]()+Duration,
|
||||
|
||||
// set new focus element since 2.0.3
|
||||
setFocus = function(element){
|
||||
|
@ -4725,9 +4719,16 @@ backbone.nativeview = __webpack_require__(/*! backbone.nativeview */ "./node_mod
|
|||
off(element, event, handlerWrapper);
|
||||
});
|
||||
},
|
||||
getTransitionDurationFromElement = function(element) {
|
||||
var duration = globalObject[getComputedStyle](element)[transitionDuration];
|
||||
duration = parseFloat(duration);
|
||||
duration = typeof duration === 'number' && !isNaN(duration) ? duration * 1000 : 0;
|
||||
return duration + 50; // we take a short offset to make sure we fire on the next frame after animation
|
||||
},
|
||||
emulateTransitionEnd = function(element,handler){ // emulateTransitionEnd since 2.0.4
|
||||
if (supportTransitions) { one(element, transitionEndEvent, function(e){ handler(e); }); }
|
||||
else { handler(); }
|
||||
var called = 0, duration = getTransitionDurationFromElement(element);
|
||||
supportTransitions && one(element, transitionEndEvent, function(e){ handler(e); called = 1; });
|
||||
setTimeout(function() { !called && handler(); }, duration);
|
||||
},
|
||||
bootstrapCustomEvent = function (eventName, componentName, related) {
|
||||
var OriginalCustomEvent = new CustomEvent( eventName + '.bs.' + componentName);
|
||||
|
@ -4750,8 +4751,8 @@ backbone.nativeview = __webpack_require__(/*! backbone.nativeview */ "./node_mod
|
|||
scroll = parent === DOC[body] ? getScroll() : { x: parent[offsetLeft] + parent[scrollLeft], y: parent[offsetTop] + parent[scrollTop] },
|
||||
linkDimensions = { w: rect[right] - rect[left], h: rect[bottom] - rect[top] },
|
||||
isPopover = hasClass(element,'popover'),
|
||||
topPosition, leftPosition,
|
||||
|
||||
topPosition, leftPosition,
|
||||
|
||||
arrow = queryElement('.arrow',element),
|
||||
arrowTop, arrowLeft, arrowWidth, arrowHeight,
|
||||
|
||||
|
@ -4770,7 +4771,7 @@ backbone.nativeview = __webpack_require__(/*! backbone.nativeview */ "./node_mod
|
|||
position = position === bottom && bottomExceed ? top : position;
|
||||
position = position === left && leftExceed ? right : position;
|
||||
position = position === right && rightExceed ? left : position;
|
||||
|
||||
|
||||
// update tooltip/popover class
|
||||
element.className[indexOf](position) === -1 && (element.className = element.className.replace(tipPositions,position));
|
||||
|
||||
|
@ -4823,7 +4824,7 @@ backbone.nativeview = __webpack_require__(/*! backbone.nativeview */ "./node_mod
|
|||
arrowLeft && (arrow[style][left] = arrowLeft + 'px');
|
||||
};
|
||||
|
||||
BSN.version = '2.0.22';
|
||||
BSN.version = '2.0.23';
|
||||
|
||||
/* Native Javascript for Bootstrap 4 | Alert
|
||||
-------------------------------------------*/
|
||||
|
@ -4993,7 +4994,7 @@ backbone.nativeview = __webpack_require__(/*! backbone.nativeview */ "./node_mod
|
|||
// DATA API
|
||||
var intervalAttribute = element[getAttribute](dataInterval),
|
||||
intervalOption = options[interval],
|
||||
intervalData = intervalAttribute === 'false' ? 0 : parseInt(intervalAttribute) || 5000, // bootstrap carousel default interval
|
||||
intervalData = intervalAttribute === 'false' ? 0 : parseInt(intervalAttribute),
|
||||
pauseData = element[getAttribute](dataPause) === hoverEvent || false,
|
||||
keyboardData = element[getAttribute](dataKeyboard) === 'true' || false,
|
||||
|
||||
|
@ -5008,8 +5009,8 @@ backbone.nativeview = __webpack_require__(/*! backbone.nativeview */ "./node_mod
|
|||
this[pause] = (options[pause] === hoverEvent || pauseData) ? hoverEvent : false; // false / hover
|
||||
|
||||
this[interval] = typeof intervalOption === 'number' ? intervalOption
|
||||
: intervalData === 0 ? 0
|
||||
: intervalData;
|
||||
: intervalOption === false || intervalData === 0 || intervalData === false ? 0
|
||||
: 5000; // bootstrap carousel default interval
|
||||
|
||||
// bind, event targets
|
||||
var self = this, index = element.index = 0, timer = element.timer = 0,
|
||||
|
@ -5128,10 +5129,10 @@ backbone.nativeview = __webpack_require__(/*! backbone.nativeview */ "./node_mod
|
|||
addClass(slides[next],carouselItem +'-'+ slideDirection);
|
||||
addClass(slides[activeItem],carouselItem +'-'+ slideDirection);
|
||||
|
||||
one(slides[activeItem], transitionEndEvent, function(e) {
|
||||
var timeout = e[target] !== slides[activeItem] ? e.elapsedTime*1000 : 0;
|
||||
one(slides[next], transitionEndEvent, function(e) {
|
||||
var timeout = e[target] !== slides[next] ? e.elapsedTime*1000+100 : 20;
|
||||
|
||||
setTimeout(function(){
|
||||
isSliding && setTimeout(function(){
|
||||
isSliding = false;
|
||||
|
||||
addClass(slides[next],active);
|
||||
|
@ -5146,7 +5147,7 @@ backbone.nativeview = __webpack_require__(/*! backbone.nativeview */ "./node_mod
|
|||
if ( !DOC.hidden && self[interval] && !hasClass(element,paused) ) {
|
||||
self.cycle();
|
||||
}
|
||||
},timeout+100);
|
||||
}, timeout);
|
||||
});
|
||||
|
||||
} else {
|
||||
|
@ -5211,23 +5212,24 @@ backbone.nativeview = __webpack_require__(/*! backbone.nativeview */ "./node_mod
|
|||
|
||||
// event targets and constants
|
||||
var accordion = null, collapse = null, self = this,
|
||||
isAnimating = false, // when true it will prevent click handlers
|
||||
accordionData = element[getAttribute]('data-parent'),
|
||||
activeCollapse, activeElement,
|
||||
|
||||
// component strings
|
||||
component = 'collapse',
|
||||
collapsed = 'collapsed',
|
||||
isAnimating = 'isAnimating',
|
||||
|
||||
// private methods
|
||||
openAction = function(collapseElement,toggle) {
|
||||
bootstrapCustomEvent.call(collapseElement, showEvent, component);
|
||||
isAnimating = true;
|
||||
collapseElement[isAnimating] = true;
|
||||
addClass(collapseElement,collapsing);
|
||||
removeClass(collapseElement,component);
|
||||
collapseElement[style][height] = collapseElement[scrollHeight] + 'px';
|
||||
|
||||
emulateTransitionEnd(collapseElement, function() {
|
||||
isAnimating = false;
|
||||
collapseElement[isAnimating] = false;
|
||||
collapseElement[setAttribute](ariaExpanded,'true');
|
||||
toggle[setAttribute](ariaExpanded,'true');
|
||||
removeClass(collapseElement,collapsing);
|
||||
|
@ -5239,7 +5241,7 @@ backbone.nativeview = __webpack_require__(/*! backbone.nativeview */ "./node_mod
|
|||
},
|
||||
closeAction = function(collapseElement,toggle) {
|
||||
bootstrapCustomEvent.call(collapseElement, hideEvent, component);
|
||||
isAnimating = true;
|
||||
collapseElement[isAnimating] = true;
|
||||
collapseElement[style][height] = collapseElement[scrollHeight] + 'px'; // set height first
|
||||
removeClass(collapseElement,component);
|
||||
removeClass(collapseElement,showClass);
|
||||
|
@ -5248,7 +5250,7 @@ backbone.nativeview = __webpack_require__(/*! backbone.nativeview */ "./node_mod
|
|||
collapseElement[style][height] = '0px';
|
||||
|
||||
emulateTransitionEnd(collapseElement, function() {
|
||||
isAnimating = false;
|
||||
collapseElement[isAnimating] = false;
|
||||
collapseElement[setAttribute](ariaExpanded,'false');
|
||||
toggle[setAttribute](ariaExpanded,'false');
|
||||
removeClass(collapseElement,collapsing);
|
||||
|
@ -5267,29 +5269,29 @@ backbone.nativeview = __webpack_require__(/*! backbone.nativeview */ "./node_mod
|
|||
// public methods
|
||||
this.toggle = function(e) {
|
||||
e[preventDefault]();
|
||||
if (isAnimating) return;
|
||||
if (!hasClass(collapse,showClass)) { self.show(); }
|
||||
else { self.hide(); }
|
||||
};
|
||||
this.hide = function() {
|
||||
if ( collapse[isAnimating] ) return;
|
||||
closeAction(collapse,element);
|
||||
addClass(element,collapsed);
|
||||
};
|
||||
this.show = function() {
|
||||
if ( accordion ) {
|
||||
var activeCollapse = queryElement('.'+component+'.'+showClass,accordion),
|
||||
toggle = activeCollapse && (queryElement('['+dataToggle+'="'+component+'"]['+dataTarget+'="#'+activeCollapse.id+'"]',accordion)
|
||||
|| queryElement('['+dataToggle+'="'+component+'"][href="#'+activeCollapse.id+'"]',accordion) ),
|
||||
correspondingCollapse = toggle && (toggle[getAttribute](dataTarget) || toggle.href);
|
||||
if ( activeCollapse && toggle && activeCollapse !== collapse ) {
|
||||
closeAction(activeCollapse,toggle);
|
||||
if ( correspondingCollapse.split('#')[1] !== collapse.id ) { addClass(toggle,collapsed); }
|
||||
else { removeClass(toggle,collapsed); }
|
||||
}
|
||||
activeCollapse = queryElement('.'+component+'.'+showClass,accordion);
|
||||
activeElement = activeCollapse && (queryElement('['+dataToggle+'="'+component+'"]['+dataTarget+'="#'+activeCollapse.id+'"]',accordion)
|
||||
|| queryElement('['+dataToggle+'="'+component+'"][href="#'+activeCollapse.id+'"]',accordion) );
|
||||
}
|
||||
|
||||
openAction(collapse,element);
|
||||
removeClass(element,collapsed);
|
||||
if ( !collapse[isAnimating] || activeCollapse && !activeCollapse[isAnimating] ) {
|
||||
if ( activeElement && activeCollapse !== collapse ) {
|
||||
closeAction(activeCollapse,activeElement);
|
||||
addClass(activeElement,collapsed);
|
||||
}
|
||||
openAction(collapse,element);
|
||||
removeClass(element,collapsed);
|
||||
}
|
||||
};
|
||||
|
||||
// init
|
||||
|
@ -5297,6 +5299,7 @@ backbone.nativeview = __webpack_require__(/*! backbone.nativeview */ "./node_mod
|
|||
on(element, clickEvent, self.toggle);
|
||||
}
|
||||
collapse = getTarget();
|
||||
collapse[isAnimating] = false; // when true it will prevent click handlers
|
||||
accordion = queryElement(options.parent) || accordionData && getClosest(element, accordionData);
|
||||
element[stringCollapse] = self;
|
||||
};
|
||||
|
@ -5454,6 +5457,7 @@ backbone.nativeview = __webpack_require__(/*! backbone.nativeview */ "./node_mod
|
|||
var btnCheck = element[getAttribute](dataTarget)||element[getAttribute]('href'),
|
||||
checkModal = queryElement( btnCheck ),
|
||||
modal = hasClass(element,'modal') ? element : checkModal,
|
||||
overlayDelay,
|
||||
|
||||
// strings
|
||||
component = 'modal',
|
||||
|
@ -5487,13 +5491,13 @@ backbone.nativeview = __webpack_require__(/*! backbone.nativeview */ "./node_mod
|
|||
return globalObject[innerWidth] || (htmlRect[right] - Math.abs(htmlRect[left]));
|
||||
},
|
||||
setScrollbar = function () {
|
||||
var bodyStyle = globalObject.getComputedStyle(DOC[body]),
|
||||
var bodyStyle = globalObject[getComputedStyle](DOC[body]),
|
||||
bodyPad = parseInt((bodyStyle[paddingRight]), 10), itemPad;
|
||||
if (bodyIsOverflowing) {
|
||||
DOC[body][style][paddingRight] = (bodyPad + scrollbarWidth) + 'px';
|
||||
if (fixedItems[length]){
|
||||
for (var i = 0; i < fixedItems[length]; i++) {
|
||||
itemPad = globalObject.getComputedStyle(fixedItems[i])[paddingRight];
|
||||
itemPad = globalObject[getComputedStyle](fixedItems[i])[paddingRight];
|
||||
fixedItems[i][style][paddingRight] = ( parseInt(itemPad) + scrollbarWidth) + 'px';
|
||||
}
|
||||
}
|
||||
|
@ -5635,6 +5639,7 @@ backbone.nativeview = __webpack_require__(/*! backbone.nativeview */ "./node_mod
|
|||
|
||||
if ( overlay && modalOverlay && !hasClass(overlay,showClass)) {
|
||||
overlay[offsetWidth]; // force reflow to enable trasition
|
||||
overlayDelay = getTransitionDurationFromElement(overlay);
|
||||
addClass(overlay, showClass);
|
||||
}
|
||||
|
||||
|
@ -5654,18 +5659,19 @@ backbone.nativeview = __webpack_require__(/*! backbone.nativeview */ "./node_mod
|
|||
keydownHandlerToggle();
|
||||
|
||||
hasClass(modal,'fade') ? emulateTransitionEnd(modal, triggerShow) : triggerShow();
|
||||
}, supportTransitions ? 150 : 0);
|
||||
}, supportTransitions && overlay ? overlayDelay : 0);
|
||||
};
|
||||
this.hide = function() {
|
||||
bootstrapCustomEvent.call(modal, hideEvent, component);
|
||||
overlay = queryElement('.'+modalBackdropString);
|
||||
overlayDelay = overlay && getTransitionDurationFromElement(overlay);
|
||||
|
||||
removeClass(modal,showClass);
|
||||
modal[setAttribute](ariaHidden, true);
|
||||
|
||||
(function(){
|
||||
setTimeout(function(){
|
||||
hasClass(modal,'fade') ? emulateTransitionEnd(modal, triggerHide) : triggerHide();
|
||||
}());
|
||||
}, supportTransitions && overlay ? overlayDelay : 0);
|
||||
};
|
||||
this.setContent = function( content ) {
|
||||
queryElement('.'+component+'-content',modal)[innerHTML] = content;
|
||||
|
@ -6021,7 +6027,7 @@ backbone.nativeview = __webpack_require__(/*! backbone.nativeview */ "./node_mod
|
|||
tabsContentContainer[style][height] = nextHeight + 'px'; // height animation
|
||||
tabsContentContainer[offsetWidth];
|
||||
emulateTransitionEnd(tabsContentContainer, triggerEnd);
|
||||
},1);
|
||||
},50);
|
||||
}
|
||||
} else {
|
||||
tabs[isAnimating] = false;
|
||||
|
@ -6048,7 +6054,7 @@ backbone.nativeview = __webpack_require__(/*! backbone.nativeview */ "./node_mod
|
|||
tabsContentContainer[style][height] = containerHeight + 'px'; // height animation
|
||||
tabsContentContainer[offsetHeight];
|
||||
activeContent[style][float] = '';
|
||||
nextContent[style][float] = '';
|
||||
nextContent[style][float] = '';
|
||||
}
|
||||
|
||||
if ( hasClass(nextContent, 'fade') ) {
|
||||
|
@ -33088,12 +33094,13 @@ var map = {
|
|||
|
||||
function webpackContext(req) {
|
||||
var id = webpackContextResolve(req);
|
||||
return __webpack_require__(id);
|
||||
var module = __webpack_require__(id);
|
||||
return module;
|
||||
}
|
||||
function webpackContextResolve(req) {
|
||||
var id = map[req];
|
||||
if(!(id + 1)) { // check for number or string
|
||||
var e = new Error("Cannot find module '" + req + "'");
|
||||
var e = new Error('Cannot find module "' + req + '".');
|
||||
e.code = 'MODULE_NOT_FOUND';
|
||||
throw e;
|
||||
}
|
||||
|
@ -65863,26 +65870,26 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|||
/*! no static exports found */
|
||||
/***/ (function(module, exports) {
|
||||
|
||||
var g;
|
||||
|
||||
// This works in non-strict mode
|
||||
g = (function() {
|
||||
return this;
|
||||
})();
|
||||
|
||||
try {
|
||||
// This works if eval is allowed (see CSP)
|
||||
g = g || Function("return this")() || (1, eval)("this");
|
||||
} catch (e) {
|
||||
// This works if the window reference is available
|
||||
if (typeof window === "object") g = window;
|
||||
}
|
||||
|
||||
// g can still be undefined, but nothing to do about it...
|
||||
// We return undefined, instead of nothing here, so it's
|
||||
// easier to handle this case. if(!global) { ...}
|
||||
|
||||
module.exports = g;
|
||||
var g;
|
||||
|
||||
// This works in non-strict mode
|
||||
g = (function() {
|
||||
return this;
|
||||
})();
|
||||
|
||||
try {
|
||||
// This works if eval is allowed (see CSP)
|
||||
g = g || Function("return this")() || (1, eval)("this");
|
||||
} catch (e) {
|
||||
// This works if the window reference is available
|
||||
if (typeof window === "object") g = window;
|
||||
}
|
||||
|
||||
// g can still be undefined, but nothing to do about it...
|
||||
// We return undefined, instead of nothing here, so it's
|
||||
// easier to handle this case. if(!global) { ...}
|
||||
|
||||
module.exports = g;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
@ -65894,28 +65901,28 @@ module.exports = g;
|
|||
/*! no static exports found */
|
||||
/***/ (function(module, exports) {
|
||||
|
||||
module.exports = function(module) {
|
||||
if (!module.webpackPolyfill) {
|
||||
module.deprecate = function() {};
|
||||
module.paths = [];
|
||||
// module.parent = undefined by default
|
||||
if (!module.children) module.children = [];
|
||||
Object.defineProperty(module, "loaded", {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return module.l;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(module, "id", {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return module.i;
|
||||
}
|
||||
});
|
||||
module.webpackPolyfill = 1;
|
||||
}
|
||||
return module;
|
||||
};
|
||||
module.exports = function(module) {
|
||||
if (!module.webpackPolyfill) {
|
||||
module.deprecate = function() {};
|
||||
module.paths = [];
|
||||
// module.parent = undefined by default
|
||||
if (!module.children) module.children = [];
|
||||
Object.defineProperty(module, "loaded", {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return module.l;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(module, "id", {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return module.i;
|
||||
}
|
||||
});
|
||||
module.webpackPolyfill = 1;
|
||||
}
|
||||
return module;
|
||||
};
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
@ -68354,9 +68361,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|||
return _converse.log(`Invalid JID "${jid}" provided in URL fragment`, Strophe.LogLevel.WARN);
|
||||
}
|
||||
|
||||
Promise.all([_converse.api.waitUntil('rosterContactsFetched'), _converse.api.waitUntil('chatBoxesFetched')]).then(() => {
|
||||
_converse.api.chats.open(jid);
|
||||
});
|
||||
_converse.api.chats.open(jid);
|
||||
}
|
||||
|
||||
_converse.router.route('converse/chat?jid=:jid', openChat);
|
||||
|
@ -69279,18 +69284,21 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|||
},
|
||||
|
||||
'open'(jids, attrs) {
|
||||
if (_.isUndefined(jids)) {
|
||||
_converse.log("chats.open: You need to provide at least one JID", Strophe.LogLevel.ERROR);
|
||||
return new Promise((resolve, reject) => {
|
||||
Promise.all([_converse.api.waitUntil('rosterContactsFetched'), _converse.api.waitUntil('chatBoxesFetched')]).then(() => {
|
||||
if (_.isUndefined(jids)) {
|
||||
const err_msg = "chats.open: You need to provide at least one JID";
|
||||
|
||||
return null;
|
||||
} else if (_.isString(jids)) {
|
||||
const chatbox = _converse.api.chats.create(jids, attrs);
|
||||
_converse.log(err_msg, Strophe.LogLevel.ERROR);
|
||||
|
||||
chatbox.trigger('show');
|
||||
return chatbox;
|
||||
}
|
||||
|
||||
return _.map(jids, jid => _converse.api.chats.create(jid, attrs).trigger('show'));
|
||||
reject(new Error(err_msg));
|
||||
} else if (_.isString(jids)) {
|
||||
resolve(_converse.api.chats.create(jids, attrs).trigger('show'));
|
||||
} else {
|
||||
resolve(_.map(jids, jid => _converse.api.chats.create(jid, attrs).trigger('show')));
|
||||
}
|
||||
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
|
||||
});
|
||||
},
|
||||
|
||||
'get'(jids) {
|
||||
|
@ -73835,8 +73843,8 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|||
throw new Error("converse-embedded: auto_join_rooms must be an Array");
|
||||
}
|
||||
|
||||
if (_converse.auto_join_rooms.length !== 1 && _converse.auto_join_private_chats.length !== 1) {
|
||||
throw new Error("converse-embedded: It doesn't make " + "sense to have the auto_join_rooms setting to zero or " + "more then one, since only one chat room can be open " + "at any time.");
|
||||
if (_converse.auto_join_rooms.length > 1 && _converse.auto_join_private_chats.length > 1) {
|
||||
throw new Error("converse-embedded: It doesn't make " + "sense to have the auto_join_rooms setting more then one, " + "since only one chat room can be open at any time.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79019,13 +79027,21 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|||
},
|
||||
|
||||
'open'(jids, attrs) {
|
||||
if (_.isUndefined(jids)) {
|
||||
throw new TypeError('rooms.open: You need to provide at least one JID');
|
||||
} else if (_.isString(jids)) {
|
||||
return _converse.api.rooms.create(jids, attrs).trigger('show');
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
_converse.api.waitUntil('chatBoxesFetched').then(() => {
|
||||
if (_.isUndefined(jids)) {
|
||||
const err_msg = 'rooms.open: You need to provide at least one JID';
|
||||
|
||||
return _.map(jids, jid => _converse.api.rooms.create(jid, attrs).trigger('show'));
|
||||
_converse.log(err_msg, Strophe.LogLevel.ERROR);
|
||||
|
||||
reject(new TypeError(err_msg));
|
||||
} else if (_.isString(jids)) {
|
||||
resolve(_converse.api.rooms.create(jids, attrs).trigger('show'));
|
||||
} else {
|
||||
resolve(_.map(jids, jid => _converse.api.rooms.create(jid, attrs).trigger('show')));
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
'get'(jids, attrs, create) {
|
||||
|
|
|
@ -816,86 +816,75 @@ Note, for MUC chatrooms, you need to use the "rooms" grouping instead.
|
|||
get
|
||||
~~~
|
||||
|
||||
Returns an object representing a chatbox. The chatbox should already be open.
|
||||
Returns an object representing a chat. The chat should already be open.
|
||||
|
||||
To return a single chatbox, provide the JID of the contact you're chatting
|
||||
with in that chatbox:
|
||||
To return a single chat, provide the JID of the contact you're chatting
|
||||
with in that chat:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
_converse.api.chats.get('buddy@example.com')
|
||||
|
||||
To return an array of chatboxes, provide an array of JIDs:
|
||||
To return an array of chats, provide an array of JIDs:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
_converse.api.chats.get(['buddy1@example.com', 'buddy2@example.com'])
|
||||
|
||||
To return all open chatboxes, call the method without any JIDs::
|
||||
To return all open chats, call the method without any JIDs::
|
||||
|
||||
_converse.api.chats.get()
|
||||
|
||||
open
|
||||
~~~~
|
||||
|
||||
Opens a chatbox and returns a `Backbone.View <http://backbonejs.org/#View>`_ object
|
||||
representing a chatbox.
|
||||
Opens a new chat.
|
||||
|
||||
It returns an promise which will resolve with a `Backbone.Model <https://backbonejs.org/#Model>`_ representing the chat.
|
||||
|
||||
Note that converse doesn't allow opening chats with users who aren't in your roster
|
||||
(unless you have set :ref:`allow_non_roster_messaging` to ``true``).
|
||||
|
||||
Before opening a chat, you should first wait until the roster has been populated.
|
||||
This is the :ref:`rosterContactsFetched` event/promise.
|
||||
|
||||
Besides that, it's a good idea to also first wait until already opened chatboxes
|
||||
(which are cached in sessionStorage) have also been fetched from the cache.
|
||||
This is the :ref:`chatBoxesFetched` event/promise.
|
||||
|
||||
These two events fire only once per session, so they're also available as promises.
|
||||
|
||||
So, to open a single chatbox:
|
||||
So, to open a single chat:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
converse.plugins.add('myplugin', {
|
||||
initialize: function() {
|
||||
var _converse = this._converse;
|
||||
Promise.all([
|
||||
_converse.api.waitUntil('rosterContactsFetched'),
|
||||
_converse.api.waitUntil('chatBoxesFetched')
|
||||
]).then(function() {
|
||||
initialize: function() {
|
||||
var _converse = this._converse;
|
||||
|
||||
// Note, buddy@example.org must be in your contacts roster!
|
||||
_converse.api.chats.open('buddy@example.com')
|
||||
});
|
||||
}
|
||||
_converse.api.chats.open('buddy@example.com').then((chat) => {
|
||||
// Now you can do something with the chat model
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
To return an array of chatboxes, provide an array of JIDs:
|
||||
To return an array of chats, provide an array of JIDs:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
converse.plugins.add('myplugin', {
|
||||
initialize: function () {
|
||||
var _converse = this._converse;
|
||||
Promise.all([
|
||||
_converse.api.waitUntil('rosterContactsFetched'),
|
||||
_converse.api.waitUntil('chatBoxesFetched')
|
||||
]).then(function() {
|
||||
// Note, these users must first be in your contacts roster!
|
||||
_converse.api.chats.open(['buddy1@example.com', 'buddy2@example.com'])
|
||||
// Note, these users must first be in your contacts roster!
|
||||
_converse.api.chats.open(['buddy1@example.com', 'buddy2@example.com']).then((chats) => {
|
||||
// Now you can do something with the chat models
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
*The returned chatbox object contains the following methods:*
|
||||
*The returned chat object contains the following methods:*
|
||||
|
||||
+-------------------+------------------------------------------+
|
||||
| Method | Description |
|
||||
+===================+==========================================+
|
||||
| close | Close the chatbox. |
|
||||
| close | Close the chat. |
|
||||
+-------------------+------------------------------------------+
|
||||
| focus | Focuses the chatbox textarea |
|
||||
| focus | Focuses the chat textarea |
|
||||
+-------------------+------------------------------------------+
|
||||
| model.endOTR | End an OTR (Off-the-record) session. |
|
||||
+-------------------+------------------------------------------+
|
||||
|
@ -903,13 +892,13 @@ To return an array of chatboxes, provide an array of JIDs:
|
|||
+-------------------+------------------------------------------+
|
||||
| model.initiateOTR | Start an OTR (off-the-record) session. |
|
||||
+-------------------+------------------------------------------+
|
||||
| model.maximize | Minimize the chatbox. |
|
||||
| model.maximize | Minimize the chat. |
|
||||
+-------------------+------------------------------------------+
|
||||
| model.minimize | Maximize the chatbox. |
|
||||
| model.minimize | Maximize the chat. |
|
||||
+-------------------+------------------------------------------+
|
||||
| model.set | Set an attribute (i.e. mutator). |
|
||||
+-------------------+------------------------------------------+
|
||||
| show | Opens/shows the chatbox. |
|
||||
| show | Opens/shows the chat. |
|
||||
+-------------------+------------------------------------------+
|
||||
|
||||
*The get and set methods can be used to retrieve and change the following attributes:*
|
||||
|
@ -917,9 +906,9 @@ To return an array of chatboxes, provide an array of JIDs:
|
|||
+-------------+-----------------------------------------------------+
|
||||
| Attribute | Description |
|
||||
+=============+=====================================================+
|
||||
| height | The height of the chatbox. |
|
||||
| height | The height of the chat. |
|
||||
+-------------+-----------------------------------------------------+
|
||||
| url | The URL of the chatbox heading. |
|
||||
| url | The URL of the chat heading. |
|
||||
+-------------+-----------------------------------------------------+
|
||||
|
||||
The **chatviews** grouping
|
||||
|
@ -1014,7 +1003,7 @@ The **rooms** grouping
|
|||
get
|
||||
~~~
|
||||
|
||||
Returns an object representing a multi user chatbox (room).
|
||||
Returns an object representing a multi user chat (room).
|
||||
It takes 3 parameters:
|
||||
|
||||
* the room JID (if not specified, all rooms will be returned).
|
||||
|
@ -1046,7 +1035,7 @@ It takes 3 parameters:
|
|||
open
|
||||
~~~~
|
||||
|
||||
Opens a multi user chatbox and returns an object representing it.
|
||||
Opens a multi user chat and returns an object representing it.
|
||||
Similar to the ``chats.get`` API.
|
||||
|
||||
It takes 2 parameters:
|
||||
|
@ -1055,7 +1044,7 @@ It takes 2 parameters:
|
|||
* A map (object) containing any extra room attributes. For example, if you want
|
||||
to specify the nickname, use ``{'nick': 'bloodninja'}``.
|
||||
|
||||
To open a single multi user chatbox, provide the JID of the room:
|
||||
To open a single multi user chat, provide the JID of the room:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
|
@ -1328,7 +1317,7 @@ Parameters:
|
|||
|
||||
Returns a Promise which results with the VCard data for a particular JID or for
|
||||
a `Backbone.Model` instance which represents an entity with a JID (such as a roster contact,
|
||||
chatbox or chatroom occupant).
|
||||
chat or chatroom occupant).
|
||||
|
||||
If a `Backbone.Model` instance is passed in, then it must have either a `jid`
|
||||
attribute or a `muc_jid` attribute.
|
||||
|
|
6
package-lock.json
generated
6
package-lock.json
generated
|
@ -2978,9 +2978,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"bootstrap.native": {
|
||||
"version": "2.0.22",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap.native/-/bootstrap.native-2.0.22.tgz",
|
||||
"integrity": "sha512-eypi4y1eKJoRt8cTwkZCI3QQ7W04rbv4VU1nBjBshqNXkONI7jO6tG3qZTwq9Zd+gDoeaQASyk6V185y+Y7KHQ==",
|
||||
"version": "2.0.23",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap.native/-/bootstrap.native-2.0.23.tgz",
|
||||
"integrity": "sha512-bcbVgqIjRkyiHd6DN8Y18BYjJTKvvnN3Msb7Yh6K5vGGsjRT3gV0IFKR3rcEYgJ5Kvg1egL9exIfN/Hvwn4wNA==",
|
||||
"dev": true
|
||||
},
|
||||
"bourbon": {
|
||||
|
|
|
@ -19,32 +19,35 @@
|
|||
|
||||
it("has a /help command to show the available commands",
|
||||
mock.initConverseWithPromises(
|
||||
null, ['rosterGroupsFetched'], {},
|
||||
null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
function (done, _converse) {
|
||||
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
test_utils.createContacts(_converse, 'current', 1);
|
||||
_converse.emit('rosterContactsFetched');
|
||||
test_utils.openControlBox();
|
||||
|
||||
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||
test_utils.openChatBoxFor(_converse, contact_jid);
|
||||
var view = _converse.chatboxviews.get(contact_jid);
|
||||
test_utils.sendMessage(view, '/help');
|
||||
test_utils.waitUntil(() => _converse.chatboxes.length == 2).then(() => {
|
||||
var view = _converse.chatboxviews.get(contact_jid);
|
||||
test_utils.sendMessage(view, '/help');
|
||||
|
||||
const info_messages = Array.prototype.slice.call(view.el.querySelectorAll('.chat-info:not(.chat-date)'), 0);
|
||||
expect(info_messages.length).toBe(3);
|
||||
expect(info_messages.pop().textContent).toBe('/help: Show this menu');
|
||||
expect(info_messages.pop().textContent).toBe('/me: Write in the third person');
|
||||
expect(info_messages.pop().textContent).toBe('/clear: Remove messages');
|
||||
const info_messages = Array.prototype.slice.call(view.el.querySelectorAll('.chat-info:not(.chat-date)'), 0);
|
||||
expect(info_messages.length).toBe(3);
|
||||
expect(info_messages.pop().textContent).toBe('/help: Show this menu');
|
||||
expect(info_messages.pop().textContent).toBe('/me: Write in the third person');
|
||||
expect(info_messages.pop().textContent).toBe('/clear: Remove messages');
|
||||
|
||||
var msg = $msg({
|
||||
from: contact_jid,
|
||||
to: _converse.connection.jid,
|
||||
type: 'chat',
|
||||
id: (new Date()).getTime()
|
||||
}).c('body').t('hello world').tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
expect(view.content.lastElementChild.textContent.trim().indexOf('hello world')).not.toBe(-1);
|
||||
done();
|
||||
var msg = $msg({
|
||||
from: contact_jid,
|
||||
to: _converse.connection.jid,
|
||||
type: 'chat',
|
||||
id: (new Date()).getTime()
|
||||
}).c('body').t('hello world').tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
expect(view.content.lastElementChild.textContent.trim().indexOf('hello world')).not.toBe(-1);
|
||||
done();
|
||||
});
|
||||
}));
|
||||
|
||||
|
||||
|
@ -108,38 +111,48 @@
|
|||
});
|
||||
}));
|
||||
|
||||
it("is created when you click on a roster item",
|
||||
mock.initConverseWithPromises(
|
||||
null, ['rosterGroupsFetched'], {},
|
||||
it("is created when you click on a roster item", mock.initConverseWithPromises(
|
||||
null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
function (done, _converse) {
|
||||
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
_converse.emit('rosterContactsFetched');
|
||||
test_utils.openControlBox();
|
||||
|
||||
var i, $el, jid, chatboxview;
|
||||
let jid, online_contacts;
|
||||
// openControlBox was called earlier, so the controlbox is
|
||||
// visible, but no other chat boxes have been created.
|
||||
expect(_converse.chatboxes.length).toEqual(1);
|
||||
spyOn(_converse.chatboxviews, 'trimChats');
|
||||
expect($("#conversejs .chatbox").length).toBe(1); // Controlbox is open
|
||||
expect(document.querySelectorAll("#conversejs .chatbox").length).toBe(1); // Controlbox is open
|
||||
|
||||
test_utils.waitUntil(function () {
|
||||
return $(_converse.rosterview.el).find('.roster-group li').length;
|
||||
}, 700).then(function () {
|
||||
var online_contacts = $(_converse.rosterview.el).find('.roster-group .current-xmpp-contact a.open-chat');
|
||||
test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group li').length, 700).then(function () {
|
||||
online_contacts = _converse.rosterview.el.querySelectorAll('.roster-group .current-xmpp-contact a.open-chat');
|
||||
expect(online_contacts.length).toBe(15);
|
||||
for (i=0; i<online_contacts.length; i++) {
|
||||
$el = $(online_contacts[i]);
|
||||
jid = $el.text().trim().replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||
$el[0].click();
|
||||
chatboxview = _converse.chatboxviews.get(jid);
|
||||
expect(_converse.chatboxes.length).toEqual(i+2);
|
||||
expect(_converse.chatboxviews.trimChats).toHaveBeenCalled();
|
||||
// Check that new chat boxes are created to the left of the
|
||||
// controlbox (but to the right of all existing chat boxes)
|
||||
expect($("#conversejs .chatbox").length).toBe(i+2);
|
||||
expect($("#conversejs .chatbox")[1].id).toBe(chatboxview.model.get('box_id'));
|
||||
}
|
||||
const el = online_contacts[0];
|
||||
jid = el.textContent.trim().replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||
el.click();
|
||||
return test_utils.waitUntil(() => _converse.chatboxes.length == 2);
|
||||
}).then(() => {
|
||||
const chatboxview = _converse.chatboxviews.get(jid);
|
||||
expect(_converse.chatboxviews.trimChats).toHaveBeenCalled();
|
||||
// Check that new chat boxes are created to the left of the
|
||||
// controlbox (but to the right of all existing chat boxes)
|
||||
expect(document.querySelectorAll("#conversejs .chatbox").length).toBe(2);
|
||||
expect(document.querySelectorAll("#conversejs .chatbox")[1].id).toBe(chatboxview.model.get('box_id'));
|
||||
online_contacts[1].click();
|
||||
return test_utils.waitUntil(() => _converse.chatboxes.length == 3);
|
||||
}).then(() => {
|
||||
const el = online_contacts[1];
|
||||
const new_jid = el.textContent.trim().replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||
const chatboxview = _converse.chatboxviews.get(jid);
|
||||
const new_chatboxview = _converse.chatboxviews.get(new_jid);
|
||||
expect(_converse.chatboxviews.trimChats).toHaveBeenCalled();
|
||||
// Check that new chat boxes are created to the left of the
|
||||
// controlbox (but to the right of all existing chat boxes)
|
||||
expect(document.querySelectorAll("#conversejs .chatbox").length).toBe(3);
|
||||
expect(document.querySelectorAll("#conversejs .chatbox")[2].id).toBe(chatboxview.model.get('box_id'));
|
||||
expect(document.querySelectorAll("#conversejs .chatbox")[1].id).toBe(new_chatboxview.model.get('box_id'));
|
||||
done();
|
||||
});
|
||||
}));
|
||||
|
|
|
@ -66,47 +66,50 @@
|
|||
|
||||
it("shows the number of unread mentions received",
|
||||
mock.initConverseWithPromises(
|
||||
null, ['rosterGroupsFetched'], {},
|
||||
null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
function (done, _converse) {
|
||||
|
||||
test_utils.createContacts(_converse, 'all').openControlBox();
|
||||
_converse.emit('rosterContactsFetched');
|
||||
|
||||
var contacts_panel = _converse.chatboxviews.get('controlbox').contactspanel;
|
||||
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||
|
||||
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||
test_utils.openChatBoxFor(_converse, sender_jid);
|
||||
var chatview = _converse.chatboxviews.get(sender_jid);
|
||||
chatview.model.set({'minimized': true});
|
||||
return test_utils.waitUntil(() => _converse.chatboxes.length).then(() => {
|
||||
|
||||
expect(_.isNull(_converse.chatboxviews.el.querySelector('.restore-chat .message-count'))).toBeTruthy();
|
||||
expect(_.isNull(_converse.rosterview.el.querySelector('.msgs-indicator'))).toBeTruthy();
|
||||
const chatview = _converse.chatboxviews.get(sender_jid);
|
||||
chatview.model.set({'minimized': true});
|
||||
|
||||
var msg = $msg({
|
||||
from: sender_jid,
|
||||
to: _converse.connection.jid,
|
||||
type: 'chat',
|
||||
id: (new Date()).getTime()
|
||||
}).c('body').t('hello').up()
|
||||
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
expect(_converse.chatboxviews.el.querySelector('.restore-chat .message-count').textContent).toBe('1');
|
||||
expect(_converse.rosterview.el.querySelector('.msgs-indicator').textContent).toBe('1');
|
||||
expect(_.isNull(_converse.chatboxviews.el.querySelector('.restore-chat .message-count'))).toBeTruthy();
|
||||
expect(_.isNull(_converse.rosterview.el.querySelector('.msgs-indicator'))).toBeTruthy();
|
||||
|
||||
msg = $msg({
|
||||
from: sender_jid,
|
||||
to: _converse.connection.jid,
|
||||
type: 'chat',
|
||||
id: (new Date()).getTime()
|
||||
}).c('body').t('hello again').up()
|
||||
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
expect(_converse.chatboxviews.el.querySelector('.restore-chat .message-count').textContent).toBe('2');
|
||||
expect(_converse.rosterview.el.querySelector('.msgs-indicator').textContent).toBe('2');
|
||||
var msg = $msg({
|
||||
from: sender_jid,
|
||||
to: _converse.connection.jid,
|
||||
type: 'chat',
|
||||
id: (new Date()).getTime()
|
||||
}).c('body').t('hello').up()
|
||||
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
expect(_converse.chatboxviews.el.querySelector('.restore-chat .message-count').textContent).toBe('1');
|
||||
expect(_converse.rosterview.el.querySelector('.msgs-indicator').textContent).toBe('1');
|
||||
|
||||
chatview.model.set({'minimized': false});
|
||||
expect(_.isNull(_converse.chatboxviews.el.querySelector('.restore-chat .message-count'))).toBeTruthy();
|
||||
expect(_.isNull(_converse.rosterview.el.querySelector('.msgs-indicator'))).toBeTruthy();
|
||||
done();
|
||||
msg = $msg({
|
||||
from: sender_jid,
|
||||
to: _converse.connection.jid,
|
||||
type: 'chat',
|
||||
id: (new Date()).getTime()
|
||||
}).c('body').t('hello again').up()
|
||||
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
expect(_converse.chatboxviews.el.querySelector('.restore-chat .message-count').textContent).toBe('2');
|
||||
expect(_converse.rosterview.el.querySelector('.msgs-indicator').textContent).toBe('2');
|
||||
|
||||
chatview.model.set({'minimized': false});
|
||||
expect(_.isNull(_converse.chatboxviews.el.querySelector('.restore-chat .message-count'))).toBeTruthy();
|
||||
expect(_.isNull(_converse.rosterview.el.querySelector('.msgs-indicator'))).toBeTruthy();
|
||||
done();
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
|
|
101
spec/converse.js
101
spec/converse.js
|
@ -1,12 +1,12 @@
|
|||
(function (root, factory) {
|
||||
define([
|
||||
"jquery",
|
||||
"jasmine",
|
||||
"mock",
|
||||
"test-utils"], factory);
|
||||
} (this, function ($, jasmine, mock, test_utils) {
|
||||
var b64_sha1 = converse.env.b64_sha1;
|
||||
var _ = converse.env._;
|
||||
} (this, function (jasmine, mock, test_utils) {
|
||||
const b64_sha1 = converse.env.b64_sha1,
|
||||
_ = converse.env._,
|
||||
u = converse.env.utils;
|
||||
|
||||
describe("Converse", function() {
|
||||
|
||||
|
@ -274,59 +274,72 @@
|
|||
|
||||
describe("The \"chats\" API", function() {
|
||||
|
||||
it("has a method 'get' which returns the chatbox model", mock.initConverseWithPromises(
|
||||
null, ['rosterInitialized'], {}, function (done, _converse) {
|
||||
it("has a method 'get' which returns the promise that resolves to a chat model", mock.initConverseWithPromises(
|
||||
null, ['rosterInitialized', 'chatBoxesInitialized'], {}, function (done, _converse) {
|
||||
test_utils.openControlBox();
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
test_utils.createContacts(_converse, 'current', 2);
|
||||
_converse.emit('rosterContactsFetched');
|
||||
|
||||
// Test on chat that doesn't exist.
|
||||
expect(_converse.api.chats.get('non-existing@jabber.org')).toBeFalsy();
|
||||
var jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||
const jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||
const jid2 = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||
|
||||
// Test on chat that's not open
|
||||
var box = _converse.api.chats.get(jid);
|
||||
let box = _converse.api.chats.get(jid);
|
||||
expect(typeof box === 'undefined').toBeTruthy();
|
||||
var chatboxview = _converse.chatboxviews.get(jid);
|
||||
// Test for single JID
|
||||
expect(_converse.chatboxes.length).toBe(1);
|
||||
|
||||
// Test for one JID
|
||||
test_utils.openChatBoxFor(_converse, jid);
|
||||
box = _converse.api.chats.get(jid);
|
||||
test_utils.waitUntil(() => _converse.chatboxes.length == 1).then(() => {
|
||||
box = _converse.api.chats.get(jid);
|
||||
expect(box instanceof Object).toBeTruthy();
|
||||
expect(box.get('box_id')).toBe(b64_sha1(jid));
|
||||
|
||||
const chatboxview = _converse.chatboxviews.get(jid);
|
||||
expect(u.isVisible(chatboxview.el)).toBeTruthy();
|
||||
// Test for multiple JIDs
|
||||
test_utils.openChatBoxFor(_converse, jid2);
|
||||
return test_utils.waitUntil(() => _converse.chatboxes.length == 2);
|
||||
}).then(() => {
|
||||
const list = _converse.api.chats.get([jid, jid2]);
|
||||
expect(_.isArray(list)).toBeTruthy();
|
||||
expect(list[0].get('box_id')).toBe(b64_sha1(jid));
|
||||
expect(list[1].get('box_id')).toBe(b64_sha1(jid2));
|
||||
done();
|
||||
}).catch(_.partial(console.error, _));
|
||||
}));
|
||||
|
||||
it("has a method 'open' which opens and returns promise that resolves to a chat model", mock.initConverseWithPromises(
|
||||
null, ['rosterGroupsFetched', 'chatBoxesInitialized'], {}, function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
test_utils.createContacts(_converse, 'current', 2);
|
||||
_converse.emit('rosterContactsFetched');
|
||||
|
||||
const jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||
const jid2 = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||
// Test on chat that doesn't exist.
|
||||
expect(_converse.api.chats.get('non-existing@jabber.org')).toBeFalsy();
|
||||
|
||||
return _converse.api.chats.open(jid).then((box) => {
|
||||
expect(box instanceof Object).toBeTruthy();
|
||||
expect(box.get('box_id')).toBe(b64_sha1(jid));
|
||||
chatboxview = _converse.chatboxviews.get(jid);
|
||||
expect($(chatboxview.el).is(':visible')).toBeTruthy();
|
||||
expect(
|
||||
_.keys(box),
|
||||
['close', 'endOTR', 'focus', 'get', 'initiateOTR', 'is_chatroom', 'maximize', 'minimize', 'open', 'set']
|
||||
);
|
||||
const chatboxview = _converse.chatboxviews.get(jid);
|
||||
expect(u.isVisible(chatboxview.el)).toBeTruthy();
|
||||
// Test for multiple JIDs
|
||||
var jid2 = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||
test_utils.openChatBoxFor(_converse, jid2);
|
||||
var list = _converse.api.chats.get([jid, jid2]);
|
||||
return _converse.api.chats.open([jid, jid2]);
|
||||
}).then((list) => {
|
||||
expect(_.isArray(list)).toBeTruthy();
|
||||
expect(list[0].get('box_id')).toBe(b64_sha1(jid));
|
||||
expect(list[1].get('box_id')).toBe(b64_sha1(jid2));
|
||||
done();
|
||||
}));
|
||||
|
||||
it("has a method 'open' which opens and returns the chatbox model", mock.initConverseWithPromises(
|
||||
null, ['rosterGroupsFetched'], {}, function (done, _converse) {
|
||||
|
||||
test_utils.openControlBox();
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
var jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||
var chatboxview;
|
||||
// Test on chat that doesn't exist.
|
||||
expect(_converse.api.chats.get('non-existing@jabber.org')).toBeFalsy();
|
||||
var box = _converse.api.chats.open(jid);
|
||||
expect(box instanceof Object).toBeTruthy();
|
||||
expect(box.get('box_id')).toBe(b64_sha1(jid));
|
||||
expect(
|
||||
_.keys(box),
|
||||
['close', 'endOTR', 'focus', 'get', 'initiateOTR', 'is_chatroom', 'maximize', 'minimize', 'open', 'set']
|
||||
);
|
||||
chatboxview = _converse.chatboxviews.get(jid);
|
||||
expect($(chatboxview.el).is(':visible')).toBeTruthy();
|
||||
// Test for multiple JIDs
|
||||
var jid2 = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||
var list = _converse.api.chats.open([jid, jid2]);
|
||||
expect(_.isArray(list)).toBeTruthy();
|
||||
expect(list[0].get('box_id')).toBe(b64_sha1(jid));
|
||||
expect(list[1].get('box_id')).toBe(b64_sha1(jid2));
|
||||
done();
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
|
|
109
spec/minchats.js
109
spec/minchats.js
|
@ -1,8 +1,9 @@
|
|||
(function (root, factory) {
|
||||
define(["jquery", "jasmine", "mock", "test-utils"], factory);
|
||||
} (this, function ($, jasmine, mock, test_utils) {
|
||||
var _ = converse.env._;
|
||||
var $msg = converse.env.$msg;
|
||||
const _ = converse.env._;
|
||||
const $msg = converse.env.$msg;
|
||||
const u = converse.env.utils;
|
||||
|
||||
describe("The Minimized Chats Widget", function () {
|
||||
|
||||
|
@ -62,9 +63,8 @@
|
|||
expect(_converse.minimized_chats.toggleview.model.get('collapsed')).toBeFalsy();
|
||||
_converse.minimized_chats.el.querySelector('#toggle-minimized-chats').click();
|
||||
|
||||
return test_utils.waitUntil(function () {
|
||||
return $(_converse.minimized_chats.el.querySelector('.minimized-chats-flyout')).is(':visible');
|
||||
}, 500).then(function () {
|
||||
return test_utils.waitUntil(() => u.isVisible(u.isVisible(_converse.minimized_chats.el.querySelector('.minimized-chats-flyout'))))
|
||||
.then(function () {
|
||||
expect(_converse.minimized_chats.toggleview.model.get('collapsed')).toBeTruthy();
|
||||
done();
|
||||
});
|
||||
|
@ -72,70 +72,79 @@
|
|||
|
||||
it("shows the number messages received to minimized chats",
|
||||
mock.initConverseWithPromises(
|
||||
null, ['rosterGroupsFetched'], {},
|
||||
null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
function (done, _converse) {
|
||||
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
_converse.emit('rosterContactsFetched');
|
||||
|
||||
test_utils.openControlBox();
|
||||
_converse.minimized_chats.toggleview.model.browserStorage._clear();
|
||||
_converse.minimized_chats.initToggle();
|
||||
|
||||
var i, contact_jid, chatview, msg;
|
||||
_converse.minimized_chats.toggleview.model.set({'collapsed': true});
|
||||
expect($(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count')).is(':visible')).toBeFalsy();
|
||||
|
||||
const unread_el = _converse.minimized_chats.toggleview.el.querySelector('.unread-message-count');
|
||||
expect(_.isNull(unread_el)).toBe(true);
|
||||
|
||||
for (i=0; i<3; i++) {
|
||||
contact_jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||
test_utils.openChatBoxFor(_converse, contact_jid);
|
||||
chatview = _converse.chatboxviews.get(contact_jid);
|
||||
chatview.model.set({'minimized': true});
|
||||
msg = $msg({
|
||||
}
|
||||
return test_utils.waitUntil(() => _converse.chatboxes.length == 4).then(() => {
|
||||
for (i=0; i<3; i++) {
|
||||
chatview = _converse.chatboxviews.get(contact_jid);
|
||||
chatview.model.set({'minimized': true});
|
||||
msg = $msg({
|
||||
from: contact_jid,
|
||||
to: _converse.connection.jid,
|
||||
type: 'chat',
|
||||
id: (new Date()).getTime()
|
||||
}).c('body').t('This message is sent to a minimized chatbox').up()
|
||||
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
expect($(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count')).is(':visible')).toBeTruthy();
|
||||
expect($(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count')).text()).toBe((i+1).toString());
|
||||
}
|
||||
// Chat state notifications don't increment the unread messages counter
|
||||
// <composing> state
|
||||
_converse.chatboxes.onMessage($msg({
|
||||
from: contact_jid,
|
||||
to: _converse.connection.jid,
|
||||
type: 'chat',
|
||||
id: (new Date()).getTime()
|
||||
}).c('body').t('This message is sent to a minimized chatbox').up()
|
||||
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
expect($(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count')).is(':visible')).toBeTruthy();
|
||||
expect($(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count')).text()).toBe((i+1).toString());
|
||||
}
|
||||
// Chat state notifications don't increment the unread messages counter
|
||||
// <composing> state
|
||||
_converse.chatboxes.onMessage($msg({
|
||||
from: contact_jid,
|
||||
to: _converse.connection.jid,
|
||||
type: 'chat',
|
||||
id: (new Date()).getTime()
|
||||
}).c('composing', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
|
||||
expect($(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count')).text()).toBe((i).toString());
|
||||
}).c('composing', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
|
||||
expect($(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count')).text()).toBe((i).toString());
|
||||
|
||||
// <paused> state
|
||||
_converse.chatboxes.onMessage($msg({
|
||||
from: contact_jid,
|
||||
to: _converse.connection.jid,
|
||||
type: 'chat',
|
||||
id: (new Date()).getTime()
|
||||
}).c('paused', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
|
||||
expect($(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count')).text()).toBe((i).toString());
|
||||
// <paused> state
|
||||
_converse.chatboxes.onMessage($msg({
|
||||
from: contact_jid,
|
||||
to: _converse.connection.jid,
|
||||
type: 'chat',
|
||||
id: (new Date()).getTime()
|
||||
}).c('paused', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
|
||||
expect($(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count')).text()).toBe((i).toString());
|
||||
|
||||
// <gone> state
|
||||
_converse.chatboxes.onMessage($msg({
|
||||
from: contact_jid,
|
||||
to: _converse.connection.jid,
|
||||
type: 'chat',
|
||||
id: (new Date()).getTime()
|
||||
}).c('gone', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
|
||||
expect($(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count')).text()).toBe((i).toString());
|
||||
// <gone> state
|
||||
_converse.chatboxes.onMessage($msg({
|
||||
from: contact_jid,
|
||||
to: _converse.connection.jid,
|
||||
type: 'chat',
|
||||
id: (new Date()).getTime()
|
||||
}).c('gone', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
|
||||
expect($(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count')).text()).toBe((i).toString());
|
||||
|
||||
// <inactive> state
|
||||
_converse.chatboxes.onMessage($msg({
|
||||
from: contact_jid,
|
||||
to: _converse.connection.jid,
|
||||
type: 'chat',
|
||||
id: (new Date()).getTime()
|
||||
}).c('inactive', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
|
||||
expect($(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count')).text()).toBe((i).toString());
|
||||
done();
|
||||
// <inactive> state
|
||||
_converse.chatboxes.onMessage($msg({
|
||||
from: contact_jid,
|
||||
to: _converse.connection.jid,
|
||||
type: 'chat',
|
||||
id: (new Date()).getTime()
|
||||
}).c('inactive', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
|
||||
expect($(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count')).text()).toBe((i).toString());
|
||||
done();
|
||||
});
|
||||
}));
|
||||
|
||||
it("shows the number messages received to minimized groupchats",
|
||||
|
|
|
@ -16,22 +16,23 @@
|
|||
|
||||
it("can be used to remove a contact",
|
||||
mock.initConverseWithPromises(
|
||||
null, ['rosterGroupsFetched'], {},
|
||||
null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
function (done, _converse) {
|
||||
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
_converse.emit('rosterContactsFetched');
|
||||
|
||||
let view, show_modal_button, modal;
|
||||
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||
test_utils.openChatBoxFor(_converse, contact_jid);
|
||||
|
||||
const view = _converse.chatboxviews.get(contact_jid);
|
||||
const show_modal_button = view.el.querySelector('.show-user-details-modal');
|
||||
expect(u.isVisible(show_modal_button)).toBeTruthy();
|
||||
show_modal_button.click();
|
||||
const modal = view.user_details_modal;
|
||||
test_utils.waitUntil(() => u.isVisible(modal.el), 1000)
|
||||
.then(function () {
|
||||
return test_utils.waitUntil(() => _converse.chatboxes.length).then(() => {
|
||||
view = _converse.chatboxviews.get(contact_jid);
|
||||
show_modal_button = view.el.querySelector('.show-user-details-modal');
|
||||
expect(u.isVisible(show_modal_button)).toBeTruthy();
|
||||
show_modal_button.click();
|
||||
modal = view.user_details_modal;
|
||||
return test_utils.waitUntil(() => u.isVisible(modal.el), 1000);
|
||||
}).then(function () {
|
||||
spyOn(window, 'confirm').and.returnValue(true);
|
||||
spyOn(view.model.contact, 'removeFromRoster').and.callFake(function (callback) {
|
||||
callback();
|
||||
|
|
|
@ -69,12 +69,7 @@
|
|||
Strophe.LogLevel.WARN
|
||||
);
|
||||
}
|
||||
Promise.all([
|
||||
_converse.api.waitUntil('rosterContactsFetched'),
|
||||
_converse.api.waitUntil('chatBoxesFetched')
|
||||
]).then(() => {
|
||||
_converse.api.chats.open(jid);
|
||||
});
|
||||
_converse.api.chats.open(jid);
|
||||
}
|
||||
_converse.router.route('converse/chat?jid=:jid', openChat);
|
||||
|
||||
|
@ -905,15 +900,22 @@
|
|||
});
|
||||
},
|
||||
'open' (jids, attrs) {
|
||||
if (_.isUndefined(jids)) {
|
||||
_converse.log("chats.open: You need to provide at least one JID", Strophe.LogLevel.ERROR);
|
||||
return null;
|
||||
} else if (_.isString(jids)) {
|
||||
const chatbox = _converse.api.chats.create(jids, attrs);
|
||||
chatbox.trigger('show');
|
||||
return chatbox;
|
||||
}
|
||||
return _.map(jids, (jid) => _converse.api.chats.create(jid, attrs).trigger('show'));
|
||||
return new Promise((resolve, reject) => {
|
||||
Promise.all([
|
||||
_converse.api.waitUntil('rosterContactsFetched'),
|
||||
_converse.api.waitUntil('chatBoxesFetched')
|
||||
]).then(() => {
|
||||
if (_.isUndefined(jids)) {
|
||||
const err_msg = "chats.open: You need to provide at least one JID";
|
||||
_converse.log(err_msg, Strophe.LogLevel.ERROR);
|
||||
reject(new Error(err_msg));
|
||||
} else if (_.isString(jids)) {
|
||||
resolve(_converse.api.chats.create(jids, attrs).trigger('show'));
|
||||
} else {
|
||||
resolve(_.map(jids, (jid) => _converse.api.chats.create(jid, attrs).trigger('show')));
|
||||
}
|
||||
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
|
||||
});
|
||||
},
|
||||
'get' (jids) {
|
||||
if (_.isUndefined(jids)) {
|
||||
|
|
|
@ -1254,14 +1254,23 @@
|
|||
}
|
||||
return _.map(jids, _.partial(createChatRoom, _, attrs));
|
||||
},
|
||||
|
||||
'open' (jids, attrs) {
|
||||
if (_.isUndefined(jids)) {
|
||||
throw new TypeError('rooms.open: You need to provide at least one JID');
|
||||
} else if (_.isString(jids)) {
|
||||
return _converse.api.rooms.create(jids, attrs).trigger('show');
|
||||
}
|
||||
return _.map(jids, (jid) => _converse.api.rooms.create(jid, attrs).trigger('show'));
|
||||
return new Promise((resolve, reject) => {
|
||||
_converse.api.waitUntil('chatBoxesFetched').then(() => {
|
||||
if (_.isUndefined(jids)) {
|
||||
const err_msg = 'rooms.open: You need to provide at least one JID';
|
||||
_converse.log(err_msg, Strophe.LogLevel.ERROR);
|
||||
reject(new TypeError(err_msg));
|
||||
} else if (_.isString(jids)) {
|
||||
resolve(_converse.api.rooms.create(jids, attrs).trigger('show'));
|
||||
} else {
|
||||
resolve(_.map(jids, (jid) => _converse.api.rooms.create(jid, attrs).trigger('show')));
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
'get' (jids, attrs, create) {
|
||||
if (_.isString(attrs)) {
|
||||
attrs = {'nick': attrs};
|
||||
|
|
Loading…
Reference in New Issue
Block a user