Skip to content

Commit

Permalink
Adapt core/src/Layout to TypeScript
Browse files Browse the repository at this point in the history
  • Loading branch information
yiwen101 committed Mar 9, 2024
1 parent aa6a41f commit ebc8b06
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 63 deletions.
61 changes: 39 additions & 22 deletions packages/core/src/Layout/Layout.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,34 @@
const { v4: uuidv4 } = require('uuid');
import { v4 as uuidv4 } from 'uuid';
import { PageSources } from '../Page/PageSources';
import { NodeProcessor } from '../html/NodeProcessor';
import * as logger from '../utils/logger';
import { ExternalManager, ExternalManagerConfig } from '../External/ExternalManager';

const { PageSources } = require('../Page/PageSources');
const { NodeProcessor } = require('../html/NodeProcessor');
const LAYOUT_PAGE_BODY_VARIABLE = 'content';

const logger = require('../utils/logger');
export type LayoutConfig = ExternalManagerConfig & { externalManager: ExternalManager };

const LAYOUT_PAGE_BODY_VARIABLE = 'content';
export type PageNjkAssets = {
headTop: string[];
headBottom: string[];
scriptBottom: string[];
layoutUserScriptsAndStyles: string[];
};

class Layout {
constructor(sourceFilePath, config) {
export class Layout {
sourceFilePath: string;
config: LayoutConfig;
includedFiles: Set<string>;
layoutProcessed: string;
layoutPageBodyVariable: string;
layoutPageNavUuid: string;
headTop: string[];
headBottom: string[];
scriptBottom: string[];
layoutUserScriptsAndStyles: string[];
generatePromise: Promise<void> | undefined;

constructor(sourceFilePath: string, config: LayoutConfig) {

Check warning on line 31 in packages/core/src/Layout/Layout.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/Layout/Layout.ts#L31

Added line #L31 was not covered by tests
this.sourceFilePath = sourceFilePath;
this.config = config;

Expand All @@ -24,15 +44,15 @@ class Layout {
this.generatePromise = undefined;
}

shouldRegenerate(filePaths) {
shouldRegenerate(filePaths: string[]): boolean {

Check warning on line 47 in packages/core/src/Layout/Layout.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/Layout/Layout.ts#L47

Added line #L47 was not covered by tests
return filePaths.some(filePath => this.includedFiles.has(filePath));
}

async generate() {
async generate(): Promise<void> {

Check warning on line 51 in packages/core/src/Layout/Layout.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/Layout/Layout.ts#L51

Added line #L51 was not covered by tests
let triesLeft = 10;
let numBodyVars;
let pageSources;
let nodeProcessor;
let pageSources: PageSources;
let nodeProcessor: NodeProcessor;

do {
const fileConfig = {
Expand All @@ -51,8 +71,8 @@ class Layout {
pluginManager, siteLinkManager, this.layoutUserScriptsAndStyles,
'layout');
// eslint-disable-next-line no-await-in-loop
this.layoutProcessed = await nodeProcessor.process(this.sourceFilePath, nunjucksProcessed,
this.sourceFilePath, layoutVariables);
this.layoutProcessed = await nodeProcessor.process(this.sourceFilePath, nunjucksProcessed.toString(),

Check warning on line 74 in packages/core/src/Layout/Layout.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/Layout/Layout.ts#L74

Added line #L74 was not covered by tests
this.sourceFilePath, layoutVariables) as string;
this.layoutPageNavUuid = nodeProcessor.pageNavProcessor.getUuid();

this.layoutProcessed = pluginManager.postRender(nodeProcessor.frontmatter, this.layoutProcessed);
Expand All @@ -75,20 +95,21 @@ class Layout {
this.scriptBottom = nodeProcessor.scriptBottom;

pageSources.addAllToSet(this.includedFiles);
await this.config.externalManager.generateDependencies(pageSources.getDynamicIncludeSrc(),
this.includedFiles);
await this.config.externalManager.generateDependencies(

Check warning on line 98 in packages/core/src/Layout/Layout.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/Layout/Layout.ts#L98

Added line #L98 was not covered by tests
pageSources.getDynamicIncludeSrc(),
this.includedFiles,
this.layoutUserScriptsAndStyles);
}

insertPage(pageContent, pageNav, pageIncludedFiles) {
insertPage(pageContent: string, pageNav: string, pageIncludedFiles: Set<string>): string {

Check warning on line 104 in packages/core/src/Layout/Layout.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/Layout/Layout.ts#L104

Added line #L104 was not covered by tests
this.includedFiles.forEach(filePath => pageIncludedFiles.add(filePath));

// Use function for .replace, in case string contains special patterns (e.g. $$, $&, $1, ...)
return this.layoutProcessed
.replace(this.layoutPageBodyVariable, () => pageContent)
.replace(this.layoutPageNavUuid, () => pageNav);
}

getPageNjkAssets() {
getPageNjkAssets(): PageNjkAssets {

Check warning on line 112 in packages/core/src/Layout/Layout.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/Layout/Layout.ts#L112

Added line #L112 was not covered by tests
return {
headTop: this.headTop,
headBottom: this.headBottom,
Expand All @@ -97,7 +118,3 @@ class Layout {
};
}
}

module.exports = {
Layout,
};
41 changes: 20 additions & 21 deletions packages/core/src/Layout/LayoutManager.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
const fs = require('fs-extra');
const path = require('path');

const { Layout } = require('./Layout');

const logger = require('../utils/logger');
import fs from 'fs-extra';
import path from 'path';
import { Layout, LayoutConfig, PageNjkAssets } from './Layout';
import * as logger from '../utils/logger';

const FRONTMATTER_NONE_ATTR = 'none';

class LayoutManager {
constructor(config) {
this.config = config;
export class LayoutManager {
private config: LayoutConfig;
private layoutsRootPath: string;
private layouts: { [name: string]: Layout };

constructor(config: LayoutConfig) {
this.config = config;
this.layoutsRootPath = path.join(config.rootPath, '_markbind', 'layouts');

this.layouts = {};
}

/**
* Flag all layouts for (re)generation when requested
*/
removeLayouts() {
removeLayouts(): void {

Check warning on line 22 in packages/core/src/Layout/LayoutManager.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/Layout/LayoutManager.ts#L22

Added line #L22 was not covered by tests
this.layouts = {};
}

/**
* Update layouts which have the provided filePaths as dependencies
*/
updateLayouts(filePaths) {
updateLayouts(filePaths: string[]): Promise<void[]> {

Check warning on line 29 in packages/core/src/Layout/LayoutManager.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/Layout/LayoutManager.ts#L29

Added line #L29 was not covered by tests
const layoutsToRegenerate = Object.entries(this.layouts)
.filter(([, layout]) => layout.shouldRegenerate(filePaths));

Expand All @@ -36,7 +36,7 @@ class LayoutManager {
}));
}

generateLayoutIfNeeded(name) {
generateLayoutIfNeeded(name: string): Promise<void> | undefined {

Check warning on line 39 in packages/core/src/Layout/LayoutManager.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/Layout/LayoutManager.ts#L39

Added line #L39 was not covered by tests
if (this.layouts[name]) {
return this.layouts[name].generatePromise;
}
Expand All @@ -52,15 +52,18 @@ class LayoutManager {
return this.layouts[name].generatePromise;
}

layoutHasPageNav(name) {
layoutHasPageNav(name: string): boolean {

Check warning on line 55 in packages/core/src/Layout/LayoutManager.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/Layout/LayoutManager.ts#L55

Added line #L55 was not covered by tests
if (name === FRONTMATTER_NONE_ATTR) {
return false;
}

return this.layouts[name] && this.layouts[name].layoutPageNavUuid;
return !!this.layouts[name] && !!this.layouts[name].layoutPageNavUuid;
}

combineLayoutWithPage(name, pageContent, pageNav, pageIncludedFiles) {
combineLayoutWithPage(name: string,
pageContent: string,
pageNav: string,
pageIncludedFiles: Set<string>): string {

Check warning on line 66 in packages/core/src/Layout/LayoutManager.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/Layout/LayoutManager.ts#L66

Added line #L66 was not covered by tests
if (name === FRONTMATTER_NONE_ATTR) {
return pageContent;
}
Expand All @@ -72,15 +75,11 @@ class LayoutManager {
return this.layouts[name].insertPage(pageContent, pageNav, pageIncludedFiles);
}

getLayoutPageNjkAssets(name) {
getLayoutPageNjkAssets(name: string): PageNjkAssets | {} {

Check warning on line 78 in packages/core/src/Layout/LayoutManager.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/Layout/LayoutManager.ts#L78

Added line #L78 was not covered by tests
if (name === FRONTMATTER_NONE_ATTR || !this.layouts[name]) {
return {};
}

return this.layouts[name].getPageNjkAssets();
}
}

module.exports = {
LayoutManager,
};
11 changes: 6 additions & 5 deletions packages/core/src/Layout/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
const { Layout } = require('./Layout');
const { LayoutManager } = require('./LayoutManager');
import { Layout } from './Layout';
import { LayoutManager } from './LayoutManager';

module.exports = {
export const LAYOUT_DEFAULT_NAME = 'default.md';
export const LAYOUT_FOLDER_PATH = '_markbind/layouts';

export {
Layout,
LayoutManager,
LAYOUT_DEFAULT_NAME: 'default.md',
LAYOUT_FOLDER_PATH: '_markbind/layouts',
};
3 changes: 2 additions & 1 deletion packages/core/src/Page/PageConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { SiteLinkManager } from '../html/SiteLinkManager';
import type { PluginManager } from '../plugins/PluginManager';

import { VariableProcessor } from '../variables/VariableProcessor';
import { LayoutManager } from '../Layout';

export interface PageAssets {
bootstrap: string;
Expand Down Expand Up @@ -66,7 +67,7 @@ export class PageConfig {
template: Template;
variableProcessor: VariableProcessor;
addressablePagesSource: string[];
layoutManager: any;
layoutManager: LayoutManager;

constructor(args: {
asset: PageAssets;
Expand Down
14 changes: 6 additions & 8 deletions packages/core/src/Page/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import type { FrontMatter } from '../plugins/Plugin';
import type { ExternalManager } from '../External/ExternalManager';
import { MbNode } from '../utils/node';

import { LAYOUT_DEFAULT_NAME } from '../Layout';

require('../patches/htmlparser2');

const _ = { cloneDeep, isObject, isArray };
Expand All @@ -27,10 +29,6 @@ const LockManager = require('../utils/LockManager');

const PACKAGE_VERSION = require('../../package.json').version;

const {
LAYOUT_DEFAULT_NAME,
} = require('../Layout');

const TITLE_PREFIX_SEPARATOR = ' - ';
const TITLE_SUFFIX_SEPARATOR = ' - ';

Expand Down Expand Up @@ -475,7 +473,7 @@ export class Page {
*/
buildPageNav(content: string) {
const isFmPageNavSpecifierValid = this.isPageNavigationSpecifierValid();
const doesLayoutHavePageNav = this.pageConfig.layoutManager.layoutHasPageNav(this.layout);
const doesLayoutHavePageNav = this.pageConfig.layoutManager.layoutHasPageNav(this.layout!);

Check warning on line 476 in packages/core/src/Page/index.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/Page/index.ts#L476

Added line #L476 was not covered by tests

if (isFmPageNavSpecifierValid && doesLayoutHavePageNav) {
this.navigableHeadings = {};
Expand Down Expand Up @@ -535,12 +533,12 @@ export class Page {

pluginManager.collectPluginPageNjkAssets(this.frontmatter, content, this.asset);

await layoutManager.generateLayoutIfNeeded(this.layout);
await layoutManager.generateLayoutIfNeeded(this.layout!);

Check warning on line 536 in packages/core/src/Page/index.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/Page/index.ts#L536

Added line #L536 was not covered by tests
const pageNav = this.buildPageNav(content);
content = layoutManager.combineLayoutWithPage(this.layout, content, pageNav, this.includedFiles);
content = layoutManager.combineLayoutWithPage(this.layout!, content, pageNav, this.includedFiles);

Check warning on line 538 in packages/core/src/Page/index.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/Page/index.ts#L538

Added line #L538 was not covered by tests
this.asset = {
...this.asset,
...layoutManager.getLayoutPageNjkAssets(this.layout),
...layoutManager.getLayoutPageNjkAssets(this.layout!),
};

pageSources.addAllToSet(this.includedFiles);
Expand Down
11 changes: 6 additions & 5 deletions packages/core/src/Site/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { Page } from '../Page';
import { PageConfig } from '../Page/PageConfig';
import { VariableProcessor } from '../variables/VariableProcessor';
import { VariableRenderer } from '../variables/VariableRenderer';
import { ExternalManager, ExternalManagerConfig } from '../External/ExternalManager';
import { ExternalManager } from '../External/ExternalManager';
import { SiteLinkManager } from '../html/SiteLinkManager';
import { PluginManager } from '../plugins/PluginManager';
import type { FrontMatter } from '../plugins/Plugin';
Expand All @@ -23,10 +23,11 @@ import * as fsUtil from '../utils/fsUtil';
import * as gitUtil from '../utils/git';
import * as logger from '../utils/logger';
import { SITE_CONFIG_NAME, LAZY_LOADING_SITE_FILE_NAME, _ } from './constants';
import { LayoutManager } from '../Layout';
import { LayoutConfig } from '../Layout/Layout';

// Change when they are migrated to TypeScript
const ProgressBar = require('../lib/progress');
const { LayoutManager } = require('../Layout');
require('../patches/htmlparser2');

const url = {
Expand Down Expand Up @@ -156,7 +157,7 @@ export class Site {
toRebuild: Set<string>;
externalManager!: ExternalManager;
// TODO: add LayoutManager when it has been migrated
layoutManager: any;
layoutManager!: LayoutManager;

constructor(rootPath: string, outputPath: string, onePagePath: string, forceReload = false,
siteConfigPath = SITE_CONFIG_NAME, dev: any, backgroundBuildMode: boolean,
Expand Down Expand Up @@ -422,7 +423,7 @@ export class Site {
* Set up the managers used with the configurations.
*/
buildManagers() {
const config: ExternalManagerConfig & { externalManager: ExternalManager } = {
const config: LayoutConfig = {
baseUrlMap: this.baseUrlMap,
baseUrl: this.siteConfig.baseUrl,
rootPath: this.rootPath,
Expand Down Expand Up @@ -618,7 +619,7 @@ export class Site {
this.beforeSiteGenerate();

try {
await this.layoutManager.updateLayouts(filePaths);
await this.layoutManager.updateLayouts(filePathArray);

Check warning on line 622 in packages/core/src/Site/index.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/Site/index.ts#L622

Added line #L622 was not covered by tests
await this.regenerateAffectedPages(uniquePaths);
await fs.remove(this.tempPath);
if (this.backgroundBuildMode) {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/Site/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { SiteConfig, SiteConfigPage } from './SiteConfig';
import { VariableRenderer } from '../variables/VariableRenderer';
import * as logger from '../utils/logger';

const { LAYOUT_DEFAULT_NAME, LAYOUT_FOLDER_PATH } = require('../Layout');
import { LAYOUT_DEFAULT_NAME, LAYOUT_FOLDER_PATH } from '../Layout';

const requiredFiles = ['index.md', 'site.json', '_markbind/'];

Expand Down

0 comments on commit ebc8b06

Please sign in to comment.