Merge branch 'master' of github.com:designcreateplay/NodeBB

v1.18.x
Julian Lam 11 years ago
commit dfd13fac0d

@ -32,7 +32,9 @@
"not_following_topic.title": "Not Following Topic",
"not_following_topic.message": "You will no longer receive notifications from this topic.",
"login_to_subscribe": "Please register or log in in order to subscribe to this topic",
"login_to_subscribe": "Please register or log in in order to subscribe to this topic.",
"markAsUnreadForAll.success" : "Topic marked as unread for all.",
"watch": "Watch",
"share_this_post": "Share this Post",

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

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

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

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

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

@ -3,9 +3,9 @@ define(function() {
Groups.init = function() {
var yourid = templates.get('yourid'),
createEl = document.getElementById('create'),
createEl = $('#create'),
createModal = $('#create-modal'),
createSubmitBtn = document.getElementById('create-modal-go'),
createSubmitBtn = $('#create-modal-go'),
createNameEl = $('#create-group-name'),
detailsModal = $('#group-details-modal'),
detailsSearch = detailsModal.find('#group-details-search'),
@ -15,14 +15,14 @@ define(function() {
searchDelay = undefined,
listEl = $('#groups-list');
createEl.addEventListener('click', function() {
createEl.on('click', function() {
createModal.modal('show');
setTimeout(function() {
createNameEl.focus();
}, 250);
}, false);
});
createSubmitBtn.addEventListener('click', function() {
createSubmitBtn.on('click', function() {
var submitObj = {
name: createNameEl.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>';
break;
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;
default:
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() {
var action = this.getAttribute('data-action'),
gid = $(this).parents('li[data-gid]').attr('data-gid');
var el = $(this),
action = el.attr('data-action'),
gid = el.parents('li[data-gid]').attr('data-gid');
switch (action) {
case 'delete':
@ -80,28 +81,20 @@ define(function() {
var formEl = detailsModal.find('form'),
nameEl = formEl.find('#change-group-name'),
descEl = formEl.find('#change-group-desc'),
memberIcon = document.createElement('li'),
numMembers = groupObj.members.length,
membersFrag = document.createDocumentFragment(),
memberIconImg, x;
x;
nameEl.val(groupObj.name);
descEl.val(groupObj.description);
// Member list
memberIcon.innerHTML = '<img /><span></span>';
memberIconImg = memberIcon.querySelector('img');
memberIconLabel = memberIcon.querySelector('span');
if (numMembers > 0) {
groupMembersEl.empty();
for (x = 0; x < numMembers; x++) {
memberIconImg.src = groupObj.members[x].picture;
memberIconLabel.innerHTML = groupObj.members[x].username;
memberIcon.setAttribute('data-uid', groupObj.members[x].uid);
membersFrag.appendChild(memberIcon.cloneNode(true));
var memberIcon = $('<li />')
.append($('<img />').attr('src', groupObj.members[x].picture))
.append($('<span />').attr('data-uid', groupObj.members[x].uid).html(groupObj.members[x].username));
groupMembersEl.append(memberIcon);
}
groupMembersEl.html('');
groupMembersEl[0].appendChild(membersFrag);
}
detailsModal.attr('data-gid', groupObj.gid);
@ -118,43 +111,39 @@ define(function() {
searchDelay = setTimeout(function() {
var searchText = searchEl.value,
resultsEl = document.getElementById('group-details-search-results'),
foundUser = document.createElement('li'),
foundUserImg, foundUserLabel;
foundUser.innerHTML = '<img /><span></span>';
foundUserImg = foundUser.getElementsByTagName('img')[0];
foundUserLabel = foundUser.getElementsByTagName('span')[0];
resultsEl = $('#group-details-search-results'),
foundUser;
socket.emit('admin.user.search', searchText, function(err, results) {
if (!err && results && results.users.length > 0) {
var numResults = results.users.length,
resultsSlug = document.createDocumentFragment(),
x;
var numResults = results.users.length, x;
if (numResults > 4) numResults = 4;
resultsEl.empty();
for (x = 0; x < numResults; x++) {
foundUserImg.src = results.users[x].picture;
foundUserLabel.innerHTML = results.users[x].username;
foundUser.setAttribute('title', results.users[x].username);
foundUser.setAttribute('data-uid', results.users[x].uid);
resultsSlug.appendChild(foundUser.cloneNode(true));
}
foundUser = $('<li />');
foundUser
.attr({title: results.users[x].username, 'data-uid': results.users[x].uid})
.append($('<img />').attr('src', results.users[x].picture))
.append($('<span />').html(results.users[x].username));
resultsEl.innerHTML = '';
resultsEl.appendChild(resultsSlug);
} else resultsEl.innerHTML = '<li>No Users Found</li>';
resultsEl.appendChild(foundUser);
}
} else {
resultsEl.html('<li>No Users Found</li>');
}
});
}, 200);
});
searchResults.on('click', 'li[data-uid]', function() {
var userLabel = this,
uid = parseInt(this.getAttribute('data-uid')),
var userLabel = $(this),
uid = parseInt(userLabel.attr('data-uid')),
gid = detailsModal.attr('data-gid'),
members = [];
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) {
@ -170,7 +159,7 @@ define(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');
socket.emit('admin.groups.get', gid, function(err, groupObj){

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

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

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

@ -2,14 +2,14 @@ define(function() {
var Topics = {};
Topics.init = function() {
var topicsListEl = document.querySelector('.topics'),
loadMoreEl = document.getElementById('topics_loadmore');
var topicsListEl = $('.topics'),
loadMoreEl = $('#topics_loadmore');
this.resolveButtonStates();
$(topicsListEl).on('click', '[data-action]', function() {
topicsListEl.on('click', '[data-action]', function() {
var $this = $(this),
action = this.getAttribute('data-action'),
action = $this.attr('data-action'),
tid = $this.parents('[data-tid]').attr('data-tid');
switch (action) {
@ -40,17 +40,17 @@ define(function() {
}
});
loadMoreEl.addEventListener('click', function() {
if (this.className.indexOf('disabled') === -1) {
var topics = document.querySelectorAll('.topics li[data-tid]');
loadMoreEl.on('click', function() {
if (!$(this).hasClass('disabled')) {
var topics = $('.topics li[data-tid]');
if(!topics.length) {
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', {
limit: 10,
after: lastTid
@ -59,27 +59,27 @@ define(function() {
return app.alertError(err.message);
}
var btnEl = document.getElementById('topics_loadmore');
var btnEl = $('#topics_loadmore');
if (topics.length > 0) {
var html = templates.prepare(templates['admin/topics'].blocks['topics']).parse({
topics: topics
}),
topicsListEl = document.querySelector('.topics');
topicsListEl = $('.topics');
// Fix relative paths
html = html.replace(/\{relative_path\}/g, RELATIVE_PATH);
topicsListEl.innerHTML += html;
topicsListEl.html(topicsListEl.html() + html);
Topics.resolveButtonStates();
btnEl.innerHTML = 'Load More Topics';
btnEl.html('Load More Topics');
$('span.timeago').timeago();
} else {
// Exhausted all topics
btnEl.className += ' disabled';
btnEl.innerHTML = 'No more topics';
btnEl.addClass('disabled');
btnEl.html('No more topics');
}
});
}
@ -88,24 +88,26 @@ define(function() {
Topics.resolveButtonStates = function() {
// Resolve proper button state for all topics
var topicsListEl = document.querySelector('.topics'),
topicEls = topicsListEl.querySelectorAll('li'),
var topicsListEl = $('.topics'),
topicEls = topicsListEl.find('li'),
numTopics = topicEls.length;
for (var x = 0; x < numTopics; x++) {
if (topicEls[x].getAttribute('data-pinned') === '1') {
topicEls[x].querySelector('[data-action="pin"]').className += ' active';
topicEls[x].removeAttribute('data-pinned');
var topic = topicEls.eq(x);
if (topic.attr('data-pinned') === '1') {
topic.find('[data-action="pin"]').addClass('active');
topic.removeAttr('data-pinned');
}
if (topicEls[x].getAttribute('data-locked') === '1') {
topicEls[x].querySelector('[data-action="lock"]').className += ' active';
topicEls[x].removeAttribute('data-locked');
if (topic.attr('data-locked') === '1') {
topic.find('[data-action="lock"]').addClass('active');
topic.removeAttr('data-locked');
}
if (topicEls[x].getAttribute('data-deleted') === '1') {
topicEls[x].querySelector('[data-action="delete"]').className += ' active';
topicEls[x].removeAttribute('data-deleted');
if (topic.attr('data-deleted') === '1') {
topic.find('[data-action="delete"]').addClass('active');
topic.removeAttr('data-deleted');
}
}
}
};
Topics.setDeleted = function(err, response) {
if(err) {
@ -113,10 +115,9 @@ define(function() {
}
if (response && response.tid) {
var btnEl = document.querySelector('li[data-tid="' + response.tid + '"] button[data-action="delete"]');
$(btnEl).addClass('active');
$(btnEl).siblings('[data-action="lock"]').addClass('active');
var btnEl = $('li[data-tid="' + response.tid + '"] button[data-action="delete"]');
btnEl.addClass('active');
btnEl.siblings('[data-action="lock"]').addClass('active');
}
};
@ -126,10 +127,10 @@ define(function() {
}
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).siblings('[data-action="lock"]').removeClass('active');
btnEl.removeClass('active');
btnEl.siblings('[data-action="lock"]').removeClass('active');
}
};
@ -139,9 +140,9 @@ define(function() {
}
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) {
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) {
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) {
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,
loadingMoreUsers = false;
@ -165,15 +165,16 @@ define(function() {
parts = url.split('/'),
active = parts[parts.length - 1];
jQuery('.nav-pills li').removeClass('active');
jQuery('.nav-pills li a').each(function() {
if (this.getAttribute('href').match(active)) {
jQuery(this.parentNode).addClass('active');
$('.nav-pills li').removeClass('active');
$('.nav-pills li a').each(function() {
var $this = $(this);
if ($this.attr('href').match(active)) {
$this.parent().addClass('active');
return false;
}
});
jQuery('#search-user').on('keyup', function() {
$('#search-user').on('keyup', function() {
if (timeoutId !== 0) {
clearTimeout(timeoutId);
timeoutId = 0;
@ -182,7 +183,7 @@ define(function() {
timeoutId = setTimeout(function() {
var username = $('#search-user').val();
jQuery('.fa-spinner').removeClass('none');
$('.fa-spinner').removeClass('none');
socket.emit('admin.user.search', username, function(err, data) {
if(err) {
@ -195,7 +196,7 @@ define(function() {
userListEl = document.querySelector('.users');
userListEl.innerHTML = html;
jQuery('.fa-spinner').addClass('none');
$('.fa-spinner').addClass('none');
if (data && data.users.length === 0) {
$('#user-notfound-notify').html('User not found!')

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

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

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

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

@ -93,7 +93,7 @@ define(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() {

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

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

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

@ -18,15 +18,16 @@ define(function() {
app.addCommasToNumbers();
jQuery('.nav-pills li').removeClass('active');
jQuery('.nav-pills li a').each(function() {
if (this.getAttribute('href').match(active)) {
jQuery(this.parentNode).addClass('active');
$('.nav-pills li').removeClass('active');
$('.nav-pills li a').each(function() {
var $this = $(this);
if ($this.attr('href').match(active)) {
$this.parent().addClass('active');
return false;
}
});
jQuery('#search-user').on('keyup', function() {
$('#search-user').on('keyup', function() {
if (timeoutId !== 0) {
clearTimeout(timeoutId);
timeoutId = 0;
@ -36,15 +37,15 @@ define(function() {
var username = $('#search-user').val();
if (username == '') {
jQuery('#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').html('<i class="fa fa-circle-o"></i>');
$('#user-notfound-notify').parent().removeClass('btn-warning label-warning btn-success label-success');
return;
}
if (lastSearch === username) return;
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() {
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) {
var chatsFrag = document.createDocumentFragment(),
chatEl = document.createElement('li'),
numChats = chats.length,
x, userObj;
var numChats = chats.length,
chatEl, x, userObj;
chatsListEl.empty();
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 {
translator.get('modules:chat.no_active', function(str) {
chatEl.className = 'no_active';
chatEl.innerHTML = '<a href="#">' + str + '</a>';
chatsFrag.appendChild(chatEl.cloneNode(true));
chatsListEl.empty();
chatsListEl.html(chatsFrag);
chatEl = $('<li />')
.addClass('no_active')
.html('<a href="#">' + str + '</a>');
chatsListEl.append(chatEl);
});
}
});
@ -79,15 +81,15 @@ define(['taskbar', 'string'], function(taskbar, S) {
}
});
chatModal.css('zIndex', topZ + 1);
}
};
module.getModal = function(touid) {
return $('#chat-modal-' + touid);
}
};
module.modalExists = function(touid) {
return $('#chat-modal-' + touid).length !== 0;
}
};
function checkStatus(chatModal) {
socket.emit('user.isOnline', chatModal.touid, function(err, data) {
@ -162,7 +164,7 @@ define(['taskbar', 'string'], function(taskbar, S) {
callback(chatModal);
});
});
}
};
module.center = function(chatModal) {
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.find('#chat-message-input').focus();
return chatModal;
}
};
module.load = function(uuid) {
var chatModal = $('div[UUID="'+uuid+'"]');
@ -180,7 +182,7 @@ define(['taskbar', 'string'], function(taskbar, S) {
scrollToBottom(chatModal.find('#chat-content'));
module.center(chatModal);
module.bringModalToTop(chatModal);
}
};
module.minimize = function(uuid) {
var chatModal = $('div[UUID="'+uuid+'"]');
@ -188,7 +190,7 @@ define(['taskbar', 'string'], function(taskbar, S) {
taskbar.minimize('chat', uuid);
clearInterval(chatModal.intervalId);
chatModal.intervalId = 0;
}
};
function getChatMessages(chatModal, callback) {
socket.emit('modules.chats.get', {touid:chatModal.touid}, function(err, messages) {

@ -4,6 +4,18 @@ define(['taskbar'], function(taskbar) {
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) {
$el.wrap('<form />').closest('form').get(0).reset();
$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
function findBootstrapEnvironment() {
var envs = ['xs', 'sm', 'md', 'lg'];
var envs = ['xs', 'sm', 'md', 'lg'],
$el = $('<div>');
$el = $('<div>');
$el.appendTo($('body'));
for (var i = envs.length - 1; i >= 0; i--) {
@ -73,8 +85,8 @@ define(['taskbar'], function(taskbar) {
function initializeDragAndDrop(post_uuid) {
if(jQuery.event.props.indexOf('dataTransfer') === -1) {
jQuery.event.props.push('dataTransfer');
if($.event.props.indexOf('dataTransfer') === -1) {
$.event.props.push('dataTransfer');
}
var draggingDocument = false;
@ -88,7 +100,7 @@ define(['taskbar'], function(taskbar) {
$(document).off('dragstart').on('dragstart', function(e) {
draggingDocument = true;
}).off('dragend').on('dragend', function(e) {
draggingDocument = false;
draggingDocument = false;
});
textarea.on('dragenter', function(e) {
@ -116,17 +128,24 @@ define(['taskbar'], function(taskbar) {
drop.on('drop', function(e) {
e.preventDefault();
var dt = e.dataTransfer,
files = dt.files;
var files = e.files || (e.dataTransfer || {}).files || (e.target.value ? [e.target.value] : []),
fd;
if(files.length) {
var fd = new FormData();
for (var i = 0, file; file = dt.files[i]; i++) {
fd.append('files[]', file, file.name);
if (window.FormData) {
fd = new FormData();
for (var i = 0, file; file = files[i]; i++) {
fd.append('files[]', file, file.name);
}
}
fileForm[0].reset();
uploadContentFiles({files: files, post_uuid: post_uuid, route: '/api/post/upload', formData: fd});
// fileForm[0].reset();
uploadContentFiles({
files: files,
post_uuid: post_uuid,
route: '/api/post/upload',
formData: fd
});
}
drop.hide();
@ -135,7 +154,8 @@ define(['taskbar'], function(taskbar) {
$(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) {
@ -143,11 +163,18 @@ define(['taskbar'], function(taskbar) {
if(blob) {
blob.name = 'upload-'+ utils.generateUUID();
var fd = new FormData();
fd.append('files[]', blob, blob.name);
if (window.FormData) {
fd = new FormData();
fd.append('files[]', blob, blob.name);
}
fileForm[0].reset();
uploadContentFiles({files: [blob], post_uuid: post_uuid, route: '/api/post/upload', formData: fd});
// fileForm[0].reset();
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);
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...) ';
if(files[i].size > parseInt(config.maximumFileSize, 10) * 1024) {
@ -181,6 +208,7 @@ define(['taskbar'], function(taskbar) {
uploadForm.off('submit').submit(function() {
$(this).find('#postUploadCsrf').val($('#csrf_token').val());
if(formData) {
formData.append('_csrf', $('#csrf_token').val());
}
@ -191,19 +219,25 @@ define(['taskbar'], function(taskbar) {
resetForm: true,
clearForm: true,
formData: formData,
error: function(xhr) {
xhr = maybeParse(xhr);
app.alertError('Error uploading file!\nStatus : ' + xhr.status + '\nMessage : ' + xhr.responseText);
if (typeof callback == 'function')
callback(xhr);
},
uploadProgress: function(event, position, total, percent) {
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');
textarea.val(current.replace(re, files[i].name+'](uploading ' + percent + '%)'));
}
},
success: function(uploads) {
uploads = maybeParse(uploads);
if(uploads && uploads.length) {
for(var i=0; i<uploads.length; ++i) {
@ -218,7 +252,7 @@ define(['taskbar'], function(taskbar) {
callback(null, uploads);
},
complete: function(xhr, status) {
complete: function() {
uploadForm[0].reset();
composer.posts[post_uuid].uploadsInProgress.pop();
}
@ -255,11 +289,15 @@ define(['taskbar'], function(taskbar) {
$(this).ajaxSubmit({
formData: formData,
error: function(xhr) {
xhr = maybeParse(xhr);
app.alertError('Error uploading file!\nStatus : ' + xhr.status + '\nMessage : ' + xhr.responseText);
if (typeof callback == 'function')
callback(xhr);
},
success: function(uploads) {
uploads = maybeParse(uploads);
postContainer.find('#topic-thumb-url').val((uploads[0] || {}).url || '').trigger('change');
if (typeof callback == 'function')
callback(null, uploads);
@ -530,19 +568,23 @@ define(['taskbar'], function(taskbar) {
$('#files').click();
});
$('#files').on('change', function(e) {
var files = e.target.files;
postContainer.find('#files').on('change', function(e) {
var files = (e.target || {}).files || ($(this).val() ? [{name: $(this).val(), type: utils.fileMimeType($(this).val())}] : null);
if(files) {
uploadContentFiles({files: files, post_uuid: post_uuid, route: '/api/post/upload'});
}
});
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) {
var fd = new FormData();
for (var i = 0, file; file = files[i]; i++) {
fd.append('files[]', file, file.name);
if (window.FormData) {
fd = new FormData();
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});
}
@ -573,21 +615,21 @@ define(['taskbar'], function(taskbar) {
resizeCenterY = 0,
resizeOffset = 0,
resizeStart = function(e) {
resizeRect = resizeEl.getBoundingClientRect();
resizeRect = resizeEl[0].getBoundingClientRect();
resizeCenterY = resizeRect.top + (resizeRect.height/2);
resizeOffset = resizeCenterY - e.clientY;
resizeActive = true;
$(window).on('mousemove', resizeAction);
$(window).on('mouseup', resizeStop);
document.body.addEventListener('touchmove', resizeTouchAction);
$('body').on('touchmove', resizeTouchAction);
},
resizeStop = function() {
resizeActive = false;
bodyEl.focus();
$(window).off('mousemove', resizeAction);
$(window).off('mouseup', resizeStop);
document.body.removeEventListener('touchmove', resizeTouchAction);
$('body').off('touchmove', resizeTouchAction);
},
resizeTouchAction = function(e) {
e.preventDefault();
@ -617,22 +659,20 @@ define(['taskbar'], function(taskbar) {
},
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();
resizeStart(e.touches[0]);
});
resizeEl.addEventListener('touchend', function(e) {
resizeEl.on('touchend', function(e) {
e.preventDefault();
resizeStop();
});
// .on('mousedown touchstart', resizeStart)
// .on('mouseup touchend', resizeStop)
window.addEventListener('resize', function() {
$(window).on('resize', function() {
if (composer.active !== undefined) {
composer.activateReposition(composer.active);
}
@ -659,7 +699,6 @@ define(['taskbar'], function(taskbar) {
}
var percentage = localStorage.getItem('composer:resizePercentage'),
bodyRect = document.body.getBoundingClientRect(),
postContainer = $('#cmp-uuid-' + post_uuid);
composer.active = post_uuid;
@ -680,10 +719,12 @@ define(['taskbar'], function(taskbar) {
postContainer.find('.upload-instructions').removeClass('hide');
}
postContainer.find('.img-upload-btn').removeClass('hide');
postContainer.find('#files.lt-ie9').removeClass('hide');
}
if(config.allowFileUploads) {
postContainer.find('.file-upload-btn').removeClass('hide');
postContainer.find('#files.lt-ie9').removeClass('hide');
}
postContainer.css('visibility', 'visible')
@ -782,155 +823,6 @@ define(['taskbar'], function(taskbar) {
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 {
newTopic: composer.newTopic,
newReply: composer.newReply,

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

@ -1,6 +1,16 @@
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) {
$('#upload-picture-modal').modal('show').removeClass('hide');
@ -21,7 +31,7 @@ define(function() {
$('#uploadForm').submit();
});
$('#uploadForm').off('submit').submit(function() {
uploadForm.off('submit').submit(function() {
function status(message) {
module.hideAlerts();
@ -52,8 +62,8 @@ define(function() {
$(this).ajaxSubmit({
error: function(xhr) {
xhr = maybeParse(xhr);
error('Error: ' + xhr.status);
},
@ -62,6 +72,8 @@ define(function() {
},
success: function(response) {
response = maybeParse(response);
if (response.error) {
error(response.error);
return;
@ -78,14 +90,14 @@ define(function() {
return false;
});
}
};
module.hideAlerts = function() {
$('#alert-status').addClass('hide');
$('#alert-success').addClass('hide');
$('#alert-error').addClass('hide');
$('#upload-progress-box').addClass('hide');
}
};
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 {
fs = require('fs'),
fs = require('fs');
path = require('path');
} catch (e) {}
templates.force_refresh = function (tpl) {
return !!config.force_refresh[tpl];
}
};
templates.get_custom_map = function (tpl) {
if (config['custom_mapping'] && tpl) {
@ -34,7 +34,7 @@
}
templates.is_available = function (tpl) {
return jQuery.inArray(tpl, available_templates) !== -1;
return $.inArray(tpl, available_templates) !== -1;
};
templates.ready = function (callback) {
@ -113,7 +113,7 @@
}
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];
available_templates = templates_data[0];
templates.ready();
@ -127,7 +127,7 @@
templates.init = function (templates_to_load, custom_templates) {
loadTemplates(templates_to_load || [], custom_templates || false);
}
};
templates.render = function(filename, options, fn) {
if ('function' === typeof options) {
@ -148,7 +148,7 @@
} else {
return fn(null, templates[tpl].parse(options));
}
}
};
templates.getTemplateNameFromUrl = function (url) {
var parts = url.split('?')[0].split('/');
@ -159,7 +159,7 @@
}
}
return '';
}
};
templates.preload_template = function(tpl_name, callback) {
@ -171,12 +171,12 @@
// should be named something else
// TODO: The "Date.now()" in the line below is only there for development purposes.
// 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 () {
this.toString = function () {
return this.html;
};
}
};
template.prototype.parse = parse;
template.prototype.html = String(html);
@ -186,7 +186,7 @@
callback();
});
}
};
templates.load_template = function (callback, url, template) {
var location = document.location || window.location,
@ -243,7 +243,7 @@
$('#content').html(translatedTemplate);
jQuery('#content [template-variable]').each(function (index, element) {
$('#content [template-variable]').each(function (index, element) {
var value = null;
switch ($(element).attr('template-type')) {
@ -268,29 +268,29 @@
});
}
}
};
templates.cancelRequest = function() {
if (apiXHR) {
apiXHR.abort();
}
}
};
templates.flush = function () {
parsed_variables = {};
}
};
templates.get = function (key) {
return parsed_variables[key];
}
};
templates.set = function (key, value) {
parsed_variables[key] = value;
}
};
templates.setGlobal = function(key, value) {
templates.globals[key] = value;
}
};
//modified from https://github.com/psychobunny/dcp.templates
var parse = function (data) {
@ -451,4 +451,4 @@
module: {
exports: {}
}
} : module)
} : module);

@ -105,7 +105,7 @@
if (value) {
for (var i = 1, ii = variables.length; i < ii; i++) {
var variable = variables[i].replace(']]', '');
value = value.replace('%' + i, variable);
value = ('' + value).replace('%' + i, variable);
}
text = text.replace(key, value);
@ -119,6 +119,7 @@
for (var key in keys) {
if (keys.hasOwnProperty(key)) {
keys[key] = '' + keys[key];
var variables = keys[key].split(/[,][?\s+]/);
var parsedKey = keys[key].replace('[[', '').replace(']]', '').split(':');
@ -127,7 +128,7 @@
}
var languageFile = parsedKey[0];
parsedKey = parsedKey[1].split(',')[0];
parsedKey = ('' + parsedKey[1]).split(',')[0];
if (files.loaded[languageFile]) {
data = insertLanguage(data, keys[key], files.loaded[languageFile][parsedKey], variables);
@ -178,7 +179,7 @@
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;
if (callback) {

@ -99,15 +99,14 @@
return difference + (min ? 'y' : ' year') + (difference !== 1 && !min ? 's' : '');
},
invalidUnicodeChars : XRegExp('[^\\p{L}\\s\\d\\-_]', 'g'),
invalidLatinChars : /[^\w\s\d\-_]/g,
trimRegex : /^\s+|\s+$/g,
collapseWhitespace : /\s+/g,
collapseDash : /-+/g,
trimTrailingDash : /-$/g,
trimLeadingDash : /^-/g,
isLatin : /^[\w]+$/,
invalidUnicodeChars: XRegExp('[^\\p{L}\\s\\d\\-_]', 'g'),
invalidLatinChars: /[^\w\s\d\-_]/g,
trimRegex: /^\s+|\s+$/g,
collapseWhitespace: /\s+/g,
collapseDash: /-+/g,
trimTrailingDash: /-$/g,
trimLeadingDash: /^-/g,
isLatin: /^[\w]+$/,
//http://dense13.com/blog/2009/05/03/converting-string-to-slug-javascript/
slugify: function(str) {
@ -138,9 +137,11 @@
isPasswordValid: function(password) {
return password && password.indexOf(' ') === -1;
},
isNumber: function(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
},
// shallow objects merge
merge: function() {
var result = {}, obj, keys;
@ -154,6 +155,43 @@
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) {
var firstChar = url.slice(0, 1);
return (firstChar === '.' || firstChar === '/');
@ -200,64 +238,8 @@
}
};
if (!String.prototype.trim) {
String.prototype.trim = function() {
return this.replace(utils.trimRegex, '');
};
}
if ('undefined' !== typeof window) {
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 ? {

@ -3,15 +3,25 @@
<head>
<title>NodeBB Administration Panel</title>
<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>
var RELATIVE_PATH = "{relative_path}";
</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="//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>
<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}/src/app.js?{cache-buster}"></script>
<script src="{relative_path}/src/templates.js?{cache-buster}"></script>
@ -37,9 +47,9 @@
});
</script>
<script src="{relative_path}/src/overrides.js"></script>
<script src="{relative_path}/src/utils.js"></script>
<link rel="stylesheet" type="text/css" href="{relative_path}/stylesheet.css?{cache-buster}" />
</head>
<body class="admin">

@ -1,14 +1,5 @@
<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">
<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]]" />
</div>
<div class="form-group">
<!-- todo: drag and drop? -->
<label for="topic-thumb-file">[[topic:composer.thumb_file_label]]</label>
<input type="file" id="topic-thumb-file" class="form-control" />
</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-list"></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>
</span>
<span class="btn btn-link file-upload-btn hide" tabindex="-1">
<i class="fa fa-upload"></i>
</span>
<!--[if gte IE 9]><!-->
<span class="btn btn-link img-upload-btn hide" tabindex="-1">
<i class="fa fa-picture-o"></i>
</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">
<input type="file" id="files" name="files[]" multiple class="hide"/>
<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>
</div>
</div>

@ -18,6 +18,13 @@
<style type="text/css">{customCSS}</style>
<!-- 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>
var RELATIVE_PATH = "{relative_path}";
</script>

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

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

@ -469,16 +469,25 @@ var path = require('path'),
async.map(files, filesIterator, function(err, images) {
deleteTempFiles();
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) {
upload(req, res, function(file, next) {
if(file.type.match('image.*')) {
if(file.type.match(/image./)) {
posts.uploadPostImage(file, next);
} else {
posts.uploadPostFile(file, next);
@ -488,7 +497,7 @@ var path = require('path'),
app.post('/topic/thumb/upload', function(req, res, next) {
upload(req, res, function(file, next) {
if(file.type.match('image.*')) {
if(file.type.match(/image./)) {
topics.uploadTopicThumb(file, next);
} else {
res.json(500, {message: 'Invalid File'});

Loading…
Cancel
Save