diff --git a/public/src/ajaxify.js b/public/src/ajaxify.js
index 1052d03541..b7d70ed170 100644
--- a/public/src/ajaxify.js
+++ b/public/src/ajaxify.js
@@ -34,7 +34,7 @@ var ajaxify = {};
 	ajaxify.go = function (url, callback, template, quiet) {
 		// start: the following should be set like so: ajaxify.onchange(function(){}); where the code actually belongs
 		$(window).off('scroll');
-		app.enter_room('global');
+		app.enterRoom('global');
 
 		pagination = pagination || document.getElementById('pagination');
 		if (pagination) {
@@ -105,7 +105,7 @@ var ajaxify = {};
 					callback();
 				}
 
-				app.process_page();
+				app.processPage();
 
 				jQuery('#content, #footer').stop(true, true).fadeIn(200, function () {
 					if (window.location.hash) {
@@ -113,7 +113,9 @@ var ajaxify = {};
 					}
 
 					if (hash) {
-						app.scrollToPost(hash.substr(1));
+						require(['forum/topic'], function(topic) {
+							topic.scrollToPost(hash.substr(1))	
+						});
 					}
 				});
 
diff --git a/public/src/app.js b/public/src/app.js
index b7f714f0f0..ee61e2afc0 100644
--- a/public/src/app.js
+++ b/public/src/app.js
@@ -125,7 +125,7 @@ var socket,
 						setTimeout(app.logout, 1000);
 					});
 
-					app.enter_room('global');
+					app.enterRoom('global');
 				}
 			},
 			async: false
@@ -186,43 +186,35 @@ var socket,
 			clearTimeout(alert.attr('timeoutId'));
 			startTimeout(alert, params.timeout);
 		} else {
-			var div = document.createElement('div'),
-				button = document.createElement('button'),
-				strong = document.createElement('strong'),
-				p = document.createElement('p');
+			var div = $('<div id="' + alert_id + '" class="alert toaster-alert alert-' + params.type +'"></div>'),
+				button = $('<button class="close">&times;</button>'),
+				strong = $('<strong>' + title + '</strong>'),
+				p = $('<p>' + params.message + '</p>');
 
-			p.innerHTML = params.message;
-			strong.innerHTML = title;
+			div.append(button)
+				.append(strong)
+				.append(p);
 
-			div.className = "alert toaster-alert " + "alert-" + params.type;
-
-			div.setAttribute('id', alert_id);
-			div.appendChild(button);
-			div.appendChild(strong);
-			div.appendChild(p);
-
-			button.className = 'close';
-			button.innerHTML = '&times;';
-			button.onclick = function (ev) {
-				div.parentNode.removeChild(div);
-			}
+			button.on('click', function () {
+				div.remove();
+			});
 
 			if (params.location == null)
 				params.location = 'alert_window';
 
-			jQuery('#' + params.location).prepend(jQuery(div).fadeIn('100'));
+			$('#' + params.location).prepend(div.fadeIn('100'));
 
 			if (params.timeout) {
 				startTimeout(div, params.timeout);
 			}
 
 			if (params.clickfn) {
-				div.onclick = function () {
+				div.on('click', function () {
 					params.clickfn();
-					jQuery(div).fadeOut(500, function () {
-						this.remove();
+					div.fadeOut(500, function () {
+						$(this).remove();
 					});
-				}
+				});
 			}
 		}
 	}
@@ -251,22 +243,23 @@ var socket,
 		});
 	}
 
-	app.current_room = null;
-	app.enter_room = function (room) {
+	app.currentRoom = null;
+	app.enterRoom = function (room) {
 		if (socket) {
-			if (app.current_room === room)
+			if (app.currentRoom === room) {
 				return;
+			}
 
 			socket.emit('event:enter_room', {
 				'enter': room,
-				'leave': app.current_room
+				'leave': app.currentRoom
 			});
 
-			app.current_room = room;
+			app.currentRoom = room;
 		}
 	};
 
-	app.populate_online_users = function () {
+	app.populateOnlineUsers = function () {
 		var uids = [];
 
 		jQuery('.post-row').each(function () {
@@ -276,9 +269,7 @@ var socket,
 		socket.emit('api:user.get_online_users', uids);
 	}
 
-	app.process_page = function () {
-		app.populate_online_users();
-
+	function highlightNavigationLink() {
 		var path = window.location.pathname,
 			parts = path.split('/'),
 			active = parts[parts.length - 1];
@@ -295,6 +286,12 @@ var socket,
 				}
 			});
 		}
+	}
+
+	app.processPage = function () {
+		app.populateOnlineUsers();
+
+		highlightNavigationLink();
 
 		$('span.timeago').timeago();
 		$('.post-content img').addClass('img-responsive');
@@ -364,95 +361,7 @@ var socket,
 			chat.center(chatModal);
 		});
 	}
