Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 28 additions & 14 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,34 @@ packages/core/src/html/**/*.js
packages/core/src/Layout/*.js
packages/core/src/lib/nunjucks-extensions/*.js
packages/core/src/lib/markdown-it/index.js
packages/core/src/lib/markdown-it/highlight/*.js
packages/core/src/lib/markdown-it/utils/*.js
packages/core/src/Page/*.js
packages/core/src/plugins/**/*.js
packages/core/src/Site/*.js
packages/core/src/utils/*.js
packages/core/src/variables/*.js
packages/core/test/unit/**/*.js

# TODO: remove when migrated to TS
!packages/core/src/Site/index.js
!packages/core/test/unit/lib/nunjucks-extensions/*.js
!markdown-it-icons.test.js
!Site.test.js
packages/core/src/lib/markdown-it/utils/index.js
packages/core/src/lib/markdown-it/highlight/helper.js
packages/core/src/lib/markdown-it/highlight/HighlightRule.js
packages/core/src/lib/markdown-it/highlight/HighlightRuleComponent.js
packages/core/src/lib/markdown-it/plugins/markdown-it-icons.js
packages/core/test/unit/html/NodeProcessor.test.js
packages/core/test/unit/html/NodeProcessor.data.js
packages/core/test/unit/html/linkProcessor.test.js
packages/core/test/unit/html/includePanelProcessor.test.js
packages/core/test/unit/html/SiteLinkManager.test.js
packages/core/test/unit/utils/utils.js
packages/core/test/unit/utils/data.js
packages/core/src/plugins/default/markbind-plugin-anchors.js
packages/core/src/plugins/default/markbind-plugin-plantuml.js
packages/core/src/plugins/default/markbind-plugin-shorthandSyntax.js
packages/core/src/plugins/default/markbind-plugin-tree.js
packages/core/test/unit/plugins/default/anchor.test.js
packages/core/test/unit/plugins/default/plantuml.test.js
packages/core/test/unit/plugins/default/shorthandSyntax.test.js
packages/core/test/unit/plugins/default/tree.test.js
packages/core/src/plugins/algolia.js
packages/core/src/plugins/disqus.js
packages/core/src/plugins/filterTags.js
packages/core/src/plugins/googleAnalytics.js
packages/core/src/plugins/mathDelimiters.js
packages/core/src/Layout/index.js
packages/core/src/Layout/Layout.js
packages/core/src/Layout/LayoutManager.js

# Rules for pure JS files
packages/core/src/lib/markdown-it/patches/*
Expand Down
37 changes: 24 additions & 13 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -81,18 +81,29 @@ packages/core/src/lib/nunjucks-extensions/*.js
packages/core/src/lib/markdown-it/index.js
packages/core/src/lib/markdown-it/highlight/*.js
packages/core/src/lib/markdown-it/plugins/markdown-it-icons.js
packages/core/src/lib/markdown-it/utils/*.js
packages/core/src/Page/*.js
packages/core/src/plugins/**/*.js
packages/core/src/Site/*.js
packages/core/src/utils/*.js
packages/core/src/variables/*.js
packages/core/test/unit/**/*.js

