Removed PathJS dependency; refactored routing
This commit is contained in:
parent
60ab927558
commit
6afd60feba
30 changed files with 293 additions and 262 deletions
|
@ -2,7 +2,6 @@
|
|||
"name": "szuru2",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"pathjs": "~0.8.1",
|
||||
"jquery.cookie": "1.4.1",
|
||||
"jquery": "~2.1.1",
|
||||
"underscore": "1.7.0",
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
|
||||
<script type="text/javascript" src="/lib/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="/lib/jquery.cookie.js"></script>
|
||||
<script type="text/javascript" src="/lib/path.js"></script>
|
||||
<script type="text/javascript" src="/lib/underscore.min.js"></script>
|
||||
<script type="text/javascript" src="/lib/mousetrap.min.js"></script>
|
||||
<script type="text/javascript" src="/lib/marked.js"></script>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
var App = App || {};
|
||||
|
||||
App.Bootstrap = function(auth, router, util, promise, presenterManager) {
|
||||
App.Bootstrap = function(auth, router, promise, presenterManager) {
|
||||
|
||||
promise.wait(
|
||||
auth.tryLoginFromCookie(),
|
||||
|
@ -25,7 +25,7 @@ App.Bootstrap = function(auth, router, util, promise, presenterManager) {
|
|||
|
||||
};
|
||||
|
||||
App.DI.registerSingleton('bootstrap', ['auth', 'router', 'util', 'promise', 'presenterManager'], App.Bootstrap);
|
||||
App.DI.registerSingleton('bootstrap', ['auth', 'router', 'promise', 'presenterManager'], App.Bootstrap);
|
||||
App.DI.registerManual('jQuery', function() { return window.$; });
|
||||
App.DI.registerManual('pathJs', function() { return window.pathjs; });
|
||||
App.DI.registerManual('_', function() { return window._; });
|
||||
|
|
|
@ -51,7 +51,8 @@ App.Pager = function(
|
|||
|
||||
function setSearchParams(newSearchParams) {
|
||||
setPage(1);
|
||||
searchParams = newSearchParams;
|
||||
searchParams = _.extend({}, newSearchParams);
|
||||
delete searchParams.page;
|
||||
}
|
||||
|
||||
function retrieve() {
|
||||
|
@ -64,7 +65,8 @@ App.Pager = function(
|
|||
|
||||
resolve({
|
||||
entities: response.json.data,
|
||||
totalRecords: totalRecords});
|
||||
totalRecords: totalRecords,
|
||||
totalPages: totalPages});
|
||||
|
||||
}).fail(function(response) {
|
||||
reject(response);
|
||||
|
|
|
@ -12,7 +12,7 @@ App.Presenters.GlobalCommentListPresenter = function(
|
|||
var $el;
|
||||
var templates = {};
|
||||
|
||||
function init(args, loaded) {
|
||||
function init(params, loaded) {
|
||||
$el = jQuery('#content');
|
||||
topNavigationPresenter.select('comments');
|
||||
|
||||
|
@ -38,25 +38,16 @@ App.Presenters.GlobalCommentListPresenter = function(
|
|||
},
|
||||
},
|
||||
function() {
|
||||
onArgsChanged(args);
|
||||
reinit(params, function() {});
|
||||
});
|
||||
})
|
||||
.fail(function() { console.log(new Error(arguments)); });
|
||||
}
|
||||
|
||||
|
||||
function reinit(args, loaded) {
|
||||
function reinit(params, loaded) {
|
||||
pagerPresenter.reinit({query: params.query});
|
||||
loaded();
|
||||
onArgsChanged(args);
|
||||
}
|
||||
|
||||
function onArgsChanged(args) {
|
||||
var searchArgs = util.parseComplexRouteArgs(args.searchArgs);
|
||||
pagerPresenter.reinit({
|
||||
page: searchArgs.page,
|
||||
searchParams: {
|
||||
query: searchArgs.query,
|
||||
order: searchArgs.order}});
|
||||
}
|
||||
|
||||
function deinit() {
|
||||
|
@ -79,6 +70,7 @@ App.Presenters.GlobalCommentListPresenter = function(
|
|||
var comments = data.comments;
|
||||
|
||||
var $post = jQuery('<li>' + templates.listItem({
|
||||
util: util,
|
||||
post: post,
|
||||
postTemplate: templates.post,
|
||||
}) + '</li>');
|
||||
|
@ -104,6 +96,7 @@ App.Presenters.GlobalCommentListPresenter = function(
|
|||
deinit: deinit,
|
||||
render: render,
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
App.DI.register('globalCommentListPresenter', ['_', 'jQuery', 'util', 'promise', 'pagerPresenter', 'topNavigationPresenter'], App.Presenters.GlobalCommentListPresenter);
|
||||
|
|
|
@ -7,7 +7,7 @@ App.Presenters.HelpPresenter = function(
|
|||
|
||||
var $el = jQuery('#content');
|
||||
|
||||
function init(args, loaded) {
|
||||
function init(params, loaded) {
|
||||
topNavigationPresenter.select('help');
|
||||
topNavigationPresenter.changeTitle('Help');
|
||||
render();
|
||||
|
|
|
@ -15,7 +15,7 @@ App.Presenters.HomePresenter = function(
|
|||
var globals;
|
||||
var post;
|
||||
|
||||
function init(args, loaded) {
|
||||
function init(params, loaded) {
|
||||
topNavigationPresenter.select('home');
|
||||
topNavigationPresenter.changeTitle('Home');
|
||||
|
||||
|
|
|
@ -13,12 +13,12 @@ App.Presenters.LoginPresenter = function(
|
|||
var $el = jQuery('#content');
|
||||
var $messages;
|
||||
var templates = {};
|
||||
var previousRoute;
|
||||
var previousLocation;
|
||||
|
||||
function init(args, loaded) {
|
||||
function init(params, loaded) {
|
||||
topNavigationPresenter.select('login');
|
||||
topNavigationPresenter.changeTitle('Login');
|
||||
previousRoute = args.previousRoute;
|
||||
previousLocation = params.previousLocation;
|
||||
promise.wait(util.promiseTemplate('login-form'))
|
||||
.then(function(template) {
|
||||
templates.login = template;
|
||||
|
@ -66,8 +66,8 @@ App.Presenters.LoginPresenter = function(
|
|||
}
|
||||
|
||||
function finishLogin() {
|
||||
if (previousRoute && !previousRoute.match(/logout|password-reset|activate|register/)) {
|
||||
router.navigate(previousRoute);
|
||||
if (previousLocation && !previousLocation.match(/logout|password-reset|activate|register/)) {
|
||||
router.navigate(previousLocation);
|
||||
} else {
|
||||
router.navigateToMainPage();
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ App.Presenters.LogoutPresenter = function(
|
|||
|
||||
var $messages = jQuery('#content');
|
||||
|
||||
function init(args, loaded) {
|
||||
function init(params, loaded) {
|
||||
topNavigationPresenter.select('logout');
|
||||
topNavigationPresenter.changeTitle('Logout');
|
||||
promise.wait(auth.logout())
|
||||
|
|
|
@ -26,17 +26,20 @@ App.Presenters.PagerPresenter = function(
|
|||
var baseUri;
|
||||
var updateCallback;
|
||||
|
||||
function init(args, loaded) {
|
||||
baseUri = args.baseUri;
|
||||
updateCallback = args.updateCallback;
|
||||
function init(params, loaded) {
|
||||
baseUri = params.baseUri;
|
||||
updateCallback = params.updateCallback;
|
||||
|
||||
messagePresenter.instant = true;
|
||||
|
||||
$target = args.$target;
|
||||
targetContent = jQuery(args.$target).html();
|
||||
$target = params.$target;
|
||||
targetContent = jQuery(params.$target).html();
|
||||
|
||||
pager.init({url: args.backendUri});
|
||||
pager.setSearchParams(args.searchParams);
|
||||
if (forceClear) {
|
||||
clearContent();
|
||||
}
|
||||
pager.init({url: params.backendUri});
|
||||
setQuery(params.query);
|
||||
|
||||
promise.wait(util.promiseTemplate('pager'))
|
||||
.then(function(template) {
|
||||
|
@ -46,62 +49,28 @@ App.Presenters.PagerPresenter = function(
|
|||
});
|
||||
}
|
||||
|
||||
function reinit(args, loaded) {
|
||||
forceClear = !_.isEqual(args.searchParams, pager.getSearchParams()) || parseInt(args.page) !== pager.getPage();
|
||||
|
||||
pager.setSearchParams(args.searchParams);
|
||||
pager.setPage(args.page || 1);
|
||||
function reinit(params, loaded) {
|
||||
if (forceClear) {
|
||||
clearContent();
|
||||
}
|
||||
setQuery(params.query);
|
||||
|
||||
promise.wait(retrieve())
|
||||
.then(loaded)
|
||||
.fail(loaded);
|
||||
|
||||
if (!endlessScroll) {
|
||||
keyboard.keydown('a', prevPage);
|
||||
keyboard.keydown('d', nextPage);
|
||||
keyboard.keydown('a', function() { pager.prevPage(); syncUrl(); });
|
||||
keyboard.keydown('d', function() { pager.nextPage(); syncUrl(); });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function deinit() {
|
||||
detachNextPageLoader();
|
||||
}
|
||||
|
||||
function prevPage() {
|
||||
pager.prevPage();
|
||||
syncUrl();
|
||||
}
|
||||
|
||||
function nextPage() {
|
||||
pager.nextPage();
|
||||
syncUrl();
|
||||
}
|
||||
|
||||
function nextPageInplace() {
|
||||
pager.nextPage();
|
||||
syncUrlInplace();
|
||||
}
|
||||
|
||||
function setPage(newPage) {
|
||||
pager.setPage(newPage);
|
||||
syncUrl();
|
||||
}
|
||||
|
||||
function setSearchParams(newSearchParams) {
|
||||
if (_.isEqual(pager.getSearchParams(), newSearchParams)) {
|
||||
return;
|
||||
}
|
||||
clearContent();
|
||||
pager.setSearchParams(newSearchParams);
|
||||
syncUrl();
|
||||
}
|
||||
|
||||
function getUrl() {
|
||||
return util.compileComplexRouteArgs(
|
||||
baseUri,
|
||||
_.extend(
|
||||
{page: pager.getPage()},
|
||||
pager.getSearchParams()));
|
||||
return util.appendComplexRouteParam(baseUri, _.extend({}, pager.getSearchParams(), {page: pager.getPage()}));
|
||||
}
|
||||
|
||||
function syncUrl() {
|
||||
|
@ -148,9 +117,11 @@ App.Presenters.PagerPresenter = function(
|
|||
showPageList();
|
||||
}
|
||||
|
||||
if (pager.getPage() < response.totalPages) {
|
||||
attachNextPageLoader();
|
||||
}
|
||||
refreshPageList();
|
||||
hideSpinner();
|
||||
attachNextPageLoader();
|
||||
resolve();
|
||||
}).fail(function(response) {
|
||||
clearContent();
|
||||
|
@ -177,7 +148,8 @@ App.Presenters.PagerPresenter = function(
|
|||
var baseLine = $target.offset().top + $target.innerHeight();
|
||||
var scrollY = jQuery(window).scrollTop() + jQuery(window).height();
|
||||
if (scrollY > baseLine) {
|
||||
nextPageInplace();
|
||||
pager.nextPage();
|
||||
syncUrlInplace();
|
||||
window.clearInterval(scrollInterval);
|
||||
}
|
||||
}, 100);
|
||||
|
@ -207,7 +179,8 @@ App.Presenters.PagerPresenter = function(
|
|||
|
||||
var $a = jQuery('<a/>');
|
||||
$a.click(function() {
|
||||
setPage(page);
|
||||
pager.setPage(page);
|
||||
syncUrl();
|
||||
});
|
||||
$a.addClass('big-button');
|
||||
$a.text(page);
|
||||
|
@ -231,12 +204,32 @@ App.Presenters.PagerPresenter = function(
|
|||
}
|
||||
}
|
||||
|
||||
function setQuery(query) {
|
||||
if (!query) {
|
||||
return;
|
||||
}
|
||||
query.page = parseInt(query.page) || 1;
|
||||
var page = query.page;
|
||||
delete query.page;
|
||||
forceClear =
|
||||
query.query !== pager.getSearchParams().query ||
|
||||
query.order !== pager.getSearchParams().order ||
|
||||
parseInt(page) !== pager.getPage();
|
||||
pager.setSearchParams(query);
|
||||
pager.setPage(page);
|
||||
}
|
||||
|
||||
function setQueryAndSyncUrl(query) {
|
||||
setQuery(query);
|
||||
syncUrl();
|
||||
}
|
||||
|
||||
return {
|
||||
init: init,
|
||||
reinit: reinit,
|
||||
deinit: deinit,
|
||||
setPage: setPage,
|
||||
setSearchParams: setSearchParams,
|
||||
syncUrl: syncUrl,
|
||||
setQuery: setQueryAndSyncUrl,
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -18,10 +18,10 @@ App.Presenters.PostCommentListPresenter = function(
|
|||
var post;
|
||||
var comments = [];
|
||||
|
||||
function init(args, loaded) {
|
||||
$el = args.$target;
|
||||
post = args.post;
|
||||
comments = args.comments || [];
|
||||
function init(params, loaded) {
|
||||
$el = params.$target;
|
||||
post = params.post;
|
||||
comments = params.comments || [];
|
||||
|
||||
privileges = {
|
||||
canListComments: auth.hasPrivilege(auth.privileges.listComments),
|
||||
|
@ -49,7 +49,7 @@ App.Presenters.PostCommentListPresenter = function(
|
|||
loaded();
|
||||
|
||||
if (comments.length === 0) {
|
||||
promise.wait(api.get('/comments/' + args.post.id))
|
||||
promise.wait(api.get('/comments/' + params.post.id))
|
||||
.then(function(response) {
|
||||
comments = response.json.data;
|
||||
render();
|
||||
|
@ -222,6 +222,7 @@ App.Presenters.PostCommentListPresenter = function(
|
|||
init: init,
|
||||
render: render,
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
App.DI.register('postCommentListPresenter', ['_', 'jQuery', 'util', 'promise', 'api', 'auth', 'topNavigationPresenter', 'messagePresenter'], App.Presenters.PostCommentListPresenter);
|
||||
|
|
|
@ -17,13 +17,13 @@ App.Presenters.PostListPresenter = function(
|
|||
var $el = jQuery('#content');
|
||||
var $searchInput;
|
||||
|
||||
var searchArgs;
|
||||
var params;
|
||||
|
||||
function init(args, loaded) {
|
||||
function init(_params, loaded) {
|
||||
topNavigationPresenter.select('posts');
|
||||
topNavigationPresenter.changeTitle('Posts');
|
||||
searchArgs = util.parseComplexRouteArgs(args.searchArgs);
|
||||
searchArgs.page = parseInt(searchArgs.page) || 1;
|
||||
params = _params;
|
||||
params.query = params.query || {};
|
||||
|
||||
promise.wait(
|
||||
util.promiseTemplate('post-list'),
|
||||
|
@ -44,23 +44,14 @@ App.Presenters.PostListPresenter = function(
|
|||
},
|
||||
},
|
||||
function() {
|
||||
onArgsChanged(args);
|
||||
reinit(params, function() {});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function reinit(args, loaded) {
|
||||
function reinit(params, loaded) {
|
||||
pagerPresenter.reinit({query: params.query});
|
||||
loaded();
|
||||
onArgsChanged(args);
|
||||
}
|
||||
|
||||
function onArgsChanged(args) {
|
||||
searchArgs = util.parseComplexRouteArgs(args.searchArgs);
|
||||
pagerPresenter.reinit({
|
||||
page: searchArgs.page,
|
||||
searchParams: {
|
||||
query: searchArgs.query,
|
||||
order: searchArgs.order}});
|
||||
}
|
||||
|
||||
function deinit() {
|
||||
|
@ -72,7 +63,7 @@ App.Presenters.PostListPresenter = function(
|
|||
$searchInput = $el.find('input[name=query]');
|
||||
App.Controls.AutoCompleteInput($searchInput);
|
||||
|
||||
$searchInput.val(searchArgs.query);
|
||||
$searchInput.val(params.query.query);
|
||||
$searchInput.keydown(searchInputKeyPressed);
|
||||
$el.find('form').submit(searchFormSubmitted);
|
||||
|
||||
|
@ -94,7 +85,8 @@ App.Presenters.PostListPresenter = function(
|
|||
|
||||
_.each(posts, function(post) {
|
||||
var $post = jQuery('<li>' + templates.listItem({
|
||||
searchArgs: searchArgs,
|
||||
util: util,
|
||||
query: params.query,
|
||||
post: post,
|
||||
}) + '</li>');
|
||||
util.loadImagesNicely($post.find('img'));
|
||||
|
@ -116,9 +108,8 @@ App.Presenters.PostListPresenter = function(
|
|||
|
||||
function updateSearch() {
|
||||
$searchInput.blur();
|
||||
pagerPresenter.setSearchParams({
|
||||
query: $searchInput.val().trim(),
|
||||
order: searchArgs.order});
|
||||
params.query.query = $searchInput.val().trim();
|
||||
pagerPresenter.setQuery(params.query);
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -20,9 +20,9 @@ App.Presenters.PostPresenter = function(
|
|||
var $messages = $el;
|
||||
|
||||
var templates = {};
|
||||
var params;
|
||||
|
||||
var postNameOrId;
|
||||
var searchArgs;
|
||||
var post;
|
||||
|
||||
var privileges = {};
|
||||
|
@ -34,7 +34,7 @@ App.Presenters.PostPresenter = function(
|
|||
var postContent;
|
||||
var postThumbnail;
|
||||
|
||||
function init(args, loaded) {
|
||||
function init(params, loaded) {
|
||||
topNavigationPresenter.select('posts');
|
||||
postsAroundCalculator.resetCache();
|
||||
|
||||
|
@ -64,18 +64,19 @@ App.Presenters.PostPresenter = function(
|
|||
templates.postContent = postContentTemplate;
|
||||
templates.history = historyTemplate;
|
||||
|
||||
reinit(args, loaded);
|
||||
reinit(params, loaded);
|
||||
}).fail(function(response) {
|
||||
showGenericError(response);
|
||||
loaded();
|
||||
});
|
||||
}
|
||||
|
||||
function reinit(args, loaded) {
|
||||
postNameOrId = args.postNameOrId;
|
||||
function reinit(_params, loaded) {
|
||||
params = _params;
|
||||
params.query = params.query || {};
|
||||
params.query.page = parseInt(params.query.page) || 1;
|
||||
|
||||
searchArgs = util.parseComplexRouteArgs(args.searchArgs);
|
||||
searchArgs.page = parseInt(searchArgs.page) || 1;
|
||||
postNameOrId = params.postNameOrId;
|
||||
|
||||
promise.wait(refreshPost())
|
||||
.then(function() {
|
||||
|
@ -86,8 +87,7 @@ App.Presenters.PostPresenter = function(
|
|||
}
|
||||
|
||||
function attachLinksToPostsAround() {
|
||||
var searchParams = {query: searchArgs.query, order: searchArgs.order};
|
||||
promise.wait(postsAroundCalculator.getLinksToPostsAround(searchParams, searchArgs.page, post.id))
|
||||
promise.wait(postsAroundCalculator.getLinksToPostsAround(params.query, post.id))
|
||||
.then(function(nextPostUrl, prevPostUrl) {
|
||||
var $prevPost = $el.find('#post-current-search .right a');
|
||||
var $nextPost = $el.find('#post-current-search .left a');
|
||||
|
@ -175,7 +175,7 @@ App.Presenters.PostPresenter = function(
|
|||
|
||||
function renderPostTemplate() {
|
||||
return templates.post({
|
||||
searchArgs: searchArgs,
|
||||
query: params.query,
|
||||
post: post,
|
||||
ownScore: post.ownScore,
|
||||
postFavorites: post.favorites,
|
||||
|
|
|
@ -23,7 +23,7 @@ App.Presenters.PostUploadPresenter = function(
|
|||
var fileDropper;
|
||||
var interactionEnabled = true;
|
||||
|
||||
function init(args, loaded) {
|
||||
function init(params, loaded) {
|
||||
topNavigationPresenter.select('upload');
|
||||
topNavigationPresenter.changeTitle('Upload');
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ App.Presenters.RegistrationPresenter = function(
|
|||
var templates = {};
|
||||
var $messages;
|
||||
|
||||
function init(args, loaded) {
|
||||
function init(params, loaded) {
|
||||
topNavigationPresenter.select('register');
|
||||
topNavigationPresenter.changeTitle('Registration');
|
||||
promise.wait(util.promiseTemplate('registration-form'))
|
||||
|
|
|
@ -13,7 +13,7 @@ App.Presenters.TagListPresenter = function(
|
|||
var $el = jQuery('#content');
|
||||
var templates = {};
|
||||
|
||||
function init(args, loaded) {
|
||||
function init(params, loaded) {
|
||||
topNavigationPresenter.select('tags');
|
||||
topNavigationPresenter.changeTitle('Tags');
|
||||
|
||||
|
@ -36,28 +36,23 @@ App.Presenters.TagListPresenter = function(
|
|||
},
|
||||
},
|
||||
function() {
|
||||
reinit(args, function() {});
|
||||
reinit(params, function() {});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function reinit(args, loaded) {
|
||||
loaded();
|
||||
function reinit(params, loaded) {
|
||||
params.query = params.query || {};
|
||||
params.query.order = params.query.order || 'name,asc';
|
||||
updateActiveOrder(params.query.order);
|
||||
|
||||
var searchArgs = util.parseComplexRouteArgs(args.searchArgs);
|
||||
searchArgs.order = searchArgs.order || 'name,asc';
|
||||
searchArgs.page = parseInt(searchArgs.page) || 1;
|
||||
updateActiveOrder(searchArgs.order);
|
||||
|
||||
pagerPresenter.reinit({
|
||||
page: searchArgs.page,
|
||||
searchParams: {
|
||||
order: searchArgs.order}});
|
||||
pagerPresenter.reinit({query: params.query});
|
||||
|
||||
keyboard.keyup('p', function() {
|
||||
$el.find('table a').eq(0).focus();
|
||||
});
|
||||
|
||||
loaded();
|
||||
}
|
||||
|
||||
function deinit() {
|
||||
|
|
|
@ -15,7 +15,7 @@ App.Presenters.TagPresenter = function(
|
|||
|
||||
var tagName;
|
||||
|
||||
function init(args, loaded) {
|
||||
function init(params, loaded) {
|
||||
topNavigationPresenter.select('tags');
|
||||
topNavigationPresenter.changeTitle('Tags');
|
||||
|
||||
|
@ -26,12 +26,12 @@ App.Presenters.TagPresenter = function(
|
|||
templates.tag = tagTemplate;
|
||||
templates.postListItem = postListItemTemplate;
|
||||
|
||||
reinit(args, loaded);
|
||||
reinit(params, loaded);
|
||||
});
|
||||
}
|
||||
|
||||
function reinit(args, loaded) {
|
||||
tagName = args.tagName;
|
||||
function reinit(params, loaded) {
|
||||
tagName = params.tagName;
|
||||
|
||||
render();
|
||||
loaded();
|
||||
|
@ -55,8 +55,9 @@ App.Presenters.TagPresenter = function(
|
|||
var $target = $el.find('.post-list ul');
|
||||
_.each(posts, function(post) {
|
||||
var $post = jQuery('<li>' + templates.postListItem({
|
||||
util: util,
|
||||
post: post,
|
||||
searchArgs: {query: tagName},
|
||||
query: {query: tagName},
|
||||
}) + '</li>');
|
||||
$target.append($post);
|
||||
});
|
||||
|
@ -72,6 +73,7 @@ App.Presenters.TagPresenter = function(
|
|||
init: init,
|
||||
reinit: reinit,
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
App.DI.register('tagPresenter', ['_', 'jQuery', 'util', 'promise', 'api', 'keyboard', 'topNavigationPresenter'], App.Presenters.TagPresenter);
|
||||
|
|
|
@ -12,7 +12,7 @@ App.Presenters.TopNavigationPresenter = function(
|
|||
var templates = {};
|
||||
var baseTitle = document.title;
|
||||
|
||||
function init(args, loaded) {
|
||||
function init(params, loaded) {
|
||||
promise.wait(util.promiseTemplate('top-navigation'))
|
||||
.then(function(template) {
|
||||
templates.topNavigation = template;
|
||||
|
|
|
@ -15,9 +15,9 @@ App.Presenters.UserAccountRemovalPresenter = function(
|
|||
var user;
|
||||
var privileges = {};
|
||||
|
||||
function init(args, loaded) {
|
||||
user = args.user;
|
||||
target = args.target;
|
||||
function init(params, loaded) {
|
||||
user = params.user;
|
||||
target = params.target;
|
||||
|
||||
privileges.canDeleteAccount =
|
||||
auth.hasPrivilege(auth.privileges.deleteAllAccounts) ||
|
||||
|
|
|
@ -17,9 +17,9 @@ App.Presenters.UserAccountSettingsPresenter = function(
|
|||
var avatarContent;
|
||||
var fileDropper;
|
||||
|
||||
function init(args, loaded) {
|
||||
user = args.user;
|
||||
target = args.target;
|
||||
function init(params, loaded) {
|
||||
user = params.user;
|
||||
target = params.target;
|
||||
|
||||
privileges = {
|
||||
canBan:
|
||||
|
|
|
@ -17,20 +17,20 @@ App.Presenters.UserActivationPresenter = function(
|
|||
var formHidden = false;
|
||||
var operation;
|
||||
|
||||
function init(args, loaded) {
|
||||
function init(params, loaded) {
|
||||
topNavigationPresenter.select('login');
|
||||
topNavigationPresenter.changeTitle('Account recovery');
|
||||
reinit(args, loaded);
|
||||
reinit(params, loaded);
|
||||
}
|
||||
|
||||
function reinit(args, loaded) {
|
||||
operation = args.operation;
|
||||
function reinit(params, loaded) {
|
||||
operation = params.operation;
|
||||
promise.wait(util.promiseTemplate('user-query-form'))
|
||||
.then(function(template) {
|
||||
templates.userQuery = template;
|
||||
if (args.token) {
|
||||
if (params.token) {
|
||||
hideForm();
|
||||
confirmToken(args.token);
|
||||
confirmToken(params.token);
|
||||
} else {
|
||||
showForm();
|
||||
}
|
||||
|
|
|
@ -14,9 +14,9 @@ App.Presenters.UserBrowsingSettingsPresenter = function(
|
|||
var user;
|
||||
var privileges = {};
|
||||
|
||||
function init(args, loaded) {
|
||||
user = args.user;
|
||||
target = args.target;
|
||||
function init(params, loaded) {
|
||||
user = params.user;
|
||||
target = params.target;
|
||||
|
||||
privileges.canChangeBrowsingSettings = auth.isLoggedIn(user.name) && user.name === auth.getCurrentUser().name;
|
||||
|
||||
|
|
|
@ -12,8 +12,9 @@ App.Presenters.UserListPresenter = function(
|
|||
|
||||
var $el = jQuery('#content');
|
||||
var templates = {};
|
||||
var params;
|
||||
|
||||
function init(args, loaded) {
|
||||
function init(params, loaded) {
|
||||
topNavigationPresenter.select('users');
|
||||
topNavigationPresenter.changeTitle('Users');
|
||||
|
||||
|
@ -36,23 +37,19 @@ App.Presenters.UserListPresenter = function(
|
|||
},
|
||||
},
|
||||
function() {
|
||||
reinit(args, function() {});
|
||||
reinit(params, function() {});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function reinit(args, loaded) {
|
||||
function reinit(_params, loaded) {
|
||||
params = _params;
|
||||
params.query = params.query || {};
|
||||
params.query.order = params.query.order || 'name,asc';
|
||||
updateActiveOrder(params.query.order);
|
||||
|
||||
pagerPresenter.reinit({query: params.query});
|
||||
loaded();
|
||||
|
||||
var searchArgs = util.parseComplexRouteArgs(args.searchArgs);
|
||||
searchArgs.order = searchArgs.order || 'name,asc';
|
||||
searchArgs.page = parseInt(searchArgs.page) || 1;
|
||||
updateActiveOrder(searchArgs.order);
|
||||
|
||||
pagerPresenter.reinit({
|
||||
page: searchArgs.page,
|
||||
searchParams: {
|
||||
order: searchArgs.order}});
|
||||
}
|
||||
|
||||
function deinit() {
|
||||
|
@ -90,7 +87,8 @@ App.Presenters.UserListPresenter = function(
|
|||
e.preventDefault();
|
||||
var $orderLink = jQuery(this);
|
||||
var activeSearchOrder = $orderLink.attr('data-order');
|
||||
pagerPresenter.setSearchParams({order: activeSearchOrder});
|
||||
params.query.order = activeSearchOrder;
|
||||
pagerPresenter.setQuery(params.query);
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -22,32 +22,32 @@ App.Presenters.UserPresenter = function(
|
|||
var userName = null;
|
||||
var activeTab;
|
||||
|
||||
function init(args, loaded) {
|
||||
function init(params, loaded) {
|
||||
promise.wait(util.promiseTemplate('user'))
|
||||
.then(function(template) {
|
||||
$messages = $el.find('.messages');
|
||||
templates.user = template;
|
||||
reinit(args, loaded);
|
||||
reinit(params, loaded);
|
||||
});
|
||||
}
|
||||
|
||||
function reinit(args, loaded) {
|
||||
if (args.userName !== userName) {
|
||||
userName = args.userName;
|
||||
function reinit(params, loaded) {
|
||||
if (params.userName !== userName) {
|
||||
userName = params.userName;
|
||||
topNavigationPresenter.select(auth.isLoggedIn(userName) ? 'my-account' : 'users');
|
||||
topNavigationPresenter.changeTitle(userName);
|
||||
|
||||
promise.wait(api.get('/users/' + userName))
|
||||
.then(function(response) {
|
||||
user = response.json;
|
||||
var extendedContext = _.extend(args, {user: user});
|
||||
var extendedContext = _.extend(params, {user: user});
|
||||
|
||||
presenterManager.initPresenters([
|
||||
[userBrowsingSettingsPresenter, _.extend({}, extendedContext, {target: '#browsing-settings-target'})],
|
||||
[userAccountSettingsPresenter, _.extend({}, extendedContext, {target: '#account-settings-target'})],
|
||||
[userAccountRemovalPresenter, _.extend({}, extendedContext, {target: '#account-removal-target'})]],
|
||||
function() {
|
||||
initTabs(args);
|
||||
initTabs(params);
|
||||
loaded();
|
||||
});
|
||||
|
||||
|
@ -58,13 +58,13 @@ App.Presenters.UserPresenter = function(
|
|||
});
|
||||
|
||||
} else {
|
||||
initTabs(args);
|
||||
initTabs(params);
|
||||
loaded();
|
||||
}
|
||||
}
|
||||
|
||||
function initTabs(args) {
|
||||
activeTab = args.tab || 'basic-info';
|
||||
function initTabs(params) {
|
||||
activeTab = params.tab || 'basic-info';
|
||||
render();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,34 +1,16 @@
|
|||
var App = App || {};
|
||||
|
||||
App.Router = function(pathJs, _, jQuery, promise, util, appState, presenterManager) {
|
||||
App.Router = function(_, jQuery, promise, util, appState, presenterManager) {
|
||||
|
||||
var root = '#/';
|
||||
var previousLocation = window.location.href;
|
||||
var routes = [];
|
||||
|
||||
injectRoutes();
|
||||
|
||||
function navigateToMainPage() {
|
||||
window.location.href = root;
|
||||
}
|
||||
|
||||
function navigate(url) {
|
||||
window.location.href = url;
|
||||
}
|
||||
|
||||
function navigateInplace(url) {
|
||||
if ('replaceState' in history) {
|
||||
history.replaceState('', '', url);
|
||||
pathJs.dispatch(document.location.hash);
|
||||
} else {
|
||||
navigate(url);
|
||||
}
|
||||
}
|
||||
|
||||
function start() {
|
||||
pathJs.listen();
|
||||
}
|
||||
|
||||
function injectRoutes() {
|
||||
inject('', 'homePresenter');
|
||||
inject('#/', 'homePresenter');
|
||||
inject('#/home', 'homePresenter');
|
||||
inject('#/login', 'loginPresenter');
|
||||
inject('#/logout', 'logoutPresenter');
|
||||
|
@ -36,24 +18,42 @@ App.Router = function(pathJs, _, jQuery, promise, util, appState, presenterManag
|
|||
inject('#/upload', 'postUploadPresenter');
|
||||
inject('#/password-reset(/:token)', 'userActivationPresenter', {operation: 'passwordReset'});
|
||||
inject('#/activate(/:token)', 'userActivationPresenter', {operation: 'activation'});
|
||||
inject('#/users(/:searchArgs)', 'userListPresenter');
|
||||
inject('#/users(/:!query)', 'userListPresenter');
|
||||
inject('#/user/:userName(/:tab)', 'userPresenter');
|
||||
inject('#/posts(/:searchArgs)', 'postListPresenter');
|
||||
inject('#/post(/:postNameOrId)(/:searchArgs)', 'postPresenter');
|
||||
inject('#/comments(/:searchArgs)', 'globalCommentListPresenter');
|
||||
inject('#/tags(/:searchArgs)', 'tagListPresenter');
|
||||
inject('#/tag(/:tagName)', 'tagPresenter');
|
||||
inject('#/posts(/:!query)', 'postListPresenter');
|
||||
inject('#/post/:postNameOrId(/:!query)', 'postPresenter');
|
||||
inject('#/comments(/:!query)', 'globalCommentListPresenter');
|
||||
inject('#/tags(/:!query)', 'tagListPresenter');
|
||||
inject('#/tag/:tagName', 'tagPresenter');
|
||||
inject('#/help', 'helpPresenter');
|
||||
setRoot('#/home');
|
||||
}
|
||||
|
||||
function setRoot(newRoot) {
|
||||
root = newRoot;
|
||||
pathJs.root(newRoot);
|
||||
function navigate(url) {
|
||||
window.location.href = url;
|
||||
}
|
||||
|
||||
function inject(path, presenterName, additionalParams) {
|
||||
pathJs.map(path).to(function() {
|
||||
function navigateToMainPage() {
|
||||
navigate(root);
|
||||
}
|
||||
|
||||
function navigateInplace(url) {
|
||||
if ('replaceState' in history) {
|
||||
history.replaceState('', '', url);
|
||||
dispatch();
|
||||
} else {
|
||||
navigate(url);
|
||||
}
|
||||
}
|
||||
|
||||
function start() {
|
||||
window.onpopstate = function() {
|
||||
dispatch();
|
||||
};
|
||||
dispatch();
|
||||
}
|
||||
|
||||
function inject(definition, presenterName, additionalParams) {
|
||||
routes.push(new Route(definition, function(params) {
|
||||
if (util.isExitConfirmationEnabled()) {
|
||||
if (window.location.href === previousLocation) {
|
||||
return;
|
||||
|
@ -67,28 +67,106 @@ App.Router = function(pathJs, _, jQuery, promise, util, appState, presenterManag
|
|||
}
|
||||
}
|
||||
|
||||
params = _.extend({}, params, additionalParams, {previousLocation: previousLocation});
|
||||
|
||||
//abort every operation that can be executed
|
||||
promise.abortAll();
|
||||
previousLocation = window.location.href;
|
||||
|
||||
var finalParams = _.extend(
|
||||
this.params,
|
||||
additionalParams,
|
||||
{previousRoute: pathJs.routes.previous});
|
||||
|
||||
var presenter = App.DI.get(presenterName);
|
||||
presenter.name = presenterName;
|
||||
presenterManager.switchContentPresenter(presenter, finalParams);
|
||||
});
|
||||
presenterManager.switchContentPresenter(presenter, params);
|
||||
}));
|
||||
}
|
||||
|
||||
function dispatch() {
|
||||
var url = document.location.hash;
|
||||
for (var i = 0; i < routes.length; i ++) {
|
||||
var route = routes[i];
|
||||
if (route.match(url)) {
|
||||
route.callback(route.params);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//todo: 404
|
||||
console.log(new Error('Unhandled route: ' + url));
|
||||
return false;
|
||||
}
|
||||
|
||||
function parseComplexParamValue(value) {
|
||||
var result = {};
|
||||
var params = (value || '').split(/;/);
|
||||
for (var i = 0; i < params.length; i ++) {
|
||||
var param = params[i];
|
||||
if (!param) {
|
||||
continue;
|
||||
}
|
||||
var kv = param.split(/=/);
|
||||
result[kv[0]] = kv[1];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function Route(definition, callback) {
|
||||
var possibleRoutes = getPossibleRoutes(definition);
|
||||
|
||||
function getPossibleRoutes(routeDefinition) {
|
||||
var parts = [];
|
||||
var re = new RegExp('\\(([^}]+?)\\)', 'g');
|
||||
while (true) {
|
||||
var text = re.exec(routeDefinition);
|
||||
if (!text) {
|
||||
break;
|
||||
}
|
||||
parts.push(text[1]);
|
||||
}
|
||||
var possibleRoutes = [routeDefinition.split('(')[0]];
|
||||
for (var i = 0; i < parts.length; i ++) {
|
||||
possibleRoutes.push(possibleRoutes[possibleRoutes.length - 1] + parts[i]);
|
||||
}
|
||||
return possibleRoutes;
|
||||
}
|
||||
|
||||
function match(url) {
|
||||
var params = {};
|
||||
for (var i = 0; i < possibleRoutes.length; i ++) {
|
||||
var possibleRoute = possibleRoutes[i];
|
||||
var compare = url;
|
||||
var possibleRouteParts = possibleRoute.split('/');
|
||||
var compareParts = compare.split('/');
|
||||
if (possibleRoute.search(':') > 0) {
|
||||
for (var j = 0; j < possibleRouteParts.length; j ++) {
|
||||
if ((j < compareParts.length) && (possibleRouteParts[j].charAt(0) === ':')) {
|
||||
var key = possibleRouteParts[j].substring(1);
|
||||
var value = compareParts[j];
|
||||
if (key.charAt(0) === '!') {
|
||||
key = key.substring(1);
|
||||
value = parseComplexParamValue(value);
|
||||
}
|
||||
params[key] = value;
|
||||
compare = compare.replace(compareParts[j], possibleRouteParts[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (possibleRoute === compare) {
|
||||
this.params = params;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
this.match = match;
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
start: start,
|
||||
navigate: navigate,
|
||||
navigateInplace: navigateInplace,
|
||||
navigateToMainPage: navigateToMainPage,
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
App.DI.registerSingleton('router', ['pathJs', '_', 'jQuery', 'promise', 'util', 'appState', 'presenterManager'], App.Router);
|
||||
App.DI.registerSingleton('router', ['_', 'jQuery', 'promise', 'util', 'appState', 'presenterManager'], App.Router);
|
||||
|
|
|
@ -9,10 +9,10 @@ App.Services.PostsAroundCalculator = function(_, promise, util, pager) {
|
|||
pager.resetCache();
|
||||
}
|
||||
|
||||
function getLinksToPostsAround(searchParams, page, postId) {
|
||||
function getLinksToPostsAround(query, postId) {
|
||||
return promise.make(function(resolve, reject) {
|
||||
pager.setSearchParams(searchParams);
|
||||
pager.setPage(page);
|
||||
pager.setSearchParams(query);
|
||||
pager.setPage(query.page);
|
||||
promise.wait(pager.retrieveCached())
|
||||
.then(function(response) {
|
||||
var postIds = _.pluck(response.entities, 'id');
|
||||
|
@ -23,8 +23,8 @@ App.Services.PostsAroundCalculator = function(_, promise, util, pager) {
|
|||
}
|
||||
|
||||
promise.wait(
|
||||
getLinkToPostAround(postIds, position, page, -1),
|
||||
getLinkToPostAround(postIds, position, page, 1))
|
||||
getLinkToPostAround(postIds, position, query.page, -1),
|
||||
getLinkToPostAround(postIds, position, query.page, 1))
|
||||
.then(function(nextPostUrl, prevPostUrl) {
|
||||
resolve(nextPostUrl, prevPostUrl);
|
||||
});
|
||||
|
@ -35,7 +35,7 @@ App.Services.PostsAroundCalculator = function(_, promise, util, pager) {
|
|||
function getLinkToPostAround(postIds, position, page, direction) {
|
||||
return promise.make(function(resolve, reject) {
|
||||
if (position + direction >= 0 && position + direction < postIds.length) {
|
||||
var url = util.compileComplexRouteArgs(
|
||||
var url = util.appendComplexRouteParam(
|
||||
'#/post/' + postIds[position + direction],
|
||||
_.extend({page: page}, pager.getSearchParams()));
|
||||
resolve(url);
|
||||
|
@ -47,7 +47,7 @@ App.Services.PostsAroundCalculator = function(_, promise, util, pager) {
|
|||
_.last(response.entities) :
|
||||
_.first(response.entities);
|
||||
|
||||
var url = util.compileComplexRouteArgs(
|
||||
var url = util.appendComplexRouteParam(
|
||||
'#/post/' + post.id,
|
||||
_.extend({page: page + direction}, pager.getSearchParams()));
|
||||
resolve(url);
|
||||
|
|
|
@ -31,31 +31,6 @@ App.Util = function(_, jQuery, marked, promise) {
|
|||
});
|
||||
}
|
||||
|
||||
function parseComplexRouteArgs(args) {
|
||||
var result = {};
|
||||
args = (args || '').split(/;/);
|
||||
for (var i = 0; i < args.length; i ++) {
|
||||
var arg = args[i];
|
||||
if (!arg) {
|
||||
continue;
|
||||
}
|
||||
var kv = arg.split(/=/);
|
||||
result[kv[0]] = kv[1];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function compileComplexRouteArgs(baseUri, args) {
|
||||
var result = baseUri + '/';
|
||||
_.each(args, function(v, k) {
|
||||
if (typeof(v) !== 'undefined') {
|
||||
result += k + '=' + v + ';';
|
||||
}
|
||||
});
|
||||
result = result.slice(0, -1);
|
||||
return result;
|
||||
}
|
||||
|
||||
function promiseTemplate(templateName) {
|
||||
return promiseTemplateFromDOM(templateName) ||
|
||||
promiseTemplateWithAJAX(templateName);
|
||||
|
@ -218,10 +193,18 @@ App.Util = function(_, jQuery, marked, promise) {
|
|||
return postDecorator(marked(preDecorator(text), options));
|
||||
}
|
||||
|
||||
function appendComplexRouteParam(baseUri, params) {
|
||||
var result = baseUri + '/';
|
||||
_.each(params, function(v, k) {
|
||||
if (typeof(v) !== 'undefined') {
|
||||
result += k + '=' + v + ';';
|
||||
}
|
||||
});
|
||||
return result.slice(0, -1);
|
||||
}
|
||||
|
||||
return {
|
||||
promiseTemplate: promiseTemplate,
|
||||
parseComplexRouteArgs: parseComplexRouteArgs,
|
||||
compileComplexRouteArgs: compileComplexRouteArgs,
|
||||
formatRelativeTime: formatRelativeTime,
|
||||
formatFileSize: formatFileSize,
|
||||
formatMarkdown: formatMarkdown,
|
||||
|
@ -230,6 +213,7 @@ App.Util = function(_, jQuery, marked, promise) {
|
|||
isExitConfirmationEnabled: isExitConfirmationEnabled,
|
||||
transparentPixel: transparentPixel,
|
||||
loadImagesNicely: loadImagesNicely,
|
||||
appendComplexRouteParam: appendComplexRouteParam,
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<div class="post-comment">
|
||||
<div class="post">
|
||||
<%= postTemplate({post: post}) %>
|
||||
<%= postTemplate({post: post, util: util}) %>
|
||||
</div>
|
||||
|
||||
<div class="post-comments-target">
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
<div class="post-small post-type-<%= post.contentType %> ">
|
||||
<a class="link"
|
||||
<% if (typeof(searchArgs) !== 'undefined') { %>
|
||||
href="#/post/<%= post.id %>/query=<%= searchArgs.query %>;order=<%= searchArgs.order %>;page=<%= searchArgs.page %>"
|
||||
<% } else { %>
|
||||
href="#/post/<%= post.id %>"
|
||||
<% } %>
|
||||
href="<%= util.appendComplexRouteParam('#/post/' + post.id, typeof(query) !== 'undefined' ? query : {}) %>"
|
||||
title="<%= _.map(post.tags, function(tag) { return '#' + tag.name; }).join(', ') %>">
|
||||
|
||||
<img width="160" height="160" class="thumb" src="/data/thumbnails/160x160/posts/<%= post.name %>" alt="<%= post.idMarkdown %>"/>
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
</div>
|
||||
|
||||
<div class="search">
|
||||
<a href="#/posts/query=<%= searchArgs.query %>;order=<%= searchArgs.order %>">
|
||||
Current search: <%= searchArgs.query || '-' %>
|
||||
<a href="#/posts/query=<%= query.query %>;order=<%= query.order %>">
|
||||
Current search: <%= query.query || '-' %>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
|
Loading…
Reference in a new issue