openresty/demo/Blog/js/blog.js

629 lines
18 KiB
JavaScript

var account = 'agentzh';
//var host = 'http://10.32.24.13:1984';
var host = 'http://localhost:1984';
//var host = 'http://api.eeeeworks.org';
//var host = 'http://api.openresty.org';
//var host = 'http://10.62.136.86';
var openresty = null;
var savedAnchor = null;
var itemsPerPage = 5;
var loadingCount = 0;
var waitMessage = null;
var timer = null;
var thisYear = null;
var thisMonth = null;
var thisDay = null;
var cachedPostCountRes = null;
var months = [
null,
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
];
$(window).ready(init);
function error (msg) {
alert(msg);
}
function debug (msg) {
$("#copyright").append(msg + "<br/>");
}
$.fn.postprocess = function (className, options) {
return this.find("a[@href*='#']").each( function () {
//debug("HERE!");
var href = $(this).attr('href');
// We need the following hack because IE expands href to
// absolute URL:
var anchor = href.replace(/^.*?\#/, '');
//debug("Anchor: " + anchor);
$(this).click( function () {
//debug(location.hash);
//$(".bnchor-location")[0].id = anchor;
location.hash = anchor;
//alert(location.hash);
if (savedAnchor == anchor) savedAnchor = null;
dispatchByAnchor();
} );
} );
};
//var count = 0;;
function setStatus (isLoading, category) {
if (isLoading) {
if (++loadingCount == 1) {
if (jQuery.browser.opera)
$(waitMessage).css('top', '2px');
else
$(waitMessage).show();
}
} else {
loadingCount--;
if (loadingCount < 0) loadingCount = 0;
if (loadingCount == 0) {
// the reason we use this hack is to work around
// a rendering bug in Win32 build of Opera
// (at least 9.25 and 9.26)
if (jQuery.browser.opera)
$(waitMessage).css('top', '-200px');
else
$(waitMessage).hide();
}
}
//count++;
//debug("[" + count + "] setStatus: " + category + ": " + loadingCount + "(" + isLoading + ")");
}
function init () {
loadingCount = 0;
var now = new Date();
thisYear = now.getFullYear();
thisMonth = now.getMonth();
thisDay = now.getDate();
waitMessage = document.getElementById('wait-message');
openresty = new OpenResty.Client(
{ server: host, user: account + '.Public' }
);
//openresty.formId = 'new_model';
if (timer) {
clearInterval(timer);
}
dispatchByAnchor();
timer = setInterval(dispatchByAnchor, 600);
//debug("before getSidebar...");
getSidebar();
}
function resetAnchor () {
var anchor = location.hash;
location.hash = anchor.replace(/^\#/, '');
}
function dispatchByAnchor () {
//debug(location.hash);
var anchor = location.hash;
anchor = anchor.replace(/^\#/, '');
if (savedAnchor == anchor)
return;
if (anchor == "") {
anchor = 'posts/1';
location.hash = 'posts/1';
}
savedAnchor = anchor;
// prevent memory leaks from dynamically created <script> nodes:
//if (loadingCount <= 0) openresty.purge();
loadingCount = 0;
var match = anchor.match(/^post-(\d+)(:comments|comment-(\d+))?/);
if (match) {
var postId = match[1];
//alert("Post ID: " + postId);
getPost(postId);
return;
}
match = anchor.match(/^search\/(\d+)\/(.*)/);
if (match) {
var page = parseInt(match[1]);
var query = match[2];
$('.pager').html('');
$('#searchbox').val(query);
getSearchResults(query, page);
getPagerForSearch(query, page);
return;
}
match = anchor.match(/^archive\/(\d+)\/(\d+)$/);
if (match) {
var year = match[1];
var month = match[2];
getArchive(year, month);
return;
}
match = anchor.match(/^(?:posts|posts\/(\d+))$/);
var page = 1;
//alert(anchor + " " + location.hash);
if (match)
page = parseInt(match[1]) || 1;
else if (anchor != 'posts/1')
top.location.hash = 'posts/1';
//debug("before getPostList...");
getPostList(page);
//debug("before getPager...");
getPager(page);
//debug("after getPager...");
$(".blog-top").attr('id', 'posts/' + page);
}
function getArchive (year, month) {
setStatus(true, 'renderPostList');
$(".pager").html('');
openresty.callback = function (res) {
renderPostList(res);
setStatus(true, 'renderArchiveNav');
openresty.callback = renderArchiveNav;
openresty.get(
'/=/view/PrevNextArchive/~/~',
{
now: year + '-' + month + '-01',
month: month,
months: months
}
);
};
openresty.get(
'/=/view/FullPostsByMonth/~/~',
{ count: 40, year: year, month: month }
);
$(".blog-top").attr('id', 'archive/' + year + '/' + month);
}
function renderArchiveNav (res) {
//debug("render archive nav: " + JSON.stringify(res));
setStatus(false, 'renderArchiveNav');
if (!openresty.isSuccess(res)) {
error("Failed to get archive navigator: " + res.errstr);
return;
}
var prev = null;
var next = null;
for (var i = 0; i < res.length; i++) {
var item = res[i];
item.year = parseInt(item.year);
item.month = parseInt(item.month);
//debug("item: " + JSON.stringify(item));
if (item.id == "prev") prev = item;
else if (item.id == "next") next = item;
}
//debug("next: " + JSON.stringify(next));
//debug("prev: " + JSON.stringify(prev));
$("#post-list-nav").html(
Jemplate.process(
'archive-nav.tt',
{ next: next, prev: prev, months: months }
)
).postprocess();
}
function getPostList (page) {
setStatus(true, 'renderPostList');
openresty.callback = renderPostList;
openresty.get('/=/model/Post/~/~', {
_limit: itemsPerPage,
_order_by: 'id:desc',
_offset: itemsPerPage * (page - 1)
});
}
function getSearchResults (query, page) {
setStatus(true, 'renderSearchResults');
openresty.callback = function (res) { renderSearchResults(res, query); };
var q = query2tsquery(query);
//alert("Query: " + q);
openresty.get('/=/view/PostSearch/~/~', {
offset: itemsPerPage * (page - 1),
count: itemsPerPage,
query: q,
order_dir: 'desc'
});
}
function doPostSearch () {
var query = $('#searchbox').val();
savedAnchor = null;
var anchor = '#search/1/' + query;
location.hash = anchor;
//alert(location.hash);
if (savedAnchor == anchor.replace(/^\#/, '')) savedAnchor = null;
dispatchByAnchor();
}
function query2tsquery (query) {
return query.replace(/[\s(){},.|&$]+/g, ' ')
.replace(/^\s+|\s+$/g, '')
.replace(/ +/g, '|');
}
function getPagerForSearch (query, page) {
setStatus(true, 'renderPagerForSearch');
openresty.callback = function (res) { renderPager(res, page, 'search/', '/' + query); };
var q = query2tsquery(query);
openresty.get('/=/view/RowCountForSearch/~/~', {query: q});
}
function getPager (page) {
setStatus(true, 'renderPager');
if (cachedPostCountRes) {
//alert("Hit!");
renderPager(cachedPostCountRes, page, 'posts/', '');
} else {
openresty.callback = function (res) { renderPager(res, page, 'posts/', ''); };
openresty.get('/=/view/RowCount/~/~', { model: 'Post' });
}
}
function getSidebar () {
//getRecentPosts();
//getRecentComments();
//getArchiveList();
setStatus(true, 'renderSidebar');
openresty.callback = function (res) { renderSidebar(res) };
openresty.get('/=/batch/GetSidebar/~/~', { year: thisYear, month: thisMonth + 1 });
}
function renderSidebar (res) {
setStatus(false, 'renderSidebar');
if (!openresty.isSuccess(res)) {
error("Failed to fetch posts for calendar: " +
res.errstr);
return;
}
getCalendar(thisYear, thisMonth, res[0]);
setStatus(true, 'renderRecentPosts');
renderRecentPosts(res[1], 0, 6);
setStatus(true, 'renderRecentComments');
renderRecentComments(res[2], 0, 6);
setStatus(true, 'getArchiveList');
renderArchiveList(res[3], 0, 12);
}
function getCalendar (year, month, posts) {
if (year == undefined || month == undefined) {
year = thisYear;
month = thisMonth;
}
var date = new Date(year, month, 1);
var first_day_of_week = date.getDay();
var end_of_month;
if (month == 11) {
end_of_month = 31;
} else {
var delta = new Date(year, month + 1, 1) - date;
end_of_month = Math.round(delta/1000/60/60/24);
}
//alert(year);
//alert(month);
//alert("thisday: " + thisDay);
$(".module-calendar").html(
Jemplate.process(
'calendar.tt',
{
year: year,
month: month,
first_day_of_week: first_day_of_week,
end_of_month: end_of_month,
today: (year == thisYear && month == thisMonth) ?
thisDay : null,
months: months
}
)
).postprocess();
// We need this 0 timeout hack for IE 6 :(
if (posts) {
//alert("Shortcut!");
setStatus(true, 'renderPostsInCalendar');
renderPostsInCalendar(posts, year, month);
} else {
setTimeout( function () {
setStatus(true, 'renderPostsInCalendar');
openresty.callback = function (res) {
renderPostsInCalendar(res, year, month);
};
openresty.get('/=/view/PostsByMonth/~/~', { year: year, month: month + 1 });
}, 0 );
}
}
function renderPostsInCalendar (res, year, month) {
setStatus(false, 'renderPostsInCalendar');
//alert("hey!");
if (!openresty.isSuccess(res)) {
error("Failed to fetch posts for calendar: " +
res.errstr);
} else {
//alert(res.errstr);
var prev_day = 0;
for (var i = 0; i < res.length; i++) {
var line = res[i];
if (prev_day == line.day) continue;
prev_day = line.day;
var id = 'day-' + year + '-' + month + '-' + line.day;
//alert("ID: " + id);
var cell = $("#" + id);
if (cell.length == 0) return;
//alert("cell html: " + cell.html());
cell.html('<a href="#post-' + line.id + '"><b>' +
cell.html() + '</b></a>').postprocess();
}
}
}
function getRecentComments (offset) {
if (!offset) offset = 0;
setStatus(true, 'renderRecentComments');
openresty.callback = function (res) { renderRecentComments(res, offset, 6) };
openresty.get('/=/view/RecentComments/~/~',
{ limit:6, offset: offset });
}
function renderRecentComments (res, offset, count) {
setStatus(false, 'renderRecentComments');
if (!openresty.isSuccess(res)) {
error("Failed to get the recent comments: " + res.errstr);
} else {
//alert("Get the recent comments: " + res.errstr);
var html = Jemplate.process(
'recent-comments.tt',
{ comments: res, offset: offset, count: count }
);
$("#recent-comments").html(html).postprocess();
}
}
function getRecentPosts (offset) {
if (!offset) offset = 0;
setStatus(true, 'renderRecentPosts');
openresty.callback = function (res) { renderRecentPosts(res, offset, 6) };
openresty.get('/=/view/RecentPosts/~/~',
{ limit:6, offset: offset });
}
function renderRecentPosts (res, offset, count) {
setStatus(false, 'renderRecentPosts');
if (!openresty.isSuccess(res)) {
error("Failed to get the recent posts: " + res.errstr);
} else {
//alert("Get the recent comments: " + res.errstr);
var html = Jemplate.process(
'recent-posts.tt',
{ posts: res, offset: offset, count: count }
);
$("#recent-posts").html(html).postprocess();
}
}
function getArchiveList (offset) {
if (offset == undefined) offset = 0;
setStatus(true, 'getArchiveList');
openresty.callback = function (res) {
renderArchiveList(res, offset, 12);
};
openresty.get(
'/=/view/PostCountByMonths/~/~',
{ offset: offset, count: 12 }
);
}
function renderArchiveList (res, offset, count) {
setStatus(false, 'getArchiveList');
if (!openresty.isSuccess(res)) {
error("Failed to get archive list: " + res.errstr);
return;
}
for (var i = 0; i < res.length; i++) {
var item = res[i];
var match = item.year_month.match(/^(\d\d\d\d)-0?(\d+)/);
if (match) {
item.year = parseInt(match[1]);
item.month = parseInt(match[2]);
} else {
error("Failed to match against year_month: " + item.year_month);
}
//debug(JSON.stringify(item));
}
$("#archive-list").html(
Jemplate.process(
'archive-list.tt',
{ archives: res, count: count, offset: offset, months: months }
)
).postprocess();
}
function postComment (form) {
var data = {};
data.sender = $("#comment-author").val();
data.email = $("#comment-email").val();
data.url = $("#comment-url").val();
data.body = $("#comment-text").val();
data.post_id = $("#comment-for").val();
//alert(JSON.stringify(data));
if (!data.sender) {
error("Name is required.");
return false;
}
if (!data.email) {
error("Email address is required.");
return false;
}
if (!data.body) {
error("Comment body is required.");
return false;
}
//openresty.purge();
setStatus(true, 'afterPostComment');
openresty.callback = afterPostComment;
//openresty.formId = 'comment-form';
// TODO openresty.post('/=/batch/NewComment/~/~', data);
openresty.get('/=/batch/NewComment/~/~', data);
return false;
}
function afterPostComment (res) {
setStatus(false, 'afterPostComment');
//alert("HERE!!! afterPostComment");
if (!openresty.isSuccess(res)) {
error("Failed to post the comment: " + res.errstr);
} else {
//alert(res.errstr);
$("#comment-text").val('');
var spans = $(".comment-count");
var commentCount = parseInt(spans.text());
var postId = spans.attr('post');
//debug(JSON.stringify(res));
var commentId = res[0].insert_id;
location.hash = 'post-' + postId + ':' +
(commentId ? 'comment-' + commentId : 'comments');
spans.text(commentCount + 1);
getRecentComments(0);
}
}
function getPost (id) {
//alert("Go to Post " + id);
$(".blog-top").attr('id', 'post-' + id);
//alert($(".blog-top").attr('id'));
setStatus(true, 'renderPost');
openresty.callback = renderPost;
openresty.get('/=/batch/GetFullPost/~/~',
{ id: id });
}
function renderPost (res) {
setStatus(false, 'renderPost');
//alert(JSON.stringify(post));
if (!openresty.isSuccess(res)) {
error("Failed to render post: " + res.errstr);
} else {
var post = res[0][0];
//if (!post) return;
$("#beta-inner.pkg").html(
Jemplate.process('post-page.tt', { post: post })
).postprocess();
renderPrevNextPost(post.id, res[1]);
//debug(JSON.stringify(post));
setStatus(true, 'renderComments');
renderComments(res[2]);
$(".pager").html('');
resetAnchor();
}
}
function renderPrevNextPost (currentId, res) {
if (!openresty.isSuccess(res)) {
error("Failed to render prev next post navigation: " +
res.errstr);
} else {
//alert("Going to render prev next post navigation: " + res.errstr);
$(".content-nav").html(
Jemplate.process('nav.tt', { posts: res, current: currentId })
).postprocess();
//resetAnchor();
}
}
function renderComments (res) {
setStatus(false, 'renderComments');
//alert("Comments: " + res.errstr);
if (!openresty.isSuccess(res)) {
error("Failed to get post list: " + res.errstr);
} else {
$(".comments-content").html(
Jemplate.process('comments.tt', { comments: res })
);
//resetAnchor();
//setTimeout( function () { alert("Hi"); resetAnchor(); }, 1000 );
}
}
function renderPostList (res) {
setStatus(false, 'renderPostList');
if (!openresty.isSuccess(res)) {
error("Failed to get post list: " + res.errstr);
} else {
//alert(JSON.stringify(data));
$("#beta-inner.pkg").html(
Jemplate.process('post-list.tt', { post_list: res })
).postprocess();
}
//resetAnchor();
}
function renderSearchResults (res, query) {
setStatus(false, 'renderSearchResults');
if (!openresty.isSuccess(res)) {
error("Failed to get search results: " + res.errstr);
} else {
if (res.length) {
var html = Jemplate.process('post-list.tt', { post_list: res })
$("#beta-inner.pkg").html(html).postprocess();
} else {
$("#beta-inner.pkg").html("<p>Sorry, no search results found for query <b>\"" + query + "\"</b>.</p>");
}
}
}
function renderPager (res, page, prefix, suffix) {
setStatus(false, 'renderPager');
if (!openresty.isSuccess(res)) {
error("Failed to render pager: " + res.errstr);
} else {
//debug("before rendering pager...");
cachedPostCountRes = res;
var pageCount = Math.ceil(parseInt(res[0].count) / itemsPerPage);
if (pageCount < 2) return;
//debug("before redering pager (2)...");
var html = Jemplate.process(
'pager.tt',
{ page: page, page_count: pageCount, title: 'Pages', prefix: prefix, suffix: suffix }
);
//debug("after html generation...");
// we use the .each hack here to work aound a JS runtime error in IE 6:
$(".pager").each( function () {
$(this).html( html ).postprocess();
} );
//debug("after rendering pager...");
resetAnchor();
}
}