mirror of
https://github.com/akveo/ngx-admin.git
synced 2026-01-06 01:28:50 +01:00
feat: docs app
This commit is contained in:
parent
62e6828680
commit
165e64eaca
203 changed files with 15928 additions and 6 deletions
28
docs/app/@theme/services/analytics.service.ts
Normal file
28
docs/app/@theme/services/analytics.service.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Akveo. All Rights Reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*/
|
||||
|
||||
import { Injectable, Inject } from '@angular/core';
|
||||
import { NB_WINDOW } from '@nebular/theme';
|
||||
|
||||
@Injectable()
|
||||
export class NgxAnalytics {
|
||||
private enabled: boolean;
|
||||
|
||||
constructor(@Inject(NB_WINDOW) private window) {
|
||||
this.enabled = this.window.location.href.indexOf('akveo.github.io') >= 0;
|
||||
}
|
||||
|
||||
trackEvent(eventName: string, eventVal: string = '') {
|
||||
if (this.enabled) {
|
||||
this.gtmPushToDataLayer({ event: eventName, eventValue: eventVal });
|
||||
}
|
||||
}
|
||||
|
||||
// Push to 'dataLayer' Google Tag Manager array
|
||||
private gtmPushToDataLayer(params) {
|
||||
this.window.dataLayer.push(params);
|
||||
}
|
||||
}
|
||||
39
docs/app/@theme/services/code-loader.service.ts
Normal file
39
docs/app/@theme/services/code-loader.service.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
import { publishReplay , refCount } from 'rxjs/operators';
|
||||
|
||||
@Injectable()
|
||||
export class NgxCodeLoaderService {
|
||||
|
||||
/**
|
||||
* Contains cached files by url.
|
||||
* */
|
||||
private cache: Map<string, Observable<string>> = new Map();
|
||||
|
||||
constructor(private http: HttpClient) {
|
||||
}
|
||||
|
||||
load(path: string): Observable<string> {
|
||||
const url = this.buildFilePath(path);
|
||||
const cached = this.cache.get(url);
|
||||
|
||||
return cached ? cached : this.buildRequest(url);
|
||||
}
|
||||
|
||||
private buildFilePath(path: string): string {
|
||||
return `assets/examples/${path}`;
|
||||
}
|
||||
|
||||
private buildRequest(url): Observable<string> {
|
||||
const request = this.http.get(url, { responseType: 'text' })
|
||||
.pipe(
|
||||
publishReplay(1),
|
||||
refCount(),
|
||||
);
|
||||
|
||||
this.cache.set(url, request);
|
||||
|
||||
return request;
|
||||
}
|
||||
}
|
||||
23
docs/app/@theme/services/dialog-state.service.ts
Normal file
23
docs/app/@theme/services/dialog-state.service.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Akveo. All Rights Reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*/
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable, ReplaySubject } from 'rxjs';
|
||||
import { share } from 'rxjs/operators';
|
||||
|
||||
@Injectable()
|
||||
export class DialogStateService {
|
||||
|
||||
protected dialogState$ = new ReplaySubject();
|
||||
|
||||
changeDialogState(state: string) {
|
||||
this.dialogState$.next({state});
|
||||
}
|
||||
|
||||
onChangeDialogState(): Observable<any> {
|
||||
return this.dialogState$.pipe(share());
|
||||
}
|
||||
}
|
||||
10
docs/app/@theme/services/highlight.service.ts
Normal file
10
docs/app/@theme/services/highlight.service.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import * as hljs from 'highlight.js';
|
||||
|
||||
@Injectable()
|
||||
export class NgxHighlightService {
|
||||
|
||||
public highlight(code: string): string {
|
||||
return hljs.highlightAuto(code, ['ts', 'html', 'scss', 'nginx']).value;
|
||||
}
|
||||
}
|
||||
25
docs/app/@theme/services/iframe-communicator.service.ts
Normal file
25
docs/app/@theme/services/iframe-communicator.service.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import { Inject, Injectable } from '@angular/core';
|
||||
import { Observable, fromEvent as observableFromEvent } from 'rxjs';
|
||||
import { filter, map } from 'rxjs/operators';
|
||||
import { NB_WINDOW } from '@nebular/theme';
|
||||
|
||||
@Injectable()
|
||||
export class NgxIframeCommunicatorService {
|
||||
|
||||
constructor(@Inject(NB_WINDOW) private window) {
|
||||
}
|
||||
|
||||
public send(payload: any, target: Window = this.window.parent) {
|
||||
if (target !== this.window) {
|
||||
target.postMessage(payload, '*');
|
||||
}
|
||||
}
|
||||
|
||||
public receive(id: string): Observable<any> {
|
||||
return observableFromEvent(this.window, 'message')
|
||||
.pipe(
|
||||
filter((msg: any) => msg.data && msg.data.id === id),
|
||||
map((msg: any) => msg.data),
|
||||
);
|
||||
}
|
||||
}
|
||||
36
docs/app/@theme/services/index.ts
Normal file
36
docs/app/@theme/services/index.ts
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Akveo. All Rights Reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*/
|
||||
|
||||
import { NgxVersionService } from './version.service';
|
||||
import { DialogStateService } from './dialog-state.service';
|
||||
import { NgxAnalytics } from './analytics.service';
|
||||
import { NgxHighlightService } from './highlight.service';
|
||||
import { NgxMenuService } from './menu.service';
|
||||
import { NgxPaginationService } from './pagination.service';
|
||||
import { NgxStructureService } from './structure.service';
|
||||
import { NgxTabbedService } from './tabbed.service';
|
||||
import { NgxTextService } from './text.service';
|
||||
import { NgxTocStateService } from './toc-state.service';
|
||||
import { NgxCodeLoaderService } from './code-loader.service';
|
||||
import { NgxStylesService } from './styles.service';
|
||||
import { NgxIframeCommunicatorService } from './iframe-communicator.service';
|
||||
|
||||
|
||||
export const ngxLandingServices = [
|
||||
NgxVersionService,
|
||||
DialogStateService,
|
||||
NgxAnalytics,
|
||||
NgxHighlightService,
|
||||
NgxMenuService,
|
||||
NgxPaginationService,
|
||||
NgxStructureService,
|
||||
NgxTabbedService,
|
||||
NgxTextService,
|
||||
NgxTocStateService,
|
||||
NgxCodeLoaderService,
|
||||
NgxStylesService,
|
||||
NgxIframeCommunicatorService,
|
||||
];
|
||||
86
docs/app/@theme/services/menu.service.ts
Normal file
86
docs/app/@theme/services/menu.service.ts
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Akveo. All Rights Reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*/
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { NbMenuItem } from '@nebular/theme';
|
||||
|
||||
import { NgxStructureService } from './structure.service';
|
||||
import { NgxTextService } from './text.service';
|
||||
|
||||
interface IItemLink {
|
||||
title: string;
|
||||
parent?: {
|
||||
link?: string;
|
||||
};
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class NgxMenuService {
|
||||
|
||||
constructor(private structureService: NgxStructureService,
|
||||
private textService: NgxTextService) {
|
||||
}
|
||||
|
||||
getPreparedMenu(basePath: string): any {
|
||||
return this.prepareMenu(this.structureService.getPreparedStructure(), { link: basePath });
|
||||
}
|
||||
|
||||
prepareMenu(structure, parent = null) {
|
||||
return structure
|
||||
.filter(item => item.name && item.type !== 'block')
|
||||
.map((item: any) => {
|
||||
const menuItem: NbMenuItem = {
|
||||
title: item.name,
|
||||
pathMatch: 'prefix',
|
||||
parent: parent,
|
||||
data: item,
|
||||
group: item.type === 'group',
|
||||
};
|
||||
menuItem.link = this.createItemLink<NbMenuItem>(menuItem);
|
||||
|
||||
if (item.children && item.children.some(child => child.type === 'page' || child.type === 'tabs')) {
|
||||
menuItem.expanded = true;
|
||||
menuItem.children = this.prepareMenu(item.children, menuItem);
|
||||
}
|
||||
|
||||
return menuItem;
|
||||
});
|
||||
}
|
||||
|
||||
protected prepareToc(item: any) {
|
||||
return item.children.reduce((acc: any[], child: any) => {
|
||||
if (child.block === 'markdown') {
|
||||
return acc.concat(this.getTocForMd(child));
|
||||
} else if (child.block === 'tabbed') {
|
||||
return acc.concat(this.getTocForTabbed(child));
|
||||
}
|
||||
acc.push(child.source.name);
|
||||
return acc;
|
||||
}, []);
|
||||
}
|
||||
|
||||
protected getTocForMd(block: any) {
|
||||
return block.children.map((section: any) => ({
|
||||
title: section.title,
|
||||
fragment: section.fragment,
|
||||
}));
|
||||
}
|
||||
|
||||
protected getTocForTabbed(block: any) {
|
||||
return block.children.map((component: any) => (
|
||||
{
|
||||
title: component.name,
|
||||
fragment: this.textService.createSlag(component.name),
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
createItemLink<T extends IItemLink>(item: T): string {
|
||||
const url = this.textService.createSlag(item.title);
|
||||
|
||||
return item.parent ? `${item.parent.link}/${url}` : url;
|
||||
}
|
||||
}
|
||||
97
docs/app/@theme/services/pagination.service.ts
Normal file
97
docs/app/@theme/services/pagination.service.ts
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Akveo. All Rights Reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*/
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { NgxStructureService } from './structure.service';
|
||||
import { NgxMenuService } from './menu.service';
|
||||
|
||||
/**
|
||||
* Pagination Item options
|
||||
*/
|
||||
class NgxPaginationItem {
|
||||
title: string;
|
||||
slag: string;
|
||||
link?: string;
|
||||
prev?: {
|
||||
title: string;
|
||||
link: string;
|
||||
};
|
||||
next?: {
|
||||
title: string;
|
||||
link: string;
|
||||
};
|
||||
parent: NgxPaginationItem;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class NgxPaginationService {
|
||||
|
||||
protected paginationItems;
|
||||
|
||||
constructor(private structureService: NgxStructureService,
|
||||
private menuService: NgxMenuService) {
|
||||
}
|
||||
|
||||
setPaginationItems(basePath: string) {
|
||||
this.paginationItems = this.addPrevNextPointers(
|
||||
this.prepareItems(
|
||||
this.structureService.getPreparedStructure(),
|
||||
{ link: basePath },
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
protected prepareItems(structure, parent = null): NgxPaginationItem[] {
|
||||
return structure
|
||||
.filter(item => item.name)
|
||||
.reduce((result, item: any) => {
|
||||
const paginationItem: NgxPaginationItem = {
|
||||
title: item.name,
|
||||
parent: parent,
|
||||
slag: item.slag,
|
||||
};
|
||||
paginationItem.link = this.menuService.createItemLink<NgxPaginationItem>(paginationItem);
|
||||
|
||||
if (item.name && item.type === 'page' || item.type === 'tabs') {
|
||||
result.push(paginationItem);
|
||||
}
|
||||
|
||||
if (item.children) {
|
||||
return result.concat(this.prepareItems(item.children, paginationItem));
|
||||
}
|
||||
|
||||
return result;
|
||||
}, [] as NgxPaginationItem[]);
|
||||
}
|
||||
|
||||
protected addPrevNextPointers(items): NgxPaginationItem[] {
|
||||
return items
|
||||
.map((paginationItem, index, paginationItems) => {
|
||||
const prev = paginationItems[index - 1];
|
||||
const next = paginationItems[index + 1];
|
||||
|
||||
if (prev) {
|
||||
paginationItem.prev = {
|
||||
link: prev.link,
|
||||
title: prev.title,
|
||||
};
|
||||
}
|
||||
|
||||
if (next) {
|
||||
paginationItem.next = {
|
||||
link: next.link,
|
||||
title: next.title,
|
||||
};
|
||||
}
|
||||
|
||||
return paginationItem;
|
||||
});
|
||||
}
|
||||
|
||||
getPaginationItem(slag: string): NgxPaginationItem {
|
||||
return this.paginationItems.find(item => item.slag === slag);
|
||||
}
|
||||
}
|
||||
150
docs/app/@theme/services/structure.service.ts
Normal file
150
docs/app/@theme/services/structure.service.ts
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Akveo. All Rights Reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*/
|
||||
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
|
||||
import { NgxTabbedService } from './tabbed.service';
|
||||
import { NgxTextService } from './text.service';
|
||||
import { DOCS, STRUCTURE } from '../../app.options';
|
||||
|
||||
@Injectable()
|
||||
export class NgxStructureService {
|
||||
|
||||
protected prepared;
|
||||
|
||||
constructor(private textService: NgxTextService,
|
||||
private tabbedService: NgxTabbedService,
|
||||
@Inject(STRUCTURE) structure,
|
||||
@Inject(DOCS) docs) {
|
||||
this.prepared = this.prepareStructure(structure, docs);
|
||||
}
|
||||
|
||||
getPreparedStructure(): any {
|
||||
return this.prepared;
|
||||
}
|
||||
|
||||
findPageBySlag(structure: any, slag: string): any {
|
||||
for (const item of structure) {
|
||||
if (item.slag === slag) {
|
||||
return item;
|
||||
}
|
||||
if (item.type === 'section' && item.children) {
|
||||
const deep = this.findPageBySlag(item.children, slag);
|
||||
if (deep) {
|
||||
return deep;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected prepareStructure(structure: any, preparedDocs: any, parentSlag?: string): any {
|
||||
return structure.map((item: any) => {
|
||||
const slag = item.name ? this.textService.createSlag(item.name) : null;
|
||||
|
||||
if (item.type === 'block' && typeof item.source === 'string') {
|
||||
|
||||
if (item.block === 'theme') {
|
||||
item.source = preparedDocs.themes[item.source];
|
||||
}
|
||||
|
||||
if (item.block === 'component') {
|
||||
item.source = this.prepareComponent(preparedDocs.classes.find((data) => data.name === item.source));
|
||||
}
|
||||
}
|
||||
|
||||
if (item.block === 'markdown') {
|
||||
item.children = this.textService.mdToSectionsHTML(require(`raw-loader!../../../articles/${item.source}`));
|
||||
}
|
||||
|
||||
if (item.children) {
|
||||
item.children = this.prepareStructure(item.children, preparedDocs, slag);
|
||||
}
|
||||
|
||||
if (item.type === 'tabs') {
|
||||
item.source = this.getComponents(item, preparedDocs);
|
||||
item.tabs = this.tabbedService.determineTabs(item);
|
||||
|
||||
// we emulate a block here
|
||||
item.children = [
|
||||
{
|
||||
type: 'block',
|
||||
block: 'tabbed',
|
||||
children: item.source,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
if (item.type === 'page' || item.type === 'tabs') {
|
||||
item.toc = this.prepareToc(item);
|
||||
item.slag = parentSlag ? `${parentSlag}_${slag}` : slag;
|
||||
}
|
||||
|
||||
return item;
|
||||
});
|
||||
}
|
||||
|
||||
protected getComponents(item: any, preparedDocs) {
|
||||
return item.source
|
||||
.map(source => preparedDocs.classes.find((data) => data.name === source))
|
||||
.map(component => this.prepareComponent(component));
|
||||
}
|
||||
|
||||
protected prepareComponent(component: any) {
|
||||
const textNodes = component.overview.filter(node => node.type === 'text');
|
||||
if (textNodes && textNodes.length) {
|
||||
textNodes[0].content = `## ${component.name}\n\n${textNodes[0].content}`; // TODO: this is bad
|
||||
}
|
||||
return {
|
||||
... component,
|
||||
slag: this.textService.createSlag(component.name),
|
||||
overview: component.overview.map((node: any) => {
|
||||
if (node.type === 'text') {
|
||||
return {
|
||||
type: node.type,
|
||||
content: this.textService.mdToSectionsHTML(node.content),
|
||||
};
|
||||
}
|
||||
return node;
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
protected prepareToc(item: any) {
|
||||
return item.children.reduce((acc: any[], child: any) => {
|
||||
if (child.block === 'markdown') {
|
||||
return acc.concat(this.getTocForMd(child));
|
||||
} else if (child.block === 'tabbed') {
|
||||
return acc.concat(this.getTocForTabbed(child));
|
||||
} else if (child.block === 'component') {
|
||||
acc.push(this.getTocForComponent(child));
|
||||
}
|
||||
return acc;
|
||||
}, []);
|
||||
}
|
||||
|
||||
protected getTocForMd(block: any) {
|
||||
return block.children.map((section: any) => ({
|
||||
title: section.title,
|
||||
fragment: section.fragment,
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
protected getTocForComponent(block: any) {
|
||||
return {
|
||||
title: block.source.name,
|
||||
fragment: block.source.slag,
|
||||
};
|
||||
}
|
||||
|
||||
protected getTocForTabbed(block: any) {
|
||||
return block.children.map((component: any) => ({
|
||||
title: component.name,
|
||||
fragment: this.textService.createSlag(component.name),
|
||||
}
|
||||
));
|
||||
}
|
||||
}
|
||||
33
docs/app/@theme/services/styles.service.ts
Normal file
33
docs/app/@theme/services/styles.service.ts
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Akveo. All Rights Reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*/
|
||||
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
import { DOCS } from '../../app.options';
|
||||
|
||||
@Injectable()
|
||||
export class NgxStylesService {
|
||||
|
||||
constructor(@Inject(DOCS) private docs) {
|
||||
}
|
||||
|
||||
mapThemedValues(classStyles: any): any {
|
||||
return classStyles.map(item => {
|
||||
item.styles.map(prop => {
|
||||
prop.themedValues = [];
|
||||
for (const themeName in this.docs.themes) {
|
||||
if (this.docs.themes.hasOwnProperty(themeName)) {
|
||||
prop.themedValues.push({
|
||||
theme: this.docs.themes[themeName].name,
|
||||
value: this.docs.themes[themeName].data[prop.name].value,
|
||||
});
|
||||
}
|
||||
}
|
||||
return prop;
|
||||
});
|
||||
return item;
|
||||
});
|
||||
}
|
||||
}
|
||||
56
docs/app/@theme/services/tabbed.service.ts
Normal file
56
docs/app/@theme/services/tabbed.service.ts
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
export class NgxTabbedService {
|
||||
|
||||
determineTabs(tabs: any): { [tab: string]: boolean } {
|
||||
return {
|
||||
'overview': this.hasOverview(tabs),
|
||||
'api': this.hasAPI(tabs),
|
||||
'theme': this.hasTheme(tabs),
|
||||
'examples': this.hasExample(tabs),
|
||||
};
|
||||
}
|
||||
|
||||
hasOverview(tabs: any): boolean {
|
||||
return tabs.source.some(source => this.componentHasOverview(source));
|
||||
}
|
||||
|
||||
hasExample(tabs: any): boolean {
|
||||
return tabs.source.some(source => this.componentHasExamples(source));
|
||||
}
|
||||
|
||||
hasTheme(tabs: any): boolean {
|
||||
return tabs.source.some(source => this.componentHasTheme(source));
|
||||
}
|
||||
|
||||
hasAPI(tabs: any): boolean {
|
||||
return tabs.source.some(source => this.componentHasMethods(source) || this.componentHasProps(source));
|
||||
}
|
||||
|
||||
componentHasTheme(component): boolean {
|
||||
return component.styles &&
|
||||
component.styles.length > 0;
|
||||
}
|
||||
|
||||
componentHasProps(component): boolean {
|
||||
return component &&
|
||||
component.props &&
|
||||
component.props.length > 0;
|
||||
}
|
||||
|
||||
componentHasMethods(component): boolean {
|
||||
return component &&
|
||||
component.methods &&
|
||||
component.methods.length > 0 &&
|
||||
component.methods.some(method => method.shortDescription || method.description);
|
||||
}
|
||||
|
||||
componentHasOverview(component): boolean {
|
||||
return component && component.overview && component.overview.length > 0;
|
||||
}
|
||||
|
||||
componentHasExamples(component): boolean {
|
||||
return component.liveExamples && component.liveExamples.length > 0;
|
||||
}
|
||||
}
|
||||
67
docs/app/@theme/services/text.service.ts
Normal file
67
docs/app/@theme/services/text.service.ts
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { Location } from '@angular/common';
|
||||
import * as marked from 'marked';
|
||||
|
||||
import { NgxHighlightService } from './highlight.service';
|
||||
|
||||
@Injectable()
|
||||
export class NgxTextService {
|
||||
|
||||
private readonly SECTION_SPLIT = '<hr>';
|
||||
private readonly TITLE_MASK = '^#{1,6}[^#]?(.+)\n';
|
||||
private readonly STRIP_HTML = '<\\/?[^>]+(>|$)';
|
||||
|
||||
constructor(private highlight: NgxHighlightService, private location: Location) {
|
||||
}
|
||||
|
||||
mdToSectionsHTML(markdown: string) {
|
||||
return this.splitIntoSections(markdown)
|
||||
.map((section) => {
|
||||
const html = this.mdToHTML(section);
|
||||
const title = this.extractTitle(section) || this.extractFirstTwoWords(html);
|
||||
const fragment = this.createSlag(title);
|
||||
return {
|
||||
source: section,
|
||||
title: title,
|
||||
fragment: fragment,
|
||||
html: html,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
mdToHTML(markdown: string) {
|
||||
return marked
|
||||
.setOptions({
|
||||
baseUrl: this.location.prepareExternalUrl(''),
|
||||
langPrefix: 'hljs ',
|
||||
highlight: (code) => this.highlight.highlight(code),
|
||||
} as any)
|
||||
.parse(markdown.trim());
|
||||
}
|
||||
|
||||
splitIntoSections(markdown: string) {
|
||||
return markdown.split(new RegExp(this.SECTION_SPLIT, 'g'))
|
||||
.filter(section => section.trim());
|
||||
}
|
||||
|
||||
extractTitle(section: string) {
|
||||
const titleMatch = section.trim().match(new RegExp(this.TITLE_MASK, 'i'));
|
||||
return titleMatch ? titleMatch[1] : '';
|
||||
}
|
||||
|
||||
extractFirstTwoWords(section: string) {
|
||||
return section
|
||||
.replace(new RegExp(this.STRIP_HTML, 'g'), '')
|
||||
.trim()
|
||||
.split(/\s+/g)
|
||||
.slice(0, 2)
|
||||
.join(' ');
|
||||
}
|
||||
|
||||
createSlag(name: string) {
|
||||
return name
|
||||
.replace(/[^a-zA-Z0-9\s]+/g, '')
|
||||
.replace(/\s/g, '-')
|
||||
.toLowerCase();
|
||||
}
|
||||
}
|
||||
29
docs/app/@theme/services/toc-state.service.ts
Normal file
29
docs/app/@theme/services/toc-state.service.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
|
||||
export interface NgxTocElement {
|
||||
fragment: string;
|
||||
element: any;
|
||||
y: number;
|
||||
setInView(val: boolean);
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class NgxTocStateService {
|
||||
state: NgxTocElement[] = [];
|
||||
|
||||
add(el: NgxTocElement) {
|
||||
this.state.push(el);
|
||||
}
|
||||
|
||||
remove(el: NgxTocElement) {
|
||||
this.state = this.state.filter(e => e !== el);
|
||||
}
|
||||
|
||||
list(): NgxTocElement[] {
|
||||
return this.state;
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.state = [];
|
||||
}
|
||||
}
|
||||
15
docs/app/@theme/services/version.service.ts
Normal file
15
docs/app/@theme/services/version.service.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Akveo. All Rights Reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*/
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
export class NgxVersionService {
|
||||
|
||||
getNgxVersion() {
|
||||
return require('../../../../package.json').version;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue