Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/core/components/app/app-class.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,20 @@ import $jsx from '../../shared/$jsx.js';

class Framework7 extends Framework7Class {
constructor(params = {}) {
const routes = params.routes;
if (routes) {
params.routes = routes.map(route => {
const newRoute = { ...route };
const options = newRoute.options ||= {};
const props = options.props ||= {};
Object.defineProperty(props, 'routeId', {
get: () => `${Date.now()}_${Math.random().toString(36).slice(2)}`,
enumerable: true,
configurable: true
});
return newRoute;
});
}
super(params);
// eslint-disable-next-line
if (Framework7.instance && typeof window !== 'undefined') {
Expand Down
2 changes: 2 additions & 0 deletions src/core/modules/router/component-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,15 @@ export default {
if (options.componentOptions && options.componentOptions.root) {
componentRoot = options.componentOptions.root;
}
const routeId = componentProps.routeId;
app.component
.create(componentFunction, componentProps, {
context: componentContext,
el: componentEl,
root: componentRoot,
})
.then((createdComponent) => {
if (routeId) createdComponent.el.routeId = routeId;
resolve(createdComponent.el);
})
.catch((err) => {
Expand Down
51 changes: 44 additions & 7 deletions src/core/modules/router/router-class.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,17 @@ class Router extends Framework7Class {
return router.findElement('.page', router.tempDom);
}

findElement(stringSelector, container) {
findElement(stringSelector, container, depth = 0) {
const router = this;
const view = router.view;
const app = router.app;

const MAX_DEPTH = 10;
if (depth > MAX_DEPTH) {
console.error('Framework7: findElement recursion depth exceeded when searching for "' + stringSelector + '". Please check the container parameter:', container);
throw new Error('Framework7: findElement recursion depth exceeded when searching for "' + stringSelector + '"');
}

// Modals Selector
const modalsSelector =
'.popup, .dialog, .popover, .actions-modal, .sheet-modal, .login-screen, .page';
Expand All @@ -236,7 +242,7 @@ class Router extends Framework7Class {
}
if (found.length === 1) return found;

found = router.findElement(selector, $container);
found = router.findElement(selector, $container, depth + 1);
if (found && found.length === 1) return found;
if (found && found.length > 1) return $(found[0]);
return undefined;
Expand Down Expand Up @@ -730,12 +736,14 @@ class Router extends Framework7Class {
if (callback === 'mounted') {
attachEvents();
}

const routeId = page.routeId || page.route.url;
if (callback === 'init') {
if (
restoreScrollTopOnBack &&
(from === 'previous' || !from) &&
to === 'current' &&
router.scrollHistory[page.route.url] &&
router.scrollHistory[routeId] &&
!$pageEl.hasClass('no-restore-scroll')
) {
let $pageContent = $pageEl.find('.page-content');
Expand All @@ -748,7 +756,7 @@ class Router extends Framework7Class {
);
});
}
$pageContent.scrollTop(router.scrollHistory[page.route.url]);
$pageContent.scrollTop(router.scrollHistory[routeId]);
}
attachEvents();
if ($pageEl[0].f7PageInitialized) {
Expand All @@ -775,11 +783,11 @@ class Router extends Framework7Class {
);
});
}
router.scrollHistory[page.route.url] = $pageContent.scrollTop();
router.scrollHistory[routeId] = $pageContent.scrollTop();
}
if (restoreScrollTopOnBack && callback === 'beforeOut' && from === 'current' && to === 'next') {
// Delete scroll position
delete router.scrollHistory[page.route.url];
delete router.scrollHistory[routeId];
}

$pageEl.trigger(colonName, page);
Expand Down Expand Up @@ -904,6 +912,15 @@ class Router extends Framework7Class {
'Framework7: wrong or not complete browserHistory configuration, trying to guess browserHistoryRoot',
);
browserHistoryRoot = location.pathname.split('index.html')[0];
} else if (browserHistory && !browserHistoryRoot) {
if (documentUrl.startsWith('/index.html')) {
window.history.replaceState(
window.history.state,
document.title,
location.pathname.replace(/^\/index\.html/, '/') + location.search + location.hash
);
documentUrl = documentUrl.replace(/^\/index\.html/, '/');
}
}
if (!browserHistory || !browserHistoryOnLoad) {
if (!initialUrl) {
Expand All @@ -930,6 +947,17 @@ class Router extends Framework7Class {
initialUrl = documentUrl;
}
router.restoreHistory();

const initialRoute = router.findMatchingRoute(initialUrl);
const anotherViewName = initialRoute.route.viewName;
if (initialRoute && anotherViewName && app.view[anotherViewName] !== view) {
if (router.params.url) {
initialUrl = router.params.url;
} else {
console.error('Framework7: Initial page not found, using default URL (null). Please set the data-url attribute on your view element.', view);
}
}

if (router.history.indexOf(initialUrl) >= 0) {
router.history = router.history.slice(0, router.history.indexOf(initialUrl) + 1);
} else if (router.params.url === initialUrl) {
Expand All @@ -941,13 +969,22 @@ class Router extends Framework7Class {
) {
initialUrl = router.history[router.history.length - 1];
} else {
router.history = [documentUrl.split(browserHistorySeparator)[0] || '/', initialUrl];
router.history = [router.params.url || documentUrl.split(browserHistorySeparator)[0] || '/', initialUrl];
}
if (router.history.length > 1) {
historyRestored = true;
} else {
router.history = [];
}

router.propsHistory = [];
for (let i = 0; i < router.history.length; i++) {
const navigateUrl = router.history[i];
const route = router.findMatchingRoute(navigateUrl);
const anotherViewName = route.route.viewName;
if (anotherViewName && router.view !== app.views[anotherViewName]) continue;
router.propsHistory.push({ ...(route?.route?.options?.props || {}) });
}
router.saveHistory();
}

Expand Down
4 changes: 4 additions & 0 deletions src/core/shared/history.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ const History = {
if (!state) state = {};

app.views.forEach((view) => {
const pageEl = view.el;
const pageElstyle = window.getComputedStyle(pageEl);
if (pageElstyle.display === 'none') return;

const router = view.router;
let viewState = state[view.id];
if (!viewState && view.params.browserHistory) {
Expand Down
4 changes: 4 additions & 0 deletions src/react/components/view.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ const View = (props) => {
f7View.current.init(elRef.current);
if (initialPage) {
initialPage.el = f7View.current.router.currentPageEl;
const routeId = pages?.[0]?.props?.routeId;
if (routeId) initialPage.el.routeId = routeId;
if (initialRoute && initialRoute.route && initialRoute.route.keepAlive) {
initialRoute.route.keepAliveData = { pageEl: initialPage.el };
}
Expand All @@ -192,6 +194,8 @@ const View = (props) => {
f7View.current.init(elRef.current);
if (initialPage) {
initialPage.el = f7View.current.router.currentPageEl;
const routeId = pages?.[0]?.props?.routeId;
if (routeId) initialPage.el.routeId = routeId;
if (initialRoute && initialRoute.route && initialRoute.route.keepAlive) {
initialRoute.route.keepAliveData = { pageEl: initialPage.el };
}
Expand Down
2 changes: 2 additions & 0 deletions src/react/shared/components-router.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export default {
let resolved;

const childrenBefore = getChildrenArray(el);
const routeId = pageData.props.routeId
function onDidUpdate(componentRouterData) {
if (componentRouterData !== viewRouter || resolved) return;
const childrenAfter = getChildrenArray(el);
Expand All @@ -62,6 +63,7 @@ export default {

const pageEl = el.children[el.children.length - 1];
pageData.el = pageEl;
if (routeId) pageEl.routeId = routeId;

resolve(pageEl);
resolved = true;
Expand Down
11 changes: 7 additions & 4 deletions src/react/shared/get-router-initial-component.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ export const getRouterInitialComponent = (router, initialComponent) => {
let initialComponentData;
const { initialUrl } = router.getInitialUrl();
const initialRoute = router.findMatchingRoute(initialUrl);
let routeProps = {};

if (initialRoute && initialRoute.route && initialRoute.route.options) {
routeProps = initialRoute.route.options.props;
let routeProps = router.propsHistory[router.propsHistory.length - 1];
// Store route props first, if not present, fallback to route options
if (!routeProps) {
if (initialRoute && initialRoute.route && initialRoute.route.options) {
routeProps = { ...initialRoute.route.options.props };
router.propsHistory.push(routeProps);
}
}

const isMasterRoute = (route) => {
Expand Down
4 changes: 4 additions & 0 deletions src/svelte/components/view.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@
f7View.init(el);
if (initialPage) {
initialPage.el = f7View.router.currentPageEl;
const routeId = pages?.[0]?.props?.routeId;
if (routeId) initialPage.el.routeId = routeId;
if (initialRoute && initialRoute.route && initialRoute.route.keepAlive) {
initialRoute.route.keepAliveData = { pageEl: initialPage.el };
}
Expand All @@ -142,6 +144,8 @@
f7View.init(el);
if (initialPage) {
initialPage.el = f7View.router.currentPageEl;
const routeId = pages?.[0]?.props?.routeId;
if (routeId) initialPage.el.routeId = routeId;
if (initialRoute && initialRoute.route && initialRoute.route.keepAlive) {
initialRoute.route.keepAliveData = { pageEl: initialPage.el };
}
Expand Down
15 changes: 7 additions & 8 deletions src/svelte/shared/components-router.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default {
openIn(router, navigateUrl, options) {
return routerOpenIn(router, navigateUrl, options);
},
pageComponentLoader({ routerEl, component, options, resolve, reject, direction }) {
pageComponentLoader({ routerEl, component, options, resolve, reject }) {
const router = this;
const routerId = router.id;
const el = routerEl;
Expand Down Expand Up @@ -54,25 +54,24 @@ export default {
let resolved;

const childrenBefore = getChildrenArray(el);
const routeId = pageData.props.routeId
function onDidUpdate(componentRouterData) {
if (componentRouterData !== viewRouter || resolved) return;
const childrenAfter = getChildrenArray(el);
if (hasSameChildren(childrenBefore, childrenAfter)) return;
app.f7events.off('viewRouterDidUpdate', onDidUpdate);

const pageEl = el.children[direction === 'backward' ? 0 : el.children.length - 1];
const pageEl = el.children[el.children.length - 1];
pageData.el = pageEl;
if (routeId) pageEl.routeId = routeId;

resolve(pageEl);
viewRouter.setPages(viewRouter.pages);
resolved = true;
}

app.f7events.on('viewRouterDidUpdate', onDidUpdate);
if (direction === 'backward') {
viewRouter.pages.unshift(pageData);
} else {
viewRouter.pages.push(pageData);
}

viewRouter.pages.push(pageData);
viewRouter.setPages(viewRouter.pages);
},
removePage($pageEl) {
Expand Down
13 changes: 8 additions & 5 deletions src/svelte/shared/get-router-initial-component.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ export const getRouterInitialComponent = (router, initialComponent) => {
let initialComponentData;
const { initialUrl } = router.getInitialUrl();
const initialRoute = router.findMatchingRoute(initialUrl);
let routeProps = {};

if (initialRoute && initialRoute.route && initialRoute.route.options) {
routeProps = initialRoute.route.options.props;
let routeProps = router.propsHistory[router.propsHistory.length - 1];
// Store route props first, if not present, fallback to route options
if (!routeProps) {
if (initialRoute && initialRoute.route && initialRoute.route.options) {
routeProps = { ...initialRoute.route.options.props };
router.propsHistory.push(routeProps);
}
}

const isMasterRoute = (route) => {
Expand All @@ -30,8 +33,8 @@ export const getRouterInitialComponent = (router, initialComponent) => {
props: {
f7route: initialRoute,
f7router: router,
...initialRoute.params,
...routeProps,
...initialRoute.params,
},
};
}
Expand Down
4 changes: 4 additions & 0 deletions src/vue/components/view.vue
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,8 @@ export default {
f7View.init(elRef.value);
if (initialPage) {
initialPage.el = f7View.router.currentPageEl;
const routeId = pages?.value[0]?.props?.routeId;
if (routeId) initialPage.el.routeId = routeId;
if (initialRoute && initialRoute.route && initialRoute.route.keepAlive) {
initialRoute.route.keepAliveData = { pageEl: initialPage.el };
}
Expand All @@ -285,6 +287,8 @@ export default {
f7View.init(elRef.value);
if (initialPage) {
initialPage.el = f7View.router.currentPageEl;
const routeId = pages?.value[0]?.props?.routeId;
if (routeId) initialPage.el.routeId = routeId;
if (initialRoute && initialRoute.route && initialRoute.route.keepAlive) {
initialRoute.route.keepAliveData = { pageEl: initialPage.el };
}
Expand Down
2 changes: 2 additions & 0 deletions src/vue/shared/components-router.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export default {
let resolved;

const childrenBefore = getChildrenArray(el);
const routeId = pageData.props.routeId
function onDidUpdate(componentRouterData) {
if (componentRouterData !== viewRouter || resolved) return;
const childrenAfter = getChildrenArray(el);
Expand All @@ -62,6 +63,7 @@ export default {

const pageEl = el.children[el.children.length - 1];
pageData.el = pageEl;
if (routeId) pageEl.routeId = routeId;

resolve(pageEl);
resolved = true;
Expand Down
11 changes: 7 additions & 4 deletions src/vue/shared/get-router-initial-component.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ export const getRouterInitialComponent = (router, initialComponent) => {
let initialComponentData;
const { initialUrl } = router.getInitialUrl();
const initialRoute = router.findMatchingRoute(initialUrl);
let routeProps = {};

if (initialRoute && initialRoute.route && initialRoute.route.options) {
routeProps = initialRoute.route.options.props;
let routeProps = router.propsHistory[router.propsHistory.length - 1];
// Store route props first, if not present, fallback to route options
if (!routeProps) {
if (initialRoute && initialRoute.route && initialRoute.route.options) {
routeProps = { ...initialRoute.route.options.props };
router.propsHistory.push(routeProps);
}
}

const isMasterRoute = (route) => {
Expand Down