import EventType from './EventType' ; import MetaProperty from './MetaProperty' ; import ModelManager from './ModelManager' ; import { PathUtils } from './PathUtils' ; /**
 * <p>The ModelRouter listens for HTML5 History API <i>popstate</i> events and calls  PageModelManager with the model path it extracted from the URL.</p>
 *
 * <h2>Configuration</h2>
 *
 * <p>The Model Router can be configured using meta properties located in the head section of the document.</p>
 *
 * <h3>Meta properties</h3>
 * <ul>
 *     <li>cq:page_model_router - default=undefined, options=disable</li>
 *     <li>cq:page_model_route_filters - default=undefined, options=RegExp<></li>
 * </ul>
 *
 * <h3>Defaults</h3>
 * <ul>
 *     <li>The ModelRouter is enabled and uses the <i>History</i> API to extract the model path from the current content path</li>
 * </ul>
 *
 * <h3>Examples and Usages</h3>
 *
 * <h4>Disables the page model router</h4>
 * <pre>
 *     <code>e.g. &lt;meta property="cq:page_model_router" content="disable"\&gt;</code>
 * </pre>
 *
 * <h4>Filters paths from the model routing with the given patterns</h4>
 * <pre>
 *     <code>e.g. &lt;meta property="cq:page_model_route_filters" content="route/not/found,^(.*)(?:exclude/path)(.*)"\&gt;</code>
 * </pre>
 *
 *  module private export class RouterModes { /**
     * Flag that indicates that the model router should be disabled.
     */ public static readonly DISABLED = 'disabled' ; /**
     * Flag that indicates that the model router should extract the model path from the content path section of the URL.
     */ public static readonly CONTENT_PATH = 'path' ; private constructor ( ) { } } param url private return export function getModelPath ( url ? ) { const localUrl = url || window . location . pathname ; return PathUtils . sanitize ( localUrl ) ; } returns { string [ ] } private export function getRouteFilters ( ) { const routeFilters = PathUtils . getMetaPropertyValue ( MetaProperty . PAGE_MODEL_ROUTE_FILTERS ) ; return routeFilters ? routeFilters . split ( ',' ) : [ ] ; } param route returns { boolean } private export function isRouteExcluded ( route ) { const routeFilters = getRouteFilters ( ) ; for ( let i = 0 , length = routeFilters . length ; i < length ; i ++ ) { if ( new RegExp ( routeFilters [ i ] ) . test ( route ) ) { return true ; } } return false ; } returns { boolean } private export function isModelRouterEnabled ( ) { if ( ! PathUtils . isBrowser ( ) ) { return false ; } const modelRouterMetaType = PathUtils . getMetaPropertyValue ( MetaProperty . PAGE_MODEL_ROUTER ) ; return ! modelRouterMetaType || ( RouterModes . DISABLED !== modelRouterMetaType ) ; } fires param { string } path private export function dispatchRouteChanged ( path ) { ModelManager . getData ( { path } ) . then ( ( model ) => { PathUtils . dispatchGlobalCustomEvent ( EventType . PAGE_MODEL_ROUTE_CHANGED , { detail : { model } } ) ; } ) ; } fires param { string } url private export function routeModel ( url ? ) { if ( ! isModelRouterEnabled ( ) ) { return ; } const path = getModelPath ( url ) ; if ( ! path || ( '/' === path ) || isRouteExcluded ( path ) ) { return ; } dispatchRouteChanged ( path ) ; } if ( isModelRouterEnabled ( ) ) { const pushState = window . history . pushState ; const replaceState = window . history . replaceState ; window . history . pushState = ( state , title , url ) => { routeModel ( url || null ) ; return pushState . apply ( history , [ state , title , url ] ) ; } ; window . history . replaceState = ( state , title , url ) => { routeModel ( url || null ) ; return replaceState . apply ( history , [ state , title , url ] ) ; } ; window . onpopstate = ( history ) => { const currentPath = history ?. target ?. location ?. pathname ; routeModel ( currentPath || null ) ; } ; }