# TODO: remove when migrated to TS
!packages/core/src/Site/index.js
!packages/core/test/unit/lib/nunjucks-extensions/*.js
!markdown-it-icons.test.js
!Site.test.js
packages/core/src/Page/index.js
packages/core/test/unit/html/NodeProcessor.test.js
packages/core/test/unit/html/NodeProcessor.data.js
packages/core/test/unit/html/linkProcessor.test.js
packages/core/test/unit/html/includePanelProcessor.test.js
packages/core/test/unit/html/SiteLinkManager.test.js
packages/core/test/unit/utils/utils.js
packages/core/test/unit/utils/data.js
packages/core/src/plugins/default/markbind-plugin-anchors.js
packages/core/src/plugins/default/markbind-plugin-plantuml.js
packages/core/src/plugins/default/markbind-plugin-shorthandSyntax.js
packages/core/src/plugins/default/markbind-plugin-tree.js
packages/core/test/unit/plugins/default/anchor.test.js
packages/core/test/unit/plugins/default/plantuml.test.js
packages/core/test/unit/plugins/default/shorthandSyntax.test.js
packages/core/test/unit/plugins/default/tree.test.js
packages/core/src/plugins/algolia.js
packages/core/src/plugins/disqus.js
packages/core/src/plugins/filterTags.js
packages/core/src/plugins/googleAnalytics.js
packages/core/src/plugins/mathDelimiters.js
packages/core/src/Layout/index.js
packages/core/src/Layout/Layout.js
packages/core/src/Layout/LayoutManager.js

# --- packages/core end ---
Original file line number Diff line number Diff line change
@@ -1,14 +1,39 @@
const { v4: uuidv4 } = require('uuid');
import { v4 as uuidv4 } from 'uuid';

const { PageSources } = require('../Page/PageSources');
const { NodeProcessor } = require('../html/NodeProcessor');
import { PageSources } from '../Page/PageSources';
import { NodeProcessor, NodeProcessorConfig } from '../html/NodeProcessor';

const logger = require('../utils/logger');
import * as logger from '../utils/logger';
import { VariableProcessor } from '../variables/VariableProcessor';
import { PluginManager } from '../plugins/PluginManager';
import { SiteLinkManager } from '../html/SiteLinkManager';
import { ExternalManager } from '../External/ExternalManager';

const LAYOUT_PAGE_BODY_VARIABLE = 'content';

class Layout {
constructor(sourceFilePath, config) {
export type LayoutConfig = {
pluginManager: PluginManager;
siteLinkManager: SiteLinkManager;
variableProcessor: VariableProcessor;
externalManager: ExternalManager;
} & NodeProcessorConfig;

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<any>;

constructor(sourceFilePath: string, config: LayoutConfig) {
this.sourceFilePath = sourceFilePath;
this.config = config;

Expand All @@ -20,11 +45,9 @@ class Layout {
this.headBottom = [];
this.scriptBottom = [];
this.layoutUserScriptsAndStyles = [];

this.generatePromise = undefined;
}

shouldRegenerate(filePaths) {
shouldRegenerate(filePaths: string[]) {
return filePaths.some(filePath => this.includedFiles.has(filePath));
}

Expand All @@ -51,8 +74,9 @@ 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,
this.sourceFilePath, layoutVariables)) as string;

this.layoutPageNavUuid = nodeProcessor.pageNavProcessor.getUuid();

this.layoutProcessed = pluginManager.postRender(nodeProcessor.frontmatter, this.layoutProcessed);
Expand All @@ -79,7 +103,7 @@ class Layout {
this.includedFiles);
}

insertPage(pageContent, pageNav, pageIncludedFiles) {
insertPage(pageContent: string, pageNav: string, pageIncludedFiles: Set<string>) {
this.includedFiles.forEach(filePath => pageIncludedFiles.add(filePath));

// Use function for .replace, in case string contains special patterns (e.g. $$, $&, $1, ...)
Expand All @@ -97,7 +121,3 @@ class Layout {
};
}
}

module.exports = {
Layout,
};
Comment thread
ong6 marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
const fs = require('fs-extra');
const path = require('path');
import * as fs from 'fs-extra';
import * as path from 'path';

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

const logger = require('../utils/logger');
import * as logger from '../utils/logger';

const FRONTMATTER_NONE_ATTR = 'none';

class LayoutManager {
constructor(config) {
export class LayoutManager {
layouts: Record<string, Layout>;
layoutsRootPath: string;
config: LayoutConfig;

constructor(config: LayoutConfig) {
this.config = config;

this.layoutsRootPath = path.join(config.rootPath, '_markbind', 'layouts');
Expand All @@ -26,7 +30,7 @@ class LayoutManager {
/**
* Update layouts which have the provided filePaths as dependencies
*/
updateLayouts(filePaths) {
updateLayouts(filePaths: string[]) {
const layoutsToRegenerate = Object.entries(this.layouts)
.filter(([, layout]) => layout.shouldRegenerate(filePaths));

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

generateLayoutIfNeeded(name) {
generateLayoutIfNeeded(name: string) {
if (this.layouts[name]) {
return this.layouts[name].generatePromise;
}
Expand All @@ -52,15 +56,15 @@ class LayoutManager {
return this.layouts[name].generatePromise;
}

layoutHasPageNav(name) {
layoutHasPageNav(name: string) {
if (name === FRONTMATTER_NONE_ATTR) {
return false;
}

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

combineLayoutWithPage(name, pageContent, pageNav, pageIncludedFiles) {
combineLayoutWithPage(name: string, pageContent: string, pageNav: string, pageIncludedFiles: Set<string>) {
if (name === FRONTMATTER_NONE_ATTR) {
return pageContent;
}
Expand All @@ -69,18 +73,14 @@ class LayoutManager {
return pageContent;
}

return this.layouts[name].insertPage(pageContent, pageNav, pageIncludedFiles);
return this.layouts[name].insertPage(pageContent, pageNav, new Set<string>(pageIncludedFiles));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we create a new instance of pageIncludedFiles here? Is it to avoid passing by reference?

}

getLayoutPageNjkAssets(name) {
getLayoutPageNjkAssets(name: string) {
if (name === FRONTMATTER_NONE_ATTR || !this.layouts[name]) {
return {};
}

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

module.exports = {
LayoutManager,
};
9 changes: 0 additions & 9 deletions packages/core/src/Layout/index.js

This file was deleted.

4 changes: 4 additions & 0 deletions packages/core/src/Layout/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export { Layout } from './Layout';
export { LayoutManager } from './LayoutManager';
export const LAYOUT_DEFAULT_NAME = 'default.md';
export const LAYOUT_FOLDER_PATH = '_markbind/layouts';
5 changes: 3 additions & 2 deletions 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 @@ -67,7 +68,7 @@ export class PageConfig {
template: Template;
variableProcessor: VariableProcessor;
addressablePagesSource: string[];
layoutManager: any;
layoutManager: LayoutManager;

constructor(args: {
asset: PageAssets;
Expand All @@ -89,7 +90,7 @@ export class PageConfig {
template: Template;
variableProcessor: VariableProcessor;
addressablePagesSource: string[];
layoutManager: any;
layoutManager: LayoutManager;
}) {
this.asset = args.asset;
this.baseUrlMap = args.baseUrlMap;
Expand Down
16 changes: 7 additions & 9 deletions packages/core/src/Page/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,14 @@ import type { SiteConfig } from '../Site/SiteConfig';
import type { FrontMatter } from '../plugins/Plugin';
import type { ExternalManager } from '../External/ExternalManager';
import { MbNode } from '../utils/node';
import { LAYOUT_DEFAULT_NAME } from '../Layout/index';

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

const _ = { cloneDeep, isObject, isArray };

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 @@ -443,7 +440,8 @@ export class Page {
*/
buildPageNav(content: string) {
const isFmPageNavSpecifierValid = this.isPageNavigationSpecifierValid();
const doesLayoutHavePageNav = this.pageConfig.layoutManager.layoutHasPageNav(this.layout);
const doesLayoutHavePageNav = this.layout ? this.pageConfig.layoutManager.layoutHasPageNav(
this.layout) : false;
Comment on lines +443 to +444

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can avoid all of these typing issues with this.layout, and the additions of ?? LAYOUT_DEFAULT_NAME below, by asserting that the layout attribute exists with a ! operator.
You'll need to modify this too (just delete the question mark)

Feel free to trace to verify that this is safe!


if (isFmPageNavSpecifierValid && doesLayoutHavePageNav) {
this.navigableHeadings = {};
Expand Down Expand Up @@ -502,13 +500,13 @@ export class Page {
const pageContent = content;

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

await layoutManager.generateLayoutIfNeeded(this.layout);
await layoutManager.generateLayoutIfNeeded(this.layout ?? LAYOUT_DEFAULT_NAME);
const pageNav = this.buildPageNav(content);
content = layoutManager.combineLayoutWithPage(this.layout, content, pageNav, this.includedFiles);
content = layoutManager.combineLayoutWithPage(this.layout ?? LAYOUT_DEFAULT_NAME,
content, pageNav, this.includedFiles);
this.asset = {
...this.asset,
...layoutManager.getLayoutPageNjkAssets(this.layout),
...layoutManager.getLayoutPageNjkAssets(this.layout ?? LAYOUT_DEFAULT_NAME),
};

pageSources.addAllToSet(this.includedFiles);
Expand Down