Merge branch 'master' into develop

v1.18.x
Julian Lam 8 years ago
commit 72e77772db

@ -1,5 +1,4 @@
node_modules/ node_modules/
public/src/nodebb.min.js
*.sublime-project *.sublime-project
*.sublime-workspace *.sublime-workspace
.project .project
@ -10,8 +9,6 @@ logs/
/public/uploads /public/uploads
/public/sounds /public/sounds
/public/vendor /public/vendor
/public/nodebb.min.js
/public/acp.min.js
/public/src/modules/string.js /public/src/modules/string.js
.idea/ .idea/
.vscode/ .vscode/
@ -19,3 +16,4 @@ logs/
*.iws *.iws
/coverage /coverage
/build /build
.eslintrc

@ -0,0 +1,128 @@
{
"extends": "airbnb-base",
"parserOptions": {
"sourceType": "script"
},
"rules": {
// Customized
"handle-callback-err": [ "error","^(e$|(e|(.*(_e|E)))rr)" ],
"comma-dangle": ["error", {
"arrays": "always-multiline",
"objects": "always-multiline",
"imports": "always-multiline",
"exports": "always-multiline",
"functions": "never"
}],
"no-empty": ["error", { "allowEmptyCatch": true }],
"no-underscore-dangle": "off",
"newline-per-chained-call": "off",
"no-console": "off",
"no-mixed-operators": ["error", { "allowSamePrecedence": true }],
"strict": ["error", "global"],
"consistent-return": "off",
"func-names": "off",
"no-tabs": "off",
"indent": ["error", "tab"],
"no-eq-null": "off",
"camelcase": "off",
"no-new": "off",
"no-shadow": "off",
"no-use-before-define": ["error", "nofunc"],
"no-prototype-builtins": "off",
"new-cap": "off",
"no-plusplus": ["error", { "allowForLoopAfterthoughts": true }],
// ES6
"prefer-rest-params": "off",
"prefer-spread": "off",
"prefer-arrow-callback": "off",
"prefer-template": "off",
"no-var": "off",
"object-shorthand": "off",
"vars-on-top": "off",
// TODO
"import/no-unresolved": "off",
"import/no-extraneous-dependencies": "off",
"import/no-dynamic-require": "off",
"import/newline-after-import": "off",
"no-bitwise": "off",
"global-require": "off",
"max-len": "off",
"no-param-reassign": "off",
"no-restricted-syntax": "off",
"no-script-url": "off",
"default-case": "off",
// "no-multi-assign": "off",
// "linebreak-style": "off",
// "one-var": "off",
// "no-undef": "off",
// "max-nested-callbacks": "off",
// "no-mixed-requires": "off",
// "brace-style": "off",
// "max-statements-per-line": "off",
// "no-unused-vars": "off",
// "no-mixed-spaces-and-tabs": "off",
// "no-useless-concat": "off",
// "require-jsdoc": "off",
// "eqeqeq": "off",
// "no-negated-condition": "off",
// "one-var-declaration-per-line": "off",
// "no-lonely-if": "off",
// "radix": "off",
// "no-else-return": "off",
// "no-useless-escape": "off",
// "block-scoped-var": "off",
// "operator-assignment": "off",
// "yoda": "off",
// "no-loop-func": "off",
// "no-void": "off",
// "valid-jsdoc": "off",
// "no-cond-assign": "off",
// "no-redeclare": "off",
// "no-unreachable": "off",
// "no-nested-ternary": "off",
// "operator-linebreak": "off",
// "guard-for-in": "off",
// "no-unneeded-ternary": "off",
// "no-sequences": "off",
// "no-extend-native": "off",
// "no-shadow-restricted-names": "off",
// "no-extra-boolean-cast": "off",
// "no-path-concat": "off",
// "no-unused-expressions": "off",
// "no-return-assign": "off",
// "no-restricted-modules": "off",
// "object-curly-spacing": "off",
// "indent": "off",
// "padded-blocks": "off",
// "eol-last": "off",
// "lines-around-directive": "off",
// "strict": "off",
// "comma-dangle": "off",
// "no-multi-spaces": "off",
// "quotes": "off",
// "keyword-spacing": "off",
// "no-mixed-operators": "off",
// "comma-spacing": "off",
// "no-trailing-spaces": "off",
// "key-spacing": "off",
// "no-multiple-empty-lines": "off",
// "spaced-comment": "off",
// "space-in-parens": "off",
// "block-spacing": "off",
// "quote-props": "off",
// "space-unary-ops": "off",
// "no-empty": "off",
// "dot-notation": "off",
// "func-call-spacing": "off",
// "array-bracket-spacing": "off",
// "object-property-newline": "off",
// "no-continue": "off",
// "no-extra-semi": "off",
// "no-spaced-func": "off",
// "no-useless-return": "off"
}
}

@ -1,111 +0,0 @@
{
"extends": "airbnb",
"rules": {
"handle-callback-err": [ "error","^(e$|(e|(.*(_e|E)))rr)" ],
"linebreak-style": "off",
"import/no-unresolved": "off",
"import/no-extraneous-dependencies": "off",
"one-var": "off",
"no-undef": "off",
"max-len": "off",
"no-new": "off",
"max-nested-callbacks": "off",
"no-mixed-requires": "off",
"brace-style": "off",
"max-statements-per-line": "off",
"no-unused-vars": "off",
"no-mixed-spaces-and-tabs": "off",
"no-useless-concat": "off",
"require-jsdoc": "off",
"eqeqeq": "off",
"camelcase": "off",
"no-negated-condition": "off",
"one-var-declaration-per-line": "off",
"new-cap": "off",
"no-lonely-if": "off",
"radix": "off",
"no-else-return": "off",
"no-useless-escape": "off",
"block-scoped-var": "off",
"operator-assignment": "off",
"default-case": "off",
"yoda": "off",
"no-use-before-define": "off",
"no-loop-func": "off",
"no-void": "off",
"valid-jsdoc": "off",
"o-eq-null": "off",
"no-cond-assign": "off",
"no-eq-null": "off",
"no-redeclare": "off",
"no-unreachable": "off",
"no-nested-ternary": "off",
"operator-linebreak": "off",
"guard-for-in": "off",
"no-unneeded-ternary": "off",
"no-sequences": "off",
"no-extend-native": "off",
"no-shadow-restricted-names": "off",
"no-extra-boolean-cast": "off",
"no-script-url": "off",
"no-path-concat": "off",
"no-unused-expressions": "off",
"no-restricted-module": "off",
"no-return-assign": "off",
"no-restricted-modules": "off",
"no-tabs": "off",
"indent": "off",
"func-names": "off",
"prefer-arrow-callback": "off",
"object-curly-spacing": "off",
"no-var": "off",
"no-shadow": "off",
"prefer-template": "off",
"padded-blocks": "off",
"eol-last": "off",
"lines-around-directive": "off",
"no-restricted-syntax": "off",
"vars-on-top": "off",
"no-prototype-builtins": "off",
"object-shorthand": "off",
"no-param-reassign": "off",
"consistent-return": "off",
"strict": "off",
"comma-dangle": "off",
"no-multi-spaces": "off",
"quotes": "off",
"keyword-spacing": "off",
"no-plusplus": "off",
"no-mixed-operators": "off",
"comma-spacing": "off",
"global-require": "off",
"no-trailing-spaces": "off",
"key-spacing": "off",
"import/newline-after-import": "off",
"no-underscore-dangle": "off",
"prefer-spread": "off",
"no-multiple-empty-lines": "off",
"spaced-comment": "off",
"prefer-rest-params": "off",
"space-in-parens": "off",
"block-spacing": "off",
"quote-props": "off",
"no-console": "off",
"space-unary-ops": "off",
"import/no-dynamic-require": "off",
"no-bitwise": "off",
"no-empty": "off",
"array-bracket-spacin": "off",
"dot-notation": "off",
"func-call-spacing": "off",
"newline-per-chained-call": "off",
"newline-per-chained-call": "off",
"array-bracket-spacing": "off",
"object-property-newline": "off",
"no-continue": "off",
"no-extra-semi": "off",
"no-spaced-func": "off",
"no-useless-return": "off"
}
}

@ -1,6 +1,10 @@
# Submitting a Pull Request to NodeBB? # Submitting a Pull Request to NodeBB?
First of all, thank you! Please consider this [style guide](https://docs.nodebb.org/en/latest/contributing/style-guide.html) when submitting your changes. Also, please join our [community](https://community.nodebb.org) to meet other NodeBB developers and designers :) First of all, thank you! Before submission, please run `npm test` to lint and run the automated NodeBB tests. If everything passes, you're good to go. If you have any errors, please fix them and re-run `npm test` to make sure there aren't any others.
## Styleguide and linting
NodeBB mostly conforms to the [AirBnB Javascript style guide](https://github.com/airbnb/javascript#readme). If you're running into a lot of ESlint errors, you may want to install an editor plugin to display them in real time.
## Contributor License Agreement ## Contributor License Agreement
@ -51,12 +55,13 @@ $ git rev-parse HEAD
If you have downloaded the `.zip` or `.tar.gz` packages from GitHub (or elsewhere), please let us know. If you have downloaded the `.zip` or `.tar.gz` packages from GitHub (or elsewhere), please let us know.
## Provide theme versions if issue is related to the theme/display ## Provide theme versions if issue is related to the theme/display
Use `npm ls` to list the versions of the theme you're using. In this example, we're running the Persona theme, which depends on the Vanilla theme.
``` bash ``` bash
$ npm ls nodebb-theme-vanilla nodebb-theme-lavender $ npm ls nodebb-theme-vanilla nodebb-theme-persona
nodebb@0.7.0-dev /home/julian/Projects/nodebb/forum nodebb@1.4.3 /path/to/nodebb
├── nodebb-theme-lavender@0.2.13 +-- nodebb-theme-persona@4.2.4
└── nodebb-theme-vanilla@0.2.35 `-- nodebb-theme-vanilla@5.2.0
``` ```
## Attempt to use `git bisect` ## Attempt to use `git bisect`

1
.gitignore vendored

@ -57,3 +57,4 @@ tx.exe
coverage coverage
build build
*.log

@ -1,8 +1,10 @@
"use strict"; 'use strict';
var fork = require('child_process').fork; var fork = require('child_process').fork;
var env = process.env; var env = process.env;
var worker, updateWorker, initWorker; var worker;
var updateWorker;
var initWorker;
var incomplete = []; var incomplete = [];
var running = 0; var running = 0;
@ -44,15 +46,13 @@ module.exports = function (grunt) {
if (updateWorker) { if (updateWorker) {
updateWorker.kill('SIGKILL'); updateWorker.kill('SIGKILL');
} }
updateWorker = fork('app.js', updateArgs, { updateWorker = fork('app.js', updateArgs, { env: env });
env: env running += 1;
});
++running;
updateWorker.on('exit', function () { updateWorker.on('exit', function () {
--running; running -= 1;
if (running === 0) { if (running === 0) {
worker = fork('app.js', args, { worker = fork('app.js', args, {
env: env env: env,
}); });
worker.on('message', function () { worker.on('message', function () {
if (incomplete.length) { if (incomplete.length) {
@ -74,17 +74,17 @@ module.exports = function (grunt) {
'public/*.less', 'public/*.less',
'node_modules/nodebb-*/*.less', 'node_modules/nodebb-*/**/*.less', 'node_modules/nodebb-*/*.less', 'node_modules/nodebb-*/**/*.less',
'!node_modules/nodebb-*/node_modules/**', '!node_modules/nodebb-*/node_modules/**',
'!node_modules/nodebb-*/.git/**' '!node_modules/nodebb-*/.git/**',
], ],
options: { options: {
interval: 1000 interval: 1000,
} },
}, },
lessUpdated_Admin: { lessUpdated_Admin: {
files: ['public/**/*.less'], files: ['public/**/*.less'],
options: { options: {
interval: 1000 interval: 1000,
} },
}, },
clientUpdated: { clientUpdated: {
files: [ files: [
@ -92,28 +92,28 @@ module.exports = function (grunt) {
'node_modules/nodebb-*/*.js', 'node_modules/nodebb-*/**/*.js', 'node_modules/nodebb-*/*.js', 'node_modules/nodebb-*/**/*.js',
'!node_modules/nodebb-*/node_modules/**', '!node_modules/nodebb-*/node_modules/**',
'node_modules/templates.js/lib/templates.js', 'node_modules/templates.js/lib/templates.js',
'!node_modules/nodebb-*/.git/**' '!node_modules/nodebb-*/.git/**',
], ],
options: { options: {
interval: 1000 interval: 1000,
} },
}, },
serverUpdated: { serverUpdated: {
files: ['*.js', 'install/*.js', 'src/**/*.js'], files: ['*.js', 'install/*.js', 'src/**/*.js'],
options: { options: {
interval: 1000 interval: 1000,
} },
}, },
templatesUpdated: { templatesUpdated: {
files: [ files: [
'src/views/**/*.tpl', 'src/views/**/*.tpl',
'node_modules/nodebb-*/*.tpl', 'node_modules/nodebb-*/**/*.tpl', 'node_modules/nodebb-*/*.tpl', 'node_modules/nodebb-*/**/*.tpl',
'!node_modules/nodebb-*/node_modules/**', '!node_modules/nodebb-*/node_modules/**',
'!node_modules/nodebb-*/.git/**' '!node_modules/nodebb-*/.git/**',
], ],
options: { options: {
interval: 1000 interval: 1000,
} },
}, },
langUpdated: { langUpdated: {
files: [ files: [
@ -127,10 +127,10 @@ module.exports = function (grunt) {
'!node_modules/nodebb-*/theme.json', '!node_modules/nodebb-*/theme.json',
], ],
options: { options: {
interval: 1000 interval: 1000,
} },
}, },
} },
}); });
grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-contrib-watch');
@ -140,16 +140,16 @@ module.exports = function (grunt) {
if (grunt.option('skip')) { if (grunt.option('skip')) {
worker = fork('app.js', args, { worker = fork('app.js', args, {
env: env env: env,
}); });
} else { } else {
initWorker = fork('app.js', initArgs, { initWorker = fork('app.js', initArgs, {
env: env env: env,
}); });
initWorker.on('exit', function () { initWorker.on('exit', function () {
worker = fork('app.js', args, { worker = fork('app.js', args, {
env: env env: env,
}); });
}); });
} }

@ -17,8 +17,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
"use strict"; 'use strict';
/*global require, global, process*/
var nconf = require('nconf'); var nconf = require('nconf');
nconf.argv().env('__'); nconf.argv().env('__');
@ -37,11 +36,11 @@ winston.add(winston.transports.Console, {
colorize: true, colorize: true,
timestamp: function () { timestamp: function () {
var date = new Date(); var date = new Date();
return (!!nconf.get('json-logging')) ? date.toJSON() : date.getDate() + '/' + (date.getMonth() + 1) + ' ' + date.toTimeString().substr(0,8) + ' [' + global.process.pid + ']'; return nconf.get('json-logging') ? date.toJSON() : date.getDate() + '/' + (date.getMonth() + 1) + ' ' + date.toTimeString().substr(0, 8) + ' [' + global.process.pid + ']';
}, },
level: nconf.get('log-level') || (global.env === 'production' ? 'info' : 'verbose'), level: nconf.get('log-level') || (global.env === 'production' ? 'info' : 'verbose'),
json: (!!nconf.get('json-logging')), json: (!!nconf.get('json-logging')),
stringify: (!!nconf.get('json-logging')) stringify: (!!nconf.get('json-logging')),
}); });
@ -75,7 +74,7 @@ if (nconf.get('setup') || nconf.get('install')) {
} else if (nconf.get('reset')) { } else if (nconf.get('reset')) {
async.waterfall([ async.waterfall([
async.apply(require('./src/reset').reset), async.apply(require('./src/reset').reset),
async.apply(require('./src/meta/build').buildAll) async.apply(require('./src/meta/build').buildAll),
], function (err) { ], function (err) {
process.exit(err ? 1 : 0); process.exit(err ? 1 : 0);
}); });
@ -93,7 +92,7 @@ function loadConfig(callback) {
winston.verbose('* using configuration stored in: %s', configFile); winston.verbose('* using configuration stored in: %s', configFile);
nconf.file({ nconf.file({
file: configFile file: configFile,
}); });
nconf.defaults({ nconf.defaults({
@ -101,7 +100,7 @@ function loadConfig(callback) {
themes_path: path.join(__dirname, 'node_modules'), themes_path: path.join(__dirname, 'node_modules'),
upload_path: 'public/uploads', upload_path: 'public/uploads',
views_dir: path.join(__dirname, 'build/public/templates'), views_dir: path.join(__dirname, 'build/public/templates'),
version: pkg.version version: pkg.version,
}); });
if (!nconf.get('isCluster')) { if (!nconf.get('isCluster')) {
@ -113,7 +112,7 @@ function loadConfig(callback) {
nconf.set('themes_path', path.resolve(__dirname, nconf.get('themes_path'))); nconf.set('themes_path', path.resolve(__dirname, nconf.get('themes_path')));
nconf.set('core_templates_path', path.join(__dirname, 'src/views')); nconf.set('core_templates_path', path.join(__dirname, 'src/views'));
nconf.set('base_templates_path', path.join(nconf.get('themes_path'), 'nodebb-theme-persona/templates')); nconf.set('base_templates_path', path.join(nconf.get('themes_path'), 'nodebb-theme-persona/templates'));
nconf.set('upload_path', path.resolve(nconf.get('base_dir'), nconf.get('upload_path'))); nconf.set('upload_path', path.resolve(nconf.get('base_dir'), nconf.get('upload_path')));
if (nconf.get('url')) { if (nconf.get('url')) {
@ -149,14 +148,14 @@ function setup() {
async.series([ async.series([
async.apply(install.setup), async.apply(install.setup),
async.apply(loadConfig), async.apply(loadConfig),
async.apply(build.buildAll) async.apply(build.buildAll),
], function (err, data) { ], function (err, data) {
// Disregard build step data // Disregard build step data
data = data[0]; data = data[0];
var separator = ' '; var separator = ' ';
if (process.stdout.columns > 10) { if (process.stdout.columns > 10) {
for(var x = 0,cols = process.stdout.columns - 10; x < cols; x++) { for (var x = 0, cols = process.stdout.columns - 10; x < cols; x += 1) {
separator += '='; separator += '=';
} }
} }
@ -194,7 +193,7 @@ function upgrade() {
async.apply(db.init), async.apply(db.init),
async.apply(meta.configs.init), async.apply(meta.configs.init),
async.apply(upgrade.upgrade), async.apply(upgrade.upgrade),
async.apply(build.buildAll) async.apply(build.buildAll),
], function (err) { ], function (err) {
if (err) { if (err) {
winston.error(err.stack); winston.error(err.stack);

@ -1,8 +1,8 @@
'use strict'; 'use strict';
var bcrypt = require('bcryptjs'), var bcrypt = require('bcryptjs');
async = require('async'); var async = require('async');
process.on('message', function (msg) { process.on('message', function (msg) {
@ -20,15 +20,15 @@ function hashPassword(password, rounds) {
}, },
function (salt, next) { function (salt, next) {
bcrypt.hash(password, salt, next); bcrypt.hash(password, salt, next);
} },
], done); ], done);
} }
function done(err, result) { function done(err, result) {
if (err) { if (err) {
process.send({err: err.message}); process.send({ err: err.message });
return process.disconnect(); return process.disconnect();
} }
process.send({result: result}); process.send({ result: result });
process.disconnect(); process.disconnect();
} }

@ -1,4 +1,4 @@
"use strict"; 'use strict';
var async = require('async'); var async = require('async');
var prompt = require('prompt'); var prompt = require('prompt');
@ -6,7 +6,7 @@ var winston = require('winston');
var questions = { var questions = {
redis: require('../src/database/redis').questions, redis: require('../src/database/redis').questions,
mongo: require('../src/database/mongo').questions mongo: require('../src/database/mongo').questions,
}; };
module.exports = function (config, callback) { module.exports = function (config, callback) {
@ -18,7 +18,7 @@ module.exports = function (config, callback) {
}, },
function (databaseConfig, next) { function (databaseConfig, next) {
saveDatabaseConfig(config, databaseConfig, next); saveDatabaseConfig(config, databaseConfig, next);
} },
], callback); ], callback);
}; };
@ -55,7 +55,7 @@ function saveDatabaseConfig(config, databaseConfig, callback) {
host: databaseConfig['redis:host'], host: databaseConfig['redis:host'],
port: databaseConfig['redis:port'], port: databaseConfig['redis:port'],
password: databaseConfig['redis:password'], password: databaseConfig['redis:password'],
database: databaseConfig['redis:database'] database: databaseConfig['redis:database'],
}; };
if (config.redis.host.slice(0, 1) === '/') { if (config.redis.host.slice(0, 1) === '/') {
@ -67,16 +67,16 @@ function saveDatabaseConfig(config, databaseConfig, callback) {
port: databaseConfig['mongo:port'], port: databaseConfig['mongo:port'],
username: databaseConfig['mongo:username'], username: databaseConfig['mongo:username'],
password: databaseConfig['mongo:password'], password: databaseConfig['mongo:password'],
database: databaseConfig['mongo:database'] database: databaseConfig['mongo:database'],
}; };
} else { } else {
return callback(new Error('unknown database : ' + config.database)); return callback(new Error('unknown database : ' + config.database));
} }
var allQuestions = questions.redis.concat(questions.mongo); var allQuestions = questions.redis.concat(questions.mongo);
for (var x = 0; x < allQuestions.length; x++) { for (var x = 0; x < allQuestions.length; x += 1) {
delete config[allQuestions[x].name]; delete config[allQuestions[x].name];
} }
callback(null, config); callback(null, config);
} }

@ -1,4 +1,4 @@
"use strict"; 'use strict';
var winston = require('winston'); var winston = require('winston');
var express = require('express'); var express = require('express');
@ -17,9 +17,9 @@ winston.add(winston.transports.File, {
colorize: true, colorize: true,
timestamp: function () { timestamp: function () {
var date = new Date(); var date = new Date();
return date.getDate() + '/' + (date.getMonth() + 1) + ' ' + date.toTimeString().substr(0,5) + ' [' + global.process.pid + ']'; return date.getDate() + '/' + (date.getMonth() + 1) + ' ' + date.toTimeString().substr(0, 5) + ' [' + global.process.pid + ']';
}, },
level: 'verbose' level: 'verbose',
}); });
var web = {}; var web = {};
@ -27,7 +27,7 @@ var scripts = [
'public/vendor/xregexp/xregexp.js', 'public/vendor/xregexp/xregexp.js',
'public/vendor/xregexp/unicode/unicode-base.js', 'public/vendor/xregexp/unicode/unicode-base.js',
'public/src/utils.js', 'public/src/utils.js',
'public/src/installer/install.js' 'public/src/installer/install.js',
]; ];
web.install = function (port) { web.install = function (port) {
@ -39,7 +39,7 @@ web.install = function (port) {
app.set('view engine', 'tpl'); app.set('view engine', 'tpl');
app.set('views', path.join(__dirname, '../src/views')); app.set('views', path.join(__dirname, '../src/views'));
app.use(bodyParser.urlencoded({ app.use(bodyParser.urlencoded({
extended: true extended: true,
})); }));
async.parallel([compileLess, compileJS], function () { async.parallel([compileLess, compileJS], function () {
@ -66,7 +66,7 @@ function welcome(req, res) {
var databases = dbs.map(function (el) { var databases = dbs.map(function (el) {
return { return {
name: el, name: el,
questions: require('../src/database/' + el).questions questions: require('../src/database/' + el).questions,
}; };
}); });
@ -75,10 +75,10 @@ function welcome(req, res) {
res.render('install/index', { res.render('install/index', {
databases: databases, databases: databases,
skipDatabaseSetup: !!nconf.get('database'), skipDatabaseSetup: !!nconf.get('database'),
error: res.locals.error ? true : false, error: !!res.locals.error,
success: res.locals.success ? true : false, success: !!res.locals.success,
values: req.body, values: req.body,
minimumPasswordLength: defaults.minimumPasswordLength minimumPasswordLength: defaults.minimumPasswordLength,
}); });
} }
@ -90,7 +90,7 @@ function install(req, res) {
} }
var child = require('child_process').fork('app', ['--setup'], { var child = require('child_process').fork('app', ['--setup'], {
env: process.env env: process.env,
}); });
child.on('close', function (data) { child.on('close', function (data) {
@ -110,7 +110,7 @@ function launch(req, res) {
var child = require('child_process').spawn('node', ['loader.js'], { var child = require('child_process').spawn('node', ['loader.js'], {
detached: true, detached: true,
stdio: ['ignore', 'ignore', 'ignore'] stdio: ['ignore', 'ignore', 'ignore'],
}); });
process.stdout.write('\nStarting NodeBB\n'); process.stdout.write('\nStarting NodeBB\n');
@ -120,7 +120,7 @@ function launch(req, res) {
async.parallel([ async.parallel([
async.apply(fs.unlink(path.join(__dirname, '../public/installer.css'))), async.apply(fs.unlink(path.join(__dirname, '../public/installer.css'))),
async.apply(fs.unlink(path.join(__dirname, '../public/installer.min.js'))) async.apply(fs.unlink(path.join(__dirname, '../public/installer.min.js'))),
], function (err) { ], function (err) {
if (err) { if (err) {
winston.warn('Unable to remove installer files'); winston.warn('Unable to remove installer files');
@ -138,7 +138,7 @@ function compileLess(callback) {
} }
less.render(style.toString(), function (err, css) { less.render(style.toString(), function (err, css) {
if(err) { if (err) {
return winston.error('Unable to compile LESS: ', err); return winston.error('Unable to compile LESS: ', err);
} }
@ -157,4 +157,4 @@ function compileJS(callback) {
fs.writeFile(path.join(__dirname, '../public/installer.min.js'), result.code, callback); fs.writeFile(path.join(__dirname, '../public/installer.min.js'), result.code, callback);
} }
module.exports = web; module.exports = web;

@ -1,29 +1,28 @@
'use strict'; 'use strict';
var nconf = require('nconf'), var nconf = require('nconf');
fs = require('fs'), var fs = require('fs');
url = require('url'), var url = require('url');
path = require('path'), var path = require('path');
fork = require('child_process').fork, var fork = require('child_process').fork;
var async = require('async');
async = require('async'), var logrotate = require('logrotate-stream');
logrotate = require('logrotate-stream'), var file = require('./src/file');
file = require('./src/file'), var pkg = require('./package.json');
pkg = require('./package.json');
nconf.argv().env().file({ nconf.argv().env().file({
file: path.join(__dirname, '/config.json') file: path.join(__dirname, 'config.json'),
}); });
var pidFilePath = __dirname + '/pidfile', var pidFilePath = path.join(__dirname, 'pidfile');
output = logrotate({ file: __dirname + '/logs/output.log', size: '1m', keep: 3, compress: true }), var outputLogFilePath = path.join(__dirname, 'logs/output.log');
silent = nconf.get('silent') === 'false' ? false : nconf.get('silent') !== false, var output = logrotate({ file: outputLogFilePath, size: '1m', keep: 3, compress: true });
numProcs, var silent = nconf.get('silent') === 'false' ? false : nconf.get('silent') !== false;
workers = [], var numProcs;
var workers = [];
Loader = { var Loader = {
timesStarted: 0 timesStarted: 0,
}; };
Loader.init = function (callback) { Loader.init = function (callback) {
if (silent) { if (silent) {
@ -50,11 +49,10 @@ Loader.displayStartupMessages = function (callback) {
}; };
Loader.addWorkerEvents = function (worker) { Loader.addWorkerEvents = function (worker) {
worker.on('exit', function (code, signal) { worker.on('exit', function (code, signal) {
if (code !== 0) { if (code !== 0) {
if (Loader.timesStarted < numProcs * 3) { if (Loader.timesStarted < numProcs * 3) {
Loader.timesStarted++; Loader.timesStarted += 1;
if (Loader.crashTimer) { if (Loader.crashTimer) {
clearTimeout(Loader.crashTimer); clearTimeout(Loader.crashTimer);
} }
@ -62,7 +60,7 @@ Loader.addWorkerEvents = function (worker) {
Loader.timesStarted = 0; Loader.timesStarted = 0;
}, 10000); }, 10000);
} else { } else {
console.log(numProcs * 3 + ' restarts in 10 seconds, most likely an error on startup. Halting.'); console.log((numProcs * 3) + ' restarts in 10 seconds, most likely an error on startup. Halting.');
process.exit(); process.exit();
} }
} }
@ -78,13 +76,13 @@ Loader.addWorkerEvents = function (worker) {
worker.on('message', function (message) { worker.on('message', function (message) {
if (message && typeof message === 'object' && message.action) { if (message && typeof message === 'object' && message.action) {
switch (message.action) { switch (message.action) {
case 'restart': case 'restart':
console.log('[cluster] Restarting...'); console.log('[cluster] Restarting...');
Loader.restart(); Loader.restart();
break; break;
case 'reload': case 'reload':
console.log('[cluster] Reloading...'); console.log('[cluster] Reloading...');
Loader.reload(); Loader.reload();
break; break;
} }
} }
@ -95,7 +93,7 @@ Loader.start = function (callback) {
numProcs = getPorts().length; numProcs = getPorts().length;
console.log('Clustering enabled: Spinning up ' + numProcs + ' process(es).\n'); console.log('Clustering enabled: Spinning up ' + numProcs + ' process(es).\n');
for (var x = 0; x < numProcs; ++x) { for (var x = 0; x < numProcs; x += 1) {
forkWorker(x, x === 0); forkWorker(x, x === 0);
} }
@ -108,17 +106,17 @@ function forkWorker(index, isPrimary) {
var ports = getPorts(); var ports = getPorts();
var args = []; var args = [];
if(!ports[index]) { if (!ports[index]) {
return console.log('[cluster] invalid port for worker : ' + index + ' ports: ' + ports.length); return console.log('[cluster] invalid port for worker : ' + index + ' ports: ' + ports.length);
} }
process.env.isPrimary = isPrimary; process.env.isPrimary = isPrimary;
process.env.isCluster = ports.length > 1 ? true : false; process.env.isCluster = ports.length > 1;
process.env.port = ports[index]; process.env.port = ports[index];
var worker = fork('app.js', args, { var worker = fork('app.js', args, {
silent: silent, silent: silent,
env: process.env env: process.env,
}); });
worker.index = index; worker.index = index;
@ -129,7 +127,7 @@ function forkWorker(index, isPrimary) {
Loader.addWorkerEvents(worker); Loader.addWorkerEvents(worker);
if (silent) { if (silent) {
var output = logrotate({ file: __dirname + '/logs/output.log', size: '1m', keep: 3, compress: true }); var output = logrotate({ file: outputLogFilePath, size: '1m', keep: 3, compress: true });
worker.stdout.pipe(output); worker.stdout.pipe(output);
worker.stderr.pipe(output); worker.stderr.pipe(output);
} }
@ -156,7 +154,7 @@ Loader.restart = function () {
nconf.remove('file'); nconf.remove('file');
nconf.use('file', { file: pathToConfig }); nconf.use('file', { file: pathToConfig });
fs.readFile(pathToConfig, {encoding: 'utf-8'}, function (err, configFile) { fs.readFile(pathToConfig, { encoding: 'utf-8' }, function (err, configFile) {
if (err) { if (err) {
console.log('Error reading config : ' + err.message); console.log('Error reading config : ' + err.message);
process.exit(); process.exit();
@ -175,7 +173,7 @@ Loader.restart = function () {
Loader.reload = function () { Loader.reload = function () {
workers.forEach(function (worker) { workers.forEach(function (worker) {
worker.send({ worker.send({
action: 'reload' action: 'reload',
}); });
}); });
}; };
@ -184,7 +182,7 @@ Loader.stop = function () {
killWorkers(); killWorkers();
// Clean up the pidfile // Clean up the pidfile
fs.unlinkSync(__dirname + '/pidfile'); fs.unlinkSync(pidFilePath);
}; };
function killWorkers() { function killWorkers() {
@ -222,16 +220,16 @@ fs.open(path.join(__dirname, 'config.json'), 'r', function (err) {
require('daemon')({ require('daemon')({
stdout: process.stdout, stdout: process.stdout,
stderr: process.stderr stderr: process.stderr,
}); });
fs.writeFile(__dirname + '/pidfile', process.pid); fs.writeFile(pidFilePath, process.pid);
} }
async.series([ async.series([
Loader.init, Loader.init,
Loader.displayStartupMessages, Loader.displayStartupMessages,
Loader.start Loader.start,
], function (err) { ], function (err) {
if (err) { if (err) {
console.log('[loader] Error during startup: ' + err.message); console.log('[loader] Error during startup: ' + err.message);
@ -239,6 +237,6 @@ fs.open(path.join(__dirname, 'config.json'), 'r', function (err) {
}); });
} else { } else {
// No config detected, kickstart web installer // No config detected, kickstart web installer
var child = require('child_process').fork('app'); require('child_process').fork('app');
} }
}); });

@ -56,7 +56,7 @@
"nodebb-plugin-dbsearch": "2.0.2", "nodebb-plugin-dbsearch": "2.0.2",
"nodebb-plugin-emoji-extended": "1.1.1", "nodebb-plugin-emoji-extended": "1.1.1",
"nodebb-plugin-emoji-one": "1.1.5", "nodebb-plugin-emoji-one": "1.1.5",
"nodebb-plugin-markdown": "7.1.0", "nodebb-plugin-markdown": "7.1.1",
"nodebb-plugin-mentions": "2.0.1", "nodebb-plugin-mentions": "2.0.1",
"nodebb-plugin-soundpack-default": "1.0.0", "nodebb-plugin-soundpack-default": "1.0.0",
"nodebb-plugin-spam-be-gone": "0.4.10", "nodebb-plugin-spam-be-gone": "0.4.10",
@ -99,10 +99,8 @@
"devDependencies": { "devDependencies": {
"coveralls": "^2.11.14", "coveralls": "^2.11.14",
"eslint": "^3.12.0", "eslint": "^3.12.0",
"eslint-config-airbnb": "^13.0.0", "eslint-config-airbnb-base": "^11.1.0",
"eslint-plugin-import": "^2.0.0", "eslint-plugin-import": "^2.2.0",
"eslint-plugin-jsx-a11y": "^2.2.3",
"eslint-plugin-react": "^6.8.0",
"grunt": "~1.0.0", "grunt": "~1.0.0",
"grunt-contrib-watch": "^1.0.0", "grunt-contrib-watch": "^1.0.0",
"istanbul": "^0.4.2", "istanbul": "^0.4.2",

@ -0,0 +1,58 @@
{
"globals": {
"app": true,
"io": true,
"socket": true,
"ajaxify": true,
"config": true,
"RELATIVE_PATH": true,
"utils": true,
"overrides": true,
"componentHandler": true,
"bootbox": true,
"templates": true,
"Visibility": true,
"Tinycon": true,
"Promise": true
},
"env": {
"jquery": true,
"amd": true,
"browser": true,
"es6": false
},
"rules": {
"no-dupe-class-members": "off",
"no-var": "off",
"object-shorthand": "off",
"prefer-arrow-callback": "off",
"prefer-spread": "off",
"prefer-reflect": "off",
"prefer-template": "off"
},
"parserOptions": {
"ecmaVersion": 5,
"ecmaFeatures": {
"arrowFunctions": false,
"classes": false,
"defaultParams": false,
"destructuring": false,
"experimentalObjectRestSpread": false,
"blockBindings": false,
"forOf": false,
"generators": false,
"globalReturn": false,
"jsx": false,
"modules": false,
"objectLiteralComputedProperties": false,
"objectLiteralDuplicateProperties": false,
"objectLiteralShorthandMethods": false,
"objectLiteralShorthandProperties": false,
"impliedStrict": false,
"restParams": false,
"spread": false,
"superInFunctions": false,
"templateStrings": false
}
}
}

@ -0,0 +1,84 @@
{
"maxerr" : 50, // {int} Maximum error before stopping
// Enforcing
"bitwise" : true, // true: Prohibit bitwise operators (&, |, ^, etc.)
"camelcase" : false, // true: Identifiers must be in camelCase
"curly" : true, // true: Require {} for every new block or scope
"eqeqeq" : true, // true: Require triple equals (===) for comparison
"forin" : true, // true: Require filtering for..in loops with obj.hasOwnProperty()
"immed" : false, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());`
"indent" : 4, // {int} Number of spaces to use for indentation
"latedef" : false, // true: Require variables/functions to be defined before being used
"newcap" : false, // true: Require capitalization of all constructor functions e.g. `new F()`
"noarg" : true, // true: Prohibit use of `arguments.caller` and `arguments.callee`
"noempty" : true, // true: Prohibit use of empty blocks
"nonew" : false, // true: Prohibit use of constructors for side-effects (without assignment)
"plusplus" : false, // true: Prohibit use of `++` & `--`
"quotmark" : false, // Quotation mark consistency:
// false : do nothing (default)
// true : ensure whatever is used is consistent
// "single" : require single quotes
// "double" : require double quotes
"undef" : true, // true: Require all non-global variables to be declared (prevents global leaks)
"unused" : true, // true: Require all defined variables be used
"strict" : true, // true: Requires all functions run in ES5 Strict Mode
"trailing" : false, // true: Prohibit trailing whitespaces
"maxparams" : false, // {int} Max number of formal params allowed per function
"maxdepth" : false, // {int} Max depth of nested blocks (within functions)
"maxstatements" : false, // {int} Max number statements per function
"maxcomplexity" : false, // {int} Max cyclomatic complexity per function
"maxlen" : false, // {int} Max number of characters per line
// Relaxing
"asi" : false, // true: Tolerate Automatic Semicolon Insertion (no semicolons)
"boss" : false, // true: Tolerate assignments where comparisons would be expected
"debug" : false, // true: Allow debugger statements e.g. browser breakpoints.
"eqnull" : false, // true: Tolerate use of `== null`
"es5" : false, // true: Allow ES5 syntax (ex: getters and setters)
"esnext" : false, // true: Allow ES.next (ES6) syntax (ex: `const`)
"moz" : false, // true: Allow Mozilla specific syntax (extends and overrides esnext features)
// (ex: `for each`, multiple try/catch, function expression…)
"evil" : false, // true: Tolerate use of `eval` and `new Function()`
"expr" : false, // true: Tolerate `ExpressionStatement` as Programs
"funcscope" : false, // true: Tolerate defining variables inside control statements"
"globalstrict" : false, // true: Allow global "use strict" (also enables 'strict')
"iterator" : false, // true: Tolerate using the `__iterator__` property
"lastsemic" : false, // true: Tolerate omitting a semicolon for the last statement of a 1-line block
"laxbreak" : false, // true: Tolerate possibly unsafe line breakings
"laxcomma" : false, // true: Tolerate comma-first style coding
"loopfunc" : false, // true: Tolerate functions being defined in loops
"multistr" : false, // true: Tolerate multi-line strings
"proto" : false, // true: Tolerate using the `__proto__` property
"scripturl" : false, // true: Tolerate script-targeted URLs
"smarttabs" : false, // true: Tolerate mixed tabs/spaces when used for alignment
"shadow" : false, // true: Allows re-define variables later in code e.g. `var x=1; x=2;`
"sub" : false, // true: Tolerate using `[]` notation when it can still be expressed in dot notation
"supernew" : false, // true: Tolerate `new function () { ... };` and `new Object;`
"validthis" : false, // true: Tolerate using this in a non-constructor function
"globals": {
"app": true,
"io": true,
"socket": true,
"ajaxify": true,
"config": true,
"RELATIVE_PATH": true,
"utils": true,
"overrides": true,
"componentHandler": true,
"bootbox": true,
"templates": true,
"Visibility": true,
"Tinycon": true,
"require": true,
"define": true,
"ace": true,
"Sortable": true,
"Slideout": true,
"NProgress": true
},
"jquery": true,
"browser": true
}

@ -39,8 +39,8 @@
"markAsUnreadForAll.success": "すべてのスレッドを未読にしました。", "markAsUnreadForAll.success": "すべてのスレッドを未読にしました。",
"mark_unread": "未読としてマーク", "mark_unread": "未読としてマーク",
"mark_unread.success": "スレッドは未読にマークされました。", "mark_unread.success": "スレッドは未読にマークされました。",
"watch": "ウッチ", "watch": "ウッチ",
"unwatch": "ウッチ解除", "unwatch": "ウッチ解除",
"watch.title": "新しい投稿の通知を受ける", "watch.title": "新しい投稿の通知を受ける",
"unwatch.title": "このスレッドの通知を停止します", "unwatch.title": "このスレッドの通知を停止します",
"share_this_post": "投稿を共有", "share_this_post": "投稿を共有",
@ -107,7 +107,7 @@
"more_guests": "ゲストさんが%1人", "more_guests": "ゲストさんが%1人",
"users_and_others": "%1と他は%2", "users_and_others": "%1と他は%2",
"sort_by": "並び替え", "sort_by": "並び替え",
"oldest_to_newest": "古い\bものから新しい順", "oldest_to_newest": "古いものから新しい順",
"newest_to_oldest": "新しいものから古い順", "newest_to_oldest": "新しいものから古い順",
"most_votes": "最も投票された順", "most_votes": "最も投票された順",
"most_posts": "最も投稿された順", "most_posts": "最も投稿された順",

@ -51,7 +51,7 @@
"change_password": "パスワードを変更", "change_password": "パスワードを変更",
"change_password_error": "無効のパスワード!", "change_password_error": "無効のパスワード!",
"change_password_error_wrong_current": "現在のパスワードは正しくありません!", "change_password_error_wrong_current": "現在のパスワードは正しくありません!",
"change_password_error_length": "パスワードは短い過ぎです!", "change_password_error_length": "パスワードが短過ぎです!",
"change_password_error_match": "パスワードは一致しません!", "change_password_error_match": "パスワードは一致しません!",
"change_password_error_privileges": "パスワードを更新する権限はありません。", "change_password_error_privileges": "パスワードを更新する権限はありません。",
"change_password_success": "パスワードを更新しました!", "change_password_success": "パスワードを更新しました!",
@ -79,7 +79,7 @@
"digest_monthly": "マンスリー", "digest_monthly": "マンスリー",
"send_chat_notifications": "オンラインではない時に新しいチャットメッセージを受信した場合、通知メールを送信する。", "send_chat_notifications": "オンラインではない時に新しいチャットメッセージを受信した場合、通知メールを送信する。",
"send_post_notifications": "購読中のスレッドに返信があった場合、メールで通知する。", "send_post_notifications": "購読中のスレッドに返信があった場合、メールで通知する。",
"settings-require-reload": "変化がありましてブラウザを更新する必要があります。ここを押して、ページ更新します。", "settings-require-reload": "設定を変更するにはページを更新する必要があります。ここを押して、ページ更新します。",
"has_no_follower": "フォロワーはまだいません :(", "has_no_follower": "フォロワーはまだいません :(",
"follows_no_one": "フォロー中のユーザーはまだいません :(", "follows_no_one": "フォロー中のユーザーはまだいません :(",
"has_no_posts": "このユーザーはまだ一つも投稿していません", "has_no_posts": "このユーザーはまだ一つも投稿していません",
@ -106,7 +106,7 @@
"delay_image_loading": "画像読み込みを遅延させる", "delay_image_loading": "画像読み込みを遅延させる",
"image_load_delay_help": "有効の場合、スレッド内の画像はスクロールされるまで読み込みません", "image_load_delay_help": "有効の場合、スレッド内の画像はスクロールされるまで読み込みません",
"scroll_to_my_post": "返信を投稿した後、新しい投稿を表示する", "scroll_to_my_post": "返信を投稿した後、新しい投稿を表示する",
"follow_topics_you_reply_to": "あなたが返信するスレッドをウォッチ", "follow_topics_you_reply_to": "あなたが返信したスレッドをウォッチする",
"follow_topics_you_create": "あなたが作成したスレッドをウォッチする", "follow_topics_you_create": "あなたが作成したスレッドをウォッチする",
"grouptitle": "グループ題名", "grouptitle": "グループ題名",
"no-group-title": "グループ名がありません", "no-group-title": "グループ名がありません",

@ -3,29 +3,29 @@
"title": "Site Başlığı", "title": "Site Başlığı",
"title.name": "Topluluk İsmi", "title.name": "Topluluk İsmi",
"title.show-in-header": "Show Site Title in Header", "title.show-in-header": "Show Site Title in Header",
"browser-title": "Browser Title", "browser-title": "Tarayıcı Başlığı",
"browser-title-help": "If no browser title is specified, the site title will be used", "browser-title-help": "If no browser title is specified, the site title will be used",
"title-layout": "Title Layout", "title-layout": "Title Layout",
"title-layout-help": "Define how the browser title will be structured ie. &#123;pageTitle&#125; | &#123;browserTitle&#125;", "title-layout-help": "Define how the browser title will be structured ie. &#123;pageTitle&#125; | &#123;browserTitle&#125;",
"description.placeholder": "A short description about your community", "description.placeholder": "A short description about your community",
"description": "Site Açıklaması", "description": "Site Açıklaması",
"keywords": "Site Keywords", "keywords": "Site Anahtar Kelimeler",
"keywords-placeholder": "Keywords describing your community, comma-separated", "keywords-placeholder": "Keywords describing your community, comma-separated",
"logo": "Site Logo", "logo": "Site Logo",
"logo.image": "Image", "logo.image": "Görsel",
"logo.image-placeholder": "Path to a logo to display on forum header", "logo.image-placeholder": "Path to a logo to display on forum header",
"logo.upload": "Yükle", "logo.upload": "Yükle",
"logo.url": "URL", "logo.url": "URL",
"logo.url-placeholder": "The URL of the site logo", "logo.url-placeholder": "The URL of the site logo",
"logo.url-help": "When the logo is clicked, send users to this address. If left blank, user will be sent to the forum index.", "logo.url-help": "When the logo is clicked, send users to this address. If left blank, user will be sent to the forum index.",
"logo.alt-text": "Alt Text", "logo.alt-text": "Alt Yazı",
"log.alt-text-placeholder": "Alternative text for accessibility", "log.alt-text-placeholder": "Alternative text for accessibility",
"favicon": "Favicon", "favicon": "Favicon",
"favicon.upload": "Yükle", "favicon.upload": "Yükle",
"touch-icon": "Homescreen/Touch Icon", "touch-icon": "Homescreen/Touch Icon",
"touch-icon.upload": "Yükle", "touch-icon.upload": "Yükle",
"touch-icon.help": "Recommended size and format: 192x192, PNG format only. If no touch icon is specified, NodeBB will fall back to using the favicon.", "touch-icon.help": "Recommended size and format: 192x192, PNG format only. If no touch icon is specified, NodeBB will fall back to using the favicon.",
"outgoing-links": "Outgoing Links", "outgoing-links": "Harici Bağlantılar",
"outgoing-links.warning-page": "Use Outgoing Links Warning Page", "outgoing-links.warning-page": "Use Outgoing Links Warning Page",
"search-default-sort-by": "Search default sort by" "search-default-sort-by": "Aramada varsayılan sıralama"
} }

