fixed conflicts

v1.18.x
Baris Soner Usakli 11 years ago
commit 30eb85f96e

@ -2,16 +2,13 @@
var ajaxify = {}; var ajaxify = {};
(function ($) { (function () {
/*global app, templates, utils*/ /*global app, templates, utils*/
var location = document.location || window.location, var location = document.location || window.location,
rootUrl = location.protocol + '//' + (location.hostname || location.host) + (location.port ? ':' + location.port : ''), rootUrl = location.protocol + '//' + (location.hostname || location.host) + (location.port ? ':' + location.port : ''),
content = null; content = null;
var current_state = null;
var executed = {};
var events = []; var events = [];
ajaxify.register_events = function (new_page_events) { ajaxify.register_events = function (new_page_events) {
for (var i = 0, ii = events.length; i < ii; i++) { for (var i = 0, ii = events.length; i < ii; i++) {
@ -114,7 +111,7 @@ var ajaxify = {};
require(['vendor/async'], function(async) { require(['vendor/async'], function(async) {
$('#content [widget-area]').each(function() { $('#content [widget-area]').each(function() {
widgetLocations.push(this.getAttribute('widget-area')); widgetLocations.push($(this).attr('widget-area'));
}); });
async.each(widgetLocations, function(location, next) { async.each(widgetLocations, function(location, next) {
@ -127,7 +124,9 @@ var ajaxify = {};
if (!renderedWidgets.length) { if (!renderedWidgets.length) {
$('body [no-widget-class]').each(function() { $('body [no-widget-class]').each(function() {
this.className = this.getAttribute('no-widget-class'); var $this = $(this);
$this.removeClass();
$this.addClass($this.attr('no-widget-class'));
}); });
} }
@ -174,7 +173,7 @@ var ajaxify = {};
app.previousUrl = window.location.href; app.previousUrl = window.location.href;
} }
if (this.getAttribute('data-ajaxify') === 'false') { if ($(this).attr('data-ajaxify') === 'false') {
return; return;
} }
@ -198,4 +197,4 @@ var ajaxify = {};
}); });
}); });
}(jQuery)); }());

@ -1,10 +1,10 @@
var socket, var socket,
config, config,
app = { app = {
"username": null, 'username': null,
"uid": null, 'uid': null,
"isFocused": true, 'isFocused': true,
"currentRoom": null 'currentRoom': null
}; };
(function () { (function () {
@ -284,7 +284,7 @@ var socket,
app.populateOnlineUsers = function () { app.populateOnlineUsers = function () {
var uids = []; var uids = [];
jQuery('.post-row').each(function () { $('.post-row').each(function () {
var uid = $(this).attr('data-uid'); var uid = $(this).attr('data-uid');
if(uids.indexOf(uid) === -1) { if(uids.indexOf(uid) === -1) {
uids.push(uid); uids.push(uid);
@ -293,8 +293,8 @@ var socket,
socket.emit('user.getOnlineUsers', uids, function (err, users) { socket.emit('user.getOnlineUsers', uids, function (err, users) {
jQuery('.username-field').each(function (index, element) { $('.username-field').each(function (index, element) {
var el = jQuery(this), var el = $(this),
uid = el.parents('li').attr('data-uid'); uid = el.parents('li').attr('data-uid');
if (uid && users[uid]) { if (uid && users[uid]) {
@ -314,19 +314,19 @@ var socket,
parts = path.split('/'), parts = path.split('/'),
active = parts[parts.length - 1]; active = parts[parts.length - 1];
jQuery('#main-nav li').removeClass('active'); $('#main-nav li').removeClass('active');
if (active) { if (active) {
jQuery('#main-nav li a').each(function () { $('#main-nav li a').each(function () {
var href = this.getAttribute('href'); var href = $(this).attr('href');
if (active == "sort-posts" || active == "sort-reputation" || active == "search" || active == "latest" || active == "online") if (active == "sort-posts" || active == "sort-reputation" || active == "search" || active == "latest" || active == "online")
active = 'users'; active = 'users';
if (href && href.match(active)) { if (href && href.match(active)) {
jQuery(this.parentNode).addClass('active'); $(this.parentNode).addClass('active');
return false; return false;
} }
}); });
} }
}; }
app.createUserTooltips = function() { app.createUserTooltips = function() {
$('img[title].teaser-pic,img[title].user-img').each(function() { $('img[title].teaser-pic,img[title].user-img').each(function() {
@ -342,7 +342,7 @@ var socket,
selector:'.fa-circle.status', selector:'.fa-circle.status',
placement: 'top' placement: 'top'
}); });
} };
app.makeNumbersHumanReadable = function(elements) { app.makeNumbersHumanReadable = function(elements) {
elements.each(function() { elements.each(function() {
@ -459,7 +459,7 @@ var socket,
} }
previousScrollTop = currentScrollTop; previousScrollTop = currentScrollTop;
}); });
} };
var titleObj = { var titleObj = {
active: false, active: false,
@ -596,7 +596,7 @@ var socket,
}); });
}; };
jQuery('document').ready(function () { $('document').ready(function () {
$('#search-form').on('submit', function () { $('#search-form').on('submit', function () {
var input = $(this).find('input'); var input = $(this).find('input');
ajaxify.go("search/" + input.val()); ajaxify.go("search/" + input.val());

@ -9,7 +9,7 @@ define(function() {
hideLinks(); hideLinks();
selectActivePill(); selectActivePill();
} };
AccountHeader.createMenu = function() { AccountHeader.createMenu = function() {
var userslug = $('.account-username-box').attr('data-userslug'); var userslug = $('.account-username-box').attr('data-userslug');
@ -30,7 +30,7 @@ define(function() {
selectActivePill(); selectActivePill();
hideLinks(); hideLinks();
}); });
} };
function hideLinks() { function hideLinks() {
var yourid = templates.get('yourid'), var yourid = templates.get('yourid'),

@ -57,7 +57,7 @@ define(['uploader'], function(uploader) {
function updateCategoryOrders() { function updateCategoryOrders() {
var categories = $('.admin-categories #entry-container').children(); var categories = $('.admin-categories #entry-container').children();
for(var i=0; i<categories.length; ++i) { for(var i = 0; i<categories.length; ++i) {
var input = $(categories[i]).find('input[data-name="order"]'); var input = $(categories[i]).find('input[data-name="order"]');
input.val(i+1).attr('data-value', i+1); input.val(i+1).attr('data-value', i+1);
@ -66,13 +66,14 @@ define(['uploader'], function(uploader) {
} }
$('#entry-container').sortable({ $('#entry-container').sortable({
stop: function( event, ui ) { stop: function(event, ui) {
updateCategoryOrders(); updateCategoryOrders();
}, },
distance: 10 distance: 10
}); });
$('.blockclass').each(function() { $('.blockclass').each(function() {
$(this).val(this.getAttribute('data-value')); var $this = $(this);
$this.val($this.attr('data-value'));
}); });
@ -115,29 +116,30 @@ define(['uploader'], function(uploader) {
} }
function enableColorPicker(idx, inputEl) { function enableColorPicker(idx, inputEl) {
var jinputEl = $(inputEl), var $inputEl = $(inputEl),
previewEl = jinputEl.parents('[data-cid]').find('.preview-box'); previewEl = $inputEl.parents('[data-cid]').find('.preview-box');
jinputEl.ColorPicker({ $inputEl.ColorPicker({
color: jinputEl.val() || '#000', color: $inputEl.val() || '#000',
onChange: function(hsb, hex) { onChange: function(hsb, hex) {
jinputEl.val('#' + hex); $inputEl.val('#' + hex);
if (inputEl.getAttribute('data-name') === 'bgColor') previewEl.css('background', '#' + hex); if ($inputEl.attr('data-name') === 'bgColor') previewEl.css('background', '#' + hex);
else if (inputEl.getAttribute('data-name') === 'color') previewEl.css('color', '#' + hex); else if ($inputEl.attr('data-name') === 'color') previewEl.css('color', '#' + hex);
modified(inputEl); modified($inputEl[0]);
} }
}); });
} }
$('document').ready(function() { $(function() {
var url = window.location.href, var url = window.location.href,
parts = url.split('/'), parts = url.split('/'),
active = parts[parts.length - 1]; active = parts[parts.length - 1];
$('.nav-pills li').removeClass('active'); $('.nav-pills li').removeClass('active');
$('.nav-pills li a').each(function() { $('.nav-pills li a').each(function() {
if (this.getAttribute('href').match(active)) { var $this = $(this);
$(this.parentNode).addClass('active'); if ($this.attr('href').match(active)) {
$this.parent().addClass('active');
return false; return false;
} }
}); });
@ -159,11 +161,11 @@ define(['uploader'], function(uploader) {
}); });
$('.dropdown').on('click', '[data-disabled]', function(ev) { $('.dropdown').on('click', '[data-disabled]', function(ev) {
var btn = $(this); var btn = $(this),
var categoryRow = btn.parents('li'); categoryRow = btn.parents('li'),
var cid = categoryRow.attr('data-cid'); cid = categoryRow.attr('data-cid'),
disabled = btn.attr('data-disabled') === 'false' ? '1' : '0';
var disabled = this.getAttribute('data-disabled') === 'false' ? '1' : '0';
categoryRow.remove(); categoryRow.remove();
modified_categories[cid] = modified_categories[cid] || {}; modified_categories[cid] = modified_categories[cid] || {};
modified_categories[cid]['disabled'] = disabled; modified_categories[cid]['disabled'] = disabled;
@ -185,14 +187,15 @@ define(['uploader'], function(uploader) {
$('.admin-categories').on('click', '.upload-button', function() { $('.admin-categories').on('click', '.upload-button', function() {
var inputEl = this; var inputEl = $(this),
var cid = $(this).parents('li[data-cid]').attr('data-cid'); cid = inputEl.parents('li[data-cid]').attr('data-cid');
uploader.open(RELATIVE_PATH + '/admin/category/uploadpicture', {cid:cid}, 0, function(imageUrlOnServer) {
inputEl.value = imageUrlOnServer; uploader.open(RELATIVE_PATH + '/admin/category/uploadpicture', {cid: cid}, 0, function(imageUrlOnServer) {
var previewBox = $(inputEl).parents('li[data-cid]').find('.preview-box'); inputEl.val(imageUrlOnServer);
var previewBox = inputEl.parents('li[data-cid]').find('.preview-box');
previewBox.css('background', 'url(' + imageUrlOnServer + '?' + new Date().getTime() + ')') previewBox.css('background', 'url(' + imageUrlOnServer + '?' + new Date().getTime() + ')')
.css('background-size', 'cover'); .css('background-size', 'cover');
modified(inputEl); modified(inputEl[0]);
}); });
}); });
@ -202,12 +205,12 @@ define(['uploader'], function(uploader) {
preview = parent.find('.preview-box'), preview = parent.find('.preview-box'),
bgColor = parent.find('.category_bgColor').val(); bgColor = parent.find('.category_bgColor').val();
inputEl.value = ''; inputEl.val('');
modified(inputEl); modified(inputEl[0]);
preview.css('background', bgColor); preview.css('background', bgColor);
$(this).hide(); $(this).addClass('hide').hide();
}); });
}); });
}; };
@ -221,8 +224,8 @@ define(['uploader'], function(uploader) {
searchEl.off().on('keyup', function() { searchEl.off().on('keyup', function() {
var searchEl = this, var searchEl = this,
resultsFrag = document.createDocumentFragment(), liEl;
liEl = document.createElement('li');
clearTimeout(searchDelay); clearTimeout(searchDelay);
searchDelay = setTimeout(function() { searchDelay = setTimeout(function() {
@ -236,23 +239,21 @@ define(['uploader'], function(uploader) {
var numResults = results.length, var numResults = results.length,
resultObj; resultObj;
for(var x=0;x<numResults;x++) { for(var x = 0; x < numResults; x++) {
resultObj = results[x]; resultObj = results[x];
liEl = $('<li />')
liEl.setAttribute('data-uid', resultObj.uid); .attr('data-uid', resultObj.uid)
liEl.innerHTML = '<div class="pull-right">' + .html('<div class="pull-right">' +
'<div class="btn-group">' + '<div class="btn-group">' +
'<button type="button" data-priv="+r" class="btn btn-default' + (resultObj.privileges['+r'] ? ' active' : '') + '">Read</button>' + '<button type="button" data-priv="+r" class="btn btn-default' + (resultObj.privileges['+r'] ? ' active' : '') + '">Read</button>' +
'<button type="button" data-priv="+w" class="btn btn-default' + (resultObj.privileges['+w'] ? ' active' : '') + '">Write</button>' + '<button type="button" data-priv="+w" class="btn btn-default' + (resultObj.privileges['+w'] ? ' active' : '') + '">Write</button>' +
'<button type="button" data-priv="mods" class="btn btn-default' + (resultObj.privileges['mods'] ? ' active' : '') + '">Moderator</button>' + '<button type="button" data-priv="mods" class="btn btn-default' + (resultObj.privileges['mods'] ? ' active' : '') + '">Moderator</button>' +
'</div>' + '</div>' +
'</div>' + '</div>' +
'<img src="' + resultObj.picture + '" /> ' + resultObj.username; '<img src="' + resultObj.picture + '" /> ' + resultObj.username);
resultsFrag.appendChild(liEl.cloneNode(true)); resultsEl.append(liEl);
} }
resultsEl.html(resultsFrag);
}); });
}, 250); }, 250);
}); });
@ -262,7 +263,7 @@ define(['uploader'], function(uploader) {
resultsEl.off().on('click', '[data-priv]', function(e) { resultsEl.off().on('click', '[data-priv]', function(e) {
var btnEl = $(this), var btnEl = $(this),
uid = btnEl.parents('li[data-uid]').attr('data-uid'), uid = btnEl.parents('li[data-uid]').attr('data-uid'),
privilege = this.getAttribute('data-priv'); privilege = btnEl.attr('data-priv');
e.preventDefault(); e.preventDefault();
socket.emit('admin.categories.setPrivilege', { socket.emit('admin.categories.setPrivilege', {
@ -278,7 +279,7 @@ define(['uploader'], function(uploader) {
}); });
modal.off().on('click', '.members li > img', function() { modal.off().on('click', '.members li > img', function() {
searchEl.val(this.getAttribute('title')); searchEl.val($(this).attr('title'));
searchEl.keyup(); searchEl.keyup();
}); });
@ -287,33 +288,31 @@ define(['uploader'], function(uploader) {
if(err) { if(err) {
return app.alertError(err.message); return app.alertError(err.message);
} }
var groupsFrag = document.createDocumentFragment(), var numResults = results.length,
numResults = results.length, trEl,
trEl = document.createElement('tr'),
resultObj; resultObj;
for(var x=0;x<numResults;x++) { for(var x = 0; x < numResults; x++) {
resultObj = results[x]; resultObj = results[x];
trEl.setAttribute('data-gid', resultObj.gid); trEl = $('<tr />')
trEl.innerHTML = '<td><h4>' + resultObj.name + '</h4></td>' + .attr('data-gid', resultObj.gid)
'<td>' + .html('<td><h4>' + resultObj.name + '</h4></td>' +
'<div class="btn-group pull-right">' + '<td>' +
'<button type="button" data-gpriv="g+r" class="btn btn-default' + (resultObj.privileges['g+r'] ? ' active' : '') + '">Read</button>' + '<div class="btn-group pull-right">' +
'<button type="button" data-gpriv="g+w" class="btn btn-default' + (resultObj.privileges['g+w'] ? ' active' : '') + '">Write</button>' + '<button type="button" data-gpriv="g+r" class="btn btn-default' + (resultObj.privileges['g+r'] ? ' active' : '') + '">Read</button>' +
'</div>' + '<button type="button" data-gpriv="g+w" class="btn btn-default' + (resultObj.privileges['g+w'] ? ' active' : '') + '">Write</button>' +
'</td>'; '</div>' +
'</td>');
groupsFrag.appendChild(trEl.cloneNode(true)); groupsResultsEl.append(trEl);
} }
groupsResultsEl.html(groupsFrag);
}); });
groupsResultsEl.off().on('click', '[data-gpriv]', function(e) { groupsResultsEl.off().on('click', '[data-gpriv]', function(e) {
var btnEl = $(this), var btnEl = $(this),
gid = btnEl.parents('tr[data-gid]').attr('data-gid'), gid = btnEl.parents('tr[data-gid]').attr('data-gid'),
privilege = this.getAttribute('data-gpriv'); privilege = btnEl.attr('data-gpriv');
e.preventDefault(); e.preventDefault();
socket.emit('admin.categories.setGroupPrivilege', { socket.emit('admin.categories.setGroupPrivilege', {
cid: cid, cid: cid,
gid: gid, gid: gid,
@ -324,7 +323,7 @@ define(['uploader'], function(uploader) {
btnEl.toggleClass('active'); btnEl.toggleClass('active');
} }
}); });
}) });
modal.modal(); modal.modal();
}; };
@ -338,57 +337,40 @@ define(['uploader'], function(uploader) {
var readLength = privilegeList['+r'].length, var readLength = privilegeList['+r'].length,
writeLength = privilegeList['+w'].length, writeLength = privilegeList['+w'].length,
modLength = privilegeList['mods'].length, modLength = privilegeList['mods'].length,
readFrag = document.createDocumentFragment(), liEl, x, userObj;
writeFrag = document.createDocumentFragment(),
modFrag = document.createDocumentFragment(),
liEl = document.createElement('li'),
x, userObj;
if (readLength > 0) { if (readLength > 0) {
for(x=0;x<readLength;x++) { for(x = 0; x < readLength; x++) {
userObj = privilegeList['+r'][x]; userObj = privilegeList['+r'][x];
liEl.setAttribute('data-uid', userObj.uid); liEl = $('<li/>').attr('data-uid', userObj.uid).html('<img src="' + userObj.picture + '" title="' + userObj.username + '" />');
readMembers.append(liEl);
liEl.innerHTML = '<img src="' + userObj.picture + '" title="' + userObj.username + '" />';
readFrag.appendChild(liEl.cloneNode(true));
} }
} else { } else {
liEl.className = 'empty'; liEl = $('<li/>').addClass('empty').html('All users can read and see this category');
liEl.innerHTML = 'All users can read and see this category'; readMembers.append(liEl);
readFrag.appendChild(liEl.cloneNode(true));
} }
if (writeLength > 0) { if (writeLength > 0) {
for(x=0;x<writeLength;x++) { for(x=0;x<writeLength;x++) {
userObj = privilegeList['+w'][x]; userObj = privilegeList['+w'][x];
liEl.setAttribute('data-uid', userObj.uid); $('<li />').attr('data-uid', userObj.uid).html('<img src="' + userObj.picture + '" title="' + userObj.username + '" />');
writeMembers.append(liEl);
liEl.innerHTML = '<img src="' + userObj.picture + '" title="' + userObj.username + '" />';
writeFrag.appendChild(liEl.cloneNode(true));
} }
} else { } else {
liEl.className = 'empty'; liEl = $('<li />').addClass('empty').html('All users can write to this category');
liEl.innerHTML = 'All users can write to this category'; writeMembers.append(liEl);
writeFrag.appendChild(liEl.cloneNode(true));
} }
if (modLength > 0) { if (modLength > 0) {
for(x=0;x<modLength;x++) { for(x = 0;x < modLength; x++) {
userObj = privilegeList['mods'][x]; userObj = privilegeList['mods'][x];
liEl.setAttribute('data-uid', userObj.uid); liEl = $('<li />').attr('data-uid', userObj.uid).html('<img src="' + userObj.picture + '" title="' + userObj.username + '" />');
moderatorsEl.append(liEl);
liEl.innerHTML = '<img src="' + userObj.picture + '" title="' + userObj.username + '" />';
modFrag.appendChild(liEl.cloneNode(true));
} }
} else { } else {
liEl.className = 'empty'; liEl = $('<li />').addClass('empty').html('No moderators');
liEl.innerHTML = 'No moderators'; moderatorsEl.appendChild(liEl);
modFrag.appendChild(liEl.cloneNode(true));
} }
readMembers.html(readFrag);
writeMembers.html(writeFrag);
moderatorsEl.html(modFrag);
}); });
}; };

@ -1,18 +1,28 @@
jQuery('document').ready(function() { $(function() {
// On menu click, change "active" state
var menuEl = document.querySelector('.sidebar-nav'), var menuEl = $('.sidebar-nav'),
liEls = menuEl.querySelectorAll('li') liEls = menuEl.find('li'),
parentEl = null; parentEl,
activate = function(li) {
liEls.removeClass('active');
li.addClass('active');
};
menuEl.addEventListener('click', function(e) { // also on ready, check the pathname, maybe it was a page refresh and no item was clicked
parentEl = e.target.parentNode; liEls.each(function(i, li){
if (parentEl.nodeName === 'LI') { li = $(li);
for (var x = 0, numLis = liEls.length; x < numLis; x++) { if ((li.find('a').attr('href') || '').indexOf(location.pathname) >= 0) {
if (liEls[x] !== parentEl) jQuery(liEls[x]).removeClass('active'); activate(li);
else jQuery(parentEl).addClass('active'); }
} });
// On menu click, change "active" state
menuEl.on('click', function(e) {
parentEl = $(e.target).parent();
if (parentEl.is('li')) {
activate(parentEl);
} }
}, false); });
}); });
socket.emit('admin.config.get', function(err, config) { socket.emit('admin.config.get', function(err, config) {

@ -3,9 +3,9 @@ define(function() {
Groups.init = function() { Groups.init = function() {
var yourid = templates.get('yourid'), var yourid = templates.get('yourid'),
createEl = document.getElementById('create'), createEl = $('#create'),
createModal = $('#create-modal'), createModal = $('#create-modal'),
createSubmitBtn = document.getElementById('create-modal-go'), createSubmitBtn = $('#create-modal-go'),
createNameEl = $('#create-group-name'), createNameEl = $('#create-group-name'),
detailsModal = $('#group-details-modal'), detailsModal = $('#group-details-modal'),
detailsSearch = detailsModal.find('#group-details-search'), detailsSearch = detailsModal.find('#group-details-search'),
@ -15,14 +15,14 @@ define(function() {
searchDelay = undefined, searchDelay = undefined,
listEl = $('#groups-list'); listEl = $('#groups-list');
createEl.addEventListener('click', function() { createEl.on('click', function() {
createModal.modal('show'); createModal.modal('show');
setTimeout(function() { setTimeout(function() {
createNameEl.focus(); createNameEl.focus();
}, 250); }, 250);
}, false); });
createSubmitBtn.addEventListener('click', function() { createSubmitBtn.on('click', function() {
var submitObj = { var submitObj = {
name: createNameEl.val(), name: createNameEl.val(),
description: $('#create-group-desc').val() description: $('#create-group-desc').val()
@ -37,7 +37,7 @@ define(function() {
errorText = '<strong>Please choose another name</strong><p>There seems to be a group with this name already.</p>'; errorText = '<strong>Please choose another name</strong><p>There seems to be a group with this name already.</p>';
break; break;
case 'name-too-short': case 'name-too-short':
errorText = '<strong>Please specify a grou name</strong><p>A group name is required for administrative purposes.</p>'; errorText = '<strong>Please specify a group name</strong><p>A group name is required for administrative purposes.</p>';
break; break;
default: default:
errorText = '<strong>Uh-Oh</strong><p>There was a problem creating your group. Please try again later!</p>'; errorText = '<strong>Uh-Oh</strong><p>There was a problem creating your group. Please try again later!</p>';
@ -57,8 +57,9 @@ define(function() {
}); });
listEl.on('click', 'button[data-action]', function() { listEl.on('click', 'button[data-action]', function() {
var action = this.getAttribute('data-action'), var el = $(this),
gid = $(this).parents('li[data-gid]').attr('data-gid'); action = el.attr('data-action'),
gid = el.parents('li[data-gid]').attr('data-gid');
switch (action) { switch (action) {
case 'delete': case 'delete':
@ -80,28 +81,20 @@ define(function() {
var formEl = detailsModal.find('form'), var formEl = detailsModal.find('form'),
nameEl = formEl.find('#change-group-name'), nameEl = formEl.find('#change-group-name'),
descEl = formEl.find('#change-group-desc'), descEl = formEl.find('#change-group-desc'),
memberIcon = document.createElement('li'),
numMembers = groupObj.members.length, numMembers = groupObj.members.length,
membersFrag = document.createDocumentFragment(), x;
memberIconImg, x;
nameEl.val(groupObj.name); nameEl.val(groupObj.name);
descEl.val(groupObj.description); descEl.val(groupObj.description);
// Member list
memberIcon.innerHTML = '<img /><span></span>';
memberIconImg = memberIcon.querySelector('img');
memberIconLabel = memberIcon.querySelector('span');
if (numMembers > 0) { if (numMembers > 0) {
groupMembersEl.empty();
for (x = 0; x < numMembers; x++) { for (x = 0; x < numMembers; x++) {
memberIconImg.src = groupObj.members[x].picture; var memberIcon = $('<li />')
memberIconLabel.innerHTML = groupObj.members[x].username; .append($('<img />').attr('src', groupObj.members[x].picture))
memberIcon.setAttribute('data-uid', groupObj.members[x].uid); .append($('<span />').attr('data-uid', groupObj.members[x].uid).html(groupObj.members[x].username));
membersFrag.appendChild(memberIcon.cloneNode(true)); groupMembersEl.append(memberIcon);
} }
groupMembersEl.html('');
groupMembersEl[0].appendChild(membersFrag);
} }
detailsModal.attr('data-gid', groupObj.gid); detailsModal.attr('data-gid', groupObj.gid);
@ -118,43 +111,39 @@ define(function() {
searchDelay = setTimeout(function() { searchDelay = setTimeout(function() {
var searchText = searchEl.value, var searchText = searchEl.value,
resultsEl = document.getElementById('group-details-search-results'), resultsEl = $('#group-details-search-results'),
foundUser = document.createElement('li'), foundUser;
foundUserImg, foundUserLabel;
foundUser.innerHTML = '<img /><span></span>';
foundUserImg = foundUser.getElementsByTagName('img')[0];
foundUserLabel = foundUser.getElementsByTagName('span')[0];
socket.emit('admin.user.search', searchText, function(err, results) { socket.emit('admin.user.search', searchText, 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;
resultsSlug = document.createDocumentFragment(),
x;
if (numResults > 4) numResults = 4; if (numResults > 4) numResults = 4;
resultsEl.empty();
for (x = 0; x < numResults; x++) { for (x = 0; x < numResults; x++) {
foundUserImg.src = results.users[x].picture; foundUser = $('<li />');
foundUserLabel.innerHTML = results.users[x].username; foundUser
foundUser.setAttribute('title', results.users[x].username); .attr({title: results.users[x].username, 'data-uid': results.users[x].uid})
foundUser.setAttribute('data-uid', results.users[x].uid); .append($('<img />').attr('src', results.users[x].picture))
resultsSlug.appendChild(foundUser.cloneNode(true)); .append($('<span />').html(results.users[x].username));
}
resultsEl.innerHTML = ''; resultsEl.appendChild(foundUser);
resultsEl.appendChild(resultsSlug); }
} else resultsEl.innerHTML = '<li>No Users Found</li>'; } else {
resultsEl.html('<li>No Users Found</li>');
}
}); });
}, 200); }, 200);
}); });
searchResults.on('click', 'li[data-uid]', function() { searchResults.on('click', 'li[data-uid]', function() {
var userLabel = this, var userLabel = $(this),
uid = parseInt(this.getAttribute('data-uid')), uid = parseInt(userLabel.attr('data-uid')),
gid = detailsModal.attr('data-gid'), gid = detailsModal.attr('data-gid'),
members = []; members = [];
groupMembersEl.find('li[data-uid]').each(function() { groupMembersEl.find('li[data-uid]').each(function() {
members.push(parseInt(this.getAttribute('data-uid'))); members.push(parseInt($(this).attr('data-uid')));
}); });
if (members.indexOf(uid) === -1) { if (members.indexOf(uid) === -1) {
@ -170,7 +159,7 @@ define(function() {
}); });
groupMembersEl.on('click', 'li[data-uid]', function() { groupMembersEl.on('click', 'li[data-uid]', function() {
var uid = this.getAttribute('data-uid'), var uid = $(this).attr('data-uid'),
gid = detailsModal.attr('data-gid'); gid = detailsModal.attr('data-gid');
socket.emit('admin.groups.get', gid, function(err, groupObj){ socket.emit('admin.groups.get', gid, function(err, groupObj){

@ -1,5 +1,5 @@
define(['forum/admin/settings'], function(Settings) { define(['forum/admin/settings'], function(Settings) {
jQuery('document').ready(function() { $(function() {
Settings.prepare(); Settings.prepare();
}); });
}); });

@ -15,38 +15,38 @@ define(['uploader'], function(uploader) {
} }
// Populate the fields on the page from the config // Populate the fields on the page from the config
var fields = document.querySelectorAll('#content [data-field]'), var fields = $('#content [data-field]'),
numFields = fields.length, numFields = fields.length,
saveBtn = document.getElementById('save'), saveBtn = $('#save'),
x, key, inputType; x, key, inputType, field;
for (x = 0; x < numFields; x++) { for (x = 0; x < numFields; x++) {
key = fields[x].getAttribute('data-field'); field = fields.eq(x);
inputType = fields[x].getAttribute('type'); key = field.attr('data-field');
if (fields[x].nodeName === 'INPUT') { inputType = field.attr('type');
if (field.is('input')) {
if (app.config[key]) { if (app.config[key]) {
switch (inputType) { switch (inputType) {
case 'text': case 'text':
case 'password': case 'password':
case 'textarea': case 'textarea':
case 'number': case 'number':
fields[x].value = app.config[key]; field.val(app.config[key]);
break; break;
case 'checkbox': case 'checkbox':
fields[x].checked = parseInt(app.config[key], 10) === 1; field.prop('checked', parseInt(app.config[key], 10) === 1);
break; break;
} }
} }
} else if (fields[x].nodeName === 'TEXTAREA') { } else if (field.is('textarea')) {
if (app.config[key]) fields[x].value = app.config[key]; if (app.config[key]) field.val(app.config[key]);
} else if (fields[x].nodeName === 'SELECT') { } else if (field.is('select')) {
if (app.config[key]) fields[x].value = app.config[key]; if (app.config[key]) field.val(app.config[key]);
} }
} }
saveBtn.addEventListener('click', function(e) { saveBtn.on('click', function(e) {
e.preventDefault(); e.preventDefault();
for (x = 0; x < numFields; x++) { for (x = 0; x < numFields; x++) {
@ -55,27 +55,28 @@ define(['uploader'], function(uploader) {
}); });
function saveField(field) { function saveField(field) {
var key = field.getAttribute('data-field'), field = $(field);
var key = field.attr('data-field'),
value; value;
if (field.nodeName === 'INPUT') { if (field.is('input')) {
inputType = field.getAttribute('type'); inputType = field.attr('type');
switch (inputType) { switch (inputType) {
case 'text': case 'text':
case 'password': case 'password':
case 'textarea': case 'textarea':
case 'number': case 'number':
value = field.value; value = field.val();
break; break;
case 'checkbox': case 'checkbox':
value = field.checked ? '1' : '0'; value = field.prop('checked') ? '1' : '0';
break; break;
} }
} else if (field.nodeName === 'TEXTAREA') { } else if (field.is('textarea')) {
value = field.value; value = field.val();
} else if (field.nodeName === 'SELECT') { } else if (field.is('select')) {
value = field.value; value = field.val();
} }
socket.emit('admin.config.set', { socket.emit('admin.config.set', {

@ -2,17 +2,21 @@ define(['forum/admin/settings'], function(Settings) {
var Themes = {}; var Themes = {};
Themes.init = function() { Themes.init = function() {
var scriptEl = document.createElement('script'); var scriptEl = $('<script />');
scriptEl.src = 'http://api.bootswatch.com/3/?callback=bootswatchListener'; scriptEl.attr('src', 'http://api.bootswatch.com/3/?callback=bootswatchListener');
document.body.appendChild(scriptEl); $('body').append(scriptEl);
var bootstrapThemeContainer = $('#bootstrap_themes'),
installedThemeContainer = $('#installed_themes'),
var bootstrapThemeContainer = document.querySelector('#bootstrap_themes'),
installedThemeContainer = document.querySelector('#installed_themes'),
themeEvent = function(e) { themeEvent = function(e) {
if (e.target.hasAttribute('data-action')) { var target = $(e.target),
switch (e.target.getAttribute('data-action')) { action = target.attr('data-action');
if (action) {
switch (action) {
case 'use': case 'use':
var parentEl = $(e.target).parents('li'), var parentEl = target.parents('li'),
themeType = parentEl.attr('data-type'), themeType = parentEl.attr('data-type'),
cssSrc = parentEl.attr('data-css'), cssSrc = parentEl.attr('data-css'),
themeId = parentEl.attr('data-theme'); themeId = parentEl.attr('data-theme');
@ -30,16 +34,15 @@ define(['forum/admin/settings'], function(Settings) {
timeout: 3500 timeout: 3500
}); });
}); });
break; break;
} }
} }
}; };
bootstrapThemeContainer.addEventListener('click', themeEvent); bootstrapThemeContainer.on('click', themeEvent);
installedThemeContainer.addEventListener('click', themeEvent); installedThemeContainer.on('click', themeEvent);
var revertEl = document.getElementById('revert_theme'); $('#revert_theme').on('click', function() {
revertEl.addEventListener('click', function() {
bootbox.confirm('Are you sure you wish to remove the custom theme and restore the NodeBB default theme?', function(confirm) { bootbox.confirm('Are you sure you wish to remove the custom theme and restore the NodeBB default theme?', function(confirm) {
if (confirm) { if (confirm) {
socket.emit('admin.themes.set', { socket.emit('admin.themes.set', {
@ -64,37 +67,32 @@ define(['forum/admin/settings'], function(Settings) {
return app.alertError(err.message); return app.alertError(err.message);
} }
var instListEl = document.getElementById('installed_themes'), var instListEl = $('#installed_themes').empty(), liEl;
themeFrag = document.createDocumentFragment(),
liEl = document.createElement('li');
liEl.setAttribute('data-type', 'local');
if (themes.length > 0) { if (themes.length > 0) {
for (var x = 0, numThemes = themes.length; x < numThemes; x++) { for (var x = 0, numThemes = themes.length; x < numThemes; x++) {
liEl.setAttribute('data-theme', themes[x].id); liEl = $('<li/ >').attr({
liEl.innerHTML = '<img src="' + (themes[x].screenshot ? '/css/previews/' + themes[x].id : RELATIVE_PATH + '/images/themes/default.png') + '" />' + 'data-type': 'local',
'<div>' + 'data-theme': themes[x].id
'<div class="pull-right">' + }).html('<img src="' + (themes[x].screenshot ? '/css/previews/' + themes[x].id : RELATIVE_PATH + '/images/themes/default.png') + '" />' +
'<button class="btn btn-primary" data-action="use">Use</button> ' + '<div>' +
'</div>' + '<div class="pull-right">' +
'<h4>' + themes[x].name + '</h4>' + '<button class="btn btn-primary" data-action="use">Use</button> ' +
'<p>' + '</div>' +
themes[x].description + '<h4>' + themes[x].name + '</h4>' +
(themes[x].url ? ' (<a href="' + themes[x].url + '">Homepage</a>)' : '') + '<p>' +
'</p>' + themes[x].description +
'</div>' + (themes[x].url ? ' (<a href="' + themes[x].url + '">Homepage</a>)' : '') +
'<div class="clear">'; '</p>' +
themeFrag.appendChild(liEl.cloneNode(true)); '</div>' +
'<div class="clear">');
instListEl.append(liEl);
} }
} else { } else {
// No themes found // No themes found
liEl.className = 'no-themes'; instListEl.append($('<li/ >').addClass('no-themes').html('No installed themes found'));
liEl.innerHTML = 'No installed themes found';
themeFrag.appendChild(liEl);
} }
instListEl.innerHTML = '';
instListEl.appendChild(themeFrag);
}); });
// Proper tabbing for "Custom CSS" field // Proper tabbing for "Custom CSS" field
@ -105,34 +103,30 @@ define(['forum/admin/settings'], function(Settings) {
Themes.prepareWidgets(); Themes.prepareWidgets();
Settings.prepare(); Settings.prepare();
} };
Themes.render = function(bootswatch) { Themes.render = function(bootswatch) {
var themeFrag = document.createDocumentFragment(), var themeContainer = $('#bootstrap_themes').empty(),
themeEl = document.createElement('li'), numThemes = bootswatch.themes.length, themeEl, theme;
themeContainer = document.querySelector('#bootstrap_themes'),
numThemes = bootswatch.themes.length;
themeEl.setAttribute('data-type', 'bootswatch');
for (var x = 0; x < numThemes; x++) { for (var x = 0; x < numThemes; x++) {
var theme = bootswatch.themes[x]; theme = bootswatch.themes[x];
themeEl.setAttribute('data-css', theme.cssCdn); themeEl = $('<li />').attr({
themeEl.setAttribute('data-theme', theme.name); 'data-type': 'bootswatch',
themeEl.innerHTML = '<img src="' + theme.thumbnail + '" />' + 'data-css': theme.cssCdn,
'<div>' + 'data-theme': theme.name
'<div class="pull-right">' + }).html('<img src="' + theme.thumbnail + '" />' +
'<button class="btn btn-primary" data-action="use">Use</button> ' + '<div>' +
'</div>' + '<div class="pull-right">' +
'<h4>' + theme.name + '</h4>' + '<button class="btn btn-primary" data-action="use">Use</button> ' +
'<p>' + theme.description + '</p>' + '</div>' +
'</div>' + '<h4>' + theme.name + '</h4>' +
'<div class="clear">'; '<p>' + theme.description + '</p>' +
themeFrag.appendChild(themeEl.cloneNode(true)); '</div>' +
'<div class="clear">');
themeContainer.append(themeEl);
} }
themeContainer.innerHTML = ''; };
themeContainer.appendChild(themeFrag);
}
Themes.prepareWidgets = function() { Themes.prepareWidgets = function() {
$('#widgets .available-widgets .panel').draggable({ $('#widgets .available-widgets .panel').draggable({
@ -167,8 +161,8 @@ define(['forum/admin/settings'], function(Settings) {
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>')
.children('small').html(''); .children('small').html('');
} }
} }
@ -178,18 +172,18 @@ define(['forum/admin/settings'], function(Settings) {
}, },
connectWith: "div" connectWith: "div"
}).on('click', '.toggle-widget', function() { }).on('click', '.toggle-widget', function() {
$(this).parents('.panel').children('.panel-body').toggleClass('hidden'); $(this).parents('.panel').children('.panel-body').toggleClass('hidden');
}).on('click', '.delete-widget', function() { }).on('click', '.delete-widget', function() {
var panel = $(this).parents('.panel'); var panel = $(this).parents('.panel');
bootbox.confirm('Are you sure you wish to delete this widget?', function(confirm) { bootbox.confirm('Are you sure you wish to delete this widget?', function(confirm) {
if (confirm) { if (confirm) {
panel.remove(); panel.remove();
} }
});
}).on('dblclick', '.panel-heading', function() {
$(this).parents('.panel').children('.panel-body').toggleClass('hidden');
}); });
}).on('dblclick', '.panel-heading', function() {
$(this).parents('.panel').children('.panel-body').toggleClass('hidden');
});
$('#widgets .btn[data-template]').on('click', function() { $('#widgets .btn[data-template]').on('click', function() {
var btn = $(this), var btn = $(this),
@ -205,13 +199,13 @@ define(['forum/admin/settings'], function(Settings) {
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) {
widgetData[data[d].name] = data[d].value; widgetData[data[d].name] = data[d].value;
} }
} }
} }
widgets.push({ widgets.push({
widget: this.getAttribute('data-widget'), widget: $(this).attr('data-widget'),
data: widgetData data: widgetData
}); });
}); });
@ -245,7 +239,7 @@ define(['forum/admin/settings'], function(Settings) {
return widget; return widget;
} }
$.get(RELATIVE_PATH + '/api/admin/themes', function(data) { $.get(RELATIVE_PATH + '/api/admin/themes', function(data) {
var areas = data.areas; var areas = data.areas;

@ -2,14 +2,14 @@ define(function() {
var Topics = {}; var Topics = {};
Topics.init = function() { Topics.init = function() {
var topicsListEl = document.querySelector('.topics'), var topicsListEl = $('.topics'),
loadMoreEl = document.getElementById('topics_loadmore'); loadMoreEl = $('#topics_loadmore');
this.resolveButtonStates(); this.resolveButtonStates();
$(topicsListEl).on('click', '[data-action]', function() { topicsListEl.on('click', '[data-action]', function() {
var $this = $(this), var $this = $(this),
action = this.getAttribute('data-action'), action = $this.attr('data-action'),
tid = $this.parents('[data-tid]').attr('data-tid'); tid = $this.parents('[data-tid]').attr('data-tid');
switch (action) { switch (action) {
@ -40,17 +40,17 @@ define(function() {
} }
}); });
loadMoreEl.addEventListener('click', function() { loadMoreEl.on('click', function() {
if (this.className.indexOf('disabled') === -1) { if (!$(this).hasClass('disabled')) {
var topics = document.querySelectorAll('.topics li[data-tid]'); var topics = $('.topics li[data-tid]');
if(!topics.length) { if(!topics.length) {
return; return;
} }
var lastTid = parseInt(topics[topics.length - 1].getAttribute('data-tid')); var lastTid = parseInt(topics.eq(topics.length - 1).attr('data-tid'));
this.innerHTML = '<i class="fa fa-refresh fa-spin"></i> Retrieving topics'; $(this).html('<i class="fa fa-refresh fa-spin"></i> Retrieving topics');
socket.emit('admin.topics.getMore', { socket.emit('admin.topics.getMore', {
limit: 10, limit: 10,
after: lastTid after: lastTid
@ -59,27 +59,27 @@ define(function() {
return app.alertError(err.message); return app.alertError(err.message);
} }
var btnEl = document.getElementById('topics_loadmore'); var btnEl = $('#topics_loadmore');
if (topics.length > 0) { if (topics.length > 0) {
var html = templates.prepare(templates['admin/topics'].blocks['topics']).parse({ var html = templates.prepare(templates['admin/topics'].blocks['topics']).parse({
topics: topics topics: topics
}), }),
topicsListEl = document.querySelector('.topics'); topicsListEl = $('.topics');
// Fix relative paths // Fix relative paths
html = html.replace(/\{relative_path\}/g, RELATIVE_PATH); html = html.replace(/\{relative_path\}/g, RELATIVE_PATH);
topicsListEl.innerHTML += html; topicsListEl.html(topicsListEl.html() + html);
Topics.resolveButtonStates(); Topics.resolveButtonStates();
btnEl.innerHTML = 'Load More Topics'; btnEl.html('Load More Topics');
$('span.timeago').timeago(); $('span.timeago').timeago();
} else { } else {
// Exhausted all topics // Exhausted all topics
btnEl.className += ' disabled'; btnEl.addClass('disabled');
btnEl.innerHTML = 'No more topics'; btnEl.html('No more topics');
} }
}); });
} }
@ -88,24 +88,26 @@ define(function() {
Topics.resolveButtonStates = function() { Topics.resolveButtonStates = function() {
// Resolve proper button state for all topics // Resolve proper button state for all topics
var topicsListEl = document.querySelector('.topics'), var topicsListEl = $('.topics'),
topicEls = topicsListEl.querySelectorAll('li'), topicEls = topicsListEl.find('li'),
numTopics = topicEls.length; numTopics = topicEls.length;
for (var x = 0; x < numTopics; x++) { for (var x = 0; x < numTopics; x++) {
if (topicEls[x].getAttribute('data-pinned') === '1') { var topic = topicEls.eq(x);
topicEls[x].querySelector('[data-action="pin"]').className += ' active'; if (topic.attr('data-pinned') === '1') {
topicEls[x].removeAttribute('data-pinned'); topic.find('[data-action="pin"]').addClass('active');
topic.removeAttr('data-pinned');
} }
if (topicEls[x].getAttribute('data-locked') === '1') { if (topic.attr('data-locked') === '1') {
topicEls[x].querySelector('[data-action="lock"]').className += ' active'; topic.find('[data-action="lock"]').addClass('active');
topicEls[x].removeAttribute('data-locked'); topic.removeAttr('data-locked');
} }
if (topicEls[x].getAttribute('data-deleted') === '1') { if (topic.attr('data-deleted') === '1') {
topicEls[x].querySelector('[data-action="delete"]').className += ' active'; topic.find('[data-action="delete"]').addClass('active');
topicEls[x].removeAttribute('data-deleted'); topic.removeAttr('data-deleted');
} }
} }
} };
Topics.setDeleted = function(err, response) { Topics.setDeleted = function(err, response) {
if(err) { if(err) {
@ -113,10 +115,9 @@ define(function() {
} }
if (response && response.tid) { if (response && response.tid) {
var btnEl = document.querySelector('li[data-tid="' + response.tid + '"] button[data-action="delete"]'); var btnEl = $('li[data-tid="' + response.tid + '"] button[data-action="delete"]');
btnEl.addClass('active');
$(btnEl).addClass('active'); btnEl.siblings('[data-action="lock"]').addClass('active');
$(btnEl).siblings('[data-action="lock"]').addClass('active');
} }
}; };
@ -126,10 +127,10 @@ define(function() {
} }
if (response && response.tid) { if (response && response.tid) {
var btnEl = document.querySelector('li[data-tid="' + response.tid + '"] button[data-action="delete"]'); var btnEl = $('li[data-tid="' + response.tid + '"] button[data-action="delete"]');
$(btnEl).removeClass('active'); btnEl.removeClass('active');
$(btnEl).siblings('[data-action="lock"]').removeClass('active'); btnEl.siblings('[data-action="lock"]').removeClass('active');
} }
}; };
@ -139,9 +140,9 @@ define(function() {
} }
if (response && response.tid) { if (response && response.tid) {
var btnEl = document.querySelector('li[data-tid="' + response.tid + '"] button[data-action="lock"]'); var btnEl = $('li[data-tid="' + response.tid + '"] button[data-action="lock"]');
$(btnEl).addClass('active'); btnEl.addClass('active');
} }
}; };
@ -151,9 +152,9 @@ define(function() {
} }
if (response && response.tid) { if (response && response.tid) {
var btnEl = document.querySelector('li[data-tid="' + response.tid + '"] button[data-action="lock"]'); var btnEl = $('li[data-tid="' + response.tid + '"] button[data-action="lock"]');
$(btnEl).removeClass('active'); btnEl.removeClass('active');
} }
}; };
@ -164,9 +165,9 @@ define(function() {
} }
if (response && response.tid) { if (response && response.tid) {
var btnEl = document.querySelector('li[data-tid="' + response.tid + '"] button[data-action="pin"]'); var btnEl = $('li[data-tid="' + response.tid + '"] button[data-action="pin"]');
$(btnEl).removeClass('active'); btnEl.removeClass('active');
} }
}; };
@ -176,9 +177,9 @@ define(function() {
} }
if (response && response.tid) { if (response && response.tid) {
var btnEl = document.querySelector('li[data-tid="' + response.tid + '"] button[data-action="pin"]'); var btnEl = $('li[data-tid="' + response.tid + '"] button[data-action="pin"]');
$(btnEl).addClass('active'); btnEl.addClass('active');
} }
}; };

@ -156,7 +156,7 @@ define(function() {
} }
jQuery('document').ready(function() { $('document').ready(function() {
var timeoutId = 0, var timeoutId = 0,
loadingMoreUsers = false; loadingMoreUsers = false;
@ -165,15 +165,16 @@ define(function() {
parts = url.split('/'), parts = url.split('/'),
active = parts[parts.length - 1]; active = parts[parts.length - 1];
jQuery('.nav-pills li').removeClass('active'); $('.nav-pills li').removeClass('active');
jQuery('.nav-pills li a').each(function() { $('.nav-pills li a').each(function() {
if (this.getAttribute('href').match(active)) { var $this = $(this);
jQuery(this.parentNode).addClass('active'); if ($this.attr('href').match(active)) {
$this.parent().addClass('active');
return false; return false;
} }
}); });
jQuery('#search-user').on('keyup', function() { $('#search-user').on('keyup', function() {
if (timeoutId !== 0) { if (timeoutId !== 0) {
clearTimeout(timeoutId); clearTimeout(timeoutId);
timeoutId = 0; timeoutId = 0;
@ -182,7 +183,7 @@ define(function() {
timeoutId = setTimeout(function() { timeoutId = setTimeout(function() {
var username = $('#search-user').val(); var username = $('#search-user').val();
jQuery('.fa-spinner').removeClass('none'); $('.fa-spinner').removeClass('none');
socket.emit('admin.user.search', username, function(err, data) { socket.emit('admin.user.search', username, function(err, data) {
if(err) { if(err) {
@ -195,7 +196,7 @@ define(function() {
userListEl = document.querySelector('.users'); userListEl = document.querySelector('.users');
userListEl.innerHTML = html; userListEl.innerHTML = html;
jQuery('.fa-spinner').addClass('none'); $('.fa-spinner').addClass('none');
if (data && data.users.length === 0) { if (data && data.users.length === 0) {
$('#user-notfound-notify').html('User not found!') $('#user-notfound-notify').html('User not found!')

@ -65,8 +65,8 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
topics = $('#topics-container').children('.category-item'), topics = $('#topics-container').children('.category-item'),
numTopics = topics.length; numTopics = topics.length;
jQuery('#topics-container, .category-sidebar').removeClass('hidden'); $('#topics-container, .category-sidebar').removeClass('hidden');
jQuery('#category-no-topics').remove(); $('#category-no-topics').remove();
if (numTopics > 0) { if (numTopics > 0) {
for (var x = 0; x < numTopics; x++) { for (var x = 0; x < numTopics; x++) {
@ -104,8 +104,8 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
translator.translate(html, function(translatedHTML) { translator.translate(html, function(translatedHTML) {
var container = $('#topics-container'); var container = $('#topics-container');
jQuery('#topics-container, .category-sidebar').removeClass('hidden'); $('#topics-container, .category-sidebar').removeClass('hidden');
jQuery('#category-no-topics').remove(); $('#category-no-topics').remove();
html = $(translatedHTML); html = $(translatedHTML);

@ -9,13 +9,17 @@ define(['notifications', 'chat'], function(Notifications, Chat) {
translator.prepareDOM(); translator.prepareDOM();
function updateUnreadCount(err, tids) { function updateUnreadCount(err, tids) {
var count = 0; var count = 0, unreadEl = $('#unread-count');
if(tids && tids.length) {
if (err) {
console.warn('Error updating unread count', err);
} else if(tids && tids.length) {
count = tids.length; count = tids.length;
} }
$('#unread-count').toggleClass('unread-count', count > 0); unreadEl
$('#unread-count').attr('data-content', count > 20 ? '20+' : count); .toggleClass('unread-count', count > 0)
.attr('data-content', count > 20 ? '20+' : count);
} }

@ -52,7 +52,7 @@ define(function() {
return false; return false;
}); });
document.querySelector('#content input').focus(); $('#content input').focus();
}; };
return Login; return Login;

@ -38,10 +38,11 @@ define(function() {
Recent.selectActivePill = function() { Recent.selectActivePill = function() {
var active = getActiveSection(); var active = getActiveSection();
jQuery('.nav-pills li').removeClass('active'); $('.nav-pills li').removeClass('active');
jQuery('.nav-pills li a').each(function() { $('.nav-pills li a').each(function() {
if (this.getAttribute('href').match(active)) { var $this = $(this);
jQuery(this.parentNode).addClass('active'); if ($this.attr('href').match(active)) {
$this.parent().addClass('active');
return false; return false;
} }
}); });

@ -93,7 +93,7 @@ define(function() {
} }
username.on('keyup', function() { username.on('keyup', function() {
jQuery('#yourUsername').html(this.value.length > 0 ? this.value : 'username'); $('#yourUsername').html(this.value.length > 0 ? this.value : 'username');
}); });
username.on('blur', function() { username.on('blur', function() {

@ -2,30 +2,29 @@ define(function() {
var ResetPassword = {}; var ResetPassword = {};
ResetPassword.init = function() { ResetPassword.init = function() {
var inputEl = document.getElementById('email'), var inputEl = $('#email'),
errorEl = document.getElementById('error'), errorEl = $('#error'),
errorTextEl = errorEl.querySelector('p'); successEl = $('#success'),
errorTextEl = errorEl.find('p');
document.getElementById('reset').onclick = function() { $('#reset').onclick = function() {
if (inputEl.value.length > 0 && inputEl.value.indexOf('@') !== -1) { if (inputEl.val() && inputEl.val().indexOf('@') !== -1) {
socket.emit('user.reset.send', { socket.emit('user.reset.send', {
email: inputEl.value email: inputEl.val()
}, function(err, data) { }, function(err, data) {
if(err) { if(err) {
return app.alertError(err.message); return app.alertError(err.message);
} }
var submitEl = document.getElementById('reset'); errorEl.addClass('hide').hide();
successEl.removeClass('hide').show();
jQuery('#error').hide(); successEl.find('p').html('An email has been dispatched to "' + inputEl.val() + '" with instructions on setting a new password.');
jQuery('#success').show(); inputEl.val('');
jQuery('#success p').html('An email has been dispatched to "' + inputEl.value + '" with instructions on setting a new password.');
inputEl.value = '';
}); });
} else { } else {
jQuery('#success').hide(); successEl.addClass('hide').hide();
jQuery(errorEl).show(); errorEl.removeClass('hide').show();
errorTextEl.innerHTML = 'Please enter a valid email'; errorTextEl.html('Please enter a valid email');
} }
}; };
}; };

@ -4,34 +4,33 @@ define(function() {
ResetCode.init = function() { ResetCode.init = function() {
var reset_code = templates.get('reset_code'); var reset_code = templates.get('reset_code');
var resetEl = document.getElementById('reset'), var resetEl = $('#reset'),
password = document.getElementById('password'), password = $('#password'),
repeat = document.getElementById('repeat'), repeat = $('#repeat'),
noticeEl = document.getElementById('notice'); noticeEl = $('#notice');
resetEl.addEventListener('click', function() { resetEl.on('click', function() {
if (password.value.length < 6) { if (password.val().length < 6) {
$('#error').hide(); $('#error').addClass('hide').hide();
noticeEl.querySelector('strong').innerHTML = 'Invalid Password'; noticeEl.find('strong').html('Invalid Password');
noticeEl.querySelector('p').innerHTML = 'The password entered is too short, please pick a different password.'; noticeEl.find('p').html('The password entered is too short, please pick a different password.');
noticeEl.style.display = 'block'; noticeEl.removeClass('hide').css({display: 'block'});
} else if (password.value !== repeat.value) { } else if (password.value !== repeat.value) {
$('#error').hide(); $('#error').hide();
noticeEl.querySelector('strong').innerHTML = 'Invalid Password'; noticeEl.find('strong').html('Invalid Password');
noticeEl.querySelector('p').innerHTML = 'The two passwords you\'ve entered do not match.'; noticeEl.find('p').html('The two passwords you\'ve entered do not match.');
noticeEl.style.display = 'block'; noticeEl.removeClass('hide').css({display: 'block'});
} else { } else {
socket.emit('user.reset.commit', { socket.emit('user.reset.commit', {
code: reset_code, code: reset_code,
password: password.value password: password.val()
}, function(err) { }, function(err) {
if(err) { if(err) {
return app.alert(err.message); return app.alert(err.message);
} }
$('#error').addClass('hide').hide();
$('#error').hide(); $('#notice').addClass('hide').hide();
$('#notice').hide(); $('#success').removeClass('hide').addClass('show').show();
$('#success').show();
}); });
} }
}, false); }, false);
@ -47,10 +46,10 @@ define(function() {
if (valid) { if (valid) {
resetEl.disabled = false; resetEl.disabled = false;
} else { } else {
var formEl = document.getElementById('reset-form'); var formEl = $('#reset-form');
// Show error message // Show error message
$('#error').show(); $('#error').show();
formEl.parentNode.removeChild(formEl); formEl.remove();
} }
}); });
}; };

@ -19,7 +19,6 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
}); });
Topic.init = function() { Topic.init = function() {
var expose_tools = templates.get('expose_tools'), var expose_tools = templates.get('expose_tools'),
tid = templates.get('topic_id'), tid = templates.get('topic_id'),
thread_state = { thread_state = {
@ -36,17 +35,16 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
$(window).trigger('action:topic.loading'); $(window).trigger('action:topic.loading');
function fixDeleteStateForPosts() { function fixDeleteStateForPosts() {
var postEls = document.querySelectorAll('#post-container li[data-deleted]'); var postEls = $('#post-container li[data-deleted]');
for (var x = 0, numPosts = postEls.length; x < numPosts; x++) { for (var x = 0, numPosts = postEls.length; x < numPosts; x++) {
if (postEls[x].getAttribute('data-deleted') === '1') { if (postEls.eq(x).attr('data-deleted') === '1') {
toggle_post_delete_state(postEls[x].getAttribute('data-pid')); toggle_post_delete_state(postEls.eq(x).attr('data-pid'));
} }
postEls[x].removeAttribute('data-deleted'); postEls.eq(x).removeAttr('data-deleted');
} }
} }
jQuery('document').ready(function() { $(function() {
app.addCommasToNumbers(); app.addCommasToNumbers();
app.enterRoom('topic_' + tid); app.enterRoom('topic_' + tid);
@ -112,54 +110,54 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
btn.parents('.thread-tools.open').find('.dropdown-toggle').trigger('click'); btn.parents('.thread-tools.open').find('.dropdown-toggle').trigger('click');
}); });
return false; return false;
}) });
moveThreadModal.on('shown.bs.modal', function() { moveThreadModal.on('shown.bs.modal', function() {
var loadingEl = document.getElementById('categories-loading'); var loadingEl = $('#categories-loading');
if (loadingEl) { if (loadingEl.length) {
socket.emit('categories.get', function(err, data) { socket.emit('categories.get', function(err, data) {
// Render categories // Render categories
var categoriesFrag = document.createDocumentFragment(), var categoryEl,
categoryEl = document.createElement('li'),
numCategories = data.categories.length, numCategories = data.categories.length,
modalBody = moveThreadModal.find('.modal-body'), modalBody = moveThreadModal.find('.modal-body'),
categoriesEl = modalBody[0].getElementsByTagName('ul')[0], categoriesEl = modalBody.find('ul').eq(0).addClass('categories-list'),
confirmDiv = document.getElementById('move-confirm'), confirmDiv = $('#move-confirm'),
confirmCat = confirmDiv.getElementsByTagName('span')[0], confirmCat = confirmDiv.find('span').eq(0),
commitEl = document.getElementById('move_thread_commit'), commitEl = $('#move_thread_commit'),
cancelEl = document.getElementById('move_thread_cancel'), cancelEl = $('#move_thread_cancel'),
x, info, targetCid, targetCatLabel; x, info, targetCid, targetCatLabel;
categoriesEl.className = 'category-list';
for (x = 0; x < numCategories; x++) { for (x = 0; x < numCategories; x++) {
info = data.categories[x]; info = data.categories[x];
categoryEl.style.background = info.bgColor; categoryEl = $('<li />');
categoryEl.style.color = info.color || '#fff'; categoryEl.css({background: info.bgColor, color: info.color || '#fff'})
categoryEl.className = info.disabled === '1' ? ' disabled' : ''; .addClass(info.disabled === '1' ? ' disabled' : '')
categoryEl.innerHTML = '<i class="fa ' + info.icon + '"></i> ' + info.name; .attr('data-cid', info.cid)
categoryEl.setAttribute('data-cid', info.cid); .html('<i class="fa ' + info.icon + '"></i> ' + info.name);
categoriesFrag.appendChild(categoryEl.cloneNode(true));
categoriesEl.append(categoryEl);
} }
categoriesEl.appendChild(categoriesFrag); loadingEl.remove();
modalBody[0].removeChild(loadingEl);
categoriesEl.on('click', function(e) {
categoriesEl.addEventListener('click', function(e) { var el = $(e.target);
if (e.target.nodeName === 'LI') { if (el.is('li')) {
confirmCat.innerHTML = e.target.innerHTML; confirmCat.html(e.target.innerHTML);
confirmDiv.style.display = 'block'; confirmDiv.css({display: 'block'});
targetCid = e.target.getAttribute('data-cid'); targetCid = el.attr('data-cid');
targetCatLabel = e.target.innerHTML; targetCatLabel = e.html();
commitEl.disabled = false; commitEl.prop('disabled', false);
} }
}, false); }, false);
commitEl.addEventListener('click', function() { commitEl.on('click', function() {
if (!commitEl.disabled && targetCid) { if (!commitEl.prop('disabled') && targetCid) {
commitEl.disabled = true; commitEl.prop('disabled', true);
$(cancelEl).fadeOut(250); cancelEl.fadeOut(250);
$(moveThreadModal).find('.modal-header button').fadeOut(250); moveThreadModal.find('.modal-header button').fadeOut(250);
commitEl.innerHTML = 'Moving <i class="fa-spin fa-refresh"></i>'; commitEl.html('Moving <i class="fa-spin fa-refresh"></i>');
socket.emit('topics.move', { socket.emit('topics.move', {
tid: tid, tid: tid,
@ -195,10 +193,10 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
var forkModal = $('#fork-thread-modal'), var forkModal = $('#fork-thread-modal'),
forkCommit = forkModal.find('#fork_thread_commit'); forkCommit = forkModal.find('#fork_thread_commit');
forkModal.removeClass('hide'); forkModal.removeClass('hide');
forkModal.css("position", "fixed") forkModal.css('position', 'fixed')
.css("left", Math.max(0, (($(window).width() - $(forkModal).outerWidth()) / 2) + $(window).scrollLeft()) + "px") .css('left', Math.max(0, (($(window).width() - $(forkModal).outerWidth()) / 2) + $(window).scrollLeft()) + 'px')
.css("top", "0px") .css('top', '0px')
.css("z-index", "2000"); .css('z-index', '2000');
showNoPostsSelected(); showNoPostsSelected();
@ -259,7 +257,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
function closeForkModal() { function closeForkModal() {
for(var i=0; i<pids.length; ++i) { for(var i=0; i<pids.length; ++i) {
$('#post-container li[data-pid="' + pids[i] + '"]').css('opacity', 1.0); $('#post-container li[data-pid="' + pids[i] + '"]').css('opacity', 1);
} }
forkModal.addClass('hide'); forkModal.addClass('hide');
$('#post-container').off('click', 'li'); $('#post-container').off('click', 'li');
@ -381,7 +379,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
$('.topic').on('click', '.post_reply', function() { $('.topic').on('click', '.post_reply', function() {
var selectionText = '', var selectionText = '',
selection = window.getSelection() || document.getSelection(); selection = window.getSelection ? window.getSelection() : document.selection.createRange();
if ($(selection.baseNode).parents('.post-content').length > 0) { if ($(selection.baseNode).parents('.post-content').length > 0) {
var snippet = selection.toString(); var snippet = selection.toString();
@ -733,7 +731,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
for (var p in posts) { for (var p in posts) {
if (posts.hasOwnProperty(p)) { if (posts.hasOwnProperty(p)) {
var post = posts[p], var post = posts[p],
postcount = jQuery('.user_postcount_' + post.uid), postcount = $('.user_postcount_' + post.uid),
ptotal = parseInt(postcount.html(), 10); ptotal = parseInt(postcount.html(), 10);
ptotal += 1; ptotal += 1;
@ -1049,8 +1047,6 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
history.replaceState({ history.replaceState({
url: window.location.pathname.slice(1) + '#' + el.attr('data-pid') url: window.location.pathname.slice(1) + '#' + el.attr('data-pid')
}, null, newUrl); }, null, newUrl);
} else {
location.hash = '#' + el.attr('data-pid');
} }
currentUrl = newUrl; currentUrl = newUrl;
} }
@ -1139,7 +1135,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
} }
} }
} }
} };
function onNewPostPagination(data) { function onNewPostPagination(data) {
var posts = data.posts; var posts = data.posts;

@ -18,15 +18,16 @@ define(function() {
app.addCommasToNumbers(); app.addCommasToNumbers();
jQuery('.nav-pills li').removeClass('active'); $('.nav-pills li').removeClass('active');
jQuery('.nav-pills li a').each(function() { $('.nav-pills li a').each(function() {
if (this.getAttribute('href').match(active)) { var $this = $(this);
jQuery(this.parentNode).addClass('active'); if ($this.attr('href').match(active)) {
$this.parent().addClass('active');
return false; return false;
} }
}); });
jQuery('#search-user').on('keyup', function() { $('#search-user').on('keyup', function() {
if (timeoutId !== 0) { if (timeoutId !== 0) {
clearTimeout(timeoutId); clearTimeout(timeoutId);
timeoutId = 0; timeoutId = 0;
@ -36,15 +37,15 @@ define(function() {
var username = $('#search-user').val(); var username = $('#search-user').val();
if (username == '') { if (username == '') {
jQuery('#user-notfound-notify').html('<i class="fa fa-circle-o"></i>'); $('#user-notfound-notify').html('<i class="fa fa-circle-o"></i>');
jQuery('#user-notfound-notify').parent().removeClass('btn-warning label-warning btn-success label-success'); $('#user-notfound-notify').parent().removeClass('btn-warning label-warning btn-success label-success');
return; return;
} }
if (lastSearch === username) return; if (lastSearch === username) return;
lastSearch = username; lastSearch = username;
jQuery('#user-notfound-notify').html('<i class="fa fa-spinner fa-spin"></i>'); $('#user-notfound-notify').html('<i class="fa fa-spinner fa-spin"></i>');
setTimeout(function() { setTimeout(function() {
socket.emit('user.search', username, function(err, data) { socket.emit('user.search', username, function(err, data) {

@ -14,30 +14,32 @@ define(['taskbar', 'string'], function(taskbar, S) {
} }
socket.emit('modules.chats.list', function(err, chats) { socket.emit('modules.chats.list', function(err, chats) {
var chatsFrag = document.createDocumentFragment(), var numChats = chats.length,
chatEl = document.createElement('li'), chatEl, x, userObj;
numChats = chats.length, chatsListEl.empty();
x, userObj;
if (!err && numChats > 0) { if (!err && numChats > 0) {
for(x=0;x<numChats;x++) {
userObj = chats[x];
chatEl.setAttribute('data-uid', userObj.uid);
chatEl.innerHTML = '<a href="javascript:app.openChat(\'' + userObj.username + '\', ' + userObj.uid + ');"><img src="' + userObj.picture + '" title="' + userObj.username + '" />' + userObj.username + '</a>';
chatsFrag.appendChild(chatEl.cloneNode(true)); for(x = 0;x < numChats; x++) {
userObj = chats[x];
chatEl = $('<li />')
.attr('data-uid', userObj.uid)
.html('<a href="javascript:app.openChat(\''
+ userObj.username
+ '\', ' + userObj.uid
+ ');"><img src="'
+ userObj.picture
+ '" title="'
+ userObj.username
+ '" />' + userObj.username + '</a>');
chatsListEl.append(chatEl);
} }
chatsListEl.empty();
chatsListEl.html(chatsFrag);
} else { } else {
translator.get('modules:chat.no_active', function(str) { translator.get('modules:chat.no_active', function(str) {
chatEl.className = 'no_active'; chatEl = $('<li />')
chatEl.innerHTML = '<a href="#">' + str + '</a>'; .addClass('no_active')
chatsFrag.appendChild(chatEl.cloneNode(true)); .html('<a href="#">' + str + '</a>');
chatsListEl.append(chatEl);
chatsListEl.empty();
chatsListEl.html(chatsFrag);
}); });
} }
}); });
@ -79,15 +81,15 @@ define(['taskbar', 'string'], function(taskbar, S) {
} }
}); });
chatModal.css('zIndex', topZ + 1); chatModal.css('zIndex', topZ + 1);
} };
module.getModal = function(touid) { module.getModal = function(touid) {
return $('#chat-modal-' + touid); return $('#chat-modal-' + touid);
} };
module.modalExists = function(touid) { module.modalExists = function(touid) {
return $('#chat-modal-' + touid).length !== 0; return $('#chat-modal-' + touid).length !== 0;
} };
function checkStatus(chatModal) { function checkStatus(chatModal) {
socket.emit('user.isOnline', chatModal.touid, function(err, data) { socket.emit('user.isOnline', chatModal.touid, function(err, data) {
@ -162,7 +164,7 @@ define(['taskbar', 'string'], function(taskbar, S) {
callback(chatModal); callback(chatModal);
}); });
}); });
} };
module.center = function(chatModal) { module.center = function(chatModal) {
chatModal.css("left", Math.max(0, (($(window).width() - $(chatModal).outerWidth()) / 2) + $(window).scrollLeft()) + "px"); chatModal.css("left", Math.max(0, (($(window).width() - $(chatModal).outerWidth()) / 2) + $(window).scrollLeft()) + "px");
@ -170,7 +172,7 @@ define(['taskbar', 'string'], function(taskbar, S) {
chatModal.css("zIndex", 2000); chatModal.css("zIndex", 2000);
chatModal.find('#chat-message-input').focus(); chatModal.find('#chat-message-input').focus();
return chatModal; return chatModal;
} };
module.load = function(uuid) { module.load = function(uuid) {
var chatModal = $('div[UUID="'+uuid+'"]'); var chatModal = $('div[UUID="'+uuid+'"]');
@ -180,7 +182,7 @@ define(['taskbar', 'string'], function(taskbar, S) {
scrollToBottom(chatModal.find('#chat-content')); scrollToBottom(chatModal.find('#chat-content'));
module.center(chatModal); module.center(chatModal);
module.bringModalToTop(chatModal); module.bringModalToTop(chatModal);
} };
module.minimize = function(uuid) { module.minimize = function(uuid) {
var chatModal = $('div[UUID="'+uuid+'"]'); var chatModal = $('div[UUID="'+uuid+'"]');
@ -188,7 +190,7 @@ define(['taskbar', 'string'], function(taskbar, S) {
taskbar.minimize('chat', uuid); taskbar.minimize('chat', uuid);
clearInterval(chatModal.intervalId); clearInterval(chatModal.intervalId);
chatModal.intervalId = 0; chatModal.intervalId = 0;
} };
function getChatMessages(chatModal, callback) { function getChatMessages(chatModal, callback) {
socket.emit('modules.chats.get', {touid:chatModal.touid}, function(err, messages) { socket.emit('modules.chats.get', {touid:chatModal.touid}, function(err, messages) {

@ -4,6 +4,18 @@ define(['taskbar'], function(taskbar) {
posts: {} posts: {}
}; };
function maybeParse(response) {
if (typeof response == 'string') {
try {
return $.parseJSON(response);
} catch (e) {
return {status: 500, message: 'Something went wrong while parsing server response'}
}
}
return response;
}
function resetInputFile($el) { function resetInputFile($el) {
$el.wrap('<form />').closest('form').get(0).reset(); $el.wrap('<form />').closest('form').get(0).reset();
$el.unwrap(); $el.unwrap();
@ -44,9 +56,9 @@ define(['taskbar'], function(taskbar) {
//http://stackoverflow.com/questions/14441456/how-to-detect-which-device-view-youre-on-using-twitter-bootstrap-api //http://stackoverflow.com/questions/14441456/how-to-detect-which-device-view-youre-on-using-twitter-bootstrap-api
function findBootstrapEnvironment() { function findBootstrapEnvironment() {
var envs = ['xs', 'sm', 'md', 'lg']; var envs = ['xs', 'sm', 'md', 'lg'],
$el = $('<div>');
$el = $('<div>');
$el.appendTo($('body')); $el.appendTo($('body'));
for (var i = envs.length - 1; i >= 0; i--) { for (var i = envs.length - 1; i >= 0; i--) {
@ -73,8 +85,8 @@ define(['taskbar'], function(taskbar) {
function initializeDragAndDrop(post_uuid) { function initializeDragAndDrop(post_uuid) {
if(jQuery.event.props.indexOf('dataTransfer') === -1) { if($.event.props.indexOf('dataTransfer') === -1) {
jQuery.event.props.push('dataTransfer'); $.event.props.push('dataTransfer');
} }
var draggingDocument = false; var draggingDocument = false;
@ -88,7 +100,7 @@ define(['taskbar'], function(taskbar) {
$(document).off('dragstart').on('dragstart', function(e) { $(document).off('dragstart').on('dragstart', function(e) {
draggingDocument = true; draggingDocument = true;
}).off('dragend').on('dragend', function(e) { }).off('dragend').on('dragend', function(e) {
draggingDocument = false; draggingDocument = false;
}); });
textarea.on('dragenter', function(e) { textarea.on('dragenter', function(e) {
@ -116,17 +128,24 @@ define(['taskbar'], function(taskbar) {
drop.on('drop', function(e) { drop.on('drop', function(e) {
e.preventDefault(); e.preventDefault();
var dt = e.dataTransfer, var files = e.files || (e.dataTransfer || {}).files || (e.target.value ? [e.target.value] : []),
files = dt.files; fd;
if(files.length) { if(files.length) {
var fd = new FormData(); if (window.FormData) {
for (var i = 0, file; file = dt.files[i]; i++) { fd = new FormData();
fd.append('files[]', file, file.name); for (var i = 0, file; file = files[i]; i++) {
fd.append('files[]', file, file.name);
}
} }
fileForm[0].reset(); // fileForm[0].reset();
uploadContentFiles({files: files, post_uuid: post_uuid, route: '/api/post/upload', formData: fd}); uploadContentFiles({
files: files,
post_uuid: post_uuid,
route: '/api/post/upload',
formData: fd
});
} }
drop.hide(); drop.hide();
@ -135,7 +154,8 @@ define(['taskbar'], function(taskbar) {
$(window).off('paste').on('paste', function(event) { $(window).off('paste').on('paste', function(event) {
var items = (event.clipboardData || event.originalEvent.clipboardData).items; var items = (event.clipboardData || event.originalEvent.clipboardData || {}).items,
fd;
if(items && items.length) { if(items && items.length) {
@ -143,11 +163,18 @@ define(['taskbar'], function(taskbar) {
if(blob) { if(blob) {
blob.name = 'upload-'+ utils.generateUUID(); blob.name = 'upload-'+ utils.generateUUID();
var fd = new FormData(); if (window.FormData) {
fd.append('files[]', blob, blob.name); fd = new FormData();
fd.append('files[]', blob, blob.name);
}
fileForm[0].reset(); // fileForm[0].reset();
uploadContentFiles({files: [blob], post_uuid: post_uuid, route: '/api/post/upload', formData: fd}); uploadContentFiles({
files: [blob],
post_uuid: post_uuid,
route: '/api/post/upload',
formData: fd
});
} }
} }
}); });
@ -167,7 +194,7 @@ define(['taskbar'], function(taskbar) {
uploadForm.attr('action', route); uploadForm.attr('action', route);
for(var i = 0; i < files.length; ++i) { for(var i = 0; i < files.length; ++i) {
var isImage = files[i].type.match('image.*'); var isImage = files[i].type.match(/image./);
text += (isImage ? '!' : '') + '[' + files[i].name + '](uploading...) '; text += (isImage ? '!' : '') + '[' + files[i].name + '](uploading...) ';
if(files[i].size > parseInt(config.maximumFileSize, 10) * 1024) { if(files[i].size > parseInt(config.maximumFileSize, 10) * 1024) {
@ -181,6 +208,7 @@ define(['taskbar'], function(taskbar) {
uploadForm.off('submit').submit(function() { uploadForm.off('submit').submit(function() {
$(this).find('#postUploadCsrf').val($('#csrf_token').val()); $(this).find('#postUploadCsrf').val($('#csrf_token').val());
if(formData) { if(formData) {
formData.append('_csrf', $('#csrf_token').val()); formData.append('_csrf', $('#csrf_token').val());
} }
@ -191,19 +219,25 @@ define(['taskbar'], function(taskbar) {
resetForm: true, resetForm: true,
clearForm: true, clearForm: true,
formData: formData, formData: formData,
error: function(xhr) { error: function(xhr) {
xhr = maybeParse(xhr);
app.alertError('Error uploading file!\nStatus : ' + xhr.status + '\nMessage : ' + xhr.responseText); app.alertError('Error uploading file!\nStatus : ' + xhr.status + '\nMessage : ' + xhr.responseText);
if (typeof callback == 'function') if (typeof callback == 'function')
callback(xhr); callback(xhr);
}, },
uploadProgress: function(event, position, total, percent) { uploadProgress: function(event, position, total, percent) {
var current = textarea.val(); var current = textarea.val();
for(var i=0; i<files.length; ++i) { for(var i=0; i < files.length; ++i) {
var re = new RegExp(files[i].name + "]\\([^)]+\\)", 'g'); var re = new RegExp(files[i].name + "]\\([^)]+\\)", 'g');
textarea.val(current.replace(re, files[i].name+'](uploading ' + percent + '%)')); textarea.val(current.replace(re, files[i].name+'](uploading ' + percent + '%)'));
} }
}, },
success: function(uploads) { success: function(uploads) {
uploads = maybeParse(uploads);
if(uploads && uploads.length) { if(uploads && uploads.length) {
for(var i=0; i<uploads.length; ++i) { for(var i=0; i<uploads.length; ++i) {
@ -218,7 +252,7 @@ define(['taskbar'], function(taskbar) {
callback(null, uploads); callback(null, uploads);
}, },
complete: function(xhr, status) { complete: function() {
uploadForm[0].reset(); uploadForm[0].reset();
composer.posts[post_uuid].uploadsInProgress.pop(); composer.posts[post_uuid].uploadsInProgress.pop();
} }
@ -255,11 +289,15 @@ define(['taskbar'], function(taskbar) {
$(this).ajaxSubmit({ $(this).ajaxSubmit({
formData: formData, formData: formData,
error: function(xhr) { error: function(xhr) {
xhr = maybeParse(xhr);
app.alertError('Error uploading file!\nStatus : ' + xhr.status + '\nMessage : ' + xhr.responseText); app.alertError('Error uploading file!\nStatus : ' + xhr.status + '\nMessage : ' + xhr.responseText);
if (typeof callback == 'function') if (typeof callback == 'function')
callback(xhr); callback(xhr);
}, },
success: function(uploads) { success: function(uploads) {
uploads = maybeParse(uploads);
postContainer.find('#topic-thumb-url').val((uploads[0] || {}).url || '').trigger('change'); postContainer.find('#topic-thumb-url').val((uploads[0] || {}).url || '').trigger('change');
if (typeof callback == 'function') if (typeof callback == 'function')
callback(null, uploads); callback(null, uploads);
@ -530,19 +568,23 @@ define(['taskbar'], function(taskbar) {
$('#files').click(); $('#files').click();
}); });
$('#files').on('change', function(e) { postContainer.find('#files').on('change', function(e) {
var files = e.target.files; var files = (e.target || {}).files || ($(this).val() ? [{name: $(this).val(), type: utils.fileMimeType($(this).val())}] : null);
if(files) { if(files) {
uploadContentFiles({files: files, post_uuid: post_uuid, route: '/api/post/upload'}); uploadContentFiles({files: files, post_uuid: post_uuid, route: '/api/post/upload'});
} }
}); });
postContainer.find('#topic-thumb-file').on('change', function(e) { postContainer.find('#topic-thumb-file').on('change', function(e) {
var files = e.target.files; var files = (e.target || {}).files || ($(this).val() ? [{name: $(this).val(), type: utils.fileMimeType($(this).val())}] : null),
fd;
if(files) { if(files) {
var fd = new FormData(); if (window.FormData) {
for (var i = 0, file; file = files[i]; i++) { fd = new FormData();
fd.append('files[]', file, file.name); for (var i = 0, file; file = files[i]; i++) {
fd.append('files[]', file, file.name);
}
} }
uploadTopicThumb({files: files, post_uuid: post_uuid, route: '/api/topic/thumb/upload', formData: fd}); uploadTopicThumb({files: files, post_uuid: post_uuid, route: '/api/topic/thumb/upload', formData: fd});
} }
@ -573,21 +615,21 @@ define(['taskbar'], function(taskbar) {
resizeCenterY = 0, resizeCenterY = 0,
resizeOffset = 0, resizeOffset = 0,
resizeStart = function(e) { resizeStart = function(e) {
resizeRect = resizeEl.getBoundingClientRect(); resizeRect = resizeEl[0].getBoundingClientRect();
resizeCenterY = resizeRect.top + (resizeRect.height/2); resizeCenterY = resizeRect.top + (resizeRect.height/2);
resizeOffset = resizeCenterY - e.clientY; resizeOffset = resizeCenterY - e.clientY;
resizeActive = true; resizeActive = true;
$(window).on('mousemove', resizeAction); $(window).on('mousemove', resizeAction);
$(window).on('mouseup', resizeStop); $(window).on('mouseup', resizeStop);
document.body.addEventListener('touchmove', resizeTouchAction); $('body').on('touchmove', resizeTouchAction);
}, },
resizeStop = function() { resizeStop = function() {
resizeActive = false; resizeActive = false;
bodyEl.focus(); bodyEl.focus();
$(window).off('mousemove', resizeAction); $(window).off('mousemove', resizeAction);
$(window).off('mouseup', resizeStop); $(window).off('mouseup', resizeStop);
document.body.removeEventListener('touchmove', resizeTouchAction); $('body').off('touchmove', resizeTouchAction);
}, },
resizeTouchAction = function(e) { resizeTouchAction = function(e) {
e.preventDefault(); e.preventDefault();
@ -617,22 +659,20 @@ define(['taskbar'], function(taskbar) {
}, },
resizeRect; resizeRect;
var resizeEl = postContainer.find('.resizer')[0]; var resizeEl = postContainer.find('.resizer');
resizeEl.addEventListener('mousedown', resizeStart); resizeEl.on('mousedown', resizeStart);
resizeEl.addEventListener('touchstart', function(e) { resizeEl.on('touchstart', function(e) {
e.preventDefault(); e.preventDefault();
resizeStart(e.touches[0]); resizeStart(e.touches[0]);
}); });
resizeEl.addEventListener('touchend', function(e) { resizeEl.on('touchend', function(e) {
e.preventDefault(); e.preventDefault();
resizeStop(); resizeStop();
}); });
// .on('mousedown touchstart', resizeStart)
// .on('mouseup touchend', resizeStop)
window.addEventListener('resize', function() { $(window).on('resize', function() {
if (composer.active !== undefined) { if (composer.active !== undefined) {
composer.activateReposition(composer.active); composer.activateReposition(composer.active);
} }
@ -652,7 +692,6 @@ define(['taskbar'], function(taskbar) {
} }
var percentage = localStorage.getItem('composer:resizePercentage'), var percentage = localStorage.getItem('composer:resizePercentage'),
bodyRect = document.body.getBoundingClientRect(),
postContainer = $('#cmp-uuid-' + post_uuid); postContainer = $('#cmp-uuid-' + post_uuid);
composer.active = post_uuid; composer.active = post_uuid;
@ -673,10 +712,12 @@ define(['taskbar'], function(taskbar) {
postContainer.find('.upload-instructions').removeClass('hide'); postContainer.find('.upload-instructions').removeClass('hide');
} }
postContainer.find('.img-upload-btn').removeClass('hide'); postContainer.find('.img-upload-btn').removeClass('hide');
postContainer.find('#files.lt-ie9').removeClass('hide');
} }
if(config.allowFileUploads) { if(config.allowFileUploads) {
postContainer.find('.file-upload-btn').removeClass('hide'); postContainer.find('.file-upload-btn').removeClass('hide');
postContainer.find('#files.lt-ie9').removeClass('hide');
} }
postContainer.css('visibility', 'visible') postContainer.css('visibility', 'visible')
@ -775,155 +816,6 @@ define(['taskbar'], function(taskbar) {
taskbar.minimize('composer', post_uuid); taskbar.minimize('composer', post_uuid);
}; };
function initializeDragAndDrop(post_uuid) {
if(jQuery.event.props.indexOf('dataTransfer') === -1) {
jQuery.event.props.push('dataTransfer');
}
var draggingDocument = false;
var postContainer = $('#cmp-uuid-' + post_uuid),
fileForm = postContainer.find('#fileForm');
drop = postContainer.find('.imagedrop'),
tabContent = postContainer.find('.tab-content'),
textarea = postContainer.find('textarea');
$(document).off('dragstart').on('dragstart', function(e) {
draggingDocument = true;
}).off('dragend').on('dragend', function(e) {
draggingDocument = false;
});
textarea.on('dragenter', function(e) {
if(draggingDocument) {
return;
}
drop.css('top', tabContent.position().top + 'px');
drop.css('height', textarea.height());
drop.css('line-height', textarea.height() + 'px');
drop.show();
drop.on('dragleave', function(ev) {
drop.hide();
drop.off('dragleave');
});
});
function cancel(e) {
e.preventDefault();
return false;
}
drop.on('dragover', cancel);
drop.on('dragenter', cancel);
drop.on('drop', function(e) {
e.preventDefault();
var dt = e.dataTransfer,
files = dt.files;
if(files.length) {
var fd = new FormData();
for (var i = 0, file; file = dt.files[i]; i++) {
fd.append('files[]', file, file.name);
}
fileForm[0].reset();
uploadSubmit(files, post_uuid, '/api/post/upload', fd);
}
drop.hide();
return false;
});
$(window).off('paste').on('paste', function(event) {
var items = (event.clipboardData || event.originalEvent.clipboardData).items;
if(items && items.length) {
var blob = items[0].getAsFile();
if(blob) {
blob.name = 'upload-'+ utils.generateUUID();
var fd = new FormData();
fd.append('files[]', blob, blob.name);
fileForm[0].reset();
uploadSubmit([blob], post_uuid, '/api/post/upload', fd);
}
}
});
}
function uploadSubmit(files, post_uuid, route, formData, callback) {
var postContainer = $('#cmp-uuid-' + post_uuid),
textarea = postContainer.find('textarea'),
text = textarea.val(),
uploadForm = postContainer.find('#fileForm');
uploadForm.attr('action', route);
for(var i=0; i<files.length; ++i) {
var isImage = files[i].type.match('image.*');
text += (isImage ? '!' : '') + '[' + files[i].name + '](uploading...) ';
if(files[i].size > parseInt(config.maximumFileSize, 10) * 1024) {
uploadForm[0].reset();
return composerAlert('File too big', 'Maximum allowed file size is ' + config.maximumFileSize + 'kbs');
}
}
textarea.val(text);
uploadForm.off('submit').submit(function() {
$(this).find('#postUploadCsrf').val($('#csrf_token').val());
if(formData) {
formData.append('_csrf', $('#csrf_token').val());
}
composer.posts[post_uuid].uploadsInProgress.push(1);
$(this).ajaxSubmit({
resetForm: true,
clearForm: true,
formData: formData,
error: function(xhr) {
app.alertError('Error uploading file!\nStatus : ' + xhr.status + '\nMessage : ' + xhr.responseText);
},
uploadProgress: function(event, position, total, percent) {
var current = textarea.val();
for(var i=0; i<files.length; ++i) {
var re = new RegExp(files[i].name + "]\\([^)]+\\)", 'g');
textarea.val(current.replace(re, files[i].name+'](uploading ' + percent + '%)'));
}
},
success: function(uploads) {
if(uploads && uploads.length) {
for(var i=0; i<uploads.length; ++i) {
var current = textarea.val();
var re = new RegExp(uploads[i].name + "]\\([^)]+\\)", 'g');
textarea.val(current.replace(re, uploads[i].name + '](' + uploads[i].url + ')'));
}
}
textarea.focus();
},
complete: function(xhr, status) {
uploadForm[0].reset();
composer.posts[post_uuid].uploadsInProgress.pop();
}
});
return false;
});
uploadForm.submit();
}
return { return {
newTopic: composer.newTopic, newTopic: composer.newTopic,
newReply: composer.newReply, newReply: composer.newReply,

@ -1,100 +1,105 @@
define(function() { define(function() {
var taskbar = { var taskbar = {
initialized: false, initialized: false,
taskbar: undefined,
tasklist: undefined,
init: function() { init: function() {
var footerEl = document.getElementById('footer'); var footerEl = $('#footer');
taskbar.taskbar = document.createElement('div'); this.taskbar = $('<div />')
var jTaskbar = $(taskbar.taskbar); .html('<div class="navbar-inner"><ul class="nav navbar-nav pull-right"></ul></div>')
taskbar.taskbar.innerHTML = '<div class="navbar-inner"><ul class="nav navbar-nav pull-right"></ul></div>'; .addClass('taskbar navbar navbar-default navbar-fixed-bottom')
taskbar.taskbar.className = 'taskbar navbar navbar-default navbar-fixed-bottom'; .attr('id', 'taskbar');
taskbar.taskbar.id = 'taskbar';
taskbar.tasklist = taskbar.taskbar.querySelector('ul'); this.tasklist = this.taskbar.find('ul');
document.body.insertBefore(taskbar.taskbar, footerEl.nextSibling); this.taskbar.insertBefore(footerEl.next());
// Posts bar events // Posts bar events
jTaskbar.on('click', 'li', function() { this.taskbar.on('click', 'li', function() {
var _btn = this, var $btn = $(this),
module = this.getAttribute('data-module'), module = $btn.attr('data-module'),
uuid = this.getAttribute('data-uuid'); uuid = $btn.attr('data-uuid');
require([module], function(module) { require([module], function(module) {
if (_btn.className.indexOf('active') === -1) { if (!$btn.hasClass('active')) {
taskbar.minimizeAll(); taskbar.minimizeAll();
module.load(uuid); module.load(uuid);
taskbar.toggleNew(uuid, false); taskbar.toggleNew(uuid, false);
app.alternatingTitle(''); app.alternatingTitle('');
// Highlight the button // Highlight the button
$(taskbar.tasklist).removeClass('active'); taskbar.tasklist.removeClass('active');
_btn.className += ' active'; $btn.addClass('active');
} else { } else {
module.minimize(uuid); module.minimize(uuid);
} }
}); });
}); });
jTaskbar.on('click', 'li a', function(e) { this.taskbar.on('click', 'li a', function(e) {
e.preventDefault(); e.preventDefault();
}); });
taskbar.initialized = true; taskbar.initialized = true;
}, },
update: function() { update: function() {
var tasks = taskbar.tasklist.querySelectorAll('li'); var tasks = taskbar.tasklist.find('li');
if (tasks.length > 0) { if (tasks.length > 0) {
taskbar.taskbar.setAttribute('data-active', '1'); taskbar.taskbar.attr('data-active', '1');
} else { } else {
taskbar.taskbar.removeAttribute('data-active'); taskbar.taskbar.removeAttr('data-active');
} }
}, },
discard: function(module, uuid) { discard: function(module, uuid) {
// Commit // Commit
var btnEl = taskbar.tasklist.querySelector('[data-module="' + module + '"][data-uuid="' + uuid + '"]'); var btnEl = taskbar.tasklist.find('[data-module="' + module + '"][data-uuid="' + uuid + '"]');
btnEl.parentNode.removeChild(btnEl); btnEl.remove();
taskbar.update(); taskbar.update();
}, },
push: function(module, uuid, options) { push: function(module, uuid, options) {
var element = $(taskbar.tasklist).find('li[data-uuid="'+uuid+'"]'); var element = taskbar.tasklist.find('li[data-uuid="'+uuid+'"]');
if(element.length) if(element.length)
return; return;
var btnEl = document.createElement('li'); var btnEl = $('<li />')
.html('<a href="#">' +
btnEl.innerHTML = '<a href="#">' + (options.icon ? '<img src="' + options.icon + '" />' : '') +
(options.icon ? '<img src="' + options.icon + '" />' : '') + '<span>' + (options.title || 'NodeBB Task') + '</span>' +
'<span>' + (options.title || 'NodeBB Task') + '</span>' + '</a>')
'</a>'; .attr({
btnEl.setAttribute('data-module', module); 'data-module': module,
btnEl.setAttribute('data-uuid', uuid); 'data-uuid': uuid
btnEl.className = options.state !== undefined ? options.state : 'active'; })
.addClass(options.state !== undefined ? options.state : 'active');
if (!options.state || options.state === 'active') taskbar.minimizeAll(); if (!options.state || options.state === 'active') taskbar.minimizeAll();
taskbar.tasklist.appendChild(btnEl); taskbar.tasklist.append(btnEl);
taskbar.update(); taskbar.update();
}, },
minimize: function(module, uuid) { minimize: function(module, uuid) {
var btnEl = taskbar.tasklist.querySelector('[data-module="' + module + '"][data-uuid="' + uuid + '"]'); var btnEl = taskbar.tasklist.find('[data-module="' + module + '"][data-uuid="' + uuid + '"]');
$(btnEl).removeClass('active'); btnEl.removeClass('active');
}, },
minimizeAll: function() { minimizeAll: function() {
$(taskbar.tasklist.querySelectorAll('.active')).removeClass('active'); taskbar.tasklist.find('.active').removeClass('active');
}, },
toggleNew: function(uuid, state) { toggleNew: function(uuid, state) {
var btnEl = $(taskbar.tasklist.querySelector('[data-uuid="' + uuid + '"]')); var btnEl = taskbar.tasklist.find('[data-uuid="' + uuid + '"]');
btnEl.toggleClass('new', state); btnEl.toggleClass('new', state);
}, },
updateActive: function(uuid) { updateActive: function(uuid) {
var tasks = $(taskbar.tasklist).find('li'); var tasks = taskbar.tasklist.find('li');
tasks.removeClass('active'); tasks.removeClass('active');
tasks.filter('[data-uuid="' + uuid + '"]').addClass('active'); tasks.filter('[data-uuid="' + uuid + '"]').addClass('active');
} }
} };
if (!taskbar.initialized) { if (!taskbar.initialized) {
taskbar.init(); taskbar.init();

@ -1,6 +1,16 @@
define(function() { define(function() {
var module = {}; var module = {},
maybeParse = function(response) {
if (typeof response == 'string') {
try {
return $.parseJSON(response);
} catch (e) {
return {error: 'Something went wrong while parsing server response'};
}
}
return response;
};
module.open = function(route, params, fileSize, callback) { module.open = function(route, params, fileSize, callback) {
$('#upload-picture-modal').modal('show').removeClass('hide'); $('#upload-picture-modal').modal('show').removeClass('hide');
@ -21,7 +31,7 @@ define(function() {
$('#uploadForm').submit(); $('#uploadForm').submit();
}); });
$('#uploadForm').off('submit').submit(function() { uploadForm.off('submit').submit(function() {
function status(message) { function status(message) {
module.hideAlerts(); module.hideAlerts();
@ -52,8 +62,8 @@ define(function() {
$(this).ajaxSubmit({ $(this).ajaxSubmit({
error: function(xhr) { error: function(xhr) {
xhr = maybeParse(xhr);
error('Error: ' + xhr.status); error('Error: ' + xhr.status);
}, },
@ -62,6 +72,8 @@ define(function() {
}, },
success: function(response) { success: function(response) {
response = maybeParse(response);
if (response.error) { if (response.error) {
error(response.error); error(response.error);
return; return;
@ -78,14 +90,14 @@ define(function() {
return false; return false;
}); });
} };
module.hideAlerts = function() { module.hideAlerts = function() {
$('#alert-status').addClass('hide'); $('#alert-status').addClass('hide');
$('#alert-success').addClass('hide'); $('#alert-success').addClass('hide');
$('#alert-error').addClass('hide'); $('#alert-error').addClass('hide');
$('#upload-progress-box').addClass('hide'); $('#upload-progress-box').addClass('hide');
} };
return module; return module;
}); });

@ -0,0 +1,51 @@
if ('undefined' !== typeof window) {
(function ($, undefined) {
$.fn.getCursorPosition = function() {
var el = $(this).get(0);
var pos = 0;
if('selectionStart' in el) {
pos = el.selectionStart;
} else if('selection' in document) {
el.focus();
var Sel = document.selection.createRange();
var SelLength = document.selection.createRange().text.length;
Sel.moveStart('character', -el.value.length);
pos = Sel.text.length - SelLength;
}
return pos;
};
$.fn.selectRange = function(start, end) {
if(!end) end = start;
return this.each(function() {
if (this.setSelectionRange) {
this.focus();
this.setSelectionRange(start, end);
} else if (this.createTextRange) {
var range = this.createTextRange();
range.collapse(true);
range.moveEnd('character', end);
range.moveStart('character', start);
range.select();
}
});
};
//http://stackoverflow.com/questions/511088/use-javascript-to-place-cursor-at-end-of-text-in-text-input-element
$.fn.putCursorAtEnd = function() {
return this.each(function() {
$(this).focus();
if (this.setSelectionRange) {
var len = $(this).val().length * 2;
this.setSelectionRange(len, len);
} else {
$(this).val($(this).val());
}
this.scrollTop = 999999;
});
};
})(jQuery || {fn:{}});
}

@ -13,13 +13,13 @@
}; };
try { try {
fs = require('fs'), fs = require('fs');
path = require('path'); path = require('path');
} catch (e) {} } catch (e) {}
templates.force_refresh = function (tpl) { templates.force_refresh = function (tpl) {
return !!config.force_refresh[tpl]; return !!config.force_refresh[tpl];
} };
templates.get_custom_map = function (tpl) { templates.get_custom_map = function (tpl) {
if (config['custom_mapping'] && tpl) { if (config['custom_mapping'] && tpl) {
@ -34,7 +34,7 @@
} }
templates.is_available = function (tpl) { templates.is_available = function (tpl) {
return jQuery.inArray(tpl, available_templates) !== -1; return $.inArray(tpl, available_templates) !== -1;
}; };
templates.ready = function (callback) { templates.ready = function (callback) {
@ -113,7 +113,7 @@
} }
function loadClient() { function loadClient() {
jQuery.when(jQuery.getJSON(RELATIVE_PATH + '/templates/config.json'), jQuery.getJSON(RELATIVE_PATH + '/api/get_templates_listing')).done(function (config_data, templates_data) { $.when($.getJSON(RELATIVE_PATH + '/templates/config.json'), $.getJSON(RELATIVE_PATH + '/api/get_templates_listing')).done(function (config_data, templates_data) {
config = config_data[0]; config = config_data[0];
available_templates = templates_data[0]; available_templates = templates_data[0];
templates.ready(); templates.ready();
@ -127,7 +127,7 @@
templates.init = function (templates_to_load, custom_templates) { templates.init = function (templates_to_load, custom_templates) {
loadTemplates(templates_to_load || [], custom_templates || false); loadTemplates(templates_to_load || [], custom_templates || false);
} };
templates.render = function(filename, options, fn) { templates.render = function(filename, options, fn) {
if ('function' === typeof options) { if ('function' === typeof options) {
@ -148,7 +148,7 @@
} else { } else {
return fn(null, templates[tpl].parse(options)); return fn(null, templates[tpl].parse(options));
} }
} };
templates.getTemplateNameFromUrl = function (url) { templates.getTemplateNameFromUrl = function (url) {
var parts = url.split('?')[0].split('/'); var parts = url.split('?')[0].split('/');
@ -159,7 +159,7 @@
} }
} }
return ''; return '';
} };
templates.preload_template = function(tpl_name, callback) { templates.preload_template = function(tpl_name, callback) {
@ -171,12 +171,12 @@
// should be named something else // should be named something else
// TODO: The "Date.now()" in the line below is only there for development purposes. // TODO: The "Date.now()" in the line below is only there for development purposes.
// It should be removed at some point. // It should be removed at some point.
jQuery.get(RELATIVE_PATH + '/templates/' + tpl_name + '.tpl?v=' + Date.now(), function (html) { $.get(RELATIVE_PATH + '/templates/' + tpl_name + '.tpl?v=' + Date.now(), function (html) {
var template = function () { var template = function () {
this.toString = function () { this.toString = function () {
return this.html; return this.html;
}; };
} };
template.prototype.parse = parse; template.prototype.parse = parse;
template.prototype.html = String(html); template.prototype.html = String(html);
@ -186,7 +186,7 @@
callback(); callback();
}); });
} };
templates.load_template = function (callback, url, template) { templates.load_template = function (callback, url, template) {
var location = document.location || window.location, var location = document.location || window.location,
@ -243,7 +243,7 @@
$('#content').html(translatedTemplate); $('#content').html(translatedTemplate);
jQuery('#content [template-variable]').each(function (index, element) { $('#content [template-variable]').each(function (index, element) {
var value = null; var value = null;
switch ($(element).attr('template-type')) { switch ($(element).attr('template-type')) {
@ -268,29 +268,29 @@
}); });
} }
} };
templates.cancelRequest = function() { templates.cancelRequest = function() {
if (apiXHR) { if (apiXHR) {
apiXHR.abort(); apiXHR.abort();
} }
} };
templates.flush = function () { templates.flush = function () {
parsed_variables = {}; parsed_variables = {};
} };
templates.get = function (key) { templates.get = function (key) {
return parsed_variables[key]; return parsed_variables[key];
} };
templates.set = function (key, value) { templates.set = function (key, value) {
parsed_variables[key] = value; parsed_variables[key] = value;
} };
templates.setGlobal = function(key, value) { templates.setGlobal = function(key, value) {
templates.globals[key] = value; templates.globals[key] = value;
} };
//modified from https://github.com/psychobunny/dcp.templates //modified from https://github.com/psychobunny/dcp.templates
var parse = function (data) { var parse = function (data) {
@ -451,4 +451,4 @@
module: { module: {
exports: {} exports: {}
} }
} : module) } : module);

@ -105,7 +105,7 @@
if (value) { if (value) {
for (var i = 1, ii = variables.length; i < ii; i++) { for (var i = 1, ii = variables.length; i < ii; i++) {
var variable = variables[i].replace(']]', ''); var variable = variables[i].replace(']]', '');
value = value.replace('%' + i, variable); value = ('' + value).replace('%' + i, variable);
} }
text = text.replace(key, value); text = text.replace(key, value);
@ -119,6 +119,7 @@
for (var key in keys) { for (var key in keys) {
if (keys.hasOwnProperty(key)) { if (keys.hasOwnProperty(key)) {
keys[key] = '' + keys[key];
var variables = keys[key].split(/[,][?\s+]/); var variables = keys[key].split(/[,][?\s+]/);
var parsedKey = keys[key].replace('[[', '').replace(']]', '').split(':'); var parsedKey = keys[key].replace('[[', '').replace(']]', '').split(':');
@ -127,7 +128,7 @@
} }
var languageFile = parsedKey[0]; var languageFile = parsedKey[0];
parsedKey = parsedKey[1].split(',')[0]; parsedKey = ('' + parsedKey[1]).split(',')[0];
if (files.loaded[languageFile]) { if (files.loaded[languageFile]) {
data = insertLanguage(data, keys[key], files.loaded[languageFile][parsedKey], variables); data = insertLanguage(data, keys[key], files.loaded[languageFile][parsedKey], variables);
@ -178,7 +179,7 @@
files.loading[filename] = true; files.loading[filename] = true;
jQuery.getJSON(RELATIVE_PATH + '/language/' + config.defaultLang + '/' + filename + '.json?v=' + timestamp, function (language) { $.getJSON(RELATIVE_PATH + '/language/' + config.defaultLang + '/' + filename + '.json?v=' + timestamp, function (language) {
files.loaded[filename] = language; files.loaded[filename] = language;
if (callback) { if (callback) {

@ -99,15 +99,14 @@
return difference + (min ? 'y' : ' year') + (difference !== 1 && !min ? 's' : ''); return difference + (min ? 'y' : ' year') + (difference !== 1 && !min ? 's' : '');
}, },
invalidUnicodeChars : XRegExp('[^\\p{L}\\s\\d\\-_]', 'g'), invalidUnicodeChars: XRegExp('[^\\p{L}\\s\\d\\-_]', 'g'),
invalidLatinChars : /[^\w\s\d\-_]/g, invalidLatinChars: /[^\w\s\d\-_]/g,
trimRegex: /^\s+|\s+$/g,
trimRegex : /^\s+|\s+$/g, collapseWhitespace: /\s+/g,
collapseWhitespace : /\s+/g, collapseDash: /-+/g,
collapseDash : /-+/g, trimTrailingDash: /-$/g,
trimTrailingDash : /-$/g, trimLeadingDash: /^-/g,
trimLeadingDash : /^-/g, isLatin: /^[\w]+$/,
isLatin : /^[\w]+$/,
//http://dense13.com/blog/2009/05/03/converting-string-to-slug-javascript/ //http://dense13.com/blog/2009/05/03/converting-string-to-slug-javascript/
slugify: function(str) { slugify: function(str) {
@ -138,9 +137,11 @@
isPasswordValid: function(password) { isPasswordValid: function(password) {
return password && password.indexOf(' ') === -1; return password && password.indexOf(' ') === -1;
}, },
isNumber: function(n) { isNumber: function(n) {
return !isNaN(parseFloat(n)) && isFinite(n); return !isNaN(parseFloat(n)) && isFinite(n);
}, },
// shallow objects merge // shallow objects merge
merge: function() { merge: function() {
var result = {}, obj, keys; var result = {}, obj, keys;
@ -154,6 +155,43 @@
return result; return result;
}, },
fileExtension: function (path) {
return ('' + path).split('.').pop();
},
fileMimeType: (function () {
// we only care about images, for now
var map = {
"bmp": "image/bmp",
"cmx": "image/x-cmx",
"cod": "image/cis-cod",
"gif": "image/gif",
"ico": "image/x-icon",
"ief": "image/ief",
"jfif": "image/pipeg",
"jpe": "image/jpeg",
"jpeg": "image/jpeg",
"jpg": "image/jpeg",
"pbm": "image/x-portable-bitmap",
"pgm": "image/x-portable-graymap",
"pnm": "image/x-portable-anymap",
"ppm": "image/x-portable-pixmap",
"ras": "image/x-cmu-raster",
"rgb": "image/x-rgb",
"svg": "image/svg+xml",
"tif": "image/tiff",
"tiff": "image/tiff",
"xbm": "image/x-xbitmap",
"xpm": "image/x-xpixmap",
"xwd": "image/x-xwindowdump"
};
return function (path) {
var extension = utils.fileExtension(path);
return map[extension] || '*';
}
})(),
isRelativeUrl: function(url) { isRelativeUrl: function(url) {
var firstChar = url.slice(0, 1); var firstChar = url.slice(0, 1);
return (firstChar === '.' || firstChar === '/'); return (firstChar === '.' || firstChar === '/');
@ -200,64 +238,8 @@
} }
}; };
if (!String.prototype.trim) {
String.prototype.trim = function() {
return this.replace(utils.trimRegex, '');
};
}
if ('undefined' !== typeof window) { if ('undefined' !== typeof window) {
window.utils = module.exports; window.utils = module.exports;
(function ($, undefined) {
$.fn.getCursorPosition = function() {
var el = $(this).get(0);
var pos = 0;
if('selectionStart' in el) {
pos = el.selectionStart;
} else if('selection' in document) {
el.focus();
var Sel = document.selection.createRange();
var SelLength = document.selection.createRange().text.length;
Sel.moveStart('character', -el.value.length);
pos = Sel.text.length - SelLength;
}
return pos;
}
$.fn.selectRange = function(start, end) {
if(!end) end = start;
return this.each(function() {
if (this.setSelectionRange) {
this.focus();
this.setSelectionRange(start, end);
} else if (this.createTextRange) {
var range = this.createTextRange();
range.collapse(true);
range.moveEnd('character', end);
range.moveStart('character', start);
range.select();
}
});
};
//http://stackoverflow.com/questions/511088/use-javascript-to-place-cursor-at-end-of-text-in-text-input-element
$.fn.putCursorAtEnd = function() {
return this.each(function() {
$(this).focus();
if (this.setSelectionRange) {
var len = $(this).val().length * 2;
this.setSelectionRange(len, len);
} else {
$(this).val($(this).val());
}
this.scrollTop = 999999;
});
};
})(jQuery);
} }
})('undefined' === typeof module ? { })('undefined' === typeof module ? {

@ -3,15 +3,25 @@
<head> <head>
<title>NodeBB Administration Panel</title> <title>NodeBB Administration Panel</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="{relative_path}/vendor/fontawesome/css/font-awesome.min.css">
<link rel="stylesheet" type="text/css" href="{relative_path}/vendor/colorpicker/colorpicker.css">
<link rel="stylesheet" type="text/css" href="{relative_path}/stylesheet.css?{cache-buster}" />
<script> <script>
var RELATIVE_PATH = "{relative_path}"; var RELATIVE_PATH = "{relative_path}";
</script> </script>
<link rel="stylesheet" href="{relative_path}/vendor/fontawesome/css/font-awesome.min.css">
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/es5-shim/2.3.0/es5-shim.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7/html5shiv.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.js"></script>
<script>__lt_ie_9__ = 1;</script>
<![endif]-->
<script src="{relative_path}/vendor/jquery/js/jquery.js"></script> <script src="{relative_path}/vendor/jquery/js/jquery.js"></script>
<script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <script src="{relative_path}/vendor/jquery/js/jquery-ui-1.10.4.custom.js"></script>
<script src="{relative_path}/vendor/bootstrap/js/bootstrap.min.js"></script> <script src="{relative_path}/vendor/bootstrap/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="{relative_path}/vendor/colorpicker/colorpicker.css">
<script src="{relative_path}/socket.io/socket.io.js"></script> <script src="{relative_path}/socket.io/socket.io.js"></script>
<script src="{relative_path}/src/app.js?{cache-buster}"></script> <script src="{relative_path}/src/app.js?{cache-buster}"></script>
<script src="{relative_path}/src/templates.js?{cache-buster}"></script> <script src="{relative_path}/src/templates.js?{cache-buster}"></script>
@ -37,9 +47,9 @@
}); });
</script> </script>
<script src="{relative_path}/src/overrides.js"></script>
<script src="{relative_path}/src/utils.js"></script> <script src="{relative_path}/src/utils.js"></script>
<link rel="stylesheet" type="text/css" href="{relative_path}/stylesheet.css?{cache-buster}" />
</head> </head>
<body class="admin"> <body class="admin">

@ -1,14 +1,5 @@
<div class="composer"> <div class="composer">
<style>
/* todo: move this to base theme */
.topic-thumb-container { width: 95%; margin-top: 5px; background: rgb(255, 255, 255); background: rgba(255, 255, 255, 0.6); padding: 10px; }
.topic-thumb-btn { cursor: hand; cursor: pointer; }
.topic-thumb-toggle-btn { margin: -25px 3% 0 0; }
.topic-thumb-preview { width: auto; height: auto; max-width: 100px; max-height: 100px }
.topic-thumb-ctrl.form-group { display: inline-block; vertical-align: -50% !important; }
</style>
<div class="composer-container"> <div class="composer-container">
<input class="title form-control" type="text" tabIndex="1" placeholder="[[topic:composer.title_placeholder]]" /> <input class="title form-control" type="text" tabIndex="1" placeholder="[[topic:composer.title_placeholder]]" />
@ -22,7 +13,6 @@
<input type="text" id="topic-thumb-url" class="form-control" placeholder="[[topic:composer.thumb_url_placeholder]]" /> <input type="text" id="topic-thumb-url" class="form-control" placeholder="[[topic:composer.thumb_url_placeholder]]" />
</div> </div>
<div class="form-group"> <div class="form-group">
<!-- todo: drag and drop? -->
<label for="topic-thumb-file">[[topic:composer.thumb_file_label]]</label> <label for="topic-thumb-file">[[topic:composer.thumb_file_label]]</label>
<input type="file" id="topic-thumb-file" class="form-control" /> <input type="file" id="topic-thumb-file" class="form-control" />
</div> </div>
@ -41,16 +31,26 @@
<span class="btn btn-link" tabindex="-1"><i class="fa fa-italic"></i></span> <span class="btn btn-link" tabindex="-1"><i class="fa fa-italic"></i></span>
<span class="btn btn-link" tabindex="-1"><i class="fa fa-list"></i></span> <span class="btn btn-link" tabindex="-1"><i class="fa fa-list"></i></span>
<span class="btn btn-link" tabindex="-1"><i class="fa fa-link"></i></span> <span class="btn btn-link" tabindex="-1"><i class="fa fa-link"></i></span>
<span class="btn btn-link img-upload-btn hide" tabindex="-1">
<i class="fa fa-picture-o"></i> <!--[if gte IE 9]><!-->
</span> <span class="btn btn-link img-upload-btn hide" tabindex="-1">
<span class="btn btn-link file-upload-btn hide" tabindex="-1"> <i class="fa fa-picture-o"></i>
<i class="fa fa-upload"></i> </span>
</span> <span class="btn btn-link file-upload-btn hide" tabindex="-1">
<i class="fa fa-upload"></i>
</span>
<!--<![endif]-->
<form id="fileForm" method="post" enctype="multipart/form-data"> <form id="fileForm" method="post" enctype="multipart/form-data">
<input type="file" id="files" name="files[]" multiple class="hide"/>
<input id="postUploadCsrf" type="hidden" name="_csrf"> <input id="postUploadCsrf" type="hidden" name="_csrf">
<!--[if gte IE 9]><!-->
<input type="file" id="files" name="files[]" multiple class="gte-ie9 hide"/>
<!--<![endif]-->
<!--[if lt IE 9]>
<input type="file" id="files" name="files[]" class="lt-ie9 hide" value="Upload"/>
<![endif]-->
</form> </form>
</div> </div>
</div> </div>

@ -18,6 +18,13 @@
<style type="text/css">{customCSS}</style> <style type="text/css">{customCSS}</style>
<!-- ENDIF useCustomCSS --> <!-- ENDIF useCustomCSS -->
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/es5-shim/2.3.0/es5-shim.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7/html5shiv.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.js"></script>
<script>__lt_ie_9__ = 1;</script>
<![endif]-->
<script> <script>
var RELATIVE_PATH = "{relative_path}"; var RELATIVE_PATH = "{relative_path}";
</script> </script>

@ -239,6 +239,7 @@ var fs = require('fs'),
'src/templates.js', 'src/templates.js',
'src/ajaxify.js', 'src/ajaxify.js',
'src/translator.js', 'src/translator.js',
'src/overrides.js',
'src/utils.js' 'src/utils.js'
], ],
minFile: nconf.get('relative_path') + 'nodebb.min.js', minFile: nconf.get('relative_path') + 'nodebb.min.js',

@ -109,20 +109,22 @@ var nconf = require('nconf'),
return res.redirect('/403'); return res.redirect('/403');
} }
var allowedTypes = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif']; var allowedTypes = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif'],
var params = null; params = null, er;
try { try {
params = JSON.parse(req.body.params); params = JSON.parse(req.body.params);
} catch (e) { } catch (e) {
return res.send({ er = {
error: 'Error uploading file! Error :' + e.message error: 'Error uploading file! Error :' + e.message
}); };
return res.send(req.xhr ? er : JSON.stringify(er));
} }
if (allowedTypes.indexOf(req.files.userPhoto.type) === -1) { if (allowedTypes.indexOf(req.files.userPhoto.type) === -1) {
res.send({ er = {
error: 'Allowed image types are png, jpg and gif!' error: 'Allowed image types are png, jpg and gif!'
}); };
res.send(req.xhr ? er : JSON.stringify(er));
return; return;
} }
@ -136,12 +138,12 @@ var nconf = require('nconf'),
return res.redirect('/403'); return res.redirect('/403');
} }
var allowedTypes = ['image/x-icon', 'image/vnd.microsoft.icon']; var allowedTypes = ['image/x-icon', 'image/vnd.microsoft.icon'],
er;
if (allowedTypes.indexOf(req.files.userPhoto.type) === -1) { if (allowedTypes.indexOf(req.files.userPhoto.type) === -1) {
res.send({ er = {error: 'You can only upload icon file type!'};
error: 'You can only upload icon file type!' res.send(req.xhr ? er : JSON.stringify(er));
});
return; return;
} }
@ -149,14 +151,12 @@ var nconf = require('nconf'),
fs.unlink(req.files.userPhoto.path); fs.unlink(req.files.userPhoto.path);
if(err) { if(err) {
return res.send({ er = {error: err.message};
error: err.message return res.send(req.xhr ? er : JSON.stringify(er));
});
} }
res.json({ var rs = {path: image.url};
path: image.url res.send(req.xhr ? rs : JSON.stringify(rs));
});
}); });
}); });
@ -166,12 +166,12 @@ var nconf = require('nconf'),
return res.redirect('/403'); return res.redirect('/403');
} }
var allowedTypes = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif']; var allowedTypes = ['image/png', 'image/jpeg', 'image/pjpeg', 'image/jpg', 'image/gif'],
er;
if (allowedTypes.indexOf(req.files.userPhoto.type) === -1) { if (allowedTypes.indexOf(req.files.userPhoto.type) === -1) {
res.send({ er = {error: 'Allowed image types are png, jpg and gif!'};
error: 'Allowed image types are png, jpg and gif!' res.send(req.xhr ? er : JSON.stringify(er));
});
return; return;
} }
@ -191,17 +191,16 @@ var nconf = require('nconf'),
function uploadImage(filename, req, res) { function uploadImage(filename, req, res) {
function done(err, image) { function done(err, image) {
var er, rs;
fs.unlink(req.files.userPhoto.path); fs.unlink(req.files.userPhoto.path);
if(err) { if(err) {
return res.send({ er = {error: err.message};
error: err.message return res.send(req.xhr ? er : JSON.stringify(er));
});
} }
res.json({ rs = {path: image.url};
path: image.url res.send(req.xhr ? rs : JSON.stringify(rs));
});
} }
if(plugins.hasListeners('filter:uploadImage')) { if(plugins.hasListeners('filter:uploadImage')) {

@ -469,16 +469,25 @@ var path = require('path'),
async.map(files, filesIterator, function(err, images) { async.map(files, filesIterator, function(err, images) {
deleteTempFiles(); deleteTempFiles();
if(err) { if(err) {
return res.json(500, err.message); return res.send(500, err.message);
} }
res.json(200, images);
// if this was not a XMLHttpRequest (hence the req.xhr check http://expressjs.com/api.html#req.xhr)
// then most likely it's submit via the iFrame workaround, via the jquery.form plugin's ajaxSubmit()
// we need to send it as text/html so IE8 won't trigger a file download for the json response
// malsup.com/jquery/form/#file-upload
// Also, req.send is safe for both types, if the response was an object, res.send will automatically submit as application/json
// expressjs.com/api.html#res.send
res.send(200, req.xhr ? images : JSON.stringify(images));
}); });
} }
app.post('/post/upload', function(req, res, next) { app.post('/post/upload', function(req, res, next) {
upload(req, res, function(file, next) { upload(req, res, function(file, next) {
if(file.type.match('image.*')) { if(file.type.match(/image./)) {
posts.uploadPostImage(file, next); posts.uploadPostImage(file, next);
} else { } else {
posts.uploadPostFile(file, next); posts.uploadPostFile(file, next);
@ -488,7 +497,7 @@ var path = require('path'),
app.post('/topic/thumb/upload', function(req, res, next) { app.post('/topic/thumb/upload', function(req, res, next) {
upload(req, res, function(file, next) { upload(req, res, function(file, next) {
if(file.type.match('image.*')) { if(file.type.match(/image./)) {
topics.uploadTopicThumb(file, next); topics.uploadTopicThumb(file, next);
} else { } else {
res.json(500, {message: 'Invalid File'}); res.json(500, {message: 'Invalid File'});

Loading…
Cancel
Save