Convert 6 JavaScript files to TypeScript (#57975)
This commit is contained in:
@@ -6,7 +6,7 @@ import { EOL } from 'os'
|
||||
|
||||
// Use platform-specific line endings for realistic tests when templates have
|
||||
// been loaded from disk
|
||||
const nl = (str) => str.replace(/\n/g, EOL)
|
||||
const nl = (str: string): string => str.replace(/\n/g, EOL)
|
||||
|
||||
describe('renderContent', () => {
|
||||
test('takes a template and a context and returns a string (async)', async () => {
|
||||
@@ -44,7 +44,7 @@ describe('renderContent', () => {
|
||||
|
||||
const html = await renderContent(template)
|
||||
const $ = cheerio.load(html, { xmlMode: true })
|
||||
expect($('ul p').length, 0)
|
||||
expect($('ul p').length).toBe(0)
|
||||
})
|
||||
|
||||
test('renders text only', async () => {
|
||||
@@ -35,10 +35,35 @@ import { visit } from 'unist-util-visit'
|
||||
import { h } from 'hastscript'
|
||||
import { fromMarkdown } from 'mdast-util-from-markdown'
|
||||
import { toHast } from 'mdast-util-to-hast'
|
||||
import type { Root } from 'mdast'
|
||||
import { header } from './code-header'
|
||||
import findPage from '@/frame/lib/find-page'
|
||||
|
||||
const languages = yaml.load(fs.readFileSync('./data/code-languages.yml', 'utf8'))
|
||||
interface LanguageConfig {
|
||||
comment: 'number' | 'slash' | 'xml' | 'percent' | 'hyphen'
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
interface ElementNode {
|
||||
type: 'element'
|
||||
tagName: string
|
||||
properties: {
|
||||
className?: string[]
|
||||
[key: string]: any
|
||||
}
|
||||
children: any[]
|
||||
data?: {
|
||||
meta?: {
|
||||
annotate?: boolean
|
||||
[key: string]: any
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const languages = yaml.load(fs.readFileSync('./data/code-languages.yml', 'utf8')) as Record<
|
||||
string,
|
||||
LanguageConfig
|
||||
>
|
||||
|
||||
const commentRegexes = {
|
||||
// Also known has hash or sharp; but the unicode name is "number sign".
|
||||
@@ -64,18 +89,25 @@ const commentRegexes = {
|
||||
hyphen: /^\s*--\s*/,
|
||||
}
|
||||
|
||||
const matcher = (node) =>
|
||||
node.type === 'element' && node.tagName === 'pre' && getPreMeta(node).annotate
|
||||
// Using 'any' for node because unist-util-visit requires broad type compatibility
|
||||
const matcher = (node: any): node is ElementNode =>
|
||||
node.type === 'element' && node.tagName === 'pre' && Boolean(getPreMeta(node).annotate)
|
||||
|
||||
export default function annotate(context) {
|
||||
return (tree) => {
|
||||
visit(tree, matcher, (node, index, parent) => {
|
||||
parent.children[index] = createAnnotatedNode(node, context)
|
||||
// Using 'any' for context because unified plugins receive different context types depending on processor configuration
|
||||
export default function annotate(context: any) {
|
||||
// Using 'any' for tree because unified's AST types are complex and vary between processors
|
||||
return (tree: any) => {
|
||||
// Using 'any' for parent because unist-util-visit's callback typing doesn't provide specific parent types
|
||||
visit(tree, matcher, (node: ElementNode, index: number | undefined, parent: any) => {
|
||||
if (index !== undefined && parent) {
|
||||
parent.children[index] = createAnnotatedNode(node, context)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function createAnnotatedNode(node, context) {
|
||||
// Using 'any' for context to match the plugin signature, and return type because hastscript returns complex hast types
|
||||
function createAnnotatedNode(node: ElementNode, context: any): any {
|
||||
const lang = node.children[0].properties.className[0].replace('language-', '')
|
||||
const code = node.children[0].children[0].value
|
||||
|
||||
@@ -102,7 +134,7 @@ function createAnnotatedNode(node, context) {
|
||||
return template({ lang, code, rows, context })
|
||||
}
|
||||
|
||||
function validate(lang, code) {
|
||||
function validate(lang: string, code: string): void {
|
||||
if (!lang) {
|
||||
throw new Error('No language specific for annotate info string.')
|
||||
}
|
||||
@@ -128,33 +160,34 @@ function validate(lang, code) {
|
||||
}
|
||||
}
|
||||
|
||||
function getRegexp(lang) {
|
||||
function getRegexp(lang: string): RegExp {
|
||||
return commentRegexes[languages[lang].comment]
|
||||
}
|
||||
|
||||
function hasChar(line) {
|
||||
function hasChar(line: string): boolean {
|
||||
return Boolean(line.trim())
|
||||
}
|
||||
|
||||
function chunkBy(arr, predicate) {
|
||||
const groups = [[]]
|
||||
function chunkBy(arr: string[], predicate: (item: string) => boolean): string[][] {
|
||||
const groups: string[][] = [[]]
|
||||
let on = predicate(arr[0])
|
||||
for (const item of arr) {
|
||||
if ((!on && predicate(item)) || (on && !predicate(item))) {
|
||||
on = !on
|
||||
groups.push([])
|
||||
}
|
||||
last(groups).push(item)
|
||||
last(groups)!.push(item)
|
||||
}
|
||||
return groups
|
||||
}
|
||||
|
||||
function matchComment(lang) {
|
||||
function matchComment(lang: string): (line: string) => boolean {
|
||||
const regex = getRegexp(lang)
|
||||
return (line) => regex.test(line)
|
||||
}
|
||||
|
||||
function getSubnav() {
|
||||
// Using 'any' return type because hastscript's h() function returns complex hast element types
|
||||
function getSubnav(): any {
|
||||
const besideBtn = h(
|
||||
'button',
|
||||
{
|
||||
@@ -179,7 +212,18 @@ function getSubnav() {
|
||||
return h('div', { className: 'annotate-toggle' }, [besideBtn, inlineBtn])
|
||||
}
|
||||
|
||||
function template({ lang, code, rows, context }) {
|
||||
// Using 'any' for context and return type due to hastscript's complex type definitions
|
||||
function template({
|
||||
lang,
|
||||
code,
|
||||
rows,
|
||||
context,
|
||||
}: {
|
||||
lang: string
|
||||
code: string
|
||||
rows: string[][][]
|
||||
context: any
|
||||
}): any {
|
||||
return h(
|
||||
'div',
|
||||
{ class: 'annotate beside' },
|
||||
@@ -210,20 +254,20 @@ function template({ lang, code, rows, context }) {
|
||||
)
|
||||
}
|
||||
|
||||
function mdToHast(text, context) {
|
||||
const mdast = fromMarkdown(text)
|
||||
// Using 'any' for context and return type to maintain compatibility with mdast-util-to-hast complex types
|
||||
function mdToHast(text: string, context: any): any {
|
||||
const mdast: Root = fromMarkdown(text)
|
||||
|
||||
// Process AUTOTITLE links if context is available
|
||||
if (context) {
|
||||
processAutotitleInMdast(mdast, context)
|
||||
}
|
||||
// Process AUTOTITLE links
|
||||
processAutotitleInMdast(mdast, context)
|
||||
|
||||
return toHast(mdast)
|
||||
}
|
||||
|
||||
// Helper method to process AUTOTITLE links in MDAST
|
||||
// This can be reused for other MDAST processing that needs AUTOTITLE support
|
||||
function processAutotitleInMdast(mdast, context) {
|
||||
// Using 'any' for context because it may or may not have pages/redirects properties depending on usage
|
||||
function processAutotitleInMdast(mdast: Root, context: any): void {
|
||||
visit(mdast, 'link', (node) => {
|
||||
if (node.url && node.url.startsWith('/')) {
|
||||
for (const child of node.children) {
|
||||
@@ -236,7 +280,10 @@ function processAutotitleInMdast(mdast, context) {
|
||||
child.value = page.rawTitle || 'AUTOTITLE'
|
||||
} catch (error) {
|
||||
// Keep AUTOTITLE if we can't get the title
|
||||
console.warn(`Could not resolve AUTOTITLE for ${node.url}:`, error.message)
|
||||
console.warn(
|
||||
`Could not resolve AUTOTITLE for ${node.url}:`,
|
||||
error instanceof Error ? error.message : String(error),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -245,12 +292,12 @@ function processAutotitleInMdast(mdast, context) {
|
||||
})
|
||||
}
|
||||
|
||||
function removeComment(lang) {
|
||||
function removeComment(lang: string): (line: string) => string {
|
||||
const regex = getRegexp(lang)
|
||||
return (line) => line.replace(regex, '')
|
||||
}
|
||||
|
||||
function getPreMeta(node) {
|
||||
function getPreMeta(node: ElementNode): { annotate?: boolean; [key: string]: any } {
|
||||
// Here's why this monstrosity works:
|
||||
// https://github.com/syntax-tree/mdast-util-to-hast/blob/c87cd606731c88a27dbce4bfeaab913a9589bf83/lib/handlers/code.js#L40-L42
|
||||
return node.children[0]?.data?.meta || {}
|
||||
Reference in New Issue
Block a user