@@ -233,41 +233,43 @@ export async function getTermsMap(version?: WcagVersion) {
233
233
234
234
// Version-specific APIs
235
235
236
- const remoteGuidelines$ : Partial < Record < WcagVersion , CheerioAPI > > = { } ;
236
+ const guidelinesCache : Partial < Record < WcagVersion , string > > = { } ;
237
237
238
238
/** Loads guidelines from TR space for specific version, caching for future calls. */
239
- const loadRemoteGuidelines = async ( version : WcagVersion ) => {
240
- if ( ! remoteGuidelines$ [ version ] ) {
241
- const $ = load (
242
- ( await axios . get ( `https://www.w3.org/TR/WCAG${ version } /` , { responseType : "text" } ) ) . data
243
- ) ;
244
-
245
- // Re-collapse definition links and notes, to be processed by this build system
246
- $ ( "a.internalDFN" ) . removeAttr ( "class data-link-type id href title" ) ;
247
- $ ( "[role='note'] .marker" ) . remove ( ) ;
248
- $ ( "[role='note']" ) . find ( "> div, > p" ) . addClass ( "note" ) . unwrap ( ) ;
249
-
250
- // Un-process bibliography references, to be processed by CustomLiquid
251
- $ ( "cite:has(a.bibref:only-child)" ) . each ( ( _ , el ) => {
252
- const $el = $ ( el ) ;
253
- $el . replaceWith ( `[${ $el . find ( "a.bibref" ) . html ( ) } ]` ) ;
254
- } ) ;
239
+ const loadRemoteGuidelines = async ( version : WcagVersion , stripRespec = true ) => {
240
+ const html =
241
+ guidelinesCache [ version ] ||
242
+ ( guidelinesCache [ version ] = (
243
+ await axios . get ( `https://www.w3.org/TR/WCAG${ version } /` , { responseType : "text" } )
244
+ ) . data ) ;
245
+
246
+ const $ = load ( html ) ;
247
+ if ( ! stripRespec ) return $ ;
248
+
249
+ // Re-collapse definition links and notes, to be processed by this build system
250
+ $ ( "a.internalDFN" ) . removeAttr ( "class data-link-type id href title" ) ;
251
+ $ ( "[role='note'] .marker" ) . remove ( ) ;
252
+ $ ( "[role='note']" ) . find ( "> div, > p" ) . addClass ( "note" ) . unwrap ( ) ;
253
+
254
+ // Un-process bibliography references, to be processed by CustomLiquid
255
+ $ ( "cite:has(a.bibref:only-child)" ) . each ( ( _ , el ) => {
256
+ const $el = $ ( el ) ;
257
+ $el . replaceWith ( `[${ $el . find ( "a.bibref" ) . html ( ) } ]` ) ;
258
+ } ) ;
255
259
256
- // Remove generated IDs and markers from examples
257
- $ ( ".example[id]" ) . removeAttr ( "id" ) ;
258
- $ ( ".example .marker:has(.self-link)" ) . remove ( ) ;
260
+ // Remove generated IDs and markers from examples
261
+ $ ( ".example[id]" ) . removeAttr ( "id" ) ;
262
+ $ ( ".example .marker:has(.self-link)" ) . remove ( ) ;
259
263
260
- // Remove extra markup from headings so they can be parsed for names
261
- $ ( "bdi" ) . remove ( ) ;
264
+ // Remove extra markup from headings so they can be parsed for names
265
+ $ ( "bdi" ) . remove ( ) ;
262
266
263
- // Remove abbr elements which exist only in TR, not in informative docs
264
- $ ( "#acknowledgements li abbr, #glossary abbr" ) . each ( ( _ , abbrEl ) => {
265
- $ ( abbrEl ) . replaceWith ( $ ( abbrEl ) . text ( ) ) ;
266
- } ) ;
267
+ // Remove abbr elements which exist only in TR, not in informative docs
268
+ $ ( "#acknowledgements li abbr, #glossary abbr" ) . each ( ( _ , abbrEl ) => {
269
+ $ ( abbrEl ) . replaceWith ( $ ( abbrEl ) . text ( ) ) ;
270
+ } ) ;
267
271
268
- remoteGuidelines$ [ version ] = $ ;
269
- }
270
- return remoteGuidelines$ [ version ] ! ;
272
+ return $ ;
271
273
} ;
272
274
273
275
/**
@@ -294,20 +296,35 @@ export const getPrinciplesForVersion = async (version: WcagVersion) =>
294
296
/** Parses errata items from the errata document for the specified WCAG version. */
295
297
export const getErrataForVersion = async ( version : WcagVersion ) => {
296
298
const $ = await loadFromFile ( join ( "errata" , `${ version } .html` ) ) ;
297
- const aSelector = `a[href^='https://www.w3.org/TR/WCAG${ version } /#']` ;
299
+ const $guidelines = await loadRemoteGuidelines ( version , false ) ;
300
+ const aSelector = `a[href*='#']:first-of-type` ;
298
301
const errata : Record < string , string [ ] > = { } ;
299
302
300
- $ ( `li:has(${ aSelector } )` ) . each ( ( _ , el ) => {
301
- const $el = $ ( el ) ;
302
- const $aEl = $el . find ( aSelector ) ;
303
- const hash = new URL ( $aEl . attr ( "href" ) ! ) . hash . slice ( 1 ) ;
304
- const erratumHtml = $el
305
- . html ( ) !
306
- . replace ( / ^ .* ?< \/ a > , ? \s * / g, "" )
307
- . replace ( / ^ ( \w ) / , ( _ , p1 ) => p1 . toUpperCase ( ) ) ;
308
- if ( hash in errata ) errata [ hash ] . push ( erratumHtml ) ;
309
- else errata [ hash ] = [ erratumHtml ] ;
310
- } ) ;
303
+ $ ( "main > section[id]" )
304
+ . last ( )
305
+ . find ( `li:has(${ aSelector } )` )
306
+ . each ( ( _ , el ) => {
307
+ const $el = $ ( el ) ;
308
+ const $aEl = $el . find ( aSelector ) ;
309
+ let hash : string | undefined = $aEl . attr ( "href" ) ! . replace ( / ^ .* # / , "" ) ;
310
+
311
+ // Check whether hash pertains to a guideline/SC section or term definition;
312
+ // if it doesn't, attempt to resolve it to one
313
+ const $hashEl = $guidelines ( `#${ hash } ` ) ;
314
+ if ( ! $hashEl . is ( "section.guideline, #terms dfn" ) ) {
315
+ const $closest = $hashEl . closest ( "#terms dd, section.guideline" ) ;
316
+ if ( $closest . is ( "#terms dd" ) ) hash = $closest . prev ( ) . find ( "dfn[id]" ) . attr ( "id" ) ;
317
+ else hash = $closest . attr ( "id" ) ;
318
+ }
319
+ if ( ! hash ) return ;
320
+
321
+ const erratumHtml = $el
322
+ . html ( ) !
323
+ . replace ( / ^ .* ?< \/ a > , ? \s * / g, "" )
324
+ . replace ( / ^ ( \w ) / , ( _ , p1 ) => p1 . toUpperCase ( ) ) ;
325
+ if ( hash in errata ) errata [ hash ] . push ( erratumHtml ) ;
326
+ else errata [ hash ] = [ erratumHtml ] ;
327
+ } ) ;
311
328
312
329
return errata ;
313
330
} ;
0 commit comments