web-apps/vendor/framework7/src/js/router.js
2016-11-11 16:24:21 +03:00

1269 lines
48 KiB
JavaScript

/*======================================================
************ Navigation / Router ************
======================================================*/
app.router = {
_remove: function (el) {
if (app.params.routerRemoveTimeout || app.params.routerRemoveWithTimeout) {
setTimeout(function () {
$(el).remove();
}, 0);
}
else $(el).remove();
},
// Temporary DOM Element
temporaryDom: document.createElement('div'),
// Find page or navbar in passed container which are related to View
findElement: function (selector, container, view, notCached) {
container = $(container);
if (notCached) selector = selector + ':not(.cached)';
var found = container.find(selector);
if (found.length > 1) {
if (typeof view.selector === 'string') {
// Search in related view
found = container.find(view.selector + ' ' + selector);
}
if (found.length > 1) {
// Search in main view
found = container.find('.' + app.params.viewMainClass + ' ' + selector);
}
}
if (found.length === 1) return found;
else {
// Try to find non cached
if (!notCached) found = app.router.findElement(selector, container, view, true);
if (found && found.length === 1) return found;
if (found && found.length > 1) return $(found[0]);
else return undefined;
}
},
// Set pages classess for animationEnd
animatePages: function (leftPage, rightPage, direction, view) {
// Loading new page
var removeClasses = 'page-on-center page-on-right page-on-left';
if (direction === 'to-left') {
leftPage.removeClass(removeClasses).addClass('page-from-center-to-left');
rightPage.removeClass(removeClasses).addClass('page-from-right-to-center');
}
// Go back
if (direction === 'to-right') {
leftPage.removeClass(removeClasses).addClass('page-from-left-to-center');
rightPage.removeClass(removeClasses).addClass('page-from-center-to-right');
}
},
// Prepare navbar before animarion
prepareNavbar: function (newNavbarInner, oldNavbarInner, newNavbarPosition) {
$(newNavbarInner).find('.sliding').each(function () {
var sliding = $(this);
var slidingOffset = newNavbarPosition === 'right' ? this.f7NavbarRightOffset : this.f7NavbarLeftOffset;
if (app.params.animateNavBackIcon) {
if (sliding.hasClass('left') && sliding.find('.back .icon').length > 0) {
sliding.find('.back .icon').transform('translate3d(' + (-slidingOffset) + 'px,0,0)');
}
}
sliding.transform('translate3d(' + slidingOffset + 'px,0,0)');
});
},
// Set navbars classess for animation
animateNavbars: function (leftNavbarInner, rightNavbarInner, direction, view) {
// Loading new page
var removeClasses = 'navbar-on-right navbar-on-center navbar-on-left';
if (direction === 'to-left') {
rightNavbarInner.removeClass(removeClasses).addClass('navbar-from-right-to-center');
rightNavbarInner.find('.sliding').each(function () {
var sliding = $(this);
sliding.transform('translate3d(0px,0,0)');
if (app.params.animateNavBackIcon) {
if (sliding.hasClass('left') && sliding.find('.back .icon').length > 0) {
sliding.find('.back .icon').transform('translate3d(0px,0,0)');
}
}
});
leftNavbarInner.removeClass(removeClasses).addClass('navbar-from-center-to-left');
leftNavbarInner.find('.sliding').each(function () {
var sliding = $(this);
var rightText;
if (app.params.animateNavBackIcon) {
if (sliding.hasClass('center') && rightNavbarInner.find('.sliding.left .back .icon').length > 0) {
rightText = rightNavbarInner.find('.sliding.left .back span');
if (rightText.length > 0) this.f7NavbarLeftOffset += rightText[0].offsetLeft;
}
if (sliding.hasClass('left') && sliding.find('.back .icon').length > 0) {
sliding.find('.back .icon').transform('translate3d(' + (-this.f7NavbarLeftOffset) + 'px,0,0)');
}
}
sliding.transform('translate3d(' + (this.f7NavbarLeftOffset) + 'px,0,0)');
});
}
// Go back
if (direction === 'to-right') {
leftNavbarInner.removeClass(removeClasses).addClass('navbar-from-left-to-center');
leftNavbarInner.find('.sliding').each(function () {
var sliding = $(this);
sliding.transform('translate3d(0px,0,0)');
if (app.params.animateNavBackIcon) {
if (sliding.hasClass('left') && sliding.find('.back .icon').length > 0) {
sliding.find('.back .icon').transform('translate3d(0px,0,0)');
}
}
});
rightNavbarInner.removeClass(removeClasses).addClass('navbar-from-center-to-right');
rightNavbarInner.find('.sliding').each(function () {
var sliding = $(this);
if (app.params.animateNavBackIcon) {
if (sliding.hasClass('left') && sliding.find('.back .icon').length > 0) {
sliding.find('.back .icon').transform('translate3d(' + (-this.f7NavbarRightOffset) + 'px,0,0)');
}
}
sliding.transform('translate3d(' + (this.f7NavbarRightOffset) + 'px,0,0)');
});
}
},
preprocess: function(view, content, url, next) {
// Plugin hook
app.pluginHook('routerPreprocess', view, content, url, next);
// Preprocess by plugin
content = app.pluginProcess('preprocess', content);
if (view && view.params && view.params.preprocess) {
content = view.params.preprocess(content, url, next);
if (typeof content !== 'undefined') {
next(content);
}
}
else if (app.params.preprocess) {
content = app.params.preprocess(content, url, next);
if (typeof content !== 'undefined') {
next(content);
}
}
else {
next(content);
}
},
preroute: function(view, options, isBack) {
if (isBack) options.isBack = true;
app.pluginHook('routerPreroute', view, options);
if ((app.params.preroute && app.params.preroute(view, options) === false) || (view && view.params.preroute && view.params.preroute(view, options) === false)) {
return true;
}
else {
return false;
}
},
template7Render: function (view, options) {
var url = options.url,
content = options.content, //initial content
t7_rendered_content = options.content, // will be rendered using Template7
context = options.context, // Context data for Template7
contextName = options.contextName,
template = options.template, // Template 7 compiled template
pageName = options.pageName;
var t7_ctx, t7_template;
if (typeof content === 'string') {
if (url) {
if (app.template7Cache[url] && !options.ignoreCache) t7_template = t7.cache[url];
else {
t7_template = t7.compile(content);
t7.cache[url] = t7_template;
}
}
else t7_template = t7.compile(content);
}
else if (template) {
t7_template = template;
}
if (context) {
t7_ctx = context;
if (context && url) {
view.contextCache[url] = context;
}
}
else {
if (contextName) {
if (contextName.indexOf('.') >= 0) {
var _ctx_path = contextName.split('.');
var _ctx = t7.data[_ctx_path[0]];
for (var i = 1; i < _ctx_path.length; i++) {
if (_ctx_path[i]) _ctx = _ctx[_ctx_path[i]];
}
t7_ctx = _ctx;
}
else t7_ctx = t7.data[contextName];
}
if (!t7_ctx && url) {
t7_ctx = t7.data['url:' + url];
}
if (!t7_ctx && typeof content === 'string' && !template) {
//try to find by page name in content
var pageNameMatch = content.match(/(data-page=["'][^"^']*["'])/);
if (pageNameMatch) {
var page = pageNameMatch[0].split('data-page=')[1].replace(/['"]/g, '');
if (page) t7_ctx = t7.data['page:' + page];
}
}
if (!t7_ctx && template && t7.templates) {
// Try to find matched template name in t7.templates
for (var templateName in t7.templates) {
if (t7.templates[templateName] === template) t7_ctx = t7.data[templateName];
}
}
if (!t7_ctx && url && url in view.contextCache) {
t7_ctx = view.contextCache[url];
}
if (!t7_ctx) {
t7_ctx = {};
}
}
if (t7_template && t7_ctx) {
if (typeof t7_ctx === 'function') t7_ctx = t7_ctx();
if (url) {
// Extend data with URL query
var query = $.parseUrlQuery(url);
t7_ctx.url_query = {};
for (var key in query) {
t7_ctx.url_query[key] = query[key];
}
}
try {
t7_rendered_content = t7_template(t7_ctx);
}
catch (e) {
t7_rendered_content = '';
if (window.console && window.console.error) {
console.error(e);
}
}
}
return {content: t7_rendered_content, context: t7_ctx};
}
};
app.router._load = function (view, options) {
options = options || {};
var url = options.url,
content = options.content, //initial content
t7_rendered = {content: options.content},
template = options.template, // Template 7 compiled template
pageName = options.pageName,
viewContainer = $(view.container),
pagesContainer = $(view.pagesContainer),
animatePages = options.animatePages,
newPage, oldPage, pagesInView, i, oldNavbarInner, newNavbarInner, navbar, dynamicNavbar, reloadPosition,
isDynamicPage = typeof url === 'undefined' && content || template,
pushState = options.pushState,
pageElement = options.pageElement;
if (typeof animatePages === 'undefined') animatePages = view.params.animatePages;
// Plugin hook
app.pluginHook('routerLoad', view, options);
// Render with Template7
if (app.params.template7Pages && typeof content === 'string' || template) {
t7_rendered = app.router.template7Render(view, options);
if (t7_rendered.content && !content) {
content = t7_rendered.content;
}
}
app.router.temporaryDom.innerHTML = '';
// Parse DOM
if (!pageName && !pageElement) {
if ((typeof content === 'string') || (url && (typeof content === 'string'))) {
app.router.temporaryDom.innerHTML = t7_rendered.content;
} else {
if ('length' in content && content.length > 1) {
for (var ci = 0; ci < content.length; ci++) {
$(app.router.temporaryDom).append(content[ci]);
}
} else {
$(app.router.temporaryDom).append(content);
}
}
}
// Reload position
reloadPosition = options.reload && (options.reloadPrevious ? 'left' : 'center');
// Find new page
if (pageName) newPage = pagesContainer.find('.page[data-page="' + pageName + '"]');
else {
if (pageElement) newPage = $(pageElement);
else newPage = app.router.findElement('.page', app.router.temporaryDom, view);
}
// If page not found exit
if (!newPage || newPage.length === 0 || (pageName && view.activePage && view.activePage.name === pageName)) {
view.allowPageChange = true;
return;
}
newPage.addClass(options.reload ? 'page-on-' + reloadPosition : 'page-on-right');
// Find old page (should be the last one) and remove older pages
pagesInView = pagesContainer.children('.page:not(.cached)');
if (pageElement) {
pagesInView = pagesInView.filter(function (index, page) {
if (page !== pageElement) return page;
});
}
if (options.reload && options.reloadPrevious && pagesInView.length === 1) {
view.allowPageChange = true;
return;
}
if (options.reload) {
oldPage = pagesInView.eq(pagesInView.length - 1);
}
else {
if (pagesInView.length > 1) {
for (i = 0; i < pagesInView.length - 2; i++) {
if (!view.params.domCache) {
app.pageRemoveCallback(view, pagesInView[i], 'left');
app.router._remove(pagesInView[i]);
}
else {
$(pagesInView[i]).addClass('cached');
}
}
if (!view.params.domCache) {
app.pageRemoveCallback(view, pagesInView[i], 'left');
app.router._remove(pagesInView[i]);
}
else {
$(pagesInView[i]).addClass('cached');
}
}
oldPage = pagesContainer.children('.page:not(.cached)');
}
if (pageElement && oldPage.length > 1) {
oldPage = oldPage.filter(function (index, page) {
if (page !== pageElement) return page;
});
}
if(view.params.domCache || pageElement) newPage.removeClass('cached');
// Dynamic navbar
if (view.params.dynamicNavbar) {
dynamicNavbar = true;
// Find navbar
if (pageName) {
newNavbarInner = viewContainer.find('.navbar-inner[data-page="' + pageName + '"]');
}
else {
newNavbarInner = app.router.findElement('.navbar-inner', app.router.temporaryDom, view);
}
if (!newNavbarInner || newNavbarInner.length === 0) {
// Look in page
newNavbarInner = newPage.find('.navbar-inner');
if (!newNavbarInner || newNavbarInner.length === 0) {
// Set false
dynamicNavbar = false;
}
else {
if (newNavbarInner.parent('.navbar').length > 0) {
newNavbarInner.prependTo(newPage);
}
}
}
if (dynamicNavbar && newPage.find('.navbar').length > 0) {
app.router._remove(newPage.find('.navbar'));
}
navbar = viewContainer.children('.navbar');
if (options.reload) {
oldNavbarInner = navbar.find('.navbar-inner:not(.cached):last-child');
}
else {
oldNavbarInner = navbar.find('.navbar-inner:not(.cached)');
if (oldNavbarInner.length > 0) {
for (i = 0; i < oldNavbarInner.length - 1; i++) {
if (!view.params.domCache) {
app.navbarRemoveCallback(view, pagesInView[i], navbar[0], oldNavbarInner[i]);
app.router._remove(oldNavbarInner[i]);
}
else
$(oldNavbarInner[i]).addClass('cached');
}
if (!newNavbarInner && oldNavbarInner.length === 1) {
if (!view.params.domCache) {
app.navbarRemoveCallback(view, pagesInView[0], navbar[0], oldNavbarInner[0]);
app.router._remove(oldNavbarInner[0]);
}
else
$(oldNavbarInner[0]).addClass('cached');
}
oldNavbarInner = navbar.find('.navbar-inner:not(.cached)');
}
}
}
if (dynamicNavbar) {
newNavbarInner.addClass(options.reload ? 'navbar-on-' + reloadPosition : 'navbar-on-right');
if(view.params.domCache || pageElement) newNavbarInner.removeClass('cached');
newPage[0].f7RelatedNavbar = newNavbarInner[0];
newNavbarInner[0].f7RelatedPage = newPage[0];
}
// save content areas into view's cache
if (!url) {
var newPageName = pageName || newPage.attr('data-page');
if (isDynamicPage) url = '#' + app.params.dynamicPageUrl.replace(/{{name}}/g, newPageName).replace(/{{index}}/g, view.history.length - (options.reload ? 1 : 0));
else url = '#' + newPageName;
if (!view.params.domCache) {
view.contentCache[url] = content;
}
if (view.params.domCache && pageName) {
view.pagesCache[url] = pageName;
}
}
else if (url && pageElement) {
view.pageElementsCache[url] = {
page: newPage,
navbarInner: newNavbarInner
};
}
// Push State
if (app.params.pushState && !options.reloadPrevious && view.main) {
if (typeof pushState === 'undefined') pushState = true;
var pushStateRoot = app.params.pushStateRoot || '';
var method = options.reload ? 'replaceState' : 'pushState';
if (pushState) {
if (!isDynamicPage && !pageName) {
history[method]({url: url, viewIndex: app.views.indexOf(view)}, '', pushStateRoot + app.params.pushStateSeparator + url);
}
else if (isDynamicPage && content) {
history[method]({content: typeof content === 'string' ? content : '', url: url, viewIndex: app.views.indexOf(view)}, '', pushStateRoot + app.params.pushStateSeparator + url);
}
else if (pageName) {
history[method]({pageName: pageName, url: url, viewIndex: app.views.indexOf(view)}, '', pushStateRoot + app.params.pushStateSeparator + url);
}
}
}
// Update View history
view.url = url;
if (options.reload) {
var lastUrl = view.history[view.history.length - (options.reloadPrevious ? 2 : 1)];
if (lastUrl &&
lastUrl.indexOf('#') === 0 &&
lastUrl in view.contentCache &&
lastUrl !== url &&
view.history.indexOf(lastUrl) === -1) {
view.contentCache[lastUrl] = null;
delete view.contentCache[lastUrl];
}
else if (lastUrl &&
lastUrl in view.pageElementsCache &&
lastUrl !== url &&
(view.history.indexOf(lastUrl) === -1 || view.history.indexOf(lastUrl) === view.history.length - 1)) {
view.pageElementsCache[lastUrl] = null;
delete view.pageElementsCache[lastUrl];
}
if (lastUrl &&
lastUrl in view.contextCache &&
lastUrl !== url &&
(view.history.indexOf(lastUrl) === -1 || view.history.indexOf(lastUrl) === view.history.length - 1)) {
view.contextCache[lastUrl] = null;
delete view.contextCache[lastUrl];
}
view.history[view.history.length - (options.reloadPrevious ? 2 : 1)] = url;
}
else {
view.history.push(url);
}
// Unique history
var historyBecameUnique = false;
if (view.params.uniqueHistory) {
var _history = view.history;
var _url = url;
if (view.params.uniqueHistoryIgnoreGetParameters) {
_history = [];
_url = url.split('?')[0];
for (i = 0; i < view.history.length; i++) {
_history.push(view.history[i].split('?')[0]);
}
}
if (_history.indexOf(_url) !== _history.lastIndexOf(_url)) {
view.history = view.history.slice(0, _history.indexOf(_url));
view.history.push(url);
historyBecameUnique = true;
}
}
// Dom manipulations
if (options.reloadPrevious) {
oldPage = oldPage.prev('.page');
newPage.insertBefore(oldPage);
if (dynamicNavbar) {
oldNavbarInner = oldNavbarInner.prev('.navbar-inner');
newNavbarInner.insertAfter(oldNavbarInner);
}
}
else {
pagesContainer.append(newPage[0]);
if (dynamicNavbar) navbar.append(newNavbarInner[0]);
}
// Remove Old Page And Navbar
if (options.reload) {
if (view.params.domCache && view.initialPages.indexOf(oldPage[0]) >= 0) {
oldPage.addClass('cached');
if (dynamicNavbar) oldNavbarInner.addClass('cached');
}
else {
app.pageRemoveCallback(view, oldPage[0], reloadPosition);
if (dynamicNavbar) app.navbarRemoveCallback(view, oldPage[0], navbar[0], oldNavbarInner[0]);
app.router._remove(oldPage);
if (dynamicNavbar) app.router._remove(oldNavbarInner);
}
}
// Page Init Events
app.pageInitCallback(view, {
pageContainer: newPage[0],
url: url,
position: options.reload ? reloadPosition : 'right',
navbarInnerContainer: dynamicNavbar ? newNavbarInner && newNavbarInner[0] : undefined,
oldNavbarInnerContainer: dynamicNavbar ? oldNavbarInner && oldNavbarInner[0] : undefined,
context: t7_rendered.context,
query: options.query,
fromPage: oldPage && oldPage.length && oldPage[0].f7PageData,
reload: options.reload,
reloadPrevious: options.reloadPrevious
});
// Navbar init event
if (dynamicNavbar) {
app.navbarInitCallback(view, newPage[0], navbar[0], newNavbarInner[0], url, options.reload ? reloadPosition : 'right');
}
if (options.reload) {
view.allowPageChange = true;
if (historyBecameUnique) view.refreshPreviousPage();
return;
}
if (dynamicNavbar && animatePages) {
app.router.prepareNavbar(newNavbarInner, oldNavbarInner, 'right');
}
// Force reLayout
var clientLeft = newPage[0].clientLeft;
// Before Anim Callback
app.pageAnimCallback('before', view, {
pageContainer: newPage[0],
url: url,
position: 'right',
oldPage: oldPage,
newPage: newPage,
query: options.query,
fromPage: oldPage && oldPage.length && oldPage[0].f7PageData
});
function afterAnimation() {
view.allowPageChange = true;
newPage.removeClass('page-from-right-to-center page-on-right page-on-left').addClass('page-on-center');
oldPage.removeClass('page-from-center-to-left page-on-center page-on-right').addClass('page-on-left');
if (dynamicNavbar) {
newNavbarInner.removeClass('navbar-from-right-to-center navbar-on-left navbar-on-right').addClass('navbar-on-center');
oldNavbarInner.removeClass('navbar-from-center-to-left navbar-on-center navbar-on-right').addClass('navbar-on-left');
}
app.pageAnimCallback('after', view, {
pageContainer: newPage[0],
url: url,
position: 'right',
oldPage: oldPage,
newPage: newPage,
query: options.query,
fromPage: oldPage && oldPage.length && oldPage[0].f7PageData
});
if (app.params.pushState && view.main) app.pushStateClearQueue();
if (!(view.params.swipeBackPage || view.params.preloadPreviousPage)) {
if (view.params.domCache) {
oldPage.addClass('cached');
if (dynamicNavbar) oldNavbarInner.addClass('cached');
}
else {
if (!(url.indexOf('#') === 0 && newPage.attr('data-page').indexOf('smart-select-') === 0)) {
app.pageRemoveCallback(view, oldPage[0], 'left');
if (dynamicNavbar) app.navbarRemoveCallback(view, oldPage[0], navbar[0], oldNavbarInner[0]);
app.router._remove(oldPage);
if (dynamicNavbar) app.router._remove(oldNavbarInner);
}
}
}
if (view.params.uniqueHistory && historyBecameUnique) {
view.refreshPreviousPage();
}
}
if (animatePages) {
// Set pages before animation
if (app.params.material && app.params.materialPageLoadDelay) {
setTimeout(function () {
app.router.animatePages(oldPage, newPage, 'to-left', view);
}, app.params.materialPageLoadDelay);
}
else {
app.router.animatePages(oldPage, newPage, 'to-left', view);
}
// Dynamic navbar animation
if (dynamicNavbar) {
setTimeout(function() {
app.router.animateNavbars(oldNavbarInner, newNavbarInner, 'to-left', view);
}, 0);
}
newPage.animationEnd(function (e) {
afterAnimation();
});
}
else {
if (dynamicNavbar) newNavbarInner.find('.sliding, .sliding .back .icon').transform('');
afterAnimation();
}
};
app.router.load = function (view, options) {
options = options || {};
if (app.router.preroute(view, options)) {
return false;
}
var url = options.url;
var content = options.content;
var pageName = options.pageName;
var pageElement = options.pageElement;
if (pageName) {
if (pageName.indexOf('?') > 0) {
options.query = $.parseUrlQuery(pageName);
options.pageName = pageName = pageName.split('?')[0];
}
}
var template = options.template;
if (view.params.reloadPages === true) options.reload = true;
if (!view.allowPageChange) return false;
if (url && view.url === url && !options.reload && !view.params.allowDuplicateUrls) return false;
view.allowPageChange = false;
if (app.xhr && view.xhr && view.xhr === app.xhr) {
app.xhr.abort();
app.xhr = false;
}
function proceed(content) {
app.router.preprocess(view, content, url, function (content) {
options.content = content;
app.router._load(view, options);
});
}
if (content || pageName || pageElement) {
proceed(content);
return;
}
else if (template) {
app.router._load(view, options);
return;
}
if (!options.url || options.url === '#') {
view.allowPageChange = true;
return;
}
app.get(options.url, view, options.ignoreCache, function (content, error) {
if (error) {
view.allowPageChange = true;
return;
}
proceed(content);
});
};
app.router._back = function (view, options) {
options = options || {};
var url = options.url,
content = options.content,
t7_rendered = {content: options.content}, // will be rendered using Template7
template = options.template, // Template 7 compiled template
animatePages = options.animatePages,
preloadOnly = options.preloadOnly,
pushState = options.pushState,
ignoreCache = options.ignoreCache,
force = options.force,
pageName = options.pageName,
pageElement = options.pageElement;
var viewContainer = $(view.container),
pagesContainer = $(view.pagesContainer),
pagesInView = pagesContainer.children('.page:not(.cached)'),
oldPage, newPage, oldNavbarInner, newNavbarInner, navbar, navbarInners, dynamicNavbar, manipulateDom = true;
if (typeof animatePages === 'undefined') animatePages = view.params.animatePages;
app.pluginHook('routerBack', view, options);
// Render with Template7
if (app.params.template7Pages && typeof content === 'string' || template) {
t7_rendered = app.router.template7Render(view, options);
if (t7_rendered.content && !content) {
content = t7_rendered.content;
}
}
// Animation
function afterAnimation() {
app.pageBackCallback('after', view, {
pageContainer: oldPage[0],
url: url,
position: 'center',
oldPage: oldPage,
newPage: newPage,
});
app.pageAnimCallback('after', view, {
pageContainer: newPage[0],
url: url,
position: 'left',
oldPage: oldPage,
newPage: newPage,
query: options.query,
fromPage: oldPage && oldPage.length && oldPage[0].f7PageData
});
app.router.afterBack(view, oldPage[0], newPage[0]);
}
function animateBack() {
// Page before animation callback
app.pageBackCallback('before', view, {
pageContainer: oldPage[0],
url: url,
position: 'center',
oldPage: oldPage,
newPage: newPage,
});
app.pageAnimCallback('before', view, {
pageContainer: newPage[0],
url: url,
position: 'left',
oldPage: oldPage,
newPage: newPage,
query: options.query,
fromPage: oldPage && oldPage.length && oldPage[0].f7PageData
});
if (animatePages) {
// Set pages before animation
app.router.animatePages(newPage, oldPage, 'to-right', view);
// Dynamic navbar animation
if (dynamicNavbar) {
setTimeout(function () {
app.router.animateNavbars(newNavbarInner, oldNavbarInner, 'to-right', view);
}, 0);
}
newPage.animationEnd(function () {
afterAnimation();
});
}
else {
if (dynamicNavbar) newNavbarInner.find('.sliding, .sliding .back .icon').transform('');
afterAnimation();
}
}
function parseNewPage() {
app.router.temporaryDom.innerHTML = '';
// Parse DOM
if ((typeof content === 'string') || (url && (typeof content === 'string'))) {
app.router.temporaryDom.innerHTML = t7_rendered.content;
} else {
if ('length' in content && content.length > 1) {
for (var ci = 0; ci < content.length; ci++) {
$(app.router.temporaryDom).append(content[ci]);
}
} else {
$(app.router.temporaryDom).append(content);
}
}
if (pageElement) newPage = $(pageElement);
else newPage = app.router.findElement('.page', app.router.temporaryDom, view);
if (view.params.dynamicNavbar) {
// Find navbar
newNavbarInner = app.router.findElement('.navbar-inner', app.router.temporaryDom, view);
}
}
function setPages() {
// If pages not found or there are still more than one, exit
if (!newPage || newPage.length === 0) {
view.allowPageChange = true;
return;
}
if (view.params.dynamicNavbar && typeof dynamicNavbar === 'undefined') {
if (!newNavbarInner || newNavbarInner.length === 0) {
dynamicNavbar = false;
}
else {
dynamicNavbar = true;
}
}
newPage.addClass('page-on-left').removeClass('cached');
if (dynamicNavbar) {
navbar = viewContainer.children('.navbar');
navbarInners = navbar.find('.navbar-inner:not(.cached)');
newNavbarInner.addClass('navbar-on-left').removeClass('cached');
}
// Remove/hide previous page in force mode
if (force) {
var pageToRemove, navbarToRemove;
pageToRemove = $(pagesInView[pagesInView.length - 2]);
if (dynamicNavbar) navbarToRemove = $(pageToRemove[0] && pageToRemove[0].f7RelatedNavbar || navbarInners[navbarInners.length - 2]);
if (view.params.domCache && view.initialPages.indexOf(pageToRemove[0]) >= 0) {
if (pageToRemove.length && pageToRemove[0] !== newPage[0]) pageToRemove.addClass('cached');
if (dynamicNavbar && navbarToRemove.length && navbarToRemove[0] !== newNavbarInner[0]) {
navbarToRemove.addClass('cached');
}
}
else {
var removeNavbar = dynamicNavbar && navbarToRemove.length;
if (pageToRemove.length) {
app.pageRemoveCallback(view, pageToRemove[0], 'right');
if (removeNavbar) {
app.navbarRemoveCallback(view, pageToRemove[0], navbar[0], navbarToRemove[0]);
}
app.router._remove(pageToRemove);
if (removeNavbar) app.router._remove(navbarToRemove);
}
else if (removeNavbar) {
app.navbarRemoveCallback(view, pageToRemove[0], navbar[0], navbarToRemove[0]);
app.router._remove(navbarToRemove);
}
}
pagesInView = pagesContainer.children('.page:not(.cached)');
if (dynamicNavbar) {
navbarInners = viewContainer.children('.navbar').find('.navbar-inner:not(.cached)');
}
if (view.history.indexOf(url) >= 0) {
view.history = view.history.slice(0, view.history.indexOf(url) + 2);
}
else {
if (view.history[[view.history.length - 2]]) {
view.history[view.history.length - 2] = url;
}
else {
view.history.unshift(url);
}
}
}
oldPage = $(pagesInView[pagesInView.length - 1]);
if (view.params.domCache) {
if (oldPage[0] === newPage[0]) {
oldPage = pagesContainer.children('.page.page-on-center');
if (oldPage.length === 0 && view.activePage) oldPage = $(view.activePage.container);
}
}
if (dynamicNavbar && !oldNavbarInner) {
oldNavbarInner = $(navbarInners[navbarInners.length - 1]);
if (view.params.domCache) {
if (oldNavbarInner[0] === newNavbarInner[0]) {
oldNavbarInner = navbar.children('.navbar-inner.navbar-on-center:not(.cached)');
}
if (oldNavbarInner.length === 0) {
oldNavbarInner = navbar.children('.navbar-inner[data-page="'+oldPage.attr('data-page')+'"]');
}
}
if (oldNavbarInner.length === 0 || newNavbarInner[0] === oldNavbarInner[0]) dynamicNavbar = false;
}
if (dynamicNavbar) {
if (manipulateDom) newNavbarInner.insertBefore(oldNavbarInner);
newNavbarInner[0].f7RelatedPage = newPage[0];
newPage[0].f7RelatedNavbar = newNavbarInner[0];
}
if (manipulateDom) newPage.insertBefore(oldPage);
// Page Init Events
app.pageInitCallback(view, {
pageContainer: newPage[0],
url: url,
position: 'left',
navbarInnerContainer: dynamicNavbar ? newNavbarInner[0] : undefined,
oldNavbarInnerContainer: dynamicNavbar ? oldNavbarInner && oldNavbarInner[0] : undefined,
context: t7_rendered.context,
query: options.query,
fromPage: oldPage && oldPage.length && oldPage[0].f7PageData,
preloadOnly: preloadOnly
});
if (dynamicNavbar) {
app.navbarInitCallback(view, newPage[0], navbar[0], newNavbarInner[0], url, 'right');
}
if (dynamicNavbar && newNavbarInner.hasClass('navbar-on-left') && animatePages) {
app.router.prepareNavbar(newNavbarInner, oldNavbarInner, 'left');
}
if (preloadOnly) {
view.allowPageChange = true;
return;
}
// Update View's URL
view.url = url;
// Force reLayout
var clientLeft = newPage[0].clientLeft;
animateBack();
// Push state
if (app.params.pushState && view.main) {
if (typeof pushState === 'undefined') pushState = true;
if (!preloadOnly && history.state && pushState) {
history.back();
}
}
return;
}
// Simple go back when we have pages on left
if (pagesInView.length > 1 && !force) {
// Exit if only preloadOnly
if (preloadOnly) {
view.allowPageChange = true;
return;
}
// Update View's URL
view.url = view.history[view.history.length - 2];
url = view.url;
// Define old and new pages
newPage = $(pagesInView[pagesInView.length - 2]);
oldPage = $(pagesInView[pagesInView.length - 1]);
// Dynamic navbar
if (view.params.dynamicNavbar) {
dynamicNavbar = true;
// Find navbar
navbarInners = viewContainer.children('.navbar').find('.navbar-inner:not(.cached)');
newNavbarInner = $(navbarInners[0]);
oldNavbarInner = $(navbarInners[1]);
if (newNavbarInner.length === 0 || oldNavbarInner.length === 0 || oldNavbarInner[0] === newNavbarInner[0]) {
dynamicNavbar = false;
}
}
manipulateDom = false;
setPages();
return;
}
if (!force) {
// Go back when there is no pages on left
if (!preloadOnly) {
view.url = view.history[view.history.length - 2];
url = view.url;
}
if (content) {
parseNewPage();
setPages();
return;
}
else if (pageName) {
// Get dom cached pages
newPage = $(viewContainer).find('.page[data-page="' + pageName + '"]');
if (view.params.dynamicNavbar) {
newNavbarInner = $(viewContainer).children('.navbar').find('.navbar-inner[data-page="' + pageName + '"]');
if (newNavbarInner.length === 0 && newPage[0].f7RelatedNavbar) {
newNavbarInner = $(newPage[0].f7RelatedNavbar);
}
if (newNavbarInner.length === 0 && newPage[0].f7PageData) {
newNavbarInner = $(newPage[0].f7PageData.navbarInnerContainer);
}
}
setPages();
return;
}
else if (url && url in view.pageElementsCache) {
newPage = view.pageElementsCache[url].page;
newNavbarInner = view.pageElementsCache[url].navbarInner;
setPages();
return;
}
else {
view.allowPageChange = true;
return;
}
}
else {
if (url && url === view.url || pageName && view.activePage && view.activePage.name === pageName) {
view.allowPageChange = true;
return;
}
// Go back with force url
if (content) {
parseNewPage();
setPages();
return;
}
else if (pageName && view.params.domCache) {
if (pageName) url = '#' + pageName;
newPage = $(viewContainer).find('.page[data-page="' + pageName + '"]');
if (newPage[0].f7PageData && newPage[0].f7PageData.url) {
url = newPage[0].f7PageData.url;
}
if (view.params.dynamicNavbar) {
newNavbarInner = $(viewContainer).children('.navbar').find('.navbar-inner[data-page="' + pageName + '"]');
if (newNavbarInner.length === 0 && newPage[0].f7RelatedNavbar) {
newNavbarInner = $(newPage[0].f7RelatedNavbar);
}
if (newNavbarInner.length === 0 && newPage[0].f7PageData) {
newNavbarInner = $(newPage[0].f7PageData.navbarInnerContainer);
}
}
setPages();
return;
}
else if (pageElement && url) {
newPage = $(pageElement);
if (view.params.dynamicNavbar) {
newNavbarInner = newPage.find('.navbar-inner');
if (newNavbarInner.length > 0) {
newPage.prepend(newNavbarInner);
app.router._remove(newPage.find('.navbar'));
}
}
setPages();
return;
}
else {
view.allowPageChange = true;
return;
}
}
};
app.router.back = function (view, options) {
options = options || {};
if (app.router.preroute(view, options, true)) {
return false;
}
var url = options.url;
var content = options.content;
var pageName = options.pageName;
var pageElement = options.pageElement;
if (pageName) {
if (pageName.indexOf('?') > 0) {
options.query = $.parseUrlQuery(pageName);
options.pageName = pageName = pageName.split('?')[0];
}
}
var force = options.force;
if (!view.allowPageChange) return false;
view.allowPageChange = false;
if (app.xhr && view.xhr && view.xhr === app.xhr) {
app.xhr.abort();
app.xhr = false;
}
var pagesInView = $(view.pagesContainer).find('.page:not(.cached)');
function proceed(content) {
app.router.preprocess(view, content, url, function (content) {
options.content = content;
app.router._back(view, options);
});
}
if (pagesInView.length > 1 && !force) {
// Simple go back to previos page in view
app.router._back(view, options);
return;
}
if (!force) {
url = view.history[view.history.length - 2] || options.url;
if (!options.url) options.url = url;
if (!url) {
view.allowPageChange = true;
return;
}
if (url.indexOf('#') === 0 && view.contentCache[url]) {
proceed(view.contentCache[url]);
return;
}
else if (url.indexOf('#') === 0 && view.params.domCache) {
if (!pageName) options.pageName = url.split('#')[1];
proceed();
return;
}
else if (url && url in view.pageElementsCache) {
proceed();
}
else if (url.indexOf('#') !== 0) {
// Load ajax page
app.get(options.url, view, options.ignoreCache, function (content, error) {
if (error) {
view.allowPageChange = true;
return;
}
proceed(content);
});
return;
}
}
else {
// Go back with force url
if (!url && content) {
proceed(content);
return;
}
else if (!url && pageName) {
if (pageName) url = '#' + pageName;
proceed();
return;
}
else if (url && pageElement) {
proceed();
return;
}
else if (url) {
app.get(options.url, view, options.ignoreCache, function (content, error) {
if (error) {
view.allowPageChange = true;
return;
}
proceed(content);
});
return;
}
}
view.allowPageChange = true;
return;
};
app.router.afterBack = function (view, oldPage, newPage) {
// Remove old page and set classes on new one
oldPage = $(oldPage);
newPage = $(newPage);
if (view.params.domCache && view.initialPages.indexOf(oldPage[0]) >= 0) {
oldPage.removeClass('page-from-center-to-right').addClass('cached');
}
else {
app.pageRemoveCallback(view, oldPage[0], 'right');
app.router._remove(oldPage);
}
newPage.removeClass('page-from-left-to-center page-on-left').addClass('page-on-center');
view.allowPageChange = true;
// Update View's History
var previousURL = view.history.pop();
var newNavbar;
// Updated dynamic navbar
if (view.params.dynamicNavbar) {
var inners = $(view.container).children('.navbar').find('.navbar-inner:not(.cached)');
var oldNavbar = $(oldPage[0].f7RelatedNavbar || inners[1]);
if (view.params.domCache && view.initialNavbars.indexOf(oldNavbar[0]) >= 0) {
oldNavbar.removeClass('navbar-from-center-to-right').addClass('cached');
}
else {
app.navbarRemoveCallback(view, oldPage[0], undefined, oldNavbar[0]);
app.router._remove(oldNavbar);
}
newNavbar = $(inners[0]).removeClass('navbar-on-left navbar-from-left-to-center').addClass('navbar-on-center');
}
// Remove pages in dom cache
if (view.params.domCache) {
$(view.container).find('.page.cached').each(function () {
var page = $(this);
var index = page.index();
var pageUrl = page[0].f7PageData && page[0].f7PageData.url;
if (pageUrl && view.history.indexOf(pageUrl) < 0 && view.initialPages.indexOf(this) < 0) {
app.pageRemoveCallback(view, page[0], 'right');
if (page[0].f7RelatedNavbar && view.params.dynamicNavbar) app.navbarRemoveCallback(view, page[0], undefined, page[0].f7RelatedNavbar);
app.router._remove(page);
if (page[0].f7RelatedNavbar && view.params.dynamicNavbar) app.router._remove(page[0].f7RelatedNavbar);
}
});
}
// Check previous page is content based only and remove it from content cache
if (!view.params.domCache &&
previousURL &&
previousURL.indexOf('#') > -1 &&
(previousURL in view.contentCache) &&
// If the same page is in the history multiple times, don't remove it.
view.history.indexOf(previousURL) === -1) {
view.contentCache[previousURL] = null;
delete view.contentCache[previousURL];
}
if (previousURL &&
(previousURL in view.pageElementsCache) &&
// If the same page is in the history multiple times, don't remove it.
view.history.indexOf(previousURL) === -1) {
view.pageElementsCache[previousURL] = null;
delete view.pageElementsCache[previousURL];
}
// Check for context cache
if (previousURL &&
(previousURL in view.contextCache) &&
// If the same page is in the history multiple times, don't remove it.
view.history.indexOf(previousURL) === -1) {
view.contextCache[previousURL] = null;
delete view.contextCache[previousURL];
}
if (app.params.pushState && view.main) app.pushStateClearQueue();
// Preload previous page
if (view.params.preloadPreviousPage) {
if (view.params.domCache && view.history.length > 1) {
var preloadUrl = view.history[view.history.length - 2];
var previousPage;
var previousNavbar;
if (preloadUrl && view.pagesCache[preloadUrl]) {
// Load by page name
previousPage = $(view.container).find('.page[data-page="' + view.pagesCache[preloadUrl] + '"]');
if (previousPage.next('.page')[0] !== newPage[0]) previousPage.insertBefore(newPage);
if (newNavbar) {
previousNavbar = $(view.container).children('.navbar').find('.navbar-inner[data-page="' + view.pagesCache[preloadUrl] + '"]');
if(!previousNavbar || previousNavbar.length === 0) previousNavbar = newNavbar.prev('.navbar-inner.cached');
if (previousNavbar.next('.navbar-inner')[0] !== newNavbar[0]) previousNavbar.insertBefore(newNavbar);
}
}
else {
// Just load previous page
previousPage = newPage.prev('.page.cached');
if (newNavbar) previousNavbar = newNavbar.prev('.navbar-inner.cached');
}
if (previousPage && previousPage.length > 0) previousPage.removeClass('cached page-on-right page-on-center').addClass('page-on-left');
if (previousNavbar && previousNavbar.length > 0) previousNavbar.removeClass('cached navbar-on-right navbar-on-center').addClass('navbar-on-left');
}
else {
app.router.back(view, {preloadOnly: true});
}
}
};