diff --git a/ui/analyse/src/ctrl.ts b/ui/analyse/src/ctrl.ts index a9f2d4d415..f4f4d34c43 100644 --- a/ui/analyse/src/ctrl.ts +++ b/ui/analyse/src/ctrl.ts @@ -42,7 +42,7 @@ import { AnaMove, StudyCtrl } from './study/interfaces'; import { StudyPracticeCtrl } from './study/practice/interfaces'; import { valid as crazyValid } from './crazy/crazyCtrl'; import { PromotionCtrl } from 'chess/promotion'; -import { WikiTheory } from './wiki'; +import wikiTheory, { WikiTheory } from './wiki'; export default class AnalyseCtrl { data: AnalyseData; @@ -124,7 +124,7 @@ export default class AnalyseCtrl { this.promotion = new PromotionCtrl(this.withCg, () => this.withCg(g => g.set(this.cgConfig)), this.redraw); if (this.data.forecast) this.forecast = makeForecast(this.data.forecast, this.data, redraw); - if (this.opts.wiki) this.wiki = new WikiTheory(); + if (this.opts.wiki) this.wiki = wikiTheory(); if (lichess.AnalyseNVUI) this.nvui = lichess.AnalyseNVUI(redraw) as NvuiPlugin; @@ -214,7 +214,7 @@ export default class AnalyseCtrl { this.onMainline = this.tree.pathIsMainline(path); this.fenInput = undefined; this.pgnInput = undefined; - this.wiki?.update(this.nodeList); + if (this.wiki) this.wiki(this.nodeList); }; flip = () => { diff --git a/ui/analyse/src/wiki.ts b/ui/analyse/src/wiki.ts index 49ef0c22bf..ed1ebc8094 100644 --- a/ui/analyse/src/wiki.ts +++ b/ui/analyse/src/wiki.ts @@ -1,25 +1,48 @@ import debounce from 'common/debounce'; -export class WikiTheory { - update = debounce( +export type WikiTheory = (nodes: Tree.Node[]) => void; + +export default function wikiTheory(): WikiTheory { + const cache = new Map(); + const show = (html: string) => $('.analyse__wiki').html(html); + + const plyPrefix = (node: Tree.Node) => `${Math.floor((node.ply + 1) / 2)}${node.ply % 2 === 1 ? '._' : '...'}`; + + const wikiBooksUrl = 'https://en.wikibooks.org'; + const apiArgs = 'origin=*&action=query&prop=extracts&formatversion=2&format=json&exchars=1200'; + + const removeEmptyParagraph = (html: string) => html.replace(/

(
|\s)*<\/p>/g, ''); + + const removeTableHeader = (html: string) => html.replace('

Theory table

', ''); + const removeTableExpl = (html: string) => + html.replace(/For explanation of theory tables see theory table and for notation see algebraic notation.?/, ''); + const removeContributing = (html: string) => + html.replace('When contributing to this Wikibook, please follow the Conventions for organization.', ''); + + const readMore = (title: string) => + `

Read more on WikiBooks

`; + + const transform = (html: string, title: string) => + removeEmptyParagraph(removeTableHeader(removeTableExpl(removeContributing(html)))) + readMore(title); + + return debounce( async (nodes: Tree.Node[]) => { - const pathParts = nodes.slice(1).map(n => `${this.plyPrefix(n)}${n.san}`); + const pathParts = nodes.slice(1).map(n => `${plyPrefix(n)}${n.san}`); const path = pathParts.join('/'); - if (!path) this.show(''); - else if (this.cache.has(path)) this.show(this.cache.get(path)!); + if (!path) show(''); + else if (cache.has(path)) show(cache.get(path)!); else if ( Array.from({ length: pathParts.length }, (_, i) => -i - 1) .map(i => pathParts.slice(0, i).join('/')) - .some(sub => this.cache.has(sub) && !this.cache.get(sub)!.length) + .some(sub => cache.has(sub) && !cache.get(sub)!.length) ) - this.show(''); + show(''); else { const title = `Chess_Opening_Theory/${path}`; - const url = `${wikiBooksUrl}/w/api.php?titles=${title}&${this.urlArgs}`; - const res = await fetch(url); + const res = await fetch(`${wikiBooksUrl}/w/api.php?titles=${title}&${apiArgs}`); const saveAndShow = (html: string) => { - this.cache.set(path, html); - this.show(html); + cache.set(path, html); + show(html); }; if (res.ok) { const json = await res.json(); @@ -31,25 +54,4 @@ export class WikiTheory { 500, true ); - private cache = new Map(); - private urlArgs = 'origin=*&action=query&prop=extracts&formatversion=2&format=json&exchars=1200'; - private plyPrefix = (node: Tree.Node) => `${Math.floor((node.ply + 1) / 2)}${node.ply % 2 === 1 ? '._' : '...'}`; - private el = $('.analyse__wiki'); - private show = (html: string) => this.el.html(html); } - -const wikiBooksUrl = 'https://en.wikibooks.org'; - -const transform = (html: string, title: string) => - removeEmptyParagraph(removeTableHeader(removeTableExpl(removeContributing(html)))) + readMore(title); - -const removeEmptyParagraph = (html: string) => html.replace(/

(
|\s)*<\/p>/g, ''); - -const removeTableHeader = (html: string) => html.replace('

Theory table

', ''); -const removeTableExpl = (html: string) => - html.replace(/For explanation of theory tables see theory table and for notation see algebraic notation.?/, ''); -const removeContributing = (html: string) => - html.replace('When contributing to this Wikibook, please follow the Conventions for organization.', ''); - -const readMore = (title: string) => - `

Read more on WikiBooks

`;