kopia lustrzana https://github.com/shoelace-style/shoelace
improvements
rodzic
aa48566aef
commit
8c44eb75d5
|
@ -1,9 +1,7 @@
|
||||||
.DS_Store
|
|
||||||
.cache
|
|
||||||
_site
|
_site
|
||||||
docs/dist
|
.cache
|
||||||
docs/search.json
|
.DS_Store
|
||||||
docs/assets/images/sprite.svg
|
|
||||||
dist
|
dist
|
||||||
|
docs/assets/images/sprite.svg
|
||||||
node_modules
|
node_modules
|
||||||
src/react
|
src/react
|
||||||
|
|
|
@ -26,7 +26,6 @@ module.exports = function (doc, options) {
|
||||||
const adjacentPre = pre.nextElementSibling?.tagName.toLowerCase() === 'pre' ? pre.nextElementSibling : null;
|
const adjacentPre = pre.nextElementSibling?.tagName.toLowerCase() === 'pre' ? pre.nextElementSibling : null;
|
||||||
const reactCode = adjacentPre?.querySelector('code[class$="react"]');
|
const reactCode = adjacentPre?.querySelector('code[class$="react"]');
|
||||||
const sourceGroupId = `code-preview-source-group-${count}`;
|
const sourceGroupId = `code-preview-source-group-${count}`;
|
||||||
const toggleId = `code-preview-toggle-${count}`;
|
|
||||||
const isExpanded = code.getAttribute('class').includes(':expanded');
|
const isExpanded = code.getAttribute('class').includes(':expanded');
|
||||||
const noCodePen = code.getAttribute('class').includes(':no-codepen');
|
const noCodePen = code.getAttribute('class').includes(':no-codepen');
|
||||||
|
|
||||||
|
@ -137,17 +136,3 @@ module.exports = function (doc, options) {
|
||||||
|
|
||||||
return doc;
|
return doc;
|
||||||
};
|
};
|
||||||
|
|
||||||
function getAdjacentExample(name, pre) {
|
|
||||||
let currentPre = pre.nextElementSibling;
|
|
||||||
|
|
||||||
while (currentPre?.tagName.toLowerCase() === 'pre') {
|
|
||||||
if (currentPre?.getAttribute('class').indexOf(name) > -1) {
|
|
||||||
return currentPre;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentPre = currentPre.nextElementSibling;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ module.exports = function (doc, options) {
|
||||||
className: 'external-link', // the class name to add to links
|
className: 'external-link', // the class name to add to links
|
||||||
noopener: true, // sets rel="noopener"
|
noopener: true, // sets rel="noopener"
|
||||||
noreferrer: true, // sets rel="noreferrer"
|
noreferrer: true, // sets rel="noreferrer"
|
||||||
ignore: link => false, // callback function to filter links that should be ignored
|
ignore: () => false, // callback function to filter links that should be ignored
|
||||||
within: 'body', // element that contains the target links
|
within: 'body', // element that contains the target links
|
||||||
target: '', // sets the target attribute
|
target: '', // sets the target attribute
|
||||||
...options
|
...options
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
const smartquotes = require('smartquotes');
|
const smartquotes = require('smartquotes');
|
||||||
|
|
||||||
smartquotes.replacements.push([/\-\-\-/g, '\u2014']); // em dash
|
smartquotes.replacements.push([/---/g, '\u2014']); // em dash
|
||||||
smartquotes.replacements.push([/\-\-/g, '\u2013']); // en dash
|
smartquotes.replacements.push([/--/g, '\u2013']); // en dash
|
||||||
smartquotes.replacements.push([/\.\.\./g, '\u2026']); // ellipsis
|
smartquotes.replacements.push([/\.\.\./g, '\u2026']); // ellipsis
|
||||||
smartquotes.replacements.push([/\(c\)/gi, '\u00A9']); // copyright
|
smartquotes.replacements.push([/\(c\)/gi, '\u00A9']); // copyright
|
||||||
smartquotes.replacements.push([/\(r\)/gi, '\u00AE']); // registered trademark
|
smartquotes.replacements.push([/\(r\)/gi, '\u00AE']); // registered trademark
|
||||||
smartquotes.replacements.push([/\?!/g, '\u2048']); // ?!
|
smartquotes.replacements.push([/\?!/g, '\u2048']); // ?!
|
||||||
smartquotes.replacements.push([/!!/g, '\u203C']); // !!
|
smartquotes.replacements.push([/!!/g, '\u203C']); // !!
|
||||||
smartquotes.replacements.push([/\?\?/g, '\u2047']); // ??
|
smartquotes.replacements.push([/\?\?/g, '\u2047']); // ??
|
||||||
smartquotes.replacements.push([/([0-9]\s?)\-(\s?[0-9])/g, '$1\u2013$2']); // number ranges use en dash
|
smartquotes.replacements.push([/([0-9]\s?)-(\s?[0-9])/g, '$1\u2013$2']); // number ranges use en dash
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Improves typography by adding smart quotes and similar corrections within the specified element(s).
|
* Improves typography by adding smart quotes and similar corrections within the specified element(s).
|
||||||
|
|
|
@ -21,12 +21,6 @@ const assetsDir = 'assets';
|
||||||
const allComponents = getAllComponents();
|
const allComponents = getAllComponents();
|
||||||
let hasBuiltSearchIndex = false;
|
let hasBuiltSearchIndex = false;
|
||||||
|
|
||||||
function benchmark (callback) {
|
|
||||||
const time = performance.now()
|
|
||||||
callback()
|
|
||||||
return performance.now() - time
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = function (eleventyConfig) {
|
module.exports = function (eleventyConfig) {
|
||||||
//
|
//
|
||||||
// Global data
|
// Global data
|
||||||
|
@ -110,19 +104,6 @@ module.exports = function (eleventyConfig) {
|
||||||
//
|
//
|
||||||
// Transforms
|
// Transforms
|
||||||
//
|
//
|
||||||
|
|
||||||
let transformTimers = {
|
|
||||||
activeLinks: 0,
|
|
||||||
anchorHeadings: 0,
|
|
||||||
tableOfContents: 0,
|
|
||||||
codePreviews: 0,
|
|
||||||
externalLinks: 0,
|
|
||||||
highlightCodeBlock: 0,
|
|
||||||
scrollingTables: 0,
|
|
||||||
copyCodeButtons: 0,
|
|
||||||
typography: 0,
|
|
||||||
prettier: 0,
|
|
||||||
}
|
|
||||||
eleventyConfig.addTransform('html-transform', function (content) {
|
eleventyConfig.addTransform('html-transform', function (content) {
|
||||||
// Parse the template and get a Document object
|
// Parse the template and get a Document object
|
||||||
const doc = new JSDOM(content, {
|
const doc = new JSDOM(content, {
|
||||||
|
@ -132,57 +113,28 @@ module.exports = function (eleventyConfig) {
|
||||||
}).window.document;
|
}).window.document;
|
||||||
|
|
||||||
// DOM transforms
|
// DOM transforms
|
||||||
transformTimers.activeLinks += benchmark(() => {
|
activeLinks(doc, { pathname: this.page.url });
|
||||||
activeLinks(doc, { pathname: this.page.url });
|
anchorHeadings(doc, {
|
||||||
})
|
within: '#content .content__body',
|
||||||
|
levels: ['h2', 'h3', 'h4', 'h5']
|
||||||
transformTimers.anchorHeadings += benchmark(() => {
|
});
|
||||||
anchorHeadings(doc, {
|
tableOfContents(doc, {
|
||||||
within: '#content .content__body',
|
levels: ['h2', 'h3'],
|
||||||
levels: ['h2', 'h3', 'h4', 'h5']
|
container: '#content .content__toc > ul',
|
||||||
});
|
within: '#content .content__body'
|
||||||
})
|
});
|
||||||
|
codePreviews(doc);
|
||||||
transformTimers.tableOfContents += benchmark(() => {
|
externalLinks(doc, { target: '_blank' });
|
||||||
tableOfContents(doc, {
|
highlightCodeBlocks(doc);
|
||||||
levels: ['h2', 'h3'],
|
scrollingTables(doc);
|
||||||
container: '#content .content__toc > ul',
|
copyCodeButtons(doc); // must be after codePreviews + highlightCodeBlocks
|
||||||
within: '#content .content__body'
|
typography(doc, '#content');
|
||||||
});
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
transformTimers.codePreviews += benchmark(() => {
|
|
||||||
codePreviews(doc);
|
|
||||||
})
|
|
||||||
|
|
||||||
transformTimers.externalLinks += benchmark(() => {
|
|
||||||
externalLinks(doc, { target: '_blank' });
|
|
||||||
})
|
|
||||||
|
|
||||||
transformTimers.highlightCodeBlock += benchmark(() => {
|
|
||||||
highlightCodeBlocks(doc);
|
|
||||||
})
|
|
||||||
|
|
||||||
transformTimers.scrollingTables += benchmark(() => {
|
|
||||||
scrollingTables(doc);
|
|
||||||
})
|
|
||||||
|
|
||||||
transformTimers.copyCodeButtons += benchmark(() => {
|
|
||||||
copyCodeButtons(doc); // must be after codePreviews + highlightCodeBlocks
|
|
||||||
})
|
|
||||||
|
|
||||||
transformTimers.typography += benchmark(() => {
|
|
||||||
typography(doc, '#content');
|
|
||||||
})
|
|
||||||
|
|
||||||
// Serialize the Document object to an HTML string and prepend the doctype
|
// Serialize the Document object to an HTML string and prepend the doctype
|
||||||
content = `<!DOCTYPE html>\n${doc.documentElement.outerHTML}`;
|
content = `<!DOCTYPE html>\n${doc.documentElement.outerHTML}`;
|
||||||
|
|
||||||
// String transforms
|
// String transforms
|
||||||
transformTimers.prettier += benchmark(() => {
|
content = prettier(content);
|
||||||
content = prettier(content);
|
|
||||||
})
|
|
||||||
|
|
||||||
return content;
|
return content;
|
||||||
});
|
});
|
||||||
|
@ -190,7 +142,7 @@ module.exports = function (eleventyConfig) {
|
||||||
//
|
//
|
||||||
// Build a search index
|
// Build a search index
|
||||||
//
|
//
|
||||||
eleventyConfig.on('eleventy.after', async ({ results }) => {
|
eleventyConfig.on('eleventy.after', ({ results }) => {
|
||||||
// We only want to build the search index on the first run so all pages get indexed.
|
// We only want to build the search index on the first run so all pages get indexed.
|
||||||
if (hasBuiltSearchIndex) {
|
if (hasBuiltSearchIndex) {
|
||||||
return;
|
return;
|
||||||
|
@ -239,13 +191,6 @@ module.exports = function (eleventyConfig) {
|
||||||
fs.writeFileSync(searchIndexFilename, JSON.stringify({ searchIndex, map }), 'utf-8');
|
fs.writeFileSync(searchIndexFilename, JSON.stringify({ searchIndex, map }), 'utf-8');
|
||||||
|
|
||||||
hasBuiltSearchIndex = true;
|
hasBuiltSearchIndex = true;
|
||||||
let totalTime = 0
|
|
||||||
Object.entries(transformTimers).forEach(([k,v]) => {
|
|
||||||
const rounded = Math.ceil(v)
|
|
||||||
console.log(k + ": " + rounded + "ms")
|
|
||||||
totalTime += rounded
|
|
||||||
})
|
|
||||||
console.log("Total transform time: " + totalTime + "ms")
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -254,9 +199,7 @@ module.exports = function (eleventyConfig) {
|
||||||
eleventyConfig.setServerOptions({
|
eleventyConfig.setServerOptions({
|
||||||
domDiff: false, // disable dom diffing so custom elements don't break on reload,
|
domDiff: false, // disable dom diffing so custom elements don't break on reload,
|
||||||
port: 4000, // if port 4000 is taken, 11ty will use the next one available
|
port: 4000, // if port 4000 is taken, 11ty will use the next one available
|
||||||
watch: [
|
watch: ['dist/**/*'] // additional files to watch that will trigger server updates (array of paths or globs)
|
||||||
"dist/**/*.*"
|
|
||||||
] // additional files to watch that will trigger server updates (array of paths or globs)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node scripts/build.js --bundle --serve",
|
"start": "node scripts/build.js --bundle --serve",
|
||||||
"build": "node scripts/build.js --bundle --types --copydir \"docs/dist\"",
|
"build": "node scripts/build.js --bundle --types --copydir \"_site/dist\"",
|
||||||
"verify": "npm run prettier:check && npm run lint && npm run build && npm run test",
|
"verify": "npm run prettier:check && npm run lint && npm run build && npm run test",
|
||||||
"prepublishOnly": "npm run verify",
|
"prepublishOnly": "npm run verify",
|
||||||
"prettier": "prettier --write --loglevel warn .",
|
"prettier": "prettier --write --loglevel warn .",
|
||||||
|
|
153
scripts/build.js
153
scripts/build.js
|
@ -1,23 +1,30 @@
|
||||||
import { spawn, execSync } from 'child_process';
|
|
||||||
import getPort, { portNumbers } from 'get-port';
|
|
||||||
import { globby } from 'globby';
|
|
||||||
import { deleteSync } from 'del';
|
import { deleteSync } from 'del';
|
||||||
|
import { globby } from 'globby';
|
||||||
|
import { execSync, spawn } from 'child_process';
|
||||||
import browserSync from 'browser-sync';
|
import browserSync from 'browser-sync';
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
|
import chokidar from 'chokidar';
|
||||||
import commandLineArgs from 'command-line-args';
|
import commandLineArgs from 'command-line-args';
|
||||||
|
import copy from 'recursive-copy';
|
||||||
import esbuild from 'esbuild';
|
import esbuild from 'esbuild';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import copy from 'recursive-copy';
|
import getPort, { portNumbers } from 'get-port';
|
||||||
|
|
||||||
const abortController = new AbortController();
|
const abortController = new AbortController();
|
||||||
const abortSignal = abortController.signal;
|
const abortSignal = abortController.signal;
|
||||||
|
|
||||||
function buildTheDocs({ watch = false }) {
|
function buildTheDocs(watch = false) {
|
||||||
|
deleteSync('./_site');
|
||||||
|
|
||||||
if (!watch) {
|
if (!watch) {
|
||||||
return execSync('npx @11ty/eleventy', { stdio: 'inherit', cwd: 'docs' });
|
return execSync('npx @11ty/eleventy --quiet', { stdio: 'inherit', cwd: 'docs' });
|
||||||
}
|
}
|
||||||
|
|
||||||
return spawn('npx', ['@11ty/eleventy', '--watch', '--incremental'], { stdio: 'inherit', cwd: 'docs', signal: abortSignal });
|
return spawn('npx', ['@11ty/eleventy', '--watch', '--incremental', '--quiet'], {
|
||||||
|
stdio: 'inherit',
|
||||||
|
cwd: 'docs',
|
||||||
|
signal: abortSignal
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const { bundle, copydir, dir, serve, types } = commandLineArgs([
|
const { bundle, copydir, dir, serve, types } = commandLineArgs([
|
||||||
|
@ -33,7 +40,7 @@ const outdir = dir;
|
||||||
deleteSync(outdir);
|
deleteSync(outdir);
|
||||||
fs.mkdirSync(outdir, { recursive: true });
|
fs.mkdirSync(outdir, { recursive: true });
|
||||||
|
|
||||||
;(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
execSync(`node scripts/make-metadata.js --outdir "${outdir}"`, { stdio: 'inherit' });
|
execSync(`node scripts/make-metadata.js --outdir "${outdir}"`, { stdio: 'inherit' });
|
||||||
execSync(`node scripts/make-react.js --outdir "${outdir}"`, { stdio: 'inherit' });
|
execSync(`node scripts/make-react.js --outdir "${outdir}"`, { stdio: 'inherit' });
|
||||||
|
@ -104,80 +111,84 @@ fs.mkdirSync(outdir, { recursive: true });
|
||||||
copy(outdir, copydir);
|
copy(outdir, copydir);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(chalk.green(`The build has been generated at ${outdir} 📦\n`));
|
|
||||||
|
|
||||||
if (serve) {
|
if (serve) {
|
||||||
// Dev
|
// Build it with --watch and --incremental
|
||||||
buildTheDocs({ watch: true });
|
buildTheDocs(true);
|
||||||
|
|
||||||
const bs = browserSync.create();
|
// Wait for the search index to appear before launching the browser. This file is generated during eleventy.after,
|
||||||
const port = await getPort({
|
// so it's usually the last one to appear.
|
||||||
port: portNumbers(4000, 4999)
|
const watcher = chokidar.watch('./_site', { persistent: true });
|
||||||
});
|
watcher.on('add', async filename => {
|
||||||
|
if (filename.endsWith('search.json')) {
|
||||||
|
watcher.close();
|
||||||
|
|
||||||
const browserSyncConfig = {
|
const bs = browserSync.create();
|
||||||
startPath: '/',
|
const port = await getPort({
|
||||||
port,
|
port: portNumbers(4000, 4999)
|
||||||
logLevel: 'silent',
|
});
|
||||||
logPrefix: '[shoelace]',
|
|
||||||
logFileChanges: true,
|
const browserSyncConfig = {
|
||||||
notify: false,
|
startPath: '/',
|
||||||
single: true,
|
port,
|
||||||
ghostMode: false,
|
logLevel: 'silent',
|
||||||
server: {
|
logPrefix: '[shoelace]',
|
||||||
baseDir: '_site',
|
logFileChanges: true,
|
||||||
routes: {
|
notify: false,
|
||||||
'/dist': './dist'
|
single: true,
|
||||||
}
|
ghostMode: false,
|
||||||
|
server: {
|
||||||
|
baseDir: '_site',
|
||||||
|
routes: {
|
||||||
|
'/dist': './dist'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Launch browser sync
|
||||||
|
bs.init(browserSyncConfig, () => {
|
||||||
|
const url = `http://localhost:${port}`;
|
||||||
|
console.log(chalk.cyan(`Launched the Shoelace dev server at ${url} 🥾\n`));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Rebuild and reload when source files change
|
||||||
|
bs.watch(['src/**/!(*.test).*']).on('change', async filename => {
|
||||||
|
buildResult
|
||||||
|
// Rebuild and reload
|
||||||
|
.rebuild()
|
||||||
|
.then(() => {
|
||||||
|
// Rebuild stylesheets when a theme file changes
|
||||||
|
if (/^src\/themes/.test(filename)) {
|
||||||
|
execSync(`node scripts/make-themes.js --outdir "${outdir}"`, { stdio: 'inherit' });
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
// Skip metadata when styles are changed
|
||||||
|
if (/(\.css|\.styles\.ts)$/.test(filename)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
execSync(`node scripts/make-metadata.js --outdir "${outdir}"`, { stdio: 'inherit' });
|
||||||
|
})
|
||||||
|
.then(() => bs.reload())
|
||||||
|
.catch(err => console.error(chalk.red(err)));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Reload without rebuilding when the docs change
|
||||||
|
bs.watch(['_site/**/*.*']).on('change', () => {
|
||||||
|
bs.reload();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
// Launch browser sync
|
|
||||||
bs.init(browserSyncConfig, () => {
|
|
||||||
const url = `http://localhost:${port}`;
|
|
||||||
console.log(chalk.cyan(`Launched the Shoelace dev server at ${url} 🥾\n`));
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Rebuild and reload when source files change
|
// Prod build
|
||||||
bs.watch(['src/**/!(*.test).*']).on('change', async filename => {
|
if (!serve) {
|
||||||
console.log(`Source file changed - ${filename}`);
|
|
||||||
|
|
||||||
buildResult
|
|
||||||
// Rebuild and reload
|
|
||||||
.rebuild()
|
|
||||||
.then(() => {
|
|
||||||
// Rebuild stylesheets when a theme file changes
|
|
||||||
if (/^src\/themes/.test(filename)) {
|
|
||||||
execSync(`node scripts/make-themes.js --outdir "${outdir}"`, { stdio: 'inherit' });
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
// Skip metadata when styles are changed
|
|
||||||
if (/(\.css|\.styles\.ts)$/.test(filename)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
execSync(`node scripts/make-metadata.js --outdir "${outdir}"`, { stdio: 'inherit' });
|
|
||||||
})
|
|
||||||
.then(() => bs.reload())
|
|
||||||
.catch(err => console.error(chalk.red(err)));
|
|
||||||
});
|
|
||||||
|
|
||||||
// Reload without rebuilding when the docs change
|
|
||||||
bs.watch(['_site/**/*.*']).on('change', async (filename) => {
|
|
||||||
console.log(`File changed - ${filename}`);
|
|
||||||
|
|
||||||
// TODO: I tried writing a debounce here, but it wasnt working -.-
|
|
||||||
bs.reload()
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Prod build
|
|
||||||
buildTheDocs();
|
buildTheDocs();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cleanup on exit
|
// Cleanup on exit
|
||||||
process.on('SIGTERM', () => {
|
process.on('SIGTERM', () => {
|
||||||
buildResult.rebuild.dispose()
|
buildResult.rebuild.dispose();
|
||||||
abortController.abort(); // Stops the child process
|
abortController.abort(); // Stops the child process
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -1,109 +0,0 @@
|
||||||
import commandLineArgs from 'command-line-args';
|
|
||||||
import fs from 'fs';
|
|
||||||
import path from 'path';
|
|
||||||
import { globby } from 'globby';
|
|
||||||
import lunr from 'lunr';
|
|
||||||
import { getAllComponents } from './shared.js';
|
|
||||||
|
|
||||||
const { outdir } = commandLineArgs({ name: 'outdir', type: String });
|
|
||||||
const metadata = JSON.parse(fs.readFileSync(path.join(outdir, 'custom-elements.json'), 'utf8'));
|
|
||||||
|
|
||||||
console.log('Generating search index for documentation');
|
|
||||||
|
|
||||||
;(async () => {
|
|
||||||
function getHeadings(markdown, maxLevel = 6) {
|
|
||||||
const headings = [];
|
|
||||||
const lines = markdown.split('\n');
|
|
||||||
|
|
||||||
lines.forEach(line => {
|
|
||||||
if (line.startsWith('#')) {
|
|
||||||
const level = line.match(/^(#+)/)[0].length;
|
|
||||||
const content = line.replace(/^#+/, '');
|
|
||||||
|
|
||||||
if (level <= maxLevel) {
|
|
||||||
headings.push({ level, content });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return headings;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getMembers(markdown) {
|
|
||||||
const members = [];
|
|
||||||
const headers = markdown.match(/\[component-header:([a-z-]+)\]/g);
|
|
||||||
|
|
||||||
if (!headers) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
headers.forEach(header => {
|
|
||||||
const tagName = header.match(/\[component-header:([a-z-]+)\]/)[1];
|
|
||||||
const component = getAllComponents(metadata).find(component => component.tagName === tagName);
|
|
||||||
|
|
||||||
if (component) {
|
|
||||||
const fields = ['members', 'cssProperties', 'cssParts', 'slots', 'events'];
|
|
||||||
|
|
||||||
fields.forEach(field => {
|
|
||||||
if (component[field]) {
|
|
||||||
component[field].forEach(entry => {
|
|
||||||
if (entry.name) members.push(entry.name);
|
|
||||||
if (entry.description) members.push(entry.description);
|
|
||||||
if (entry.attribute) members.push(entry.attribute);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return members.join(' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
const files = await globby('./docs/**/*.md');
|
|
||||||
const map = {};
|
|
||||||
const searchIndex = lunr(function () {
|
|
||||||
// The search index uses these field names extensively, so shortening them can save some serious bytes. The initial
|
|
||||||
// index file went from 468 KB => 401 KB by using single-character names!
|
|
||||||
this.ref('id'); // id
|
|
||||||
this.field('t', { boost: 10 }); // title
|
|
||||||
this.field('h', { boost: 5 }); // headings
|
|
||||||
this.field('m', { boost: 2 }); // members (props, methods, events, etc.)
|
|
||||||
this.field('c'); // content
|
|
||||||
|
|
||||||
files.forEach((file, index) => {
|
|
||||||
const relativePath = path.relative('./docs', file).replace(/\\/g, '/');
|
|
||||||
const relativePathNoExtension = relativePath.split('.').slice(0, -1).join('.');
|
|
||||||
const url = relativePath.replace(/\.md$/, '');
|
|
||||||
const filename = path.basename(file);
|
|
||||||
// Ignore certain directories and files
|
|
||||||
if (
|
|
||||||
relativePath.startsWith('assets/') ||
|
|
||||||
relativePath.startsWith('dist/') ||
|
|
||||||
filename === '_sidebar.md' ||
|
|
||||||
filename === '404.md'
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const content = fs.readFileSync(file, 'utf8');
|
|
||||||
const allHeadings = getHeadings(content, 4);
|
|
||||||
const title = allHeadings.find(heading => heading.level === 1)?.content || '';
|
|
||||||
const headings = allHeadings
|
|
||||||
.filter(heading => heading.level > 1)
|
|
||||||
.map(heading => heading.content)
|
|
||||||
.concat([relativePathNoExtension])
|
|
||||||
.join(' ');
|
|
||||||
const members = getMembers(content);
|
|
||||||
|
|
||||||
// Remove markdown code fields from search results. This seems to make search results a bit more accurate and
|
|
||||||
// reduces search.json from ~679 KB to ~455 KB.
|
|
||||||
const prunedContent = content.replace(/```(.*?)```/gs, '');
|
|
||||||
|
|
||||||
this.add({ id: index, t: title, h: headings, m: members, c: prunedContent });
|
|
||||||
|
|
||||||
map[index] = { title, url };
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
fs.writeFileSync('./docs/search.json', JSON.stringify({ searchIndex, map }), 'utf8');
|
|
||||||
})();
|
|
Ładowanie…
Reference in New Issue