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 @@
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();
+ });
+ }
}
});
};