library-ts/browser/dom/PageHandler.ts

1285 lines
29 KiB
TypeScript

import { PageData } from "./PageData";
import { PageTransitionHandler } from "./PageTransitionHandler";
import { sleep } from "../animation/sleep";
import { EventSlot } from "../events/EventSlot";
import { ElementAttribute } from "./ElementAttribute";
import { OnClick, OnMouseDown, OnMouseEnter } from "./EventListeners";
import { LanguageCode } from "../i18n/LanguageCode";
import { Link, LinkType } from "./LinkResolver";
import { RootPathResolver } from "./RootPathResolver";
import { Loader } from "../xhttp/Loader";
import { ElementType } from "./ElementType";
import { RegExpUtility } from "../text/RegExpUtitlity";
import { AttributeValue } from "./AttributeValue";
export class FunctionHandleAnchor extends HTMLAnchorElement
{
_functionCallback:()=>void;
_assignedClickListener = false;
}
export class PageRequestEvent
{
lastPage:string;
nextPage:string;
}
export class PagesJSON
{
pages:string[];
}
export enum PageHandlerMode
{
PHP,
HTML,
ELECTRON
}
export class PageHandler
{
private _pagesPath = "_scripts/pages.json";
private _pages = new Map<string,PageData>();
private _startPage:string;
get startPage(){ return this._startPage;}
private _currentPage:string;
private _nextPage:string;
private _isLoading:boolean = false;
private _followUpPage:string = null;
private _pageRootTag = "body";
private _forceHTTPS = true;
private _pageParameters = "?no-page-token=true";
readonly onPageRequest = new EventSlot<PageRequestEvent>();
get pageRootTag(){ return this._pageRootTag; }
transitionHandler:PageTransitionHandler;
private _webAdress:string;
private _localAdressExtension:string;
private _rootPathResolver = new RootPathResolver();
get rootPathResolver(){ return this._rootPathResolver; }
private _preloadImagesFlag:boolean = true;
private _maxPreloadingDurationMS:number = 2000;
private static _localHost = "http://localhost:8080";
private static _localNetworkRegexPattern = /^(http:\/\/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}?:XXXX)/
private static _localNetworkRegex = RegExpUtility.createRegExp( this._localNetworkRegexPattern, "XXXX", 8080 + "" );
private _isHTMLMode:boolean = false;
private _fileLocation:string = "";
private _isFileMode:boolean = false;
private _pagesLoaded = false;
setPagesPath( path:string )
{
this._pagesPath = path;
}
setAdress( localExtension: string, web:string )
{
this._localAdressExtension = localExtension;
this._webAdress = web;
}
setPageRootTag( pageRootTag:string )
{
this._pageRootTag = pageRootTag;
}
get pageParameters()
{
return this._pageParameters;
}
getParameterValue( name:string )
{
let parameters = window.location.search;
let pageParameters = parameters.length > 0 ? parameters.substring( 1 ) : null;
if ( ! pageParameters )
{
return null;
}
let pairs = pageParameters.split( "&" );
for ( let p of pairs )
{
let keyValue = p.split( "=" );
if ( keyValue.length !== 2 )
{
continue;
}
if ( keyValue[ 0 ] === name )
{
return decodeURIComponent( keyValue[ 1 ] );
}
}
return null;
}
static setLocalHostPort( port:number )
{
PageHandler._localHost = "http://localhost:" + port;
PageHandler._localNetworkRegex = RegExpUtility.createRegExp( this._localNetworkRegexPattern, "XXXX", port + "" );
}
constructor( localAdressExtension:string, webAdress:string, disableForceHTTPS?:boolean, mode:PageHandlerMode = PageHandlerMode.PHP )
{
if ( disableForceHTTPS === true )
{
this._forceHTTPS = false;
}
if ( PageHandlerMode.HTML == mode || PageHandlerMode.ELECTRON == mode )
{
this._isHTMLMode = true;
}
if ( PageHandlerMode.ELECTRON == mode )
{
this.setFileLocation( localAdressExtension );
}
else
{
this.setAdress( localAdressExtension, webAdress );
}
//this._startPage = this.currentPage;
//console.log( "START PAGE:", this._startPage );
}
setFileLocation( location:string )
{
this._fileLocation = location;
this._isFileMode = true;
}
get localAdress()
{
let adress = this.trimmedLocation;
if ( adress.startsWith( PageHandler._localHost ) )
{
return PageHandler._localHost + this._localAdressExtension;
}
if ( PageHandler._localNetworkRegex.test( adress ) )
{
return PageHandler._localNetworkRegex.exec( adress )[ 1 ] + this._localAdressExtension;
}
return null;
}
get isLocalNetwork()
{
let adress = this.trimmedLocation;
// console.log( "Checking adress for localhost", adress, PageHandler._localHost, PageHandler._localNetworkRegex );
if ( adress.startsWith( PageHandler._localHost ) )
{
// console.log( "Is starting with localhost" );
return true;
}
// console.log( "Not starting with localhost" );
if ( PageHandler._localNetworkRegex.test( adress ) )
{
// console.log( "Is starting with localhost regex" );
return true;
}
// console.log( "Not starting with localhost regex" );
return false;
}
get isFileMode()
{
return this._isFileMode;
}
async initialize()
{
this._isLoading = true;
let pagesPath = this.getAbsolutePath( this._pagesPath ) + "?" + new Date().getTime() ;
//console.log( "loading pages", pagesPath );
let pages:string[] = [];
setTimeout(
()=>
{
// console.log( "PAGES_DATA", ( window as any ).PAGES_DATA );
},
3000
);
if ( ( window as any ).PAGES_DATA )
{
//console.log( "USING PAGE DATA FROM JS PAGES" );
pages = ( window as any ).PAGES_DATA as string[];
}
else
{
console.log( "LOADING PAGE DATA FROM JSON", this.isLocalNetwork, pagesPath );
let pagesData = await Loader.loadJSON<PagesJSON>( pagesPath );
pages = pagesData.pages;
}
for ( let i = 0; i < pages.length; i++ )
{
let page = pages[ i ];
let absolutePath = this.getAbsolutePath( page );
//console.log( "adding page: ", page, ">>", absolutePath );
this._pages.set( page, new PageData( this, absolutePath, page ) );
}
this._pagesLoaded = true;
this._startPage = this.currentPage;
///console.log( "loading pages", this._startPage );
this.removeFunctionHandleLink();
this.resolveRootPaths( document );
this._isLoading = false;
this._startUpdater();
if ( this._followUpPage )
{
this._loadPage( this._followUpPage );
}
return Promise.resolve();
}
private _currentLanguage:string = null;
get currentLanguage()
{
if ( ! this._currentLanguage )
{
this._currentLanguage = document.querySelector( "html" ).getAttribute( "lang" ) || "en";
}
return this._currentLanguage;
}
get languageCode()
{
return this.currentLanguage as LanguageCode;
}
resolveRootPaths( target:Element|Document )
{
let filePath = this.currentPage;
// console.log( "resolveRootPaths: FILEPATH:" + filePath );
if ( filePath === null )
{
return;
}
this._rootPathResolver.process( target, filePath );
}
private async _loadPage( page:string ):Promise<void>
{
if ( this._isLoading )
{
this._followUpPage = page;
return Promise.resolve();
}
this._dispatchPageRequest( this._currentPage, page );
this._isLoading = true;
this._followUpPage = null;
this._nextPage = page;
let next = this._nextPage;
if ( this.transitionHandler )
{
await this.transitionHandler.onTransitionOut( this );
}
let pageData = await this._getPageData( next );
if ( pageData == null )
{
console.log( "No page data found:", page, next );
}
this._currentLanguage = pageData.language;
let elementType = new ElementType( this.pageRootTag );
let pageRoot = elementType.query( document.documentElement );
pageRoot.innerHTML = pageData.pageRootInnerHTML;
this.resolveRootPaths( pageRoot );
this._scrollToY( pageData.scrollTop );
document.title = pageData.title;
document.querySelector( "html" ).setAttribute( "lang", this._currentLanguage );
this._abortPreloadingImages = false;
if ( this._preloadImagesFlag )
{
await Promise.race( [ sleep( this._maxPreloadingDurationMS ), this._preloadImages() ])
}
this._abortPreloadingImages = true;
if ( this.transitionHandler )
{
await this.transitionHandler.onTransitionIn( this );
}
this._currentPage = this._nextPage;
if ( this._followUpPage )
{
let page = this._followUpPage;
this._followUpPage = null;
await this._loadPage( page );
}
this._isLoading = false;
return Promise.resolve();
}
private _pageAliases:Map<string,string> = new Map<string,string>();
public normalizePageLink( page:string )
{
return this._normalizePageLink( page );
}
private _normalizePageLink( page:string )
{
if ( page === "" )
{
return this._isHTMLMode ? "index.html" : "index.php";
}
if ( this._pages.has( page ) )
{
return page;
}
if ( this._pageAliases.has( page ) )
{
page = this._pageAliases.get( page );
}
if ( this._pages.has( page ) )
{
return page;
}
if ( ! this._isHTMLMode && page.endsWith( ".html" ) )
{
let phpPage = page.replace( /\.html$/, ".php" );
if ( this._pages.has( phpPage ) )
{
return phpPage;
}
}
let ending = this._isHTMLMode ? ".html" : ".php";
if ( ! page.endsWith( ending ) )
{
let indexPage = page + ending;
if ( this._pages.has( indexPage ) )
{
return indexPage;
}
let indexDirectoryPage = page.replace( /\/$/, "" ) + "/index" + ending;
if ( this._pages.has( indexDirectoryPage ) )
{
return indexDirectoryPage;
}
}
if ( PageHandler.isHiddenPage() )
{
return null;
}
// console.log( "Page not found:", page, [...this._pages.keys()].join( ", " ) );
return null;
}
static isHiddenPage()
{
let value = PageHandler.pageInfoAttribute.from( document.body );
return value === "hidden";
}
static readonly pageInfoAttribute = new ElementAttribute( "page-info" );
getFilteredPages( filter:RegExp )
{
let pages:string[] = [];
this._pages.forEach(
( v, k )=>
{
if ( filter.test( k ) )
{
pages.push( k );
}
}
);
return pages;
}
async getPage( page:string ):Promise<PageData>
{
console.log( "getPage:", page );
return this._getPageData( page );
}
private async _getPageData( page:string ):Promise<PageData>
{
if ( ! this._pages.has( page ) )
{
return Promise.resolve( null );
}
let data = this._pages.get( page );
if ( ! data.ready )
{
await data.load();
}
return Promise.resolve( data );
}
private _abortPreloadingImages = false;
private async _preloadImages():Promise<void>
{
let images = ElementType.image.queryAll( document.body );
let backgroundImages = document.body.querySelectorAll( `[style*="background-image"]` );
//console.log( "preloading images", `found: <img> ${images.length}, [style*="background-image"] ${backgroundImages.length}`, )
for ( let i = 0; i < images.length && ! this._abortPreloadingImages; i++ )
{
let path = images[ i ].getAttribute( "src" );
if ( path && path !== "" )
{
await this._preloadImage( path );
}
}
for ( let i = 0; i < backgroundImages.length && ! this._abortPreloadingImages; i++ )
{
let htmlElement = backgroundImages[ i ] as HTMLElement;
let backgroundImageValue = htmlElement.style.backgroundImage;
var regexResult = backgroundImageValue.match(/url\(["']?([^"']*)["']?\)/);
if ( regexResult && regexResult[ 1 ] )
{
let path = regexResult[ 1 ];
await this._preloadImage( path );
}
}
return Promise.resolve();
}
private async _preloadImage( path:string ):Promise<void>
{
try
{
//console.log( "preloading image", path );
await Loader.loadImage( path );
}
catch ( e )
{
}
return Promise.resolve();
}
getAbsolutePath( path:string )
{
if ( this.isFileMode )
{
return this._fileLocation + "/" + path
}
else if ( this.isLocalNetwork )
{
return this.localAdress + "/" + path
}
else
{
return this._webAdress + "/" + path;
}
}
getRootPath( absolutePath:string )
{
let pagePath:string = null;
if ( this.isFileMode )
{
pagePath = absolutePath.substring( this._fileLocation.length );
}
else if ( this.isLocalNetwork )
{
pagePath = absolutePath.substring( this.localAdress.length );
}
else
{
if ( absolutePath.startsWith( "http:" ) && this._forceHTTPS )
{
absolutePath = "https:" + absolutePath.substring( "http:".length );
}
pagePath = absolutePath.substring( this._webAdress.length );
}
if ( pagePath.startsWith( "/" ) )
{
pagePath = pagePath.substring( 1 );
}
return pagePath;
}
get trimmedLocation()
{
let trimmedLocation = window.location.href;
let hash = /#.*$/.exec( trimmedLocation );
if ( hash )
{
trimmedLocation = trimmedLocation.replace( /#.*$/, "" );
}
let search = /\?.*$/.exec( trimmedLocation );
if ( search )
{
trimmedLocation = trimmedLocation.replace( /\?.*$/, "" );
}
return trimmedLocation;
}
get hasFunctionHandleLink()
{
let trimmedLocation = window.location.href;
let hash = /#\[.*\]$/.exec( trimmedLocation );
if ( hash )
{
return true;
}
return false;
}
removeFunctionHandleLink()
{
if ( this.hasFunctionHandleLink )
{
window.location.href = this.trimmedLocation;
}
}
get currentPage()
{
let location = this.getRootPath( this.trimmedLocation );
let normalized = this._normalizePageLink( location );
return normalized;
}
private _startUpdater()
{
if ( 'scrollRestoration' in window.history )
{
window.history.scrollRestoration = 'manual';
}
let page = this.currentPage;
this._currentPage = page;
this._nextPage = page;
let updater = () =>
{
requestAnimationFrame(
()=>
{
this._update();
updater();
}
);
}
updater();
}
get currentScrollTop()
{
var value= typeof window.pageYOffset !== undefined ? window.pageYOffset:
document.documentElement.scrollTop? document.documentElement.scrollTop:
document.body.scrollTop? document.body.scrollTop:0;
return value;
}
replaceLinks()
{
let anchors = ElementType.anchor.queryAll( document.body );
for ( let a of anchors )
{
this._processLink( a as HTMLAnchorElement );
}
}
private _dispatchPageRequest( lastPage:string, nextPage:string )
{
let pageRequestEvent = new PageRequestEvent();
pageRequestEvent.lastPage = lastPage;
pageRequestEvent.nextPage = nextPage;
this.onPageRequest.dispatch( pageRequestEvent );
}
createAbsoluteLink( link:Link )
{
let clone = link.clone();
if ( LinkType.ABSOLUTE === link.type )
{
return clone;
}
clone.type = LinkType.ABSOLUTE;
if ( LinkType.ROOT === link.type )
{
clone.path = link.path.replace( "::", window.location.host );
}
if ( LinkType.RELATIVE === link.type )
{
clone.path = new URL( link.path, window.location.href ).href;
}
return clone;
}
createRootLink( link:Link )
{
if ( link.type === LinkType.ROOT )
{
return link.clone();
}
let absoluteLink = this.createAbsoluteLink( link );
let clone = absoluteLink.clone();
clone.type = LinkType.ROOT;
clone.path = RootPathResolver.rootToken + ( new URL( absoluteLink.path ).pathname );
return clone;
}
getRealPagePath( page:string )
{
page = page.replace( /^\//, "" );
if ( this._pages.has( page ) )
{
return page;
}
let phpExtensionPage = page + ".php";
if ( this._pages.has( phpExtensionPage ) )
{
return page;
}
let directoryWithIndexPage = page + "/index.php";
if ( this._pages.get( directoryWithIndexPage ) )
{
return directoryWithIndexPage;
}
console.warn( "Page not found:", page );
return null;
}
createRelativeLink( link:Link )
{
if ( link.type === LinkType.RELATIVE )
{
return link.clone();
}
let clone = this.createRootLink( link ).clone();
clone.type = LinkType.RELATIVE;
let replaced = link.path.replace( RootPathResolver.rootToken, "" );
let file = RegExpUtility.fileNameOrLastPath( replaced );
let pathDirectory = RegExpUtility.parentPath( this._normalizePageLink( replaced ) );
let currentDirectory = this.currentPath;
let isDirectoryWithoutSlash = false;
let directoryPrefix = "";
if ( ! window.location.pathname.endsWith( "/" ) )
{
let windowPath = window.location.pathname.replace( /^\//, "" );
let windowWithoutSlashPath = windowPath + "/index.php";
let normalizedPath = this._normalizePageLink( windowPath );
isDirectoryWithoutSlash = normalizedPath === windowWithoutSlashPath;
console.log( "CREATED RELATIVE INFO", windowPath, normalizedPath, isDirectoryWithoutSlash );
if ( isDirectoryWithoutSlash )
{
directoryPrefix = RegExpUtility.fileNameOrLastPath( windowPath );
}
}
let path = RegExpUtility.createRelativeDirectoryPath( currentDirectory, pathDirectory );
if ( path != "" && ! path.endsWith( "/" ) )
{
path += "/";
}
path += file;
if ( isDirectoryWithoutSlash )
{
path = directoryPrefix + "/" + path;
}
console.log(
"CREATED RELATIVE LINK:", link.path,
">> from ", currentDirectory, isDirectoryWithoutSlash, "to", pathDirectory, ">>",
path );
clone.path = path;
return clone;
}
convertLink( link:Link, type:LinkType )
{
if ( link.type === type )
{
return link.clone();
}
if ( LinkType.ABSOLUTE == type )
{
return this.createAbsoluteLink( link );
}
if ( LinkType.ROOT == type )
{
return this.createRootLink( link );
}
if ( LinkType.RELATIVE == type )
{
return this.createRelativeLink( link );
}
return null;
}
setPage( href:string, loadPage:boolean = true )
{
let normalizedPath:string = null;
if ( RootPathResolver.isRootPath( href ) )
{
let resolvedRootPath = RootPathResolver.clearRootPath( href );
normalizedPath = this._normalizePageLink( resolvedRootPath );
this._pages.get( normalizedPath ).scrollTop = 0;
console.log( "LOADING ROOT ADRESS", { href, resolvedRootPath, normalizedPath } );
let sourceDirectory = this.currentPath;
let targetDirectory = RegExpUtility.parentPath( normalizedPath );
let relativePath = RegExpUtility.createRelativeDirectoryPath( sourceDirectory, targetDirectory );
let targetFile = RegExpUtility.fileNameOrLastPath( normalizedPath );
let historyAdress = "." + RegExpUtility.join( relativePath, targetFile );
let historyAdressShort = historyAdress.replace( /\/?index\.php$/, "" );
historyAdressShort = historyAdressShort.replace( /\.php$/, "" );
console.log( "PUSHING STATE", historyAdress, historyAdressShort );
history.pushState( { historyAdressShort }, "", historyAdressShort );
if ( ! loadPage )
{
this._nextPage = historyAdressShort;
this._followUpPage = null;
}
}
else
{
let pageAdress = this.resolveRelativeLink( href );
normalizedPath = this._normalizePageLink( pageAdress );
console.log( "LOADING RELATIVE ADRESS", { href, pageAdress, normalizedPath } );
this._pages.get( normalizedPath ).scrollTop = 0;
history.pushState( { href }, "", href );
if ( ! loadPage )
{
this._nextPage = href;
this._followUpPage = null;
}
}
}
static pageHandlerLink = new ElementAttribute( "page-handler-link" );
makePageHandleLink( a:HTMLAnchorElement )
{
let originalHref = ElementAttribute.href.from( a, "" );
if ( originalHref.startsWith( "https://" ) || originalHref.startsWith( "https://" ) )
{
AttributeValue.target_blank.set( a );
return;
}
else
{
AttributeValue.target_blank.removeFrom( a );
}
if ( PageHandler.pageHandlerLink.in( a ) )
{
return;
}
PageHandler.pageHandlerLink.to( a );
let pageHandlingAttribute = "data-page-handling";
a.addEventListener(
"mousedown",
( e:MouseEvent )=>
{
let hasRequest = e.button === 0;
a.setAttribute( pageHandlingAttribute, hasRequest + "" );
}
);
a.addEventListener(
"click",
( e:MouseEvent)=>
{
let href = a.getAttribute( "href" );
let hasRequest = a.getAttribute( pageHandlingAttribute ) === "true";
if ( hasRequest )
{
a.removeAttribute( "href" );
/*
let pageAdress = this.resolveRelativeLink( href );
pageAdress = this._normalizePageLink( pageAdress );
console.log( "href", `"${href}"`, "pageAdress", `"${pageAdress}"` );
this._pages.get( pageAdress ).scrollTop = 0;
history.pushState( { href }, "", href );
*/
this.setPage( href );
e.preventDefault();
e.stopImmediatePropagation();
e.stopPropagation();
setTimeout(
()=>
{
a.setAttribute( "href", href );
},
200
)
}
}
)
}
static isFunctionHandleLink( link:string )
{
return link.startsWith( "#[" ) && link.endsWith( "]" );
}
static makeFunctionHandleLink( a:HTMLAnchorElement )
{
let element = a as FunctionHandleAnchor;
if ( element._assignedClickListener )
{
return;
}
element._assignedClickListener = true;
let hrefValue = ElementAttribute.href.from( a );
OnMouseDown.add( a, ( e:MouseEvent )=>
{
ElementAttribute.href.removeFrom( a );
}
);
OnMouseEnter.add( a, ( e:MouseEvent )=>
{
ElementAttribute.href.to( a, hrefValue );
}
);
/*
OnContextMenu.add( a, ( e:MouseEvent )=>
{
e.preventDefault();
e.stopImmediatePropagation();
e.stopPropagation();
}
);
*/
OnClick.add( a, ( e:MouseEvent)=>
{
console.log( "FUNCTION HANDLE CLICK", e );
e.preventDefault();
e.stopImmediatePropagation();
e.stopPropagation();
if ( element._functionCallback )
{
element._functionCallback();
}
setTimeout(
()=>
{
ElementAttribute.href.to( a, hrefValue );
},
200
)
}
)
}
static setFunctionHandleLink( e:Element, name:string, callback:()=>void )
{
let a = e as HTMLAnchorElement;
this.setFunctionHandleName( a, name );
this.setFunctionHandleCallback( a, callback );
this.makeFunctionHandleLink( a );
}
static setFunctionHandleName( a:HTMLAnchorElement, name:string )
{
ElementAttribute.href.to( a, `#[ ${name} ]`);
}
static setFunctionHandleCallback( a:HTMLAnchorElement, callback:()=>void )
{
let handle = a as FunctionHandleAnchor;
handle._functionCallback = callback;
}
private _processLink( a:HTMLAnchorElement )
{
let hrefValue = ElementAttribute.href.from( a );
if ( ! hrefValue )
{
return;
}
if ( hrefValue.startsWith( "http" ) || hrefValue.startsWith( "mailto" ) )
{
return;
}
if ( hrefValue.startsWith( "#" ) )
{
return;
}
if ( PageHandler.isFunctionHandleLink( hrefValue ) )
{
PageHandler.makeFunctionHandleLink( a );
return;
}
if ( AttributeValue.target_blank.in( a ) )
{
console.log( "Not processing blank link:", ElementAttribute.href.from( a ), a );
return;
}
else
{
console.log( "Processing blank link:", ElementAttribute.href.from( a ), a );
}
this.makePageHandleLink( a );
}
private get currentPath():string
{
let relativePagePath = this.getRootPath( this.trimmedLocation );
let currentPath = this._normalizePageLink( relativePagePath );
if ( currentPath.endsWith( ".html" ) || currentPath.endsWith( ".php" ) )
{
let end = currentPath.lastIndexOf( "/" );
if ( end === -1 )
{
console.log( "No slash in path", currentPath );
return "";
}
currentPath = currentPath.substring( 0, end );
}
if ( currentPath.startsWith( "/" ) )
{
currentPath = currentPath.substring( 1 );
}
return currentPath;
}
private resolveRelativeLink( link:string )
{
let currentPath = this.currentPath;
if ( ! window.location.pathname.endsWith( "/" ) )
{
let windowPath = window.location.pathname.replace( /^\//, "" );
let windowExtendedPath = windowPath + "/index.php";
let normalizedPath = this._normalizePageLink( windowPath );
if ( normalizedPath === windowExtendedPath )
{
currentPath = RegExpUtility.parentPath( currentPath );
console.log( "CREATED SHORTER PATH:", this.currentPath, ">>", currentPath );
}
else
{
console.log( "CREATED PATH IS OK:", { windowPath, windowExtendedPath, normalizedPath, currentPath } );
}
}
let pathFragments = currentPath === "" ? [] : currentPath.split( "/" );
let linkPathFragments = link.split( "/" );
for ( let i = 0; i < linkPathFragments.length; i++ )
{
if ( linkPathFragments[ i ] === ".." )
{
pathFragments.pop();
}
else
{
pathFragments.push( linkPathFragments[ i ] );
}
}
let resolvedPath = pathFragments.join( "/" );
console.log( "resolving: ", this.currentPath, link, ">>", resolvedPath );
return resolvedPath;
}
setPageWithoutLoading( rootPath:string )
{
//this._nextPage = page;
//this._followUpPage = page;
//this.loadPage( page );
rootPath = rootPath.replace( /\.php$/, "" );
let page = "::/" + rootPath;
let relativeLink = this.createRelativeLink( Link.Root( page ) );
let relative = relativeLink.path;
this._nextPage = relativeLink.path;
console.log( "setPageWithoutLoading", { relative, page, rootPath } );
this.setPage( relative, false );
}
getRootPathNextPage()
{
let link = Link.Relative( this._nextPage );
let abs = this.createRootLink( link );
abs.path = abs.path.replace( /^\:\:\/\//, "" );
//console.log( link.path, abs.path );
return this._normalizePageLink( abs.path );
}
private _update()
{
if ( this._isLoading )
{
return;
}
let location = this.getRootPath( this.trimmedLocation );
location = this._normalizePageLink( location );
let rootPathNextPage = this.getRootPathNextPage();
if ( rootPathNextPage !== location && this._nextPage !== location )
{
console.log(
{
current: location,
next: this._nextPage,
normalizedNext: rootPathNextPage
}
);
this._loadPage( location );
}
else
{
let pageData = this._pages.get( this._currentPage );
if ( pageData )
{
pageData.scrollTop = this.currentScrollTop;
}
else
{
if ( ! PageHandler.isHiddenPage() )
{
console.log( this._currentPage, this.currentPage, "NO PAGE DATA" );
}
}
}
}
private _scrollToY( y:number )
{
document.documentElement.scrollTop = y;
document.body.scrollTop = y;
}
}