diff --git a/package-lock.json b/package-lock.json index 8f56a693..ce22ca81 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,8 +22,8 @@ "@angular/router": "18.0.0", "@angular/service-worker": "18.0.0", "@mapbox/rehype-prism": "^0.5.0", - "@ngx-loading-bar/core": "^5.1.2", - "@ngx-loading-bar/http-client": "^5.1.2", + "@ngx-loading-bar/core": "^6.0.2", + "@ngx-loading-bar/http-client": "^6.0.2", "@stackblitz/sdk": "^1.5.3", "@swimlane/docspa-core": "^6.0.0", "@swimlane/docspa-remark-preset": "^6.0.0", @@ -7187,33 +7187,28 @@ } }, "node_modules/@ngx-loading-bar/core": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@ngx-loading-bar/core/-/core-5.1.2.tgz", - "integrity": "sha512-zyD96OQpoB+0wcdCCNOmTwPMYAi6Ukp0BqnCyusN2jOsUNbPQur2GsvKAFH3TbomJdgrO0TJ4TeT1idumx/4Gw==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@ngx-loading-bar/core/-/core-6.0.2.tgz", + "integrity": "sha512-8r+OQEYXwvU+2ZXK6CY3Guh2yJuG8pQ2XNryHVbPZB2Ub3VmzhGWqjxXAQgxmsi+GxrD4m+nGmGZPeOrNH1ztA==", "dependencies": { - "tslib": ">=1.7.1" + "tslib": "^2.0.0" }, "peerDependencies": { - "@angular/common": ">=9.0.0", - "rxjs": ">=6.3.0" + "@angular/common": ">=13.0.0", + "rxjs": "^6.5.3 || ^7.0.0" } }, "node_modules/@ngx-loading-bar/http-client": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@ngx-loading-bar/http-client/-/http-client-5.1.2.tgz", - "integrity": "sha512-ebzgA8YA3CvJ8JKWQ6jymaS1a6P0pc9wYbwQKjmNwxWBcEKBdL89Ne+v1Y/08/rAZAsVH0If4dpmZPZU9K+10g==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@ngx-loading-bar/http-client/-/http-client-6.0.2.tgz", + "integrity": "sha512-wMzyg9YBvHlOqYMQK82j7fnF6GlXb1RNg/rjvl34uq3+xsqic9vUhEziEDlVEKvpbnXh5yMd05Aj7J4GwRaFcw==", "dependencies": { - "tslib": "^1.10.0" + "tslib": "^2.0.0" }, "peerDependencies": { - "@ngx-loading-bar/core": "5.1.2" + "@ngx-loading-bar/core": "6.0.2" } }, - "node_modules/@ngx-loading-bar/http-client/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -34470,26 +34465,19 @@ "dev": true }, "@ngx-loading-bar/core": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@ngx-loading-bar/core/-/core-5.1.2.tgz", - "integrity": "sha512-zyD96OQpoB+0wcdCCNOmTwPMYAi6Ukp0BqnCyusN2jOsUNbPQur2GsvKAFH3TbomJdgrO0TJ4TeT1idumx/4Gw==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@ngx-loading-bar/core/-/core-6.0.2.tgz", + "integrity": "sha512-8r+OQEYXwvU+2ZXK6CY3Guh2yJuG8pQ2XNryHVbPZB2Ub3VmzhGWqjxXAQgxmsi+GxrD4m+nGmGZPeOrNH1ztA==", "requires": { - "tslib": ">=1.7.1" + "tslib": "^2.0.0" } }, "@ngx-loading-bar/http-client": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@ngx-loading-bar/http-client/-/http-client-5.1.2.tgz", - "integrity": "sha512-ebzgA8YA3CvJ8JKWQ6jymaS1a6P0pc9wYbwQKjmNwxWBcEKBdL89Ne+v1Y/08/rAZAsVH0If4dpmZPZU9K+10g==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@ngx-loading-bar/http-client/-/http-client-6.0.2.tgz", + "integrity": "sha512-wMzyg9YBvHlOqYMQK82j7fnF6GlXb1RNg/rjvl34uq3+xsqic9vUhEziEDlVEKvpbnXh5yMd05Aj7J4GwRaFcw==", "requires": { - "tslib": "^1.10.0" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - } + "tslib": "^2.0.0" } }, "@nodelib/fs.scandir": { diff --git a/package.json b/package.json index ef0d6baf..542914d1 100644 --- a/package.json +++ b/package.json @@ -65,8 +65,8 @@ "@angular/router": "18.0.0", "@angular/service-worker": "18.0.0", "@mapbox/rehype-prism": "^0.5.0", - "@ngx-loading-bar/core": "^5.1.2", - "@ngx-loading-bar/http-client": "^5.1.2", + "@ngx-loading-bar/core": "^6.0.2", + "@ngx-loading-bar/http-client": "^6.0.2", "@stackblitz/sdk": "^1.5.3", "@swimlane/docspa-core": "^6.0.0", "@swimlane/docspa-remark-preset": "^6.0.0", @@ -78,7 +78,7 @@ "hast-util-to-dom": "^2.0.6", "intersection-observer": "^0.12.0", "lunr": "^2.3.9", - "ngx-logger": "^5.0.11", + "ngx-logger": "5.0.12", "normalize-path": "^3.0.0", "path": "^0.12.7", "path-browserify": "^1.0.1", diff --git a/projects/swimlane/docspa-core/src/lib/docspa-core.module.ts b/projects/swimlane/docspa-core/src/lib/docspa-core.module.ts index 56448102..6dec6a99 100644 --- a/projects/swimlane/docspa-core/src/lib/docspa-core.module.ts +++ b/projects/swimlane/docspa-core/src/lib/docspa-core.module.ts @@ -1,66 +1,69 @@ -import { NgModule, ModuleWithProviders } from '@angular/core'; -import { BrowserModule } from '@angular/platform-browser'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { FormsModule } from '@angular/forms'; -import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; -import { RouterModule } from '@angular/router'; - -import { LoggerModule } from 'ngx-logger'; +import { NgModule, ModuleWithProviders } from "@angular/core"; +import { BrowserModule } from "@angular/platform-browser"; +import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; +import { FormsModule } from "@angular/forms"; +import { RouterModule } from "@angular/router"; +import { + provideHttpClient, + withInterceptorsFromDi, + HTTP_INTERCEPTORS, +} from "@angular/common/http"; +// import { LoggerModule } from "ngx-logger"; // Internal -import { MarkdownElementsModule } from './modules/markdown-elements/markdown-elements.module'; -import { MarkdownModule } from './modules/markdown/markdown.module'; +import { MarkdownElementsModule } from "./modules/markdown-elements/markdown-elements.module"; +import { MarkdownModule } from "./modules/markdown/markdown.module"; -import { SettingsService } from './services/settings.service'; -import { FetchService } from './services/fetch.service'; -import { RouterService } from './services/router.service'; -import { CacheInterceptor } from './services/cache.interceptor'; -import { HooksService } from './services/hooks.service'; -import { SectionScrollSpyDirective } from './directives/section-spy.directive'; -import { ListCollapseDirective } from './directives/list-collapse.directive'; +import { SettingsService } from "./services/settings.service"; +import { FetchService } from "./services/fetch.service"; +import { RouterService } from "./services/router.service"; +import { CacheInterceptor } from "./services/cache.interceptor"; +import { HooksService } from "./services/hooks.service"; +import { SectionScrollSpyDirective } from "./directives/section-spy.directive"; +import { ListCollapseDirective } from "./directives/list-collapse.directive"; -import { DocSPACoreComponent } from './docspa-core.component'; -import { SafeHtmlPipe } from './pipes/safe-html.pipe'; +import { DocSPACoreComponent } from "./docspa-core.component"; +import { PipesModule } from "./pipes"; -import { DOCSPA_CONFIG_TOKEN, DOCSPA_ENVIRONMENT } from './docspa-core.tokens'; +import { DOCSPA_CONFIG_TOKEN, DOCSPA_ENVIRONMENT } from "./docspa-core.tokens"; @NgModule({ imports: [ BrowserModule, FormsModule, - HttpClientModule, BrowserAnimationsModule, MarkdownModule, - LoggerModule, + PipesModule, + // LoggerModule, MarkdownElementsModule, - RouterModule + RouterModule, ], declarations: [ DocSPACoreComponent, - SafeHtmlPipe, SectionScrollSpyDirective, - ListCollapseDirective - ], - exports: [ - DocSPACoreComponent, - SafeHtmlPipe, + ListCollapseDirective, ], + exports: [DocSPACoreComponent], providers: [ SettingsService, FetchService, RouterService, HooksService, - { provide: HTTP_INTERCEPTORS, useClass: CacheInterceptor, multi: true } - ] + provideHttpClient(withInterceptorsFromDi()), + { provide: HTTP_INTERCEPTORS, useClass: CacheInterceptor, multi: true }, + ], }) export class DocspaCoreModule { - static forRoot(config: any = {}, environment: any = {}): ModuleWithProviders { + static forRoot( + config: any = {}, + environment: any = {} + ): ModuleWithProviders { return { ngModule: DocspaCoreModule, providers: [ { provide: DOCSPA_ENVIRONMENT, useValue: environment }, - { provide: DOCSPA_CONFIG_TOKEN, useValue: config } - ] + { provide: DOCSPA_CONFIG_TOKEN, useValue: config }, + ], }; } diff --git a/projects/swimlane/docspa-core/src/lib/modules/markdown/markdown.service.ts b/projects/swimlane/docspa-core/src/lib/modules/markdown/markdown.service.ts index 6821ed42..78f0d4d9 100644 --- a/projects/swimlane/docspa-core/src/lib/modules/markdown/markdown.service.ts +++ b/projects/swimlane/docspa-core/src/lib/modules/markdown/markdown.service.ts @@ -1,45 +1,53 @@ -import { Injectable, InjectionToken, Inject, Optional } from '@angular/core'; - -import { NGXLogger } from 'ngx-logger'; - -import unified from 'unified'; -import markdown from 'remark-parse'; -import remark2rehype from 'remark-rehype'; -import rehypeStringify from 'rehype-stringify'; -import raw from 'rehype-raw'; -import frontmatter from 'remark-frontmatter'; -import slug from 'remark-slug'; -import sectionize from 'remark-sectionize'; -import { getTitle } from '@swimlane/docspa-remark-preset'; -import toString from 'mdast-util-to-string'; -import { resolve } from 'url'; -import visit from 'unist-util-visit'; -import strip from 'remark-strip-html'; - -import type { VFileCompatible } from 'vfile'; -import type * as mdast from 'mdast'; - -import { tocPlugin } from './plugins/toc'; -import { removeNodesPlugin } from './plugins/remove'; -import { sectionPlugin } from './plugins/sections'; - -import { RouterService } from '../../services/router.service'; -import { LocationService } from '../../services/location.service'; -import { HooksService } from '../../services/hooks.service'; - -import { links, images } from '../../shared/links'; -import lazyInitialize from '../../shared/lazy-init'; -import { VFile, isVfile, Preset, TOCOptions, TOCData, SectionData } from '../../shared/vfile'; - -import type { Link } from '../../shared/ast'; - -export const MARKDOWN_CONFIG_TOKEN = new InjectionToken( 'forRoot() configuration.' ); +import { Injectable, InjectionToken, Inject, Optional } from "@angular/core"; + +// import { NGXLogger } from 'ngx-logger'; + +import unified from "unified"; +import markdown from "remark-parse"; +import remark2rehype from "remark-rehype"; +import rehypeStringify from "rehype-stringify"; +import raw from "rehype-raw"; +import frontmatter from "remark-frontmatter"; +import slug from "remark-slug"; +import sectionize from "remark-sectionize"; +import { getTitle } from "@swimlane/docspa-remark-preset"; +import toString from "mdast-util-to-string"; +import { resolve } from "url"; +import visit from "unist-util-visit"; +import strip from "remark-strip-html"; + +import type { VFileCompatible } from "vfile"; +import type * as mdast from "mdast"; + +import { tocPlugin } from "./plugins/toc"; +import { removeNodesPlugin } from "./plugins/remove"; +import { sectionPlugin } from "./plugins/sections"; + +import { RouterService } from "../../services/router.service"; +import { LocationService } from "../../services/location.service"; +import { HooksService } from "../../services/hooks.service"; + +import { links, images } from "../../shared/links"; +import lazyInitialize from "../../shared/lazy-init"; +import { + VFile, + isVfile, + Preset, + TOCOptions, + TOCData, + SectionData, +} from "../../shared/vfile"; + +import type { Link } from "../../shared/ast"; + +export const MARKDOWN_CONFIG_TOKEN = new InjectionToken( + "forRoot() configuration." +); @Injectable({ - providedIn: 'root' + providedIn: "root", }) export class MarkdownService { - /** * Processor for converting md to html */ @@ -110,7 +118,7 @@ export class MarkdownService { constructor( private locationService: LocationService, - private logger: NGXLogger, + // private logger: any, private hooks: HooksService, private routerService: RouterService, @Optional() @Inject(MARKDOWN_CONFIG_TOKEN) private config: Preset @@ -119,8 +127,8 @@ export class MarkdownService { this.config.plugins = this.config.plugins || []; if (this.config.reporter) { - this.hooks.afterEach.tap('logging', (page: any) => { - this.logger.info(this.config.reporter(page)); + this.hooks.afterEach.tap("logging", (page: any) => { + // this.logger.info(this.config.reporter(page)); }); } } @@ -144,13 +152,13 @@ export class MarkdownService { ...(file.data?.tocOptions || {}), ...options, }; - const err = await this.tocProcessor.process(file) as VFile; + const err = (await this.tocProcessor.process(file)) as VFile; return err || file; } async processLinks(doc: VFileCompatible) { const file = VFile(doc) as VFile; - const err = await this.linksProcessor.process(file) as VFile; + const err = (await this.linksProcessor.process(file)) as VFile; return err || file; } @@ -158,15 +166,18 @@ export class MarkdownService { * Get Sections */ async getSections(doc: VFileCompatible): Promise { - const file = isVfile(doc) ? doc : VFile(String(doc)) as VFile; + const file = isVfile(doc) ? doc : (VFile(String(doc)) as VFile); const tree = this.sectionProcessor.parse(file); await this.sectionProcessor.run(tree, file); - file.data.title = (file.data.matter ? file.data.matter.title : false) || file.data.title || file.path; + file.data.title = + (file.data.matter ? file.data.matter.title : false) || + file.data.title || + file.path; return file.data?.sections || []; } async getTocLinks(doc: VFileCompatible): Promise { - const file = isVfile(doc) ? doc : VFile(String(doc)) as VFile; + const file = isVfile(doc) ? doc : (VFile(String(doc)) as VFile); file.data = file.data || {}; await this.processLinks(file); return file.data.tocSearch; @@ -176,23 +187,34 @@ export class MarkdownService { private linkPlugin = () => { return (tree: mdast.Root, file: VFile) => { file.data = file.data || {}; - file.data.tocSearch = []; // TODO: rename - return visit(tree, 'link', (node: Link, index: number, parent: mdast.Parent) => { - file.data.tocSearch.push(this.convertToTocData(file, node, parent)); - return true; - }); + file.data.tocSearch = []; // TODO: rename + return visit( + tree, + "link", + (node: Link, index: number, parent: mdast.Parent) => { + file.data.tocSearch.push(this.convertToTocData(file, node, parent)); + return true; + } + ); }; - } + }; - private convertToTocData(file: VFile, node: Link, _parent?: mdast.Parent): TOCData { + private convertToTocData( + file: VFile, + node: Link, + _parent?: mdast.Parent + ): TOCData { const content = toString(node); - const name = (file.data.matter ? file.data.matter.title : false) || file.data.title || file.path; + const name = + (file.data.matter ? file.data.matter.title : false) || + file.data.title || + file.path; let { url } = node; - let link: string | string[] = ''; - let fragment = ''; + let link: string | string[] = ""; + let fragment = ""; - if (node.data && node.data.hName === 'md-link') { + if (node.data && node.data.hName === "md-link") { // resolve path relative to source document url = resolve(node.data.hProperties.source, url); link = node.data.hProperties.link as string; @@ -200,12 +222,12 @@ export class MarkdownService { link = this.locationService.prepareLink(link, this.routerService.root); } else { - [link = '', fragment] = url.split('#'); + [link = "", fragment] = url.split("#"); } // Hack to preserve trailing slash - if (typeof link === 'string' && link.length > 1 && link.endsWith('/')) { - link = [link, '']; + if (typeof link === "string" && link.length > 1 && link.endsWith("/")) { + link = [link, ""]; } return { @@ -213,8 +235,8 @@ export class MarkdownService { url, content, link, - fragment: fragment ? fragment.replace(/^#/, '') : undefined, - depth: node.depth as number + fragment: fragment ? fragment.replace(/^#/, "") : undefined, + depth: node.depth as number, }; } } diff --git a/projects/swimlane/docspa-core/src/lib/pipes/index.ts b/projects/swimlane/docspa-core/src/lib/pipes/index.ts new file mode 100644 index 00000000..973a4b96 --- /dev/null +++ b/projects/swimlane/docspa-core/src/lib/pipes/index.ts @@ -0,0 +1,8 @@ +import { SafeHtmlPipe } from "./safe-html.pipe"; +import { NgModule } from "@angular/core"; + +@NgModule({ + declarations: [SafeHtmlPipe], + exports: [SafeHtmlPipe], +}) +export class PipesModule {} diff --git a/projects/swimlane/docspa-core/src/lib/services/router.service.ts b/projects/swimlane/docspa-core/src/lib/services/router.service.ts index f1cbf0cf..ab91a22f 100644 --- a/projects/swimlane/docspa-core/src/lib/services/router.service.ts +++ b/projects/swimlane/docspa-core/src/lib/services/router.service.ts @@ -1,19 +1,25 @@ -import { Injectable, EventEmitter, SimpleChange, SimpleChanges, NgZone } from '@angular/core'; -import { Router, ActivatedRouteSnapshot } from '@angular/router'; +import { + Injectable, + EventEmitter, + SimpleChange, + SimpleChanges, + NgZone, +} from "@angular/core"; +import { Router, ActivatedRouteSnapshot } from "@angular/router"; -import { NGXLogger } from 'ngx-logger'; +// import { NGXLogger } from 'ngx-logger'; -import { goExternal, isAbsolutePath } from '../shared/utils'; -import { getFullPath } from '../shared/vfile'; +import { goExternal, isAbsolutePath } from "../shared/utils"; +import { getFullPath } from "../shared/vfile"; -import { SettingsService } from './settings.service'; -import { FetchService } from './fetch.service'; -import { LocationService } from './location.service'; +import { SettingsService } from "./settings.service"; +import { FetchService } from "./fetch.service"; +import { LocationService } from "./location.service"; -import { VFile } from '../shared/vfile'; +import { VFile } from "../shared/vfile"; @Injectable({ - providedIn: 'root' + providedIn: "root", }) export class RouterService { homepage: string; @@ -38,39 +44,39 @@ export class RouterService { private settings: SettingsService, private fetchService: FetchService, private locationService: LocationService, - private logger: NGXLogger, + // private logger: any, private router: Router, private ngZone: NgZone ) { - if (window['Cypress']) { - window['cypressNavigateByUrl'] = (url: string) => this.navigateByUrl(url); + if (window["Cypress"]) { + window["cypressNavigateByUrl"] = (url: string) => this.navigateByUrl(url); } } activateRoute(snapshot: ActivatedRouteSnapshot) { - const url = snapshot.url.map(s => s.path).join('/'); + const url = snapshot.url.map((s) => s.path).join("/"); let root = this.router.url; if (snapshot.fragment) { // eslint-disable-next-line security/detect-non-literal-regexp - root = root.replace(new RegExp('#' + snapshot.fragment + '$'), ''); + root = root.replace(new RegExp("#" + snapshot.fragment + "$"), ""); } // eslint-disable-next-line security/detect-non-literal-regexp - root = root.replace(new RegExp(url + '$'), ''); - if (!root.endsWith('/')) { - root += '/'; + root = root.replace(new RegExp(url + "$"), ""); + if (!root.endsWith("/")) { + root += "/"; } - const path = url + (snapshot.fragment ? `#${snapshot.fragment}` : ''); + const path = url + (snapshot.fragment ? `#${snapshot.fragment}` : ""); this.go(path, root); } go(url: string, root = this.root) { - url = url || '/'; + url = url || "/"; if (isAbsolutePath(url)) { goExternal(url); return Promise.resolve({}); } url = this.canonicalize(url); - return this.urlChange(url || '/', root); + return this.urlChange(url || "/", root); } navigateByUrl(url: string) { @@ -79,42 +85,50 @@ export class RouterService { }); } - private async urlChange(url = '/', root = this.root) { + private async urlChange(url = "/", root = this.root) { const changes: SimpleChanges = {}; - this.logger.debug(`location changed: ${url}`); + // this.logger.debug(`location changed: ${url}`); if (this.root !== root) { - changes.root = new SimpleChange(this.root, this.root = root, false); + changes.root = new SimpleChange(this.root, (this.root = root), false); } if (this.url !== url) { - changes.url = new SimpleChange(this.url, this.url = url, false); + changes.url = new SimpleChange(this.url, (this.url = url), false); } - let [page = '/', anchor = ''] = url.split(/[#?]/); - anchor = anchor || ''; - page = page || '/'; + let [page = "/", anchor = ""] = url.split(/[#?]/); + anchor = anchor || ""; + page = page || "/"; - this.logger.debug(`page: ${page}`); - this.logger.debug(`anchor: ${anchor}`); + // this.logger.debug(`page: ${page}`); + // this.logger.debug(`anchor: ${anchor}`); const vfile = this.locationService.pageToFile(page); - if (anchor.includes('id=')) { + if (anchor.includes("id=")) { const params = new URLSearchParams(anchor); - anchor = params.get('id'); + anchor = params.get("id"); } if (this.anchor !== anchor) { - changes.anchor = new SimpleChange(this.anchor, this.anchor = anchor, false); + changes.anchor = new SimpleChange( + this.anchor, + (this.anchor = anchor), + false + ); } if (this.contentPage !== page) { - changes.contentPage = new SimpleChange(this.contentPage, this.contentPage = page, false); + changes.contentPage = new SimpleChange( + this.contentPage, + (this.contentPage = page), + false + ); const [coverPage, sideLoads] = await Promise.all([ this.resolveCoverPath(vfile), - this.resolveSideloadPaths(vfile) + this.resolveSideloadPaths(vfile), ]); changes.coverPage = new SimpleChange(null, coverPage, false); @@ -129,17 +143,21 @@ export class RouterService { } private canonicalize(url: string) { - const hp = this.settings.homepage.replace(/\.md$/, ''); - url = url.replace(/\.md$/, ''); + const hp = this.settings.homepage.replace(/\.md$/, ""); + url = url.replace(/\.md$/, ""); // eslint-disable-next-line security/detect-non-literal-regexp - url = url.replace(new RegExp(`${hp}$`), '/'); + url = url.replace(new RegExp(`${hp}$`), "/"); return url; } private async resolveCoverPath(vfile: VFile) { - const path = vfile.basename === this.settings.homepage ? - await this.fetchService.find(getFullPath(vfile), this.settings.coverpage) : - null; + const path = + vfile.basename === this.settings.homepage + ? await this.fetchService.find( + getFullPath(vfile), + this.settings.coverpage + ) + : null; return this.locationService.stripBasePath(path); } @@ -147,16 +165,19 @@ export class RouterService { const sideLoad = this.settings.sideLoad; const keys = Object.keys(sideLoad); - const promises = keys.map(key => { + const promises = keys.map((key) => { return this.fetchService.findup(vfile.cwd, vfile.path, sideLoad[key]); }); const sideLoadPathsArr = await Promise.all(promises); - return sideLoadPathsArr.reduce((acc: {[key: string]: string}, path: any, idx: number) => { - const key = keys[idx]; - acc[key] = this.locationService.stripBasePath(path); - return acc; - }, {} as {[key: string]: string}); + return sideLoadPathsArr.reduce( + (acc: { [key: string]: string }, path: any, idx: number) => { + const key = keys[idx]; + acc[key] = this.locationService.stripBasePath(path); + return acc; + }, + {} as { [key: string]: string } + ); } } diff --git a/projects/swimlane/docspa-remark-preset/CHANGELOG.md b/projects/swimlane/docspa-remark-preset/CHANGELOG.md index 0342ee6a..371ccb67 100644 --- a/projects/swimlane/docspa-remark-preset/CHANGELOG.md +++ b/projects/swimlane/docspa-remark-preset/CHANGELOG.md @@ -6,6 +6,9 @@ _(none)_ -------------------- +## 7.0.0 (2024-09-27) +_(none)_ + ## 7.0.0 (2020-11-02) * Added remark-sectionize * Removed remark-html-emoji-image for performance diff --git a/projects/swimlane/docspa-stackblitz/src/lib/docspa-stackblitz.module.ts b/projects/swimlane/docspa-stackblitz/src/lib/docspa-stackblitz.module.ts index 1a72676c..4aef024f 100644 --- a/projects/swimlane/docspa-stackblitz/src/lib/docspa-stackblitz.module.ts +++ b/projects/swimlane/docspa-stackblitz/src/lib/docspa-stackblitz.module.ts @@ -1,35 +1,38 @@ -import { NgModule, Injector, ModuleWithProviders } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { createCustomElement } from '@angular/elements'; +import { NgModule, Injector, ModuleWithProviders } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { createCustomElement } from "@angular/elements"; -import { EmbedStackblitzComponent } from './docspa-stackblitz.component'; +import { EmbedStackblitzComponent } from "./docspa-stackblitz.component"; -import { MarkdownService, customSmartCodes } from '@swimlane/docspa-core'; +import { MarkdownService, customSmartCodes } from "@swimlane/docspa-core"; @NgModule({ - declarations: [EmbedStackblitzComponent], - imports: [ - CommonModule - ], - exports: [EmbedStackblitzComponent], - bootstrap: [] + declarations: [EmbedStackblitzComponent], + imports: [CommonModule], + exports: [EmbedStackblitzComponent], + bootstrap: [], }) export class DocspaStackblitzModule { - static forRoot(): ModuleWithProviders { - return { - ngModule: DocspaStackblitzModule, - }; - } + // static forRoot(): ModuleWithProviders { + // return { + // ngModule: DocspaStackblitzModule, + // }; + // } constructor(private injector: Injector, markdownService: MarkdownService) { - const content = createCustomElement(EmbedStackblitzComponent, { injector: this.injector }); + const content = createCustomElement(EmbedStackblitzComponent, { + injector: this.injector, + }); customElements.define(EmbedStackblitzComponent.is, content); // Adds a remarkplugin to process `[[stack-blitz]]` blocks - markdownService.remarkPlugins.push([customSmartCodes, { - stackblitz: { - tagName: 'embed-stackblitz' - } - }]); + markdownService.remarkPlugins.push([ + customSmartCodes, + { + stackblitz: { + tagName: "embed-stackblitz", + }, + }, + ]); } } diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index e9c4080a..96ac1555 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -1,34 +1,38 @@ -import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; +import { NgModule } from "@angular/core"; +import { RouterModule, Routes } from "@angular/router"; import { Location, LocationStrategy, - PathLocationStrategy -} from '@angular/common'; -import { DocSPACoreComponent, LocationWithSlashes } from '@swimlane/docspa-core'; + PathLocationStrategy, +} from "@angular/common"; +import { + DocSPACoreComponent, + LocationWithSlashes, +} from "@swimlane/docspa-core"; const routes: Routes = [ - { // For testing sub-routes - path: 'docspa', + { + // For testing sub-routes + path: "docspa", children: [ { - path: '**', - component: DocSPACoreComponent - } - ] + path: "**", + component: DocSPACoreComponent, + }, + ], }, { - path: '**', - component: DocSPACoreComponent - } + path: "**", + component: DocSPACoreComponent, + }, ]; @NgModule({ - imports: [RouterModule.forRoot(routes, { relativeLinkResolution: 'legacy' })], + imports: [RouterModule.forRoot(routes)], exports: [RouterModule], providers: [ { provide: Location, useClass: LocationWithSlashes }, - { provide: LocationStrategy, useClass: PathLocationStrategy } - ] + { provide: LocationStrategy, useClass: PathLocationStrategy }, + ], }) -export class AppRoutingModule { } +export class AppRoutingModule {} diff --git a/src/app/plugins/grid.css b/src/app/plugins/grid.css index 8807a5d9..c7a8fcdd 100644 --- a/src/app/plugins/grid.css +++ b/src/app/plugins/grid.css @@ -1,11 +1,11 @@ -.markdown-section .custom-block.grid table { - width: 100%; -} - -.markdown-section .custom-block.grid table, -.markdown-section .custom-block.grid tr, -.markdown-section .custom-block.grid th, -.markdown-section .custom-block.grid td { - border: none; - vertical-align: top; -} \ No newline at end of file +/* .markdown-section .custom-block.grid table { + width: 100%; +} + +.markdown-section .custom-block.grid table, +.markdown-section .custom-block.grid tr, +.markdown-section .custom-block.grid th, +.markdown-section .custom-block.grid td { + border: none; + vertical-align: top; +} */ diff --git a/src/app/plugins/grid.module.ts b/src/app/plugins/grid.module.ts index b3753170..8e01a16c 100644 --- a/src/app/plugins/grid.module.ts +++ b/src/app/plugins/grid.module.ts @@ -1,21 +1,21 @@ -import { NgModule } from '@angular/core'; -import { MarkdownService } from '@swimlane/docspa-core'; -import { customBlocks } from '@swimlane/docspa-remark-preset'; - -import './grid.css'; - -@NgModule({ -}) -export class GridPluginModule { - constructor(markdownService: MarkdownService) { - - // Adds a remarkplugin to process tab blocks - markdownService.remarkPlugins.push([customBlocks, { - grid: { - classes: 'grid', - title: 'optional' - } - }]); - } -} - +import { NgModule } from "@angular/core"; +import { MarkdownService } from "@swimlane/docspa-core"; +import { customBlocks } from "@swimlane/docspa-remark-preset"; + +import "./grid.css"; + +@NgModule({}) +export class GridPluginModule { + constructor(markdownService: MarkdownService) { + // Adds a remarkplugin to process tab blocks + markdownService.remarkPlugins.push([ + customBlocks, + { + grid: { + classes: "grid", + title: "optional", + }, + }, + ]); + } +} diff --git a/src/app/plugins/lazy-img.css b/src/app/plugins/lazy-img.css index d95d2ba2..3ed6e9d1 100644 --- a/src/app/plugins/lazy-img.css +++ b/src/app/plugins/lazy-img.css @@ -1,8 +1,9 @@ -[is="lazyload-image"]:not(.medium-zoom-image--open) { +/* [is="lazyload-image"]:not(.medium-zoom-image--open) { transform: perspective(600px) rotateX(-90deg); transform-origin: 50% 120%; opacity: 0; - transition: opacity 600ms, transform 600ms cubic-bezier(.74,.01,.52,2.05); + transition: opacity 600ms, + transform 600ms cubic-bezier(0.74, 0.01, 0.52, 2.05); } [is="lazyload-image"].loaded:not(.medium-zoom-image--open) { @@ -16,4 +17,4 @@ opacity: unset; transition: unset; } -} \ No newline at end of file +} */ diff --git a/src/app/plugins/lazy-img.ts b/src/app/plugins/lazy-img.ts index f5f4d8f5..c69a8ee5 100644 --- a/src/app/plugins/lazy-img.ts +++ b/src/app/plugins/lazy-img.ts @@ -1,32 +1,30 @@ -import './lazy-img.css'; +import "./lazy-img.css"; export default class LazyloadImage extends HTMLImageElement { - original = ''; + original = ""; intersectionObserver: IntersectionObserver; matchMediaPrint: MediaQueryList; static get FALLBACK_IMAGE(): string { - return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAEElEQVR42gEFAPr/AP///wAI/AL+Sr4t6gAAAABJRU5ErkJggg=='; + return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAEElEQVR42gEFAPr/AP///wAI/AL+Sr4t6gAAAABJRU5ErkJggg=="; } static get observedAttributes(): string[] { - return [ - 'offset' - ]; + return ["offset"]; } get offset(): string { - return this.getAttribute('offset'); + return this.getAttribute("offset"); } set offset(value: string) { - this.setAttribute('offset', value); + this.setAttribute("offset", value); } get observer(): IntersectionObserver { if (!this.intersectionObserver) { this.intersectionObserver = new IntersectionObserver(this.onIntersect, { - rootMargin: this.offset + rootMargin: this.offset, }); } return this.intersectionObserver; @@ -34,7 +32,7 @@ export default class LazyloadImage extends HTMLImageElement { get mediaMatch(): MediaQueryList { if (!this.matchMediaPrint) { - this.matchMediaPrint = window.matchMedia('print'); + this.matchMediaPrint = window.matchMedia("print"); } return this.matchMediaPrint; } @@ -48,7 +46,7 @@ export default class LazyloadImage extends HTMLImageElement { } connectedCallback(): void { - this.classList.toggle('loading', false); + this.classList.toggle("loading", false); this.observe(); } @@ -56,7 +54,11 @@ export default class LazyloadImage extends HTMLImageElement { this.unobserve(); } - attributeChangedCallback(_name: string, _oldValue: unknown, _newValue: unknown): void { + attributeChangedCallback( + _name: string, + _oldValue: unknown, + _newValue: unknown + ): void { if (this.observer === null) { return; } @@ -67,13 +69,13 @@ export default class LazyloadImage extends HTMLImageElement { private observe() { this.observer.observe(this); - this.mediaMatch.addEventListener('change', this.onPrint); + this.mediaMatch.addEventListener("change", this.onPrint); } private unobserve() { this.observer.unobserve(this); this.observer.disconnect(); - this.mediaMatch.removeEventListener('change', this.onPrint); + this.mediaMatch.removeEventListener("change", this.onPrint); } private onPrint() { @@ -92,20 +94,20 @@ export default class LazyloadImage extends HTMLImageElement { } private load() { - this.addEventListener('load', () => { + this.addEventListener("load", () => { this.unobserve(); }); - this.addEventListener('error', () => { + this.addEventListener("error", () => { this.src = LazyloadImage.FALLBACK_IMAGE; this.unobserve(); }); this.src = this.original; - this.classList.toggle('loaded', true); + this.classList.toggle("loaded", true); } } -customElements.define('lazyload-image', LazyloadImage, { - extends: 'img' +customElements.define("lazyload-image", LazyloadImage, { + extends: "img", }); diff --git a/src/docs/angular-cli-install.md b/src/docs/angular-cli-install.md index e4a39f1a..bb6760e7 100644 --- a/src/docs/angular-cli-install.md +++ b/src/docs/angular-cli-install.md @@ -32,17 +32,17 @@ npm i --save-dev @types/node ```ts export const config = { - name: 'My DocSPA Site', - basePath: 'docs/', - homepage: 'README.md', - notFoundPage: '_404.md', + name: "My DocSPA Site", + basePath: "docs/", + homepage: "README.md", + notFoundPage: "_404.md", sideLoad: { - sidebar: '_sidebar.md', - navbar: '_navbar.md', - rightSidebar: '/_sidebar2.md', - footer: '_footer.md' + sidebar: "_sidebar.md", + navbar: "_navbar.md", + rightSidebar: "/_sidebar2.md", + footer: "_footer.md", }, - coverpage: '_coverpage.md', + coverpage: "_coverpage.md", }; ``` @@ -54,14 +54,14 @@ Add the following to `pollyfill.ts`: ```ts // Used for browsers with partially native support of Custom Elements -import '@webcomponents/custom-elements/src/native-shim'; +import "@webcomponents/custom-elements/src/native-shim"; // Used for browsers without a native support of Custom Elements -import '@webcomponents/custom-elements/custom-elements.min'; +import "@webcomponents/custom-elements/custom-elements.min"; -window['global'] = globalThis as any; -window['process'] = window['process'] || require('process/browser'); -window['Buffer'] = window['Buffer'] || require('buffer').Buffer; +window["global"] = globalThis as any; +window["process"] = window["process"] || require("process/browser"); +window["Buffer"] = window["Buffer"] || require("buffer").Buffer; ``` ## Edit `index.html` to add a docsify theme: @@ -86,58 +86,45 @@ window['Buffer'] = window['Buffer'] || require('buffer').Buffer; ## Add imports and config to `AppModule` ```ts { mark="7-10,19-22,24-26" } -import { NgModule } from '@angular/core'; -import { BrowserModule } from '@angular/platform-browser'; +import { NgModule } from "@angular/core"; +import { BrowserModule } from "@angular/platform-browser"; -import { AppRoutingModule } from './app-routing.module'; -import { AppComponent } from './app.component'; +import { AppRoutingModule } from "./app-routing.module"; +import { AppComponent } from "./app.component"; -import { config } from '../docspa.config'; -import { DocspaCoreModule, MarkdownElementsModule, MarkdownModule, MARKDOWN_CONFIG_TOKEN } from '@swimlane/docspa-core'; -import { LoggerModule, NgxLoggerLevel } from 'ngx-logger'; -import { preset } from '@swimlane/docspa-remark-preset'; +import { config } from "../docspa.config"; +import { DocspaCoreModule, MarkdownElementsModule, MarkdownModule, MARKDOWN_CONFIG_TOKEN } from "@swimlane/docspa-core"; +import { LoggerModule, NgxLoggerLevel } from "ngx-logger"; +import { preset } from "@swimlane/docspa-remark-preset"; @NgModule({ - declarations: [ - AppComponent - ], - imports: [ - BrowserModule, - AppRoutingModule, - DocspaCoreModule.forRoot(config), - LoggerModule.forRoot({ level: NgxLoggerLevel.WARN }), - MarkdownModule.forRoot(), - MarkdownElementsModule.forRoot(), - ], - providers: [ - { provide: MARKDOWN_CONFIG_TOKEN, useFactory: () => preset } - ], - bootstrap: [AppComponent] + declarations: [AppComponent], + imports: [BrowserModule, AppRoutingModule, DocspaCoreModule.forRoot(config), LoggerModule.forRoot({ level: NgxLoggerLevel.WARN }), MarkdownModule.forRoot(), MarkdownElementsModule.forRoot()], + providers: [{ provide: MARKDOWN_CONFIG_TOKEN, useFactory: () => preset }], + bootstrap: [AppComponent], }) -export class AppModule { } +export class AppModule {} ``` ## Update `app-routing.module.ts` to support DocSPA routing ```ts { mark="1,4,6-8,11,13-16" } -import { LocationStrategy, PathLocationStrategy } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; -import { DocSPACoreComponent, LocationWithSlashes } from '@swimlane/docspa-core'; +import { LocationStrategy, PathLocationStrategy } from "@angular/common"; +import { NgModule } from "@angular/core"; +import { RouterModule, Routes } from "@angular/router"; +import { DocSPACoreComponent, LocationWithSlashes } from "@swimlane/docspa-core"; -const routes: Routes = [ - { path: '**', component: DocSPACoreComponent } -]; +const routes: Routes = [{ path: "**", component: DocSPACoreComponent }]; @NgModule({ - imports: [RouterModule.forRoot(routes, { relativeLinkResolution: 'legacy' })], + imports: [RouterModule.forRoot(routes)], exports: [RouterModule], providers: [ { provide: Location, useClass: LocationWithSlashes }, - { provide: LocationStrategy, useClass: PathLocationStrategy } - ] + { provide: LocationStrategy, useClass: PathLocationStrategy }, + ], }) -export class AppRoutingModule { } +export class AppRoutingModule {} ``` ## Remove boilerplate from `app.component.html` diff --git a/src/index.scss b/src/index.scss index 27fbbe45..e1a459a9 100644 --- a/src/index.scss +++ b/src/index.scss @@ -1 +1 @@ -@import '~/projects/swimlane/docspa-search/src/index.scss'; \ No newline at end of file +@import "/projects/swimlane/docspa-search/src/index.scss"; diff --git a/tsconfig.json b/tsconfig.json index b3fd21c9..056184a1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,14 +10,14 @@ "moduleResolution": "node", "emitDecoratorMetadata": true, "experimentalDecorators": true, - "target": "es2015", + "target": "ES2022", "allowJs": false, "allowSyntheticDefaultImports": true, "esModuleInterop": true, "resolveJsonModule": true, "typeRoots": ["node_modules/@types"], "types": ["node", "jasmine"], - "lib": ["es2017", "dom"], + "lib": ["ES2022", "dom"], "paths": { "@swimlane/docspa-core": [ "./projects/swimlane/docspa-core/src/public_api"