bestax-migrate 2.29.0 → 2.29.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -23,7 +23,10 @@
23
23
  * passes through as written (`class` aside);
24
24
  * - an `on…` attribute is code React can't run from a string, and a name
25
25
  * JSX can't spell (`@click`, `x-on:click`) can't be written at all; both
26
- * are handed back to the caller instead of emitted.
26
+ * are handed back to the caller instead of emitted;
27
+ * - an attribute HTML gives the element no meaning for, which the browser
28
+ * ignores and React's types reject there (`type` on a `<textarea>`), is
29
+ * handed back too (`IGNORED`).
27
30
  */
28
31
  import { type Element } from './parse.js';
29
32
  export type PropValue = true | string | {
@@ -44,16 +47,20 @@ export interface Prop {
44
47
  * Something the converter can't carry over as written, for the caller to
45
48
  * report. Emitted: `unknown-attribute`, `javascript-url`, `style-important`
46
49
  * (without its priority), and the element kinds. Not emitted:
47
- * `attribute-name`, `event-handler`, `style` (the one declaration it
48
- * quotes), `element-name` (its children are), and a `conditional-comment`.
50
+ * `attribute-name`, `ignored-attribute`, `event-handler`, `style` (the one
51
+ * declaration it quotes), `element-name` (its children are), and a
52
+ * `conditional-comment`.
49
53
  */
50
54
  export interface HtmlIssue {
51
- kind: 'attribute-name' | 'event-handler' | 'unknown-attribute' | 'javascript-url' | 'style' | 'style-important' | 'custom-element' | 'obsolete-element' | 'unknown-element' | 'template' | 'element-name' | 'conditional-comment';
55
+ kind: 'attribute-name' | 'ignored-attribute' | 'event-handler' | 'unknown-attribute' | 'javascript-url' | 'style' | 'style-important' | 'custom-element' | 'obsolete-element' | 'unknown-element' | 'template' | 'element-name' | 'conditional-comment';
52
56
  /** The attribute, tag or CSS property it is about, as written. */
53
57
  token: string;
54
58
  /** The attribute it is on, for its line. */
55
59
  attribute?: string;
56
- /** What a report quotes: a handler's code, a style, a declaration. */
60
+ /**
61
+ * What a report quotes: a handler's code, a style, a declaration, the tag
62
+ * an ignored attribute was on.
63
+ */
57
64
  detail?: string;
58
65
  /** For an `event-handler`, the React prop that takes a function. */
59
66
  prop?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"attributes.d.ts","sourceRoot":"","sources":["../../../../src/sources/_shared/html/attributes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,EAAqB,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AAI7D,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/D,MAAM,WAAW,IAAI;IACnB,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,CAAC;IACjB;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,EACA,gBAAgB,GAChB,eAAe,GACf,mBAAmB,GACnB,gBAAgB,GAChB,OAAO,GACP,iBAAiB,GACjB,gBAAgB,GAChB,kBAAkB,GAClB,iBAAiB,GACjB,UAAU,GACV,cAAc,GACd,qBAAqB,CAAC;IAC1B,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAKD;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,MAAM,CAwD5C,CAAC;AAuCH;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAMzD;AA8DD,kEAAkE;AAClE,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAK5C;AAED,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG;IACnD,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,MAAM,EAAE,SAAS,EAAE,CAAC;CACrB,CAiGA;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,KAAK,GAAE,MAAM,GAAG,KAAc,GAC7B,OAAO,CAET;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI1D"}
1
+ {"version":3,"file":"attributes.d.ts","sourceRoot":"","sources":["../../../../src/sources/_shared/html/attributes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAGH,OAAO,EAAqB,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AAI7D,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/D,MAAM,WAAW,IAAI;IACnB,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,CAAC;IACjB;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,EACA,gBAAgB,GAChB,mBAAmB,GACnB,eAAe,GACf,mBAAmB,GACnB,gBAAgB,GAChB,OAAO,GACP,iBAAiB,GACjB,gBAAgB,GAChB,kBAAkB,GAClB,iBAAiB,GACjB,UAAU,GACV,cAAc,GACd,qBAAqB,CAAC;IAC1B,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAMD;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,MAAM,CAwD5C,CAAC;AA+CH;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAMzD;AA8DD,kEAAkE;AAClE,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAK5C;AAED,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG;IACnD,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,MAAM,EAAE,SAAS,EAAE,CAAC;CACrB,CA8GA;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,KAAK,GAAE,MAAM,GAAG,KAAc,GAC7B,OAAO,CAET;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI1D"}
@@ -23,12 +23,16 @@
23
23
  * passes through as written (`class` aside);
24
24
  * - an `on…` attribute is code React can't run from a string, and a name
25
25
  * JSX can't spell (`@click`, `x-on:click`) can't be written at all; both
26
- * are handed back to the caller instead of emitted.
26
+ * are handed back to the caller instead of emitted;
27
+ * - an attribute HTML gives the element no meaning for, which the browser
28
+ * ignores and React's types reject there (`type` on a `<textarea>`), is
29
+ * handed back too (`IGNORED`).
27
30
  */
28
31
  import { find, hastToReact, html, svg } from 'property-information';
29
32
  import { isElement, isText } from './parse.js';
30
33
  import { styleObject } from './style.js';
31
34
  import { attributeValue, jsString } from './text.js';
35
+ const HTML = 'http://www.w3.org/1999/xhtml';
32
36
  const SVG = 'http://www.w3.org/2000/svg';
33
37
  const MATHML = 'http://www.w3.org/1998/Math/MathML';
34
38
  /**
@@ -106,6 +110,13 @@ const VALUE_NOT_TYPED = new Set([
106
110
  'reset',
107
111
  'submit',
108
112
  ]);
113
+ /**
114
+ * Attributes HTML gives these elements no meaning for, by tag: the browser
115
+ * ignores them, and React's types reject them there, so they are left out.
116
+ */
117
+ const IGNORED = {
118
+ textarea: new Set(['type']),
119
+ };
109
120
  /** What JSX can write as an attribute name (no namespace, no symbols). */
110
121
  const JSX_NAME = /^[A-Za-z_$][\w$-]*$/;
111
122
  /**
@@ -244,6 +255,17 @@ export function convertAttributes(element) {
244
255
  add(attribute === 'class' ? 'className' : attribute, value, attribute);
245
256
  continue;
246
257
  }
258
+ if (element.namespaceURI === HTML &&
259
+ Object.hasOwn(IGNORED, tag) &&
260
+ IGNORED[tag].has(attribute.toLowerCase())) {
261
+ issues.push({
262
+ kind: 'ignored-attribute',
263
+ token: attribute,
264
+ attribute,
265
+ detail: tag,
266
+ });
267
+ continue;
268
+ }
247
269
  if (tag === 'option' && attribute === 'selected' && selectOf(element)) {
248
270
  continue; // The select carries it, as its `defaultValue`.
249
271
  }
@@ -6,11 +6,13 @@
6
6
  * Every conversion this table allows must render exactly the HTML the raw
7
7
  * element rendered. That is a claim about bestax, and the render tests hold
8
8
  * it: each root, modifier and helper here is rendered through the built
9
- * library and compared with the raw markup it replaces. One exception, on
10
- * purpose: Font Awesome's own `<i aria-hidden="true">` alone in a `.icon`
9
+ * library and compared with the raw markup it replaces. The exceptions are
10
+ * on purpose. Font Awesome's own `<i aria-hidden="true">` alone in a `.icon`
11
11
  * that carries nothing assistive tech reads converts to `Icon`, which writes
12
12
  * the attribute on the `.icon` instead, since the glyph is hidden either way
13
- * (see `readsGlyph`).
13
+ * (see `readsGlyph`). And a Bulma 0.9 helper v1 removed, which styles
14
+ * nothing under v1, converts as the v1 helper that does its job (see
15
+ * `REPLACED_IN_V1`).
14
16
  *
15
17
  * Data only: `scripts/gen-mcp-index.mjs` imports it directly for the MCP
16
18
  * server's `lookup_bulma_classes`, so nothing Node cannot strip (no enums, no
@@ -301,8 +303,8 @@ export interface RootEntry {
301
303
  * else, the target renders its children as given. An `<i>` that carries
302
304
  * the `aria-hidden` the target writes, as Font Awesome's own markup does,
303
305
  * reads too when the element carries nothing assistive tech reads: the
304
- * attribute moves up onto it, the one difference in markup a conversion
305
- * makes.
306
+ * attribute moves up onto it, a difference in markup a conversion makes
307
+ * on purpose.
306
308
  */
307
309
  readonly readsGlyph?: ReadsGlyph;
308
310
  /**
@@ -349,6 +351,12 @@ export interface RootEntry {
349
351
  * no prop for them.
350
352
  */
351
353
  readonly omits?: Readonly<Record<string, string>>;
354
+ /**
355
+ * Bulma styles this root's modifiers, and the classes it omits, only on
356
+ * the element that carries the root itself (`.image.is-64x64`), so on an
357
+ * element without it they do nothing, and the planner flags them.
358
+ */
359
+ readonly modifiersNeedRoot?: boolean;
352
360
  }
353
361
  export declare const COLORS: readonly ["primary", "link", "info", "success", "warning", "danger", "black", "black-bis", "black-ter", "grey-darker", "grey-dark", "grey", "grey-light", "grey-lighter", "white", "white-bis", "white-ter", "light", "dark"];
354
362
  export declare const SIZES: readonly ["0", "1", "2", "3", "4", "5", "6", "auto"];
@@ -416,6 +424,15 @@ export declare const WRAPPER_OWN_PROPS: Readonly<Record<string, readonly string[
416
424
  export declare const REMOVED_IN_V1: readonly string[];
417
425
  /** Bulma 0.9 classes v1 dropped, with what replaced them. */
418
426
  export declare const LEGACY_09: Readonly<Record<string, string>>;
427
+ /**
428
+ * Bulma 0.9 helpers v1 removed whose job a v1 helper does, with that helper.
429
+ * Each is a helper token for the v1 helper's prop, so wherever its element
430
+ * converts it becomes that prop, which renders the v1 class in its place:
431
+ * the conversion here that changes a class, since the class it replaces
432
+ * styles nothing under v1. Where its element stays markup, or the prop is
433
+ * not written, it gets its `LEGACY_09` TODO instead.
434
+ */
435
+ export declare const REPLACED_IN_V1: Readonly<Record<string, string>>;
419
436
  /**
420
437
  * `text-color` and `background` resolve to a per-target prop (`RootEntry`'s
421
438
  * `textColor`/`bgColor`); `flex-container` only renders beside a flex
@@ -460,8 +477,14 @@ export declare function placedFor(list: string): RootEntry | undefined;
460
477
  export declare function flaggableRoot(token: string): RootEntry | undefined;
461
478
  /** A root's modifier for a class. */
462
479
  export declare function modifierFor(entry: RootEntry, token: string): Modifier | undefined;
480
+ /** Whether a root takes a class as a modifier, or omits it on purpose. */
481
+ export declare function modifiesRoot(entry: RootEntry, token: string): boolean;
482
+ /** The root a class modifies when Bulma styles it only on that root. */
483
+ export declare function rootItNeeds(token: string): string | undefined;
463
484
  /** What replaced a Bulma 0.9 class v1 removed. */
464
485
  export declare function legacyHint(token: string): string | undefined;
486
+ /** The v1 helper a removed Bulma 0.9 helper converts as. */
487
+ export declare function replacedBy(token: string): string | undefined;
465
488
  /** The bestax wrapper for a plain tag. */
466
489
  export declare function wrapperFor(tag: string): string | undefined;
467
490
  //# sourceMappingURL=class-map.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"class-map.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/class-map.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"class-map.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/class-map.ts"],"names":[],"mappings":"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"}
@@ -6,11 +6,13 @@
6
6
  * Every conversion this table allows must render exactly the HTML the raw
7
7
  * element rendered. That is a claim about bestax, and the render tests hold
8
8
  * it: each root, modifier and helper here is rendered through the built
9
- * library and compared with the raw markup it replaces. One exception, on
10
- * purpose: Font Awesome's own `<i aria-hidden="true">` alone in a `.icon`
9
+ * library and compared with the raw markup it replaces. The exceptions are
10
+ * on purpose. Font Awesome's own `<i aria-hidden="true">` alone in a `.icon`
11
11
  * that carries nothing assistive tech reads converts to `Icon`, which writes
12
12
  * the attribute on the `.icon` instead, since the glyph is hidden either way
13
- * (see `readsGlyph`).
13
+ * (see `readsGlyph`). And a Bulma 0.9 helper v1 removed, which styles
14
+ * nothing under v1, converts as the v1 helper that does its job (see
15
+ * `REPLACED_IN_V1`).
14
16
  *
15
17
  * Data only: `scripts/gen-mcp-index.mjs` imports it directly for the MCP
16
18
  * server's `lookup_bulma_classes`, so nothing Node cannot strip (no enums, no
@@ -1476,6 +1478,7 @@ export const ROOTS = {
1476
1478
  `is-${ratio}`,
1477
1479
  '`size` renders `has-ratio` beside it as well',
1478
1480
  ])),
1481
+ modifiersNeedRoot: true,
1479
1482
  absorbs: {
1480
1483
  tag: 'img',
1481
1484
  attributesOn: 'element',
@@ -1862,8 +1865,6 @@ export const ROOTS = {
1862
1865
  'theme-dark': plain('a theme scope; bestax sets themes through `Theme`'),
1863
1866
  'theme-light': plain('a theme scope; bestax sets themes through `Theme`'),
1864
1867
  fa: plain("Font Awesome's own class, styled by Bulma inside `.icon`"),
1865
- marginless: plain('a Bulma helper with no bestax prop'),
1866
- paddingless: plain('a Bulma helper with no bestax prop'),
1867
1868
  };
1868
1869
  function todo(target, why) {
1869
1870
  return { status: 'todo', target, why };
@@ -2047,6 +2048,20 @@ export const REMOVED_IN_V1 = [
2047
2048
  /** Bulma 0.9 classes v1 dropped, with what replaced them. */
2048
2049
  export const LEGACY_09 = {
2049
2050
  tile: 'Bulma v1 removed tiles; rebuild the layout with `Grid` and `Cell` (see the Bulma 0.9 to 1 guide)',
2051
+ 'is-marginless': 'Bulma v1 removed `is-marginless`, so it styles nothing now; write v1\'s `m-0` in its place, or `m="0"` on a bestax component. The codemod does that itself wherever the element converts',
2052
+ 'is-paddingless': 'Bulma v1 removed `is-paddingless`, so it styles nothing now; write v1\'s `p-0` in its place, or `p="0"` on a bestax component. The codemod does that itself wherever the element converts',
2053
+ };
2054
+ /**
2055
+ * Bulma 0.9 helpers v1 removed whose job a v1 helper does, with that helper.
2056
+ * Each is a helper token for the v1 helper's prop, so wherever its element
2057
+ * converts it becomes that prop, which renders the v1 class in its place:
2058
+ * the conversion here that changes a class, since the class it replaces
2059
+ * styles nothing under v1. Where its element stays markup, or the prop is
2060
+ * not written, it gets its `LEGACY_09` TODO instead.
2061
+ */
2062
+ export const REPLACED_IN_V1 = {
2063
+ 'is-marginless': 'm-0',
2064
+ 'is-paddingless': 'p-0',
2050
2065
  };
2051
2066
  function helperTokens(group, prefix, values, prop, suffix = '') {
2052
2067
  return values.map(value => [
@@ -2083,6 +2098,9 @@ export const HELPER_TOKENS = new Map([
2083
2098
  ...helperTokens('text-color', 'has-text-', HELPER_COLORS, 'textColor'),
2084
2099
  ...helperTokens('background', 'has-background-', HELPER_COLORS, 'bgColor'),
2085
2100
  ...SPACING_PROPS.flatMap(prop => helperTokens('spacing', `${prop}-`, SIZES, prop)),
2101
+ // Bulma 0.9's, as the v1 helper that replaced each (`REPLACED_IN_V1`).
2102
+ ['is-marginless', { group: 'spacing', write: { prop: 'm', value: '0' } }],
2103
+ ['is-paddingless', { group: 'spacing', write: { prop: 'p', value: '0' } }],
2086
2104
  ...helperTokens('typography', 'is-size-', TEXT_SIZES, 'textSize'),
2087
2105
  ...helperPerViewport('typography', 'is-size-', TEXT_SIZES, 'textSize', SIZE_VIEWPORTS),
2088
2106
  ...helperTokens('typography', 'has-text-', ALIGNMENTS, 'textAlign'),
@@ -2185,6 +2203,10 @@ export const PASSTHROUGH = [
2185
2203
  why: 'a Bulma helper with no bestax prop',
2186
2204
  match: /^(?:is-display-.+|is-visibility-.+|is-float-.+|is-clear-.+|has-text-weight-extrabold|is-align-content-(?:baseline|start|end)|is-align-items-self-(?:start|end)|is-offset-0(?:-[a-z]+)?)$/,
2187
2205
  },
2206
+ {
2207
+ why: 'Bulma\'s other name for `m-0` or `p-0`, with the same rule; bestax writes that rule as `m="0"` or `p="0"`, which renders `m-0` or `p-0`, so the class stays as it is',
2208
+ match: /^(?:marginless|paddingless)$/,
2209
+ },
2188
2210
  {
2189
2211
  why: 'a `.breadcrumb` separator, which converts only on its own `.breadcrumb`',
2190
2212
  match: /^has-[a-z]+-separator$/,
@@ -2236,10 +2258,23 @@ export function flaggableRoot(token) {
2236
2258
  export function modifierFor(entry, token) {
2237
2259
  return entry.modifiers ? own(entry.modifiers, token) : undefined;
2238
2260
  }
2261
+ /** Whether a root takes a class as a modifier, or omits it on purpose. */
2262
+ export function modifiesRoot(entry, token) {
2263
+ return (modifierFor(entry, token) !== undefined ||
2264
+ (entry.omits !== undefined && own(entry.omits, token) !== undefined));
2265
+ }
2266
+ /** The root a class modifies when Bulma styles it only on that root. */
2267
+ export function rootItNeeds(token) {
2268
+ return Object.keys(ROOTS).find(root => ROOTS[root].modifiersNeedRoot && modifiesRoot(ROOTS[root], token));
2269
+ }
2239
2270
  /** What replaced a Bulma 0.9 class v1 removed. */
2240
2271
  export function legacyHint(token) {
2241
2272
  return own(LEGACY_09, token);
2242
2273
  }
2274
+ /** The v1 helper a removed Bulma 0.9 helper converts as. */
2275
+ export function replacedBy(token) {
2276
+ return own(REPLACED_IN_V1, token);
2277
+ }
2243
2278
  /** The bestax wrapper for a plain tag. */
2244
2279
  export function wrapperFor(tag) {
2245
2280
  return own(WRAPPERS, tag);
@@ -1 +1 @@
1
- {"version":3,"file":"html-rules.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/html-rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,2EAA2E;AAC3E,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EASjD,CAAC;AAEF,0EAA0E;AAC1E,eAAO,MAAM,aAAa,EAAE,SAAS,MAAM,EAAkC,CAAC;AAE9E,8EAA8E;AAC9E,eAAO,MAAM,eAAe,EAAE,SAAS,MAAM,EAO5C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,SAAS,MAAM,EAQxC,CAAC;AAoCF,eAAO,MAAM,UAAU,EAAE,WAAW,CAAC,MAAM,CAAoC,CAAC;AAKhF,2DAA2D;AAC3D,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAErE;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAO/D"}
1
+ {"version":3,"file":"html-rules.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/html-rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,2EAA2E;AAC3E,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EASjD,CAAC;AAEF,0EAA0E;AAC1E,eAAO,MAAM,aAAa,EAAE,SAAS,MAAM,EAAkC,CAAC;AAE9E,8EAA8E;AAC9E,eAAO,MAAM,eAAe,EAAE,SAAS,MAAM,EAO5C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,SAAS,MAAM,EAQxC,CAAC;AA2CF,eAAO,MAAM,UAAU,EAAE,WAAW,CAAC,MAAM,CAAoC,CAAC;AAKhF,2DAA2D;AAC3D,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAErE;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAO/D"}
@@ -56,7 +56,7 @@ const EVENT_ATTRIBUTES = Object.values(html.property)
56
56
  .map(info => info.attribute)
57
57
  .filter(attribute => /^on[a-z]+$/.test(attribute));
58
58
  const VOCABULARY = {
59
- 'html-head': new Set(['title', 'meta', 'link', 'style', 'base']),
59
+ 'html-head': new Set(['title', 'meta', 'csp', 'link', 'style', 'base']),
60
60
  'html-asset': new Set(ASSET_KINDS),
61
61
  'html-script': new Set(SCRIPT_PATTERNS),
62
62
  'html-document': new Set([
@@ -79,7 +79,14 @@ const VOCABULARY = {
79
79
  'unknown',
80
80
  ]),
81
81
  'html-url': new Set(['javascript', 'missing', 'relative']),
82
- 'html-attr': new Set(['important', 'name', 'style', 'unknown']),
82
+ 'html-attr': new Set([
83
+ 'ignored',
84
+ 'important',
85
+ 'name',
86
+ 'stray',
87
+ 'style',
88
+ 'unknown',
89
+ ]),
83
90
  'html-parse': new Set(Object.values(ErrorCodes)),
84
91
  'html-file': new Set(['exists', 'not-included', 'template-syntax']),
85
92
  };
@@ -54,12 +54,21 @@ export declare function keepingMost(displays: ReadonlySet<string>): string;
54
54
  */
55
55
  export declare const pageDisplayOf: DisplayOf;
56
56
  /**
57
- * The component a page becomes: its file's name in PascalCase (its folder's
58
- * for an `index.html`) and `Page`, so `hero.html` can't shadow bestax's
59
- * `Hero`. A name starting with a digit starts with `Page` instead
60
- * (`404.html` is `Page404`), and one with nothing to go by is `Page`.
57
+ * The component a page becomes: its file's name in PascalCase and `Page`, so
58
+ * `hero.html` can't shadow bestax's `Hero`. A name starting with a digit
59
+ * starts with `Page` instead (`404.html` is `Page404`), and one with nothing
60
+ * to go by is `Page`. An `index.html` is named after its folder, which is
61
+ * what tells `docs/index.html` from `blog/index.html`, but for the site's home
62
+ * page: the `index.html` in a folder the run starts from (`roots`, the
63
+ * project's `runRoots`), with other pages beside it and none of them named
64
+ * `HomePage` already. Another spelling of the index beside it (`index.htm`)
65
+ * is no other page: it only competes for the name, and an `index.html` wins
66
+ * it, so one folder writes one `HomePage`. Only that page's folder is read
67
+ * for the pages beside it.
61
68
  */
62
- export declare function componentName(file: string): string;
69
+ export declare function componentName(file: string, roots?: unknown): string;
70
+ /** The other HTML pages in a page's folder, by file name. */
71
+ export declare function pagesBeside(file: string): string[];
63
72
  /**
64
73
  * Where a page's module goes: beside it, `.tsx` when the package around it is
65
74
  * TypeScript (a tsconfig, or a dependency on `typescript`), `.jsx` otherwise.
@@ -1 +1 @@
1
- {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/html.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAIH,OAAO,KAAK,EAEV,UAAU,EACV,aAAa,EACb,SAAS,EACT,gBAAgB,EACjB,MAAM,gBAAgB,CAAC;AAexB,OAAO,EAIL,KAAK,SAAS,EAEf,MAAM,+BAA+B,CAAC;AAiEvC;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,MAAM,CAYjE;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,aAAa,EAAE,SAoB3B,CAAC;AAIF;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAiBlD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,gBAAqB,GAC7B,MAAM,CAQR;AAsBD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAU3E;AA4KD,+EAA+E;AAC/E,eAAO,MAAM,YAAY,wCAAsC,CAAC;AAivBhE;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA4BjD;AAID,+EAA+E;AAC/E,MAAM,WAAW,aAAc,SAAQ,UAAU;IAC/C,2EAA2E;IAC3E,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAWD,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,aAAa,GAAG,SAAS,EACpC,OAAO,GAAE,gBAAqB,GAC7B,aAAa,CAgHf;AAED,yCAAyC;AACzC,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,aAAa,GAAG,SAAS,EACpC,OAAO,GAAE,gBAAqB,GAC7B,UAAU,CAGZ"}
1
+ {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/html.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAIH,OAAO,KAAK,EAEV,UAAU,EACV,aAAa,EACb,SAAS,EACT,gBAAgB,EACjB,MAAM,gBAAgB,CAAC;AAexB,OAAO,EAIL,KAAK,SAAS,EAEf,MAAM,+BAA+B,CAAC;AAiEvC;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,MAAM,CAYjE;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,aAAa,EAAE,SAoB3B,CAAC;AAsBF;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAgBnE;AAYD,6DAA6D;AAC7D,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAmBlD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,gBAAqB,GAC7B,MAAM,CAQR;AAsBD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAU3E;AA4KD,+EAA+E;AAC/E,eAAO,MAAM,YAAY,wCAAsC,CAAC;AAyxBhE;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA4BjD;AAID,+EAA+E;AAC/E,MAAM,WAAW,aAAc,SAAQ,UAAU;IAC/C,2EAA2E;IAC3E,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAWD,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,aAAa,GAAG,SAAS,EACpC,OAAO,GAAE,gBAAqB,GAC7B,aAAa,CAsHf;AAgCD,yCAAyC;AACzC,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,aAAa,GAAG,SAAS,EACpC,OAAO,GAAE,gBAAqB,GAC7B,UAAU,CAGZ"}
@@ -40,7 +40,7 @@ import { bulmaDisplay, bulmaOutOfFlow, HELPER_DISPLAY } from './display.js';
40
40
  import { bulmaBuildMessage, bulmaMediaMessage, bulmaStylesheetMessage, classifyAsset, extensionMessage, fontAwesomeMessage, jqueryMessage, PRIMARY_CLASS, scriptMessage, stylesheetMessage, webfontMessage, } from './html-assets.js';
41
41
  import { htmlRuleId, NAVBAR_FIXED_CLASSES, THEME_CLASSES, } from './html-rules.js';
42
42
  import { inNextApp, writesTypeScript } from './project.js';
43
- import transform from './transform.js';
43
+ import transform, { FILE_RULES } from './transform.js';
44
44
  const HTML_NS = 'http://www.w3.org/1999/xhtml';
45
45
  function attributeOf(element, name) {
46
46
  return element.attrs.find(attr => attr.name === name && !attr.prefix)?.value;
@@ -132,17 +132,8 @@ export const pageDisplayOf = element => {
132
132
  return keepingMost(displays);
133
133
  };
134
134
  // ---- Naming and placing the module -----------------------------------------
135
- /**
136
- * The component a page becomes: its file's name in PascalCase (its folder's
137
- * for an `index.html`) and `Page`, so `hero.html` can't shadow bestax's
138
- * `Hero`. A name starting with a digit starts with `Page` instead
139
- * (`404.html` is `Page404`), and one with nothing to go by is `Page`.
140
- */
141
- export function componentName(file) {
142
- const stem = path.basename(file, path.extname(file));
143
- const named = /^index$/i.test(stem)
144
- ? path.basename(path.dirname(path.resolve(file)))
145
- : stem;
135
+ /** A page's name with nothing but its words, as a component's name. */
136
+ function pageName(named) {
146
137
  const words = named.split(/[^\p{L}\p{Nd}]+/u).filter(Boolean);
147
138
  const pascal = words
148
139
  .map(word => {
@@ -159,6 +150,66 @@ export function componentName(file) {
159
150
  name = `${pascal}Page`;
160
151
  return /^[\p{ID_Start}$_][\p{ID_Continue}$]*$/u.test(name) ? name : 'Page';
161
152
  }
153
+ const HOME = 'HomePage';
154
+ /**
155
+ * The component a page becomes: its file's name in PascalCase and `Page`, so
156
+ * `hero.html` can't shadow bestax's `Hero`. A name starting with a digit
157
+ * starts with `Page` instead (`404.html` is `Page404`), and one with nothing
158
+ * to go by is `Page`. An `index.html` is named after its folder, which is
159
+ * what tells `docs/index.html` from `blog/index.html`, but for the site's home
160
+ * page: the `index.html` in a folder the run starts from (`roots`, the
161
+ * project's `runRoots`), with other pages beside it and none of them named
162
+ * `HomePage` already. Another spelling of the index beside it (`index.htm`)
163
+ * is no other page: it only competes for the name, and an `index.html` wins
164
+ * it, so one folder writes one `HomePage`. Only that page's folder is read
165
+ * for the pages beside it.
166
+ */
167
+ export function componentName(file, roots) {
168
+ const stem = path.basename(file, path.extname(file));
169
+ if (!/^index$/i.test(stem))
170
+ return pageName(stem);
171
+ const dir = path.dirname(path.resolve(file));
172
+ const atRoot = Array.isArray(roots) && roots.includes(dir);
173
+ const beside = atRoot ? pagesBeside(file) : [];
174
+ const rivals = beside.filter(isIndexPage);
175
+ const pages = beside.filter(sibling => !isIndexPage(sibling));
176
+ const own = indexRank(path.basename(file));
177
+ const home = pages.length > 0 &&
178
+ pages.every(page => pageName(path.basename(page, path.extname(page))) !== HOME) &&
179
+ rivals.every(rival => indexRank(rival) > own);
180
+ return home ? HOME : pageName(path.basename(dir));
181
+ }
182
+ /** Whether a page beside another is its folder's index, by another spelling. */
183
+ function isIndexPage(name) {
184
+ return /^index\.html?$/i.test(name);
185
+ }
186
+ /** Which of a folder's index pages is its home: `.html` first, then by name. */
187
+ function indexRank(name) {
188
+ return `${path.extname(name).toLowerCase() === '.html' ? 0 : 1}${name}`;
189
+ }
190
+ /** The other HTML pages in a page's folder, by file name. */
191
+ export function pagesBeside(file) {
192
+ const dir = path.dirname(path.resolve(file));
193
+ let names;
194
+ try {
195
+ names = fs.readdirSync(dir);
196
+ }
197
+ catch {
198
+ return [];
199
+ }
200
+ const own = path.basename(file);
201
+ const isPage = (name) => {
202
+ try {
203
+ return fs.statSync(path.join(dir, name)).isFile();
204
+ }
205
+ catch {
206
+ return false;
207
+ }
208
+ };
209
+ return names
210
+ .filter(name => name !== own && /\.html?$/i.test(name) && isPage(name))
211
+ .sort();
212
+ }
162
213
  /**
163
214
  * Where a page's module goes: beside it, `.tsx` when the package around it is
164
215
  * TypeScript (a tsconfig, or a dependency on `typescript`), `.jsx` otherwise.
@@ -232,7 +283,7 @@ const SCRIPT_PATTERNS = [
232
283
  [
233
284
  'theme',
234
285
  /data-theme|dataset\.theme|theme-(?:dark|light)|prefers-color-scheme/,
235
- "switches Bulma's light and dark schemes: bestax's `Theme` writes `data-theme` on `<html>` from its `colorMode` (`light`, `dark` or `system`), so keep the choice in state, saved in `localStorage`, and pass it; `Theme` writes the attribute from an effect, after the first paint, so for a saved choice to paint first, keep a small inline script in the `<head>` of the app's index.html that reads it (or the OS's, with none saved) and writes `data-theme` before the app loads, and start the state from what that script wrote",
286
+ "switches Bulma's light and dark schemes: bestax's `Theme` writes `data-theme` on `<html>` from its `colorMode` (`light`, `dark` or `system`), so keep the choice in state, saved in `localStorage`, and pass it; `Theme` writes the attribute from an effect, after the first paint, so for a saved choice to paint first, keep a small inline script in the `<head>` of the app's index.html that reads it (or the OS's, with none saved) and writes `data-theme` before the app loads, and start the state from what that script wrote (the bestax-theming skill's `examples/dark-mode.tsx` has the script and the app's side)",
236
287
  ],
237
288
  ];
238
289
  /**
@@ -265,7 +316,7 @@ function scriptNotes(script, page) {
265
316
  return [
266
317
  {
267
318
  rule: htmlRuleId('html-script', 'json-ld'),
268
- message: `structured data for search engines (JSON-LD) was dropped with the page's scripts: render it where the app sets each page's head, as \`<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }} />\`; the JSON is ${kept}`,
319
+ message: `structured data for search engines (JSON-LD) was dropped with the page's scripts: data about the whole site, or about a single-page app's one page, goes in the app's index.html as it is, where a crawler that runs no JavaScript still reads it, and data that differs from page to page goes where the app sets each page's head, as \`<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }} />\`; the JSON is ${kept}`,
269
320
  line,
270
321
  endLine,
271
322
  },
@@ -479,6 +530,11 @@ function assetNotes(page, root) {
479
530
  }
480
531
  return { notes, importsBulma };
481
532
  }
533
+ /** A `<meta http-equiv>` that sets the page's Content Security Policy. */
534
+ function isCsp(meta) {
535
+ return ((attributeOf(meta, 'http-equiv') ?? '').trim().toLowerCase() ===
536
+ 'content-security-policy');
537
+ }
482
538
  /** What a `<meta>` is for: its `name`, `property`, `http-equiv` or charset. */
483
539
  function metaKind(meta) {
484
540
  if (attributeOf(meta, 'charset') !== undefined)
@@ -511,7 +567,17 @@ function headNotes(head, notes, page) {
511
567
  });
512
568
  break;
513
569
  case 'meta':
514
- metas.push(node);
570
+ if (isCsp(node)) {
571
+ notes.push({
572
+ rule: htmlRuleId('html-head', 'csp'),
573
+ message: "the page's `<head>` sets a Content Security Policy in a `<meta http-equiv>`, which a component can't carry: it was written for what this page loads, and copied into the app's index.html as it is, it can block what the app loads instead (a Vite dev server runs an inline script for React's fast refresh and opens a socket for hot reloading, and the build serves the app's own scripts, styles and fonts), so write the app's own policy, best sent as a response header, and try it under both the dev server and the build",
574
+ line,
575
+ endLine,
576
+ });
577
+ }
578
+ else {
579
+ metas.push(node);
580
+ }
515
581
  break;
516
582
  case 'link': {
517
583
  const rel = (attributeOf(node, 'rel') ?? '').toLowerCase().split(/\s+/);
@@ -572,6 +638,12 @@ function headNotes(head, notes, page) {
572
638
  }
573
639
  /** Bulma's light and dark schemes, by `data-theme` value. */
574
640
  const SCHEMES = new Set(['light', 'dark']);
641
+ /**
642
+ * Where a page's scheme goes in the app: on its `<html>`, which the first
643
+ * paint reads, since `Theme` writes the attribute from an effect, after it.
644
+ */
645
+ const SCHEME_ON_HTML = "put it on the `<html>` in the app's index.html, where the first paint has it";
646
+ const SCHEME_TOGGLE = "for a scheme the visitor switches, bestax's `Theme colorMode` writes the choice only after that paint, so write a saved one before it too, as the `html-script:theme` recipe says and the bestax-theming skill's `examples/dark-mode.tsx` does";
575
647
  function documentAttributeNotes(where, element, notes) {
576
648
  if (!element)
577
649
  return;
@@ -602,7 +674,7 @@ function documentAttributeNotes(where, element, notes) {
602
674
  else if (THEME_CLASSES.includes(token)) {
603
675
  notes.push({
604
676
  rule: htmlRuleId('html-document', token),
605
- message: `the page's \`<${where}>\` has \`${token}\`, which sets Bulma's ${token.slice(6)} scheme: put it on the \`<html>\` in the app's index.html, or render bestax's \`<Theme colorMode="${token.slice(6)}">\`, which writes \`data-theme\` on \`<html>\``,
677
+ message: `the page's \`<${where}>\` has \`${token}\`, which sets Bulma's ${token.slice(6)} scheme: ${SCHEME_ON_HTML}; ${SCHEME_TOGGLE}`,
606
678
  line,
607
679
  });
608
680
  }
@@ -623,9 +695,7 @@ function documentAttributeNotes(where, element, notes) {
623
695
  const scheme = value.trim().toLowerCase();
624
696
  notes.push({
625
697
  rule: htmlRuleId('html-document', name),
626
- message: `the page's \`<${where}>\` has \`data-theme="${quote(value)}"\`, which sets Bulma's color scheme: put it on the \`<html>\` in the app's index.html${SCHEMES.has(scheme)
627
- ? `, or render bestax's \`<Theme colorMode="${scheme}">\`, which writes it on \`<html>\``
628
- : ''}`,
698
+ message: `the page's \`<${where}>\` has \`data-theme="${quote(value)}"\`, which sets Bulma's color scheme: ${SCHEME_ON_HTML}${SCHEMES.has(scheme) ? `; ${SCHEME_TOGGLE}` : ''}`,
629
699
  line,
630
700
  });
631
701
  continue;
@@ -711,11 +781,26 @@ function convertedNote(issue) {
711
781
  line,
712
782
  };
713
783
  case 'attribute-name':
784
+ // A name with no letter or digit in it is no directive: it is a stray
785
+ // character the browser read as an attribute (`<figure … \>`).
786
+ if (!/[\p{L}\p{N}]/u.test(token)) {
787
+ return {
788
+ rule: htmlRuleId('html-attr', 'stray'),
789
+ message: `\`${quote(token, 20)}\` in the tag is a stray character, a typo (such as \`\\>\` meant as \`/>\`) that the browser read as the name of an empty attribute: it was left out, so there is nothing to port, and it can go from the page too`,
790
+ line,
791
+ };
792
+ }
714
793
  return {
715
794
  rule: htmlRuleId('html-attr', 'name'),
716
795
  message: `the attribute \`${token}\` was left out, since JSX can't write that name (a framework's directive, such as \`@click\` or \`:class\`, is code to port into the component), or the element already has it under another spelling`,
717
796
  line,
718
797
  };
798
+ case 'ignored-attribute':
799
+ return {
800
+ rule: htmlRuleId('html-attr', 'ignored'),
801
+ message: `\`${token}\` was left out: HTML gives a \`<${issue.detail}>\` no \`${token}\` attribute, so the browser ignored it, and React's types reject it there; there is nothing to port, unless a stylesheet or script of the page's selects on it`,
802
+ line,
803
+ };
719
804
  case 'unknown-attribute':
720
805
  return {
721
806
  rule: htmlRuleId('html-attr', 'unknown'),
@@ -917,7 +1002,7 @@ function outsideCommentLines(comments) {
917
1002
  });
918
1003
  }
919
1004
  function todoLine(note, page) {
920
- const message = note.message.replace(/[\r\n\u2028\u2029]+/g, ' ').trim();
1005
+ const message = todoText(note.message);
921
1006
  const at = note.line === null
922
1007
  ? ''
923
1008
  : note.lines !== undefined
@@ -1081,7 +1166,7 @@ export function convertPage(file, source, collector, options = {}) {
1081
1166
  // The transform retargets it under `--css`, as it would in a JSX file.
1082
1167
  ...(assets.importsBulma ? [BULMA_IMPORT] : []),
1083
1168
  ...notes.document.map(note => todoLine(note, page)),
1084
- `export default function ${componentName(file)}() {`,
1169
+ `export default function ${componentName(file, options.runRoots)}() {`,
1085
1170
  ...contentLines(notes.content, page).map(line => ` ${line}`),
1086
1171
  ' return (',
1087
1172
  ];
@@ -1097,14 +1182,21 @@ export function convertPage(file, source, collector, options = {}) {
1097
1182
  }
1098
1183
  // The transform reads the module's path, so the gates for a server
1099
1184
  // component or another JSX runtime apply to it; its report names the page.
1185
+ const planned = new Map();
1100
1186
  const onPage = {
1101
- add: entry => collector?.add({
1102
- ...entry,
1103
- file,
1104
- line: entry.line === null || entry.line < jsxStart
1187
+ add: entry => {
1188
+ const line = entry.line === null || entry.line < jsxStart
1105
1189
  ? null
1106
- : emitted.htmlLineOf(entry.line - jsxStart + 1),
1107
- }),
1190
+ : emitted.htmlLineOf(entry.line - jsxStart + 1);
1191
+ // A file-level gate's TODO is about the whole page, so it gets no
1192
+ // page line of the element it sits on.
1193
+ const forFile = FILE_RULES.includes(entry.rule);
1194
+ if (line !== null && !forFile) {
1195
+ const text = todoText(entry.message);
1196
+ planned.set(text, [...(planned.get(text) ?? []), line]);
1197
+ }
1198
+ collector?.add({ ...entry, file, line });
1199
+ },
1108
1200
  };
1109
1201
  const { output } = runTransform(transform, outputPath, intermediate, onPage, {
1110
1202
  ...options,
@@ -1112,10 +1204,37 @@ export function convertPage(file, source, collector, options = {}) {
1112
1204
  });
1113
1205
  return {
1114
1206
  outputPath,
1115
- output: finishModule(output ?? intermediate),
1207
+ output: finishModule(withPageLines(output ?? intermediate, planned, page)),
1116
1208
  intermediate,
1117
1209
  };
1118
1210
  }
1211
+ /** A TODO's message as its comment writes it, on one line. */
1212
+ function todoText(message) {
1213
+ return message.replace(/[\r\n\u2028\u2029]+/g, ' ').trim();
1214
+ }
1215
+ /**
1216
+ * The planner's TODO lines, each with the page's lines it is about. The
1217
+ * transform writes one line for each message, however many elements share
1218
+ * it (five `.icon`s missing the same attribute), above the `return`, so the
1219
+ * lines go on after, the way the page's own notes carry theirs. Nothing from
1220
+ * the `return` on is read, since the page's text is there.
1221
+ */
1222
+ function withPageLines(code, planned, page) {
1223
+ if (planned.size === 0)
1224
+ return code;
1225
+ const lines = code.split('\n');
1226
+ for (let i = 0; i < lines.length; i++) {
1227
+ if (/^\s*return\b/.test(lines[i]))
1228
+ break;
1229
+ const todo = /^\s*\/\/ TODO\(bestax-migrate\): (.*)$/.exec(lines[i]);
1230
+ const on = todo ? planned.get(todo[1]) : undefined;
1231
+ if (!on)
1232
+ continue;
1233
+ const at = [...new Set(on)].sort((a, b) => a - b).join(', ');
1234
+ lines[i] = `${lines[i]} (${page}:${at})`;
1235
+ }
1236
+ return lines.join('\n');
1237
+ }
1119
1238
  /** The `transformHtml` the CLI calls. */
1120
1239
  export function transformHtml(file, source, collector, options = {}) {
1121
1240
  const { outputPath, output } = convertPage(file, source, collector, options);
@@ -7,11 +7,12 @@
7
7
  * renders exactly the markup the element did. Anything that would change the
8
8
  * markup is either left in `className` (a class with no prop here) or refuses
9
9
  * the whole element with a TODO (an attribute or tag the component would
10
- * render differently). One exception, on purpose: Font Awesome's own
10
+ * render differently). The exceptions are on purpose. Font Awesome's own
11
11
  * `<i aria-hidden="true">` alone in a `.icon` that carries nothing assistive
12
12
  * tech reads (the table's `hiddenMovesBeside`) converts to `Icon`, which writes that attribute
13
13
  * on the `.icon` instead (`movesHidden`), since the glyph is hidden either
14
- * way.
14
+ * way. And a Bulma 0.9 helper v1 removed (`REPLACED_IN_V1`), which styles
15
+ * nothing under v1, converts as the v1 helper that does its job.
15
16
  */
16
17
  import { type Glyph } from './glyph.js';
17
18
  export interface ElementFacts {
@@ -107,6 +108,12 @@ export interface ElementFacts {
107
108
  * The string the element's content renders, when it is one static text.
108
109
  */
109
110
  text?: string;
111
+ /**
112
+ * The element's `className` is computed in a way the codemod doesn't read
113
+ * whole (anything but a `clsx` or `classnames` call of parts it reads), so
114
+ * it may carry classes `tokens` doesn't hold.
115
+ */
116
+ unreadClasses?: boolean;
110
117
  /**
111
118
  * The classes the element directly around this one renders: its static
112
119
  * ones, or for a bestax component already in the file, its root class and
@@ -211,9 +218,9 @@ export interface Conversion {
211
218
  glyph?: Glyph;
212
219
  /**
213
220
  * That child carried the `aria-hidden` the target writes on the element
214
- * (Font Awesome's own `<i aria-hidden="true">`), so it moves up: the one
215
- * way a conversion's markup differs from the element's, on purpose, since
216
- * the glyph is hidden either way. The render tests compare it with the
221
+ * (Font Awesome's own `<i aria-hidden="true">`), so it moves up: a way a
222
+ * conversion's markup differs from the element's on purpose, since the
223
+ * glyph is hidden either way. The render tests compare it with the
217
224
  * attribute moved up, and nothing else.
218
225
  */
219
226
  movesHidden?: true;
@@ -1 +1 @@
1
- {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/plan.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/plan.ts"],"names":[],"mappings":"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"}
@@ -7,13 +7,14 @@
7
7
  * renders exactly the markup the element did. Anything that would change the
8
8
  * markup is either left in `className` (a class with no prop here) or refuses
9
9
  * the whole element with a TODO (an attribute or tag the component would
10
- * render differently). One exception, on purpose: Font Awesome's own
10
+ * render differently). The exceptions are on purpose. Font Awesome's own
11
11
  * `<i aria-hidden="true">` alone in a `.icon` that carries nothing assistive
12
12
  * tech reads (the table's `hiddenMovesBeside`) converts to `Icon`, which writes that attribute
13
13
  * on the `.icon` instead (`movesHidden`), since the glyph is hidden either
14
- * way.
14
+ * way. And a Bulma 0.9 helper v1 removed (`REPLACED_IN_V1`), which styles
15
+ * nothing under v1, converts as the v1 helper that does its job.
15
16
  */
16
- import { FORWARDS_REF, HELPER_PROPS, HELPER_TOKENS, inTagSet, legacyHint, modifierFor, numberAttrsOf, placedFor, PRECEDENCE, rootFor, WRAPPER_OWN_PROPS, wrapperFor, } from './class-map.js';
17
+ import { FORWARDS_REF, HELPER_PROPS, HELPER_TOKENS, inTagSet, legacyHint, modifierFor, modifiesRoot, numberAttrsOf, placedFor, PRECEDENCE, replacedBy, rootFor, rootItNeeds, WRAPPER_OWN_PROPS, wrapperFor, } from './class-map.js';
17
18
  import { glyphProps, readDrawnGlyph, readGlyph, readHiddenGlyph, } from './glyph.js';
18
19
  import { aTag } from '../_shared/articles.js';
19
20
  import { ruleId } from './rules.js';
@@ -53,6 +54,13 @@ function precedence(token) {
53
54
  function rootLabel(tokens) {
54
55
  return tokens.find(token => rootFor(token)?.status === 'mapped') ?? 'button';
55
56
  }
57
+ /**
58
+ * Whether the target renders this tag: the one it renders by itself (or the
59
+ * heading its size picks), or one its `as` takes.
60
+ */
61
+ function reachesTag(entry, tag, renders = entry.tag) {
62
+ return (tag === renders || entry.as === 'any' || (entry.as?.includes(tag) ?? false));
63
+ }
56
64
  function tagsItReaches(entry) {
57
65
  if (entry.as === 'any')
58
66
  return 'any tag through `as`';
@@ -60,19 +68,66 @@ function tagsItReaches(entry) {
60
68
  return entry.as.map(tag => `<${tag}>`).join(', ');
61
69
  return `only <${entry.tag}>`;
62
70
  }
71
+ /**
72
+ * Every class the element may carry: its fixed ones, and any a condition
73
+ * adds, which the element has to be right with as well as without.
74
+ */
75
+ function carriedBy(facts) {
76
+ return [...new Set([...facts.tokens, ...(facts.conditional ?? []).flat()])];
77
+ }
63
78
  export function plan(facts) {
79
+ const result = planElement(facts);
80
+ // A Bulma 0.9 helper v1 removed converts as the v1 helper that replaced
81
+ // it, and only one that stays a class gets the TODO naming that helper:
82
+ // where it converted, nothing is left to do.
83
+ const kept = new Set(result.conversion?.className?.split(' ') ?? []);
84
+ const stays = carriedBy(facts).filter(token => replacedBy(token) &&
85
+ (!result.conversion || !facts.tokens.includes(token) || kept.has(token)));
86
+ if (stays.length === 0)
87
+ return result;
88
+ return {
89
+ ...result,
90
+ todos: [
91
+ ...result.todos,
92
+ ...stays.map(token => ({
93
+ rule: ruleId('legacy', token),
94
+ message: legacyHint(token),
95
+ })),
96
+ ],
97
+ };
98
+ }
99
+ function planElement(facts) {
64
100
  const todos = [];
65
101
  const { tag, tokens } = facts;
66
- // Every class the element may carry: its fixed ones, and any a condition
67
- // adds, which the element has to be right with as well as without.
68
- const carried = [
69
- ...new Set([...tokens, ...(facts.conditional ?? []).flat()]),
70
- ];
102
+ const carried = carriedBy(facts);
71
103
  const mayCarry = (token) => carried.includes(token);
72
104
  for (const token of carried) {
73
- const hint = legacyHint(token);
105
+ // One that converts says so only if it stays, which `plan` knows.
106
+ const hint = replacedBy(token) ? undefined : legacyHint(token);
74
107
  if (hint)
75
108
  todos.push({ rule: ruleId('legacy', token), message: hint });
109
+ // A modifier Bulma styles only on its own root does nothing on an element
110
+ // with no root it modifies. That's a claim about every class the element
111
+ // carries, and the remedy drops one, so it's made only when the codemod
112
+ // reads them all. A re-run converts the element only on a tag the root's
113
+ // target renders, so only there does the advice promise one.
114
+ const root = rootItNeeds(token);
115
+ if (root &&
116
+ !facts.unreadClasses &&
117
+ !carried.some(other => {
118
+ const entry = rootFor(other);
119
+ return entry !== undefined && modifiesRoot(entry, token);
120
+ })) {
121
+ const needed = rootFor(root);
122
+ const article = /^[aeiou]/.test(root) ? 'an' : 'a';
123
+ const fix = reachesTag(needed, tag)
124
+ ? `add \`${root}\`, which bestax \`${needed.target}\` renders, then re-run`
125
+ : `add \`${root}\` for Bulma to style it, though bestax \`${needed.target}\` renders ${tagsItReaches(needed)}, not ${aTag(tag)}, so the element stays markup`;
126
+ todos.push({
127
+ rule: ruleId('modifier', root),
128
+ message: `\`${token}\` is ${article} \`.${root}\` modifier, and Bulma styles it only on the element that carries \`.${root}\`, so on this one it styles nothing unless the project's own CSS gives it a rule; if this element is the ${root}, ${fix}, and otherwise drop the class`,
129
+ });
130
+ }
76
131
  }
77
132
  // A family this source leaves as markup keeps its element as markup, even
78
133
  // beside a class it would convert (`navbar box`): the family's parts carry no
@@ -142,8 +197,7 @@ export function plan(facts) {
142
197
  }
143
198
  let as;
144
199
  if (renders !== tag) {
145
- const reachable = entry.as === 'any' || (entry.as?.includes(tag) ?? false);
146
- if (!reachable) {
200
+ if (!reachesTag(entry, tag, renders)) {
147
201
  return refuse('tag', target, `bestax \`${target}\` renders ${tagsItReaches(entry)}, not ${aTag(tag)}; keep the markup, or change the tag and re-run`);
148
202
  }
149
203
  as = tag;
@@ -253,7 +307,7 @@ export function plan(facts) {
253
307
  // Font Awesome's own markup hides the <i> rather than the element around
254
308
  // it, and a target that renders the glyph from props writes the same
255
309
  // `aria-hidden` on the element in its place: it moves up, and the glyph is
256
- // hidden either way. The one difference in markup a conversion makes, on
310
+ // hidden either way. A difference in markup a conversion makes on
257
311
  // purpose; the render tests compare it with the attribute moved up. Only
258
312
  // onto an element that carries nothing assistive tech reads, by name and
259
313
  // whatever the value: an expression may render as anything.
@@ -765,6 +819,15 @@ function buildIcons(children, target) {
765
819
  * base `display` beside a per-viewport one, a flex-container helper with no
766
820
  * flex `display`, `gapless` beside a `gap`) stays a class, as does one it
767
821
  * leaves out, and so does a modifier missing the attribute it needs.
822
+ *
823
+ * The first class to claim a prop keeps it, but a Bulma 0.9 class v1 removed
824
+ * claims one only after every other class has: whatever the order, a live
825
+ * class beside it for the same prop (`p-2 is-paddingless`) is what the page
826
+ * renders today and keeps the prop, and the removed one stays a class, with
827
+ * the TODO `plan` gives it. Beside a class for a different prop, such as an
828
+ * axis (`px-2 is-paddingless`), it still converts: the two render `px-2` and
829
+ * `p-0`, and v1's stylesheet puts every side and axis class after `p-0`, so
830
+ * the axis keeps its sides and `p-0` zeroes the rest.
768
831
  */
769
832
  function propsFrom(entry, tokens, tag, root, attributes) {
770
833
  const numbers = [];
@@ -774,7 +837,11 @@ function propsFrom(entry, tokens, tag, root, attributes) {
774
837
  const sourceOf = new Map();
775
838
  const groupOf = new Map();
776
839
  const converted = new Set(root ? [root] : []);
777
- for (const token of tokens) {
840
+ const claiming = [
841
+ ...tokens.filter(token => !replacedBy(token)),
842
+ ...tokens.filter(token => replacedBy(token)),
843
+ ];
844
+ for (const token of claiming) {
778
845
  if (converted.has(token))
779
846
  continue;
780
847
  const modifier = modifierFor(entry, token);
@@ -3,11 +3,13 @@
3
3
  * see from one file: which files a Next.js App Router may render as server
4
4
  * components, which packages render JSX through a runtime other than React,
5
5
  * and, for the module an HTML page becomes, which are written in TypeScript
6
- * and which are Next.js apps, where that module imports no stylesheet.
6
+ * and which are Next.js apps, where that module imports no stylesheet, and
7
+ * which folders the run starts from, where an `index.html` is the site's
8
+ * home page.
7
9
  *
8
10
  * Read once per run, from every package.json the run touches: the nearest one
9
11
  * above each target, and every one below it, so a monorepo run from its root
10
- * still finds `apps/web`.
12
+ * still finds `apps/web`. The folders come from the targets themselves.
11
13
  */
12
14
  /** `jsxImportSource` values whose JSX is React's. */
13
15
  export declare const REACT_RUNTIMES: ReadonlySet<string>;
@@ -42,6 +44,12 @@ export interface ProjectFacts {
42
44
  serverComponentRoots: ServerComponentRoot[];
43
45
  jsxRuntimes: JsxRuntime[];
44
46
  packageLanguages: PackageLanguage[];
47
+ /**
48
+ * The folders the run starts from, absolute: each folder it names and each
49
+ * named file's folder, but for one inside another. Only an `index.html`
50
+ * in one of them can be the site's home page.
51
+ */
52
+ runRoots: string[];
45
53
  }
46
54
  /**
47
55
  * The JSX runtime a package declares: what its tsconfig's `jsxImportSource`
@@ -1 +1 @@
1
- {"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/project.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,qDAAqD;AACrD,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,MAAM,CAK7C,CAAC;AAqBH,MAAM,WAAW,UAAU;IACzB,uCAAuC;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,mEAAmE;AACnE,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,4DAA4D;IAC5D,UAAU,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,oBAAoB,EAAE,mBAAmB,EAAE,CAAC;IAC5C,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,gBAAgB,EAAE,eAAe,EAAE,CAAC;CACrC;AA2GD;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,GACjD,MAAM,GAAG,IAAI,CAKf;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,YAAY,CAuD9D;AAcD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,CAE1E;AAED,oEAAoE;AACpE,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,CAEnE"}
1
+ {"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/project.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,qDAAqD;AACrD,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,MAAM,CAK7C,CAAC;AAqBH,MAAM,WAAW,UAAU;IACzB,uCAAuC;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,mEAAmE;AACnE,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,4DAA4D;IAC5D,UAAU,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,oBAAoB,EAAE,mBAAmB,EAAE,CAAC;IAC5C,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,gBAAgB,EAAE,eAAe,EAAE,CAAC;IACpC;;;;OAIG;IACH,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAmHD;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,GACjD,MAAM,GAAG,IAAI,CAKf;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,YAAY,CA8D9D;AAcD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,CAE1E;AAED,oEAAoE;AACpE,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,CAEnE"}
@@ -3,11 +3,13 @@
3
3
  * see from one file: which files a Next.js App Router may render as server
4
4
  * components, which packages render JSX through a runtime other than React,
5
5
  * and, for the module an HTML page becomes, which are written in TypeScript
6
- * and which are Next.js apps, where that module imports no stylesheet.
6
+ * and which are Next.js apps, where that module imports no stylesheet, and
7
+ * which folders the run starts from, where an `index.html` is the site's
8
+ * home page.
7
9
  *
8
10
  * Read once per run, from every package.json the run touches: the nearest one
9
11
  * above each target, and every one below it, so a monorepo run from its root
10
- * still finds `apps/web`.
12
+ * still finds `apps/web`. The folders come from the targets themselves.
11
13
  */
12
14
  import fs from 'node:fs';
13
15
  import path from 'node:path';
@@ -35,6 +37,11 @@ const SKIP_DIRS = new Set([
35
37
  '.next',
36
38
  '.e2e-tmp',
37
39
  ]);
40
+ /** Whether `dir` is a folder below `parent`. */
41
+ function isInside(dir, parent) {
42
+ const relative = path.relative(parent, dir);
43
+ return (relative !== '' && !relative.startsWith('..') && !path.isAbsolute(relative));
44
+ }
38
45
  function nearestManifest(target) {
39
46
  let dir = path.resolve(target);
40
47
  if (fs.statSync(dir, { throwIfNoEntry: false })?.isFile()) {
@@ -162,6 +169,7 @@ export function runtimeOf(dir, deps) {
162
169
  }
163
170
  export function analyzeProject(targets) {
164
171
  const manifests = new Set();
172
+ const starts = new Set();
165
173
  for (const target of targets) {
166
174
  const nearest = nearestManifest(target);
167
175
  if (nearest)
@@ -169,6 +177,10 @@ export function analyzeProject(targets) {
169
177
  const below = [];
170
178
  if (fs.statSync(target, { throwIfNoEntry: false })?.isDirectory()) {
171
179
  manifestsBelow(path.resolve(target), below);
180
+ starts.add(path.resolve(target));
181
+ }
182
+ else {
183
+ starts.add(path.dirname(path.resolve(target)));
172
184
  }
173
185
  for (const manifest of below)
174
186
  manifests.add(manifest);
@@ -177,6 +189,9 @@ export function analyzeProject(targets) {
177
189
  serverComponentRoots: [],
178
190
  jsxRuntimes: [],
179
191
  packageLanguages: [],
192
+ runRoots: [...starts]
193
+ .filter(dir => ![...starts].some(other => isInside(dir, other)))
194
+ .sort(),
180
195
  };
181
196
  for (const manifest of [...manifests].sort()) {
182
197
  let pkg;
@@ -1 +1 @@
1
- {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAYH,eAAO,MAAM,KAAK,EAAE,WAAW,CAAC,MAAM,CAapC,CAAC;AAqCH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAK1D"}
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAYH,eAAO,MAAM,KAAK,EAAE,WAAW,CAAC,MAAM,CAcpC,CAAC;AAqCH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAK1D"}
@@ -20,6 +20,7 @@ export const KINDS = new Set([
20
20
  'dynamic-class',
21
21
  'family',
22
22
  'legacy',
23
+ 'modifier',
23
24
  'only-child',
24
25
  'ref',
25
26
  'spread',
@@ -5,7 +5,8 @@
5
5
  * scope when a lowercase JSX element carries a `className` with a Bulma class
6
6
  * `class-map.ts` knows. Each such element goes through `plan()`, which
7
7
  * converts it only when the component renders exactly the same markup, but
8
- * for the one exception it states (Font Awesome's hidden `<i>`).
8
+ * for the exceptions it states (Font Awesome's hidden `<i>`, and a Bulma 0.9
9
+ * helper v1 removed).
9
10
  *
10
11
  * Passes, in order:
11
12
  * 1. the shared stylesheet-import pass (a no-op under the default `keep`)
@@ -19,5 +20,11 @@
19
20
  */
20
21
  import type { API, FileInfo } from 'jscodeshift';
21
22
  import type { TransformOptions } from '../../types.js';
23
+ /**
24
+ * The rules of the gates that leave a whole file alone. Their TODO is about
25
+ * the file, though it sits on the first element that would convert, so no
26
+ * line of the file is where it came from.
27
+ */
28
+ export declare const FILE_RULES: readonly ["jsx-runtime", "imports", "styled-jsx", "rsc"];
22
29
  export default function transform(fileInfo: FileInfo, api: API, options?: TransformOptions): string | undefined;
23
30
  //# sourceMappingURL=transform.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/transform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAW,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAkiCvD,MAAM,CAAC,OAAO,UAAU,SAAS,CAC/B,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,GAAG,EACR,OAAO,GAAE,gBAAqB,GAC7B,MAAM,GAAG,SAAS,CAs9BpB"}
1
+ {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/transform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAW,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAkiCvD;;;;GAIG;AACH,eAAO,MAAM,UAAU,0DAKb,CAAC;AAGX,MAAM,CAAC,OAAO,UAAU,SAAS,CAC/B,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,GAAG,EACR,OAAO,GAAE,gBAAqB,GAC7B,MAAM,GAAG,SAAS,CAy9BpB"}
@@ -5,7 +5,8 @@
5
5
  * scope when a lowercase JSX element carries a `className` with a Bulma class
6
6
  * `class-map.ts` knows. Each such element goes through `plan()`, which
7
7
  * converts it only when the component renders exactly the same markup, but
8
- * for the one exception it states (Font Awesome's hidden `<i>`).
8
+ * for the exceptions it states (Font Awesome's hidden `<i>`, and a Bulma 0.9
9
+ * helper v1 removed).
9
10
  *
10
11
  * Passes, in order:
11
12
  * 1. the shared stylesheet-import pass (a no-op under the default `keep`)
@@ -876,6 +877,17 @@ function onlyChildOf(elementPath, bestaxLocals) {
876
877
  ? name
877
878
  : undefined;
878
879
  }
880
+ /**
881
+ * The rules of the gates that leave a whole file alone. Their TODO is about
882
+ * the file, though it sits on the first element that would convert, so no
883
+ * line of the file is where it came from.
884
+ */
885
+ export const FILE_RULES = [
886
+ 'jsx-runtime',
887
+ 'imports',
888
+ 'styled-jsx',
889
+ 'rsc',
890
+ ];
879
891
  export default function transform(fileInfo, api, options = {}) {
880
892
  const source = fileInfo.source;
881
893
  // Cheap pre-filter: no className and no stylesheet import, nothing to do.
@@ -1246,6 +1258,11 @@ export default function transform(fileInfo, api, options = {}) {
1246
1258
  const className = classAttr ? staticClassName(classAttr) : '';
1247
1259
  const surrounding = around(elementPath);
1248
1260
  const sole = soleChild(element);
1261
+ // A joiner call the codemod can read converts exactly: its fixed classes
1262
+ // as for a static className, and each condition on a flag as its prop.
1263
+ const joined = className === null
1264
+ ? readJoiner(classAttr.value, callee => isJoiner(callee, elementPath))
1265
+ : undefined;
1249
1266
  const facts = {
1250
1267
  tag: name.name,
1251
1268
  tokens: className === null
@@ -1271,15 +1288,13 @@ export default function transform(fileInfo, api, options = {}) {
1271
1288
  holderOnlyChildOf: onlyChildOf(elementPath.parent, bestaxLocals),
1272
1289
  }),
1273
1290
  ...(textOf(element) !== undefined && { text: textOf(element) }),
1291
+ // Any other computed className may carry classes its strings don't
1292
+ // show (a variable, a call).
1293
+ ...(className === null && !joined && { unreadClasses: true }),
1274
1294
  };
1275
1295
  if (facts.tokens.some(token => rootFor(token)?.readsGlyph)) {
1276
1296
  Object.assign(facts, glyphPlace(elementPath));
1277
1297
  }
1278
- // A joiner call the codemod can read converts exactly: its fixed classes
1279
- // as for a static className, and each condition on a flag as its prop.
1280
- const joined = className === null
1281
- ? readJoiner(classAttr.value, callee => isJoiner(callee, elementPath))
1282
- : undefined;
1283
1298
  let exact;
1284
1299
  if (joined) {
1285
1300
  exact = plan({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bestax-migrate",
3
- "version": "2.29.0",
3
+ "version": "2.29.2",
4
4
  "description": "Codemods for migrating existing React apps from other Bulma libraries to @allxsmith/bestax-bulma",
5
5
  "type": "module",
6
6
  "bin": {
@@ -40,7 +40,7 @@
40
40
  "jscodeshift": "^17.3.0",
41
41
  "parse5": "^7.3.0",
42
42
  "property-information": "^7.2.0",
43
- "@allxsmith/bestax-bulma": "^5.39.0"
43
+ "@allxsmith/bestax-bulma": "^5.40.0"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@jest/globals": "^30.0.0",