mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-03-06 12:31:33 +01:00
Merge remote-tracking branch 'origin/master' into 0.5.1
This commit is contained in:
@@ -58,7 +58,7 @@
|
||||
"validator": "~3.16.1",
|
||||
"winston": "~0.7.2",
|
||||
"xregexp": "~2.0.0",
|
||||
"templates.js": "0.0.9"
|
||||
"templates.js": "0.0.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "~1.13.0"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"use strict";
|
||||
/*global define, socket, app, bootbox, tabIndent, config, RELATIVE_PATH*/
|
||||
/*global define, socket, app, bootbox, tabIndent, config, RELATIVE_PATH, templates */
|
||||
|
||||
define('forum/admin/themes', ['forum/admin/settings'], function(Settings) {
|
||||
var Themes = {};
|
||||
@@ -71,17 +71,17 @@ define('forum/admin/themes', ['forum/admin/settings'], function(Settings) {
|
||||
if (confirm) {
|
||||
socket.emit('admin.themes.set', {
|
||||
type: 'local',
|
||||
id: 'nodebb-theme-cerulean'
|
||||
id: 'nodebb-theme-vanilla'
|
||||
}, function(err) {
|
||||
if (err) {
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
highlightSelectedTheme('nodebb-theme-cerulean');
|
||||
highlightSelectedTheme('nodebb-theme-vanilla');
|
||||
app.alert({
|
||||
alert_id: 'admin:theme',
|
||||
type: 'success',
|
||||
title: 'Theme Changed',
|
||||
message: 'You have successfully reverted your NodeBB back to it\'s default theme. Restarting your NodeBB <i class="fa fa-refresh fa-spin"></i>',
|
||||
message: 'You have successfully reverted your NodeBB back to it\'s default theme.',
|
||||
timeout: 3500
|
||||
});
|
||||
});
|
||||
@@ -95,34 +95,19 @@ define('forum/admin/themes', ['forum/admin/settings'], function(Settings) {
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
|
||||
var instListEl = $('#installed_themes').empty(), liEl;
|
||||
var instListEl = $('#installed_themes');
|
||||
|
||||
if (!themes.length) {
|
||||
instListEl.append($('<li/ >').addClass('no-themes').html('No installed themes found'));
|
||||
return;
|
||||
} else {
|
||||
templates.parse('partials/admin/theme_list', {
|
||||
themes: themes
|
||||
}, function(html) {
|
||||
instListEl.html(html);
|
||||
highlightSelectedTheme(config['theme:id']);
|
||||
});
|
||||
}
|
||||
|
||||
for (var x = 0, numThemes = themes.length; x < numThemes; x++) {
|
||||
liEl = $('<li/ >').attr({
|
||||
'data-type': 'local',
|
||||
'data-theme': themes[x].id
|
||||
}).html('<img src="' + (themes[x].screenshot ? RELATIVE_PATH + '/css/previews/' + themes[x].id : RELATIVE_PATH + '/images/themes/default.png') + '" />' +
|
||||
'<div>' +
|
||||
'<div class="pull-right">' +
|
||||
'<button class="btn btn-primary" data-action="use">Use</button> ' +
|
||||
'</div>' +
|
||||
'<h4>' + themes[x].name + '</h4>' +
|
||||
'<p>' +
|
||||
themes[x].description +
|
||||
(themes[x].url ? ' (<a href="' + themes[x].url + '">Homepage</a>)' : '') +
|
||||
'</p>' +
|
||||
'</div>' +
|
||||
'<div class="clear">');
|
||||
|
||||
instListEl.append(liEl);
|
||||
}
|
||||
|
||||
highlightSelectedTheme(config['theme:id']);
|
||||
});
|
||||
|
||||
// Proper tabbing for "Custom CSS" field
|
||||
@@ -138,26 +123,23 @@ define('forum/admin/themes', ['forum/admin/settings'], function(Settings) {
|
||||
};
|
||||
|
||||
Themes.render = function(bootswatch) {
|
||||
var themeContainer = $('#bootstrap_themes').empty(),
|
||||
numThemes = bootswatch.themes.length, themeEl, theme;
|
||||
var themeContainer = $('#bootstrap_themes');
|
||||
|
||||
for (var x = 0; x < numThemes; x++) {
|
||||
theme = bootswatch.themes[x];
|
||||
themeEl = $('<li />').attr({
|
||||
'data-type': 'bootswatch',
|
||||
'data-css': theme.cssCdn,
|
||||
'data-theme': theme.name
|
||||
}).html('<img src="' + theme.thumbnail + '" />' +
|
||||
'<div>' +
|
||||
'<div class="pull-right">' +
|
||||
'<button class="btn btn-primary" data-action="use">Use</button> ' +
|
||||
'</div>' +
|
||||
'<h4>' + theme.name + '</h4>' +
|
||||
'<p>' + theme.description + '</p>' +
|
||||
'</div>' +
|
||||
'<div class="clear">');
|
||||
themeContainer.append(themeEl);
|
||||
}
|
||||
templates.parse('partials/admin/theme_list', {
|
||||
themes: bootswatch.themes.map(function(theme) {
|
||||
return {
|
||||
type: 'bootswatch',
|
||||
id: theme.name,
|
||||
name: theme.name,
|
||||
description: theme.description,
|
||||
screenshot_url: theme.thumbnail,
|
||||
url: theme.preview,
|
||||
css: theme.cssCdn
|
||||
};
|
||||
})
|
||||
}, function(html) {
|
||||
themeContainer.html(html);
|
||||
});
|
||||
};
|
||||
|
||||
Themes.prepareWidgets = function() {
|
||||
|
||||
@@ -36,7 +36,7 @@ Please use the npm module instead - require('templates.js')
|
||||
}
|
||||
|
||||
callback(parse(loaded, obj, bind));
|
||||
});
|
||||
});
|
||||
} else {
|
||||
callback(parse(templates.cache[template], obj, bind));
|
||||
}
|
||||
@@ -58,14 +58,15 @@ Please use the npm module instead - require('templates.js')
|
||||
};
|
||||
|
||||
templates.getBlock = function(template, block) {
|
||||
return template.replace(new RegExp('[\\s\\S]*(<!--[\\s]*BEGIN ' + block + '[\\s]*-->[\r\n]*[\\s\\S]*?[\r\n]*<!--[\\s]*END ' + block + '[\\s]*-->)[\\s\\S]*', 'g'), '$1');
|
||||
return template.replace(new RegExp('[\\s\\S]*(<!--[\\s]*BEGIN ' + block + '[\\s]*-->[\\s\\S]*?<!--[\\s]*END ' + block + '[\\s]*-->)[\\s\\S]*', 'g'), '$1');
|
||||
};
|
||||
|
||||
function express(filename, options, fn) {
|
||||
console.log(filename, options, fn);
|
||||
var fs = require('fs'),
|
||||
tpl = filename.replace(options.settings.views + '/', '');
|
||||
|
||||
options['_locals'] = null;
|
||||
|
||||
if (!templates.cache[tpl]) {
|
||||
fs.readFile(filename, function(err, html) {
|
||||
templates.cache[tpl] = (html || '').toString();
|
||||
@@ -82,11 +83,11 @@ Please use the npm module instead - require('templates.js')
|
||||
}
|
||||
|
||||
function makeRegex(block) {
|
||||
return new RegExp('<!--[\\s]*BEGIN ' + block + '[\\s]*-->[\\s\\S]*?<!--[\\s]*END ' + block + '[\\s]*-->');
|
||||
return new RegExp('[\\t ]*<!--[\\s]*BEGIN ' + block + '[\\s]*-->[\\s\\S]*?<!--[\\s]*END ' + block + '[\\s]*-->');
|
||||
}
|
||||
|
||||
function makeBlockRegex(block) {
|
||||
return new RegExp('([\\n]?<!--[\\s]*BEGIN ' + block + '[\\s]*-->[\\n]?)|([\\n]?<!--[\\s]*END ' + block + '[\\s]*-->[\\n]?)', 'g');
|
||||
return new RegExp('([\\t ]*<!--[\\s]*BEGIN ' + block + '[\\s]*-->[\\r\\n?|\\n]?)|(<!--[\\s]*END ' + block + '[\\s]*-->)', 'g');
|
||||
}
|
||||
|
||||
function makeConditionalRegex(block) {
|
||||
@@ -94,7 +95,7 @@ Please use the npm module instead - require('templates.js')
|
||||
}
|
||||
|
||||
function makeStatementRegex(key) {
|
||||
return new RegExp('([\\s]*<!--[\\s]*IF ' + key + '[\\s]*-->)|(<!--[\\s]*ENDIF ' + key + '[\\s]*-->[\\s]*)', 'gi');
|
||||
return new RegExp('([\\s]*<!--[\\s]*IF ' + key + '[\\s]*-->)|(<!--[\\s]*ENDIF ' + key + '[\\s]*-->[\\s]*)', 'g');
|
||||
}
|
||||
|
||||
function registerGlobals(obj) {
|
||||
@@ -113,23 +114,23 @@ Please use the npm module instead - require('templates.js')
|
||||
if (matches !== null) {
|
||||
for (var i = 0, ii = matches.length; i < ii; i++) {
|
||||
var statement = makeStatementRegex(key),
|
||||
nestedConditionals = matches[i].match(/[\s|\S]<!-- IF[\s\S]*ENDIF[\s\S]*-->[\s|\S]/),
|
||||
match = matches[i].replace(statement, '').replace(/[\s|\S]<!-- IF[\s\S]*ENDIF[\s\S]*-->[\s|\S]/gi, '<!-- NESTED -->'),
|
||||
conditionalBlock = match.split(/\s*<!-- ELSE -->\s*/);
|
||||
nestedConditionals = matches[i].match(/(?!^)<!-- IF[\s\S]*ENDIF[\s\S]*?-->(?!$)/),
|
||||
match = matches[i].replace(statement, '').replace(/(?!^)<!-- IF[\s\S]*ENDIF[\s\S]*?-->/gi, '<!-- NESTED -->'),
|
||||
conditionalBlock = match.split(/[\r\n?\n]*?<!-- ELSE -->[\r\n?\n]*?/);
|
||||
|
||||
if (conditionalBlock[1]) {
|
||||
// there is an else statement
|
||||
if (!value) {
|
||||
template = template.replace(matches[i], conditionalBlock[1].replace(/(^[\r\n\t]*)|([\r\n\t]*$)/gi, ''));
|
||||
if (!value) { // todo check second line break conditional, doesn't match.
|
||||
template = template.replace(matches[i], conditionalBlock[1].replace(/(^[\r\n?|\n]*)|([\r\n\t]*$)/gi, ''));
|
||||
} else {
|
||||
template = template.replace(matches[i], conditionalBlock[0].replace(/(^[\r\n\t]*)|([\r\n\t]*$)/gi, ''));
|
||||
template = template.replace(matches[i], conditionalBlock[0].replace(/(^[\r\n?|\n]*)|([\r\n\t]*$)/gi, ''));
|
||||
}
|
||||
} else {
|
||||
// regular if statement
|
||||
if (!value) {
|
||||
template = template.replace(matches[i], '');
|
||||
} else {
|
||||
template = template.replace(matches[i], match.replace(/(^[\r\n\t]*)|([\r\n\t]*$)/gi, ''));
|
||||
template = template.replace(matches[i], match.replace(/(^[\r\n?|\n]*)|([\r\n\t]*$)/gi, ''));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,40 +182,43 @@ Please use the npm module instead - require('templates.js')
|
||||
var regex = makeRegex(key), block;
|
||||
|
||||
if (!array[key].length) {
|
||||
return template;
|
||||
return template.replace(regex, '');
|
||||
}
|
||||
|
||||
while (block = template.match(regex)) {
|
||||
block = block[0].replace(makeBlockRegex(key), '');
|
||||
|
||||
|
||||
var numblocks = array[key].length - 1,
|
||||
iterator = 0,
|
||||
result = '',
|
||||
parsedBlock;
|
||||
|
||||
do {
|
||||
parsedBlock = parse(block, array[key][iterator], bind, namespace, {iterator: iterator, total: numblocks}) + ((iterator < numblocks) ? '\r\n':'');
|
||||
|
||||
parsedBlock = parse(block, array[key][iterator], bind, namespace, {iterator: iterator, total: numblocks});
|
||||
|
||||
result += (!bind) ? parsedBlock : setBindContainer(parsedBlock, bind + namespace + iterator);
|
||||
result = parseFunctions(block, result, {
|
||||
data: array[key][iterator],
|
||||
iterator: iterator,
|
||||
numblocks: numblocks
|
||||
});
|
||||
|
||||
result = checkConditional(result, '@first', iterator === 0);
|
||||
result = checkConditional(result, '!@first', iterator !== 0);
|
||||
result = checkConditional(result, '@last', iterator === numblocks);
|
||||
result = checkConditional(result, '!@last', iterator !== numblocks);
|
||||
|
||||
result = result.replace(/^[\r\n?|\n|\t]*?|[\r\n?|\n|\t]*?$/g, '');
|
||||
|
||||
result = parseFunctions(block, result, {
|
||||
data: array[key][iterator],
|
||||
iterator: iterator,
|
||||
numblocks: numblocks
|
||||
});
|
||||
|
||||
if (bind) {
|
||||
array[key][iterator].__template = block;
|
||||
}
|
||||
} while (iterator++ < numblocks);
|
||||
|
||||
template = template.replace(regex, result);
|
||||
template = template.replace(regex, result.replace(/^[\r\n?|\n]|[\r\n?|\n]$/g, ''));
|
||||
}
|
||||
|
||||
|
||||
return template;
|
||||
}
|
||||
|
||||
@@ -248,14 +252,14 @@ Please use the npm module instead - require('templates.js')
|
||||
this['__' + key] = value;
|
||||
|
||||
var els = document.querySelectorAll('[data-binding="' + (this.__iterator !== false ? (bind + this.__namespace + this.__iterator) : bind) + '"]');
|
||||
|
||||
|
||||
for (var el in els) {
|
||||
if (els.hasOwnProperty(el)) {
|
||||
if (this.__parent) {
|
||||
var parent = this.__parent();
|
||||
els[el].innerHTML = parse(parent.template, parent.data, false);
|
||||
} else {
|
||||
els[el].innerHTML = parse(this.__template, obj, false, this.__namespace);
|
||||
els[el].innerHTML = parse(this.__template, obj, false, this.__namespace);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -295,7 +299,7 @@ Please use the npm module instead - require('templates.js')
|
||||
template = parse(template, obj[key], bind, namespace + key + '.');
|
||||
} else {
|
||||
template = parseValue(template, namespace + key, obj[key]);
|
||||
|
||||
|
||||
if (bind && obj[key]) {
|
||||
setupBindings({
|
||||
obj: obj,
|
||||
|
||||
@@ -39,6 +39,15 @@ module.exports = function(Meta) {
|
||||
return next();
|
||||
} else {
|
||||
var configObj = JSON.parse(file.toString());
|
||||
|
||||
// Minor adjustments for API output
|
||||
configObj.type = 'local';
|
||||
if (configObj.screenshot) {
|
||||
configObj.screenshot_url = nconf.get('relative_path') + '/css/previews/' + configObj.id
|
||||
} else {
|
||||
configObj.screenshot_url = nconf.get('relative_path') + '/images/themes/default.png';
|
||||
}
|
||||
|
||||
next(err, configObj);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user