-
-	app.createNewPosts = function (data, infiniteLoaded) {
-		if(!data || (data.posts && !data.posts.length))
-			return;
-
-		if (data.posts[0].uid !== app.uid) {
-			data.posts[0].display_moderator_tools = 'none';
-		}
-
-		function removeAlreadyAddedPosts() {
-			data.posts = data.posts.filter(function(post) {
-				return $('#post-container li[data-pid="' + post.pid +'"]').length === 0;
-			});
-		}
-
-		function findInsertionPoint() {
-			var after = null,
-				firstPid = data.posts[0].pid;
-			$('#post-container li[data-pid]').each(function() {
-				if(parseInt(firstPid, 10) > parseInt($(this).attr('data-pid'), 10))
-				after = $(this);
-			else
-				return false;
-			});
-			return after;
-		}
-
-		removeAlreadyAddedPosts();
-		if(!data.posts.length)
-			return;
-		var insertAfter = findInsertionPoint();
-
-		var html = templates.prepare(templates['topic'].blocks['posts']).parse(data);
-		translator.translate(html, function(translatedHTML) {
-			var translated = $(translatedHTML);
-			if(!infiniteLoaded) {
-				translated.removeClass('infiniteloaded');
-			}
-
-			translated.insertAfter(insertAfter)
-				.hide()
-				.fadeIn('slow');
-
-			for (var x = 0, numPosts = data.posts.length; x < numPosts; x++) {
-				socket.emit('api:post.privileges', data.posts[x].pid);
-			}
-
-			app.infiniteLoaderActive = false;
-
-			app.populate_online_users();
-			app.addCommasToNumbers();
-			$('span.timeago').timeago();
-			$('.post-content img').addClass('img-responsive');
-		});
-	}
-
-	app.infiniteLoaderActive = false;
-
-	app.loadMorePosts = function (tid, callback) {
-		var	indicatorEl = $('.loading-indicator');
-
-		if (app.infiniteLoaderActive) {
-			return;
-		}
-
-		app.infiniteLoaderActive = true;
-
-		if (indicatorEl.attr('done') === '0') {
-			indicatorEl.fadeIn();
-		}
-
-		socket.emit('api:topic.loadMore', {
-			tid: tid,
-			after: $('#post-container .post-row.infiniteloaded').length
-		}, function (data) {
-			app.infiniteLoaderActive = false;
-			if (data.posts.length) {
-				indicatorEl.attr('done', '0');
-				app.createNewPosts(data, true);
-			} else {
-				indicatorEl.attr('done', '1');
-			}
-			indicatorEl.fadeOut();
-			if (callback) {
-				callback(data.posts);
-			}
-		});
-	}
-
+	
 	app.scrollToTop = function () {
 		$('body,html').animate({
 			scrollTop: 0
@@ -465,42 +374,6 @@ var socket,
 		});
 	}
 
