';
- themeFrag.appendChild(themeEl.cloneNode(true));
+ theme = bootswatch.themes[x];
+ themeEl = $('
').attr({
+ 'data-type': 'bootswatch',
+ 'data-css': theme.cssCdn,
+ 'data-theme': theme.name
+ }).html('
');
+ 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('
')
- .children('small').html('');
+ .append('
')
+ .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;
diff --git a/public/src/forum/admin/topics.js b/public/src/forum/admin/topics.js
index 1d112ddca4..545fc6b2a3 100644
--- a/public/src/forum/admin/topics.js
+++ b/public/src/forum/admin/topics.js
@@ -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 = '
Retrieving topics';
+ $(this).html('
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');
}
};
diff --git a/public/src/forum/admin/users.js b/public/src/forum/admin/users.js
index 42e466534d..25e6aee335 100644
--- a/public/src/forum/admin/users.js
+++ b/public/src/forum/admin/users.js
@@ -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!')
diff --git a/public/src/forum/category.js b/public/src/forum/category.js
index 09eacd8c55..1a27392a4d 100644
--- a/public/src/forum/category.js
+++ b/public/src/forum/category.js
@@ -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);
diff --git a/public/src/forum/footer.js b/public/src/forum/footer.js
index d5eac0bf4f..e866b70cf9 100644
--- a/public/src/forum/footer.js
+++ b/public/src/forum/footer.js
@@ -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);
}
diff --git a/public/src/forum/login.js b/public/src/forum/login.js
index 1f4df45ea6..11afd12cdc 100644
--- a/public/src/forum/login.js
+++ b/public/src/forum/login.js
@@ -52,7 +52,7 @@ define(function() {
return false;
});
- document.querySelector('#content input').focus();
+ $('#content input').focus();
};
return Login;
diff --git a/public/src/forum/recent.js b/public/src/forum/recent.js
index 8837c41367..8c7d6c3b32 100644
--- a/public/src/forum/recent.js
+++ b/public/src/forum/recent.js
@@ -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;
}
});
diff --git a/public/src/forum/register.js b/public/src/forum/register.js
index 4f0acb2a0d..674f53af6e 100644
--- a/public/src/forum/register.js
+++ b/public/src/forum/register.js
@@ -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() {
diff --git a/public/src/forum/reset.js b/public/src/forum/reset.js
index a04b3d31e5..f67e1a28b8 100644
--- a/public/src/forum/reset.js
+++ b/public/src/forum/reset.js
@@ -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');
}
};
};
diff --git a/public/src/forum/reset_code.js b/public/src/forum/reset_code.js
index 2eb4b49f28..0afd3fc266 100644
--- a/public/src/forum/reset_code.js
+++ b/public/src/forum/reset_code.js
@@ -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();
}
});
};
diff --git a/public/src/forum/topic.js b/public/src/forum/topic.js
index f603ca4aba..1f3c58a24b 100644
--- a/public/src/forum/topic.js
+++ b/public/src/forum/topic.js
@@ -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);
@@ -112,54 +110,54 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
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 = '
' + info.name;
- categoryEl.setAttribute('data-cid', info.cid);
- categoriesFrag.appendChild(categoryEl.cloneNode(true));
- }
- categoriesEl.appendChild(categoriesFrag);
- modalBody[0].removeChild(loadingEl);
+ categoryEl = $('
');
+ categoryEl.css({background: info.bgColor, color: info.color || '#fff'})
+ .addClass(info.disabled === '1' ? ' disabled' : '')
+ .attr('data-cid', info.cid)
+ .html('
' + info.name);
- 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;
+ categoriesEl.append(categoryEl);
+ }
+ 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
';
+ 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
');
socket.emit('topics.move', {
tid: tid,
@@ -195,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();
@@ -259,7 +257,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
function closeForkModal() {
for(var i=0; i
0) {
var snippet = selection.toString();
@@ -733,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;
@@ -1049,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;
}
@@ -1139,7 +1135,7 @@ define(['composer', 'forum/pagination'], function(composer, pagination) {
}
}
}
- }
+ };
function onNewPostPagination(data) {
var posts = data.posts;
diff --git a/public/src/forum/users.js b/public/src/forum/users.js
index e0af14faf7..e64b29ec00 100644
--- a/public/src/forum/users.js
+++ b/public/src/forum/users.js
@@ -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('');
- jQuery('#user-notfound-notify').parent().removeClass('btn-warning label-warning btn-success label-success');
+ $('#user-notfound-notify').html('');
+ $('#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('');
+ $('#user-notfound-notify').html('');
setTimeout(function() {
socket.emit('user.search', username, function(err, data) {
diff --git a/public/src/modules/chat.js b/public/src/modules/chat.js
index 230f4d4ad3..a79e213b48 100644
--- a/public/src/modules/chat.js
+++ b/public/src/modules/chat.js
@@ -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
' + userObj.username + '';
+ chatEl = $('')
+ .attr('data-uid', userObj.uid)
+ .html('
' + userObj.username + '');
- chatsFrag.appendChild(chatEl.cloneNode(true));
+ chatsListEl.append(chatEl);
}
-
- chatsListEl.empty();
- chatsListEl.html(chatsFrag);
} else {
translator.get('modules:chat.no_active', function(str) {
- chatEl.className = 'no_active';
- chatEl.innerHTML = '' + str + '';
- chatsFrag.appendChild(chatEl.cloneNode(true));
-
- chatsListEl.empty();
- chatsListEl.html(chatsFrag);
+ chatEl = $('')
+ .addClass('no_active')
+ .html('' + str + '');
+ 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) {
diff --git a/public/src/modules/composer.js b/public/src/modules/composer.js
index 45b8c2b974..7cc896bcd5 100644
--- a/public/src/modules/composer.js
+++ b/public/src/modules/composer.js
@@ -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('').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 = $('');
- $el = $('
');
$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
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')
+ .html('')
+ .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 = '' +
- (options.icon ? '
' : '') +
- '' + (options.title || 'NodeBB Task') + '' +
- '';
- btnEl.setAttribute('data-module', module);
- btnEl.setAttribute('data-uuid', uuid);
- btnEl.className = options.state !== undefined ? options.state : 'active';
+ var btnEl = $('')
+ .html('' +
+ (options.icon ? '
' : '') +
+ '' + (options.title || 'NodeBB Task') + '' +
+ '')
+ .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();
diff --git a/public/src/modules/uploader.js b/public/src/modules/uploader.js
index c82073c17a..fe9715e4d0 100644
--- a/public/src/modules/uploader.js
+++ b/public/src/modules/uploader.js
@@ -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;
});
\ No newline at end of file
diff --git a/public/src/overrides.js b/public/src/overrides.js
new file mode 100644
index 0000000000..df4ab27f24
--- /dev/null
+++ b/public/src/overrides.js
@@ -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:{}});
+}
\ No newline at end of file
diff --git a/public/src/templates.js b/public/src/templates.js
index f3b239866d..cf12ba9a09 100644
--- a/public/src/templates.js
+++ b/public/src/templates.js
@@ -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);
diff --git a/public/src/translator.js b/public/src/translator.js
index 10c511fc21..265365ce5e 100644
--- a/public/src/translator.js
+++ b/public/src/translator.js
@@ -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) {
diff --git a/public/src/utils.js b/public/src/utils.js
index 2e4064d1f8..1ebd7e475b 100644
--- a/public/src/utils.js
+++ b/public/src/utils.js
@@ -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 ? {
diff --git a/public/templates/admin/header.tpl b/public/templates/admin/header.tpl
index 66a6f87187..944785c592 100644
--- a/public/templates/admin/header.tpl
+++ b/public/templates/admin/header.tpl
@@ -3,15 +3,25 @@
NodeBB Administration Panel
+
+
+
+
+
-
+
+
-
+
-
@@ -37,9 +47,9 @@
});
+
-
diff --git a/public/templates/composer.tpl b/public/templates/composer.tpl
index 584ba48153..e600021dc0 100644
--- a/public/templates/composer.tpl
+++ b/public/templates/composer.tpl
@@ -1,14 +1,5 @@
-
-
@@ -22,7 +13,6 @@
-
@@ -41,16 +31,26 @@
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/public/templates/header.tpl b/public/templates/header.tpl
index 4a5aa70794..decbae43da 100644
--- a/public/templates/header.tpl
+++ b/public/templates/header.tpl
@@ -18,6 +18,13 @@
+
+
diff --git a/src/meta.js b/src/meta.js
index cb8f43c3fb..f4411904fd 100644
--- a/src/meta.js
+++ b/src/meta.js
@@ -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',
diff --git a/src/routes/admin.js b/src/routes/admin.js
index d04ac78b80..1741f62c6f 100644
--- a/src/routes/admin.js
+++ b/src/routes/admin.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')) {
diff --git a/src/routes/api.js b/src/routes/api.js
index 7737f49e38..4b326fe565 100644
--- a/src/routes/api.js
+++ b/src/routes/api.js
@@ -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'});