diff --git a/loader.js b/loader.js index 2effb4ffa0..2ab9be2715 100644 --- a/loader.js +++ b/loader.js @@ -44,11 +44,18 @@ var nconf = require('nconf'), nconf.argv(); +// Start the daemon! if (nconf.get('d')) { // Check for a still-active NodeBB process if (fs.existsSync(pidFilePath)) { - console.log('\n Error: Another NodeBB is already running!'); - process.exit(); + try { + var pid = fs.readFileSync(pidFilePath, { encoding: 'utf-8' }); + process.kill(pid, 0); + console.log('\n Error: Another NodeBB is already running!'); + process.exit(); + } catch (e) { + fs.unlinkSync(pidFilePath); + } } // Initialise logging streams diff --git a/public/src/forum/admin/groups.js b/public/src/forum/admin/groups.js index c5b69e8743..970822fa73 100644 --- a/public/src/forum/admin/groups.js +++ b/public/src/forum/admin/groups.js @@ -127,7 +127,7 @@ define(function() { .append($('').attr('src', results.users[x].picture)) .append($('').html(results.users[x].username)); - resultsEl.appendChild(foundUser); + resultsEl.append(foundUser); } } else { resultsEl.html('
  • No Users Found
  • '); diff --git a/public/src/forum/pagination.js b/public/src/forum/pagination.js index 3b19fce4c1..afd4bf3fb8 100644 --- a/public/src/forum/pagination.js +++ b/public/src/forum/pagination.js @@ -17,8 +17,6 @@ define(function() { return pagination.loadPage(pagination.currentPage - 1); }).on('click', '.next', function() { return pagination.loadPage(pagination.currentPage + 1); - }).on('click', '.page', function() { - return pagination.loadPage($(this).attr('data-page')); }).on('click', '.select_page', function(e) { e.preventDefault(); bootbox.prompt('Enter page number:', function(pageNum) { @@ -77,7 +75,11 @@ define(function() { return false; } - ajaxify.go(window.location.pathname.slice(1) + '?page=' + page); + ajaxify.go(window.location.pathname.slice(1) + '?page=' + page, function() { + if (typeof callback === 'function') { + callback(); + } + }); return true; } diff --git a/public/src/forum/topic.js b/public/src/forum/topic.js index 6a697f5849..a74c3d18fe 100644 --- a/public/src/forum/topic.js +++ b/public/src/forum/topic.js @@ -309,7 +309,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) { var bookmark = localStorage.getItem('topic:' + tid + ':bookmark'); if (window.location.hash) { Topic.scrollToPost(window.location.hash.substr(1), true); - } else if (bookmark) { + } else if (bookmark && (!config.usePagination || (config.usePagination && pagination.currentPage === 1))) { app.alert({ alert_id: 'bookmark', message: '[[topic:bookmark_instructions]]', @@ -324,7 +324,9 @@ define(['composer', 'forum/pagination'], function(composer, pagination) { }); } - updateHeader(); + if (!window.location.hash && !config.usePagination) { + updateHeader(); + } $('#post-container').on('mouseenter', '.favourite-tooltip', function(e) { if (!$(this).data('users-loaded')) { @@ -1037,26 +1039,29 @@ define(['composer', 'forum/pagination'], function(composer, pagination) { if(index > Topic.postCount) { index = Topic.postCount; } + $('#pagination').html(index + ' out of ' + Topic.postCount); $('.progress-bar').width((index / Topic.postCount * 100) + '%'); - if(!parseInt(el.attr('data-index'), 10)) { - localStorage.removeItem('topic:' + templates.get('topic_id') + ':bookmark'); - } else { + var currentBookmark = localStorage.getItem('topic:' + templates.get('topic_id') + ':bookmark'); + if (!currentBookmark || parseInt(el.attr('data-pid'), 10) > parseInt(currentBookmark, 10)) { localStorage.setItem('topic:' + templates.get('topic_id') + ':bookmark', el.attr('data-pid')); + } - if (!scrollingToPost) { - var newUrl = window.location.protocol + '//' + window.location.host + window.location.pathname + '#' + el.attr('data-pid') - if (newUrl !== currentUrl) { - if (history.replaceState) { - history.replaceState({ - url: window.location.pathname.slice(1) + '#' + el.attr('data-pid') - }, null, newUrl); - } - currentUrl = newUrl; + if (!scrollingToPost) { + + var newUrl = window.location.href.replace(window.location.hash, '') + '#' + el.attr('data-pid'); + + if (newUrl !== currentUrl) { + if (history.replaceState) { + history.replaceState({ + url: window.location.pathname.slice(1) + (window.location.search ? window.location.search : '' ) + '#' + el.attr('data-pid') + }, null, newUrl); } + currentUrl = newUrl; } } + return false; } }); @@ -1090,7 +1095,9 @@ define(['composer', 'forum/pagination'], function(composer, pagination) { return; } if(parseInt(page, 10) !== pagination.currentPage) { - pagination.loadPage(page); + pagination.loadPage(page, function() { + scrollToPid(pid); + }); } else { scrollToPid(pid); } @@ -1106,6 +1113,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) { if(after < 0) { after = 0; } + loadMorePosts(tid, after, function() { scrollToPid(pid); }); @@ -1123,6 +1131,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) { scrollTop: (scrollTo.offset().top - $('#header-menu').height() - offset) + "px" }, duration !== undefined ? duration : 400, function() { scrollingToPost = false; + updateHeader(); if (highlight) { scrollTo.parent().find('.topic-item').addClass('highlight'); setTimeout(function() { diff --git a/public/templates/account.tpl b/public/templates/account.tpl index d099d68767..7b660a185d 100644 --- a/public/templates/account.tpl +++ b/public/templates/account.tpl @@ -115,7 +115,7 @@
    - {ips.ip} +
    {ips.ip}
    diff --git a/src/meta.js b/src/meta.js index 91ef0d6474..ad788fdece 100644 --- a/src/meta.js +++ b/src/meta.js @@ -253,6 +253,7 @@ var fs = require('fs'), jsPaths = scripts.map(function (jsPath) { jsPath = path.normalize(jsPath); + // The filter:scripts.get plugin will be deprecated as of v0.5.0, specify scripts in plugin.json instead if (jsPath.substring(0, 7) === 'plugins') { var matches = _.map(plugins.staticDirs, function(realPath, mappedPath) { if (jsPath.match(mappedPath)) { @@ -263,7 +264,10 @@ var fs = require('fs'), }).filter(function(a) { return a; }); if (matches.length) { - var relPath = jsPath.slice(new String('plugins/' + matches[0]).length); + var relPath = jsPath.slice(new String('plugins/' + matches[0]).length), + pluginId = matches[0].split(path.sep)[0]; + + winston.warn('[meta.scripts.get (' + pluginId + ')] filter:scripts.get is deprecated, consider using "scripts" in plugin.json'); return plugins.staticDirs[matches[0]] + relPath; } else { winston.warn('[meta.scripts.get] Could not resolve mapped path: ' + jsPath + '. Are you sure it is defined by a plugin?'); @@ -274,31 +278,49 @@ var fs = require('fs'), } }); + // Remove scripts that could not be found (remove this line at v0.5.0) Meta.js.scripts = jsPaths.filter(function(path) { return path !== null; }); - if (process.env.NODE_ENV !== 'development') { - callback(null, [ - Meta.js.minFile - ]); - } else { - callback(null, scripts); - } + // Add plugin scripts + Meta.js.scripts = Meta.js.scripts.concat(plugins.clientScripts); + + callback(null, [ + Meta.js.minFile + ]); }); }, minify: function (callback) { var uglifyjs = require('uglify-js'), - jsPaths = this.scripts, minified; if (process.env.NODE_ENV === 'development') { winston.info('Minifying client-side libraries'); } - minified = uglifyjs.minify(jsPaths); + minified = uglifyjs.minify(this.scripts); this.cache = minified.code; callback(); + }, + concatenate: function(callback) { + if (process.env.NODE_ENV === 'development') { + winston.info('Concatenating client-side libraries into one file'); + } + + async.map(this.scripts, function(path, next) { + fs.readFile(path, { encoding: 'utf-8' }, next); + }, function(err, contents) { + if (err) { + winston.error('[meta.js.concatenate] Could not minify javascript! Error: ' + err.message); + process.exit(); + } + + Meta.js.cache = contents.reduce(function(output, src) { + return output.length ? output + ';\n' + src : src; + }, ''); + callback(); + }); } }; diff --git a/src/plugins.js b/src/plugins.js index f334d8b0da..688184f81a 100644 --- a/src/plugins.js +++ b/src/plugins.js @@ -17,6 +17,7 @@ var fs = require('fs'), Plugins.staticDirs = {}; Plugins.cssFiles = []; Plugins.lessFiles = []; + Plugins.clientScripts = []; Plugins.initialized = false; @@ -222,6 +223,20 @@ var fs = require('fs'), })); } + next(); + }, + function(next) { + // Client-side scripts + if (pluginData.scripts && pluginData.scripts instanceof Array) { + if (global.env === 'development') { + winston.info('[plugins] Found ' + pluginData.scripts.length + ' js file(s) for plugin ' + pluginData.id); + } + + Plugins.clientScripts = Plugins.clientScripts.concat(pluginData.scripts.map(function(file) { + return path.join(__dirname, '../node_modules/', pluginData.id, file); + })); + } + next(); } ], function(err) { diff --git a/src/routes/meta.js b/src/routes/meta.js index 0900ca07d8..cc5683b924 100644 --- a/src/routes/meta.js +++ b/src/routes/meta.js @@ -45,12 +45,22 @@ var path = require('path'), }); app.get('/nodebb.min.js', function(req, res) { + var sendCached = function() { + return res.type('text/javascript').send(meta.js.cache); + } if (meta.js.cache) { - res.type('text/javascript').send(meta.js.cache); + sendCached(); } else { - meta.js.minify(function() { - res.type('text/javascript').send(meta.js.cache); - }); + if (app.enabled('minification')) { + meta.js.minify(function() { + sendCached(); + }); + } else { + // Compress only + meta.js.concatenate(function() { + sendCached(); + }); + } } }); };