Add eslint with lodash checking and apply its suggestions

This commit is contained in:
JC Brand 2017-01-26 14:49:02 +00:00
parent 343e5777d1
commit 081f075aa9
32 changed files with 531 additions and 257 deletions

264
.eslintrc.json Normal file
View File

@ -0,0 +1,264 @@
{
"env": {
"browser": true,
"jasmine": true
},
"plugins": ["lodash"],
"extends": ["eslint:recommended", "plugin:lodash/canonical"],
"globals": {
"window": true,
"sinon": true,
"define": true
},
"rules": {
"lodash/prefer-lodash-method": [2, {
"ignoreMethods": ["find", "endsWith", "startsWith", "filter", "map"]
}],
"lodash/prefer-startswith": "off",
"lodash/prefer-constant": "off",
"lodash/prefer-noop": "off",
"lodash/prefer-lodash-typecheck": "off",
"lodash/preferred-alias": "off",
"accessor-pairs": "error",
"array-bracket-spacing": "off",
"array-callback-return": "error",
"arrow-body-style": "error",
"arrow-parens": "error",
"arrow-spacing": "error",
"block-scoped-var": "off",
"block-spacing": "off",
"brace-style": "off",
"callback-return": "off",
"camelcase": "off",
"capitalized-comments": "off",
"class-methods-use-this": "error",
"comma-dangle": "off",
"comma-spacing": "off",
"comma-style": "off",
"complexity": "off",
"computed-property-spacing": [
"error",
"never"
],
"consistent-return": "off",
"consistent-this": "off",
"curly": "off",
"default-case": "off",
"dot-location": [
"error",
"property"
],
"dot-notation": [
"error",
{
"allowKeywords": false
}
],
"eol-last": "error",
"eqeqeq": "off",
"func-call-spacing": "off",
"no-spaced-func": "off",
"func-name-matching": "error",
"func-names": "off",
"func-style": "off",
"generator-star-spacing": "error",
"global-require": "off",
"guard-for-in": "error",
"handle-callback-err": "error",
"id-blacklist": "error",
"id-length": "off",
"id-match": "error",
"indent": "off",
"init-declarations": "off",
"jsx-quotes": "error",
"key-spacing": "off",
"keyword-spacing": "off",
"line-comment-position": "off",
"linebreak-style": [
"error",
"unix"
],
"lines-around-comment": "off",
"lines-around-directive": "off",
"max-depth": "error",
"max-len": "off",
"max-lines": "off",
"max-nested-callbacks": "error",
"max-params": "off",
"max-statements": "off",
"max-statements-per-line": "off",
"multiline-ternary": "off",
"new-parens": "error",
"newline-after-var": "off",
"newline-before-return": "off",
"newline-per-chained-call": "off",
"no-alert": "off",
"no-array-constructor": "error",
"no-await-in-loop": "error",
"no-bitwise": "off",
"no-caller": "error",
"no-console": "off",
"no-catch-shadow": "error",
"no-cond-assign": [
"error",
"except-parens"
],
"no-confusing-arrow": "error",
"no-continue": "off",
"no-div-regex": "error",
"no-duplicate-imports": "error",
"no-else-return": "off",
"no-empty-function": "off",
"no-eq-null": "error",
"no-eval": "error",
"no-extend-native": "off",
"no-extra-bind": "off",
"no-extra-label": "error",
"no-extra-parens": "off",
"no-floating-decimal": "error",
"no-implicit-globals": "off",
"no-implied-eval": "error",
"no-inline-comments": "off",
"no-inner-declarations": [
"error",
"functions"
],
"no-invalid-this": "off",
"no-iterator": "error",
"no-label-var": "error",
"no-labels": "error",
"no-lone-blocks": "error",
"no-lonely-if": "off",
"no-loop-func": "error",
"no-magic-numbers": "off",
"no-mixed-operators": "off",
"no-mixed-requires": "error",
"no-multi-assign": "off",
"no-multi-spaces": "off",
"no-multi-str": "error",
"no-multiple-empty-lines": "error",
"no-native-reassign": "error",
"no-negated-condition": "off",
"no-negated-in-lhs": "error",
"no-nested-ternary": "off",
"no-new": "error",
"no-new-func": "error",
"no-new-object": "error",
"no-new-require": "error",
"no-new-wrappers": "error",
"no-octal-escape": "error",
"no-param-reassign": "off",
"no-path-concat": "error",
"no-plusplus": "off",
"no-process-env": "error",
"no-process-exit": "error",
"no-proto": "error",
"no-prototype-builtins": "error",
"no-restricted-globals": "error",
"no-restricted-imports": "error",
"no-restricted-modules": "error",
"no-restricted-properties": "error",
"no-restricted-syntax": "error",
"no-return-assign": "error",
"no-return-await": "error",
"no-script-url": "error",
"no-self-compare": "error",
"no-sequences": "error",
"no-shadow": "off",
"no-shadow-restricted-names": "error",
"no-sync": "error",
"no-tabs": "error",
"no-template-curly-in-string": "error",
"no-ternary": "off",
"no-throw-literal": "error",
"no-trailing-spaces": "off",
"no-undef-init": "error",
"no-undefined": "off",
"no-underscore-dangle": "off",
"no-unmodified-loop-condition": "error",
"no-unneeded-ternary": "off",
"no-unused-vars": "off",
"no-unused-expressions": "off",
"no-use-before-define": "off",
"no-useless-call": "error",
"no-useless-computed-key": "error",
"no-useless-concat": "error",
"no-useless-constructor": "error",
"no-useless-escape": "off",
"no-useless-rename": "error",
"no-useless-return": "off",
"no-var": "off",
"no-void": "error",
"no-warning-comments": "off",
"no-whitespace-before-property": "error",
"no-with": "error",
"object-curly-newline": "off",
"object-curly-spacing": "off",
"object-property-newline": [
"error",
{
"allowMultiplePropertiesPerLine": true
}
],
"object-shorthand": "off",
"one-var": "off",
"one-var-declaration-per-line": "off",
"operator-assignment": "off",
"operator-linebreak": [
"error",
"after"
],
"padded-blocks": "off",
"prefer-arrow-callback": "off",
"prefer-const": "error",
"prefer-destructuring": [
"error",
{
"array": false,
"object": false
}
],
"prefer-numeric-literals": "error",
"prefer-promise-reject-errors": "error",
"prefer-reflect": "off",
"prefer-rest-params": "off",
"prefer-spread": "off",
"prefer-template": "off",
"quote-props": "off",
"quotes": "off",
"radix": [
"error",
"always"
],
"require-await": "error",
"require-jsdoc": "off",
"rest-spread-spacing": "error",
"semi": "off",
"semi-spacing": "off",
"sort-imports": "error",
"sort-keys": "off",
"sort-vars": "off",
"space-before-blocks": "off",
"space-before-function-paren": "off",
"space-in-parens": "off",
"space-infix-ops": "off",
"space-unary-ops": "off",
"spaced-comment": "off",
"strict": "off",
"symbol-description": "error",
"template-curly-spacing": "error",
"unicode-bom": [
"error",
"never"
],
"valid-jsdoc": "error",
"vars-on-top": "off",
"wrap-iife": [
"error",
"any"
],
"wrap-regex": "error",
"yield-star-spacing": "error",
"yoda": "off"
}
}

View File