@ -25,30 +25,7 @@
} }
} }
.tag-item {
border: solid 1px @gray-light;
background-color: transparent;
color: @gray-light;
padding: .2em .6em .3em;
font-size: 75%;
font-weight: 700;
white-space: nowrap;
}
.tag-topic-count { .tag-topic-count {
border: solid 1px lighten(@brand-primary, 20%); font-size: 14px;
background-color: lighten(@brand-primary, 20%);
padding: 6px;
font-size: 75%;
font-weight: 700;
white-space: nowrap;
border-left: none;
padding-right: 5px;
padding-left: 5px;
border-width: 1px 1px 2px medium;
a {
color: #FFFFFF;
}
} }
} }

@ -0,0 +1,8 @@
{
"globals": {
"ace": true,
"Sortable": true,
"Slideout": true,
"NProgress": true
}
}

@ -1,5 +1,4 @@
"use strict"; 'use strict';
/*global config, componentHandler, socket, app, bootbox, Slideout, NProgress, utils*/
(function () { (function () {
var logoutTimer = 0; var logoutTimer = 0;
@ -14,7 +13,7 @@
message: '[[login:logged-out-due-to-inactivity]]', message: '[[login:logged-out-due-to-inactivity]]',
callback: function () { callback: function () {
window.location.reload(); window.location.reload();
} },
}); });
}, 3600000); }, 3600000);
} }
@ -34,7 +33,7 @@
$(document).ready(function () { $(document).ready(function () {
setupKeybindings(); setupKeybindings();
if(!/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) { if (!/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
require(['admin/modules/search'], function (search) { require(['admin/modules/search'], function (search) {
search.init(); search.init();
}); });
@ -109,14 +108,15 @@
var mainTitle; var mainTitle;
var pageTitle; var pageTitle;
if (/admin\/general\/dashboard$/.test(url)) { if (/admin\/general\/dashboard$/.test(url)) {
mainTitle = pageTitle = '[[admin/menu:general/dashboard]]'; pageTitle = '[[admin/menu:general/dashboard]]';
mainTitle = pageTitle;
} else if (/admin\/plugins\//.test(url)) { } else if (/admin\/plugins\//.test(url)) {
mainTitle = fallback; mainTitle = fallback;
pageTitle = '[[admin/menu:section-plugins]] > ' + mainTitle; pageTitle = '[[admin/menu:section-plugins]] > ' + mainTitle;
} else { } else {
var matches = url.match(/admin\/(.+?)\/(.+?)$/); var matches = url.match(/admin\/(.+?)\/(.+?)$/);
mainTitle = '[[admin/menu:' + matches[1] + '/' + matches[2] + ']]'; mainTitle = '[[admin/menu:' + matches[1] + '/' + matches[2] + ']]';
pageTitle = '[[admin/menu:section-' + pageTitle = '[[admin/menu:section-' +
(matches[1] === 'development' ? 'advanced' : matches[1]) + (matches[1] === 'development' ? 'advanced' : matches[1]) +
']]' + (matches[2] ? (' > ' + mainTitle) : ''); ']]' + (matches[2] ? (' > ' + mainTitle) : '');
if (matches[2] === 'settings') { if (matches[2] === 'settings') {
@ -158,14 +158,14 @@
} }
function launchSnackbar(params) { function launchSnackbar(params) {
var message = (params.title ? "<strong>" + params.title + "</strong>" : '') + (params.message ? params.message : ''); var message = (params.title ? '<strong>' + params.title + '</strong>' : '') + (params.message ? params.message : '');
require(['translator'], function (translator) { require(['translator'], function (translator) {
translator.translate(message, function (html) { translator.translate(message, function (html) {
var bar = $.snackbar({ var bar = $.snackbar({
content: html, content: html,
timeout: params.timeout || 3000, timeout: params.timeout || 3000,
htmlAllowed: true htmlAllowed: true,
}); });
if (params.clickfn) { if (params.clickfn) {
@ -177,18 +177,18 @@
function configureSlidemenu() { function configureSlidemenu() {
var env = utils.findBootstrapEnvironment(); var env = utils.findBootstrapEnvironment();
var slideout = new Slideout({ var slideout = new Slideout({
'panel': document.getElementById('panel'), panel: document.getElementById('panel'),
'menu': document.getElementById('menu'), menu: document.getElementById('menu'),
'padding': 256, padding: 256,
'tolerance': 70 tolerance: 70,
}); });
if (env === 'md' || env === 'lg') { if (env === 'md' || env === 'lg') {
slideout.disableTouch(); slideout.disableTouch();
} }
$('#mobile-menu').on('click', function () { $('#mobile-menu').on('click', function () {
slideout.toggle(); slideout.toggle();
}); });
@ -199,36 +199,36 @@
$(window).on('resize', function () { $(window).on('resize', function () {
slideout.close(); slideout.close();
env = utils.findBootstrapEnvironment(); env = utils.findBootstrapEnvironment();
if (env === 'md' || env === 'lg') { if (env === 'md' || env === 'lg') {
slideout.disableTouch(); slideout.disableTouch();
$('#header').css({ $('#header').css({
'position': 'relative' position: 'relative',
}); });
} else { } else {
slideout.enableTouch(); slideout.enableTouch();
$('#header').css({ $('#header').css({
'position': 'fixed' position: 'fixed',
}); });
} }
}); });
function onOpeningMenu() { function onOpeningMenu() {
$('#header').css({ $('#header').css({
'top': $('#panel').position().top * -1 + 'px', top: ($('#panel').position().top * -1) + 'px',
'position': 'absolute' position: 'absolute',
}); });
} }
slideout.on('open', onOpeningMenu); slideout.on('open', onOpeningMenu);
slideout.on('close', function () { slideout.on('close', function () {
$('#header').css({ $('#header').css({
'top': '0px', top: '0px',
'position': 'fixed' position: 'fixed',
}); });
}); });
} }
}()); }());

@ -1,7 +1,7 @@
"use strict"; 'use strict';
/*global config, define, app, socket, ajaxify, bootbox, templates, Chart, utils */
define('admin/advanced/errors', ['Chart', 'translator'], function (Chart, translator) {
define('admin/advanced/errors', ['Chart'], function (Chart) {
var Errors = {}; var Errors = {};
Errors.init = function () { Errors.init = function () {
@ -26,9 +26,9 @@ define('admin/advanced/errors', ['Chart', 'translator'], function (Chart, transl
}; };
Errors.setupCharts = function () { Errors.setupCharts = function () {
var notFoundCanvas = document.getElementById('not-found'), var notFoundCanvas = document.getElementById('not-found');
tooBusyCanvas = document.getElementById('toobusy'), var tooBusyCanvas = document.getElementById('toobusy');
dailyLabels = utils.getDaysArray(); var dailyLabels = utils.getDaysArray();
dailyLabels = dailyLabels.slice(-7); dailyLabels = dailyLabels.slice(-7);
@ -41,73 +41,73 @@ define('admin/advanced/errors', ['Chart', 'translator'], function (Chart, transl
labels: dailyLabels, labels: dailyLabels,
datasets: [ datasets: [
{ {
label: "", label: '',
backgroundColor: "rgba(186,139,175,0.2)", backgroundColor: 'rgba(186,139,175,0.2)',
borderColor: "rgba(186,139,175,1)", borderColor: 'rgba(186,139,175,1)',
pointBackgroundColor: "rgba(186,139,175,1)", pointBackgroundColor: 'rgba(186,139,175,1)',
pointHoverBackgroundColor: "#fff", pointHoverBackgroundColor: '#fff',
pointBorderColor: "#fff", pointBorderColor: '#fff',
pointHoverBorderColor: "rgba(186,139,175,1)", pointHoverBorderColor: 'rgba(186,139,175,1)',
data: ajaxify.data.analytics['not-found'] data: ajaxify.data.analytics['not-found'],
} },
] ],
}, },
'toobusy': { toobusy: {
labels: dailyLabels, labels: dailyLabels,
datasets: [ datasets: [
{ {
label: "", label: '',
backgroundColor: "rgba(151,187,205,0.2)", backgroundColor: 'rgba(151,187,205,0.2)',
borderColor: "rgba(151,187,205,1)", borderColor: 'rgba(151,187,205,1)',
pointBackgroundColor: "rgba(151,187,205,1)", pointBackgroundColor: 'rgba(151,187,205,1)',
pointHoverBackgroundColor: "#fff", pointHoverBackgroundColor: '#fff',
pointBorderColor: "#fff", pointBorderColor: '#fff',
pointHoverBorderColor: "rgba(151,187,205,1)", pointHoverBorderColor: 'rgba(151,187,205,1)',
data: ajaxify.data.analytics['toobusy'] data: ajaxify.data.analytics.toobusy,
} },
] ],
} },
}; };
notFoundCanvas.width = $(notFoundCanvas).parent().width(); notFoundCanvas.width = $(notFoundCanvas).parent().width();
tooBusyCanvas.width = $(tooBusyCanvas).parent().width(); tooBusyCanvas.width = $(tooBusyCanvas).parent().width();
new Chart(notFoundCanvas.getContext('2d'), { new Chart(notFoundCanvas.getContext('2d'), {
type: 'line', type: 'line',
data: data['not-found'], data: data['not-found'],
options: { options: {
responsive: true, responsive: true,
legend: { legend: {
display: false display: false,
}, },
scales: { scales: {
yAxes: [{ yAxes: [{
ticks: { ticks: {
beginAtZero: true beginAtZero: true,
} },
}] }],
} },
} },
}); });
new Chart(tooBusyCanvas.getContext('2d'), { new Chart(tooBusyCanvas.getContext('2d'), {
type: 'line', type: 'line',
data: data['toobusy'], data: data.toobusy,
options: { options: {
responsive: true, responsive: true,
legend: { legend: {
display: false display: false,
}, },
scales: { scales: {
yAxes: [{ yAxes: [{
ticks: { ticks: {
beginAtZero: true beginAtZero: true,
} },
}] }],
} },
} },
}); });
}; };
return Errors; return Errors;
}); });

@ -1,13 +1,10 @@
"use strict"; 'use strict';
/* global define, socket, app */
define('admin/advanced/events', function () { define('admin/advanced/events', function () {
var Events = {}; var Events = {};
Events.init = function () { Events.init = function () {
$('[data-action="clear"]').on('click', function () { $('[data-action="clear"]').on('click', function () {
socket.emit('admin.deleteAllEvents', function (err) { socket.emit('admin.deleteAllEvents', function (err) {
if (err) { if (err) {
@ -16,7 +13,6 @@ define('admin/advanced/events', function () {
$('.events-list').empty(); $('.events-list').empty();
}); });
}); });
}; };
return Events; return Events;

@ -1,5 +1,5 @@
"use strict"; 'use strict';
/* global define, socket, app */
define('admin/advanced/logs', function () { define('admin/advanced/logs', function () {
var Logs = {}; var Logs = {};
@ -10,30 +10,30 @@ define('admin/advanced/logs', function () {
// Affix menu // Affix menu
$('.affix').affix(); $('.affix').affix();
$('.logs').find('button[data-action]').on('click', function (event) { $('.logs').find('button[data-action]').on('click', function () {
var btnEl = $(this), var btnEl = $(this);
action = btnEl.attr('data-action'); var action = btnEl.attr('data-action');
switch(action) { switch (action) {
case 'reload': case 'reload':
socket.emit('admin.logs.get', function (err, logs) { socket.emit('admin.logs.get', function (err, logs) {
if (!err) { if (!err) {
logsEl.text(logs); logsEl.text(logs);
logsEl.scrollTop(logsEl.prop('scrollHeight')); logsEl.scrollTop(logsEl.prop('scrollHeight'));
} else { } else {
app.alertError(err.message); app.alertError(err.message);
} }
}); });
break; break;
case 'clear': case 'clear':
socket.emit('admin.logs.clear', function (err) { socket.emit('admin.logs.clear', function (err) {
if (!err) { if (!err) {
app.alertSuccess('[[admin/advanced/logs:clear-success]]'); app.alertSuccess('[[admin/advanced/logs:clear-success]]');
btnEl.prev().click(); btnEl.prev().click();
} }
}); });
break; break;
} }
}); });
}; };

@ -1,37 +1,36 @@
"use strict"; 'use strict';
/* global ace, define, app, socket */
define('admin/appearance/customise', ['admin/settings'], function (Settings) { define('admin/appearance/customise', ['admin/settings'], function (Settings) {
var Customise = {}; var Customise = {};
Customise.init = function () { Customise.init = function () {
Settings.prepare(function () { Settings.prepare(function () {
$('#customCSS').text($('#customCSS-holder').val()); $('#customCSS').text($('#customCSS-holder').val());
$('#customHTML').text($('#customHTML-holder').val()); $('#customHTML').text($('#customHTML-holder').val());
var customCSS = ace.edit("customCSS"),
customHTML = ace.edit("customHTML");
customCSS.setTheme("ace/theme/twilight"); var customCSS = ace.edit('customCSS');
customCSS.getSession().setMode("ace/mode/css"); var customHTML = ace.edit('customHTML');
customCSS.setTheme('ace/theme/twilight');
customCSS.getSession().setMode('ace/mode/css');
customCSS.on('change', function (event) { customCSS.on('change', function () {
app.flags = app.flags || {}; app.flags = app.flags || {};
app.flags._unsaved = true; app.flags._unsaved = true;
$('#customCSS-holder').val(customCSS.getValue()); $('#customCSS-holder').val(customCSS.getValue());
}); });
customHTML.setTheme("ace/theme/twilight"); customHTML.setTheme('ace/theme/twilight');
customHTML.getSession().setMode("ace/mode/html"); customHTML.getSession().setMode('ace/mode/html');
customHTML.on('change', function (event) { customHTML.on('change', function () {
app.flags = app.flags || {}; app.flags = app.flags || {};
app.flags._unsaved = true; app.flags._unsaved = true;
$('#customHTML-holder').val(customHTML.getValue()); $('#customHTML-holder').val(customHTML.getValue());
}); });
}); });
}; };
return Customise; return Customise;
}); });

@ -1,14 +1,14 @@
"use strict"; 'use strict';
/* global define, app, socket, templates */
define('admin/appearance/skins', ['translator'], function (translator) { define('admin/appearance/skins', ['translator'], function (translator) {
var Skins = {}; var Skins = {};
Skins.init = function () { Skins.init = function () {
// Populate skins from Bootswatch API // Populate skins from Bootswatch API
$.ajax({ $.ajax({
method: 'get', method: 'get',
url: 'https://bootswatch.com/api/3.json' url: 'https://bootswatch.com/api/3.json',
}).done(Skins.render); }).done(Skins.render);
$('#skins').on('click', function (e) { $('#skins').on('click', function (e) {
@ -21,16 +21,16 @@ define('admin/appearance/skins', ['translator'], function (translator) {
var action = target.attr('data-action'); var action = target.attr('data-action');
if (action && action === 'use') { if (action && action === 'use') {
var parentEl = target.parents('[data-theme]'), var parentEl = target.parents('[data-theme]');
themeType = parentEl.attr('data-type'), var themeType = parentEl.attr('data-type');
cssSrc = parentEl.attr('data-css'), var cssSrc = parentEl.attr('data-css');
themeId = parentEl.attr('data-theme'); var themeId = parentEl.attr('data-theme');
socket.emit('admin.themes.set', { socket.emit('admin.themes.set', {
type: themeType, type: themeType,
id: themeId, id: themeId,
src: cssSrc src: cssSrc,
}, function (err) { }, function (err) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
@ -42,7 +42,7 @@ define('admin/appearance/skins', ['translator'], function (translator) {
type: 'info', type: 'info',
title: '[[admin/appearance/skins:skin-updated]]', title: '[[admin/appearance/skins:skin-updated]]',
message: themeId ? ('[[admin/appearance/skins:applied-success, ' + themeId + ']]') : '[[admin/appearance/skins:revert-success]]', message: themeId ? ('[[admin/appearance/skins:applied-success, ' + themeId + ']]') : '[[admin/appearance/skins:revert-success]]',
timeout: 5000 timeout: 5000,
}); });
}); });
} }
@ -62,10 +62,10 @@ define('admin/appearance/skins', ['translator'], function (translator) {
screenshot_url: theme.thumbnail, screenshot_url: theme.thumbnail,
url: theme.preview, url: theme.preview,
css: theme.cssCdn, css: theme.cssCdn,
skin: true skin: true,
}; };
}), }),
showRevert: true showRevert: true,
}, function (html) { }, function (html) {
translator.translate(html, function (html) { translator.translate(html, function (html) {
themeContainer.html(html); themeContainer.html(html);
@ -73,7 +73,7 @@ define('admin/appearance/skins', ['translator'], function (translator) {
if (config['theme:src']) { if (config['theme:src']) {
var skin = config['theme:src'] var skin = config['theme:src']
.match(/latest\/(\S+)\/bootstrap.min.css/)[1] .match(/latest\/(\S+)\/bootstrap.min.css/)[1]
.replace(/(^|\s)([a-z])/g , function (m,p1,p2) {return p1 + p2.toUpperCase();}); .replace(/(^|\s)([a-z])/g, function (m, p1, p2) { return p1 + p2.toUpperCase(); });
highlightSelectedTheme(skin); highlightSelectedTheme(skin);
} }

@ -1,24 +1,24 @@
"use strict"; 'use strict';
/* global define, app, socket, bootbox, templates, config */
define('admin/appearance/themes', ['translator'], function (translator) { define('admin/appearance/themes', ['translator'], function (translator) {
var Themes = {}; var Themes = {};
Themes.init = function () { Themes.init = function () {
$('#installed_themes').on('click', function (e) { $('#installed_themes').on('click', function (e) {
var target = $(e.target), var target = $(e.target);
action = target.attr('data-action'); var action = target.attr('data-action');
if (action && action === 'use') { if (action && action === 'use') {
var parentEl = target.parents('[data-theme]'), var parentEl = target.parents('[data-theme]');
themeType = parentEl.attr('data-type'), var themeType = parentEl.attr('data-type');
cssSrc = parentEl.attr('data-css'), var cssSrc = parentEl.attr('data-css');
themeId = parentEl.attr('data-theme'); var themeId = parentEl.attr('data-theme');
socket.emit('admin.themes.set', { socket.emit('admin.themes.set', {
type: themeType, type: themeType,
id: themeId, id: themeId,
src: cssSrc src: cssSrc,
}, function (err) { }, function (err) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
@ -34,18 +34,18 @@ define('admin/appearance/themes', ['translator'], function (translator) {
timeout: 5000, timeout: 5000,
clickfn: function () { clickfn: function () {
socket.emit('admin.restart'); socket.emit('admin.restart');
} },
}); });
}); });
} }
}); });
$('#revert_theme').on('click', function () { $('#revert_theme').on('click', function () {
bootbox.confirm('[[admin/appearance/themes:revert-confirm]]', function (confirm) { bootbox.confirm('[[admin/appearance/themes:revert-confirm]]', function (confirm) {
if (confirm) { if (confirm) {
socket.emit('admin.themes.set', { socket.emit('admin.themes.set', {
type: 'local', type: 'local',
id: 'nodebb-theme-persona' id: 'nodebb-theme-persona',
}, function (err) { }, function (err) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
@ -56,7 +56,7 @@ define('admin/appearance/themes', ['translator'], function (translator) {
type: 'success', type: 'success',
title: '[[admin/appearance/themes:theme-changed]]', title: '[[admin/appearance/themes:theme-changed]]',
message: '[[admin/appearance/themes:revert-success]]', message: '[[admin/appearance/themes:revert-success]]',
timeout: 3500 timeout: 3500,
}); });
}); });
} }
@ -64,7 +64,7 @@ define('admin/appearance/themes', ['translator'], function (translator) {
}); });
socket.emit('admin.themes.getInstalled', function (err, themes) { socket.emit('admin.themes.getInstalled', function (err, themes) {
if(err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
} }
@ -72,10 +72,9 @@ define('admin/appearance/themes', ['translator'], function (translator) {
if (!themes.length) { if (!themes.length) {
instListEl.append($('<li/ >').addClass('no-themes').translateHtml('[[admin/appearance/themes:no-themes]]')); instListEl.append($('<li/ >').addClass('no-themes').translateHtml('[[admin/appearance/themes:no-themes]]'));
return;
} else { } else {
templates.parse('admin/partials/theme_list', { templates.parse('admin/partials/theme_list', {
themes: themes themes: themes,
}, function (html) { }, function (html) {
translator.translate(html, function (html) { translator.translate(html, function (html) {
instListEl.html(html); instListEl.html(html);

@ -1,12 +1,12 @@
"use strict"; 'use strict';
/* global define, app, socket, bootbox */
define('admin/extend/plugins', ['jqueryui', 'translator'], function (jqueryui, translator) { define('admin/extend/plugins', ['jqueryui', 'translator'], function (jqueryui, translator) {
var Plugins = {}; var Plugins = {};
Plugins.init = function () { Plugins.init = function () {
var pluginsList = $('.plugins'), var pluginsList = $('.plugins');
numPlugins = pluginsList[0].querySelectorAll('li').length, var numPlugins = pluginsList[0].querySelectorAll('li').length;
pluginID; var pluginID;
if (!numPlugins) { if (!numPlugins) {
translator.translate('<li><p><i>[[admin/extend/plugins:none-found]]</i></p></li>', function (html) { translator.translate('<li><p><i>[[admin/extend/plugins:none-found]]</i></p></li>', function (html) {
@ -29,7 +29,7 @@ define('admin/extend/plugins', ['jqueryui', 'translator'], function (jqueryui, t
btn.html(buttonText); btn.html(buttonText);
btn.toggleClass('btn-warning', status.active).toggleClass('btn-success', !status.active); btn.toggleClass('btn-warning', status.active).toggleClass('btn-success', !status.active);
//clone it to active plugins tab // clone it to active plugins tab
if (status.active && !$('#active #' + pluginID).length) { if (status.active && !$('#active #' + pluginID).length) {
$('#active ul').prepend(pluginEl.clone(true)); $('#active ul').prepend(pluginEl.clone(true));
} }
@ -44,7 +44,7 @@ define('admin/extend/plugins', ['jqueryui', 'translator'], function (jqueryui, t
require(['admin/modules/instance'], function (instance) { require(['admin/modules/instance'], function (instance) {
instance.restart(); instance.restart();
}); });
} },
}); });
}); });
}); });
@ -71,21 +71,19 @@ define('admin/extend/plugins', ['jqueryui', 'translator'], function (jqueryui, t
return; return;
} }
require(['semver'], function (semver) { if (payload.version !== 'latest') {
if (payload.version !== 'latest') { Plugins.toggleInstall(pluginID, payload.version);
Plugins.toggleInstall(pluginID, payload.version); } else if (payload.version === 'latest') {
} else if (payload.version === 'latest') { confirmInstall(pluginID, function (confirm) {
confirmInstall(pluginID, function (confirm) { if (confirm) {
if (confirm) { Plugins.toggleInstall(pluginID, 'latest');
Plugins.toggleInstall(pluginID, 'latest'); } else {
} else { btn.removeAttr('disabled');
btn.removeAttr('disabled'); }
} });
}); } else {
} else { btn.removeAttr('disabled');
btn.removeAttr('disabled'); }
}
});
}); });
}); });
@ -145,7 +143,7 @@ define('admin/extend/plugins', ['jqueryui', 'translator'], function (jqueryui, t
var plugins = $('#order-active-plugins-modal .plugin-list').children(); var plugins = $('#order-active-plugins-modal .plugin-list').children();
var data = []; var data = [];
plugins.each(function (index, el) { plugins.each(function (index, el) {
data.push({name: $(el).text(), order: index}); data.push({ name: $(el).text(), order: index });
}); });
socket.emit('admin.plugins.orderActivePlugins', data, function (err) { socket.emit('admin.plugins.orderActivePlugins', data, function (err) {
@ -162,7 +160,7 @@ define('admin/extend/plugins', ['jqueryui', 'translator'], function (jqueryui, t
function confirmInstall(pluginID, callback) { function confirmInstall(pluginID, callback) {
bootbox.confirm(translator.compile('admin/extend/plugins:alert.possibly-incompatible', pluginID), function (confirm) { bootbox.confirm(translator.compile('admin/extend/plugins:alert.possibly-incompatible', pluginID), function (confirm) {
callback(confirm); callback(confirm);
}); });
} }
@ -170,7 +168,7 @@ define('admin/extend/plugins', ['jqueryui', 'translator'], function (jqueryui, t
btn.attr('disabled', true).find('i').attr('class', 'fa fa-refresh fa-spin'); btn.attr('disabled', true).find('i').attr('class', 'fa fa-refresh fa-spin');
socket.emit('admin.plugins.upgrade', { socket.emit('admin.plugins.upgrade', {
id: pluginID, id: pluginID,
version: version version: version,
}, function (err, isActive) { }, function (err, isActive) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
@ -190,7 +188,7 @@ define('admin/extend/plugins', ['jqueryui', 'translator'], function (jqueryui, t
require(['admin/modules/instance'], function (instance) { require(['admin/modules/instance'], function (instance) {
instance.reload(); instance.reload();
}); });
} },
}); });
} }
}); });
@ -198,12 +196,11 @@ define('admin/extend/plugins', ['jqueryui', 'translator'], function (jqueryui, t
Plugins.toggleInstall = function (pluginID, version, callback) { Plugins.toggleInstall = function (pluginID, version, callback) {
var btn = $('li[data-plugin-id="' + pluginID + '"] button[data-action="toggleInstall"]'); var btn = $('li[data-plugin-id="' + pluginID + '"] button[data-action="toggleInstall"]');
var activateBtn = btn.siblings('[data-action="toggleActive"]');
btn.find('i').attr('class', 'fa fa-refresh fa-spin'); btn.find('i').attr('class', 'fa fa-refresh fa-spin');
socket.emit('admin.plugins.toggleInstall', { socket.emit('admin.plugins.toggleInstall', {
id: pluginID, id: pluginID,
version: version version: version,
}, function (err, pluginData) { }, function (err, pluginData) {
if (err) { if (err) {
btn.removeAttr('disabled'); btn.removeAttr('disabled');
@ -217,7 +214,7 @@ define('admin/extend/plugins', ['jqueryui', 'translator'], function (jqueryui, t
title: '[[admin/extend/plugins:alert.' + (pluginData.installed ? 'installed' : 'uninstalled') + ']]', title: '[[admin/extend/plugins:alert.' + (pluginData.installed ? 'installed' : 'uninstalled') + ']]',
message: '[[admin/extend/plugins:alert.' + (pluginData.installed ? 'install-success' : 'uninstall-success') + ']]', message: '[[admin/extend/plugins:alert.' + (pluginData.installed ? 'install-success' : 'uninstall-success') + ']]',
type: 'info', type: 'info',
timeout: 5000 timeout: 5000,
}); });
if (typeof callback === 'function') { if (typeof callback === 'function') {
@ -232,9 +229,9 @@ define('admin/extend/plugins', ['jqueryui', 'translator'], function (jqueryui, t
type: 'GET', type: 'GET',
data: { data: {
package: pluginId, package: pluginId,
version: nbbVersion[0] version: nbbVersion[0],
}, },
dataType: 'json' dataType: 'json',
}).done(function (payload) { }).done(function (payload) {
callback(undefined, payload); callback(undefined, payload);
}).fail(callback); }).fail(callback);

@ -1,14 +1,14 @@
"use strict"; 'use strict';
/* global define, app, ajaxify, socket, templates, bootbox */
define('admin/extend/rewards', ['translator'], function (translator) { define('admin/extend/rewards', ['translator'], function (translator) {
var rewards = {}; var rewards = {};
var available, var available;
active, var active;
conditions, var conditions;
conditionals; var conditionals;
rewards.init = function () { rewards.init = function () {
available = ajaxify.data.rewards; available = ajaxify.data.rewards;
@ -25,10 +25,10 @@ define('admin/extend/rewards', ['translator'], function (translator) {
update($(this)); update($(this));
}) })
.on('click', '.delete', function () { .on('click', '.delete', function () {
var parent = $(this).parents('[data-id]'), var parent = $(this).parents('[data-id]');
id = parent.attr('data-id'); var id = parent.attr('data-id');
socket.emit('admin.rewards.delete', {id: id}, function (err) { socket.emit('admin.rewards.delete', { id: id }, function (err) {
if (err) { if (err) {
app.alertError(err.message); app.alertError(err.message);
} else { } else {
@ -40,10 +40,9 @@ define('admin/extend/rewards', ['translator'], function (translator) {
return false; return false;
}) })
.on('click', '.toggle', function () { .on('click', '.toggle', function () {
var btn = $(this), var btn = $(this);
disabled = btn.hasClass('btn-success'), var disabled = btn.hasClass('btn-success');
id = $(this).parents('[data-id]').attr('data-id'); btn.toggleClass('btn-warning').toggleClass('btn-success').translateHtml('[[admin/extend/rewards:' + (disabled ? 'disable' : 'enable') + ']]');
btn.toggleClass('btn-warning').toggleClass('btn-success').translateHtml('[[admin/extend/rewards:' + disabled ? 'disable' : 'enable' + ']]');
// send disable api call // send disable api call
return false; return false;
}); });
@ -57,26 +56,26 @@ define('admin/extend/rewards', ['translator'], function (translator) {
function select(el) { function select(el) {
el.val(el.attr('data-selected')); el.val(el.attr('data-selected'));
switch (el.attr('name')) { switch (el.attr('name')) {
case 'rid': case 'rid':
selectReward(el); selectReward(el);
break; break;
} }
} }
function update(el) { function update(el) {
el.attr('data-selected', el.val()); el.attr('data-selected', el.val());
switch (el.attr('name')) { switch (el.attr('name')) {
case 'rid': case 'rid':
selectReward(el); selectReward(el);
break; break;
} }
} }
function selectReward(el) { function selectReward(el) {
var parent = el.parents('[data-rid]'), var parent = el.parents('[data-rid]');
div = parent.find('.inputs'), var div = parent.find('.inputs');
inputs, var inputs;
html = ''; var html = '';
for (var reward in available) { for (var reward in available) {
if (available.hasOwnProperty(reward)) { if (available.hasOwnProperty(reward)) {
@ -95,15 +94,15 @@ define('admin/extend/rewards', ['translator'], function (translator) {
inputs.forEach(function (input) { inputs.forEach(function (input) {
html += '<label for="' + input.name + '">' + input.label + '<br />'; html += '<label for="' + input.name + '">' + input.label + '<br />';
switch (input.type) { switch (input.type) {
case 'select': case 'select':
html += '<select name="' + input.name + '">'; html += '<select name="' + input.name + '">';
input.values.forEach(function (value) { input.values.forEach(function (value) {
html += '<option value="' + value.value + '">' + value.name + '</option>'; html += '<option value="' + value.value + '">' + value.name + '</option>';
}); });
break; break;
case 'text': case 'text':
html += '<input type="text" name="' + input.name + '" />'; html += '<input type="text" name="' + input.name + '" />';
break; break;
} }
html += '</label><br />'; html += '</label><br />';
}); });
@ -113,8 +112,8 @@ define('admin/extend/rewards', ['translator'], function (translator) {
function populateInputs() { function populateInputs() {
$('[data-rid]').each(function (i) { $('[data-rid]').each(function (i) {
var div = $(this).find('.inputs'), var div = $(this).find('.inputs');
rewards = active[i].rewards; var rewards = active[i].rewards;
for (var reward in rewards) { for (var reward in rewards) {
if (rewards.hasOwnProperty(reward)) { if (rewards.hasOwnProperty(reward)) {
@ -133,7 +132,7 @@ define('admin/extend/rewards', ['translator'], function (translator) {
value: '', value: '',
claimable: 1, claimable: 1,
rid: null, rid: null,
id: null id: null,
}], }],
conditions: conditions, conditions: conditions,
conditionals: conditionals, conditionals: conditionals,
@ -153,9 +152,9 @@ define('admin/extend/rewards', ['translator'], function (translator) {
var activeRewards = []; var activeRewards = [];
$('#active li').each(function () { $('#active li').each(function () {
var data = {rewards: {}}, var data = { rewards: {} };
main = $(this).find('form.main').serializeArray(), var main = $(this).find('form.main').serializeArray();
rewards = $(this).find('form.rewards').serializeArray(); var rewards = $(this).find('form.rewards').serializeArray();
main.forEach(function (obj) { main.forEach(function (obj) {
data[obj.name] = obj.value; data[obj.name] = obj.value;

@ -1,7 +1,7 @@
"use strict"; 'use strict';
/* global define, app, socket, bootbox */
define('admin/extend/widgets', ['jqueryui'], function (jqueryui) {
define('admin/extend/widgets', ['jqueryui'], function () {
var Widgets = {}; var Widgets = {};
Widgets.init = function () { Widgets.init = function () {
@ -35,7 +35,7 @@ define('admin/extend/widgets', ['jqueryui'], function (jqueryui) {
return $(e.target).parents('.widget-panel').clone(); return $(e.target).parents('.widget-panel').clone();
}, },
distance: 10, distance: 10,
connectToSortable: ".widget-area" connectToSortable: '.widget-area',
}); });
$('#widgets .available-containers .containers > [data-container-html]') $('#widgets .available-containers .containers > [data-container-html]')
@ -46,7 +46,7 @@ define('admin/extend/widgets', ['jqueryui'], function (jqueryui) {
return target.clone().addClass('block').width(target.width()).css('opacity', '0.5'); return target.clone().addClass('block').width(target.width()).css('opacity', '0.5');
}, },
distance: 10 distance: 10,
}) })
.each(function () { .each(function () {
$(this).attr('data-container-html', $(this).attr('data-container-html').replace(/\\\{([\s\S]*?)\\\}/g, '{$1}')); $(this).attr('data-container-html', $(this).attr('data-container-html').replace(/\\\{([\s\S]*?)\\\}/g, '{$1}'));
@ -57,7 +57,7 @@ define('admin/extend/widgets', ['jqueryui'], function (jqueryui) {
createDatePicker(ui.item); createDatePicker(ui.item);
appendToggle(ui.item); appendToggle(ui.item);
}, },
connectWith: "div" connectWith: 'div',
}).on('click', '.delete-widget', function () { }).on('click', '.delete-widget', function () {
var panel = $(this).parents('.widget-panel'); var panel = $(this).parents('.widget-panel');
@ -67,7 +67,7 @@ define('admin/extend/widgets', ['jqueryui'], function (jqueryui) {
} }
}); });
}).on('mouseup', '> .panel > .panel-heading', function (evt) { }).on('mouseup', '> .panel > .panel-heading', function (evt) {
if ( !( $(this).parent().is('.ui-sortable-helper') || $(evt.target).closest('.delete-widget').length ) ) { if (!($(this).parent().is('.ui-sortable-helper') || $(evt.target).closest('.delete-widget').length)) {
$(this).parent().children('.panel-body').toggleClass('hidden'); $(this).parent().children('.panel-body').toggleClass('hidden');
} }
}); });
@ -80,24 +80,26 @@ define('admin/extend/widgets', ['jqueryui'], function (jqueryui) {
$('#widgets [data-template][data-location]').each(function (i, el) { $('#widgets [data-template][data-location]').each(function (i, el) {
el = $(el); el = $(el);
var template = el.attr('data-template'), var template = el.attr('data-template');
location = el.attr('data-location'), var location = el.attr('data-location');
area = el.children('.widget-area'), var area = el.children('.widget-area');
widgets = []; var widgets = [];
area.find('.widget-panel[data-widget]').each(function () { area.find('.widget-panel[data-widget]').each(function () {
var widgetData = {}, var widgetData = {};
data = $(this).find('form').serializeArray(); var data = $(this).find('form').serializeArray();
for (var d in data) { for (var d in data) {
if (data.hasOwnProperty(d)) { if (data.hasOwnProperty(d)) {
if (data[d].name) { if (data[d].name) {
if (widgetData[data[d].name]) { if (widgetData[data[d].name]) {
if(!Array.isArray(widgetData[data[d].name])) { if (!Array.isArray(widgetData[data[d].name])) {
widgetData[data[d].name] = [ widgetData[data[d].name] ]; widgetData[data[d].name] = [
widgetData[data[d].name],
];
} }
widgetData[data[d].name].push(data[d].value); widgetData[data[d].name].push(data[d].value);
}else{ } else {
widgetData[data[d].name] = data[d].value; widgetData[data[d].name] = data[d].value;
} }
} }
@ -106,16 +108,16 @@ define('admin/extend/widgets', ['jqueryui'], function (jqueryui) {
widgets.push({ widgets.push({
widget: $(this).attr('data-widget'), widget: $(this).attr('data-widget'),
data: widgetData data: widgetData,
}); });
}); });
socket.emit('admin.widgets.set', { socket.emit('admin.widgets.set', {
template: template, template: template,
location: location, location: location,
widgets: widgets widgets: widgets,
}, function (err) { }, function (err) {
total--; total -= 1;
if (err) { if (err) {
app.alertError(err.message); app.alertError(err.message);
@ -127,19 +129,18 @@ define('admin/extend/widgets', ['jqueryui'], function (jqueryui) {
type: 'success', type: 'success',
title: '[[admin/extend/widgets:alert.updated]]', title: '[[admin/extend/widgets:alert.updated]]',
message: '[[admin/extend/widgets:alert.update-success]]', message: '[[admin/extend/widgets:alert.update-success]]',
timeout: 2500 timeout: 2500,
}); });
} }
}); });
}); });
} }
$('.color-selector').on('click', '.btn', function () { $('.color-selector').on('click', '.btn', function () {
var btn = $(this), var btn = $(this);
selector = btn.parents('.color-selector'), var selector = btn.parents('.color-selector');
container = selector.parents('[data-container-html]'), var container = selector.parents('[data-container-html]');
classList = []; var classList = [];
selector.children().each(function () { selector.children().each(function () {
classList.push($(this).attr('data-class')); classList.push($(this).attr('data-class'));
@ -160,7 +161,7 @@ define('admin/extend/widgets', ['jqueryui'], function (jqueryui) {
el.find('.date-selector').datepicker({ el.find('.date-selector').datepicker({
changeMonth: true, changeMonth: true,
changeYear: true, changeYear: true,
yearRange: currentYear + ':' + (currentYear + 100) yearRange: currentYear + ':' + (currentYear + 100),
}); });
} }
@ -175,7 +176,7 @@ define('admin/extend/widgets', ['jqueryui'], function (jqueryui) {
el.find('.panel-body .container-html').val(ui.draggable.attr('data-container-html')); el.find('.panel-body .container-html').val(ui.draggable.attr('data-container-html'));
el.find('.panel-body').removeClass('hidden'); el.find('.panel-body').removeClass('hidden');
}, },
hoverClass: "panel-info" hoverClass: 'panel-info',
}) })
.children('.panel-heading') .children('.panel-heading')
.append('<div class="pull-right pointer"><span class="delete-widget"><i class="fa fa-times-circle"></i></span></div><div class="pull-left pointer"><span class="toggle-widget"><i class="fa fa-chevron-circle-down"></i></span>&nbsp;</div>') .append('<div class="pull-right pointer"><span class="delete-widget"><i class="fa fa-times-circle"></i></span></div><div class="pull-left pointer"><span class="toggle-widget"><i class="fa fa-chevron-circle-down"></i></span>&nbsp;</div>')
@ -191,8 +192,8 @@ define('admin/extend/widgets', ['jqueryui'], function (jqueryui) {
} }
widget.find('input, textarea, select').each(function () { widget.find('input, textarea, select').each(function () {
var input = $(this), var input = $(this);
value = data[input.attr('name')]; var value = data[input.attr('name')];
if (input.attr('type') === 'checkbox') { if (input.attr('type') === 'checkbox') {
input.prop('checked', !!value).trigger('change'); input.prop('checked', !!value).trigger('change');
@ -207,15 +208,15 @@ define('admin/extend/widgets', ['jqueryui'], function (jqueryui) {
$.get(RELATIVE_PATH + '/api/admin/extend/widgets', function (data) { $.get(RELATIVE_PATH + '/api/admin/extend/widgets', function (data) {
var areas = data.areas; var areas = data.areas;
for(var i = 0; i < areas.length; ++i) { for (var i = 0; i < areas.length; i += 1) {
var area = areas[i], var area = areas[i];
widgetArea = $('#widgets .area[data-template="' + area.template + '"][data-location="' + area.location + '"]').find('.widget-area'); var widgetArea = $('#widgets .area[data-template="' + area.template + '"][data-location="' + area.location + '"]').find('.widget-area');
widgetArea.html(''); widgetArea.html('');
for (var k = 0; k < area.data.length; ++k) { for (var k = 0; k < area.data.length; k += 1) {
var widgetData = area.data[k], var widgetData = area.data[k];
widgetEl = $('.available-widgets [data-widget="' + widgetData.widget + '"]').clone(true).removeClass('hide'); var widgetEl = $('.available-widgets [data-widget="' + widgetData.widget + '"]').clone(true).removeClass('hide');
widgetArea.append(populateWidget(widgetEl, widgetData.data)); widgetArea.append(populateWidget(widgetEl, widgetData.data));
appendToggle(widgetEl); appendToggle(widgetEl);

@ -1,30 +1,32 @@
"use strict"; 'use strict';
/*global define, ajaxify, app, socket, utils, bootbox, RELATIVE_PATH*/
define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (semver, Chart, translator) { define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (semver, Chart, translator) {
var Admin = {}; var Admin = {};
var intervals = { var intervals = {
rooms: false, rooms: false,
graphs: false graphs: false,
}; };
var isMobile = false; var isMobile = false;
var isPrerelease = /^v?\d+\.\d+\.\d+-.+$/; var isPrerelease = /^v?\d+\.\d+\.\d+-.+$/;
var graphData = { var graphData = {
rooms: {}, rooms: {},
traffic: {} traffic: {},
}; };
var currentGraph = { var currentGraph = {
units: 'hours', units: 'hours',
until: undefined until: undefined,
}; };
var DEFAULTS = { var DEFAULTS = {
roomInterval: 10000, roomInterval: 10000,
graphInterval: 15000, graphInterval: 15000,
realtimeInterval: 1500 realtimeInterval: 1500,
}; };
$(window).on('action:ajaxify.start', function (ev, data) { var usedTopicColors = [];
$(window).on('action:ajaxify.start', function () {
clearInterval(intervals.rooms); clearInterval(intervals.rooms);
clearInterval(intervals.graphs); clearInterval(intervals.graphs);
@ -50,10 +52,10 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
return !isPrerelease.test(version.name); // filter out automated prerelease versions return !isPrerelease.test(version.name); // filter out automated prerelease versions
}); });
var version = $('#version').html(), var version = $('#version').html();
latestVersion = releases[0].name.slice(1), var latestVersion = releases[0].name.slice(1);
checkEl = $('.version-check'), var checkEl = $('.version-check');
text; var text;
// Alter box colour accordingly // Alter box colour accordingly
if (semver.eq(latestVersion, version)) { if (semver.eq(latestVersion, version)) {
@ -121,51 +123,52 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
traffic: null, traffic: null,
registered: null, registered: null,
presence: null, presence: null,
topics: null topics: null,
}; };
var topicColors = ["#bf616a","#5B90BF","#d08770","#ebcb8b","#a3be8c","#96b5b4","#8fa1b3","#b48ead","#ab7967","#46BFBD"]; var topicColors = ['#bf616a', '#5B90BF', '#d08770', '#ebcb8b', '#a3be8c', '#96b5b4', '#8fa1b3', '#b48ead', '#ab7967', '#46BFBD'];
var usedTopicColors = [];
/* eslint-disable */
// from chartjs.org // from chartjs.org
function lighten(col, amt) { function lighten(col, amt) {
var usePound = false; var usePound = false;
if (col[0] == "#") { if (col[0] === '#') {
col = col.slice(1); col = col.slice(1);
usePound = true; usePound = true;
} }
var num = parseInt(col,16); var num = parseInt(col, 16);
var r = (num >> 16) + amt; var r = (num >> 16) + amt;
if (r > 255) r = 255; if (r > 255) r = 255;
else if (r < 0) r = 0; else if (r < 0) r = 0;
var b = ((num >> 8) & 0x00FF) + amt; var b = ((num >> 8) & 0x00FF) + amt;
if (b > 255) b = 255; if (b > 255) b = 255;
else if (b < 0) b = 0; else if (b < 0) b = 0;
var g = (num & 0x0000FF) + amt; var g = (num & 0x0000FF) + amt;
if (g > 255) g = 255; if (g > 255) g = 255;
else if (g < 0) g = 0; else if (g < 0) g = 0;
return (usePound ? "#" : "") + (g | (b << 8) | (r << 16)).toString(16); return (usePound ? '#' : '') + (g | (b << 8) | (r << 16)).toString(16);
} }
/* eslint-enable */
function setupGraphs() { function setupGraphs() {
var trafficCanvas = document.getElementById('analytics-traffic'), var trafficCanvas = document.getElementById('analytics-traffic');
registeredCanvas = document.getElementById('analytics-registered'), var registeredCanvas = document.getElementById('analytics-registered');
presenceCanvas = document.getElementById('analytics-presence'), var presenceCanvas = document.getElementById('analytics-presence');
topicsCanvas = document.getElementById('analytics-topics'), var topicsCanvas = document.getElementById('analytics-topics');
trafficCtx = trafficCanvas.getContext('2d'), var trafficCtx = trafficCanvas.getContext('2d');
registeredCtx = registeredCanvas.getContext('2d'), var registeredCtx = registeredCanvas.getContext('2d');
presenceCtx = presenceCanvas.getContext('2d'), var presenceCtx = presenceCanvas.getContext('2d');
topicsCtx = topicsCanvas.getContext('2d'), var topicsCtx = topicsCanvas.getContext('2d');
trafficLabels = utils.getHoursArray(); var trafficLabels = utils.getHoursArray();
if (isMobile) { if (isMobile) {
Chart.defaults.global.tooltips.enabled = false; Chart.defaults.global.tooltips.enabled = false;
@ -188,25 +191,25 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
datasets: [ datasets: [
{ {
label: translations[0], label: translations[0],
backgroundColor: "rgba(220,220,220,0.2)", backgroundColor: 'rgba(220,220,220,0.2)',
borderColor: "rgba(220,220,220,1)", borderColor: 'rgba(220,220,220,1)',
pointBackgroundColor: "rgba(220,220,220,1)", pointBackgroundColor: 'rgba(220,220,220,1)',
pointHoverBackgroundColor: "#fff", pointHoverBackgroundColor: '#fff',
pointBorderColor: "#fff", pointBorderColor: '#fff',
pointHoverBorderColor: "rgba(220,220,220,1)", pointHoverBorderColor: 'rgba(220,220,220,1)',
data: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
}, },
{ {
label: translations[1], label: translations[1],
backgroundColor: "rgba(151,187,205,0.2)", backgroundColor: 'rgba(151,187,205,0.2)',
borderColor: "rgba(151,187,205,1)", borderColor: 'rgba(151,187,205,1)',
pointBackgroundColor: "rgba(151,187,205,1)", pointBackgroundColor: 'rgba(151,187,205,1)',
pointHoverBackgroundColor: "#fff", pointHoverBackgroundColor: '#fff',
pointBorderColor: "#fff", pointBorderColor: '#fff',
pointHoverBorderColor: "rgba(151,187,205,1)", pointHoverBorderColor: 'rgba(151,187,205,1)',
data: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
} },
] ],
}; };
trafficCanvas.width = $(trafficCanvas).parent().width(); trafficCanvas.width = $(trafficCanvas).parent().width();
@ -216,34 +219,34 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
options: { options: {
responsive: true, responsive: true,
legend: { legend: {
display: false display: false,
}, },
scales: { scales: {
yAxes: [{ yAxes: [{
ticks: { ticks: {
beginAtZero: true beginAtZero: true,
} },
}] }],
} },
} },
}); });
graphs.registered = new Chart(registeredCtx, { graphs.registered = new Chart(registeredCtx, {
type: 'doughnut', type: 'doughnut',
data: { data: {
labels: translations.slice(2, 4), labels: translations.slice(2, 4),
datasets: [{ datasets: [{
data: [1, 1], data: [1, 1],
backgroundColor: ["#F7464A", "#46BFBD"], backgroundColor: ['#F7464A', '#46BFBD'],
hoverBackgroundColor: ["#FF5A5E", "#5AD3D1"] hoverBackgroundColor: ['#FF5A5E', '#5AD3D1'],
}] }],
}, },
options: { options: {
responsive: true, responsive: true,
legend: { legend: {
display: false display: false,
} },
} },
}); });
graphs.presence = new Chart(presenceCtx, { graphs.presence = new Chart(presenceCtx, {
@ -252,18 +255,18 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
labels: translations.slice(4, 9), labels: translations.slice(4, 9),
datasets: [{ datasets: [{
data: [1, 1, 1, 1, 1], data: [1, 1, 1, 1, 1],
backgroundColor: ["#F7464A", "#46BFBD", "#FDB45C", "#949FB1", "#9FB194"], backgroundColor: ['#F7464A', '#46BFBD', '#FDB45C', '#949FB1', '#9FB194'],
hoverBackgroundColor: ["#FF5A5E", "#5AD3D1", "#FFC870", "#A8B3C5", "#A8B3C5"] hoverBackgroundColor: ['#FF5A5E', '#5AD3D1', '#FFC870', '#A8B3C5', '#A8B3C5'],
}] }],
}, },
options: { options: {
responsive: true, responsive: true,
legend: { legend: {
display: false display: false,
} },
} },
}); });
graphs.topics = new Chart(topicsCtx, { graphs.topics = new Chart(topicsCtx, {
type: 'doughnut', type: 'doughnut',
data: { data: {
@ -271,15 +274,15 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
datasets: [{ datasets: [{
data: [], data: [],
backgroundColor: [], backgroundColor: [],
hoverBackgroundColor: [] hoverBackgroundColor: [],
}] }],
}, },
options: { options: {
responsive: true, responsive: true,
legend: { legend: {
display: false display: false,
} },
} },
}); });
updateTrafficGraph(); updateTrafficGraph();
@ -289,11 +292,11 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
$('[data-action="updateGraph"]').on('click', function () { $('[data-action="updateGraph"]').on('click', function () {
var until; var until;
switch($(this).attr('data-until')) { switch ($(this).attr('data-until')) {
case 'last-month': case 'last-month':
var lastMonth = new Date(); var lastMonth = new Date();
lastMonth.setDate(lastMonth.getDate() - 30); lastMonth.setDate(lastMonth.getDate() - 30);
until = lastMonth.getTime(); until = lastMonth.getTime();
} }
updateTrafficGraph($(this).attr('data-units'), until); updateTrafficGraph($(this).attr('data-units'), until);
$('[data-action="updateGraph"]').removeClass('active'); $('[data-action="updateGraph"]').removeClass('active');
@ -325,7 +328,7 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
socket.emit('admin.analytics.get', { socket.emit('admin.analytics.get', {
graph: 'traffic', graph: 'traffic',
units: units || 'hours', units: units || 'hours',
until: until until: until,
}, function (err, data) { }, function (err, data) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
@ -374,36 +377,36 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
graphs.presence.update(); graphs.presence.update();
} }
function updateTopicsGraph(topics) { function updateTopicsGraph(topics) {
if (!Object.keys(topics).length) { if (!Object.keys(topics).length) {
topics = {"0": { topics = { 0: {
title: "No users browsing", title: 'No users browsing',
value: 1 value: 1,
}}; } };
} }
var tids = Object.keys(topics); var tids = Object.keys(topics);
graphs.topics.data.labels = []; graphs.topics.data.labels = [];
graphs.topics.data.datasets[0].data = []; graphs.topics.data.datasets[0].data = [];
graphs.topics.data.datasets[0].backgroundColor = []; graphs.topics.data.datasets[0].backgroundColor = [];
graphs.topics.data.datasets[0].hoverBackgroundColor = []; graphs.topics.data.datasets[0].hoverBackgroundColor = [];
for (var i = 0, ii = tids.length; i < ii; i++) { for (var i = 0, ii = tids.length; i < ii; i += 1) {
graphs.topics.data.labels.push(topics[tids[i]].title); graphs.topics.data.labels.push(topics[tids[i]].title);
graphs.topics.data.datasets[0].data.push(topics[tids[i]].value); graphs.topics.data.datasets[0].data.push(topics[tids[i]].value);
graphs.topics.data.datasets[0].backgroundColor.push(topicColors[i]); graphs.topics.data.datasets[0].backgroundColor.push(topicColors[i]);
graphs.topics.data.datasets[0].hoverBackgroundColor.push(lighten(topicColors[i], 10)); graphs.topics.data.datasets[0].hoverBackgroundColor.push(lighten(topicColors[i], 10));
} }
function buildTopicsLegend() { function buildTopicsLegend() {
var legend = $('#topics-legend').html(''); var legend = $('#topics-legend').html('');
for (var i = 0, ii = tids.length; i < ii; i++) { for (var i = 0, ii = tids.length; i < ii; i += 1) {
var topic = topics[tids[i]]; var topic = topics[tids[i]];
var label = topic.value === '0' ? topic.title : '<a title="' + topic.title + '"href="' + RELATIVE_PATH + '/topic/' + tids[i] + '" target="_blank"> ' + topic.title + '</a>'; var label = topic.value === '0' ? topic.title : '<a title="' + topic.title + '"href="' + RELATIVE_PATH + '/topic/' + tids[i] + '" target="_blank"> ' + topic.title + '</a>';
legend.append( legend.append(
'<li>' + '<li>' +
'<div style="background-color: ' + topicColors[i] + ';"></div>' + '<div style="background-color: ' + topicColors[i] + ';"></div>' +

@ -1,12 +1,11 @@
"use strict"; 'use strict';
/*global define*/
define('admin/general/homepage', ['admin/settings'], function (Settings) {
define('admin/general/homepage', ['admin/settings'], function () {
function toggleCustomRoute() { function toggleCustomRoute() {
if ($('[data-field="homePageRoute"]').val()) { if ($('[data-field="homePageRoute"]').val()) {
$('#homePageCustom').hide(); $('#homePageCustom').hide();
}else{ } else {
$('#homePageCustom').show(); $('#homePageCustom').show();
} }
} }

@ -1,5 +1,5 @@
"use strict"; 'use strict';
/*global define*/
define('admin/general/languages', ['admin/settings'], function (Settings) { define('admin/general/languages', ['admin/settings'], function (Settings) {
var Languages = {}; var Languages = {};

@ -1,9 +1,9 @@
"use strict"; 'use strict';
/* global define, app, ajaxify, socket, templates */
define('admin/general/navigation', ['translator', 'iconSelect', 'jqueryui'], function (translator, iconSelect, jqueryui) {
var navigation = {}, define('admin/general/navigation', ['translator', 'iconSelect', 'jqueryui'], function (translator, iconSelect) {
available; var navigation = {};
var available;
navigation.init = function () { navigation.init = function () {
available = ajaxify.data.available; available = ajaxify.data.available;
@ -18,12 +18,12 @@ define('admin/general/navigation', ['translator', 'iconSelect', 'jqueryui'], fun
connectToSortable: '#active-navigation', connectToSortable: '#active-navigation',
helper: 'clone', helper: 'clone',
distance: 10, distance: 10,
stop: drop stop: drop,
}); });
}); });
$('#active-navigation').sortable().droppable({ $('#active-navigation').sortable().droppable({
accept: $('#available li .drag-item') accept: $('#available li .drag-item'),
}); });
$('#enabled').on('click', '.iconPicker', function () { $('#enabled').on('click', '.iconPicker', function () {
@ -40,8 +40,8 @@ define('admin/general/navigation', ['translator', 'iconSelect', 'jqueryui'], fun
$('#active-navigation').on('click', 'li', onSelect); $('#active-navigation').on('click', 'li', onSelect);
$('#enabled') $('#enabled')
.on('click', '.delete', remove) .on('click', '.delete', remove)
.on('click', '.toggle', toggle); .on('click', '.toggle', toggle);
$('#save').on('click', save); $('#save').on('click', save);
}; };
@ -61,14 +61,14 @@ define('admin/general/navigation', ['translator', 'iconSelect', 'jqueryui'], fun
} }
function drop(ev, ui) { function drop(ev, ui) {
var id = ui.helper.attr('data-id'), var id = ui.helper.attr('data-id');
el = $('#active-navigation [data-id="' + id + '"]'), var el = $('#active-navigation [data-id="' + id + '"]');
data = id === 'custom' ? {iconClass: 'fa-navicon'} : available[id]; var data = id === 'custom' ? { iconClass: 'fa-navicon' } : available[id];
data.enabled = false; data.enabled = false;
data.index = (parseInt($('#enabled').children().last().attr('data-index'), 10) || 0) + 1; data.index = (parseInt($('#enabled').children().last().attr('data-index'), 10) || 0) + 1;
templates.parse('admin/general/navigation', 'navigation', {navigation: [data]}, function (li) { templates.parse('admin/general/navigation', 'navigation', { navigation: [data] }, function (li) {
translator.translate(li, function (li) { translator.translate(li, function (li) {
li = $(translator.unescape(li)); li = $(translator.unescape(li));
el.after(li); el.after(li);
@ -76,12 +76,12 @@ define('admin/general/navigation', ['translator', 'iconSelect', 'jqueryui'], fun
}); });
}); });
templates.parse('admin/general/navigation', 'enabled', {enabled: [data]}, function (li) { templates.parse('admin/general/navigation', 'enabled', { enabled: [data] }, function (li) {
translator.translate(li, function (li) { translator.translate(li, function (li) {
li = $(translator.unescape(li)); li = $(translator.unescape(li));
$('#enabled').append(li); $('#enabled').append(li);
componentHandler.upgradeDom(); componentHandler.upgradeDom();
}); });
}); });
} }
@ -95,9 +95,9 @@ define('admin/general/navigation', ['translator', 'iconSelect', 'jqueryui'], fun
indices.forEach(function (index) { indices.forEach(function (index) {
var el = $('#enabled').children('[data-index="' + index + '"]'); var el = $('#enabled').children('[data-index="' + index + '"]');
var form = el.find('form').serializeArray(), var form = el.find('form').serializeArray();
data = {}, var data = {};
properties = {}; var properties = {};
form.forEach(function (input) { form.forEach(function (input) {
if (input.name.slice(0, 9) === 'property:' && input.value === 'on') { if (input.name.slice(0, 9) === 'property:' && input.value === 'on') {
@ -135,8 +135,8 @@ define('admin/general/navigation', ['translator', 'iconSelect', 'jqueryui'], fun
} }
function toggle() { function toggle() {
var btn = $(this), var btn = $(this);
disabled = btn.hasClass('btn-success'); var disabled = btn.hasClass('btn-success');
translator.translate(disabled ? '[[admin/general/navigation:btn.disable]]' : '[[admin/general/navigation:btn.enable]]', function (html) { translator.translate(disabled ? '[[admin/general/navigation:btn.disable]]' : '[[admin/general/navigation:btn.enable]]', function (html) {
btn.toggleClass('btn-warning').toggleClass('btn-success').html(html); btn.toggleClass('btn-warning').toggleClass('btn-success').html(html);
btn.parents('li').find('[name="enabled"]').val(disabled ? 'on' : ''); btn.parents('li').find('[name="enabled"]').val(disabled ? 'on' : '');

@ -1,5 +1,5 @@
"use strict"; 'use strict';
/*global define, socket*/
define('admin/general/social', [], function () { define('admin/general/social', [], function () {
var social = {}; var social = {};
@ -12,7 +12,7 @@ define('admin/general/social', [], function () {
networks.push($(this).attr('id')); networks.push($(this).attr('id'));
} }
}); });
socket.emit('admin.social.savePostSharingNetworks', networks, function (err) { socket.emit('admin.social.savePostSharingNetworks', networks, function (err) {
if (err) { if (err) {
return app.alertError(err); return app.alertError(err);

@ -1,5 +1,5 @@
"use strict"; 'use strict';
/* global app, define, socket */
define('admin/general/sounds', ['sounds', 'settings', 'admin/settings'], function (Sounds, Settings, AdminSettings) { define('admin/general/sounds', ['sounds', 'settings', 'admin/settings'], function (Sounds, Settings, AdminSettings) {
var SoundsAdmin = {}; var SoundsAdmin = {};
@ -21,7 +21,7 @@ define('admin/general/sounds', ['sounds', 'settings', 'admin/settings'], functio
saveEl.on('click', function () { saveEl.on('click', function () {
Settings.save('sounds', $('.sounds form'), function () { Settings.save('sounds', $('.sounds form'), function () {
socket.emit('admin.fireEvent', { socket.emit('admin.fireEvent', {
name: 'event:sounds.reloadMapping' name: 'event:sounds.reloadMapping',
}); });
app.alertSuccess('[[admin/general/sounds:saved]]'); app.alertSuccess('[[admin/general/sounds:saved]]');
}); });

@ -1,12 +1,14 @@
"use strict"; 'use strict';
/*global define, socket, app, bootbox, templates, ajaxify, Sortable */
define('admin/manage/categories', ['vendor/jquery/serializeObject/jquery.ba-serializeobject.min', 'translator'], function (serialize, translator) { define('admin/manage/categories', ['vendor/jquery/serializeObject/jquery.ba-serializeobject.min', 'translator'], function (serialize, translator) {
var Categories = {}, newCategoryId = -1, sortables; var Categories = {};
var newCategoryId = -1;
var sortables;
Categories.init = function () { Categories.init = function () {
socket.emit('admin.categories.getAll', function (error, payload) { socket.emit('admin.categories.getAll', function (error, payload) {
if(error) { if (error) {
return app.alertError(error.message); return app.alertError(error.message);
} }
@ -17,10 +19,10 @@ define('admin/manage/categories', ['vendor/jquery/serializeObject/jquery.ba-seri
// Enable/Disable toggle events // Enable/Disable toggle events
$('.categories').on('click', 'button[data-action="toggle"]', function () { $('.categories').on('click', 'button[data-action="toggle"]', function () {
var $this = $(this), var $this = $(this);
cid = $this.attr('data-cid'), var cid = $this.attr('data-cid');
parentEl = $this.parents('li[data-cid="' + cid + '"]'), var parentEl = $this.parents('li[data-cid="' + cid + '"]');
disabled = parentEl.hasClass('disabled'); var disabled = parentEl.hasClass('disabled');
var children = parentEl.find('li[data-cid]').map(function () { var children = parentEl.find('li[data-cid]').map(function () {
return $(this).attr('data-cid'); return $(this).attr('data-cid');
@ -38,8 +40,20 @@ define('admin/manage/categories', ['vendor/jquery/serializeObject/jquery.ba-seri
} }
templates.parse('admin/partials/categories/create', { templates.parse('admin/partials/categories/create', {
categories: categories categories: categories,
}, function (html) { }, function (html) {
var modal = bootbox.dialog({
title: '[[admin/manage/categories:alert.create]]',
message: html,
buttons: {
save: {
label: '[[global:save]]',
className: 'btn-primary',
callback: submit,
},
},
});
function submit() { function submit() {
var formData = modal.find('form').serializeObject(); var formData = modal.find('form').serializeObject();
formData.description = ''; formData.description = '';
@ -50,18 +64,6 @@ define('admin/manage/categories', ['vendor/jquery/serializeObject/jquery.ba-seri
return false; return false;
} }
var modal = bootbox.dialog({
title: '[[admin/manage/categories:alert.create]]',
message: html,
buttons: {
save: {
label: '[[global:save]]',
className: 'btn-primary',
callback: submit
}
}
});
modal.find('form').on('submit', submit); modal.find('form').on('submit', submit);
}); });
}); });
@ -78,7 +80,7 @@ define('admin/manage/categories', ['vendor/jquery/serializeObject/jquery.ba-seri
title: '[[admin/manage/categories:alert.created]]', title: '[[admin/manage/categories:alert.created]]',
message: '[[admin/manage/categories:alert.create-success]]', message: '[[admin/manage/categories:alert.create-success]]',
type: 'success', type: 'success',
timeout: 2000 timeout: 2000,
}); });
ajaxify.go('admin/manage/categories/' + data.cid); ajaxify.go('admin/manage/categories/' + data.cid);
@ -106,7 +108,7 @@ define('admin/manage/categories', ['vendor/jquery/serializeObject/jquery.ba-seri
cids.forEach(function (cid) { cids.forEach(function (cid) {
payload[cid] = { payload[cid] = {
disabled: disabled ? 1 : 0 disabled: disabled ? 1 : 0,
}; };
}); });
@ -123,16 +125,19 @@ define('admin/manage/categories', ['vendor/jquery/serializeObject/jquery.ba-seri
} }
function itemDragDidEnd(e) { function itemDragDidEnd(e) {
var isCategoryUpdate = (newCategoryId != -1); var isCategoryUpdate = parseInt(newCategoryId, 10) !== -1;
//Update needed? // Update needed?
if((e.newIndex != undefined && e.oldIndex != e.newIndex) || isCategoryUpdate) { if ((e.newIndex != null && parseInt(e.oldIndex, 10) !== parseInt(e.newIndex, 10)) || isCategoryUpdate) {
var parentCategory = isCategoryUpdate ? sortables[newCategoryId] : sortables[e.from.dataset.cid], var parentCategory = isCategoryUpdate ? sortables[newCategoryId] : sortables[e.from.dataset.cid];
modified = {}, i = 0, list = parentCategory.toArray(), len = list.length; var modified = {};
var i = 0;
var list = parentCategory.toArray();
var len = list.length;
for(i; i < len; ++i) { for (i; i < len; i += 1) {
modified[list[i]] = { modified[list[i]] = {
order: (i + 1) order: (i + 1),
}; };
} }
@ -161,7 +166,7 @@ define('admin/manage/categories', ['vendor/jquery/serializeObject/jquery.ba-seri
if (category.name !== translated) { if (category.name !== translated) {
category.name = translated; category.name = translated;
} }
++count; count += 1;
if (count === parent.length) { if (count === parent.length) {
continueRender(); continueRender();
@ -176,13 +181,13 @@ define('admin/manage/categories', ['vendor/jquery/serializeObject/jquery.ba-seri
function continueRender() { function continueRender() {
templates.parse('admin/partials/categories/category-rows', { templates.parse('admin/partials/categories/category-rows', {
cid: parentId, cid: parentId,
categories: categories categories: categories,
}, function (html) { }, function (html) {
translator.translate(html, function (html) { translator.translate(html, function (html) {
container.append(html); container.append(html);
// Handle and children categories in this level have // Handle and children categories in this level have
for(var x = 0,numCategories = categories.length; x < numCategories; x++) { for (var x = 0, numCategories = categories.length; x < numCategories; x += 1) {
renderList(categories[x].children, $('li[data-cid="' + categories[x].cid + '"]'), categories[x].cid); renderList(categories[x].children, $('li[data-cid="' + categories[x].cid + '"]'), categories[x].cid);
} }
@ -192,9 +197,9 @@ define('admin/manage/categories', ['vendor/jquery/serializeObject/jquery.ba-seri
animation: 150, animation: 150,
handle: '.icon', handle: '.icon',
dataIdAttr: 'data-cid', dataIdAttr: 'data-cid',
ghostClass: "placeholder", ghostClass: 'placeholder',
onAdd: itemDidAdd, onAdd: itemDidAdd,
onEnd: itemDragDidEnd onEnd: itemDragDidEnd,
}); });
}); });
}); });
@ -202,4 +207,4 @@ define('admin/manage/categories', ['vendor/jquery/serializeObject/jquery.ba-seri
} }
return Categories; return Categories;
}); });

@ -1,5 +1,5 @@
"use strict"; 'use strict';
/*global define, ajaxify, utils */
define('admin/manage/category-analytics', ['Chart'], function (Chart) { define('admin/manage/category-analytics', ['Chart'], function (Chart) {
var CategoryAnalytics = {}; var CategoryAnalytics = {};
@ -10,11 +10,11 @@ define('admin/manage/category-analytics', ['Chart'], function (Chart) {
var topicsCanvas = document.getElementById('topics:daily'); var topicsCanvas = document.getElementById('topics:daily');
var postsCanvas = document.getElementById('posts:daily'); var postsCanvas = document.getElementById('posts:daily');
var hourlyLabels = utils.getHoursArray().map(function (text, idx) { var hourlyLabels = utils.getHoursArray().map(function (text, idx) {
return idx % 3 ? '' : text; return idx % 3 ? '' : text;
}); });
var dailyLabels = utils.getDaysArray().map(function (text, idx) { var dailyLabels = utils.getDaysArray().map(function (text, idx) {
return idx % 3 ? '' : text; return idx % 3 ? '' : text;
}); });
if (utils.isMobile()) { if (utils.isMobile()) {
Chart.defaults.global.tooltips.enabled = false; Chart.defaults.global.tooltips.enabled = false;
@ -25,69 +25,69 @@ define('admin/manage/category-analytics', ['Chart'], function (Chart) {
labels: hourlyLabels, labels: hourlyLabels,
datasets: [ datasets: [
{ {
label: "", label: '',
backgroundColor: "rgba(186,139,175,0.2)", backgroundColor: 'rgba(186,139,175,0.2)',
borderColor: "rgba(186,139,175,1)", borderColor: 'rgba(186,139,175,1)',
pointBackgroundColor: "rgba(186,139,175,1)", pointBackgroundColor: 'rgba(186,139,175,1)',
pointHoverBackgroundColor: "#fff", pointHoverBackgroundColor: '#fff',
pointBorderColor: "#fff", pointBorderColor: '#fff',
pointHoverBorderColor: "rgba(186,139,175,1)", pointHoverBorderColor: 'rgba(186,139,175,1)',
data: ajaxify.data.analytics['pageviews:hourly'] data: ajaxify.data.analytics['pageviews:hourly'],
} },
] ],
}, },
'pageviews:daily': { 'pageviews:daily': {
labels: dailyLabels, labels: dailyLabels,
datasets: [ datasets: [
{ {
label: "", label: '',
backgroundColor: "rgba(151,187,205,0.2)", backgroundColor: 'rgba(151,187,205,0.2)',
borderColor: "rgba(151,187,205,1)", borderColor: 'rgba(151,187,205,1)',
pointBackgroundColor: "rgba(151,187,205,1)", pointBackgroundColor: 'rgba(151,187,205,1)',
pointHoverBackgroundColor: "#fff", pointHoverBackgroundColor: '#fff',
pointBorderColor: "#fff", pointBorderColor: '#fff',
pointHoverBorderColor: "rgba(151,187,205,1)", pointHoverBorderColor: 'rgba(151,187,205,1)',
data: ajaxify.data.analytics['pageviews:daily'] data: ajaxify.data.analytics['pageviews:daily'],
} },
] ],
}, },
'topics:daily': { 'topics:daily': {
labels: dailyLabels.slice(-7), labels: dailyLabels.slice(-7),
datasets: [ datasets: [
{ {
label: "", label: '',
backgroundColor: "rgba(171,70,66,0.2)", backgroundColor: 'rgba(171,70,66,0.2)',
borderColor: "rgba(171,70,66,1)", borderColor: 'rgba(171,70,66,1)',
pointBackgroundColor: "rgba(171,70,66,1)", pointBackgroundColor: 'rgba(171,70,66,1)',
pointHoverBackgroundColor: "#fff", pointHoverBackgroundColor: '#fff',
pointBorderColor: "#fff", pointBorderColor: '#fff',
pointHoverBorderColor: "rgba(171,70,66,1)", pointHoverBorderColor: 'rgba(171,70,66,1)',
data: ajaxify.data.analytics['topics:daily'] data: ajaxify.data.analytics['topics:daily'],
} },
] ],
}, },
'posts:daily': { 'posts:daily': {
labels: dailyLabels.slice(-7), labels: dailyLabels.slice(-7),
datasets: [ datasets: [
{ {
label: "", label: '',
backgroundColor: "rgba(161,181,108,0.2)", backgroundColor: 'rgba(161,181,108,0.2)',
borderColor: "rgba(161,181,108,1)", borderColor: 'rgba(161,181,108,1)',
pointBackgroundColor: "rgba(161,181,108,1)", pointBackgroundColor: 'rgba(161,181,108,1)',
pointHoverBackgroundColor: "#fff", pointHoverBackgroundColor: '#fff',
pointBorderColor: "#fff", pointBorderColor: '#fff',
pointHoverBorderColor: "rgba(161,181,108,1)", pointHoverBorderColor: 'rgba(161,181,108,1)',
data: ajaxify.data.analytics['posts:daily'] data: ajaxify.data.analytics['posts:daily'],
} },
] ],
} },
}; };
hourlyCanvas.width = $(hourlyCanvas).parent().width(); hourlyCanvas.width = $(hourlyCanvas).parent().width();
dailyCanvas.width = $(dailyCanvas).parent().width(); dailyCanvas.width = $(dailyCanvas).parent().width();
topicsCanvas.width = $(topicsCanvas).parent().width(); topicsCanvas.width = $(topicsCanvas).parent().width();
postsCanvas.width = $(postsCanvas).parent().width(); postsCanvas.width = $(postsCanvas).parent().width();
new Chart(hourlyCanvas.getContext('2d'), { new Chart(hourlyCanvas.getContext('2d'), {
type: 'line', type: 'line',
data: data['pageviews:hourly'], data: data['pageviews:hourly'],
@ -95,18 +95,18 @@ define('admin/manage/category-analytics', ['Chart'], function (Chart) {
responsive: true, responsive: true,
animation: false, animation: false,
legend: { legend: {
display: false display: false,
}, },
scales: { scales: {
yAxes: [{ yAxes: [{
ticks: { ticks: {
beginAtZero: true beginAtZero: true,
} },
}] }],
} },
} },
}); });
new Chart(dailyCanvas.getContext('2d'), { new Chart(dailyCanvas.getContext('2d'), {
type: 'line', type: 'line',
data: data['pageviews:daily'], data: data['pageviews:daily'],
@ -114,18 +114,18 @@ define('admin/manage/category-analytics', ['Chart'], function (Chart) {
responsive: true, responsive: true,
animation: false, animation: false,
legend: { legend: {
display: false display: false,
}, },
scales: { scales: {
yAxes: [{ yAxes: [{
ticks: { ticks: {
beginAtZero: true beginAtZero: true,
} },
}] }],
} },
} },
}); });
new Chart(topicsCanvas.getContext('2d'), { new Chart(topicsCanvas.getContext('2d'), {
type: 'line', type: 'line',
data: data['topics:daily'], data: data['topics:daily'],
@ -133,18 +133,18 @@ define('admin/manage/category-analytics', ['Chart'], function (Chart) {
responsive: true, responsive: true,
animation: false, animation: false,
legend: { legend: {
display: false display: false,
}, },
scales: { scales: {
yAxes: [{ yAxes: [{
ticks: { ticks: {
beginAtZero: true beginAtZero: true,
} },
}] }],
} },
} },
}); });
new Chart(postsCanvas.getContext('2d'), { new Chart(postsCanvas.getContext('2d'), {
type: 'line', type: 'line',
data: data['posts:daily'], data: data['posts:daily'],
@ -152,18 +152,18 @@ define('admin/manage/category-analytics', ['Chart'], function (Chart) {
responsive: true, responsive: true,
animation: false, animation: false,
legend: { legend: {
display: false display: false,
}, },
scales: { scales: {
yAxes: [{ yAxes: [{
ticks: { ticks: {
beginAtZero: true beginAtZero: true,
} },
}] }],
} },
} },
}); });
}; };
return CategoryAnalytics; return CategoryAnalytics;
}); });

@ -1,12 +1,12 @@
"use strict"; 'use strict';
/*global config, define, app, socket, ajaxify, bootbox, templates */
define('admin/manage/category', [ define('admin/manage/category', [
'uploader', 'uploader',
'iconSelect', 'iconSelect',
'admin/modules/colorpicker', 'admin/modules/colorpicker',
'autocomplete', 'autocomplete',
'translator' 'translator',
], function (uploader, iconSelect, colorpicker, autocomplete, translator) { ], function (uploader, iconSelect, colorpicker, autocomplete, translator) {
var Category = {}; var Category = {};
var modified_categories = {}; var modified_categories = {};
@ -26,40 +26,14 @@ define('admin/manage/category', [
} }
} }
function save(e) {
e.preventDefault();
if(Object.keys(modified_categories).length) {
socket.emit('admin.categories.update', modified_categories, function (err, results) {
if (err) {
return app.alertError(err.message);
}
if (results && results.length) {
app.flags._unsaved = false;
app.alert({
title: '[[admin/manage/categories:alert.updated]]',
message: translator.compile(
'admin/manage/categories:alert.updated-success',
results.join('&#44; ')
),
type: 'success',
timeout: 2000
});
}
});
modified_categories = {};
}
}
$('.blockclass, form.category select').each(function () { $('.blockclass, form.category select').each(function () {
var $this = $(this); var $this = $(this);
$this.val($this.attr('data-value')); $this.val($this.attr('data-value'));
}); });
function enableColorPicker(idx, inputEl) { function enableColorPicker(idx, inputEl) {
var $inputEl = $(inputEl), var $inputEl = $(inputEl);
previewEl = $inputEl.parents('[data-cid]').find('.category-preview'); var previewEl = $inputEl.parents('[data-cid]').find('.category-preview');
colorpicker.enable($inputEl, function (hsb, hex) { colorpicker.enable($inputEl, function (hsb, hex) {
if ($inputEl.attr('data-name') === 'bgColor') { if ($inputEl.attr('data-name') === 'bgColor') {
@ -103,7 +77,7 @@ define('admin/manage/category', [
title: 'Updated Categories', title: 'Updated Categories',
message: 'Category IDs ' + result.join(', ') + ' was successfully updated.', message: 'Category IDs ' + result.join(', ') + ' was successfully updated.',
type: 'success', type: 'success',
timeout: 2000 timeout: 2000,
}); });
} }
}); });
@ -134,7 +108,7 @@ define('admin/manage/category', [
$('.copy-settings').on('click', function () { $('.copy-settings').on('click', function () {
selectCategoryModal(function (cid) { selectCategoryModal(function (cid) {
socket.emit('admin.categories.copySettingsFrom', {fromCid: cid, toCid: ajaxify.data.category.cid}, function (err) { socket.emit('admin.categories.copySettingsFrom', { fromCid: cid, toCid: ajaxify.data.category.cid }, function (err) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
} }
@ -152,7 +126,7 @@ define('admin/manage/category', [
uploader.show({ uploader.show({
title: '[[admin/manage/categories:alert.upload-image]]', title: '[[admin/manage/categories:alert.upload-image]]',
route: config.relative_path + '/api/admin/category/uploadpicture', route: config.relative_path + '/api/admin/category/uploadpicture',
params: {cid: cid} params: { cid: cid },
}, function (imageUrlOnServer) { }, function (imageUrlOnServer) {
$('#category-image').val(imageUrlOnServer); $('#category-image').val(imageUrlOnServer);
var previewBox = inputEl.parent().parent().siblings('.category-preview'); var previewBox = inputEl.parent().parent().siblings('.category-preview');
@ -186,7 +160,7 @@ define('admin/manage/category', [
$('button[data-action="removeParent"]').on('click', function () { $('button[data-action="removeParent"]').on('click', function () {
var payload = {}; var payload = {};
payload[ajaxify.data.category.cid] = { payload[ajaxify.data.category.cid] = {
parentCid: 0 parentCid: 0,
}; };
socket.emit('admin.categories.update', payload, function (err) { socket.emit('admin.categories.update', payload, function (err) {
@ -220,26 +194,26 @@ define('admin/manage/category', [
var tagEl = $('#tag-whitelist'); var tagEl = $('#tag-whitelist');
tagEl.tagsinput({ tagEl.tagsinput({
confirmKeys: [13, 44], confirmKeys: [13, 44],
trimValue: true trimValue: true,
}); });
ajaxify.data.category.tagWhitelist.forEach(function (tag) { ajaxify.data.category.tagWhitelist.forEach(function (tag) {
tagEl.tagsinput('add', tag); tagEl.tagsinput('add', tag);
}); });
tagEl.on('itemAdded itemRemoved', function (event) { tagEl.on('itemAdded itemRemoved', function () {
modified(tagEl); modified(tagEl);
}); });
} }
Category.setupPrivilegeTable = function () { Category.setupPrivilegeTable = function () {
$('.privilege-table-container').on('change', 'input[type="checkbox"]', function () { $('.privilege-table-container').on('change', 'input[type="checkbox"]', function () {
var checkboxEl = $(this), var checkboxEl = $(this);
privilege = checkboxEl.parent().attr('data-privilege'), var privilege = checkboxEl.parent().attr('data-privilege');
state = checkboxEl.prop('checked'), var state = checkboxEl.prop('checked');
rowEl = checkboxEl.parents('tr'), var rowEl = checkboxEl.parents('tr');
member = rowEl.attr('data-group-name') || rowEl.attr('data-uid'), var member = rowEl.attr('data-group-name') || rowEl.attr('data-uid');
isPrivate = parseInt(rowEl.attr('data-private') || 0, 10), var isPrivate = parseInt(rowEl.attr('data-private') || 0, 10);
isGroup = rowEl.attr('data-group-name') !== undefined; var isGroup = rowEl.attr('data-group-name') !== undefined;
if (member) { if (member) {
if (isGroup && privilege === 'groups:moderate' && !isPrivate && state) { if (isGroup && privilege === 'groups:moderate' && !isPrivate && state) {
@ -247,7 +221,7 @@ define('admin/manage/category', [
if (confirm) { if (confirm) {
Category.setPrivilege(member, privilege, state, checkboxEl); Category.setPrivilege(member, privilege, state, checkboxEl);
} else { } else {
checkboxEl.prop('checked', checkboxEl.prop('checked') ^ 1); checkboxEl.prop('checked', !checkboxEl.prop('checked'));
} }
}); });
} else { } else {
@ -273,7 +247,7 @@ define('admin/manage/category', [
} }
templates.parse('admin/partials/categories/privileges', { templates.parse('admin/partials/categories/privileges', {
privileges: privileges privileges: privileges,
}, function (html) { }, function (html) {
translator.translate(html, function (html) { translator.translate(html, function (html) {
$('.privilege-table-container').html(html); $('.privilege-table-container').html(html);
@ -295,7 +269,7 @@ define('admin/manage/category', [
privs.push(el.getAttribute('data-privilege')); privs.push(el.getAttribute('data-privilege'));
} }
}); });
for(var x = 0,numPrivs = privs.length; x < numPrivs; x++) { for (var x = 0, numPrivs = privs.length; x < numPrivs; x += 1) {
var inputs = $('.privilege-table tr[data-group-name]:not([data-group-name="registered-users"],[data-group-name="guests"]) td[data-privilege="' + privs[x] + '"] input'); var inputs = $('.privilege-table tr[data-group-name]:not([data-group-name="registered-users"],[data-group-name="guests"]) td[data-privilege="' + privs[x] + '"] input');
inputs.each(function (idx, el) { inputs.each(function (idx, el) {
if (!el.checked) { if (!el.checked) {
@ -310,7 +284,7 @@ define('admin/manage/category', [
cid: ajaxify.data.category.cid, cid: ajaxify.data.category.cid,
privilege: privilege, privilege: privilege,
set: state, set: state,
member: member member: member,
}, function (err) { }, function (err) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
@ -332,19 +306,19 @@ define('admin/manage/category', [
}); });
templates.parse('partials/category_list', { templates.parse('partials/category_list', {
categories: categories categories: categories,
}, function (html) { }, function (html) {
var modal = bootbox.dialog({ var modal = bootbox.dialog({
message: html, message: html,
title: '[[admin/manage/categories:alert.set-parent-category]]' title: '[[admin/manage/categories:alert.set-parent-category]]',
}); });
modal.find('li[data-cid]').on('click', function () { modal.find('li[data-cid]').on('click', function () {
var parentCid = $(this).attr('data-cid'), var parentCid = $(this).attr('data-cid');
payload = {}; var payload = {};
payload[ajaxify.data.category.cid] = { payload[ajaxify.data.category.cid] = {
parentCid: parentCid parentCid: parentCid,
}; };
socket.emit('admin.categories.update', payload, function (err) { socket.emit('admin.categories.update', payload, function (err) {
@ -371,7 +345,7 @@ define('admin/manage/category', [
var modal = bootbox.dialog({ var modal = bootbox.dialog({
title: '[[admin/manage/categories:alert.find-user]]', title: '[[admin/manage/categories:alert.find-user]]',
message: '<input class="form-control input-lg" placeholder="[[admin/manage/categories:alert.user-search]]" />', message: '<input class="form-control input-lg" placeholder="[[admin/manage/categories:alert.user-search]]" />',
show: true show: true,
}); });
modal.on('shown.bs.modal', function () { modal.on('shown.bs.modal', function () {
@ -382,7 +356,7 @@ define('admin/manage/category', [
cid: ajaxify.data.category.cid, cid: ajaxify.data.category.cid,
privilege: ['find', 'read', 'topics:read'], privilege: ['find', 'read', 'topics:read'],
set: true, set: true,
member: ui.item.user.uid member: ui.item.user.uid,
}, function (err) { }, function (err) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
@ -399,7 +373,7 @@ define('admin/manage/category', [
var modal = bootbox.dialog({ var modal = bootbox.dialog({
title: '[[admin/manage/categories:alert.find-group]]', title: '[[admin/manage/categories:alert.find-group]]',
message: '<input class="form-control input-lg" placeholder="[[admin/manage/categories:alert.group-search]]" />', message: '<input class="form-control input-lg" placeholder="[[admin/manage/categories:alert.group-search]]" />',
show: true show: true,
}); });
modal.on('shown.bs.modal', function () { modal.on('shown.bs.modal', function () {
@ -410,7 +384,7 @@ define('admin/manage/category', [
cid: ajaxify.data.category.cid, cid: ajaxify.data.category.cid,
privilege: ['groups:find', 'groups:read', 'groups:topics:read'], privilege: ['groups:find', 'groups:read', 'groups:topics:read'],
set: true, set: true,
member: ui.item.group.name member: ui.item.group.name,
}, function (err) { }, function (err) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
@ -434,7 +408,7 @@ define('admin/manage/category', [
Category.copyPrivilegesFromCategory = function () { Category.copyPrivilegesFromCategory = function () {
selectCategoryModal(function (cid) { selectCategoryModal(function (cid) {
socket.emit('admin.categories.copyPrivilegesFrom', {toCid: ajaxify.data.category.cid, fromCid: cid}, function (err) { socket.emit('admin.categories.copyPrivilegesFrom', { toCid: ajaxify.data.category.cid, fromCid: cid }, function (err) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
} }
@ -450,16 +424,9 @@ define('admin/manage/category', [
} }
templates.parse('admin/partials/categories/select-category', { templates.parse('admin/partials/categories/select-category', {
categories: categories categories: categories,
}, function (html) { }, function (html) {
translator.translate(html, function (html) { translator.translate(html, function (html) {
function submit() {
var formData = modal.find('form').serializeObject();
callback(formData['select-cid']);
modal.modal('hide');
return false;
}
var modal = bootbox.dialog({ var modal = bootbox.dialog({
title: 'Select a Category', title: 'Select a Category',
message: html, message: html,
@ -467,11 +434,18 @@ define('admin/manage/category', [
save: { save: {
label: 'Copy', label: 'Copy',
className: 'btn-primary', className: 'btn-primary',
callback: submit callback: submit,
} },
} },
}); });
function submit() {
var formData = modal.find('form').serializeObject();
callback(formData['select-cid']);
modal.modal('hide');
return false;
}
modal.find('form').on('submit', submit); modal.find('form').on('submit', submit);
}); });
}); });
@ -480,4 +454,4 @@ define('admin/manage/category', [
return Category; return Category;
}); });

@ -1,22 +1,22 @@
"use strict"; 'use strict';
/*global define, templates, socket, ajaxify, app, bootbox */
define('admin/manage/group', [ define('admin/manage/group', [
'forum/groups/memberlist', 'forum/groups/memberlist',
'iconSelect', 'iconSelect',
'admin/modules/colorpicker', 'admin/modules/colorpicker',
'translator' 'translator',
], function (memberList, iconSelect, colorpicker, translator) { ], function (memberList, iconSelect, colorpicker, translator) {
var Groups = {}; var Groups = {};
Groups.init = function () { Groups.init = function () {
var groupDetailsSearch = $('#group-details-search'), var groupDetailsSearch = $('#group-details-search');
groupDetailsSearchResults = $('#group-details-search-results'), var groupDetailsSearchResults = $('#group-details-search-results');
groupIcon = $('#group-icon'), var groupIcon = $('#group-icon');
changeGroupUserTitle = $('#change-group-user-title'), var changeGroupUserTitle = $('#change-group-user-title');
changeGroupLabelColor = $('#change-group-label-color'), var changeGroupLabelColor = $('#change-group-label-color');
groupLabelPreview = $('#group-label-preview'), var groupLabelPreview = $('#group-label-preview');
searchDelay; var searchDelay;
var groupName = ajaxify.data.group.name; var groupName = ajaxify.data.group.name;
@ -32,28 +32,27 @@ define('admin/manage/group', [
}); });
groupDetailsSearch.on('keyup', function () { groupDetailsSearch.on('keyup', function () {
if (searchDelay) { if (searchDelay) {
clearTimeout(searchDelay); clearTimeout(searchDelay);
} }
searchDelay = setTimeout(function () { searchDelay = setTimeout(function () {
var searchText = groupDetailsSearch.val(), var searchText = groupDetailsSearch.val();
foundUser; var foundUser;
socket.emit('admin.user.search', { socket.emit('admin.user.search', {
query: searchText query: searchText,
}, function (err, results) { }, function (err, results) {
if (!err && results && results.users.length > 0) { if (!err && results && results.users.length > 0) {
var numResults = results.users.length, var numResults = results.users.length;
x; var x;
if (numResults > 20) { if (numResults > 20) {
numResults = 20; numResults = 20;
} }
groupDetailsSearchResults.empty(); groupDetailsSearchResults.empty();
for (x = 0; x < numResults; x++) { for (x = 0; x < numResults; x += 1) {
foundUser = $('<li />'); foundUser = $('<li />');
foundUser foundUser
.attr({ .attr({
@ -63,7 +62,7 @@ define('admin/manage/group', [
'data-userslug': results.users[x].userslug, 'data-userslug': results.users[x].userslug,
'data-picture': results.users[x].picture, 'data-picture': results.users[x].picture,
'data-usericon-bgColor': results.users[x]['icon:bgColor'], 'data-usericon-bgColor': results.users[x]['icon:bgColor'],
'data-usericon-text': results.users[x]['icon:text'] 'data-usericon-text': results.users[x]['icon:text'],
}) })
.append(results.users[x].picture ? .append(results.users[x].picture ?
$('<img />').addClass('avatar avatar-sm').attr('src', results.users[x].picture) : $('<img />').addClass('avatar avatar-sm').attr('src', results.users[x].picture) :
@ -80,12 +79,12 @@ define('admin/manage/group', [
}); });
groupDetailsSearchResults.on('click', 'li[data-uid]', function () { groupDetailsSearchResults.on('click', 'li[data-uid]', function () {
var userLabel = $(this), var userLabel = $(this);
uid = parseInt(userLabel.attr('data-uid'), 10); var uid = parseInt(userLabel.attr('data-uid'), 10);
socket.emit('admin.groups.join', { socket.emit('admin.groups.join', {
groupName: groupName, groupName: groupName,
uid: uid uid: uid,
}, function (err) { }, function (err) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
@ -96,15 +95,15 @@ define('admin/manage/group', [
username: userLabel.attr('data-username'), username: userLabel.attr('data-username'),
userslug: userLabel.attr('data-userslug'), userslug: userLabel.attr('data-userslug'),
picture: userLabel.attr('data-picture'), picture: userLabel.attr('data-picture'),
"icon:bgColor": userLabel.attr('data-usericon-bgColor'), 'icon:bgColor': userLabel.attr('data-usericon-bgColor'),
"icon:text": userLabel.attr('data-usericon-text') 'icon:text': userLabel.attr('data-usericon-text'),
}; };
templates.parse('admin/partials/groups/memberlist', 'members', { templates.parse('admin/partials/groups/memberlist', 'members', {
group: { group: {
isOwner: ajaxify.data.group.isOwner, isOwner: ajaxify.data.group.isOwner,
members: [member] members: [member],
} },
}, function (html) { }, function (html) {
translator.translate(html, function (html) { translator.translate(html, function (html) {
$('[component="groups/members"] tbody').prepend(html); $('[component="groups/members"] tbody').prepend(html);
@ -114,18 +113,18 @@ define('admin/manage/group', [
}); });
$('[component="groups/members"]').on('click', '[data-action]', function () { $('[component="groups/members"]').on('click', '[data-action]', function () {
var btnEl = $(this), var btnEl = $(this);
userRow = btnEl.parents('[data-uid]'), var userRow = btnEl.parents('[data-uid]');
ownerFlagEl = userRow.find('.member-name i'), var ownerFlagEl = userRow.find('.member-name i');
isOwner = !ownerFlagEl.hasClass('invisible') ? true : false, var isOwner = !ownerFlagEl.hasClass('invisible');
uid = userRow.attr('data-uid'), var uid = userRow.attr('data-uid');
action = btnEl.attr('data-action'); var action = btnEl.attr('data-action');
switch (action) { switch (action) {
case 'toggleOwnership': case 'toggleOwnership':
socket.emit('groups.' + (isOwner ? 'rescind' : 'grant'), { socket.emit('groups.' + (isOwner ? 'rescind' : 'grant'), {
toUid: uid, toUid: uid,
groupName: groupName groupName: groupName,
}, function (err) { }, function (err) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
@ -141,14 +140,13 @@ define('admin/manage/group', [
} }
socket.emit('admin.groups.leave', { socket.emit('admin.groups.leave', {
uid: uid, uid: uid,
groupName: groupName groupName: groupName,
}, function (err) { }, function (err) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
} }
userRow.slideUp().remove(); userRow.slideUp().remove();
}); });
}); });
break; break;
default: default:
@ -176,8 +174,8 @@ define('admin/manage/group', [
userTitleEnabled: $('#group-userTitleEnabled').is(':checked'), userTitleEnabled: $('#group-userTitleEnabled').is(':checked'),
private: $('#group-private').is(':checked'), private: $('#group-private').is(':checked'),
hidden: $('#group-hidden').is(':checked'), hidden: $('#group-hidden').is(':checked'),
disableJoinRequests: $('#group-disableJoinRequests').is(':checked') disableJoinRequests: $('#group-disableJoinRequests').is(':checked'),
} },
}, function (err) { }, function (err) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
@ -194,7 +192,6 @@ define('admin/manage/group', [
}); });
return false; return false;
}); });
}; };
return Groups; return Groups;

@ -1,5 +1,5 @@
"use strict"; 'use strict';
/*global define, templates, socket, ajaxify, app, admin, bootbox, utils, config */
define('admin/manage/groups', ['translator'], function (translator) { define('admin/manage/groups', ['translator'], function (translator) {
var Groups = {}; var Groups = {};
@ -7,10 +7,10 @@ define('admin/manage/groups', ['translator'], function (translator) {
var intervalId = 0; var intervalId = 0;
Groups.init = function () { Groups.init = function () {
var createModal = $('#create-modal'), var createModal = $('#create-modal');
createGroupName = $('#create-group-name'), var createGroupName = $('#create-group-name');
createModalGo = $('#create-modal-go'), var createModalGo = $('#create-modal-go');
createModalError = $('#create-modal-error'); var createModalError = $('#create-modal-error');
handleSearch(); handleSearch();
@ -29,10 +29,9 @@ define('admin/manage/groups', ['translator'], function (translator) {
createModalGo.on('click', function () { createModalGo.on('click', function () {
var submitObj = { var submitObj = {
name: createGroupName.val(), name: createGroupName.val(),
description: $('#create-group-desc').val() description: $('#create-group-desc').val(),
}, };
errorText;
socket.emit('admin.groups.create', submitObj, function (err) { socket.emit('admin.groups.create', submitObj, function (err) {
if (err) { if (err) {
@ -52,18 +51,18 @@ define('admin/manage/groups', ['translator'], function (translator) {
}); });
$('.groups-list').on('click', 'button[data-action]', function () { $('.groups-list').on('click', 'button[data-action]', function () {
var el = $(this), var el = $(this);
action = el.attr('data-action'), var action = el.attr('data-action');
groupName = el.parents('tr[data-groupname]').attr('data-groupname'); var groupName = el.parents('tr[data-groupname]').attr('data-groupname');
switch (action) { switch (action) {
case 'delete': case 'delete':
bootbox.confirm('[[admin/manage/groups:alerts.confirm-delete]]', function (confirm) { bootbox.confirm('[[admin/manage/groups:alerts.confirm-delete]]', function (confirm) {
if (confirm) { if (confirm) {
socket.emit('groups.delete', { socket.emit('groups.delete', {
groupName: groupName groupName: groupName,
}, function (err, data) { }, function (err) {
if(err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
} }
@ -77,6 +76,8 @@ define('admin/manage/groups', ['translator'], function (translator) {
}; };
function handleSearch() { function handleSearch() {
var queryEl = $('#group-search');
function doSearch() { function doSearch() {
if (!queryEl.val()) { if (!queryEl.val()) {
return ajaxify.refresh(); return ajaxify.refresh();
@ -86,15 +87,15 @@ define('admin/manage/groups', ['translator'], function (translator) {
socket.emit('groups.search', { socket.emit('groups.search', {
query: queryEl.val(), query: queryEl.val(),
options: { options: {
sort: 'date' sort: 'date',
} },
}, function (err, groups) { }, function (err, groups) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
} }
templates.parse('admin/manage/groups', 'groups', { templates.parse('admin/manage/groups', 'groups', {
groups: groups groups: groups,
}, function (html) { }, function (html) {
translator.translate(html, function (html) { translator.translate(html, function (html) {
groupsEl.find('[data-groupname]').remove(); groupsEl.find('[data-groupname]').remove();
@ -104,8 +105,6 @@ define('admin/manage/groups', ['translator'], function (translator) {
}); });
} }
var queryEl = $('#group-search');
queryEl.on('keyup', function () { queryEl.on('keyup', function () {
if (intervalId) { if (intervalId) {
clearTimeout(intervalId); clearTimeout(intervalId);

@ -1,15 +1,14 @@
'use strict'; 'use strict';
/* globals $, app, socket, templates, define, bootbox */
define('admin/manage/ip-blacklist', ['translator'], function (translator) {
define('admin/manage/ip-blacklist', [], function () {
var Blacklist = {}; var Blacklist = {};
Blacklist.init = function () { Blacklist.init = function () {
var blacklist = $('#blacklist-rules'); var blacklist = $('#blacklist-rules');
blacklist.on('keyup', function () { blacklist.on('keyup', function () {
$('#blacklist-rules-holder').val(blacklist.val()); $('#blacklist-rules-holder').val(blacklist.val());
}); });
$('[data-action="apply"]').on('click', function () { $('[data-action="apply"]').on('click', function () {
@ -27,7 +26,7 @@ define('admin/manage/ip-blacklist', ['translator'], function (translator) {
$('[data-action="test"]').on('click', function () { $('[data-action="test"]').on('click', function () {
socket.emit('blacklist.validate', { socket.emit('blacklist.validate', {
rules: blacklist.val() rules: blacklist.val(),
}, function (err, data) { }, function (err, data) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
@ -41,4 +40,4 @@ define('admin/manage/ip-blacklist', ['translator'], function (translator) {
}; };
return Blacklist; return Blacklist;
}); });

@ -1,19 +1,17 @@
"use strict"; 'use strict';
/* global config, socket, define, templates, bootbox, app, ajaxify, */
define('admin/manage/registration', function () { define('admin/manage/registration', function () {
var Registration = {}; var Registration = {};
Registration.init = function () { Registration.init = function () {
$('.users-list').on('click', '[data-action]', function () {
$('.users-list').on('click', '[data-action]', function (ev) {
var parent = $(this).parents('[data-username]'); var parent = $(this).parents('[data-username]');
var action = $(this).attr('data-action'); var action = $(this).attr('data-action');
var username = parent.attr('data-username'); var username = parent.attr('data-username');
var method = action === 'accept' ? 'admin.user.acceptRegistration' : 'admin.user.rejectRegistration'; var method = action === 'accept' ? 'admin.user.acceptRegistration' : 'admin.user.rejectRegistration';
socket.emit(method, {username: username}, function (err) { socket.emit(method, { username: username }, function (err) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
} }
@ -22,7 +20,7 @@ define('admin/manage/registration', function () {
return false; return false;
}); });
$('.invites-list').on('click', '[data-action]', function (ev) { $('.invites-list').on('click', '[data-action]', function () {
var parent = $(this).parents('[data-invitation-mail][data-invited-by]'); var parent = $(this).parents('[data-invitation-mail][data-invited-by]');
var email = parent.attr('data-invitation-mail'); var email = parent.attr('data-invitation-mail');
var invitedBy = parent.attr('data-invited-by'); var invitedBy = parent.attr('data-invited-by');
@ -30,9 +28,9 @@ define('admin/manage/registration', function () {
var method = 'admin.user.deleteInvitation'; var method = 'admin.user.deleteInvitation';
var removeRow = function () { var removeRow = function () {
var nextRow = parent.next(), var nextRow = parent.next();
thisRowinvitedBy = parent.find('.invited-by'), var thisRowinvitedBy = parent.find('.invited-by');
nextRowInvitedBy = nextRow.find('.invited-by'); var nextRowInvitedBy = nextRow.find('.invited-by');
if (nextRowInvitedBy.html() !== undefined && nextRowInvitedBy.html().length < 2) { if (nextRowInvitedBy.html() !== undefined && nextRowInvitedBy.html().length < 2) {
nextRowInvitedBy.html(thisRowinvitedBy.html()); nextRowInvitedBy.html(thisRowinvitedBy.html());
} }
@ -41,7 +39,7 @@ define('admin/manage/registration', function () {
if (action === 'delete') { if (action === 'delete') {
bootbox.confirm('[[admin/manage/registration:invitations.confirm-delete]]', function (confirm) { bootbox.confirm('[[admin/manage/registration:invitations.confirm-delete]]', function (confirm) {
if (confirm) { if (confirm) {
socket.emit(method, {email: email, invitedBy: invitedBy}, function (err) { socket.emit(method, { email: email, invitedBy: invitedBy }, function (err) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
} }

@ -1,13 +1,13 @@
"use strict"; 'use strict';
/*global define, socket, app, utils, bootbox, ajaxify*/
define('admin/manage/tags', [ define('admin/manage/tags', [
'forum/infinitescroll', 'forum/infinitescroll',
'admin/modules/selectable', 'admin/modules/selectable',
'admin/modules/colorpicker' 'admin/modules/colorpicker',
], function (infinitescroll, selectable, colorpicker) { ], function (infinitescroll, selectable, colorpicker) {
var Tags = {}, var Tags = {};
timeoutId = 0; var timeoutId = 0;
Tags.init = function () { Tags.init = function () {
selectable.enable('.tag-management', '.tag-row'); selectable.enable('.tag-management', '.tag-row');
@ -38,7 +38,7 @@ define('admin/manage/tags', [
createModalGo.on('click', function () { createModalGo.on('click', function () {
socket.emit('admin.tags.create', { socket.emit('admin.tags.create', {
tag: createTagName.val() tag: createTagName.val(),
}, function (err) { }, function (err) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
@ -61,12 +61,16 @@ define('admin/manage/tags', [
} }
timeoutId = setTimeout(function () { timeoutId = setTimeout(function () {
socket.emit('topics.searchAndLoadTags', {query: $('#tag-search').val()}, function (err, result) { socket.emit('topics.searchAndLoadTags', {
query: $('#tag-search').val(),
}, function (err, result) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
} }
app.parseAndTranslate('admin/manage/tags', 'tags', {tags: result.tags}, function (html) { app.parseAndTranslate('admin/manage/tags', 'tags', {
tags: result.tags,
}, function (html) {
$('.tag-list').html(html); $('.tag-list').html(html);
utils.makeNumbersHumanReadable(html.find('.human-readable-number')); utils.makeNumbersHumanReadable(html.find('.human-readable-number'));
timeoutId = 0; timeoutId = 0;
@ -85,20 +89,20 @@ define('admin/manage/tags', [
return; return;
} }
var firstTag = $(tagsToModify[0]), var firstTag = $(tagsToModify[0]);
title = tagsToModify.length > 1 ? '[[admin/manage/tags:alerts.editing-multiple]]' : '[[admin/manage/tags:alerts.editing-x, ' + firstTag.find('.tag-item').text() + ']]'; var title = tagsToModify.length > 1 ? '[[admin/manage/tags:alerts.editing-multiple]]' : '[[admin/manage/tags:alerts.editing-x, ' + firstTag.find('.tag-item').attr('data-tag') + ']]';
var modal = bootbox.dialog({ var modal = bootbox.dialog({
title: title, title: title,
message: firstTag.find('.tag-modal').html(), message: firstTag.find('.tag-modal').html(),
buttons: { buttons: {
success: { success: {
label: "Save", label: 'Save',
className: "btn-primary save", className: 'btn-primary save',
callback: function () { callback: function () {
var modal = $('.bootbox'), var modal = $('.bootbox');
bgColor = modal.find('[data-name="bgColor"]').val(), var bgColor = modal.find('[data-name="bgColor"]').val();
color = modal.find('[data-name="color"]').val(); var color = modal.find('[data-name="color"]').val();
tagsToModify.each(function (idx, tag) { tagsToModify.each(function (idx, tag) {
tag = $(tag); tag = $(tag);
@ -109,9 +113,9 @@ define('admin/manage/tags', [
save(tag); save(tag);
}); });
} },
} },
} },
}); });
handleColorPickers(modal); handleColorPickers(modal);
@ -133,7 +137,9 @@ define('admin/manage/tags', [
tagsToDelete.each(function (index, el) { tagsToDelete.each(function (index, el) {
tags.push($(el).attr('data-tag')); tags.push($(el).attr('data-tag'));
}); });
socket.emit('admin.tags.deleteTags', {tags: tags}, function (err) { socket.emit('admin.tags.deleteTags', {
tags: tags,
}, function (err) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
} }
@ -155,8 +161,8 @@ define('admin/manage/tags', [
function save(tag) { function save(tag) {
var data = { var data = {
tag: tag.attr('data-tag'), tag: tag.attr('data-tag'),
bgColor : tag.find('[data-name="bgColor"]').val(), bgColor: tag.find('[data-name="bgColor"]').val(),
color : tag.find('[data-name="color"]').val() color: tag.find('[data-name="color"]').val(),
}; };
socket.emit('admin.tags.update', data, function (err) { socket.emit('admin.tags.update', data, function (err) {
@ -169,4 +175,4 @@ define('admin/manage/tags', [
} }
return Tags; return Tags;
}); });

@ -1,6 +1,5 @@
"use strict"; 'use strict';
/* global config, socket, define, templates, bootbox, app, ajaxify */
define('admin/manage/users', ['translator'], function (translator) { define('admin/manage/users', ['translator'], function (translator) {
var Users = {}; var Users = {};
@ -91,7 +90,7 @@ define('admin/manage/users', ['translator'], function (translator) {
buttons: { buttons: {
close: { close: {
label: '[[global:close]]', label: '[[global:close]]',
className: 'btn-link' className: 'btn-link',
}, },
submit: { submit: {
label: '[[admin/manage/users:alerts.button-ban-x, ' + uids.length + ']]', label: '[[admin/manage/users:alerts.button-ban-x, ' + uids.length + ']]',
@ -100,11 +99,11 @@ define('admin/manage/users', ['translator'], function (translator) {
data[cur.name] = cur.value; data[cur.name] = cur.value;
return data; return data;
}, {}); }, {});
var until = formData.length ? (Date.now() + formData.length * 1000 * 60 * 60 * (parseInt(formData.unit, 10) ? 24 : 1)) : 0; var until = formData.length ? (Date.now() + (formData.length * 1000 * 60 * 60 * (parseInt(formData.unit, 10) ? 24 : 1))) : 0;
socket.emit('user.banUsers', { uids: uids, until: until, reason: formData.reason }, done('[[admin/manage/users:alerts.ban-success]]', '.ban', true)); socket.emit('user.banUsers', { uids: uids, until: until, reason: formData.reason }, done('[[admin/manage/users:alerts.ban-success]]', '.ban', true));
} },
} },
} },
}); });
}); });
}); });
@ -257,7 +256,7 @@ define('admin/manage/users', ['translator'], function (translator) {
buttons: { buttons: {
cancel: { cancel: {
label: '[[admin/manage/users:alerts.button-cancel]]', label: '[[admin/manage/users:alerts.button-cancel]]',
className: 'btn-link' className: 'btn-link',
}, },
create: { create: {
label: '[[admin/manage/users:alerts.button-create]]', label: '[[admin/manage/users:alerts.button-create]]',
@ -265,9 +264,9 @@ define('admin/manage/users', ['translator'], function (translator) {
callback: function () { callback: function () {
createUser.call(this); createUser.call(this);
return false; return false;
} },
} },
} },
}); });
}); });
}); });
@ -289,11 +288,11 @@ define('admin/manage/users', ['translator'], function (translator) {
var user = { var user = {
username: username, username: username,
email: email, email: email,
password: password password: password,
}; };
socket.emit('admin.user.createUser', user, function (err) { socket.emit('admin.user.createUser', user, function (err) {
if(err) { if (err) {
return errorEl.translateHtml('[[admin/manage/users:alerts.error-x, ' + err.message + ']]').removeClass('hide'); return errorEl.translateHtml('[[admin/manage/users:alerts.error-x, ' + err.message + ']]').removeClass('hide');
} }
@ -314,12 +313,12 @@ define('admin/manage/users', ['translator'], function (translator) {
} }
var $this = $(this); var $this = $(this);
var type = $this.attr('data-search-type'); var type = $this.attr('data-search-type');
timeoutId = setTimeout(function () { timeoutId = setTimeout(function () {
$('.fa-spinner').removeClass('hidden'); $('.fa-spinner').removeClass('hidden');
socket.emit('admin.user.search', {searchBy: type, query: $this.val()}, function (err, data) { socket.emit('admin.user.search', { searchBy: type, query: $this.val() }, function (err, data) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
} }
@ -352,7 +351,6 @@ define('admin/manage/users', ['translator'], function (translator) {
handleUserCreate(); handleUserCreate();
handleInvite(); handleInvite();
}; };
function handleInvite() { function handleInvite() {

@ -1,6 +1,5 @@
"use strict"; 'use strict';
/*globals define*/
define('admin/modules/colorpicker', function () { define('admin/modules/colorpicker', function () {
var colorpicker = {}; var colorpicker = {};
@ -19,7 +18,7 @@ define('admin/modules/colorpicker', function () {
}, },
onShow: function (colpkr) { onShow: function (colpkr) {
$(colpkr).css('z-index', 1051); $(colpkr).css('z-index', 1051);
} },
}); });
}); });
}; };

@ -1,6 +1,5 @@
"use strict"; 'use strict';
/*globals define, app, socket*/
define('admin/modules/instance', function () { define('admin/modules/instance', function () {
var instance = {}; var instance = {};
@ -11,7 +10,7 @@ define('admin/modules/instance', function () {
type: 'info', type: 'info',
title: 'Reloading... <i class="fa fa-spin fa-refresh"></i>', title: 'Reloading... <i class="fa fa-spin fa-refresh"></i>',
message: 'NodeBB is reloading.', message: 'NodeBB is reloading.',
timeout: 5000 timeout: 5000,
}); });
$(window).one('action:reconnected', function () { $(window).one('action:reconnected', function () {
@ -20,7 +19,7 @@ define('admin/modules/instance', function () {
type: 'success', type: 'success',
title: '<i class="fa fa-check"></i> Success', title: '<i class="fa fa-check"></i> Success',
message: 'NodeBB has reloaded successfully.', message: 'NodeBB has reloaded successfully.',
timeout: 5000 timeout: 5000,
}); });
if (typeof callback === 'function') { if (typeof callback === 'function') {
@ -37,7 +36,7 @@ define('admin/modules/instance', function () {
type: 'info', type: 'info',
title: 'Rebuilding... <i class="fa fa-spin fa-refresh"></i>', title: 'Rebuilding... <i class="fa fa-spin fa-refresh"></i>',
message: 'NodeBB is rebuilding front-end assets (css, javascript, etc).', message: 'NodeBB is rebuilding front-end assets (css, javascript, etc).',
timeout: 10000 timeout: 10000,
}); });
$(window).one('action:reconnected', function () { $(window).one('action:reconnected', function () {
@ -46,7 +45,7 @@ define('admin/modules/instance', function () {
type: 'success', type: 'success',
title: '<i class="fa fa-check"></i> Success', title: '<i class="fa fa-check"></i> Success',
message: 'NodeBB has successfully restarted.', message: 'NodeBB has successfully restarted.',
timeout: 10000 timeout: 10000,
}); });
if (typeof callback === 'function') { if (typeof callback === 'function') {
@ -60,7 +59,7 @@ define('admin/modules/instance', function () {
type: 'info', type: 'info',
title: 'Build Complete!... <i class="fa fa-spin fa-refresh"></i>', title: 'Build Complete!... <i class="fa fa-spin fa-refresh"></i>',
message: 'NodeBB is reloading.', message: 'NodeBB is reloading.',
timeout: 10000 timeout: 10000,
}); });
}); });
}; };

@ -1,5 +1,5 @@
"use strict"; 'use strict';
/* globals socket, app, define, ajaxify, config */
define('admin/modules/search', ['mousetrap'], function (mousetrap) { define('admin/modules/search', ['mousetrap'], function (mousetrap) {
var search = {}; var search = {};
@ -73,7 +73,7 @@ define('admin/modules/search', ['mousetrap'], function (mousetrap) {
if (!selected.length) { if (!selected.length) {
selected = menu.find('li.result > a').first().attr('href'); selected = menu.find('li.result > a').first().attr('href');
} }
var href = selected ? selected : config.relative_path + '/search/' + input.val(); var href = selected || config.relative_path + '/search/' + input.val();
ajaxify.go(href.replace(/^\//, '')); ajaxify.go(href.replace(/^\//, ''));
@ -128,7 +128,7 @@ define('admin/modules/search', ['mousetrap'], function (mousetrap) {
menu.toggleClass('state-start-typing', len === 0); menu.toggleClass('state-start-typing', len === 0);
menu.toggleClass('state-keep-typing', len > 0 && len < 3); menu.toggleClass('state-keep-typing', len > 0 && len < 3);
if (len >= 3) { if (len >= 3) {
menu.prepend(find(dict, value)); menu.prepend(find(dict, value));
@ -150,4 +150,4 @@ define('admin/modules/search', ['mousetrap'], function (mousetrap) {
} }
return search; return search;
}); });

@ -1,13 +1,12 @@
"use strict"; 'use strict';
/*globals define*/
define('admin/modules/selectable', ['jqueryui'], function (jqueryui) { define('admin/modules/selectable', ['jqueryui'], function () {
var selectable = {}; var selectable = {};
selectable.enable = function (containerEl, targets) { selectable.enable = function (containerEl, targets) {
$(containerEl).selectable({ $(containerEl).selectable({
filter: targets filter: targets,
}); });
}; };

@ -1,5 +1,5 @@
'use strict'; 'use strict';
/*global define, app, socket, ajaxify */
define('admin/settings', ['uploader'], function (uploader) { define('admin/settings', ['uploader'], function (uploader) {
var Settings = {}; var Settings = {};
@ -11,8 +11,8 @@ define('admin/settings', ['uploader'], function (uploader) {
Settings.populateTOC = function () { Settings.populateTOC = function () {
$('.settings-header').each(function () { $('.settings-header').each(function () {
var header = $(this).text(), var header = $(this).text();
anchor = header.toLowerCase().replace(/ /g, '-').trim(); var anchor = header.toLowerCase().replace(/ /g, '-').trim();
$(this).prepend('<a name="' + anchor + '"></a>'); $(this).prepend('<a name="' + anchor + '"></a>');
$('.section-content ul').append('<li><a href="#' + anchor + '">' + header + '</a></li>'); $('.section-content ul').append('<li><a href="#' + anchor + '">' + header + '</a></li>');
@ -21,11 +21,14 @@ define('admin/settings', ['uploader'], function (uploader) {
Settings.prepare = function (callback) { Settings.prepare = function (callback) {
// Populate the fields on the page from the config // Populate the fields on the page from the config
var fields = $('#content [data-field]'), var fields = $('#content [data-field]');
numFields = fields.length, var numFields = fields.length;
saveBtn = $('#save'), var saveBtn = $('#save');
revertBtn = $('#revert'), var revertBtn = $('#revert');
x, key, inputType, field; var x;
var key;
var inputType;
var field;
// Handle unsaved changes // Handle unsaved changes
$(fields).on('change', function () { $(fields).on('change', function () {
@ -33,7 +36,7 @@ define('admin/settings', ['uploader'], function (uploader) {
app.flags._unsaved = true; app.flags._unsaved = true;
}); });
for (x = 0; x < numFields; x++) { for (x = 0; x < numFields; x += 1) {
field = fields.eq(x); field = fields.eq(x);
key = field.attr('data-field'); key = field.attr('data-field');
inputType = field.attr('type'); inputType = field.attr('type');
@ -80,7 +83,7 @@ define('admin/settings', ['uploader'], function (uploader) {
timeout: 2500, timeout: 2500,
title: 'Changes Not Saved', title: 'Changes Not Saved',
message: 'NodeBB encountered a problem saving your changes', message: 'NodeBB encountered a problem saving your changes',
type: 'danger' type: 'danger',
}); });
} }
@ -91,7 +94,7 @@ define('admin/settings', ['uploader'], function (uploader) {
timeout: 2500, timeout: 2500,
title: 'Changes Saved', title: 'Changes Saved',
message: 'Your changes to the NodeBB configuration have been saved.', message: 'Your changes to the NodeBB configuration have been saved.',
type: 'success' type: 'success',
}); });
$(window).trigger('action:admin.settingsSaved'); $(window).trigger('action:admin.settingsSaved');
@ -126,7 +129,7 @@ define('admin/settings', ['uploader'], function (uploader) {
route: uploadBtn.attr('data-route'), route: uploadBtn.attr('data-route'),
params: {}, params: {},
showHelp: uploadBtn.attr('data-help') ? uploadBtn.attr('data-help') === 1 : undefined, showHelp: uploadBtn.attr('data-help') ? uploadBtn.attr('data-help') === 1 : undefined,
accept: uploadBtn.attr('data-accept') accept: uploadBtn.attr('data-accept'),
}, function (image) { }, function (image) {
// need to move these into template, ex data-callback // need to move these into template, ex data-callback
if (ajaxify.currentPage === 'admin/general/sounds') { if (ajaxify.currentPage === 'admin/general/sounds') {
@ -148,8 +151,9 @@ define('admin/settings', ['uploader'], function (uploader) {
fields.each(function () { fields.each(function () {
var field = $(this); var field = $(this);
var key = field.attr('data-field'), var key = field.attr('data-field');
value, inputType; var value;
var inputType;
if (field.is('input')) { if (field.is('input')) {
inputType = field.attr('type'); inputType = field.attr('type');
@ -178,7 +182,7 @@ define('admin/settings', ['uploader'], function (uploader) {
return callback(err); return callback(err);
} }
for(var field in data) { for (var field in data) {
if (data.hasOwnProperty(field)) { if (data.hasOwnProperty(field)) {
app.config[field] = data[field]; app.config[field] = data[field];
} }

@ -1,9 +1,8 @@
'use strict'; 'use strict';
/* globals define */
define('admin/settings/cookies', [ define('admin/settings/cookies', [
'admin/modules/colorpicker' 'admin/modules/colorpicker',
], function (colorpicker) { ], function (colorpicker) {
var Module = {}; var Module = {};
@ -22,4 +21,4 @@ define('admin/settings/cookies', [
}; };
return Module; return Module;
}); });

@ -1,9 +1,9 @@
"use strict"; 'use strict';
/* global define, socket, app, ajaxify, ace */
define('admin/settings/email', ['admin/settings'], function (settings) {
var module = {}, define('admin/settings/email', ['admin/settings'], function () {
emailEditor; var module = {};
var emailEditor;
module.init = function () { module.init = function () {
configureEmailTester(); configureEmailTester();
@ -17,7 +17,7 @@ define('admin/settings/email', ['admin/settings'], function (settings) {
function configureEmailTester() { function configureEmailTester() {
$('button[data-action="email.test"]').off('click').on('click', function () { $('button[data-action="email.test"]').off('click').on('click', function () {
socket.emit('admin.email.test', {template: $('#test-email').val()}, function (err) { socket.emit('admin.email.test', { template: $('#test-email').val() }, function (err) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
} }
@ -30,10 +30,10 @@ define('admin/settings/email', ['admin/settings'], function (settings) {
function configureEmailEditor() { function configureEmailEditor() {
$('#email-editor-selector').on('change', updateEmailEditor); $('#email-editor-selector').on('change', updateEmailEditor);
emailEditor = ace.edit("email-editor"); emailEditor = ace.edit('email-editor');
emailEditor.$blockScrolling = Infinity; emailEditor.$blockScrolling = Infinity;
emailEditor.setTheme("ace/theme/twilight"); emailEditor.setTheme('ace/theme/twilight');
emailEditor.getSession().setMode("ace/mode/html"); emailEditor.getSession().setMode('ace/mode/html');
emailEditor.on('change', function () { emailEditor.on('change', function () {
var emailPath = $('#email-editor-selector').val(); var emailPath = $('#email-editor-selector').val();

@ -1,7 +1,7 @@
"use strict"; 'use strict';
/* global define, socket */
define('admin/settings/general', ['admin/settings'], function (Settings) {
define('admin/settings/general', ['admin/settings'], function () {
var Module = {}; var Module = {};
Module.init = function () { Module.init = function () {

@ -1,7 +1,7 @@
"use strict"; 'use strict';
/*global app, bootbox, templates, socket, config, RELATIVE_PATH*/
var ajaxify = ajaxify || {};
var ajaxify = window.ajaxify || {};
$(document).ready(function () { $(document).ready(function () {
var location = document.location || window.location; var location = document.location || window.location;
@ -25,11 +25,11 @@ $(document).ready(function () {
if (ev !== null && ev.state) { if (ev !== null && ev.state) {
if (ev.state.url === null && ev.state.returnPath !== undefined) { if (ev.state.url === null && ev.state.returnPath !== undefined) {
window.history.replaceState({ window.history.replaceState({
url: ev.state.returnPath url: ev.state.returnPath,
}, ev.state.returnPath, config.relative_path + '/' + ev.state.returnPath); }, ev.state.returnPath, config.relative_path + '/' + ev.state.returnPath);
} else if (ev.state.url !== undefined) { } else if (ev.state.url !== undefined) {
ajaxify.go(ev.state.url, function () { ajaxify.go(ev.state.url, function () {
$(window).trigger('action:popstate', {url: ev.state.url}); $(window).trigger('action:popstate', { url: ev.state.url });
}, true); }, true);
} }
} }
@ -73,7 +73,7 @@ $(document).ready(function () {
// If any listeners alter url and set it to an empty string, abort the ajaxification // If any listeners alter url and set it to an empty string, abort the ajaxification
if (url === null) { if (url === null) {
$(window).trigger('action:ajaxify.end', {url: url, tpl_url: ajaxify.data.template.name, title: ajaxify.data.title}); $(window).trigger('action:ajaxify.end', { url: url, tpl_url: ajaxify.data.template.name, title: ajaxify.data.title });
return false; return false;
} }
@ -81,7 +81,6 @@ $(document).ready(function () {
$('#footer, #content').removeClass('hide').addClass('ajaxifying'); $('#footer, #content').removeClass('hide').addClass('ajaxifying');
ajaxify.loadData(url, function (err, data) { ajaxify.loadData(url, function (err, data) {
if (!err || (err && err.data && (parseInt(err.data.status, 10) !== 302 && parseInt(err.data.status, 10) !== 308))) { if (!err || (err && err.data && (parseInt(err.data.status, 10) !== 302 && parseInt(err.data.status, 10) !== 308))) {
ajaxify.updateHistory(url, quiet); ajaxify.updateHistory(url, quiet);
} }
@ -116,7 +115,7 @@ $(document).ready(function () {
url = ajaxify.removeRelativePath(url.replace(/^\/|\/$/g, '')); url = ajaxify.removeRelativePath(url.replace(/^\/|\/$/g, ''));
var payload = { var payload = {
url: url url: url,
}; };
$(window).trigger('action:ajaxify.start', payload); $(window).trigger('action:ajaxify.start', payload);
@ -128,7 +127,7 @@ $(document).ready(function () {
ajaxify.currentPage = url.split(/[?#]/)[0]; ajaxify.currentPage = url.split(/[?#]/)[0];
if (window.history && window.history.pushState) { if (window.history && window.history.pushState) {
window.history[!quiet ? 'pushState' : 'replaceState']({ window.history[!quiet ? 'pushState' : 'replaceState']({
url: url url: url,
}, url, RELATIVE_PATH + '/' + url); }, url, RELATIVE_PATH + '/' + url);
} }
}; };
@ -158,7 +157,6 @@ $(document).ready(function () {
app.alertError('[[global:please_log_in]]'); app.alertError('[[global:please_log_in]]');
app.previousUrl = url; app.previousUrl = url;
window.location.href = config.relative_path + '/login'; window.location.href = config.relative_path + '/login';
return;
} else if (status === 302 || status === 308) { } else if (status === 302 || status === 308) {
if (data.responseJSON && data.responseJSON.external) { if (data.responseJSON && data.responseJSON.external) {
window.location.href = data.responseJSON.external; window.location.href = data.responseJSON.external;
@ -195,18 +193,19 @@ $(document).ready(function () {
} }
ajaxify.end = function (url, tpl_url) { ajaxify.end = function (url, tpl_url) {
var count = 2;
function done() { function done() {
if (--count === 0) { count -= 1;
$(window).trigger('action:ajaxify.end', {url: url, tpl_url: tpl_url, title: ajaxify.data.title}); if (count === 0) {
$(window).trigger('action:ajaxify.end', { url: url, tpl_url: tpl_url, title: ajaxify.data.title });
} }
} }
var count = 2;
ajaxify.loadScript(tpl_url, done); ajaxify.loadScript(tpl_url, done);
ajaxify.widgets.render(tpl_url, url, done); ajaxify.widgets.render(tpl_url, url, done);
$(window).trigger('action:ajaxify.contentLoaded', {url: url, tpl: tpl_url}); $(window).trigger('action:ajaxify.contentLoaded', { url: url, tpl: tpl_url });
app.processPage(); app.processPage();
@ -243,7 +242,7 @@ $(document).ready(function () {
} }
var data = { var data = {
tpl_url: tpl_url, tpl_url: tpl_url,
scripts: [location + tpl_url] scripts: [location + tpl_url],
}; };
$(window).trigger('action:script.load', data); $(window).trigger('action:script.load', data);
@ -285,13 +284,13 @@ $(document).ready(function () {
ajaxify.loadData = function (url, callback) { ajaxify.loadData = function (url, callback) {
url = ajaxify.removeRelativePath(url); url = ajaxify.removeRelativePath(url);
$(window).trigger('action:ajaxify.loadingData', {url: url}); $(window).trigger('action:ajaxify.loadingData', { url: url });
apiXHR = $.ajax({ apiXHR = $.ajax({
url: RELATIVE_PATH + '/api/' + url, url: RELATIVE_PATH + '/api/' + url,
cache: false, cache: false,
headers: { headers: {
'X-Return-To': app.previousUrl 'X-Return-To': app.previousUrl,
}, },
success: function (data) { success: function (data) {
if (!data) { if (!data) {
@ -301,7 +300,7 @@ $(document).ready(function () {
ajaxify.data = data; ajaxify.data = data;
data.config = config; data.config = config;
$(window).trigger('action:ajaxify.dataLoaded', {url: url, data: data}); $(window).trigger('action:ajaxify.dataLoaded', { url: url, data: data });
callback(null, data); callback(null, data);
}, },
@ -311,9 +310,9 @@ $(document).ready(function () {
} }
callback({ callback({
data: data, data: data,
textStatus: textStatus textStatus: textStatus,
}); });
} },
}); });
}; };
@ -322,14 +321,14 @@ $(document).ready(function () {
callback(templates.cache[template]); callback(templates.cache[template]);
} else { } else {
$.ajax({ $.ajax({
url: config.relative_path + '/assets/templates/' + template + '.tpl' + '?' + config['cache-buster'], url: config.relative_path + '/assets/templates/' + template + '.tpl?' + config['cache-buster'],
type: 'GET', type: 'GET',
success: function (data) { success: function (data) {
callback(data.toString()); callback(data.toString());
}, },
error: function (error) { error: function (error) {
throw new Error("Unable to load template: " + template + " (" + error.statusText + ")"); throw new Error('Unable to load template: ' + template + ' (' + error.statusText + ')');
} },
}); });
} }
}; };
@ -344,6 +343,12 @@ $(document).ready(function () {
// Enhancing all anchors to ajaxify... // Enhancing all anchors to ajaxify...
$(document.body).on('click', 'a', function (e) { $(document.body).on('click', 'a', function (e) {
var _self = this; var _self = this;
if (this.target !== '' || (this.protocol !== 'http:' && this.protocol !== 'https:')) {
return;
}
var internalLink = utils.isInternalURI(this, window.location, RELATIVE_PATH);
var process = function () { var process = function () {
if (!e.ctrlKey && !e.shiftKey && !e.metaKey && e.which === 1) { if (!e.ctrlKey && !e.shiftKey && !e.metaKey && e.which === 1) {
if (internalLink) { if (internalLink) {
@ -352,10 +357,8 @@ $(document).ready(function () {
// Special handling for urls with hashes // Special handling for urls with hashes
if (window.location.pathname === this.pathname && this.hash.length) { if (window.location.pathname === this.pathname && this.hash.length) {
window.location.hash = this.hash; window.location.hash = this.hash;
} else { } else if (ajaxify.go(pathname)) {
if (ajaxify.go(pathname)) { e.preventDefault();
e.preventDefault();
}
} }
} else if (window.location.pathname !== '/outgoing') { } else if (window.location.pathname !== '/outgoing') {
if (config.openOutgoingLinksInNewTab && $.contains(contentEl, this)) { if (config.openOutgoingLinksInNewTab && $.contains(contentEl, this)) {
@ -369,18 +372,11 @@ $(document).ready(function () {
} }
}; };
if (this.target !== '' || (this.protocol !== 'http:' && this.protocol !== 'https:')) {
return;
}
var internalLink = utils.isInternalURI(this, window.location, RELATIVE_PATH);
if ($(this).attr('data-ajaxify') === 'false') { if ($(this).attr('data-ajaxify') === 'false') {
if (!internalLink) { if (!internalLink) {
return; return;
} else {
return e.preventDefault();
} }
return e.preventDefault();
} }
// Default behaviour for rss feeds // Default behaviour for rss feeds
@ -421,5 +417,4 @@ $(document).ready(function () {
templates.cache[$(this).attr('data-template')] = $('<div/>').html($(this).html()).text(); templates.cache[$(this).attr('data-template')] = $('<div/>').html($(this).html()).text();
$(this).parent().remove(); $(this).parent().remove();
}); });
});
});

@ -1,7 +1,7 @@
"use strict"; 'use strict';
/*global templates, ajaxify, utils, bootbox, overrides, socket, config, Visibility*/
var app = app || {};
var app = window.app || {};
app.isFocused = true; app.isFocused = true;
app.currentRoom = null; app.currentRoom = null;
@ -17,7 +17,7 @@ app.cacheBuster = null;
app.cacheBuster = config['cache-buster']; app.cacheBuster = config['cache-buster'];
bootbox.setDefaults({ bootbox.setDefaults({
locale: config.userLang locale: config.userLang,
}); });
app.load = function () { app.load = function () {
@ -69,7 +69,7 @@ app.cacheBuster = null;
clickfn: function () { clickfn: function () {
window.location.reload(); window.location.reload();
}, },
type: 'warning' type: 'warning',
}); });
} }
}); });
@ -77,7 +77,6 @@ app.cacheBuster = null;
require(['taskbar', 'helpers', 'forum/pagination'], function (taskbar, helpers, pagination) { require(['taskbar', 'helpers', 'forum/pagination'], function (taskbar, helpers, pagination) {
taskbar.init(); taskbar.init();
// templates.js helpers
helpers.register(); helpers.register();
pagination.init(); pagination.init();
@ -99,16 +98,16 @@ app.cacheBuster = null;
$.ajax(config.relative_path + '/logout', { $.ajax(config.relative_path + '/logout', {
type: 'POST', type: 'POST',
headers: { headers: {
'x-csrf-token': config.csrf_token 'x-csrf-token': config.csrf_token,
}, },
success: function () { success: function () {
var payload = { var payload = {
next: config.relative_path + '/' next: config.relative_path + '/',
}; };
$(window).trigger('action:app.loggedOut', payload); $(window).trigger('action:app.loggedOut', payload);
window.location.href = payload.next; window.location.href = payload.next;
} },
}); });
}; };
@ -129,7 +128,7 @@ app.cacheBuster = null;
title: '[[global:alert.success]]', title: '[[global:alert.success]]',
message: message, message: message,
type: 'success', type: 'success',
timeout: timeout ? timeout : 5000 timeout: timeout || 5000,
}); });
}; };
@ -144,7 +143,7 @@ app.cacheBuster = null;
title: '[[global:alert.error]]', title: '[[global:alert.error]]',
message: message, message: message,
type: 'danger', type: 'danger',
timeout: timeout ? timeout : 10000 timeout: timeout || 10000,
}); });
}; };
@ -164,7 +163,7 @@ app.cacheBuster = null;
closeButton: false, closeButton: false,
callback: function () { callback: function () {
window.location.reload(); window.location.reload();
} },
}); });
}); });
}); });
@ -176,7 +175,7 @@ app.cacheBuster = null;
var previousRoom = app.currentRoom; var previousRoom = app.currentRoom;
app.currentRoom = room; app.currentRoom = room;
socket.emit('meta.rooms.enter', { socket.emit('meta.rooms.enter', {
enter: room enter: room,
}, function (err) { }, function (err) {
if (err) { if (err) {
app.currentRoom = previousRoom; app.currentRoom = previousRoom;
@ -214,7 +213,7 @@ app.cacheBuster = null;
if (!utils.isTouchDevice()) { if (!utils.isTouchDevice()) {
$(this).tooltip({ $(this).tooltip({
placement: placement || $(this).attr('title-placement') || 'top', placement: placement || $(this).attr('title-placement') || 'top',
title: $(this).attr('title') title: $(this).attr('title'),
}); });
} }
}); });
@ -223,8 +222,8 @@ app.cacheBuster = null;
app.createStatusTooltips = function () { app.createStatusTooltips = function () {
if (!utils.isTouchDevice()) { if (!utils.isTouchDevice()) {
$('body').tooltip({ $('body').tooltip({
selector:'.fa-circle.status', selector: '.fa-circle.status',
placement: 'top' placement: 'top',
}); });
} }
}; };
@ -263,36 +262,36 @@ app.cacheBuster = null;
login: { login: {
format: 'alert', format: 'alert',
title: '[[global:welcome_back]] ' + app.user.username + '!', title: '[[global:welcome_back]] ' + app.user.username + '!',
message: '[[global:you_have_successfully_logged_in]]' message: '[[global:you_have_successfully_logged_in]]',
}, },
banned: { banned: {
format: 'modal', format: 'modal',
title: '[[error:user-banned]]', title: '[[error:user-banned]]',
message: '[[error:user-banned-reason, ' + utils.params().banned + ']]' message: '[[error:user-banned-reason, ' + utils.params().banned + ']]',
} },
}; };
function showAlert(type) { function showAlert(type) {
switch (messages[type].format) { switch (messages[type].format) {
case 'alert': case 'alert':
app.alert({ app.alert({
type: 'success', type: 'success',
title: messages[type].title, title: messages[type].title,
message: messages[type].message, message: messages[type].message,
timeout: 5000 timeout: 5000,
}); });
break; break;
case 'modal': case 'modal':
require(['translator'], function (translator) { require(['translator'], function (translator) {
translator.translate(messages[type].message, function (translated) { translator.translate(messages[type].message, function (translated) {
bootbox.alert({ bootbox.alert({
title: messages[type].title, title: messages[type].title,
message: translated message: translated,
});
}); });
}); });
break; });
break;
} }
} }
@ -326,7 +325,7 @@ app.cacheBuster = null;
if (chat.modalExists(roomId)) { if (chat.modalExists(roomId)) {
loadAndCenter(chat.getModal(roomId)); loadAndCenter(chat.getModal(roomId));
} else { } else {
socket.emit('modules.chats.loadRoom', {roomId: roomId, uid: uid || app.user.uid}, function (err, roomData) { socket.emit('modules.chats.loadRoom', { roomId: roomId, uid: uid || app.user.uid }, function (err, roomData) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
} }
@ -350,7 +349,7 @@ app.cacheBuster = null;
return app.alertError('[[error:cant-chat-with-yourself]]'); return app.alertError('[[error:cant-chat-with-yourself]]');
} }
socket.emit('modules.chats.newRoom', {touid: touid}, function (err, roomId) { socket.emit('modules.chats.newRoom', { touid: touid }, function (err, roomId) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
} }
@ -366,10 +365,10 @@ app.cacheBuster = null;
}; };
var titleObj = { var titleObj = {
active: false, active: false,
interval: undefined, interval: undefined,
titles: [] titles: [],
}; };
app.alternatingTitle = function (title) { app.alternatingTitle = function (title) {
if (typeof title !== 'string') { if (typeof title !== 'string') {
@ -425,7 +424,7 @@ app.cacheBuster = null;
app.toggleNavbar = function (state) { app.toggleNavbar = function (state) {
var navbarEl = $('.navbar'); var navbarEl = $('.navbar');
if (navbarEl) { if (navbarEl) {
navbarEl.toggleClass('hidden', !!!state); navbarEl.toggleClass('hidden', !state);
} }
}; };
@ -439,7 +438,7 @@ app.cacheBuster = null;
$(this).tooltip({ $(this).tooltip({
placement: 'bottom', placement: 'bottom',
trigger: 'hover', trigger: 'hover',
title: $(this).attr('title') title: $(this).attr('title'),
}); });
} }
}); });
@ -448,7 +447,7 @@ app.cacheBuster = null;
$('#search-form').parent().tooltip({ $('#search-form').parent().tooltip({
placement: 'bottom', placement: 'bottom',
trigger: 'hover', trigger: 'hover',
title: $('#search-button i').attr('title') title: $('#search-button i').attr('title'),
}); });
} }
@ -456,15 +455,15 @@ app.cacheBuster = null;
$('#user_dropdown').tooltip({ $('#user_dropdown').tooltip({
placement: 'bottom', placement: 'bottom',
trigger: 'hover', trigger: 'hover',
title: $('#user_dropdown').attr('title') title: $('#user_dropdown').attr('title'),
}); });
} }
} }
app.handleSearch = function () { app.handleSearch = function () {
var searchButton = $("#search-button"), var searchButton = $('#search-button');
searchFields = $("#search-fields"), var searchFields = $('#search-fields');
searchInput = $('#search-fields input'); var searchInput = $('#search-fields input');
$('#search-form .advanced-search-link').on('mousedown', function () { $('#search-form .advanced-search-link').on('mousedown', function () {
ajaxify.go('/search'); ajaxify.go('/search');
@ -481,8 +480,8 @@ app.cacheBuster = null;
searchButton.on('click', function (e) { searchButton.on('click', function (e) {
if (!config.loggedIn && !config.allowGuestSearching) { if (!config.loggedIn && !config.allowGuestSearching) {
app.alert({ app.alert({
message:'[[error:search-requires-login]]', message: '[[error:search-requires-login]]',
timeout: 3000 timeout: 3000,
}); });
ajaxify.go('login'); ajaxify.go('login');
return false; return false;
@ -507,8 +506,8 @@ app.cacheBuster = null;
}; };
app.prepareSearch = function () { app.prepareSearch = function () {
$("#search-fields").removeClass('hidden'); $('#search-fields').removeClass('hidden');
$("#search-button").addClass('hidden'); $('#search-button').addClass('hidden');
$('#search-fields input').focus(); $('#search-fields input').focus();
}; };
@ -516,7 +515,7 @@ app.cacheBuster = null;
$('[component="header/usercontrol"] [data-status]').off('click').on('click', function (e) { $('[component="header/usercontrol"] [data-status]').off('click').on('click', function (e) {
var status = $(this).attr('data-status'); var status = $(this).attr('data-status');
socket.emit('user.setStatus', status, function (err) { socket.emit('user.setStatus', status, function (err) {
if(err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
} }
$('[data-uid="' + app.user.uid + '"] [component="user/status"], [component="header/profilelink"] [component="user/status"]') $('[data-uid="' + app.user.uid + '"] [component="user/status"], [component="header/profilelink"] [component="user/status"]')
@ -547,7 +546,7 @@ app.cacheBuster = null;
app.newTopic = function (cid, tags) { app.newTopic = function (cid, tags) {
$(window).trigger('action:composer.topic.new', { $(window).trigger('action:composer.topic.new', {
cid: cid || ajaxify.data.cid || 0, cid: cid || ajaxify.data.cid || 0,
tags: tags || (ajaxify.data.tag ? [ajaxify.data.tag] : []) tags: tags || (ajaxify.data.tag ? [ajaxify.data.tag] : []),
}); });
}; };
@ -558,7 +557,7 @@ app.cacheBuster = null;
var scriptEl = document.createElement('script'); var scriptEl = document.createElement('script');
scriptEl.type = 'text/javascript'; scriptEl.type = 'text/javascript';
scriptEl.src = config.relative_path + '/assets/vendor/jquery/js/jquery-ui.js' + '?' + config['cache-buster']; scriptEl.src = config.relative_path + '/assets/vendor/jquery/js/jquery-ui.js?' + config['cache-buster'];
scriptEl.onload = callback; scriptEl.onload = callback;
document.head.appendChild(scriptEl); document.head.appendChild(scriptEl);
}; };
@ -570,7 +569,7 @@ app.cacheBuster = null;
var msg = { var msg = {
alert_id: 'email_confirm', alert_id: 'email_confirm',
type: 'warning', type: 'warning',
timeout: 0 timeout: 0,
}; };
if (!app.user.email) { if (!app.user.email) {
@ -657,6 +656,5 @@ app.cacheBuster = null;
}); });
}); });
}); });
}; };
}()); }());

@ -1,6 +1,5 @@
'use strict'; 'use strict';
/* globals define */
define('forum/account/best', ['forum/account/header', 'forum/account/posts'], function (header, posts) { define('forum/account/best', ['forum/account/header', 'forum/account/posts'], function (header, posts) {
var Best = {}; var Best = {};

@ -1,6 +1,5 @@
'use strict'; 'use strict';
/* globals define */
define('forum/account/bookmarks', ['forum/account/header', 'forum/account/posts'], function (header, posts) { define('forum/account/bookmarks', ['forum/account/header', 'forum/account/posts'], function (header, posts) {
var Bookmarks = {}; var Bookmarks = {};

@ -1,6 +1,5 @@
'use strict'; 'use strict';
/* globals define */
define('forum/account/downvoted', ['forum/account/header', 'forum/account/posts'], function (header, posts) { define('forum/account/downvoted', ['forum/account/header', 'forum/account/posts'], function (header, posts) {
var Downvoted = {}; var Downvoted = {};

@ -1,12 +1,10 @@
'use strict'; 'use strict';
/* globals define, ajaxify, socket, app, config, templates, bootbox */
define('forum/account/edit', ['forum/account/header', 'translator', 'components', 'pictureCropper'], function (header, translator, components, pictureCropper) { define('forum/account/edit', ['forum/account/header', 'translator', 'components', 'pictureCropper'], function (header, translator, components, pictureCropper) {
var AccountEdit = {}; var AccountEdit = {};
AccountEdit.init = function () { AccountEdit.init = function () {
header.init(); header.init();
$('#submitBtn').on('click', updateProfile); $('#submitBtn').on('click', updateProfile);
@ -16,7 +14,7 @@ define('forum/account/edit', ['forum/account/header', 'translator', 'components'
changeMonth: true, changeMonth: true,
changeYear: true, changeYear: true,
yearRange: '1900:-5y', yearRange: '1900:-5y',
defaultDate: '-13y' defaultDate: '-13y',
}); });
}); });
@ -36,7 +34,7 @@ define('forum/account/edit', ['forum/account/header', 'translator', 'components'
location: $('#inputLocation').val(), location: $('#inputLocation').val(),
groupTitle: $('#groupTitle').val(), groupTitle: $('#groupTitle').val(),
signature: $('#inputSignature').val(), signature: $('#inputSignature').val(),
aboutme: $('#inputAboutMe').val() aboutme: $('#inputAboutMe').val(),
}; };
$(window).trigger('action:profile.update', userData); $(window).trigger('action:profile.update', userData);
@ -71,10 +69,9 @@ define('forum/account/edit', ['forum/account/header', 'translator', 'components'
} }
function handleImageChange() { function handleImageChange() {
$('#changePictureBtn').on('click', function () { $('#changePictureBtn').on('click', function () {
socket.emit('user.getProfilePictures', { socket.emit('user.getProfilePictures', {
uid: ajaxify.data.uid uid: ajaxify.data.uid,
}, function (err, pictures) { }, function (err, pictures) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
@ -88,7 +85,7 @@ define('forum/account/edit', ['forum/account/header', 'translator', 'components'
templates.parse('partials/modals/change_picture_modal', { templates.parse('partials/modals/change_picture_modal', {
pictures: pictures, pictures: pictures,
uploaded: uploaded, uploaded: uploaded,
allowProfileImageUploads: ajaxify.data.allowProfileImageUploads allowProfileImageUploads: ajaxify.data.allowProfileImageUploads,
}, function (html) { }, function (html) {
translator.translate(html, function (html) { translator.translate(html, function (html) {
var modal = bootbox.dialog({ var modal = bootbox.dialog({
@ -100,13 +97,13 @@ define('forum/account/edit', ['forum/account/header', 'translator', 'components'
close: { close: {
label: '[[global:close]]', label: '[[global:close]]',
callback: onCloseModal, callback: onCloseModal,
className: 'btn-link' className: 'btn-link',
}, },
update: { update: {
label: '[[global:save_changes]]', label: '[[global:save_changes]]',
callback: saveSelection callback: saveSelection,
} },
} },
}); });
modal.on('shown.bs.modal', updateImages); modal.on('shown.bs.modal', updateImages);
@ -171,15 +168,14 @@ define('forum/account/edit', ['forum/account/header', 'translator', 'components'
if ($('#confirm-username').val() !== app.user.username) { if ($('#confirm-username').val() !== app.user.username) {
app.alertError('[[error:invalid-username]]'); app.alertError('[[error:invalid-username]]');
return false; return false;
} else {
socket.emit('user.deleteAccount', {}, function (err) {
if (err) {
return app.alertError(err.message);
}
window.location.href = config.relative_path + '/';
});
} }
socket.emit('user.deleteAccount', {}, function (err) {
if (err) {
return app.alertError(err.message);
}
window.location.href = config.relative_path + '/';
});
}); });
modal.on('shown.bs.modal', function () { modal.on('shown.bs.modal', function () {
@ -227,7 +223,7 @@ define('forum/account/edit', ['forum/account/header', 'translator', 'components'
imageDimension: ajaxify.data.profileImageDimension, imageDimension: ajaxify.data.profileImageDimension,
title: '[[user:upload_picture]]', title: '[[user:upload_picture]]',
description: '[[user:upload_a_picture]]', description: '[[user:upload_a_picture]]',
accept: '.png,.jpg,.bmp' accept: '.png,.jpg,.bmp',
}, function (url) { }, function (url) {
onUploadComplete(url); onUploadComplete(url);
}); });
@ -271,7 +267,7 @@ define('forum/account/edit', ['forum/account/header', 'translator', 'components'
modal.find('[data-action="remove-uploaded"]').on('click', function () { modal.find('[data-action="remove-uploaded"]').on('click', function () {
socket.emit('user.removeUploadedPicture', { socket.emit('user.removeUploadedPicture', {
uid: ajaxify.data.theirid uid: ajaxify.data.theirid,
}, function (err) { }, function (err) {
modal.modal('hide'); modal.modal('hide');
if (err) { if (err) {
@ -298,7 +294,7 @@ define('forum/account/edit', ['forum/account/header', 'translator', 'components'
function changeUserPicture(type, callback) { function changeUserPicture(type, callback) {
socket.emit('user.changePicture', { socket.emit('user.changePicture', {
type: type, type: type,
uid: ajaxify.data.theirid uid: ajaxify.data.theirid,
}, callback); }, callback);
} }

@ -1,6 +1,5 @@
'use strict'; 'use strict';
/* globals define, ajaxify, socket, app */
define('forum/account/edit/email', ['forum/account/header'], function (header) { define('forum/account/edit/email', ['forum/account/header'], function (header) {
var AccountEditEmail = {}; var AccountEditEmail = {};
@ -12,7 +11,7 @@ define('forum/account/edit/email', ['forum/account/header'], function (header) {
var userData = { var userData = {
uid: $('#inputUID').val(), uid: $('#inputUID').val(),
email: $('#inputNewEmail').val(), email: $('#inputNewEmail').val(),
password: $('#inputCurrentPassword').val() password: $('#inputCurrentPassword').val(),
}; };
if (!userData.email) { if (!userData.email) {

@ -1,6 +1,5 @@
'use strict'; 'use strict';
/* globals define, ajaxify, socket, app, utils */
define('forum/account/edit/password', ['forum/account/header', 'translator'], function (header, translator) { define('forum/account/edit/password', ['forum/account/header', 'translator'], function (header, translator) {
var AccountEditPassword = {}; var AccountEditPassword = {};
@ -64,9 +63,9 @@ define('forum/account/edit/password', ['forum/account/header', 'translator'], fu
if ((passwordvalid && passwordsmatch) || app.user.isAdmin) { if ((passwordvalid && passwordsmatch) || app.user.isAdmin) {
btn.addClass('disabled').find('i').removeClass('hide'); btn.addClass('disabled').find('i').removeClass('hide');
socket.emit('user.changePassword', { socket.emit('user.changePassword', {
'currentPassword': currentPassword.val(), currentPassword: currentPassword.val(),
'newPassword': password.val(), newPassword: password.val(),
'uid': ajaxify.data.theirid uid: ajaxify.data.theirid,
}, function (err) { }, function (err) {
btn.removeClass('disabled').find('i').addClass('hide'); btn.removeClass('disabled').find('i').addClass('hide');
currentPassword.val(''); currentPassword.val('');

@ -1,6 +1,5 @@
'use strict'; 'use strict';
/* globals define, ajaxify, socket, app, utils, config */
define('forum/account/edit/username', ['forum/account/header'], function (header) { define('forum/account/edit/username', ['forum/account/header'], function (header) {
var AccountEditUsername = {}; var AccountEditUsername = {};
@ -12,7 +11,7 @@ define('forum/account/edit/username', ['forum/account/header'], function (header
var userData = { var userData = {
uid: $('#inputUID').val(), uid: $('#inputUID').val(),
username: $('#inputNewUsername').val(), username: $('#inputNewUsername').val(),
password: $('#inputCurrentPassword').val() password: $('#inputCurrentPassword').val(),
}; };
if (!userData.username) { if (!userData.username) {

@ -1,6 +1,5 @@
'use strict'; 'use strict';
/* globals define */
define('forum/account/followers', ['forum/account/header'], function (header) { define('forum/account/followers', ['forum/account/header'], function (header) {
var Followers = {}; var Followers = {};

@ -1,6 +1,5 @@
'use strict'; 'use strict';
/* globals define */
define('forum/account/following', ['forum/account/header'], function (header) { define('forum/account/following', ['forum/account/header'], function (header) {
var Following = {}; var Following = {};

@ -1,6 +1,5 @@
'use strict'; 'use strict';
/* globals ajaxify, define, app, socket, utils */
define('forum/account/groups', ['forum/account/header'], function (header) { define('forum/account/groups', ['forum/account/header'], function (header) {
var AccountTopics = {}; var AccountTopics = {};

@ -1,11 +1,11 @@
'use strict'; 'use strict';
/* globals define, app, config, ajaxify, socket, bootbox, templates */
define('forum/account/header', [ define('forum/account/header', [
'coverPhoto', 'coverPhoto',
'pictureCropper', 'pictureCropper',
'components', 'components',
'translator' 'translator',
], function (coverPhoto, pictureCropper, components, translator) { ], function (coverPhoto, pictureCropper, components, translator) {
var AccountHeader = {}; var AccountHeader = {};
var isAdminOrSelfOrGlobalMod; var isAdminOrSelfOrGlobalMod;
@ -77,7 +77,7 @@ define('forum/account/header', [
socket.emit('user.updateCover', { socket.emit('user.updateCover', {
uid: ajaxify.data.uid, uid: ajaxify.data.uid,
imageData: imageData, imageData: imageData,
position: position position: position,
}, callback); }, callback);
}, },
function () { function () {
@ -89,7 +89,7 @@ define('forum/account/header', [
restrictImageDimension: false, restrictImageDimension: false,
paramName: 'uid', paramName: 'uid',
paramValue: ajaxify.data.theirid, paramValue: ajaxify.data.theirid,
accept: '.png,.jpg,.bmp' accept: '.png,.jpg,.bmp',
}, function (imageUrlOnServer) { }, function (imageUrlOnServer) {
components.get('account/cover').css('background-image', 'url(' + imageUrlOnServer + '?' + config['cache-buster'] + ')'); components.get('account/cover').css('background-image', 'url(' + imageUrlOnServer + '?' + config['cache-buster'] + ')');
}); });
@ -100,7 +100,7 @@ define('forum/account/header', [
function toggleFollow(type) { function toggleFollow(type) {
socket.emit('user.' + type, { socket.emit('user.' + type, {
uid: ajaxify.data.uid uid: ajaxify.data.uid,
}, function (err) { }, function (err) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
@ -123,7 +123,7 @@ define('forum/account/header', [
buttons: { buttons: {
close: { close: {
label: '[[global:close]]', label: '[[global:close]]',
className: 'btn-link' className: 'btn-link',
}, },
submit: { submit: {
label: '[[user:ban_account]]', label: '[[user:ban_account]]',
@ -132,21 +132,21 @@ define('forum/account/header', [
data[cur.name] = cur.value; data[cur.name] = cur.value;
return data; return data;
}, {}); }, {});
var until = parseInt(formData.length, 10) ? (Date.now() + formData.length * 1000 * 60 * 60 * (parseInt(formData.unit, 10) ? 24 : 1)) : 0; var until = parseInt(formData.length, 10) ? (Date.now() + (formData.length * 1000 * 60 * 60 * (parseInt(formData.unit, 10) ? 24 : 1))) : 0;
socket.emit('user.banUsers', { socket.emit('user.banUsers', {
uids: [ajaxify.data.theirid], uids: [ajaxify.data.theirid],
until: until, until: until,
reason: formData.reason || '' reason: formData.reason || '',
}, function (err) { }, function (err) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
} }
ajaxify.refresh(); ajaxify.refresh();
}); });
} },
} },
} },
}); });
}); });
} }
@ -195,7 +195,7 @@ define('forum/account/header', [
} }
socket.emit('user.removeCover', { socket.emit('user.removeCover', {
uid: ajaxify.data.uid uid: ajaxify.data.uid,
}, function (err) { }, function (err) {
if (!err) { if (!err) {
ajaxify.refresh(); ajaxify.refresh();

@ -1,6 +1,5 @@
'use strict'; 'use strict';
/* globals define, socket, ajaxify, app */
define('forum/account/info', ['forum/account/header', 'components'], function (header, components) { define('forum/account/info', ['forum/account/header', 'components'], function (header, components) {
var Info = {}; var Info = {};
@ -14,7 +13,7 @@ define('forum/account/info', ['forum/account/header', 'components'], function (h
function handleModerationNote() { function handleModerationNote() {
$('[component="account/save-moderation-note"]').on('click', function () { $('[component="account/save-moderation-note"]').on('click', function () {
var note = $('[component="account/moderation-note"]').val(); var note = $('[component="account/moderation-note"]').val();
socket.emit('user.setModerationNote', {uid: ajaxify.data.uid, note: note}, function (err) { socket.emit('user.setModerationNote', { uid: ajaxify.data.uid, note: note }, function (err) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
} }
@ -35,8 +34,8 @@ define('forum/account/info', ['forum/account/header', 'components'], function (h
url: config.relative_path + '/api/user/' + ajaxify.data.userslug + '/session/' + uuid, url: config.relative_path + '/api/user/' + ajaxify.data.userslug + '/session/' + uuid,
method: 'delete', method: 'delete',
headers: { headers: {
'x-csrf-token': config.csrf_token 'x-csrf-token': config.csrf_token,
} },
}).done(function () { }).done(function () {
parentEl.remove(); parentEl.remove();
}).fail(function (err) { }).fail(function (err) {

@ -1,10 +1,10 @@
'use strict'; 'use strict';
/* globals define, app, socket, utils, config, ajaxify */
define('forum/account/posts', ['forum/account/header', 'forum/infinitescroll'], function (header, infinitescroll) { define('forum/account/posts', ['forum/account/header', 'forum/infinitescroll'], function (header, infinitescroll) {
var AccountPosts = {}; var AccountPosts = {};
var method, template; var method;
var template;
AccountPosts.init = function () { AccountPosts.init = function () {
header.init(); header.init();
@ -29,7 +29,7 @@ define('forum/account/posts', ['forum/account/header', 'forum/infinitescroll'],
infinitescroll.loadMore(method, { infinitescroll.loadMore(method, {
uid: ajaxify.data.theirid, uid: ajaxify.data.theirid,
after: $('[component="posts"]').attr('data-nextstart') after: $('[component="posts"]').attr('data-nextstart'),
}, function (data, done) { }, function (data, done) {
if (data.posts && data.posts.length) { if (data.posts && data.posts.length) {
onPostsLoaded(data.posts, done); onPostsLoaded(data.posts, done);
@ -41,7 +41,7 @@ define('forum/account/posts', ['forum/account/header', 'forum/infinitescroll'],
} }
function onPostsLoaded(posts, callback) { function onPostsLoaded(posts, callback) {
app.parseAndTranslate(template, 'posts', {posts: posts}, function (html) { app.parseAndTranslate(template, 'posts', { posts: posts }, function (html) {
$('[component="posts"]').append(html); $('[component="posts"]').append(html);
html.find('img:not(.not-responsive)').addClass('img-responsive'); html.find('img:not(.not-responsive)').addClass('img-responsive');
html.find('.timeago').timeago(); html.find('.timeago').timeago();

@ -1,13 +1,11 @@
'use strict'; 'use strict';
/* globals define, ajaxify, app, socket, bootbox */
define('forum/account/profile', [ define('forum/account/profile', [
'forum/account/header', 'forum/account/header',
'forum/infinitescroll', 'forum/infinitescroll',
'translator', 'components',
'components' ], function (header, infinitescroll) {
], function (header, infinitescroll, translator) {
var Account = {}; var Account = {};
var theirid; var theirid;
@ -22,10 +20,10 @@ define('forum/account/profile', [
socket.removeListener('event:user_status_change', onUserStatusChange); socket.removeListener('event:user_status_change', onUserStatusChange);
socket.on('event:user_status_change', onUserStatusChange); socket.on('event:user_status_change', onUserStatusChange);
if (!config.usePagination) { if (!config.usePagination) {
infinitescroll.init(loadMorePosts); infinitescroll.init(loadMorePosts);
} }
}; };
function processPage() { function processPage() {
@ -49,7 +47,7 @@ define('forum/account/profile', [
infinitescroll.loadMore('posts.loadMoreUserPosts', { infinitescroll.loadMore('posts.loadMoreUserPosts', {
after: $('[component="posts"]').attr('data-nextstart'), after: $('[component="posts"]').attr('data-nextstart'),
uid: theirid uid: theirid,
}, function (data, done) { }, function (data, done) {
if (data.posts && data.posts.length) { if (data.posts && data.posts.length) {
onPostsLoaded(data.posts, done); onPostsLoaded(data.posts, done);
@ -70,8 +68,7 @@ define('forum/account/profile', [
return callback(); return callback();
} }
app.parseAndTranslate('account/profile', 'posts', {posts: posts}, function (html) { app.parseAndTranslate('account/profile', 'posts', { posts: posts }, function (html) {
$('[component="posts"]').append(html); $('[component="posts"]').append(html);
html.find('.timeago').timeago(); html.find('.timeago').timeago();

@ -1,6 +1,5 @@
'use strict'; 'use strict';
/*global define, socket, app, ajaxify, config*/
define('forum/account/settings', ['forum/account/header', 'components', 'sounds'], function (header, components, sounds) { define('forum/account/settings', ['forum/account/header', 'components', 'sounds'], function (header, components, sounds) {
var AccountSettings = {}; var AccountSettings = {};
@ -57,13 +56,13 @@ define('forum/account/settings', ['forum/account/header', 'components', 'sounds'
} }
switch (input.attr('type')) { switch (input.attr('type')) {
case 'text': case 'text':
case 'textarea': case 'textarea':
settings[setting] = input.val(); settings[setting] = input.val();
break; break;
case 'checkbox': case 'checkbox':
settings[setting] = input.is(':checked') ? 1 : 0; settings[setting] = input.is(':checked') ? 1 : 0;
break; break;
} }
}); });
@ -71,7 +70,7 @@ define('forum/account/settings', ['forum/account/header', 'components', 'sounds'
} }
function saveSettings(settings) { function saveSettings(settings) {
socket.emit('user.saveSettings', {uid: ajaxify.data.theirid, settings: settings}, function (err, newSettings) { socket.emit('user.saveSettings', { uid: ajaxify.data.theirid, settings: settings }, function (err, newSettings) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
} }
@ -99,7 +98,7 @@ define('forum/account/settings', ['forum/account/header', 'components', 'sounds'
timeout: 5000, timeout: 5000,
clickfn: function () { clickfn: function () {
ajaxify.refresh(); ajaxify.refresh();
} },
}); });
} }
}); });

@ -1,10 +1,9 @@
'use strict'; 'use strict';
/* globals define, app, socket, utils, config, ajaxify */
define('forum/account/topics', ['forum/account/header', 'forum/infinitescroll'], function (header, infinitescroll) { define('forum/account/topics', ['forum/account/header', 'forum/infinitescroll'], function (header, infinitescroll) {
var AccountTopics = {}; var AccountTopics = {};
var template, set; var set;
AccountTopics.init = function () { AccountTopics.init = function () {
header.init(); header.init();
@ -13,7 +12,6 @@ define('forum/account/topics', ['forum/account/header', 'forum/infinitescroll'],
}; };
AccountTopics.handleInfiniteScroll = function (_template, _set) { AccountTopics.handleInfiniteScroll = function (_template, _set) {
template = _template;
set = _set; set = _set;
if (!config.usePagination) { if (!config.usePagination) {
@ -28,7 +26,7 @@ define('forum/account/topics', ['forum/account/header', 'forum/infinitescroll'],
infinitescroll.loadMore('topics.loadMoreFromSet', { infinitescroll.loadMore('topics.loadMoreFromSet', {
set: set, set: set,
after: $('[component="category"]').attr('data-nextstart') after: $('[component="category"]').attr('data-nextstart'),
}, function (data, done) { }, function (data, done) {
if (data.topics && data.topics.length) { if (data.topics && data.topics.length) {
onTopicsLoaded(data.topics, done); onTopicsLoaded(data.topics, done);
@ -41,12 +39,12 @@ define('forum/account/topics', ['forum/account/header', 'forum/infinitescroll'],
} }
function onTopicsLoaded(topics, callback) { function onTopicsLoaded(topics, callback) {
app.parseAndTranslate('account/topics', 'topics', {topics: topics}, function (html) { app.parseAndTranslate('account/topics', 'topics', { topics: topics }, function (html) {
$('[component="category"]').append(html); $('[component="category"]').append(html);
html.find('.timeago').timeago(); html.find('.timeago').timeago();
app.createUserTooltips(); app.createUserTooltips();
utils.makeNumbersHumanReadable(html.find('.human-readable-number')); utils.makeNumbersHumanReadable(html.find('.human-readable-number'));
$(window).trigger('action:topics.loaded', {topics: topics}); $(window).trigger('action:topics.loaded', { topics: topics });
callback(); callback();
}); });
} }

@ -1,6 +1,5 @@
'use strict'; 'use strict';
/* globals define */
define('forum/account/upvoted', ['forum/account/header', 'forum/account/posts'], function (header, posts) { define('forum/account/upvoted', ['forum/account/header', 'forum/account/posts'], function (header, posts) {
var Upvoted = {}; var Upvoted = {};

@ -1,6 +1,6 @@
'use strict'; 'use strict';
/* globals define, app, socket, utils */
define('forum/account/watched', ['forum/account/header', 'forum/account/topics'], function (header, topics) { define('forum/account/watched', ['forum/account/header', 'forum/account/topics'], function (header, topics) {
var AccountWatched = {}; var AccountWatched = {};

@ -1,6 +1,5 @@
'use strict'; 'use strict';
/* globals define, socket, app, templates, ajaxify*/
define('forum/categories', ['components', 'translator'], function (components, translator) { define('forum/categories', ['components', 'translator'], function (components, translator) {
var categories = {}; var categories = {};
@ -18,7 +17,7 @@ define('forum/categories', ['components', 'translator'], function (components, t
socket.on('event:new_post', categories.onNewPost); socket.on('event:new_post', categories.onNewPost);
$('.category-header').tooltip({ $('.category-header').tooltip({
placement: 'bottom' placement: 'bottom',
}); });
}; };
@ -36,11 +35,10 @@ define('forum/categories', ['components', 'translator'], function (components, t
} }
var recentPosts = category.find('[component="category/posts"]'); var recentPosts = category.find('[component="category/posts"]');
var insertBefore = recentPosts.first();
parseAndTranslate([post], function (html) { parseAndTranslate([post], function (html) {
html.hide(); html.hide();
if(recentPosts.length === 0) { if (recentPosts.length === 0) {
html.appendTo(category); html.appendTo(category);
} else { } else {
html.insertBefore(recentPosts.first()); html.insertBefore(recentPosts.first());
@ -55,12 +53,12 @@ define('forum/categories', ['components', 'translator'], function (components, t
recentPosts.last().remove(); recentPosts.last().remove();
} }
$(window).trigger('action:posts.loaded', {posts: [post]}); $(window).trigger('action:posts.loaded', { posts: [post] });
}); });
} }
function parseAndTranslate(posts, callback) { function parseAndTranslate(posts, callback) {
templates.parse('categories', '(categories.)?posts', {categories: {posts: posts}}, function (html) { templates.parse('categories', '(categories.)?posts', { categories: { posts: posts } }, function (html) {
translator.translate(html, function (translatedHTML) { translator.translate(html, function (translatedHTML) {
translatedHTML = $(translatedHTML); translatedHTML = $(translatedHTML);
translatedHTML.find('.post-content img:not(.not-responsive)').addClass('img-responsive'); translatedHTML.find('.post-content img:not(.not-responsive)').addClass('img-responsive');

@ -1,5 +1,5 @@
"use strict"; 'use strict';
/* global define, config, templates, app, utils, ajaxify, socket */
define('forum/category', [ define('forum/category', [
'forum/infinitescroll', 'forum/infinitescroll',
@ -10,7 +10,7 @@ define('forum/category', [
'components', 'components',
'translator', 'translator',
'topicSelect', 'topicSelect',
'forum/pagination' 'forum/pagination',
], function (infinitescroll, share, navigator, categoryTools, sort, components, translator, topicSelect, pagination) { ], function (infinitescroll, share, navigator, categoryTools, sort, components, translator, topicSelect, pagination) {
var Category = {}; var Category = {};
@ -62,8 +62,8 @@ define('forum/category', [
handleIgnoreWatch(cid); handleIgnoreWatch(cid);
$(window).trigger('action:topics.loaded', {topics: ajaxify.data.topics}); $(window).trigger('action:topics.loaded', { topics: ajaxify.data.topics });
$(window).trigger('action:category.loaded', {cid: ajaxify.data.cid}); $(window).trigger('action:category.loaded', { cid: ajaxify.data.cid });
}; };
function handleScrollToTopicIndex() { function handleScrollToTopicIndex() {
@ -112,13 +112,12 @@ define('forum/category', [
}); });
}; };
Category.navigatorCallback = function (topIndex, bottomIndex, elementCount) { Category.navigatorCallback = function (topIndex, bottomIndex) {
return bottomIndex; return bottomIndex;
}; };
$(window).on('action:ajaxify.contentLoaded', function (ev, data) { $(window).on('action:ajaxify.contentLoaded', function () {
if (ajaxify.data.template.category && ajaxify.data.cid) { if (ajaxify.data.template.category && ajaxify.data.cid) {
var bookmarkIndex = localStorage.getItem('category:' + ajaxify.data.cid + ':bookmark'); var bookmarkIndex = localStorage.getItem('category:' + ajaxify.data.cid + ':bookmark');
var clickedIndex = localStorage.getItem('category:' + ajaxify.data.cid + ':bookmark:clicked'); var clickedIndex = localStorage.getItem('category:' + ajaxify.data.cid + ':bookmark:clicked');
@ -178,7 +177,7 @@ define('forum/category', [
if (scrollTo.length) { if (scrollTo.length) {
$('html, body').animate({ $('html, body').animate({
scrollTop: (scrollTo.offset().top - offset) + 'px' scrollTop: (scrollTo.offset().top - offset) + 'px',
}, duration !== undefined ? duration : 400, function () { }, duration !== undefined ? duration : 400, function () {
Category.highlightTopic(clickedIndex); Category.highlightTopic(clickedIndex);
navigator.update(); navigator.update();
@ -205,16 +204,16 @@ define('forum/category', [
var editable = !!$('.thread-tools').length; var editable = !!$('.thread-tools').length;
templates.parse('category', 'topics', { templates.parse('category', 'topics', {
privileges: {editable: editable}, privileges: { editable: editable },
showSelect: editable, showSelect: editable,
topics: [topic], topics: [topic],
template: {category: true} template: { category: true },
}, function (html) { }, function (html) {
translator.translate(html, function (translatedHTML) { translator.translate(html, function (translatedHTML) {
var topic = $(translatedHTML), var topic = $(translatedHTML);
container = $('[component="category"]'), var container = $('[component="category"]');
topics = $('[component="category/topic"]'), var topics = $('[component="category/topic"]');
numTopics = topics.length; var numTopics = topics.length;
$('[component="category"]').removeClass('hidden'); $('[component="category"]').removeClass('hidden');
$('.category-sidebar').removeClass('hidden'); $('.category-sidebar').removeClass('hidden');
@ -226,16 +225,15 @@ define('forum/category', [
} }
if (numTopics > 0) { if (numTopics > 0) {
for (var x = 0; x < numTopics; x++) { for (var x = 0; x < numTopics; x += 1) {
var pinned = $(topics[x]).hasClass('pinned'); var pinned = $(topics[x]).hasClass('pinned');
if (pinned) { if (!pinned) {
if(x === numTopics - 1) { topic.insertBefore(topics[x]);
topic.insertAfter(topics[x]); break;
} }
continue; if (x === numTopics - 1) {
topic.insertAfter(topics[x]);
} }
topic.insertBefore(topics[x]);
break;
} }
} else { } else {
container.append(topic); container.append(topic);
@ -254,7 +252,7 @@ define('forum/category', [
function updateTopicCount() { function updateTopicCount() {
socket.emit('categories.getTopicCount', ajaxify.data.cid, function (err, topicCount) { socket.emit('categories.getTopicCount', ajaxify.data.cid, function (err, topicCount) {
if(err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
} }
navigator.setCount(topicCount); navigator.setCount(topicCount);
@ -287,7 +285,7 @@ define('forum/category', [
direction: direction, direction: direction,
author: params.author, author: params.author,
tag: params.tag, tag: params.tag,
categoryTopicSort: config.categoryTopicSort categoryTopicSort: config.categoryTopicSort,
}, function (data, done) { }, function (data, done) {
if (data.topics && data.topics.length) { if (data.topics && data.topics.length) {
Category.onTopicsLoaded(data, direction, done); Category.onTopicsLoaded(data, direction, done);
@ -319,7 +317,8 @@ define('forum/category', [
data.showSelect = data.privileges.editable; data.showSelect = data.privileges.editable;
var after, before; var after;
var before;
var topics = $('[component="category/topic"]'); var topics = $('[component="category/topic"]');
if (direction > 0 && topics.length) { if (direction > 0 && topics.length) {
@ -337,8 +336,8 @@ define('forum/category', [
if (after) { if (after) {
html.insertAfter(after); html.insertAfter(after);
} else if (before) { } else if (before) {
var height = $(document).height(), var height = $(document).height();
scrollTop = $(window).scrollTop(); var scrollTop = $(window).scrollTop();
html.insertBefore(before); html.insertBefore(before);
@ -355,7 +354,7 @@ define('forum/category', [
app.createUserTooltips(); app.createUserTooltips();
utils.makeNumbersHumanReadable(html.find('.human-readable-number')); utils.makeNumbersHumanReadable(html.find('.human-readable-number'));
$(window).trigger('action:topics.loaded', {topics: data.topics}); $(window).trigger('action:topics.loaded', { topics: data.topics });
callback(); callback();
}); });

@ -1,16 +1,13 @@
'use strict'; 'use strict';
/* globals define, app, socket, bootbox, ajaxify */
define('forum/category/tools', [ define('forum/category/tools', [
'forum/topic/move', 'forum/topic/move',
'topicSelect', 'topicSelect',
'components', 'components',
'translator' 'translator',
], function (move, topicSelect, components, translator) { ], function (move, topicSelect, components, translator) {
var CategoryTools = {}; var CategoryTools = {};
CategoryTools.init = function (cid) { CategoryTools.init = function (cid) {
@ -38,7 +35,7 @@ define('forum/category/tools', [
components.get('topic/lock').on('click', function () { components.get('topic/lock').on('click', function () {
var tids = topicSelect.getSelectedTids(); var tids = topicSelect.getSelectedTids();
if (tids.length) { if (tids.length) {
socket.emit('topics.lock', {tids: tids, cid: CategoryTools.cid}, onCommandComplete); socket.emit('topics.lock', { tids: tids, cid: CategoryTools.cid }, onCommandComplete);
} }
return false; return false;
}); });
@ -46,7 +43,7 @@ define('forum/category/tools', [
components.get('topic/unlock').on('click', function () { components.get('topic/unlock').on('click', function () {
var tids = topicSelect.getSelectedTids(); var tids = topicSelect.getSelectedTids();
if (tids.length) { if (tids.length) {
socket.emit('topics.unlock', {tids: tids, cid: CategoryTools.cid}, onCommandComplete); socket.emit('topics.unlock', { tids: tids, cid: CategoryTools.cid }, onCommandComplete);
} }
return false; return false;
}); });
@ -54,7 +51,7 @@ define('forum/category/tools', [
components.get('topic/pin').on('click', function () { components.get('topic/pin').on('click', function () {
var tids = topicSelect.getSelectedTids(); var tids = topicSelect.getSelectedTids();
if (tids.length) { if (tids.length) {
socket.emit('topics.pin', {tids: tids, cid: CategoryTools.cid}, onCommandComplete); socket.emit('topics.pin', { tids: tids, cid: CategoryTools.cid }, onCommandComplete);
} }
return false; return false;
}); });
@ -62,7 +59,7 @@ define('forum/category/tools', [
components.get('topic/unpin').on('click', function () { components.get('topic/unpin').on('click', function () {
var tids = topicSelect.getSelectedTids(); var tids = topicSelect.getSelectedTids();
if (tids.length) { if (tids.length) {
socket.emit('topics.unpin', {tids: tids, cid: CategoryTools.cid}, onCommandComplete); socket.emit('topics.unpin', { tids: tids, cid: CategoryTools.cid }, onCommandComplete);
} }
return false; return false;
}); });
@ -126,7 +123,7 @@ define('forum/category/tools', [
return; return;
} }
socket.emit('topics.' + command, {tids: tids, cid: CategoryTools.cid}, onDeletePurgeComplete); socket.emit('topics.' + command, { tids: tids, cid: CategoryTools.cid }, onDeletePurgeComplete);
}); });
}); });
} }
@ -163,7 +160,6 @@ define('forum/category/tools', [
} }
function updateDropdownOptions() { function updateDropdownOptions() {
var tids = topicSelect.getSelectedTids(); var tids = topicSelect.getSelectedTids();
var isAnyDeleted = isAny(isTopicDeleted, tids); var isAnyDeleted = isAny(isTopicDeleted, tids);
var areAllDeleted = areAll(isTopicDeleted, tids); var areAllDeleted = areAll(isTopicDeleted, tids);
@ -182,8 +178,8 @@ define('forum/category/tools', [
} }
function isAny(method, tids) { function isAny(method, tids) {
for(var i = 0; i < tids.length; ++i) { for (var i = 0; i < tids.length; i += 1) {
if(method(tids[i])) { if (method(tids[i])) {
return true; return true;
} }
} }
@ -191,8 +187,8 @@ define('forum/category/tools', [
} }
function areAll(method, tids) { function areAll(method, tids) {
for(var i = 0; i < tids.length; ++i) { for (var i = 0; i < tids.length; i += 1) {
if(!method(tids[i])) { if (!method(tids[i])) {
return false; return false;
} }
} }
@ -254,7 +250,7 @@ define('forum/category/tools', [
var pinnedTopics = $('[component="category/topic"].pinned'); var pinnedTopics = $('[component="category/topic"].pinned');
pinnedTopics.each(function (index, element) { pinnedTopics.each(function (index, element) {
data.push({tid: $(element).attr('data-tid'), order: pinnedTopics.length - index - 1}); data.push({ tid: $(element).attr('data-tid'), order: pinnedTopics.length - index - 1 });
}); });
socket.emit('topics.orderPinnedTopics', data, function (err) { socket.emit('topics.orderPinnedTopics', data, function (err) {
@ -262,7 +258,7 @@ define('forum/category/tools', [
return app.alertError(err.message); return app.alertError(err.message);
} }
}); });
} },
}); });
}); });
} }

@ -1,6 +1,5 @@
'use strict'; 'use strict';
/* globals define, app, ajaxify, utils, socket, templates */
define('forum/chats', [ define('forum/chats', [
'components', 'components',
@ -8,10 +7,10 @@ define('forum/chats', [
'mousetrap', 'mousetrap',
'forum/chats/recent', 'forum/chats/recent',
'forum/chats/search', 'forum/chats/search',
'forum/chats/messages' 'forum/chats/messages',
], function (components, translator, mousetrap, recentChats, search, messages) { ], function (components, translator, mousetrap, recentChats, search, messages) {
var Chats = { var Chats = {
initialised: false initialised: false,
}; };
var newMessage = false; var newMessage = false;
@ -61,7 +60,6 @@ define('forum/chats', [
Chats.addSendHandlers(ajaxify.data.roomId, $('.chat-input'), $('.expanded-chat button[data-action="send"]')); Chats.addSendHandlers(ajaxify.data.roomId, $('.chat-input'), $('.expanded-chat button[data-action="send"]'));
$('[data-action="pop-out"]').on('click', function () { $('[data-action="pop-out"]').on('click', function () {
var text = components.get('chat/input').val(); var text = components.get('chat/input').val();
var roomId = ajaxify.data.roomId; var roomId = ajaxify.data.roomId;
@ -99,8 +97,8 @@ define('forum/chats', [
return; return;
} }
loading = true; loading = true;
var start = parseInt($('.chat-content').children('[data-index]').first().attr('data-index'), 10) + 1; var start = parseInt($('.chat-content').children('[data-index]').first().attr('data-index'), 10) + 1;
socket.emit('modules.chats.getMessages', {roomId: roomId, uid: uid, start: start}, function (err, data) { socket.emit('modules.chats.getMessages', { roomId: roomId, uid: uid, start: start }, function (err, data) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
} }
@ -134,16 +132,16 @@ define('forum/chats', [
Chats.addHotkeys = function () { Chats.addHotkeys = function () {
mousetrap.bind('ctrl+up', function () { mousetrap.bind('ctrl+up', function () {
var activeContact = $('.chats-list .bg-primary'), var activeContact = $('.chats-list .bg-primary');
prev = activeContact.prev(); var prev = activeContact.prev();
if (prev.length) { if (prev.length) {
Chats.switchChat(prev.attr('data-roomid')); Chats.switchChat(prev.attr('data-roomid'));
} }
}); });
mousetrap.bind('ctrl+down', function () { mousetrap.bind('ctrl+down', function () {
var activeContact = $('.chats-list .bg-primary'), var activeContact = $('.chats-list .bg-primary');
next = activeContact.next(); var next = activeContact.next();
if (next.length) { if (next.length) {
Chats.switchChat(next.attr('data-roomid')); Chats.switchChat(next.attr('data-roomid'));
@ -172,7 +170,7 @@ define('forum/chats', [
if (oldName === newName) { if (oldName === newName) {
return; return;
} }
socket.emit('modules.chats.renameRoom', {roomId: roomId, newName: newName}, function (err) { socket.emit('modules.chats.renameRoom', { roomId: roomId, newName: newName }, function (err) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
} }
@ -207,8 +205,8 @@ define('forum/chats', [
this.$el.css(this._applyPlacement(position)); this.$el.css(this._applyPlacement(position));
this.$el.css('position', 'absolute'); this.$el.css('position', 'absolute');
return this; return this;
} },
} },
}; };
$(window).trigger('chat:autocomplete:init', data); $(window).trigger('chat:autocomplete:init', data);
@ -220,7 +218,7 @@ define('forum/chats', [
Chats.createTagsInput = function (tagEl, data) { Chats.createTagsInput = function (tagEl, data) {
tagEl.tagsinput({ tagEl.tagsinput({
confirmKeys: [13, 44], confirmKeys: [13, 44],
trimValue: true trimValue: true,
}); });
if (data.users && data.users.length) { if (data.users && data.users.length) {
@ -237,10 +235,10 @@ define('forum/chats', [
if (event.item === app.user.username) { if (event.item === app.user.username) {
return; return;
} }
socket.emit('modules.chats.addUserToRoom', {roomId: data.roomId, username: event.item}, function (err) { socket.emit('modules.chats.addUserToRoom', { roomId: data.roomId, username: event.item }, function (err) {
if (err) { if (err) {
app.alertError(err.message); app.alertError(err.message);
tagEl.tagsinput('remove', event.item, {nouser: true}); tagEl.tagsinput('remove', event.item, { nouser: true });
} }
}); });
}); });
@ -264,7 +262,7 @@ define('forum/chats', [
if (event.options && event.options.nouser) { if (event.options && event.options.nouser) {
return; return;
} }
socket.emit('modules.chats.removeUserFromRoom', {roomId: data.roomId, username: event.item}, function (err) { socket.emit('modules.chats.removeUserFromRoom', { roomId: data.roomId, username: event.item }, function (err) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
} }
@ -313,22 +311,20 @@ define('forum/chats', [
data.message.self = data.self; data.message.self = data.self;
messages.appendChatMessage($('.expanded-chat .chat-content'), data.message); messages.appendChatMessage($('.expanded-chat .chat-content'), data.message);
} else { } else if (ajaxify.currentPage.startsWith('chats')) {
if (ajaxify.currentPage.startsWith("chats")) { var roomEl = $('[data-roomid=' + data.roomId + ']');
var roomEl = $('[data-roomid=' + data.roomId + ']');
if (roomEl.length > 0) {
if (roomEl.length > 0) { roomEl.addClass('unread');
roomEl.addClass("unread"); } else {
} else { var recentEl = components.get('chat/recent');
var recentEl = components.get('chat/recent'); templates.parse('partials/chats/recent_room', {
templates.parse('partials/chats/recent_room', { rooms: { roomId: data.roomId, lastUser: data.message.fromUser, usernames: data.message.fromUser.username, unread: true },
rooms: { "roomId": data.roomId, "lastUser": data.message.fromUser, "usernames": data.message.fromUser.username, "unread": true } }, function (html) {
}, function (html) { translator.translate(html, function (translated) {
translator.translate(html, function (translated) { recentEl.prepend(translated);
recentEl.prepend(translated);
});
}); });
} });
} }
} }
}); });
@ -356,7 +352,7 @@ define('forum/chats', [
messagesList.height($(window).height() - (fromTop + inputHeight + (margin * 4))); messagesList.height($(window).height() - (fromTop + inputHeight + (margin * 4)));
components.get('chat/recent').height($('.expanded-chat').height() - (searchHeight + searchListHeight)); components.get('chat/recent').height($('.expanded-chat').height() - (searchHeight + searchListHeight));
$('[component="chat/search/list"]').css('max-height', components.get('chat/recent').height() / 2 + 'px'); $('[component="chat/search/list"]').css('max-height', (components.get('chat/recent').height() / 2) + 'px');
} }
Chats.setActive(); Chats.setActive();

@ -1,9 +1,7 @@
'use strict'; 'use strict';
/* globals define, socket, app, ajaxify, templates, bootbox */
define('forum/chats/messages', ['components', 'sounds', 'translator'], function (components, sounds, translator) { define('forum/chats/messages', ['components', 'sounds', 'translator'], function (components, sounds, translator) {
var messages = {}; var messages = {};
messages.sendMessage = function (roomId, inputEl) { messages.sendMessage = function (roomId, inputEl) {
@ -24,13 +22,13 @@ define('forum/chats/messages', ['components', 'sounds', 'translator'], function
$(window).trigger('action:chat.sent', { $(window).trigger('action:chat.sent', {
roomId: roomId, roomId: roomId,
message: msg, message: msg,
mid: mid mid: mid,
}); });
if (!mid) { if (!mid) {
socket.emit('modules.chats.send', { socket.emit('modules.chats.send', {
roomId: roomId, roomId: roomId,
message: msg message: msg,
}, function (err) { }, function (err) {
if (err) { if (err) {
inputEl.val(msg); inputEl.val(msg);
@ -46,7 +44,7 @@ define('forum/chats/messages', ['components', 'sounds', 'translator'], function
socket.emit('modules.chats.edit', { socket.emit('modules.chats.edit', {
roomId: roomId, roomId: roomId,
mid: mid, mid: mid,
message: msg message: msg,
}, function (err) { }, function (err) {
if (err) { if (err) {
inputEl.val(msg); inputEl.val(msg);
@ -58,7 +56,6 @@ define('forum/chats/messages', ['components', 'sounds', 'translator'], function
}; };
messages.appendChatMessage = function (chatContentEl, data) { messages.appendChatMessage = function (chatContentEl, data) {
var lastSpeaker = parseInt(chatContentEl.find('.chat-message').last().attr('data-uid'), 10); var lastSpeaker = parseInt(chatContentEl.find('.chat-message').last().attr('data-uid'), 10);
if (!Array.isArray(data)) { if (!Array.isArray(data)) {
data.newSet = lastSpeaker !== data.fromuid; data.newSet = lastSpeaker !== data.fromuid;
@ -81,7 +78,7 @@ define('forum/chats/messages', ['components', 'sounds', 'translator'], function
messages.parseMessage = function (data, callback) { messages.parseMessage = function (data, callback) {
templates.parse('partials/chats/message' + (Array.isArray(data) ? 's' : ''), { templates.parse('partials/chats/message' + (Array.isArray(data) ? 's' : ''), {
messages: data messages: data,
}, function (html) { }, function (html) {
translator.translate(html, callback); translator.translate(html, callback);
}); });
@ -114,10 +111,10 @@ define('forum/chats/messages', ['components', 'sounds', 'translator'], function
messages.onChatMessageEdit = function () { messages.onChatMessageEdit = function () {
socket.on('event:chats.edit', function (data) { socket.on('event:chats.edit', function (data) {
data.messages.forEach(function (message) { data.messages.forEach(function (message) {
var self = parseInt(message.fromuid, 10) === parseInt(app.user.uid); var self = parseInt(message.fromuid, 10) === parseInt(app.user.uid, 10);
message.self = self ? 1 : 0; message.self = self ? 1 : 0;
messages.parseMessage(message, function (html) { messages.parseMessage(message, function (html) {
var body = components.get('chat/message', message.messageId); var body = components.get('chat/message', message.messageId);
if (body.length) { if (body.length) {
body.replaceWith(html); body.replaceWith(html);
components.get('chat/message', message.messageId).find('.timeago').timeago(); components.get('chat/message', message.messageId).find('.timeago').timeago();
@ -136,7 +133,7 @@ define('forum/chats/messages', ['components', 'sounds', 'translator'], function
socket.emit('modules.chats.delete', { socket.emit('modules.chats.delete', {
messageId: messageId, messageId: messageId,
roomId: roomId roomId: roomId,
}, function (err) { }, function (err) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);

@ -1,9 +1,7 @@
'use strict'; 'use strict';
/* globals define, socket, app */
define('forum/chats/recent', function () { define('forum/chats/recent', function () {
var recent = {}; var recent = {};
recent.init = function () { recent.init = function () {
@ -24,7 +22,7 @@ define('forum/chats/recent', function () {
recentChats.attr('loading', 1); recentChats.attr('loading', 1);
socket.emit('modules.chats.getRecentChats', { socket.emit('modules.chats.getRecentChats', {
uid: ajaxify.data.uid, uid: ajaxify.data.uid,
after: recentChats.attr('data-nextstart') after: recentChats.attr('data-nextstart'),
}, function (err, data) { }, function (err, data) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
@ -55,4 +53,4 @@ define('forum/chats/recent', function () {
return recent; return recent;
}); });

@ -1,9 +1,7 @@
'use strict'; 'use strict';
/* globals define, socket, app */
define('forum/chats/search', ['components'], function (components) { define('forum/chats/search', ['components'], function (components) {
var search = {}; var search = {};
search.init = function () { search.init = function () {
@ -29,7 +27,7 @@ define('forum/chats/search', ['components'], function (components) {
socket.emit('user.search', { socket.emit('user.search', {
query: username, query: username,
searchBy: 'username' searchBy: 'username',
}, function (err, data) { }, function (err, data) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
@ -41,11 +39,11 @@ define('forum/chats/search', ['components'], function (components) {
function displayResults(chatsListEl, data) { function displayResults(chatsListEl, data) {
chatsListEl.empty(); chatsListEl.empty();
data.users = data.users.filter(function (user) { data.users = data.users.filter(function (user) {
return parseInt(user.uid, 10) !== parseInt(app.user.uid, 10); return parseInt(user.uid, 10) !== parseInt(app.user.uid, 10);
}); });
if (!data.users.length) { if (!data.users.length) {
return chatsListEl.translateHtml('<li><div><span>[[users:no-users-found]]</span></div></li>'); return chatsListEl.translateHtml('<li><div><span>[[users:no-users-found]]</span></div></li>');
} }

@ -1,6 +1,5 @@
'use strict'; 'use strict';
/* globals define */
define('forum/compose', [], function () { define('forum/compose', [], function () {
var Compose = {}; var Compose = {};
@ -10,7 +9,7 @@ define('forum/compose', [], function () {
if (container.length) { if (container.length) {
$(window).trigger('action:composer.enhance', { $(window).trigger('action:composer.enhance', {
container: container container: container,
}); });
} }
}; };

@ -1,8 +1,7 @@
"use strict"; 'use strict';
/*globals define, app, socket*/
define('forum/footer', ['notifications', 'chat', 'components', 'translator'], function (Notifications, Chat, components, translator) {
define('forum/footer', ['notifications', 'chat', 'components', 'translator'], function (Notifications, Chat, components, translator) {
Notifications.prepareDOM(); Notifications.prepareDOM();
Chat.prepareDOM(); Chat.prepareDOM();
translator.prepareDOM(); translator.prepareDOM();

@ -1,5 +1,5 @@
"use strict"; 'use strict';
/* globals define, socket, ajaxify, app, bootbox, utils, config */
define('forum/groups/details', [ define('forum/groups/details', [
'forum/groups/memberlist', 'forum/groups/memberlist',
@ -8,9 +8,8 @@ define('forum/groups/details', [
'coverPhoto', 'coverPhoto',
'pictureCropper', 'pictureCropper',
'translator', 'translator',
'vendor/colorpicker/colorpicker' 'vendor/colorpicker/colorpicker',
], function (memberList, iconSelect, components, coverPhoto, pictureCropper, translator) { ], function (memberList, iconSelect, components, coverPhoto, pictureCropper, translator) {
var Details = {}; var Details = {};
var groupName; var groupName;
@ -27,7 +26,7 @@ define('forum/groups/details', [
socket.emit('groups.cover.update', { socket.emit('groups.cover.update', {
groupName: groupName, groupName: groupName,
imageData: imageData, imageData: imageData,
position: position position: position,
}, callback); }, callback);
}, },
function () { function () {
@ -38,7 +37,7 @@ define('forum/groups/details', [
allowSkippingCrop: true, allowSkippingCrop: true,
restrictImageDimension: false, restrictImageDimension: false,
paramName: 'groupName', paramName: 'groupName',
paramValue: groupName paramValue: groupName,
}, function (imageUrlOnServer) { }, function (imageUrlOnServer) {
components.get('groups/cover').css('background-image', 'url(' + imageUrlOnServer + ')'); components.get('groups/cover').css('background-image', 'url(' + imageUrlOnServer + ')');
}); });
@ -54,18 +53,18 @@ define('forum/groups/details', [
components.get('groups/activity').find('.content img:not(.not-responsive)').addClass('img-responsive'); components.get('groups/activity').find('.content img:not(.not-responsive)').addClass('img-responsive');
detailsPage.on('click', '[data-action]', function () { detailsPage.on('click', '[data-action]', function () {
var btnEl = $(this), var btnEl = $(this);
userRow = btnEl.parents('[data-uid]'), var userRow = btnEl.parents('[data-uid]');
ownerFlagEl = userRow.find('.member-name > i'), var ownerFlagEl = userRow.find('.member-name > i');
isOwner = !ownerFlagEl.hasClass('invisible') ? true : false, var isOwner = !ownerFlagEl.hasClass('invisible');
uid = userRow.attr('data-uid'), var uid = userRow.attr('data-uid');
action = btnEl.attr('data-action'); var action = btnEl.attr('data-action');
switch (action) { switch (action) {
case 'toggleOwnership': case 'toggleOwnership':
socket.emit('groups.' + (isOwner ? 'rescind' : 'grant'), { socket.emit('groups.' + (isOwner ? 'rescind' : 'grant'), {
toUid: uid, toUid: uid,
groupName: groupName groupName: groupName,
}, function (err) { }, function (err) {
if (!err) { if (!err) {
ownerFlagEl.toggleClass('invisible'); ownerFlagEl.toggleClass('invisible');
@ -78,7 +77,7 @@ define('forum/groups/details', [
case 'kick': case 'kick':
socket.emit('groups.kick', { socket.emit('groups.kick', {
uid: uid, uid: uid,
groupName: groupName groupName: groupName,
}, function (err) { }, function (err) {
if (!err) { if (!err) {
userRow.slideUp().remove(); userRow.slideUp().remove();
@ -96,7 +95,7 @@ define('forum/groups/details', [
Details.deleteGroup(); Details.deleteGroup();
break; break;
case 'join': // intentional fall-throughs! case 'join': // intentional fall-throughs!
case 'leave': case 'leave':
case 'accept': case 'accept':
case 'reject': case 'reject':
@ -108,7 +107,7 @@ define('forum/groups/details', [
case 'rejectAll': case 'rejectAll':
socket.emit('groups.' + action, { socket.emit('groups.' + action, {
toUid: uid, toUid: uid,
groupName: groupName groupName: groupName,
}, function (err) { }, function (err) {
if (!err) { if (!err) {
ajaxify.refresh(); ajaxify.refresh();
@ -122,15 +121,15 @@ define('forum/groups/details', [
}; };
Details.prepareSettings = function () { Details.prepareSettings = function () {
var settingsFormEl = components.get('groups/settings'), var settingsFormEl = components.get('groups/settings');
colorBtn = settingsFormEl.find('[data-action="color-select"]'), var colorBtn = settingsFormEl.find('[data-action="color-select"]');
colorValueEl = settingsFormEl.find('[name="labelColor"]'), var colorValueEl = settingsFormEl.find('[name="labelColor"]');
iconBtn = settingsFormEl.find('[data-action="icon-select"]'), var iconBtn = settingsFormEl.find('[data-action="icon-select"]');
previewEl = settingsFormEl.find('.label'), var previewEl = settingsFormEl.find('.label');
previewIcon = previewEl.find('i'), var previewIcon = previewEl.find('i');
userTitleEl = settingsFormEl.find('[name="userTitle"]'), var userTitleEl = settingsFormEl.find('[name="userTitle"]');
userTitleEnabledEl = settingsFormEl.find('[name="userTitleEnabled"]'), var userTitleEnabledEl = settingsFormEl.find('[name="userTitleEnabled"]');
iconValueEl = settingsFormEl.find('[name="icon"]'); var iconValueEl = settingsFormEl.find('[name="icon"]');
// Add color picker to settings form // Add color picker to settings form
colorBtn.ColorPicker({ colorBtn.ColorPicker({
@ -141,7 +140,7 @@ define('forum/groups/details', [
}, },
onShow: function (colpkr) { onShow: function (colpkr) {
$(colpkr).css('z-index', 1051); $(colpkr).css('z-index', 1051);
} },
}); });
// Add icon selection interface // Add icon selection interface
@ -173,8 +172,8 @@ define('forum/groups/details', [
}; };
Details.update = function () { Details.update = function () {
var settingsFormEl = components.get('groups/settings'), var settingsFormEl = components.get('groups/settings');
checkboxes = settingsFormEl.find('input[type="checkbox"][name]'); var checkboxes = settingsFormEl.find('input[type="checkbox"][name]');
if (settingsFormEl.length) { if (settingsFormEl.length) {
require(['vendor/jquery/serializeObject/jquery.ba-serializeobject.min'], function () { require(['vendor/jquery/serializeObject/jquery.ba-serializeobject.min'], function () {
@ -190,7 +189,7 @@ define('forum/groups/details', [
socket.emit('groups.update', { socket.emit('groups.update', {
groupName: groupName, groupName: groupName,
values: settings values: settings,
}, function (err) { }, function (err) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
@ -216,7 +215,7 @@ define('forum/groups/details', [
bootbox.prompt('Please enter the name of this group in order to delete it:', function (response) { bootbox.prompt('Please enter the name of this group in order to delete it:', function (response) {
if (response === groupName) { if (response === groupName) {
socket.emit('groups.delete', { socket.emit('groups.delete', {
groupName: groupName groupName: groupName,
}, function (err) { }, function (err) {
if (!err) { if (!err) {
app.alertSuccess('[[groups:event.deleted, ' + utils.escapeHTML(groupName) + ']]'); app.alertSuccess('[[groups:event.deleted, ' + utils.escapeHTML(groupName) + ']]');
@ -241,7 +240,7 @@ define('forum/groups/details', [
autocomplete.user(searchInput, function (event, selected) { autocomplete.user(searchInput, function (event, selected) {
socket.emit('groups.issueInvite', { socket.emit('groups.issueInvite', {
toUid: selected.item.user.uid, toUid: selected.item.user.uid,
groupName: ajaxify.data.group.name groupName: ajaxify.data.group.name,
}, function (err) { }, function (err) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
@ -258,7 +257,7 @@ define('forum/groups/details', [
} }
socket.emit('groups.issueMassInvite', { socket.emit('groups.issueMassInvite', {
usernames: usernames, usernames: usernames,
groupName: ajaxify.data.group.name groupName: ajaxify.data.group.name,
}, function (err) { }, function (err) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
@ -277,7 +276,7 @@ define('forum/groups/details', [
} }
socket.emit('groups.cover.remove', { socket.emit('groups.cover.remove', {
groupName: ajaxify.data.group.name groupName: ajaxify.data.group.name,
}, function (err) { }, function (err) {
if (!err) { if (!err) {
ajaxify.refresh(); ajaxify.refresh();

@ -1,12 +1,10 @@
"use strict"; 'use strict';
/* globals app, define, ajaxify, socket, bootbox, utils, templates */
define('forum/groups/list', ['forum/infinitescroll'], function (infinitescroll) { define('forum/groups/list', ['forum/infinitescroll'], function (infinitescroll) {
var Groups = {}; var Groups = {};
Groups.init = function () { Groups.init = function () {
var groupsEl = $('#groups-list');
infinitescroll.init(Groups.loadMoreGroups); infinitescroll.init(Groups.loadMoreGroups);
// Group creation // Group creation
@ -14,7 +12,7 @@ define('forum/groups/list', ['forum/infinitescroll'], function (infinitescroll)
bootbox.prompt('[[groups:new-group.group_name]]', function (name) { bootbox.prompt('[[groups:new-group.group_name]]', function (name) {
if (name && name.length) { if (name && name.length) {
socket.emit('groups.create', { socket.emit('groups.create', {
name: name name: name,
}, function (err) { }, function (err) {
if (!err) { if (!err) {
ajaxify.go('groups/' + utils.slugify(name)); ajaxify.go('groups/' + utils.slugify(name));
@ -43,11 +41,11 @@ define('forum/groups/list', ['forum/infinitescroll'], function (infinitescroll)
infinitescroll.loadMore('groups.loadMore', { infinitescroll.loadMore('groups.loadMore', {
sort: $('#search-sort').val(), sort: $('#search-sort').val(),
after: $('[component="groups/container"]').attr('data-nextstart') after: $('[component="groups/container"]').attr('data-nextstart'),
}, function (data, done) { }, function (data, done) {
if (data && data.groups.length) { if (data && data.groups.length) {
templates.parse('partials/groups/list', { templates.parse('partials/groups/list', {
groups: data.groups groups: data.groups,
}, function (html) { }, function (html) {
$('#groups-list').append(html); $('#groups-list').append(html);
done(); done();
@ -63,16 +61,16 @@ define('forum/groups/list', ['forum/infinitescroll'], function (infinitescroll)
}; };
Groups.search = function () { Groups.search = function () {
var groupsEl = $('#groups-list'), var groupsEl = $('#groups-list');
queryEl = $('#search-text'), var queryEl = $('#search-text');
sortEl = $('#search-sort'); var sortEl = $('#search-sort');
socket.emit('groups.search', { socket.emit('groups.search', {
query: queryEl.val(), query: queryEl.val(),
options: { options: {
sort: sortEl.val(), sort: sortEl.val(),
filterHidden: true filterHidden: true,
} },
}, function (err, groups) { }, function (err, groups) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
@ -81,7 +79,7 @@ define('forum/groups/list', ['forum/infinitescroll'], function (infinitescroll)
return group.name !== 'registered-users' && group.name !== 'guests'; return group.name !== 'registered-users' && group.name !== 'guests';
}); });
templates.parse('partials/groups/list', { templates.parse('partials/groups/list', {
groups: groups groups: groups,
}, function (html) { }, function (html) {
groupsEl.empty().append(html); groupsEl.empty().append(html);
}); });

@ -1,8 +1,7 @@
"use strict"; 'use strict';
/* globals define, socket, ajaxify, app */
define('forum/groups/memberlist', ['components', 'forum/infinitescroll'], function (components, infinitescroll) {
define('forum/groups/memberlist', ['components', 'forum/infinitescroll'], function () {
var MemberList = {}; var MemberList = {};
var searchInterval; var searchInterval;
var groupName; var groupName;
@ -23,7 +22,7 @@ define('forum/groups/memberlist', ['components', 'forum/infinitescroll'], functi
} }
searchInterval = setTimeout(function () { searchInterval = setTimeout(function () {
socket.emit('groups.searchMembers', {groupName: groupName, query: query}, function (err, results) { socket.emit('groups.searchMembers', { groupName: groupName, query: query }, function (err, results) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
} }
@ -56,7 +55,7 @@ define('forum/groups/memberlist', ['components', 'forum/infinitescroll'], functi
members.attr('loading', 1); members.attr('loading', 1);
socket.emit('groups.loadMoreMembers', { socket.emit('groups.loadMoreMembers', {
groupName: groupName, groupName: groupName,
after: members.attr('data-nextstart') after: members.attr('data-nextstart'),
}, function (err, data) { }, function (err, data) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
@ -88,10 +87,10 @@ define('forum/groups/memberlist', ['components', 'forum/infinitescroll'], functi
app.parseAndTranslate('groups/details', 'members', { app.parseAndTranslate('groups/details', 'members', {
group: { group: {
members: users, members: users,
isOwner: ajaxify.data.group.isOwner isOwner: ajaxify.data.group.isOwner,
} },
}, callback); }, callback);
} }
return MemberList; return MemberList;
}); });

@ -1,9 +1,7 @@
'use strict'; 'use strict';
/* globals define, socket, app */
define('forum/infinitescroll', function () { define('forum/infinitescroll', function () {
var scroll = {}; var scroll = {};
var callback; var callback;
var previousScrollTop = 0; var previousScrollTop = 0;
@ -34,7 +32,8 @@ define('forum/infinitescroll', function () {
var offsetTop = container.offset() ? container.offset().top : 0; var offsetTop = container.offset() ? container.offset().top : 0;
var scrollPercent = 100 * (currentScrollTop - offsetTop) / (viewportHeight <= 0 ? wh : viewportHeight); var scrollPercent = 100 * (currentScrollTop - offsetTop) / (viewportHeight <= 0 ? wh : viewportHeight);
var top = 20, bottom = 80; var top = 20;
var bottom = 80;
var direction = currentScrollTop > previousScrollTop ? 1 : -1; var direction = currentScrollTop > previousScrollTop ? 1 : -1;
@ -55,7 +54,7 @@ define('forum/infinitescroll', function () {
} }
loadingMore = true; loadingMore = true;
var hookData = {method: method, data: data}; var hookData = { method: method, data: data };
$(window).trigger('action:infinitescroll.loadmore', hookData); $(window).trigger('action:infinitescroll.loadmore', hookData);
socket.emit(hookData.method, hookData.data, function (err, data) { socket.emit(hookData.method, hookData.data, function (err, data) {
@ -76,8 +75,8 @@ define('forum/infinitescroll', function () {
var removeCount = els.length - count; var removeCount = els.length - count;
if (direction > 0) { if (direction > 0) {
var height = $(document).height(), var height = $(document).height();
scrollTop = $(window).scrollTop(); var scrollTop = $(window).scrollTop();
els.slice(0, removeCount).remove(); els.slice(0, removeCount).remove();
@ -88,4 +87,4 @@ define('forum/infinitescroll', function () {
}; };
return scroll; return scroll;
}); });

@ -1,13 +1,13 @@
"use strict"; 'use strict';
/* global define, app, config, RELATIVE_PATH */
define('forum/login', ['translator'], function (translator) {
define('forum/login', [], function () {
var Login = {}; var Login = {};
Login.init = function () { Login.init = function () {
var errorEl = $('#login-error-notify'), var errorEl = $('#login-error-notify');
submitEl = $('#login'), var submitEl = $('#login');
formEl = $('#login-form'); var formEl = $('#login-form');
submitEl.on('click', function (e) { submitEl.on('click', function (e) {
e.preventDefault(); e.preventDefault();
@ -33,12 +33,12 @@ define('forum/login', ['translator'], function (translator) {
formEl.ajaxSubmit({ formEl.ajaxSubmit({
headers: { headers: {
'x-csrf-token': config.csrf_token 'x-csrf-token': config.csrf_token,
}, },
success: function (data, status) { success: function (data) {
window.location.href = data + '?loggedin'; window.location.href = data + '?loggedin';
}, },
error: function (data, status) { error: function (data) {
if (data.status === 403 && data.responseText === 'Forbidden') { if (data.status === 403 && data.responseText === 'Forbidden') {
window.location.href = config.relative_path + '/login?error=csrf-invalid'; window.location.href = config.relative_path + '/login?error=csrf-invalid';
} else { } else {
@ -52,7 +52,7 @@ define('forum/login', ['translator'], function (translator) {
$('#password').select(); $('#password').select();
} }
} }
} },
}); });
} }
}); });

@ -1,6 +1,5 @@
'use strict'; 'use strict';
/* globals define, socket, app */
define('forum/notifications', ['components', 'notifications', 'forum/infinitescroll'], function (components, notifs, infinitescroll) { define('forum/notifications', ['components', 'notifications', 'forum/infinitescroll'], function (components, notifs, infinitescroll) {
var Notifications = {}; var Notifications = {};
@ -46,7 +45,7 @@ define('forum/notifications', ['components', 'notifications', 'forum/infinitescr
} }
var notifList = $('.notifications-list'); var notifList = $('.notifications-list');
infinitescroll.loadMore('notifications.loadMore', { infinitescroll.loadMore('notifications.loadMore', {
after: notifList.attr('data-nextstart') after: notifList.attr('data-nextstart'),
}, function (data, done) { }, function (data, done) {
if (!data) { if (!data) {
return done(); return done();
@ -55,7 +54,7 @@ define('forum/notifications', ['components', 'notifications', 'forum/infinitescr
if (!data.notifications || !data.notifications.length) { if (!data.notifications || !data.notifications.length) {
return done(); return done();
} }
app.parseAndTranslate('notifications', 'notifications', {notifications: data.notifications}, function (html) { app.parseAndTranslate('notifications', 'notifications', { notifications: data.notifications }, function (html) {
notifList.append(html); notifList.append(html);
html.find('.timeago').timeago(); html.find('.timeago').timeago();
done(); done();

@ -1,5 +1,5 @@
'use strict'; 'use strict';
/*global define, utils, ajaxify, bootbox*/
define('forum/pagination', function () { define('forum/pagination', function () {
var pagination = {}; var pagination = {};

@ -1,6 +1,5 @@
'use strict'; 'use strict';
/* globals define, app, socket*/
define('forum/popular', ['components'], function (components) { define('forum/popular', ['components'], function (components) {
var Popular = {}; var Popular = {};

@ -1,6 +1,5 @@
'use strict'; 'use strict';
/* globals define, app, socket, utils, ajaxify, config */
define('forum/recent', ['forum/infinitescroll', 'components'], function (infinitescroll, components) { define('forum/recent', ['forum/infinitescroll', 'components'], function (infinitescroll, components) {
var Recent = {}; var Recent = {};
@ -27,7 +26,7 @@ define('forum/recent', ['forum/infinitescroll', 'components'], function (infinit
infinitescroll.init(Recent.loadMoreTopics); infinitescroll.init(Recent.loadMoreTopics);
} }
$(window).trigger('action:topics.loaded', {topics: ajaxify.data.topics}); $(window).trigger('action:topics.loaded', { topics: ajaxify.data.topics });
}; };
Recent.watchForNewPosts = function () { Recent.watchForNewPosts = function () {
@ -47,13 +46,13 @@ define('forum/recent', ['forum/infinitescroll', 'components'], function (infinit
return; return;
} }
++newTopicCount; newTopicCount += 1;
Recent.updateAlertText(); Recent.updateAlertText();
} }
function onNewPost(data) { function onNewPost(data) {
function showAlert() { function showAlert() {
++newPostCount; newPostCount += 1;
Recent.updateAlertText(); Recent.updateAlertText();
} }
@ -135,7 +134,7 @@ define('forum/recent', ['forum/infinitescroll', 'components'], function (infinit
after: $('[component="category"]').attr('data-nextstart'), after: $('[component="category"]').attr('data-nextstart'),
cid: utils.params().cid, cid: utils.params().cid,
filter: ajaxify.data.selectedFilter.filter, filter: ajaxify.data.selectedFilter.filter,
set: $('[component="category"]').attr('data-set') ? $('[component="category"]').attr('data-set') : 'topics:recent' set: $('[component="category"]').attr('data-set') ? $('[component="category"]').attr('data-set') : 'topics:recent',
}, function (data, done) { }, function (data, done) {
if (data.topics && data.topics.length) { if (data.topics && data.topics.length) {
Recent.onTopicsLoaded('recent', data.topics, false, done); Recent.onTopicsLoaded('recent', data.topics, false, done);
@ -147,7 +146,6 @@ define('forum/recent', ['forum/infinitescroll', 'components'], function (infinit
}; };
Recent.onTopicsLoaded = function (templateName, topics, showSelect, callback) { Recent.onTopicsLoaded = function (templateName, topics, showSelect, callback) {
topics = topics.filter(function (topic) { topics = topics.filter(function (topic) {
return !components.get('category/topic', 'tid', topic.tid).length; return !components.get('category/topic', 'tid', topic.tid).length;
}); });
@ -156,14 +154,14 @@ define('forum/recent', ['forum/infinitescroll', 'components'], function (infinit
return callback(); return callback();
} }
app.parseAndTranslate(templateName, 'topics', {topics: topics, showSelect: showSelect}, function (html) { app.parseAndTranslate(templateName, 'topics', { topics: topics, showSelect: showSelect }, function (html) {
$('#category-no-topics').remove(); $('#category-no-topics').remove();
$('[component="category"]').append(html); $('[component="category"]').append(html);
html.find('.timeago').timeago(); html.find('.timeago').timeago();
app.createUserTooltips(); app.createUserTooltips();
utils.makeNumbersHumanReadable(html.find('.human-readable-number')); utils.makeNumbersHumanReadable(html.find('.human-readable-number'));
$(window).trigger('action:topics.loaded', {topics: topics}); $(window).trigger('action:topics.loaded', { topics: topics });
callback(); callback();
}); });
}; };

@ -1,19 +1,17 @@
'use strict'; 'use strict';
/* globals define, app, utils, socket, config, ajaxify, bootbox */
define('forum/register', ['translator'], function (translator) { define('forum/register', ['translator'], function (translator) {
var Register = {}, var Register = {};
validationError = false, var validationError = false;
successIcon = ''; var successIcon = '';
Register.init = function () { Register.init = function () {
var email = $('#email'), var email = $('#email');
username = $('#username'), var username = $('#username');
password = $('#password'), var password = $('#password');
password_confirm = $('#password-confirm'), var password_confirm = $('#password-confirm');
register = $('#register'); var register = $('#register');
handleLanguageOverride(); handleLanguageOverride();
@ -78,7 +76,7 @@ define('forum/register', ['translator'], function (translator) {
registerBtn.parents('form').ajaxSubmit({ registerBtn.parents('form').ajaxSubmit({
headers: { headers: {
'x-csrf-token': config.csrf_token 'x-csrf-token': config.csrf_token,
}, },
success: function (data) { success: function (data) {
registerBtn.removeClass('disabled'); registerBtn.removeClass('disabled');
@ -106,7 +104,7 @@ define('forum/register', ['translator'], function (translator) {
registerBtn.removeClass('disabled'); registerBtn.removeClass('disabled');
} }
}); });
} },
}); });
}); });
}); });
@ -122,7 +120,7 @@ define('forum/register', ['translator'], function (translator) {
} }
socket.emit('user.emailExists', { socket.emit('user.emailExists', {
email: email email: email,
}, function (err, exists) { }, function (err, exists) {
if (err) { if (err) {
app.alertError(err.message); app.alertError(err.message);
@ -152,7 +150,7 @@ define('forum/register', ['translator'], function (translator) {
showError(username_notify, '[[error:invalid-username]]'); showError(username_notify, '[[error:invalid-username]]');
} else { } else {
socket.emit('user.exists', { socket.emit('user.exists', {
username: username username: username,
}, function (err, exists) { }, function (err, exists) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
@ -170,8 +168,8 @@ define('forum/register', ['translator'], function (translator) {
} }
function validatePassword(password, password_confirm) { function validatePassword(password, password_confirm) {
var password_notify = $('#password-notify'), var password_notify = $('#password-notify');
password_confirm_notify = $('#password-confirm-notify'); var password_confirm_notify = $('#password-confirm-notify');
if (password.length < ajaxify.data.minimumPasswordLength) { if (password.length < ajaxify.data.minimumPasswordLength) {
showError(password_notify, '[[user:change_password_error_length]]'); showError(password_notify, '[[user:change_password_error_length]]');
@ -193,8 +191,8 @@ define('forum/register', ['translator'], function (translator) {
} }
function validatePasswordConfirm(password, password_confirm) { function validatePasswordConfirm(password, password_confirm) {
var password_notify = $('#password-notify'), var password_notify = $('#password-notify');
password_confirm_notify = $('#password-confirm-notify'); var password_confirm_notify = $('#password-confirm-notify');
if (!password || password_notify.hasClass('alert-error')) { if (!password || password_notify.hasClass('alert-error')) {
return; return;
@ -230,8 +228,8 @@ define('forum/register', ['translator'], function (translator) {
function handleLanguageOverride() { function handleLanguageOverride() {
if (!app.user.uid && config.defaultLang !== config.userLang) { if (!app.user.uid && config.defaultLang !== config.userLang) {
var formEl = $('[component="register/local"]'), var formEl = $('[component="register/local"]');
langEl = $('<input type="hidden" name="userLang" value="' + config.userLang + '" />'); var langEl = $('<input type="hidden" name="userLang" value="' + config.userLang + '" />');
formEl.append(langEl); formEl.append(langEl);
} }

@ -1,18 +1,18 @@
"use strict"; 'use strict';
/*globals define, app, socket*/
define('forum/reset', function () { define('forum/reset', function () {
var ResetPassword = {}; var ResetPassword = {};
ResetPassword.init = function () { ResetPassword.init = function () {
var inputEl = $('#email'), var inputEl = $('#email');
errorEl = $('#error'), var errorEl = $('#error');
successEl = $('#success'); var successEl = $('#success');
$('#reset').on('click', function () { $('#reset').on('click', function () {
if (inputEl.val() && inputEl.val().indexOf('@') !== -1) { if (inputEl.val() && inputEl.val().indexOf('@') !== -1) {
socket.emit('user.reset.send', inputEl.val(), function (err) { socket.emit('user.reset.send', inputEl.val(), function (err) {
if(err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
} }

@ -1,5 +1,5 @@
"use strict"; 'use strict';
/*globals define, app, ajaxify, socket, config*/
define('forum/reset_code', function () { define('forum/reset_code', function () {
var ResetCode = {}; var ResetCode = {};
@ -20,7 +20,7 @@ define('forum/reset_code', function () {
resetEl.prop('disabled', true).html('<i class="fa fa-spin fa-refresh"></i> Changing Password'); resetEl.prop('disabled', true).html('<i class="fa fa-spin fa-refresh"></i> Changing Password');
socket.emit('user.reset.commit', { socket.emit('user.reset.commit', {
code: reset_code, code: reset_code,
password: password.val() password: password.val(),
}, function (err) { }, function (err) {
if (err) { if (err) {
ajaxify.refresh(); ajaxify.refresh();

@ -1,6 +1,5 @@
'use strict'; 'use strict';
/* globals app, define, utils*/
define('forum/search', ['search', 'autocomplete'], function (searchModule, autocomplete) { define('forum/search', ['search', 'autocomplete'], function (searchModule, autocomplete) {
var Search = {}; var Search = {};
@ -36,7 +35,7 @@ define('forum/search', ['search', 'autocomplete'], function (searchModule, autoc
function getSearchData() { function getSearchData() {
var form = $('#advanced-search'); var form = $('#advanced-search');
var searchData = { var searchData = {
in: $('#search-in').val() in: $('#search-in').val(),
}; };
searchData.term = $('#search-input').val(); searchData.term = $('#search-input').val();
if (searchData.in === 'posts' || searchData.in === 'titlesposts' || searchData.in === 'titles') { if (searchData.in === 'posts' || searchData.in === 'titlesposts' || searchData.in === 'titles') {
@ -128,7 +127,8 @@ define('forum/search', ['search', 'autocomplete'], function (searchModule, autoc
var regex = new RegExp('(' + regexStr + ')', 'gi'); var regex = new RegExp('(' + regexStr + ')', 'gi');
$('.search-result-text p, .search-result-text h4').each(function () { $('.search-result-text p, .search-result-text h4').each(function () {
var result = $(this), nested = []; var result = $(this);
var nested = [];
result.find('*').each(function () { result.find('*').each(function () {
$(this).after('<!-- ' + nested.length + ' -->'); $(this).after('<!-- ' + nested.length + ' -->');
@ -137,7 +137,7 @@ define('forum/search', ['search', 'autocomplete'], function (searchModule, autoc
result.html(result.html().replace(regex, '<strong>$1</strong>')); result.html(result.html().replace(regex, '<strong>$1</strong>'));
for (var i = 0, ii = nested.length; i < ii; i++) { for (var i = 0, ii = nested.length; i < ii; i += 1) {
result.html(result.html().replace('<!-- ' + i + ' -->', nested[i].html())); result.html(result.html().replace('<!-- ' + i + ' -->', nested[i].html()));
} }
}); });
@ -168,7 +168,7 @@ define('forum/search', ['search', 'autocomplete'], function (searchModule, autoc
var tagEl = $('#has-tags'); var tagEl = $('#has-tags');
tagEl.tagsinput({ tagEl.tagsinput({
confirmKeys: [13, 44], confirmKeys: [13, 44],
trimValue: true trimValue: true,
}); });
autocomplete.tag($('#has-tags').siblings('.bootstrap-tagsinput').find('input')); autocomplete.tag($('#has-tags').siblings('.bootstrap-tagsinput').find('input'));

@ -1,6 +1,5 @@
'use strict'; 'use strict';
/* globals define, app, ajaxify, socket */
define('forum/tag', ['forum/recent', 'forum/infinitescroll'], function (recent, infinitescroll) { define('forum/tag', ['forum/recent', 'forum/infinitescroll'], function (recent, infinitescroll) {
var Tag = {}; var Tag = {};
@ -21,13 +20,13 @@ define('forum/tag', ['forum/recent', 'forum/infinitescroll'], function (recent,
} }
function loadMoreTopics(direction) { function loadMoreTopics(direction) {
if(direction < 0 || !$('[component="category"]').length) { if (direction < 0 || !$('[component="category"]').length) {
return; return;
} }
infinitescroll.loadMore('topics.loadMoreFromSet', { infinitescroll.loadMore('topics.loadMoreFromSet', {
set: 'tag:' + ajaxify.data.tag + ':topics', set: 'tag:' + ajaxify.data.tag + ':topics',
after: $('[component="category"]').attr('data-nextstart') after: $('[component="category"]').attr('data-nextstart'),
}, function (data, done) { }, function (data, done) {
if (data.topics && data.topics.length) { if (data.topics && data.topics.length) {
recent.onTopicsLoaded('tag', data.topics, false, done); recent.onTopicsLoaded('tag', data.topics, false, done);

@ -1,6 +1,5 @@
'use strict'; 'use strict';
/* globals define, app, utils, socket */
define('forum/tags', ['forum/infinitescroll'], function (infinitescroll) { define('forum/tags', ['forum/infinitescroll'], function (infinitescroll) {
var Tags = {}; var Tags = {};
@ -20,7 +19,7 @@ define('forum/tags', ['forum/infinitescroll'], function (infinitescroll) {
} }
timeoutId = setTimeout(function () { timeoutId = setTimeout(function () {
socket.emit('topics.searchAndLoadTags', {query: $('#tag-search').val()}, function (err, results) { socket.emit('topics.searchAndLoadTags', { query: $('#tag-search').val() }, function (err, results) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
} }
@ -40,7 +39,7 @@ define('forum/tags', ['forum/infinitescroll'], function (infinitescroll) {
} }
infinitescroll.loadMore('topics.loadMoreTags', { infinitescroll.loadMore('topics.loadMoreTags', {
after: $('.tag-list').attr('data-nextstart') after: $('.tag-list').attr('data-nextstart'),
}, function (data, done) { }, function (data, done) {
if (data && data.tags && data.tags.length) { if (data && data.tags && data.tags.length) {
onTagsLoaded(data.tags, false, done); onTagsLoaded(data.tags, false, done);
@ -53,7 +52,7 @@ define('forum/tags', ['forum/infinitescroll'], function (infinitescroll) {
function resetSearch() { function resetSearch() {
socket.emit('topics.loadMoreTags', { socket.emit('topics.loadMoreTags', {
after: 0 after: 0,
}, function (err, data) { }, function (err, data) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
@ -64,7 +63,7 @@ define('forum/tags', ['forum/infinitescroll'], function (infinitescroll) {
function onTagsLoaded(tags, replace, callback) { function onTagsLoaded(tags, replace, callback) {
callback = callback || function () {}; callback = callback || function () {};
app.parseAndTranslate('tags', 'tags', {tags: tags}, function (html) { app.parseAndTranslate('tags', 'tags', { tags: tags }, function (html) {
$('.tag-list')[replace ? 'html' : 'append'](html); $('.tag-list')[replace ? 'html' : 'append'](html);
utils.makeNumbersHumanReadable(html.find('.human-readable-number')); utils.makeNumbersHumanReadable(html.find('.human-readable-number'));
callback(); callback();

@ -1,8 +1,6 @@
'use strict'; 'use strict';
/* globals define, app, socket, config, ajaxify, RELATIVE_PATH, utils */
define('forum/topic', [ define('forum/topic', [
'forum/infinitescroll', 'forum/infinitescroll',
'forum/topic/threadTools', 'forum/topic/threadTools',
@ -12,10 +10,10 @@ define('forum/topic', [
'forum/topic/replies', 'forum/topic/replies',
'navigator', 'navigator',
'sort', 'sort',
'components' 'components',
], function (infinitescroll, threadTools, postTools, events, posts, replies, navigator, sort, components) { ], function (infinitescroll, threadTools, postTools, events, posts, replies, navigator, sort, components) {
var Topic = {}, var Topic = {};
currentUrl = ''; var currentUrl = '';
$(window).on('action:ajaxify.start', function (ev, data) { $(window).on('action:ajaxify.start', function (ev, data) {
if (Topic.replaceURLTimeout) { if (Topic.replaceURLTimeout) {
@ -112,8 +110,8 @@ define('forum/topic', [
mousetrap.bind('ctrl+f', function (e) { mousetrap.bind('ctrl+f', function (e) {
if (config.topicSearchEnabled) { if (config.topicSearchEnabled) {
// If in topic, open search window and populate, otherwise regular behaviour // If in topic, open search window and populate, otherwise regular behaviour
var match = ajaxify.currentPage.match(/^topic\/([\d]+)/), var match = ajaxify.currentPage.match(/^topic\/([\d]+)/);
tid; var tid;
if (match) { if (match) {
e.preventDefault(); e.preventDefault();
tid = match[1]; tid = match[1];
@ -157,12 +155,12 @@ define('forum/topic', [
message: '[[topic:bookmark_instructions]]', message: '[[topic:bookmark_instructions]]',
timeout: 0, timeout: 0,
type: 'info', type: 'info',
clickfn : function () { clickfn: function () {
navigator.scrollToPost(parseInt(bookmark - 1, 10), true); navigator.scrollToPost(parseInt(bookmark - 1, 10), true);
}, },
closefn : function () { closefn: function () {
localStorage.removeItem('topic:' + tid + ':bookmark'); localStorage.removeItem('topic:' + tid + ':bookmark');
} },
}); });
setTimeout(function () { setTimeout(function () {
app.removeAlert('bookmark'); app.removeAlert('bookmark');
@ -245,13 +243,11 @@ define('forum/topic', [
var newUrl = 'topic/' + ajaxify.data.slug + (index > 1 ? ('/' + index) : ''); var newUrl = 'topic/' + ajaxify.data.slug + (index > 1 ? ('/' + index) : '');
if (newUrl !== currentUrl) { if (newUrl !== currentUrl) {
if (Topic.replaceURLTimeout) { if (Topic.replaceURLTimeout) {
clearTimeout(Topic.replaceURLTimeout); clearTimeout(Topic.replaceURLTimeout);
} }
Topic.replaceURLTimeout = setTimeout(function () { Topic.replaceURLTimeout = setTimeout(function () {
if (index >= elementCount && app.user.uid) { if (index >= elementCount && app.user.uid) {
socket.emit('topics.markAsRead', [ajaxify.data.tid]); socket.emit('topics.markAsRead', [ajaxify.data.tid]);
} }
@ -266,7 +262,7 @@ define('forum/topic', [
} }
history.replaceState({ history.replaceState({
url: newUrl + search url: newUrl + search,
}, null, window.location.protocol + '//' + window.location.host + RELATIVE_PATH + '/' + newUrl + search); }, null, window.location.protocol + '//' + window.location.host + RELATIVE_PATH + '/' + newUrl + search);
} }
currentUrl = newUrl; currentUrl = newUrl;
@ -281,8 +277,8 @@ define('forum/topic', [
if (ajaxify.data.postcount > ajaxify.data.bookmarkThreshold && (!currentBookmark || parseInt(index, 10) > parseInt(currentBookmark, 10))) { if (ajaxify.data.postcount > ajaxify.data.bookmarkThreshold && (!currentBookmark || parseInt(index, 10) > parseInt(currentBookmark, 10))) {
if (app.user.uid) { if (app.user.uid) {
socket.emit('topics.bookmark', { socket.emit('topics.bookmark', {
'tid': ajaxify.data.tid, tid: ajaxify.data.tid,
'index': index index: index,
}, function (err) { }, function (err) {
if (err) { if (err) {
return app.alertError(err.message); return app.alertError(err.message);
@ -298,7 +294,6 @@ define('forum/topic', [
if (!currentBookmark || parseInt(index, 10) >= parseInt(currentBookmark, 10)) { if (!currentBookmark || parseInt(index, 10) >= parseInt(currentBookmark, 10)) {
app.removeAlert('bookmark'); app.removeAlert('bookmark');
} }
} }

@ -1,9 +1,7 @@
'use strict'; 'use strict';
/* globals define, app, ajaxify, socket */
define('forum/topic/delete-posts', ['components', 'postSelect'], function (components, postSelect) { define('forum/topic/delete-posts', ['components', 'postSelect'], function (components, postSelect) {
var DeletePosts = {}; var DeletePosts = {};
var modal; var modal;
var deleteBtn; var deleteBtn;
@ -49,7 +47,7 @@ define('forum/topic/delete-posts', ['components', 'postSelect'], function (compo
btn.attr('disabled', true); btn.attr('disabled', true);
socket.emit(command, { socket.emit(command, {
tid: ajaxify.data.tid, tid: ajaxify.data.tid,
pids: postSelect.pids pids: postSelect.pids,
}, function (err) { }, function (err) {
btn.removeAttr('disabled'); btn.removeAttr('disabled');
if (err) { if (err) {

@ -1,16 +1,14 @@
'use strict'; 'use strict';
/* globals config, app, ajaxify, define, socket, templates, utils */
define('forum/topic/events', [ define('forum/topic/events', [
'forum/topic/postTools', 'forum/topic/postTools',
'forum/topic/threadTools', 'forum/topic/threadTools',
'forum/topic/posts', 'forum/topic/posts',
'components', 'components',
'translator' 'translator',
], function (postTools, threadTools, posts, components, translator) { ], function (postTools, threadTools, posts, components, translator) {
var Events = {}; var Events = {};
var events = { var events = {
@ -44,12 +42,12 @@ define('forum/topic/events', [
'posts.unvote': togglePostVote, 'posts.unvote': togglePostVote,
'event:new_notification': onNewNotification, 'event:new_notification': onNewNotification,
'event:new_post': posts.onNewPost 'event:new_post': posts.onNewPost,
}; };
Events.init = function () { Events.init = function () {
Events.removeListeners(); Events.removeListeners();
for(var eventName in events) { for (var eventName in events) {
if (events.hasOwnProperty(eventName)) { if (events.hasOwnProperty(eventName)) {
socket.on(eventName, events[eventName]); socket.on(eventName, events[eventName]);
} }
@ -57,7 +55,7 @@ define('forum/topic/events', [
}; };
Events.removeListeners = function () { Events.removeListeners = function () {
for(var eventName in events) { for (var eventName in events) {
if (events.hasOwnProperty(eventName)) { if (events.hasOwnProperty(eventName)) {
socket.removeListener(eventName, events[eventName]); socket.removeListener(eventName, events[eventName]);
} }
@ -113,7 +111,7 @@ define('forum/topic/events', [
if (topicTitle.length && data.topic.title && topicTitle.html() !== data.topic.title) { if (topicTitle.length && data.topic.title && topicTitle.html() !== data.topic.title) {
ajaxify.data.title = data.topic.title; ajaxify.data.title = data.topic.title;
var newUrl = 'topic/' + data.topic.slug + (window.location.search ? window.location.search : ''); var newUrl = 'topic/' + data.topic.slug + (window.location.search ? window.location.search : '');
history.replaceState({url: newUrl}, null, window.location.protocol + '//' + window.location.host + config.relative_path + '/' + newUrl); history.replaceState({ url: newUrl }, null, window.location.protocol + '//' + window.location.host + config.relative_path + '/' + newUrl);
topicTitle.fadeOut(250, function () { topicTitle.fadeOut(250, function () {
topicTitle.html(data.topic.title).fadeIn(250); topicTitle.html(data.topic.title).fadeIn(250);
@ -137,7 +135,7 @@ define('forum/topic/events', [
var editData = { var editData = {
editor: data.editor, editor: data.editor,
editedISO: utils.toISOString(data.post.edited) editedISO: utils.toISOString(data.post.edited),
}; };
templates.parse('partials/topic/post-editor', editData, function (html) { templates.parse('partials/topic/post-editor', editData, function (html) {
@ -151,7 +149,7 @@ define('forum/topic/events', [
}); });
if (data.topic.tags && tagsUpdated(data.topic.tags)) { if (data.topic.tags && tagsUpdated(data.topic.tags)) {
templates.parse('partials/post_bar', 'tags', {tags: data.topic.tags}, function (html) { templates.parse('partials/post_bar', 'tags', { tags: data.topic.tags }, function (html) {
var tags = $('.tags'); var tags = $('.tags');
tags.fadeOut(250, function () { tags.fadeOut(250, function () {
@ -166,7 +164,7 @@ define('forum/topic/events', [
return true; return true;
} }
for (var i = 0; i < tags.length; ++i) { for (var i = 0; i < tags.length; i += 1) {
if (!$('.tags .tag-item[data-tag="' + tags[i].value + '"]').length) { if (!$('.tags .tag-item[data-tag="' + tags[i].value + '"]').length) {
return true; return true;
} }
@ -179,7 +177,7 @@ define('forum/topic/events', [
$(this).remove(); $(this).remove();
posts.showBottomPostBar(); posts.showBottomPostBar();
}); });
ajaxify.data.postcount --; ajaxify.data.postcount -= 1;
postTools.updatePostCount(ajaxify.data.postcount); postTools.updatePostCount(ajaxify.data.postcount);
require(['forum/topic/replies'], function (replies) { require(['forum/topic/replies'], function (replies) {
replies.onPostPurged(postData); replies.onPostPurged(postData);

@ -1,9 +1,7 @@
'use strict'; 'use strict';
/* globals define, app, ajaxify, socket */
define('forum/topic/fork', ['components', 'postSelect'], function (components, postSelect) { define('forum/topic/fork', ['components', 'postSelect'], function (components, postSelect) {
var Fork = {}; var Fork = {};
var forkModal; var forkModal;
var forkCommit; var forkCommit;
@ -44,7 +42,7 @@ define('forum/topic/fork', ['components', 'postSelect'], function (components, p
socket.emit('topics.createTopicFromPosts', { socket.emit('topics.createTopicFromPosts', {
title: forkModal.find('#fork-title').val(), title: forkModal.find('#fork-title').val(),
pids: postSelect.pids, pids: postSelect.pids,
fromTid: ajaxify.data.tid fromTid: ajaxify.data.tid,
}, function (err, newTopic) { }, function (err, newTopic) {
function fadeOutAndRemove(pid) { function fadeOutAndRemove(pid) {
components.get('post', 'pid', pid).fadeOut(500, function () { components.get('post', 'pid', pid).fadeOut(500, function () {
@ -63,7 +61,7 @@ define('forum/topic/fork', ['components', 'postSelect'], function (components, p
type: 'success', type: 'success',
clickfn: function () { clickfn: function () {
ajaxify.go('topic/' + newTopic.slug); ajaxify.go('topic/' + newTopic.slug);
} },
}); });
postSelect.pids.forEach(function (pid) { postSelect.pids.forEach(function (pid) {

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save