Files
NodeBB/public/src/ajaxify.js

231 lines
5.8 KiB
JavaScript
Raw Normal View History

2013-11-21 12:28:10 -05:00
"use strict";
2013-11-21 12:28:10 -05:00
var ajaxify = {};
(function ($) {
/*global app, templates, utils*/
2013-08-23 13:45:57 -04:00
var location = document.location || window.location,
rootUrl = location.protocol + '//' + (location.hostname || location.host) + (location.port ? ':' + location.port : ''),
2013-04-22 19:13:39 +00:00
content = null;
var current_state = null;
var executed = {};
2013-04-22 19:27:56 +00:00
var events = [];
ajaxify.register_events = function (new_page_events) {
2013-09-17 13:04:40 -04:00
for (var i = 0, ii = events.length; i < ii; i++) {
socket.removeAllListeners(events[i]); // optimize this to user removeListener(event, listener) instead.
}
events = new_page_events;
};
window.onpopstate = function (event) {
// "quiet": If set to true, will not call pushState
2013-11-21 12:28:10 -05:00
if (event !== null && event.state && event.state.url !== undefined) {
ajaxify.go(event.state.url, null, null, true);
2013-11-21 12:28:10 -05:00
}
};
var pagination, paginator_bar;
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.enterRoom('global');
pagination = pagination || document.getElementById('pagination');
paginator_bar = pagination ? document.body.querySelector('.progress-container') : undefined;
2013-11-21 12:28:10 -05:00
if (pagination) {
pagination.parentNode.style.display = 'none';
paginator_bar.style.display = 'none';
2013-11-21 12:28:10 -05:00
}
2013-08-28 01:23:19 +08:00
window.onscroll = null;
// end
2013-08-28 01:23:19 +08:00
// Remove trailing slash
url = url.replace(/\/$/, "");
2013-08-01 16:11:00 -04:00
var hash = window.location.hash;
2013-09-17 13:04:40 -04:00
if (url.indexOf(RELATIVE_PATH.slice(1)) !== -1) {
2013-07-10 18:42:38 -04:00
url = url.slice(RELATIVE_PATH.length);
}
var tpl_url = templates.get_custom_map(url.split('?')[0]);
2013-08-23 13:45:57 -04:00
if (tpl_url == false && !templates[url]) {
2013-09-17 13:04:40 -04:00
if (url === '' || url === '/') {
2013-07-10 18:42:38 -04:00
tpl_url = 'home';
} else {
tpl_url = url.split('/')[0].split('?')[0];
2013-07-10 18:42:38 -04:00
}
2013-08-23 13:45:57 -04:00
} else if (templates[url]) {
tpl_url = url;
}
if (templates.is_available(tpl_url) && !templates.force_refresh(tpl_url)) {
if (window.history && window.history.pushState) {
window.history[!quiet ? 'pushState' : 'replaceState']({
url: url
}, url, RELATIVE_PATH + '/' + url);
$.ajax(RELATIVE_PATH + '/plugins/fireHook', {
type: 'PUT',
data: {
_csrf: $('#csrf_token').val(),
hook: 'page.load',
args: {
template: tpl_url,
url: url,
uid: app.uid
2013-11-21 12:28:10 -05:00
}
}
});
}
translator.load(tpl_url);
jQuery('#footer, #content').addClass('ajaxifying');
templates.flush();
templates.load_template(function () {
exec_body_scripts(content);
require(['forum/' + tpl_url], function(script) {
2013-11-21 12:28:10 -05:00
if (script && script.init) {
script.init();
}
});
if (callback) {
callback();
}
2013-08-23 13:45:57 -04:00
app.processPage();
2013-09-24 16:46:45 -04:00
jQuery('#content, #footer').stop(true, true).removeClass('ajaxifying');
2013-11-21 12:28:10 -05:00
if (window.location.hash) {
hash = window.location.hash;
}
if (hash) {
require(['forum/topic'], function(topic) {
topic.scrollToPost(hash.substr(1));
});
}
2013-08-01 16:11:00 -04:00
app.refreshTitle(url);
}, url, template);
return true;
}
return false;
};
$('document').ready(function () {
2013-11-21 12:28:10 -05:00
if (!window.history || !window.history.pushState) {
return; // no ajaxification for old browsers
}
2013-04-22 19:13:39 +00:00
content = content || document.getElementById('content');
// Enhancing all anchors to ajaxify...
$(document.body).on('click', 'a', function (e) {
2013-08-23 13:45:57 -04:00
function hrefEmpty(href) {
2013-11-21 12:28:10 -05:00
return href === 'javascript:;' || href === window.location.href + "#" || href.slice(-1) === "#";
2013-08-23 13:45:57 -04:00
}
2013-11-21 12:28:10 -05:00
if (hrefEmpty(this.href) || this.target !== '' || this.protocol === 'javascript:') {
2013-09-25 13:08:11 -04:00
return;
2013-11-21 12:28:10 -05:00
}
2013-09-25 13:08:11 -04:00
2013-11-21 12:28:10 -05:00
if(!window.location.pathname.match(/\/(403|404)$/g)) {
app.previousUrl = window.location.href;
2013-11-21 12:28:10 -05:00
}
2013-11-21 12:28:10 -05:00
if (this.getAttribute('data-ajaxify') === 'false') {
return;
}
if (!e.ctrlKey && e.which === 1) {
if (this.host === window.location.host) {
// Internal link
var url = this.href.replace(rootUrl + '/', '');
if (ajaxify.go(url)) {
2013-09-25 13:08:11 -04:00
e.preventDefault();
}
} else if (window.location.pathname !== '/outgoing') {
// External Link
2013-10-01 12:07:58 -04:00
if (config.useOutgoingLinksPage == true) {
ajaxify.go('outgoing?url=' + encodeURIComponent(this.href));
e.preventDefault();
}
}
}
});
2013-04-22 19:13:39 +00:00
});
function exec_body_scripts(body_el) {
// modified from http://stackoverflow.com/questions/2592092/executing-script-elements-inserted-with-innerhtml
2013-04-22 19:13:39 +00:00
function nodeName(elem, name) {
return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
}
2013-04-22 19:13:39 +00:00
function evalScript(elem) {
2013-09-17 13:04:40 -04:00
var data = (elem.text || elem.textContent || elem.innerHTML || ""),
head = document.getElementsByTagName("head")[0] ||
document.documentElement,
2013-06-20 16:48:17 -04:00
script = document.createElement("script");
script.type = "text/javascript";
try {
2013-09-17 13:04:40 -04:00
script.appendChild(document.createTextNode(data));
} catch (e) {
script.text = data;
}
2013-04-22 19:13:39 +00:00
if (elem.src) {
script.src = elem.src;
}
head.insertBefore(script, head.firstChild);
2013-06-26 13:18:19 -04:00
//TODO: remove from head before inserting?, doing this breaks scripts in safari so commented out for now
//head.removeChild(script);
}
2013-04-22 19:13:39 +00:00
var scripts = [],
script,
children_nodes = $(body_el).find('script'),
child,
i;
2013-04-22 19:13:39 +00:00
for (i = 0; children_nodes[i]; i++) {
child = children_nodes[i];
2013-09-17 13:04:40 -04:00
if (nodeName(child, "script") &&
(!child.type || child.type.toLowerCase() === "text/javascript")) {
scripts.push(child);
}
2013-04-22 19:13:39 +00:00
}
for (i = 0; scripts[i]; i++) {
script = scripts[i];
if (script.parentNode) {
script.parentNode.removeChild(script);
}
2013-04-22 19:13:39 +00:00
evalScript(scripts[i]);
}
}
2013-08-23 13:45:57 -04:00
}(jQuery));