-	app.scrollToPost = function (pid) {
-		if (!pid) {
-			return;
-		}
-
-		var container = $(document.body),
-			scrollTo = $('#post_anchor_' + pid),
-			tid = $('#post-container').attr('data-tid');
-
-		function animateScroll() {
-			$('body,html').animate({
-				scrollTop: scrollTo.offset().top - container.offset().top + container.scrollTop() - $('#header-menu').height()
-			}, 400);
-		}
-
-		if (!scrollTo.length && tid) {
-
-			var intervalID = setInterval(function () {
-				app.loadMorePosts(tid, function (posts) {
-					scrollTo = $('#post_anchor_' + pid);
-
-					if (tid && scrollTo.length) {
-						animateScroll();
-					}
-
-					if (!posts.length || scrollTo.length)
-						clearInterval(intervalID);
-				});
-			}, 100);
-
-		} else if (tid) {
-			animateScroll();
-		}
-
-	}
-
 	jQuery('document').ready(function () {
 		$('#search-form').on('submit', function () {
 			var input = $(this).find('input');
diff --git a/public/src/forum/account.js b/public/src/forum/account.js
index 82be082aeb..ce352d85c4 100644
--- a/public/src/forum/account.js
+++ b/public/src/forum/account.js
@@ -10,7 +10,7 @@ define(['forum/accountheader'], function(header) {
 
 		$(document).ready(function() {
 			var username = $('.account-username a').html();
-			app.enter_room('user/' + theirid);
+			app.enterRoom('user/' + theirid);
 
 			app.addCommasToNumbers();
 
diff --git a/public/src/forum/admin/index.js b/public/src/forum/admin/index.js
index 4b7008a541..c5cd4c413a 100644
--- a/public/src/forum/admin/index.js
+++ b/public/src/forum/admin/index.js
@@ -20,7 +20,7 @@ define(function() {
 			document.getElementById('connections').innerHTML = total;
 		});
 
-		app.enter_room('admin');
+		app.enterRoom('admin');
 		socket.emit('api:get_all_rooms');
 	};
 
diff --git a/public/src/forum/category.js b/public/src/forum/category.js
index 6faf331f43..3e9a73eef4 100644
--- a/public/src/forum/category.js
+++ b/public/src/forum/category.js
@@ -3,7 +3,6 @@ define(function () {
 
 	Category.init = function() {
 		var	cid = templates.get('category_id'),
-			room = 'category_' + cid,
 			twitterEl = jQuery('#twitter-intent'),
 			facebookEl = jQuery('#facebook-share'),
 			googleEl = jQuery('#google-share'),
@@ -12,7 +11,7 @@ define(function () {
 			google_url = templates.get('google-share-url'),
 			loadingMoreTopics = false;
 
-		app.enter_room(room);
+		app.enterRoom('category_' + cid);
 
 		twitterEl.on('click', function () {
 			window.open(twitter_url, '_blank', 'width=550,height=420,scrollbars=no,status=no');
diff --git a/public/src/forum/recent.js b/public/src/forum/recent.js
index 50e53792a9..934a3e248b 100644
--- a/public/src/forum/recent.js
+++ b/public/src/forum/recent.js
@@ -8,7 +8,7 @@ define(function() {
 	var active = '';
 
 	Recent.init = function() {
-		app.enter_room('recent_posts');
+		app.enterRoom('recent_posts');
 
 		ajaxify.register_events([
 			'event:new_topic',
diff --git a/public/src/forum/topic.js b/public/src/forum/topic.js
index 60ba06f1ef..06fd9aca66 100644
--- a/public/src/forum/topic.js
+++ b/public/src/forum/topic.js
@@ -1,5 +1,7 @@
 define(function() {
-	var	Topic = {};
+	var	Topic = {},
+		infiniteLoaderActive = false;
+
 
 	Topic.init = function() {
 		var expose_tools = templates.get('expose_tools'),
@@ -32,7 +34,7 @@ define(function() {
 
 			app.addCommasToNumbers();
 
-			app.enter_room('topic_' + tid);
+			app.enterRoom('topic_' + tid);
 
 			if($('#post-container .sub-posts').length) {
 				$('.topic-main-buttons').removeClass('hide').parent().removeClass('hide');
@@ -250,7 +252,7 @@ define(function() {
 			var bookmark = localStorage.getItem('topic:' + tid + ':bookmark');
 
 			if(bookmark) {
-				app.scrollToPost(parseInt(bookmark, 10));
+				Topic.scrollToPost(parseInt(bookmark, 10));
 			}
 
 			$('#post-container').on('click', '.deleted', function(ev) {
@@ -262,15 +264,15 @@ define(function() {
 			$(window).off('scroll').on('scroll', function() {
 				var bottom = ($(document).height() - $(window).height()) * 0.9;
 
-				if ($(window).scrollTop() > bottom && !app.infiniteLoaderActive && $('#post-container').children().length) {
-					app.loadMorePosts(tid, function(posts) {
+				if ($(window).scrollTop() > bottom && !infiniteLoaderActive && $('#post-container').children().length) {
+					loadMorePosts(tid, function(posts) {
 						fixDeleteStateForPosts();
 					});
 				}
 			});
 		}
 
-		var reply_fn = function() {
+		$('.topic').on('click', '.post_reply', function() {
 			var selectionText = '',
 				selection = window.getSelection() || document.getSelection();
 
@@ -284,8 +286,7 @@ define(function() {
 					cmp.push(tid, null, null, selectionText.length > 0 ? selectionText + '\n\n' : '');
 				});
 			}
-		};
-		$('.topic').on('click', '.post_reply', reply_fn);
+		});
 
 		$('#post-container').on('click', '.quote', function() {
 			if (thread_state.locked !== '1') {
@@ -312,12 +313,12 @@ define(function() {
 			if (element.attr('class') == 'icon-star-empty') {
 				socket.emit('api:posts.favourite', {
 					pid: pid,
-					room_id: app.current_room
+					room_id: app.currentRoom
 				});
 			} else {
 				socket.emit('api:posts.unfavourite', {
 					pid: pid,
-					room_id: app.current_room
+					room_id: app.currentRoom
 				});
 			}
 		});
@@ -450,7 +451,7 @@ define(function() {
 					});
 				}
 			}
-			app.populate_online_users();
+			app.populateOnlineUsers();
 		});
 
 		socket.on('event:rep_up', function(data) {
@@ -817,5 +818,129 @@ define(function() {
 		window.onload = updateHeader;
 	};
 
+	Topic.scrollToPost = function(pid) {
+		if (!pid) {
+			return;
+		}
+
+		var container = $(document.body),
+			scrollTo = $('#post_anchor_' + pid),
+			tid = $('#post-container').attr('data-tid');
+
+		function animateScroll() {
+			$('body,html').animate({
+				scrollTop: scrollTo.offset().top - container.offset().top + container.scrollTop() - $('#header-menu').height()
+			}, 400);
+		}
+
+		if (!scrollTo.length && tid) {
+
+			var intervalID = setInterval(function () {
+				loadMorePosts(tid, function (posts) {
+					scrollTo = $('#post_anchor_' + pid);
+
+					if (tid && scrollTo.length) {
+						animateScroll();
+					}
+
+					if (!posts.length || scrollTo.length)
+						clearInterval(intervalID);
+				});
+			}, 100);
+
+		} else if (tid) {
+			animateScroll();
+		}
+	}
+
+	function createNewPosts(data, infiniteLoaded) {
+		if(!data || (data.posts && !data.posts.length))
+			return;
+
+		if (data.posts[0].uid !== app.uid) {
+			data.posts[0].display_moderator_tools = 'none';
+		}
+
+		function removeAlreadyAddedPosts() {
+			data.posts = data.posts.filter(function(post) {
+				return $('#post-container li[data-pid="' + post.pid +'"]').length === 0;
+			});
+		}
+
+		function findInsertionPoint() {
+			var after = null,
+				firstPid = data.posts[0].pid;
+			$('#post-container li[data-pid]').each(function() {
+				if(parseInt(firstPid, 10) > parseInt($(this).attr('data-pid'), 10))
+				after = $(this);
+			else
+				return false;
+			});
+			return after;
+		}
+
+		removeAlreadyAddedPosts();
+		if(!data.posts.length) {
+			return;
+		}
+		
+		var insertAfter = findInsertionPoint();
+
+		var html = templates.prepare(templates['topic'].blocks['posts']).parse(data);
+		
+		translator.translate(html, function(translatedHTML) {
+			var translated = $(translatedHTML);
+			if(!infiniteLoaded) {
+				translated.removeClass('infiniteloaded');
+			}
+
+			translated.insertAfter(insertAfter)
+				.hide()
+				.fadeIn('slow');
+
+			for (var x = 0, numPosts = data.posts.length; x < numPosts; x++) {
+				socket.emit('api:post.privileges', data.posts[x].pid);
+			}
+
+			infiniteLoaderActive = false;
+
+			app.populateOnlineUsers();
+			app.addCommasToNumbers();
+			$('span.timeago').timeago();
+			$('.post-content img').addClass('img-responsive');
+		});
+	}
+
+	function loadMorePosts(tid, callback) {
+		var	indicatorEl = $('.loading-indicator');
+
+		if (infiniteLoaderActive) {
+			return;
+		}
+
+		infiniteLoaderActive = true;
+
+		if (indicatorEl.attr('done') === '0') {
+			indicatorEl.fadeIn();
+		}
+
+		socket.emit('api:topic.loadMore', {
+			tid: tid,
+			after: $('#post-container .post-row.infiniteloaded').length
+		}, function (data) {
+			infiniteLoaderActive = false;
+			if (data.posts.length) {
+				indicatorEl.attr('done', '0');
+				createNewPosts(data, true);
+			} else {
+				indicatorEl.attr('done', '1');
+			}
+			indicatorEl.fadeOut();
+			if (callback) {
+				callback(data.posts);
+			}
+		});
+	}
+
 	return Topic;
 });
\ No newline at end of file