@ -3,11 +3,12 @@ BOWER ?= node_modules/.bin/bower
BUILDDIR = ./docs
BUNDLE ?= ./.bundle/bin/bundle
GRUNT ?= ./node_modules/.bin/grunt
HTTPSERVE ?= ./node_modules/.bin/http-server
JSHINT ?= ./node_modules/.bin/jshint
HTTPSERVE ?= ./node_modules/.bin/http-server
JSHINT ?= ./node_modules/.bin/jshint
ESLINT ?= ./node_modules/.bin/eslint
PAPER =
PHANTOMJS ?= ./node_modules/.bin/phantomjs
RJS ?= ./node_modules/.bin/r.js
RJS ?= ./node_modules/.bin/r.js
PO2JSON ?= ./node_modules/.bin/po2json
SASS ?= ./.bundle/bin/sass
CLEANCSS ?= ./node_modules/.bin/cleancss
@ -16,16 +17,13 @@ SPHINXOPTS =
# Internal variables.
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) ./docs/source
SOURCES = $(wildcard *.js) $(wildcard spec/*.js) $(wildcard src/*.js)
SOURCES = $(wildcard *.js) $(wildcard spec/*.js) $(wildcard src/*.js)
JSHINTEXCEPTIONS = $(GENERATED) \
src/otr.js \
src/crypto.js \
src/build-mobile.js \
src/build-no-jquery.js \
src/build-no-dependencies.js \
src/build.js \
src/bigint.js
CHECKSOURCES = $(filter-out $(JSHINTEXCEPTIONS),$(SOURCES))
src/build-mobile.js \
src/build-no-jquery.js \
src/build-no-dependencies.js \
src/build.js \
CHECKSOURCES = $(filter-out $(JSHINTEXCEPTIONS),$(SOURCES))
.PHONY: all
all: dev dist
@ -189,8 +187,13 @@ build:: stamp-bundler stamp-bower css
jshint: stamp-bower
$(JSHINT) --config jshintrc $(CHECKSOURCES)
.PHONY: eslint
eslint: stamp-npm
$(ESLINT) src/
$(ESLINT) spec/
.PHONY: check
check: stamp-bower jshint
check: stamp-bower jshint eslint
$(PHANTOMJS) node_modules/phantom-jasmine/lib/run_jasmine_test.coffee tests.html
########################################################################

View File

@ -39,19 +39,22 @@
"bower": "latest",
"clean-css": "^3.4.19",
"crypto-js": "3.1.2-5",
"eslint": "^3.14.1",
"eslint-plugin-lodash": "^2.3.3",
"greenkeeper": "^4.1.0",
"grunt": "^1.0.1",
"grunt-cli": "^1.1.0",
"grunt-json": "^0.2.0",
"http-server": "^0.9.0",
"install": "^0.8.4",
"jed": "0.5.4",
"jquery": "2.2.3",
"jquery-easing": "0.0.1",
"jquery.browser": ">=0.1.0",
"jshint": "^2.9.4",
"lodash": "^4.17.4",
"lodash-cli": "^4.17.4",
"moment": "~2.13.0",
"npm": "^4.1.1",
"otr": "0.2.16",
"phantom-jasmine": "0.1.8",
"phantomjs": "~1.9.7-1",

View File

@ -154,8 +154,8 @@
var attrs = ['id', 'box_id', 'visible'];
var new_attrs, old_attrs;
for (var i=0; i<attrs.length; i++) {
new_attrs = _.pluck(_.pluck(newchatboxes.models, 'attributes'), attrs[i]);
old_attrs = _.pluck(_.pluck(converse.chatboxes.models, 'attributes'), attrs[i]);
new_attrs = _.map(_.map(newchatboxes.models, 'attributes'), attrs[i]);
old_attrs = _.map(_.map(converse.chatboxes.models, 'attributes'), attrs[i]);
expect(_.isEqual(new_attrs, old_attrs)).toEqual(true);
}
converse.rosterview.render();
@ -739,7 +739,7 @@
sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
msg = $msg({
from: sender_jid,
to: converse.bare_jid+'/'+"some-other-resource",
to: converse.bare_jid+"/some-other-resource",
type: 'chat',
id: (new Date()).getTime()
}).c('body').t("This message will not be shown").up()
@ -758,7 +758,7 @@
message = "This message sent to a different resource will be shown";
msg = $msg({
from: sender_jid,
to: converse.bare_jid+'/'+"some-other-resource",
to: converse.bare_jid+"/some-other-resource",
type: 'chat',
id: '134234623462346'
}).c('body').t(message).up()
@ -1571,7 +1571,7 @@
test_utils.openChatBoxFor(converse, sender_jid);
var view = converse.chatboxviews.get(sender_jid);
expect(view.$el.find('.chat-event').length).toBe(0);
view.showStatusNotification(sender_jid+' '+'is typing');
view.showStatusNotification(sender_jid+' is typing');
expect(view.$el.find('.chat-event').length).toBe(1);
var msg = $msg({
from: sender_jid,

View File

@ -331,8 +331,8 @@
.c('x', { 'xmlns': 'jabber:x:data', 'type': 'form'})
.c('title').t('Configuration for "coven" Room').up()
.c('instructions').t('Complete this form to modify the configuration of your room.').up()
.c('field', {'type': 'hidden', 'var': 'FORM_TYPE'}).
c('value').t('http://jabber.org/protocol/muc#roomconfig').up().up()
.c('field', {'type': 'hidden', 'var': 'FORM_TYPE'})
.c('value').t('http://jabber.org/protocol/muc#roomconfig').up().up()
.c('field', {
'label': 'Natural-Language Room Name',
'type': 'text-single',
@ -1078,8 +1078,8 @@
var attrs = ['id', 'box_id', 'visible'];
var new_attrs, old_attrs;
for (var i=0; i<attrs.length; i++) {
new_attrs = _.pluck(_.pluck(newchatboxes.models, 'attributes'), attrs[i]);
old_attrs = _.pluck(_.pluck(converse.chatboxes.models, 'attributes'), attrs[i]);
new_attrs = _.map(_.map(newchatboxes.models, 'attributes'), attrs[i]);
old_attrs = _.map(_.map(converse.chatboxes.models, 'attributes'), attrs[i]);
// FIXME: should have have to sort here? Order must
// probably be the same...
// This should be fixed once the controlbox always opens

View File

@ -1031,7 +1031,7 @@
var stanza = $pres({from: 'data@enterprise/resource', type: 'subscribe'});
converse.connection._dataRecv(test_utils.createRequest(stanza));
expect(converse.roster.pluck('jid').length).toBe(1);
expect(_.contains(converse.roster.pluck('jid'), 'data@enterprise')).toBeTruthy();
expect(_.includes(converse.roster.pluck('jid'), 'data@enterprise')).toBeTruthy();
// Taken from the spec
// http://xmpp.org/rfcs/rfc3921.html#rfc.section.7.3
@ -1057,7 +1057,7 @@
subscription:'both'
}).c('group').t('Friends');
converse.roster.onReceivedFromServer(stanza.tree());
expect(_.contains(converse.roster.pluck('jid'), 'data@enterprise')).toBeTruthy();
expect(_.includes(converse.roster.pluck('jid'), 'data@enterprise')).toBeTruthy();
}));
});
@ -1083,8 +1083,8 @@
// have the same attributes values as the original ones.
attrs = ['jid', 'fullname', 'subscription', 'ask'];
for (var i=0; i<attrs.length; i++) {
new_attrs = _.pluck(_.pluck(new_roster.models, 'attributes'), attrs[i]);
old_attrs = _.pluck(_.pluck(converse.roster.models, 'attributes'), attrs[i]);
new_attrs = _.map(_.map(new_roster.models, 'attributes'), attrs[i]);
old_attrs = _.map(_.map(converse.roster.models, 'attributes'), attrs[i]);
// Roster items in storage are not necessarily sorted,
// so we have to sort them here to do a proper
// comparison

View File

@ -219,7 +219,7 @@
// You can retrieve multiple contacts by passing in an array
var jid2 = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
var list = converse_api.contacts.get([jid, jid2]);
expect(Array.isArray(list)).toBeTruthy();
expect(_.isArray(list)).toBeTruthy();
expect(list[0].fullname).toBe(mock.cur_names[0]);
expect(list[1].fullname).toBe(mock.cur_names[1]);
// Check that all JIDs are returned if you call without any parameters
@ -262,7 +262,7 @@
var jid2 = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(converse, jid2);
var list = converse_api.chats.get([jid, jid2]);
expect(Array.isArray(list)).toBeTruthy();
expect(_.isArray(list)).toBeTruthy();
expect(list[0].get('box_id')).toBe(b64_sha1(jid));
expect(list[1].get('box_id')).toBe(b64_sha1(jid2));
}));
@ -279,7 +279,7 @@
expect(box instanceof Object).toBeTruthy();
expect(box.get('box_id')).toBe(b64_sha1(jid));
expect(
Object.keys(box),
_.keys(box),
['close', 'endOTR', 'focus', 'get', 'initiateOTR', 'is_chatroom', 'maximize', 'minimize', 'open', 'set']
);
chatboxview = converse.chatboxviews.get(jid);
@ -287,7 +287,7 @@
// Test for multiple JIDs
var jid2 = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
var list = converse_api.chats.open([jid, jid2]);
expect(Array.isArray(list)).toBeTruthy();
expect(_.isArray(list)).toBeTruthy();
expect(list[0].get('box_id')).toBe(b64_sha1(jid));
expect(list[1].get('box_id')).toBe(b64_sha1(jid2));
});
@ -296,7 +296,7 @@
describe("The \"settings\" API", function() {
it("has methods 'get' and 'set' to set configuration settings", mock.initConverse(function (converse) {
expect(Object.keys(converse_api.settings)).toEqual(["get", "set"]);
expect(_.keys(converse_api.settings)).toEqual(["get", "set"]);
expect(converse_api.settings.get("play_sounds")).toBe(false);
converse_api.settings.set("play_sounds", true);
expect(converse_api.settings.get("play_sounds")).toBe(true);

View File

@ -86,7 +86,7 @@
waits(250);
runs(function () {
expect(
_.contains(
_.includes(
converse.chatboxviews.keys(),
'notify.example.com')
).toBeTruthy();

View File

@ -447,7 +447,7 @@
.c('never').up();
converse.connection._dataRecv(test_utils.createRequest(stanza));
expect(feature.save).toHaveBeenCalled();
expect(feature.get('preferences').default).toBe('never');
expect(feature.get('preferences')['default']).toBe('never');
// Restore
converse.message_archiving = 'never';

View File

@ -39,7 +39,7 @@
expect(chatview.model.get('minimized')).toBeTruthy();
expect(converse.minimized_chats.$el.is(':visible')).toBeTruthy();
expect(converse.minimized_chats.keys().length).toBe(2);
expect(_.contains(converse.minimized_chats.keys(), contact_jid)).toBeTruthy();
expect(_.includes(converse.minimized_chats.keys(), contact_jid)).toBeTruthy();
}));
it("can be toggled to hide or show minimized chats", mock.initConverse(function (converse) {

View File

@ -1,15 +1,16 @@
/*global converse */
(function (root, factory) {
define([
"jquery",
"converse-api",
"mock",
"test_utils",
"utils",
"transcripts"
], factory
);
} (this, function ($, mock, test_utils, utils, transcripts) {
} (this, function (converse_api, mock, test_utils, utils, transcripts) {
var _ = converse_api.env._;
var $ = converse_api.env.jQuery;
var Strophe = converse_api.env.Strophe;
var IGNORED_TAGS = [
'stream:features',
@ -63,7 +64,7 @@
if (el.nodeType === 3) {
return; // Ignore text
}
if (_.contains(IGNORED_TAGS, el.nodeName.toLowerCase())) {
if (_.includes(IGNORED_TAGS, el.nodeName.toLowerCase())) {
return;
}
var _stanza = traverseElement(el);

View File

@ -43,7 +43,7 @@
expect(context.show_toolbar).toBeFalsy();
expect(context.chatview_avatar_width).toBe(32);
expect(context.chatview_avatar_height).toBe(48);
expect(Object.keys(context.visible_toolbar_buttons)).toEqual(Object.keys(settings.visible_toolbar_buttons));
expect(_.keys(context.visible_toolbar_buttons)).toEqual(_.keys(settings.visible_toolbar_buttons));
expect(context.visible_toolbar_buttons.emoticons).toBeFalsy();
expect(context.visible_toolbar_buttons.call).toBeFalsy();
expect(context.visible_toolbar_buttons.toggle_occupants).toBeFalsy();
@ -57,7 +57,7 @@
}
};
utils.applyUserSettings(context, settings, user_settings);
expect(Object.keys(context.visible_toolbar_buttons)).toEqual(Object.keys(settings.visible_toolbar_buttons));
expect(_.keys(context.visible_toolbar_buttons)).toEqual(_.keys(settings.visible_toolbar_buttons));
expect(context.visible_toolbar_buttons.toggle_occupants).toBeTruthy();
});
});

View File

@ -47,10 +47,10 @@
},
'set': function (value, message) {
var data = {'status': value};
if (!_.contains(_.keys(converse.STATUS_WEIGHTS), value)) {
if (!_.includes(_.keys(converse.STATUS_WEIGHTS), value)) {
throw new Error('Invalid availability value. See https://xmpp.org/rfcs/rfc3921.html#rfc.section.2.2.2.1');
}
if (typeof message === "string") {
if (_.isString(message)) {
data.status_message = message;
}
converse.xmppstatus.sendPresence(value);
@ -68,17 +68,17 @@
},
'settings': {
'get': function (key) {
if (_.contains(Object.keys(converse.default_settings), key)) {
if (_.includes(_.keys(converse.default_settings), key)) {
return converse[key];
}
},
'set': function (key, val) {
var o = {};
if (typeof key === "object") {
_.assignIn(converse, _.pick(key, Object.keys(converse.default_settings)));
} else if (typeof key === "string") {
if (_.isObject(key)) {
_.assignIn(converse, _.pick(key, _.keys(converse.default_settings)));
} else if (_.isString("string")) {
o[key] = val;
_.assignIn(converse, _.pick(o, Object.keys(converse.default_settings)));
_.assignIn(converse, _.pick(o, _.keys(converse.default_settings)));
}
}
},
@ -91,15 +91,15 @@
}
return null;
};
if (typeof jids === "undefined") {
if (_.isUndefined(jids)) {
jids = converse.roster.pluck('jid');
} else if (typeof jids === "string") {
} else if (_.isString(jids)) {
return _transform(jids);
}
return _.map(jids, _transform);
},
'add': function (jid, name) {
if (typeof jid !== "string" || jid.indexOf('@') < 0) {
if (!_.isString(jid) || !_.includes(jid, '@')) {
throw new TypeError('contacts.add: invalid jid');
}
converse.roster.addAndSubscribe(jid, _.isEmpty(name)? jid: name);
@ -108,10 +108,10 @@
'chats': {
'open': function (jids) {
var chatbox;
if (typeof jids === "undefined") {
if (_.isUndefined(jids)) {
converse.log("chats.open: You need to provide at least one JID", "error");
return null;
} else if (typeof jids === "string") {
} else if (_.isString(jids)) {
chatbox = converse.wrappedChatBox(
converse.chatboxes.getChatBox(jids, true).trigger('show')
);
@ -125,7 +125,7 @@
});
},
'get': function (jids) {
if (typeof jids === "undefined") {
if (_.isUndefined(jids)) {
var result = [];
converse.chatboxes.each(function (chatbox) {
// FIXME: Leaky abstraction from MUC. We need to add a
@ -135,13 +135,14 @@
}
});
return result;
} else if (typeof jids === "string") {
} else if (_.isString(jids)) {
return converse.wrappedChatBox(converse.chatboxes.getChatBox(jids));
}
return _.map(jids,
_.partial(
_.compose(
converse.wrappedChatBox.bind(converse), converse.chatboxes.getChatBox.bind(converse.chatboxes)
_.flow(
converse.chatboxes.getChatBox.bind(converse.chatboxes),
converse.wrappedChatBox.bind(converse)
), _, true
)
);
@ -149,7 +150,7 @@
},
'tokens': {
'get': function (id) {
if (!converse.expose_rid_and_sid || typeof converse.connection === "undefined") {
if (!converse.expose_rid_and_sid || _.isUndefined(converse.connection)) {
return null;
}
if (id.toLowerCase() === 'rid') {
@ -170,7 +171,7 @@
converse.off(evt, handler);
},
'stanza': function (name, options, handler) {
if (typeof options === 'function') {
if (_.isFunction(options)) {
handler = options;
options = {};
} else {

View File

@ -207,7 +207,7 @@
model: converse.Bookmark,
initialize: function () {
this.on('add', _.compose(this.markRoomAsBookmarked, this.openBookmarkedRoom));
this.on('add', _.flow(this.openBookmarkedRoom, this.markRoomAsBookmarked));
this.on('remove', this.markRoomAsUnbookmarked, this);
this.on('remove', this.sendBookmarkStanza, this);
@ -369,7 +369,7 @@
this.render();
},
render: function (cfg) {
render: function () {
this.$el.html(converse.templates.bookmarks_list({
'toggle_state': this.list_model.get('toggle-state'),
'desc_bookmarks': __('Click to toggle the bookmarks list'),
@ -378,7 +378,7 @@
if (this.list_model.get('toggle-state') !== converse.OPENED) {
this.$('.bookmarks').hide();
}
this.model.each(this.renderBookmarkListElement, this);
this.model.each(this.renderBookmarkListElement.bind(this));
var controlboxview = converse.chatboxviews.get('controlbox');
if (!_.isUndefined(controlboxview)) {
this.$el.prependTo(controlboxview.$('#chatrooms'));

View File

@ -221,12 +221,12 @@
*/
var that = this;
var insert = prepend ? this.$content.prepend : this.$content.append;
_.compose(
this.scrollDownMessageHeight.bind(this),
_.flow(
function ($el) {
insert.call(that.$content, $el);
return $el;
}
},
this.scrollDownMessageHeight.bind(this)
)(this.renderMessage(attrs));
},
@ -282,18 +282,22 @@
msg_dates.push(current_msg_date);
msg_dates.sort();
idx = msg_dates.indexOf(current_msg_date)-1;
_.compose(
this.scrollDownMessageHeight.bind(this),
function ($el) {
$el.insertAfter(this.$content.find('.chat-message[data-isodate="'+msg_dates[idx]+'"]'));
return $el;
}.bind(this)
)(this.renderMessage(attrs));
_.flow(
function ($el) {
$el.insertAfter(this.$content.find('.chat-message[data-isodate="'+msg_dates[idx]+'"]'));
return $el;
}.bind(this),
this.scrollDownMessageHeight.bind(this)
)(this.renderMessage(attrs));
},
getExtraMessageTemplateAttributes: function (attrs) {
// Provides a hook for sending more attributes to the
// message template.
getExtraMessageTemplateAttributes: function () {
/* Provides a hook for sending more attributes to the
* message template.
*
* Parameters:
* (Object) attrs: An object containing message attributes.
*/
return {};
},
@ -373,7 +377,7 @@
this.clear_status_timeout = window.setTimeout(this.clearStatusNotification.bind(this), 30000);
} else if (message.get('chat_state') === converse.PAUSED) {
this.showStatusNotification(message.get('fullname')+' '+__('has stopped typing'));
} else if (_.contains([converse.INACTIVE, converse.ACTIVE], message.get('chat_state'))) {
} else if (_.includes([converse.INACTIVE, converse.ACTIVE], message.get('chat_state'))) {
this.$content.find('div.chat-event').remove();
} else if (message.get('chat_state') === converse.GONE) {
this.showStatusNotification(message.get('fullname')+' '+__('has gone away'));
@ -435,7 +439,7 @@
* Parameters:
* (Object) message - The message Backbone object that was added.
*/
if (typeof this.clear_status_timeout !== 'undefined') {
if (!_.isUndefined(this.clear_status_timeout)) {
window.clearTimeout(this.clear_status_timeout);
delete this.clear_status_timeout;
}
@ -544,7 +548,7 @@
* (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') {
if (!_.isUndefined(this.chat_state_timeout)) {
window.clearTimeout(this.chat_state_timeout);
delete this.chat_state_timeout;
}
@ -649,7 +653,7 @@
showStatusMessage: function (msg) {
msg = msg || this.model.get('status');
if (typeof msg === "string") {
if (_.isString(msg)) {
this.$el.find('p.user-custom-message').text(msg).attr('title', msg);
}
return this;
@ -757,12 +761,12 @@
},
show: function (focus) {
if (typeof this.debouncedShow === 'undefined') {
if (_.isUndefined(this.debouncedShow)) {
/* 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.
*/
this.debouncedShow = _.debounce(this._show, 250, true);
this.debouncedShow = _.debounce(this._show, 250, {'leading': true});
}
this.debouncedShow.apply(this, arguments);
return this;

View File

@ -120,7 +120,7 @@
onChatBoxesFetched: function (collection, resp) {
this.__super__.onChatBoxesFetched.apply(this, arguments);
if (!_.include(_.pluck(resp, 'id'), 'controlbox')) {
if (!_.includes(_.map(resp, 'id'), 'controlbox')) {
this.add({
id: 'controlbox',
box_id: 'controlbox'
@ -363,8 +363,12 @@
return this;
},
showHelpMessages: function (msgs) {
// Override showHelpMessages in ChatBoxView, for now do nothing.
showHelpMessages: function () {
/* Override showHelpMessages in ChatBoxView, for now do nothing.
*
* Parameters:
* (Array) msgs: Array of messages
*/
return;
}
});
@ -431,7 +435,7 @@
if (errors) { return; }
if (converse.locked_domain) {
jid = Strophe.escapeNode(jid) + '@' + converse.locked_domain;
} else if (converse.default_domain && jid.indexOf('@') === -1) {
} else if (converse.default_domain && !_.includes(jid, '@')) {
jid = jid + '@' + converse.default_domain;
}
this.connect($form, jid, password);
@ -723,7 +727,7 @@
},
updateOnlineCount: _.debounce(function () {
if (typeof converse.roster === 'undefined') {
if (_.isUndefined(converse.roster)) {
return;
}
var $count = this.$('#online-count');

View File

@ -117,8 +117,8 @@
converse.log = function (txt, level) {
var logger;
if (typeof console === "undefined" || typeof console.log === "undefined") {
logger = { log: function () {}, error: function () {} };
if (_.isUndefined(console) || _.isUndefined(console.log)) {
logger = { log: _.noop, error: _.noop };
} else {
logger = console;
}
@ -134,11 +134,11 @@
converse.initialize = function (settings, callback) {
"use strict";
settings = typeof settings !== "undefined" ? settings : {};
settings = !_.isUndefined(settings) ? settings : {};
var init_deferred = new $.Deferred();
var converse = this;
if (typeof converse.chatboxes !== 'undefined') {
if (!_.isUndefined(converse.chatboxes)) {
// Looks like converse.initialized was called again without logging
// out or disconnecting in the previous session.
// This happens in tests.
@ -190,8 +190,8 @@
// Detect support for the user's locale
// ------------------------------------
var locales = typeof locales === "undefined" ? {} : locales;
this.isConverseLocale = function (locale) { return typeof locales[locale] !== "undefined"; };
var locales = _.isUndefined(locales) ? {} : locales;
this.isConverseLocale = function (locale) { return !_.isUndefined(locales[locale]); };
this.isMomentLocale = function (locale) { return moment.locale() !== moment.locale(locale); };
if (!moment.locale) { //moment.lang is deprecated after 2.8.1, use moment.locale instead
moment.locale = moment.lang;
@ -248,7 +248,7 @@
};
_.assignIn(this, this.default_settings);
// Allow only whitelisted configuration attributes to be overwritten
_.assignIn(this, _.pick(settings, Object.keys(this.default_settings)));
_.assignIn(this, _.pick(settings, _.keys(this.default_settings)));
// BBB
if (this.prebind === true) { this.authentication = converse.PREBIND; }
@ -265,7 +265,7 @@
// Module-level variables
// ----------------------
this.callback = callback || function () {};
this.callback = callback || _.noop;
/* When reloading the page:
* For new sessions, we need to send out a presence stanza to notify
* the server/network that we're online.
@ -300,11 +300,14 @@
};
this.sendCSI = function (stat) {
/* Send out a Chat Status Notification (XEP-0352) */
if (converse.features[Strophe.NS.CSI] || true) {
converse.connection.send($build(stat, {xmlns: Strophe.NS.CSI}));
converse.inactive = (stat === converse.INACTIVE) ? true : false;
}
/* Send out a Chat Status Notification (XEP-0352)
*
* Parameters:
* (String) stat: The user's chat status
*/
// XXX if (converse.features[Strophe.NS.CSI] || true) {
converse.connection.send($build(stat, {xmlns: Strophe.NS.CSI}));
converse.inactive = (stat === converse.INACTIVE) ? true : false;
};
this.onUserActivity = function () {
@ -400,7 +403,7 @@
};
this.reconnect = _.debounce(function (condition) {
this.reconnect = _.debounce(function () {
converse.log('The connection has dropped, attempting to reconnect.');
converse.giveFeedback(
__("Reconnecting"),
@ -547,7 +550,7 @@
this.logOut = function () {
converse.setDisconnectionCause(converse.LOGOUT, undefined, true);
if (typeof converse.connection !== 'undefined') {
if (!_.isUndefined(converse.connection)) {
converse.connection.disconnect();
}
converse.chatboxviews.closeAllChatBoxes();
@ -659,7 +662,7 @@
};
this.unregisterPresenceHandler = function () {
if (typeof converse.presence_ref !== 'undefined') {
if (!_.isUndefined(converse.presence_ref)) {
converse.connection.deleteHandler(converse.presence_ref);
delete converse.presence_ref;
}
@ -748,7 +751,7 @@
this.RosterContact = Backbone.Model.extend({
initialize: function (attributes, options) {
initialize: function (attributes) {
var jid = attributes.jid;
var bare_jid = Strophe.getBareJidFromJid(jid);
var resource = Strophe.getResourceFromJid(jid);
@ -804,7 +807,7 @@
}));
},
ackUnsubscribe: function (jid) {
ackUnsubscribe: function () {
/* Upon receiving the presence stanza of type "unsubscribed",
* the user SHOULD acknowledge receipt of that subscription state
* notification by sending a presence stanza of type "unsubscribe"
@ -919,7 +922,7 @@
},
subscribeToSuggestedItems: function (msg) {
$(msg).find('item').each(function (i, items) {
$(msg).find('item').each(function () {
if (this.getAttribute('action') === 'add') {
converse.roster.addAndSubscribe(
this.getAttribute('jid'), null, converse.xmppstatus.get('fullname'));
@ -964,7 +967,7 @@
var iq = $iq({type: 'set'})
.c('query', {xmlns: Strophe.NS.ROSTER})
.c('item', { jid: jid, name: name });
_.map(groups, function (group) { iq.c('group').t(group).up(); });
_.each(groups, function (group) { iq.c('group').t(group).up(); });
converse.connection.sendIQ(iq, callback, errback);
},
@ -984,7 +987,7 @@
groups = groups || [];
name = _.isEmpty(name)? jid: name;
this.sendContactAddIQ(jid, name, groups,
function (iq) {
function () {
var contact = this.create(_.assignIn({
ask: undefined,
fullname: name,
@ -1010,7 +1013,7 @@
if (item) {
resources = item.get('resources');
if (resources) {
if (_.indexOf(resources, resource) === -1) {
if (!_.includes(resources, resource)) {
resources.push(resource);
item.set({'resources': resources});
}
@ -1044,7 +1047,7 @@
ignored = _.union(ignored, ['dnd', 'xa', 'away']);
}
for (i=0; i<models_length; i++) {
if (_.indexOf(ignored, models[i].get('chat_status')) === -1) {
if (!_.includes(ignored, models[i].get('chat_status'))) {
count++;
}
}
@ -1107,13 +1110,10 @@
*/
var jid = item.getAttribute('jid');
if (this.isSelf(jid)) { return; }
var groups = [],
var groups = _.map(item.getElementsByTagName('group'), Strophe.getText),
contact = this.get(jid),
ask = item.getAttribute("ask"),
subscription = item.getAttribute("subscription");
$.map(item.getElementsByTagName('group'), function (group) {
groups.push(Strophe.getText(group));
});
if (!contact) {
if ((subscription === "none" && ask === null) || (subscription === "remove")) {
return; // We're lazy when adding contacts.
@ -1245,7 +1245,7 @@
this.RosterGroup = Backbone.Model.extend({
initialize: function (attributes, options) {
initialize: function (attributes) {
this.set(_.assignIn({
description: DESC_GROUP_TOGGLE,
state: converse.OPENED
@ -1360,7 +1360,7 @@
};
},
createMessage: function ($message, $delay, original_stanza) {
createMessage: function () {
return this.messages.create(this.getMessageAttributes.apply(this, arguments));
}
});
@ -1617,8 +1617,8 @@
constructPresence: function (type, status_message) {
var presence;
type = typeof type === 'string' ? type : (this.get('status') || converse.default_state);
status_message = typeof status_message === 'string' ? status_message : undefined;
type = _.isString(type) ? type : (this.get('status') || converse.default_state);
status_message = _.isString(status_message) ? status_message : undefined;
// Most of these presence types are actually not explicitly sent,
// but I add all of them here for reference and future proofing.
if ((type === 'unavailable') ||

View File

@ -110,7 +110,7 @@
* We need this information for the drag-resizing feature.
*/
var $flyout = this.$el.find('.box-flyout');
if (typeof this.model.get('height') === 'undefined') {
if (_.isUndefined(this.model.get('height'))) {
var height = $flyout.height();
var width = $flyout.width();
this.model.set('height', height);
@ -212,7 +212,7 @@
this.setChatBoxHeight(this.height);
}
}
if (converse.resizing.direction.indexOf('left') !== -1) {
if (_.includes(converse.resizing.direction, 'left')) {
diff = this.prev_pageX - ev.pageX;
if (diff) {
this.width = ((this.width+diff) > (this.model.get('min_width') || 0)) ? (this.width+diff) : this.model.get('min_width');
@ -292,9 +292,9 @@
* default_value. If value is close enough to
* default_value, then default_value is returned instead.
*/
if (typeof value === 'undefined') {
if (_.isUndefined(value)) {
return undefined;
} else if (typeof default_value === 'undefined') {
} else if (_.isUndefined(default_value)) {
return value;
}
var resistance = 10;

View File

@ -76,7 +76,7 @@
},
initialize: function () {
if (typeof this.setDimensions !== "undefined") {
if (!_.isUndefined(this.setDimensions)) {
// setDimensions is defined for dragresize
$(window).on('resize', _.debounce(this.setDimensions.bind(this), 100));
}
@ -103,7 +103,7 @@
)
)
);
if (typeof this.setWidth !== "undefined") {
if (!_.isUndefined(this.setWidth)) {
// setWidth is defined for dragresize
$(window).on('resize', _.debounce(this.setWidth.bind(this), 100));
}

View File

@ -99,7 +99,7 @@
converse.queryForArchivedMessages(options, function (messages) {
this.clearSpinner();
if (messages.length) {
_.map(messages, converse.chatboxes.onMessage.bind(converse.chatboxes));
_.each(messages, converse.chatboxes.onMessage.bind(converse.chatboxes));
}
}.bind(this),
function () {
@ -163,7 +163,7 @@
* get the next or previous page in the result set.
*/
var date, messages = [];
if (typeof options === "function") {
if (_.isFunction(options)) {
callback = options;
errback = callback;
}
@ -176,14 +176,14 @@
*/
var queryid = converse.connection.getUniqueId();
var attrs = {'type':'set'};
if (typeof options !== "undefined" && options.groupchat) {
if (!_.isUndefined(options) && options.groupchat) {
if (!options['with']) {
throw new Error('You need to specify a "with" value containing the chat room JID, when querying groupchat messages.');
}
attrs.to = options['with'];
}
var stanza = $iq(attrs).c('query', {'xmlns':Strophe.NS.MAM, 'queryid':queryid});
if (typeof options !== "undefined") {
if (!_.isUndefined(options)) {
stanza.c('x', {'xmlns':Strophe.NS.XFORM, 'type': 'submit'})
.c('field', {'var':'FORM_TYPE', 'type': 'hidden'})
.c('value').t(Strophe.NS.MAM).up().up();
@ -209,7 +209,7 @@
}
}
if (typeof callback === "function") {
if (_.isFunction(callback)) {
converse.connection.addHandler(function (message) {
var $msg = $(message), rsm,
$fin = $msg.find('fin[xmlns="'+Strophe.NS.MAM+'"]');

View File

@ -255,7 +255,7 @@
}
var oldest_chat, boxes_width, view,
$minimized = converse.minimized_chats.$el,
minimized_width = _.contains(this.model.pluck('minimized'), true) ? $minimized.outerWidth(true) : 0,
minimized_width = _.includes(this.model.pluck('minimized'), true) ? $minimized.outerWidth(true) : 0,
new_id = newchat ? newchat.model.get('id') : null;
boxes_width = _.reduce(this.xget(new_id), function (memo, view) {
@ -283,7 +283,7 @@
exclude_ids.push('controlbox');
var i = 0;
var model = this.model.sort().at(i);
while (_.contains(exclude_ids, model.get('id')) ||
while (_.includes(exclude_ids, model.get('id')) ||
model.get('minimized') === true) {
i++;
model = this.model.at(i);
@ -370,7 +370,7 @@
this.model.messages.off('add',null,this);
this.remove();
this.model.maximize();
}, 200, true)
}, 200, {'leading': true})
});
converse.MinimizedChats = Backbone.Overview.extend({

View File

@ -496,13 +496,15 @@
this.insertIntoTextArea(ev.target.textContent);
},
requestMemberList: function (affiliation) {
requestMemberList: function (chatroom_jid, affiliation) {
/* Send an IQ stanza to the server, asking it for the
* member-list of this room.
*
* See: http://xmpp.org/extensions/xep-0045.html#modifymember
*
* Parameters:
* (String) chatroom_jid: The JID of the chatroom for
* which the member-list is being requested
* (String) affiliation: The specific member list to
* fetch. 'admin', 'owner' or 'member'.
*
@ -512,7 +514,7 @@
*/
var deferred = new $.Deferred();
affiliation = affiliation || 'member';
var iq = $iq({to: this.model.get('jid'), type: "get"})
var iq = $iq({to: chatroom_jid, type: "get"})
.c("query", {xmlns: Strophe.NS.MUC_ADMIN})
.c("item", {'affiliation': affiliation});
converse.connection.sendIQ(iq, deferred.resolve, deferred.reject);
@ -561,8 +563,8 @@
* (Array) new_list: Array containing the new affiliations
* (Array) old_list: Array containing the old affiliations
*/
var new_jids = _.pluck(new_list, 'jid');
var old_jids = _.pluck(old_list, 'jid');
var new_jids = _.map(new_list, 'jid');
var old_jids = _.map(old_list, 'jid');
// Get the new affiliations
var delta = _.map(_.difference(new_jids, old_jids), function (jid) {
@ -587,6 +589,30 @@
return delta;
},
sendAffiliationIQ: function (chatroom_jid, affiliation, member) {
/* Send an IQ stanza specifying an affiliation change.
*
* Paremeters:
* (String) chatroom_jid: JID of the relevant room
* (String) affiliation: affiliation (could also be stored
* on the member object).
* (Object) member: Map containing the member's jid and
* optionally a reason and affiliation.
*/
var deferred = new $.Deferred();
var iq = $iq({to: chatroom_jid, type: "set"})
.c("query", {xmlns: Strophe.NS.MUC_ADMIN})
.c("item", {
'affiliation': member.affiliation || affiliation,
'jid': member.jid
});
if (!_.isUndefined(member.reason)) {
iq.c("reason", member.reason);
}
converse.connection.sendIQ(iq, deferred.resolve, deferred.reject);
return deferred;
},
setAffiliation: function (affiliation, members) {
/* Send IQ stanzas to the server to set an affiliation for
* the provided JIDs.
@ -599,6 +625,7 @@
* Related ticket: https://prosody.im/issues/issue/795
*
* Parameters:
* (String) affiliation: The affiliation
* (Object) members: A map of jids, affiliations and
* optionally reasons. Only those entries with the
* same affiliation as being currently set will be
@ -615,21 +642,11 @@
return _.isUndefined(member.affiliation) ||
member.affiliation === affiliation;
});
var promises = _.map(members, function (member) {
var deferred = new $.Deferred();
var iq = $iq({to: this.model.get('jid'), type: "set"})
.c("query", {xmlns: Strophe.NS.MUC_ADMIN})
.c("item", {
'affiliation': member.affiliation || affiliation,
'jid': member.jid
});
if (!_.isUndefined(member.reason)) {
iq.c("reason", member.reason);
}
converse.connection.sendIQ(iq, deferred.resolve, deferred.reject);
return deferred;
}, this);
return $.when.apply($, promises);
var promises = _.map(
members,
_.partial(this.sendAffiliationIQ, this.model.get('jid'), affiliation)
);
return $.when.apply($, promises);
},
setAffiliations: function (members, onSuccess, onError) {
@ -648,8 +665,8 @@
onSuccess(null);
return;
}
var affiliations = _.uniq(_.pluck(members, 'affiliation'));
var promises = _.map(affiliations, _.partial(this.setAffiliation, _, members), this);
var affiliations = _.uniq(_.map(members, 'affiliation'));
var promises = _.map(affiliations, _.partial(this.setAffiliation.bind(this), _, members));
$.when.apply($, promises).done(onSuccess).fail(onError);
},
@ -661,24 +678,20 @@
* Any amount of XMLElement objects, representing the IQ
* stanzas.
*/
return _.flatten(_.map(arguments, this.parseMemberListIQ));
return _.flatMap(arguments, this.parseMemberListIQ);
},
getJidsWithAffiliations: function (affiliations) {
/* Returns a map of JIDs that have the affiliations
* as provided.
*/
if (typeof affiliations === "string") {
if (_.isString(affiliations)) {
affiliations = [affiliations];
}
var that = this;
var deferred = new $.Deferred();
var promises = [];
_.each(affiliations, function (affiliation) {
promises.push(that.requestMemberList(affiliation));
});
var promises = _.map(affiliations, _.partial(this.requestMemberList, this.model.get('jid')));
$.when.apply($, promises).always(
_.compose(deferred.resolve, this.marshallAffiliationIQs.bind(this))
_.flow(this.marshallAffiliationIQs.bind(this), deferred.resolve)
);
return deferred.promise();
},
@ -838,7 +851,7 @@
clearChatRoomMessages: function (ev) {
/* Remove all messages from the chat room UI.
*/
if (typeof ev !== "undefined") { ev.stopPropagation(); }
if (!_.isUndefined(ev)) { ev.stopPropagation(); }
var result = confirm(__("Are you sure you want to clear the messages from this room?"));
if (result === true) {
this.$content.empty();
@ -995,7 +1008,7 @@
room_no_longer_anon || room_now_semi_anon || room_now_fully_anon) {
this.getRoomFeatures();
}
_.compose(this.onChatRoomMessage.bind(this), this.showStatusMessages.bind(this))(stanza);
_.flow(this.showStatusMessages.bind(this), this.onChatRoomMessage.bind(this))(stanza);
return true;
},
@ -1354,7 +1367,7 @@
if (_.isUndefined(ev) && this.model.get('auto_configure')) {
this.fetchRoomConfiguration().then(that.autoConfigureChatRoom.bind(that));
} else {
if (typeof ev !== 'undefined' && ev.preventDefault) {
if (!_.isUndefined(ev) && ev.preventDefault) {
ev.preventDefault();
}
this.showSpinner();
@ -1472,7 +1485,7 @@
*/
this.$('.chatroom-body').children().addClass('hidden');
this.$('span.centered.spinner').remove();
if (typeof message !== "string") {
if (!_.isString(message)) {
message = '';
}
this.$('.chatroom-body').append(
@ -1583,7 +1596,7 @@
'messages': _.reject(_.map(statuses, mapper), _.isUndefined),
};
// 2. Get disconnection messages based on the <status> elements
var codes = _.map(statuses, function (stat) { return stat.getAttribute('code'); });
var codes = _.invokeMap(statuses, Element.prototype.getAttribute, 'code');
var disconnection_codes = _.intersection(codes, _.keys(converse.muc.disconnect_messages));
var disconnected = is_self && disconnection_codes.length > 0;
if (disconnected) {
@ -1649,10 +1662,12 @@
// Unfortunately this doesn't work (returns empty list)
// var elements = stanza.querySelectorAll('x[xmlns="'+Strophe.NS.MUC_USER+'"]');
var elements = _.chain(stanza.querySelectorAll('x')).filter(function (x) {
return x.getAttribute('xmlns') === Strophe.NS.MUC_USER;
}).value();
var elements = _.filter(
stanza.querySelectorAll('x'),
function (x) {
return x.getAttribute('xmlns') === Strophe.NS.MUC_USER;
}
);
var notifications = _.map(
elements,
_.partial(this.parseXUserElement.bind(this), _, stanza, is_self)
@ -1845,7 +1860,7 @@
function (messages) {
that.clearSpinner();
if (messages.length) {
_.map(messages, that.onChatRoomMessage.bind(that));
_.each(messages, that.onChatRoomMessage.bind(that));
}
},
function () {
@ -2027,11 +2042,12 @@
}, {
name: 'contacts-dataset',
source: function (q, cb) {
var results = [];
_.each(converse.roster.filter(utils.contains(['fullname', 'jid'], q)), function (n) {
results.push({value: n.get('fullname'), jid: n.get('jid')});
});
cb(results);
cb(_.map(
converse.roster.filter(utils.contains(['fullname', 'jid'], q)),
function (n) {
return {value: n.get('fullname'), jid: n.get('jid')};
}
));
},
templates: {
suggestion: _.template('<p data-jid="{{jid}}">{{value}}</p>')
@ -2331,7 +2347,7 @@
'box_id': b64_sha1(room_jid),
'password': $x.attr('password')
});
if (!_.contains(
if (!_.includes(
[Strophe.Status.CONNECTING, Strophe.Status.CONNECTED],
chatroom.get('connection_status'))
) {
@ -2359,9 +2375,9 @@
* settings).
*/
_.each(converse.auto_join_rooms, function (room) {
if (typeof room === 'string') {
if (_.isString(room)) {
converse_api.rooms.open(room);
} else if (typeof room === 'object') {
} else if (_.isObject(room)) {
converse_api.rooms.open(room.jid, room.nick);
} else {
converse.log('Invalid room criteria specified for "auto_join_rooms"', 'error');
@ -2388,26 +2404,26 @@
_.extend(converse_api, {
'rooms': {
'close': function (jids) {
if (typeof jids === "undefined") {
if (_.isUndefined(jids)) {
converse.chatboxviews.each(function (view) {
if (view.is_chatroom && view.model) {
view.close();
}
});
} else if (typeof jids === "string") {
} else if (_.isString(jids)) {
var view = converse.chatboxviews.get(jids);
if (view) { view.close(); }
} else {
_.map(jids, function (jid) {
_.each(jids, function (jid) {
var view = converse.chatboxviews.get(jid);
if (view) { view.close(); }
});
}
},
'open': function (jids, attrs) {
if (typeof attrs === "string") {
if (_.isString(attrs)) {
attrs = {'nick': attrs};
} else if (typeof attrs === "undefined") {
} else if (_.isUndefined(attrs)) {
attrs = {};
}
if (_.isUndefined(attrs.maximize)) {
@ -2416,20 +2432,20 @@
if (!attrs.nick && converse.muc_nickname_from_jid) {
attrs.nick = Strophe.getNodeFromJid(converse.bare_jid);
}
if (typeof jids === "undefined") {
if (_.isUndefined(jids)) {
throw new TypeError('rooms.open: You need to provide at least one JID');
} else if (typeof jids === "string") {
} else if (_.isString(jids)) {
return converse.getWrappedChatRoom(jids, attrs, converse.createChatRoom);
}
return _.map(jids, _.partial(converse.getWrappedChatRoom, _, attrs, converse.createChatRoom));
},
'get': function (jids, attrs, create) {
if (typeof attrs === "string") {
if (_.isString(attrs)) {
attrs = {'nick': attrs};
} else if (typeof attrs === "undefined") {
} else if (_.isUndefined(attrs)) {
attrs = {};
}
if (typeof jids === "undefined") {
if (_.isUndefined(jids)) {
var result = [];
converse.chatboxes.each(function (chatbox) {
if (chatbox.get('type') === 'chatroom') {
@ -2442,7 +2458,7 @@
if (!attrs.nick) {
attrs.nick = Strophe.getNodeFromJid(converse.bare_jid);
}
if (typeof jids === "string") {
if (_.isString(jids)) {
return converse.getWrappedChatRoom(jids, attrs, fetcher);
}
return _.map(jids, _.partial(converse.getWrappedChatRoom, _, attrs, fetcher));

View File

@ -68,7 +68,7 @@
return false;
}
var mentioned = (new RegExp("\\b"+room.get('nick')+"\\b")).test($body.text());
notify_all = notify_all === true || (_.isArray(notify_all) && _.contains(notify_all, room_jid));
notify_all = notify_all === true || (_.isArray(notify_all) && _.includes(notify_all, room_jid));
if (sender === room.get('nick') || (!notify_all && !mentioned)) {
return false;
}
@ -102,7 +102,7 @@
// feature, but no browser currently supports it.
// https://developer.mozilla.org/en-US/docs/Web/API/notification/sound
var audio;
if (converse.play_sounds && typeof Audio !== "undefined") {
if (converse.play_sounds && !_.isUndefined(Audio)) {
audio = new Audio(converse.sounds_path+"msg_received.ogg");
if (audio.canPlayType('/audio/ogg')) {
audio.play();
@ -130,7 +130,7 @@
*/
var n, title, contact_jid, roster_item,
from_jid = $message.attr('from');
if ($message.attr('type') === 'headline' || from_jid.indexOf('@') === -1) {
if ($message.attr('type') === 'headline' || !_.includes(from_jid, '@')) {
// XXX: 2nd check is workaround for Prosody which doesn't
// give type "headline"
title = __(___("Notification from %1$s"), from_jid);
@ -138,7 +138,7 @@
if ($message.attr('type') === 'groupchat') {
title = __(___("%1$s says"), Strophe.getResourceFromJid(from_jid));
} else {
if (typeof converse.roster === 'undefined') {
if (_.isUndefined(converse.roster)) {
converse.log("Could not send notification, because roster is undefined", "error");
return;
}
@ -159,7 +159,7 @@
/* Creates an HTML5 Notification to inform of a change in a
* contact's chat state.
*/
if (_.contains(converse.chatstate_notification_blacklist, contact.jid)) {
if (_.includes(converse.chatstate_notification_blacklist, contact.jid)) {
// Don't notify if the user is being ignored.
return;
}
@ -243,7 +243,7 @@
converse.requestPermission = function (evt) {
if (converse.supports_html5_notification &&
! _.contains(['denied', 'granted'], Notification.permission)) {
! _.includes(['denied', 'granted'], Notification.permission)) {
// Ask user to enable HTML5 notifications
Notification.requestPermission();
}

View File

@ -30,14 +30,13 @@
// For translations
var __ = utils.__.bind(converse);
var HAS_CSPRNG = ((typeof crypto !== 'undefined') &&
((typeof crypto.randomBytes === 'function') ||
(typeof crypto.getRandomValues === 'function')
var HAS_CSPRNG = ((!_.isUndefined(crypto)) &&
((_.isFunction(crypto.randomBytes)) || (_.isFunction(crypto.getRandomValues))
));
var HAS_CRYPTO = HAS_CSPRNG && (
(typeof CryptoJS !== "undefined") &&
(typeof otr.OTR !== "undefined") &&
(typeof otr.DSA !== "undefined")
(!_.isUndefined(CryptoJS)) &&
(!_.isUndefined(otr.OTR)) &&
(!_.isUndefined(otr.DSA))
);
var UNENCRYPTED = 0;
@ -105,7 +104,7 @@
* "visible" OTR messages being exchanged.
*/
return this.__super__.shouldPlayNotification.apply(this, arguments) &&
!(utils.isOTRMessage($message[0]) && !_.contains([UNVERIFIED, VERIFIED], this.get('otr_status')));
!(utils.isOTRMessage($message[0]) && !_.includes([UNVERIFIED, VERIFIED], this.get('otr_status')));
},
createMessage: function ($message, $delay, original_stanza) {
@ -119,7 +118,7 @@
if (text.match(/^\?OTRv23?/)) {
this.initiateOTR(text);
} else {
if (_.contains([UNVERIFIED, VERIFIED], this.get('otr_status'))) {
if (_.includes([UNVERIFIED, VERIFIED], this.get('otr_status'))) {
this.otr.receiveMsg(text);
} else {
if (text.match(/^\?OTR/)) {
@ -142,11 +141,11 @@
var pass, instance_tag, saved_key, pass_check;
if (converse.cache_otr_key) {
pass = converse.otr.getSessionPassphrase();
if (typeof pass !== "undefined") {
if (!_.isUndefined(pass)) {
instance_tag = window.sessionStorage[b64_sha1(this.id+'instance_tag')];
saved_key = window.sessionStorage[b64_sha1(this.id+'priv_key')];
pass_check = window.sessionStorage[b64_sha1(this.connection.jid+'pass_check')];
if (saved_key && instance_tag && typeof pass_check !== 'undefined') {
if (saved_key && instance_tag && !_.isUndefined(pass_check)) {
var decrypted = cipher.decrypt(CryptoJS.algo.AES, saved_key, pass);
var key = otr.DSA.parsePrivate(decrypted.toString(CryptoJS.enc.Latin1));
if (cipher.decrypt(CryptoJS.algo.AES, pass_check, pass).toString(CryptoJS.enc.Latin1) === 'match') {
@ -285,7 +284,7 @@
this.model.on('showReceivedOTRMessage', function (text) {
this.showMessage({'message': text, 'sender': 'them'});
}, this);
if ((_.contains([UNVERIFIED, VERIFIED], this.model.get('otr_status'))) || converse.use_otr_by_default) {
if ((_.includes([UNVERIFIED, VERIFIED], this.model.get('otr_status'))) || converse.use_otr_by_default) {
this.model.initiateOTR();
}
},
@ -319,7 +318,7 @@
return this.model.initiateOTR();
}
}
if (_.contains([UNVERIFIED, VERIFIED], this.model.get('otr_status'))) {
if (_.includes([UNVERIFIED, VERIFIED], this.model.get('otr_status'))) {
// Off-the-record encryption is active
this.model.otr.sendMsg(text);
this.model.trigger('showSentOTRMessage', text);
@ -372,7 +371,7 @@
},
endOTR: function (ev) {
if (typeof ev !== "undefined") {
if (!_.isUndefined(ev)) {
ev.preventDefault();
ev.stopPropagation();
}
@ -485,7 +484,7 @@
};
_.extend(converse.default_settings, settings);
_.extend(converse, settings);
_.extend(converse, _.pick(converse.user_settings, Object.keys(settings)));
_.extend(converse, _.pick(converse.user_settings, _.keys(settings)));
// Only allow OTR if we have the capability
converse.allow_otr = converse.allow_otr && HAS_CRYPTO;
@ -500,7 +499,7 @@
if (converse.authentication === 'prebind') {
var key = b64_sha1(converse.connection.jid),
pass = window.sessionStorage[key];
if (typeof pass === 'undefined') {
if (_.isUndefined(pass)) {
pass = Math.floor(Math.random()*4294967295).toString();
window.sessionStorage[key] = pass;
}
@ -516,7 +515,7 @@
if (converse.cache_otr_key) {
var cipher = CryptoJS.lib.PasswordBasedCipher;
var pass = this.getSessionPassphrase();
if (typeof pass !== "undefined") {
if (!_.isUndefined(pass)) {
// Encrypt the key and set in sessionStorage. Also store instance tag.
window.sessionStorage[b64_sha1(jid+'priv_key')] =
cipher.encrypt(CryptoJS.algo.AES, key.packPrivate(), pass).toString();

View File

@ -42,12 +42,12 @@
//
// var feature = converse.features.findWhere({'var': Strophe.NS.PING});
converse.lastStanzaDate = new Date();
if (typeof jid === 'undefined' || jid === null) {
if (_.isNil(jid)) {
jid = Strophe.getDomainFromJid(converse.bare_jid);
}
if (typeof timeout === 'undefined' ) { timeout = null; }
if (typeof success === 'undefined' ) { success = null; }
if (typeof error === 'undefined' ) { error = null; }
if (_.isUndefined(timeout) ) { timeout = null; }
if (_.isUndefined(success) ) { success = null; }
if (_.isUndefined(error) ) { error = null; }
if (converse.connection) {
converse.connection.ping.ping(jid, success, error, timeout);
return true;

View File

@ -51,7 +51,7 @@
// Add Strophe Statuses
var i = 0;
Object.keys(Strophe.Status).forEach(function (key) {
_.each(_.keys(Strophe.Status), function (key) {
i = Math.max(i, Strophe.Status[key]);
});
Strophe.Status.REGIFAIL = i + 1;
@ -211,7 +211,7 @@
};
_.extend(this, defaults);
if (settings) {
_.extend(this, _.pick(settings, Object.keys(defaults)));
_.extend(this, _.pick(settings, _.keys(defaults)));
}
},
@ -254,7 +254,7 @@
onRegistering: function (status, error) {
var that;
converse.log('onRegistering');
if (_.contains([
if (_.includes([
Strophe.Status.DISCONNECTED,
Strophe.Status.CONNFAIL,
Strophe.Status.REGIFAIL,
@ -320,7 +320,7 @@
}.bind(this));
} else {
// Show fields
_.each(Object.keys(this.fields), function (key) {
_.each(_.keys(this.fields), function (key) {
if (key === "username") {
$input = converse.templates.form_username({
domain: ' @'+this.domain,

View File

@ -110,8 +110,8 @@
a = a.get('name');
b = b.get('name');
var special_groups = _.keys(HEADER_WEIGHTS);
var a_is_special = _.contains(special_groups, a);
var b_is_special = _.contains(special_groups, b);
var a_is_special = _.includes(special_groups, a);
var b_is_special = _.includes(special_groups, b);
if (!a_is_special && !b_is_special ) {
return a.toLowerCase() < b.toLowerCase() ? -1 : (a.toLowerCase() > b.toLowerCase() ? 1 : 0);
} else if (a_is_special && b_is_special) {
@ -345,7 +345,7 @@
query = query.toLowerCase();
if (type === 'groups') {
_.each(this.getAll(), function (view, idx) {
if (view.model.get('name').toLowerCase().indexOf(query.toLowerCase()) === -1) {
if (!_.includes(view.model.get('name').toLowerCase(), query.toLowerCase())) {
view.hide();
} else if (view.model.contacts.length > 0) {
view.show();
@ -407,7 +407,7 @@
if (_.has(contact.changed, 'subscription')) {
if (contact.changed.subscription === 'from') {
this.addContactToGroup(contact, HEADER_PENDING_CONTACTS);
} else if (_.contains(['both', 'to'], contact.get('subscription'))) {
} else if (_.includes(['both', 'to'], contact.get('subscription'))) {
this.addExistingContact(contact);
}
}
@ -550,6 +550,7 @@
},
render: function () {
var that = this;
if (!this.mayBeShown()) {
this.$el.hide();
return this;
@ -568,10 +569,10 @@
_.each(classes_to_remove,
function (cls) {
if (this.el.className.indexOf(cls) !== -1) {
this.$el.removeClass(cls);
if (_.includes(that.el.className, cls)) {
that.$el.removeClass(cls);
}
}, this);
});
this.$el.addClass(chat_status).data('status', chat_status);
if ((ask === 'subscribe') || (subscription === 'from')) {
@ -861,7 +862,7 @@
},
onContactGroupChange: function (contact) {
var in_this_group = _.contains(contact.get('groups'), this.model.get('name'));
var in_this_group = _.includes(contact.get('groups'), this.model.get('name'));
var cid = contact.get('id');
var in_this_overview = !this.get(cid);
if (in_this_group && !in_this_overview) {

View File

@ -3,6 +3,7 @@
* This file is used to tell require.js which components (or plugins) to load
* when it generates a build.
*/
/*global define */
if (typeof define !== 'undefined') {
/* When running tests, define is not defined. */

View File

@ -1,3 +1,4 @@
/*global define */
define(['jquery'], function (jq) {
return jq.noConflict( true );
});

View File

@ -1,25 +0,0 @@
/*global $ */
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define("converse", ["jquery"], function($) {
return factory($);
});
} else {
factory($);
}
}(this, function ($) {
$.eventEmitter = {
emit: function(evt, data) {
$(this).trigger(evt, data);
},
once: function(evt, handler) {
$(this).one(evt, handler);
},
on: function(evt, handler) {
$(this).bind(evt, handler);
},
off: function(evt, handler) {
$(this).unbind(evt, handler);
}
};
}));

View File

@ -6,6 +6,7 @@
*
* See also src/moment_locales.js
*/
/*global define */
(function (root, factory) {
define("locales", ['jed',
'text!af',

View File

@ -1,4 +1,4 @@
/*global escape, locales, Jed */
/*global define, escape, locales, Jed */
(function (root, factory) {
define([
"jquery",
@ -244,8 +244,8 @@
// check if an @ signal is included, and if not, we assume it's
// a headline message.
( $message.attr('type') !== 'error' &&
typeof from_jid !== 'undefined' &&
from_jid.indexOf('@') === -1
!_.isUndefined(from_jid) &&
!_.includes(from_jid, '@')
)) {
return true;
}
@ -326,11 +326,11 @@
if (typeof attr === 'object') {
var value = false;
_.forEach(attr, function (a) {
value = value || item.get(a).toLowerCase().indexOf(query.toLowerCase()) !== -1;
value = value || _.includes(item.get(a).toLowerCase(), query.toLowerCase());
});
return value;
} else if (typeof attr === 'string') {
return item.get(attr).toLowerCase().indexOf(query.toLowerCase()) !== -1;
return _.includes(item.get(attr).toLowerCase(), query.toLowerCase());
} else {
throw new TypeError('contains: wrong attribute type. Must be string or array.');
}
@ -360,7 +360,7 @@
options.push(tpl_select_option({
value: value,
label: $($options[j]).attr('label'),
selected: (values.indexOf(value) >= 0),
selected: _.startsWith(values, value),
required: $field.find('required').length
}));
}