diff --git a/apps/sample-blog/src/app/slow/slow.component.ts b/apps/sample-blog/src/app/slow/slow.component.ts
index 2099337e3..3bfe0b227 100644
--- a/apps/sample-blog/src/app/slow/slow.component.ts
+++ b/apps/sample-blog/src/app/slow/slow.component.ts
@@ -15,7 +15,7 @@ import { first } from 'rxjs/operators';
export class SlowComponent {
isGenerated = isScullyGenerated();
- delay$ = this.http.get('http://localhost:8200/slow/4000');
+ delay$ = this.http.get('http://localhost:8200/slow/2000');
constructor(private http: HttpClient) {
this.delay$.pipe(first()).subscribe();
diff --git a/apps/sample-blog/src/app/static/static.component.html b/apps/sample-blog/src/app/static/static.component.html
index 4af243315..abaca58f0 100644
--- a/apps/sample-blog/src/app/static/static.component.html
+++ b/apps/sample-blog/src/app/static/static.component.html
@@ -1,4 +1,5 @@
-
Available routes
+
+{{ title$ | async }}
Top level routes only console.log('current route', r)),
+ map(r => r.title || ''),
+ tap(t => this.title.setTitle(t))
+ );
constructor(
private srs: ScullyRoutesService,
- private route: ActivatedRoute
+ private route: ActivatedRoute,
+ private title: Title
) {}
get routes() {
diff --git a/guess b/guess
deleted file mode 160000
index 180dcd23e..000000000
--- a/guess
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 180dcd23ecf0adbe2dcc5e84648ba9963c3e9479
diff --git a/libs/ng-lib/src/lib/idleMonitor/idle-monitor.service.ts b/libs/ng-lib/src/lib/idleMonitor/idle-monitor.service.ts
index 208745bcd..c5ab5c692 100644
--- a/libs/ng-lib/src/lib/idleMonitor/idle-monitor.service.ts
+++ b/libs/ng-lib/src/lib/idleMonitor/idle-monitor.service.ts
@@ -29,11 +29,11 @@ declare global {
}
}
-if (window) {
- window.addEventListener('AngularReady', ev => {
- console.log('appReady fired', ev);
- });
-}
+// if (window) {
+// window.addEventListener('AngularReady', ev => {
+// console.log('appReady fired', ev);
+// });
+// }
@Injectable({
providedIn: 'root'
@@ -149,8 +149,13 @@ export class IdleMonitorService {
}, 50);
return;
}
- window.dispatchEvent(this.appReady);
- this.setState('idle', true);
+ this.zone.run(() => {
+ /** run this inside the zone, and give the app 250Ms to wrap up, before scraping starts */
+ setTimeout(() => {
+ window.dispatchEvent(this.appReady);
+ this.setState('idle', true);
+ }, 250);
+ });
};
monitor();
});
@@ -172,6 +177,6 @@ export class IdleMonitorService {
}
}
-function dropEndingSlash(str: string) {
+export function dropEndingSlash(str: string) {
return str.endsWith('/') ? str.slice(0, -1) : str;
}
diff --git a/libs/ng-lib/src/lib/route-service/scully-routes.service.ts b/libs/ng-lib/src/lib/route-service/scully-routes.service.ts
index 8062d88b7..bb93e5c44 100644
--- a/libs/ng-lib/src/lib/route-service/scully-routes.service.ts
+++ b/libs/ng-lib/src/lib/route-service/scully-routes.service.ts
@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
-import { Observable, of, ReplaySubject } from 'rxjs';
+import { Observable, of, ReplaySubject, merge } from 'rxjs';
import {
catchError,
map,
@@ -8,6 +8,8 @@ import {
filter
} from 'rxjs/operators';
import { fetchHttp } from '../utils/fetchHttp';
+import { Router, NavigationEnd, NavigationStart } from '@angular/router';
+import { basePathOnly } from '../utils/basePathOnly';
export interface ScullyRoute {
route: string;
@@ -25,6 +27,9 @@ export interface ScullyRoute {
})
export class ScullyRoutesService {
private refresh = new ReplaySubject(1);
+ /**
+ * An observable with all routes, published and unpublished alike
+ */
allRoutes$: Observable = this.refresh.pipe(
switchMap(() => fetchHttp('/assets/scully-routes.json')),
catchError(() => {
@@ -38,6 +43,9 @@ export class ScullyRoutesService {
map(this.cleanDups),
shareReplay({ refCount: false, bufferSize: 1 })
);
+ /**
+ * An observable with available routes (all published routes)
+ */
available$ = this.allRoutes$.pipe(
map(list =>
list.filter(r =>
@@ -47,6 +55,9 @@ export class ScullyRoutesService {
shareReplay({ refCount: false, bufferSize: 1 })
);
+ /**
+ * an observable with all unpublished routes
+ */
unPublished$ = this.allRoutes$.pipe(
map(list =>
list.filter(r =>
@@ -56,6 +67,10 @@ export class ScullyRoutesService {
shareReplay({ refCount: false, bufferSize: 1 })
);
+ /**
+ * An observable with the top-level off all published routes.
+ * (in an urls it would be `http://www.sample.org/__thisPart__/subroutes`)
+ */
topLevel$: Observable = this.available$.pipe(
map(routes =>
routes.filter((r: ScullyRoute) => !r.route.slice(1).includes('/'))
@@ -63,36 +78,50 @@ export class ScullyRoutesService {
shareReplay({ refCount: false, bufferSize: 1 })
);
- constructor() {
+ constructor(private router: Router) {
/** kick off first cycle */
this.reload();
}
+ /**
+ * returns an observable that returns the route information for the
+ * route currently selected. subscribes to route-events to update when needed
+ */
getCurrent(): Observable {
if (!location) {
/** probably not in a browser, no current location available */
return of();
}
- const curLocation = decodeURI(location.pathname).trim();
- return this.available$.pipe(
- map(list =>
- list.find(
+ /** fire off at start, and when navigation is done. */
+ return merge(of(new NavigationEnd(0, '', '')), this.router.events).pipe(
+ filter(e => e instanceof NavigationEnd),
+ switchMap(() => this.available$),
+ map(list => {
+ const curLocation = basePathOnly(encodeURI(location.pathname).trim());
+ return list.find(
r =>
- curLocation === r.route.trim() ||
+ curLocation === basePathOnly(r.route.trim()) ||
(r.slugs &&
Array.isArray(r.slugs) &&
- r.slugs.find(slug => curLocation.endsWith(slug.trim())))
- )
- )
+ r.slugs.find(slug =>
+ curLocation.endsWith(basePathOnly(slug.trim()))
+ ))
+ );
+ })
);
}
+ /**
+ * internal, as routes can have multiple slugs, and so occur multiple times
+ * this util function collapses all slugs back into 1 route.
+ */
private cleanDups(routes: ScullyRoute[]) {
const m = new Map();
routes.forEach(r => m.set(r.sourceFile || r.route, r));
return [...m.values()];
}
+ /** an utility that will force a reload of the `scully-routes.json` file */
reload(): void {
this.refresh.next();
}
diff --git a/libs/plugins/from-data/src/lib/plugins-from-data.ts b/libs/plugins/from-data/src/lib/plugins-from-data.ts
index 3ff025d89..6f70e5ef3 100644
--- a/libs/plugins/from-data/src/lib/plugins-from-data.ts
+++ b/libs/plugins/from-data/src/lib/plugins-from-data.ts
@@ -1,12 +1,14 @@
import { routeSplit, registerPlugin, HandledRoute } from '@scullyio/scully';
+export const extraData = 'extraData';
+
/**
* This plugin replaces the parameter with a counter from 0 to the numberOfPages
* in the config.
* @param route
* @param options
*/
-export const dataRoutesPlugin = async (
+const dataRoutesPlugin = async (
route,
options
): Promise[]> => {
diff --git a/libs/scully/src/lib/systemPlugins/storeRoutes.ts b/libs/scully/src/lib/systemPlugins/storeRoutes.ts
index f185936f2..e093b2473 100644
--- a/libs/scully/src/lib/systemPlugins/storeRoutes.ts
+++ b/libs/scully/src/lib/systemPlugins/storeRoutes.ts
@@ -24,7 +24,7 @@ export async function storeRoutes(routes: HandledRoute[]) {
}
try {
const jsonResult = JSON.stringify(
- routes.map(r => ({ route: r.route || '/', ...r.data }))
+ routes.map(r => ({ route: r.route || '/', title: r['title'], ...r.data }))
);
const write = file => {
createFolderFor(file);
diff --git a/tests/cypress/integration/getcurrent.spec.js b/tests/cypress/integration/getcurrent.spec.js
new file mode 100644
index 000000000..50629ff4b
--- /dev/null
+++ b/tests/cypress/integration/getcurrent.spec.js
@@ -0,0 +1,19 @@
+///
+
+const { textSpanContainsTextSpan } = require('typescript');
+
+context('RoutesService tests', () => {
+ it('should start with toplevel', () => {
+ cy.visit('/home');
+ cy.get('main>app-static>h1').should(el =>
+ assert.isTrue(el.html() === 'Toplevel routes in application')
+ );
+ });
+
+ it('navigate to all', () => {
+ cy.get('main > app-static > a:nth-child(2)')
+ .click()
+ .get('main>app-static>h1')
+ .should(el => assert.isTrue(el.html() === 'All routes in application'));
+ });
+});
diff --git a/tests/cypress/integration/sampleBlog.spec.js b/tests/cypress/integration/sampleBlog.spec.js
index 6a1abe952..e53feeb60 100644
--- a/tests/cypress/integration/sampleBlog.spec.js
+++ b/tests/cypress/integration/sampleBlog.spec.js
@@ -1,6 +1,6 @@
///
-context('check first integration test', () => {
+context('combined integration tests', () => {
it('check if a users exist', () => {
cy.visit('/home');
cy.get('ul>li>a')
@@ -28,7 +28,7 @@ context('check first integration test', () => {
onRequest: req => {
cy.log('Call http done');
expect(true).to.equal(false);
- },
+ }
});
cy.visit('/user');
cy.wait(3000);
@@ -37,15 +37,15 @@ context('check first integration test', () => {
it('Check the list of users after navigation', () => {
cy.visit('/home');
cy.get('ul>li>a')
- .contains('/user', {timeout: 1250})
+ .contains('/user', { timeout: 1250 })
.click()
.wait(500)
.get('a')
- .contains('Leanne', {timeout: 1250})
+ .contains('Leanne', { timeout: 1250 })
.click()
.wait(5)
.get('p')
- .contains('1', {timeout: 1250});
+ .contains('1', { timeout: 1250 });
});
it('Check of transferState exist in html', () => {
@@ -77,7 +77,9 @@ context('check first integration test', () => {
});
it('check link to have target_blank in blog page 2', () => {
- cy.visit('/blog/___UNPUBLISHED___k5nhcflm_SJwD4Z0QDrIHg1PGHo2mrfLZE8sfUsPy/');
+ cy.visit(
+ '/blog/___UNPUBLISHED___k5nhcflm_SJwD4Z0QDrIHg1PGHo2mrfLZE8sfUsPy/'
+ );
cy.get('a[target]').should('have.attr', 'target', '_blank');
});
@@ -86,7 +88,7 @@ context('check first integration test', () => {
cy.visit('/slow').reload();
cy.get('app-slow>h1').contains('Scully Not Generated');
- cy.wait(4100)
+ cy.wait(2100)
.get('app-slow>h1')
.contains('Scully Generated');
});
diff --git a/tests/jest/src/__tests__/__snapshots__/home.spec.ts.snap b/tests/jest/src/__tests__/__snapshots__/home.spec.ts.snap
index c2fe1fd45..206bb26ac 100644
--- a/tests/jest/src/__tests__/__snapshots__/home.spec.ts.snap
+++ b/tests/jest/src/__tests__/__snapshots__/home.spec.ts.snap
@@ -3,7 +3,7 @@
exports[`Check list of all Check clean all list from scully 1`] = `
"
- SampleBlog
+ All routes in application
@@ -11,7 +11,7 @@ exports[`Check list of all Check clean all list from scully 1`] = `
- Scully demo blog app! rendering inside scully🏠Available routes
Top level routes onlyUnpublished routes
+ Scully demo blog app! rendering inside scully🏠All routes in application
Top level routes onlyUnpublished routes
"
diff --git a/tsconfig.json b/tsconfig.json
index a701dd95f..91eac843c 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -31,5 +31,5 @@
"angularCompilerOptions": {
"disableTypeScriptVersionCheck": true
},
- "exclude": ["node_modules", "tmp"]
+ "exclude": ["node_modules", "tmp", "dist"]
}