@mdn/fred 1.6.2 → 1.8.0

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.
Files changed (149) hide show
  1. package/.env-dist +4 -0
  2. package/CHANGELOG.md +66 -0
  3. package/CONTRIBUTING.md +2 -2
  4. package/README.md +31 -2
  5. package/build/eslint-fred.js +6 -4
  6. package/build/plugins/generate-element-map.js +3 -2
  7. package/build/utils.js +0 -23
  8. package/components/breadcrumbs-bar/server.css +12 -0
  9. package/components/color-theme/element.js +1 -0
  10. package/components/content-feedback/element.js +58 -22
  11. package/components/content-section/server.css +15 -2
  12. package/components/curriculum/module.css +1 -0
  13. package/components/curriculum-module/server.css +1 -0
  14. package/components/env/index.js +6 -0
  15. package/components/footer/server.js +1 -1
  16. package/components/heading-anchor/server.js +0 -2
  17. package/components/issues-table/element.js +6 -4
  18. package/components/language-switcher/element.js +1 -0
  19. package/components/live-sample-result/element.js +1 -0
  20. package/components/menu/base.css +2 -1
  21. package/components/menu/constants.js +438 -147
  22. package/components/menu/missing-docs.json +133 -0
  23. package/components/menu/server.js +78 -657
  24. package/components/menu/types.d.ts +50 -0
  25. package/components/menu/update-missing-docs.js +66 -0
  26. package/components/modal/element.js +3 -2
  27. package/components/navigation/server.js +1 -1
  28. package/components/observatory-tests-and-scores/element.js +13 -7
  29. package/components/outer-layout/utils.js +2 -2
  30. package/components/play-runner/element.js +14 -6
  31. package/components/playground/element.js +11 -5
  32. package/components/recently-visited/element.js +4 -2
  33. package/components/scrim-inline/element.js +11 -5
  34. package/components/search-modal/element.js +1 -0
  35. package/components/writer-reload/element.js +10 -2
  36. package/entry.client.js +1 -0
  37. package/hooks/ga-init.js +31 -0
  38. package/hooks/glean-init.js +2 -6
  39. package/l10n/en-US.ftl +6 -0
  40. package/l10n/fr.ftl +145 -1
  41. package/out/service-worker.js +1 -1
  42. package/out/service-worker.js.map +1 -1
  43. package/out/static/client/{1231.84c230e0fa92f2d4.js → 1231.6a66b96b566b2cca.js} +14 -10
  44. package/out/static/client/1231.6a66b96b566b2cca.js.map +1 -0
  45. package/out/static/client/{2190.7995f19655987265.js → 2190.a21d8b0d7b75a20d.js} +5 -5
  46. package/out/static/client/2190.a21d8b0d7b75a20d.js.map +1 -0
  47. package/out/static/client/{2319.2034183eaacce69a.js → 2319.a419f6d93c814f50.js} +12 -8
  48. package/out/static/client/2319.a419f6d93c814f50.js.map +1 -0
  49. package/out/static/client/{3092.94a3edc866458ab7.js → 3092.54b703ff89ccdaf7.js} +6 -6
  50. package/out/static/client/3092.54b703ff89ccdaf7.js.map +1 -0
  51. package/out/static/client/{3200.024a6b1d06d80026.js → 3200.dc89d9709a81e853.js} +2 -1
  52. package/out/static/client/{3200.024a6b1d06d80026.js.map → 3200.dc89d9709a81e853.js.map} +1 -1
  53. package/out/static/client/{486.bb14d2f437221509.js → 486.b6950b0a4cfb9116.js} +2 -2
  54. package/out/static/client/{486.bb14d2f437221509.js.map → 486.b6950b0a4cfb9116.js.map} +1 -1
  55. package/out/static/client/{5446.3e0ac5aa93616c6f.js → 5446.2e663885069b1680.js} +4 -2
  56. package/out/static/client/5446.2e663885069b1680.js.map +1 -0
  57. package/out/static/client/{603.775311ee1356e86f.js → 603.45bf3e185d1b890d.js} +7 -7
  58. package/out/static/client/603.45bf3e185d1b890d.js.map +1 -0
  59. package/out/static/client/{6465.08012ddcd4597c76.js → 6465.2dc41017ae6abc34.js} +2 -1
  60. package/out/static/client/6465.2dc41017ae6abc34.js.map +1 -0
  61. package/out/static/client/{6480.09f744cd2fb69ed8.js → 6480.c839ead24f125a7e.js} +3 -2
  62. package/out/static/client/{6480.09f744cd2fb69ed8.js.map → 6480.c839ead24f125a7e.js.map} +1 -1
  63. package/out/static/client/7185.278701dcd05fcd30.js +2 -0
  64. package/out/static/client/7185.278701dcd05fcd30.js.map +1 -0
  65. package/out/static/client/9379.edc05ee9f550804e.js +2 -0
  66. package/out/static/client/9379.edc05ee9f550804e.js.map +1 -0
  67. package/out/static/client/{9784.3c73a0debfcca553.js → 9784.1c8d6e465137fd58.js} +13 -9
  68. package/out/static/client/{9784.3c73a0debfcca553.js.map → 9784.1c8d6e465137fd58.js.map} +1 -1
  69. package/out/static/client/{9804.d9ffbe6b7c44eab3.js → 9804.ba52ea55253eca7b.js} +2 -2
  70. package/out/static/client/{9804.d9ffbe6b7c44eab3.js.map → 9804.ba52ea55253eca7b.js.map} +1 -1
  71. package/out/static/client/9914.021220acc0d3e777.js +11 -0
  72. package/out/static/client/9914.021220acc0d3e777.js.map +1 -0
  73. package/out/static/client/index.0f05d4ac6b3b88a1.js +419 -0
  74. package/out/static/client/index.0f05d4ac6b3b88a1.js.map +1 -0
  75. package/out/static/client/{runtime.b178b9749f31202a.js → runtime.c323b9d2153b4ebf.js} +2 -2
  76. package/out/static/client/{runtime.b178b9749f31202a.js.map → runtime.c323b9d2153b4ebf.js.map} +1 -1
  77. package/out/static/client/stats.json +200 -200
  78. package/out/static/client/styles-breadcrumbs-bar.02910e49bb8b2372.css +2 -0
  79. package/out/static/client/styles-breadcrumbs-bar.02910e49bb8b2372.css.map +1 -0
  80. package/out/static/client/{styles-content-section.d18f07ab3d79a1d2.css → styles-content-section.6dc04fb9b3f3d595.css} +2 -2
  81. package/out/static/client/{styles-content-section.d18f07ab3d79a1d2.css.map → styles-content-section.6dc04fb9b3f3d595.css.map} +1 -1
  82. package/out/static/client/styles-curriculum-landing.cbaf6ff367369a26.css.map +1 -1
  83. package/out/static/client/styles-curriculum-module.c7ec78d3e724cf64.css.map +1 -1
  84. package/out/static/client/{styles-global.fb7afecd89ca2dff.js → styles-global.01d60465c4584631.js} +1 -1
  85. package/out/static/client/styles-global.4031cdde644ed6ce.css +2 -0
  86. package/out/static/client/{styles-global.684fd2c5254c94b8.css.map → styles-global.4031cdde644ed6ce.css.map} +1 -1
  87. package/out/static/client/styles-menu.c41c14be9597dcd9.css +2 -0
  88. package/out/static/client/styles-menu.c41c14be9597dcd9.css.map +1 -0
  89. package/out/static/client/watify_bg.c5a182c47876cd2b.wasm +0 -0
  90. package/out/static/legacy/{1539.ad5e9bc68ca36ebd.js → 1539.f16c6732d55f64b7.js} +3 -3
  91. package/out/static/legacy/{1539.ad5e9bc68ca36ebd.js.map → 1539.f16c6732d55f64b7.js.map} +1 -1
  92. package/out/static/legacy/7185.278701dcd05fcd30.js +2 -0
  93. package/out/static/legacy/7185.278701dcd05fcd30.js.map +1 -0
  94. package/out/static/legacy/asset-manifest.json +9 -9
  95. package/out/static/legacy/{index.ad3600b01e18974e.html → index.19cded28f6c1e506.html} +1 -1
  96. package/out/static/legacy/{index.5592b02d966df8ba.js → index.e979e65eb8758f6f.js} +3 -3
  97. package/out/static/legacy/{index.5592b02d966df8ba.js.map → index.e979e65eb8758f6f.js.map} +1 -1
  98. package/out/static/legacy/stats.json +13 -13
  99. package/out/static/legacy/watify_bg.c5a182c47876cd2b.wasm +0 -0
  100. package/out/static/legacy/{yari.8ce0be252d1ae155.js → yari.7f26dc58679ef833.js} +3 -3
  101. package/out/static/legacy/{yari.8ce0be252d1ae155.js.map → yari.7f26dc58679ef833.js.map} +1 -1
  102. package/out/static/ssr/7185.js +1 -1
  103. package/out/static/ssr/7185.js.map +1 -1
  104. package/out/static/ssr/index.js +369 -620
  105. package/out/static/ssr/index.js.map +1 -1
  106. package/out/static/ssr/stats.json +4 -4
  107. package/out/static/ssr/watify_bg.c5a182c47876cd2b.wasm +0 -0
  108. package/package.json +20 -20
  109. package/scripts/npm-test.js +22 -0
  110. package/server.js +22 -4
  111. package/utils/dnt-helper.js +59 -0
  112. package/utils/name-transformation.js +40 -0
  113. package/utils/telemetry-opt-out.js +12 -0
  114. package/wdio.conf.js +4 -2
  115. package/components/menu/check-missing-docs.js +0 -44
  116. package/out/static/client/1231.84c230e0fa92f2d4.js.map +0 -1
  117. package/out/static/client/2190.7995f19655987265.js.map +0 -1
  118. package/out/static/client/2319.2034183eaacce69a.js.map +0 -1
  119. package/out/static/client/3092.94a3edc866458ab7.js.map +0 -1
  120. package/out/static/client/5446.3e0ac5aa93616c6f.js.map +0 -1
  121. package/out/static/client/603.775311ee1356e86f.js.map +0 -1
  122. package/out/static/client/6465.08012ddcd4597c76.js.map +0 -1
  123. package/out/static/client/7185.a014a928e9a39779.js +0 -2
  124. package/out/static/client/7185.a014a928e9a39779.js.map +0 -1
  125. package/out/static/client/9379.7cdf58b4fb5efa66.js +0 -2
  126. package/out/static/client/9379.7cdf58b4fb5efa66.js.map +0 -1
  127. package/out/static/client/9914.251fe19f0038e97b.js +0 -11
  128. package/out/static/client/9914.251fe19f0038e97b.js.map +0 -1
  129. package/out/static/client/index.26176fe4ab13dce5.js +0 -268
  130. package/out/static/client/index.26176fe4ab13dce5.js.map +0 -1
  131. package/out/static/client/styles-breadcrumbs-bar.e2fa6dfb04a38166.css +0 -2
  132. package/out/static/client/styles-breadcrumbs-bar.e2fa6dfb04a38166.css.map +0 -1
  133. package/out/static/client/styles-global.684fd2c5254c94b8.css +0 -2
  134. package/out/static/client/styles-menu.5193bf2642ae7d64.css +0 -2
  135. package/out/static/client/styles-menu.5193bf2642ae7d64.css.map +0 -1
  136. package/out/static/client/watify_bg.9877982a693ec402.wasm +0 -0
  137. package/out/static/legacy/7185.a014a928e9a39779.js +0 -2
  138. package/out/static/legacy/7185.a014a928e9a39779.js.map +0 -1
  139. package/out/static/legacy/watify_bg.9877982a693ec402.wasm +0 -0
  140. package/out/static/ssr/watify_bg.9877982a693ec402.wasm +0 -0
  141. /package/out/static/client/{2190.7995f19655987265.js.LICENSE.txt → 2190.a21d8b0d7b75a20d.js.LICENSE.txt} +0 -0
  142. /package/out/static/client/{2319.2034183eaacce69a.js.LICENSE.txt → 2319.a419f6d93c814f50.js.LICENSE.txt} +0 -0
  143. /package/out/static/client/{603.775311ee1356e86f.js.LICENSE.txt → 603.45bf3e185d1b890d.js.LICENSE.txt} +0 -0
  144. /package/out/static/client/{6480.09f744cd2fb69ed8.js.LICENSE.txt → 6480.c839ead24f125a7e.js.LICENSE.txt} +0 -0
  145. /package/out/static/client/{9784.3c73a0debfcca553.js.LICENSE.txt → 9784.1c8d6e465137fd58.js.LICENSE.txt} +0 -0
  146. /package/out/static/client/{index.26176fe4ab13dce5.js.LICENSE.txt → index.0f05d4ac6b3b88a1.js.LICENSE.txt} +0 -0
  147. /package/out/static/legacy/{1539.ad5e9bc68ca36ebd.js.LICENSE.txt → 1539.f16c6732d55f64b7.js.LICENSE.txt} +0 -0
  148. /package/out/static/legacy/{index.5592b02d966df8ba.js.LICENSE.txt → index.e979e65eb8758f6f.js.LICENSE.txt} +0 -0
  149. /package/out/static/legacy/{yari.8ce0be252d1ae155.js.LICENSE.txt → yari.7f26dc58679ef833.js.LICENSE.txt} +0 -0
package/.env-dist CHANGED
@@ -25,6 +25,10 @@ RARI_URL="http://localhost:8083"
25
25
  # FRED_GLEAN_ENABLED=true
26
26
  # FRED_GLEAN_DEBUG=true
27
27
 
28
+ # uncomment to enable Google Analytics 4
29
+ # FRED_GA_ENABLED=true
30
+ # FRED_GA_MEASUREMENT_ID=G-XXXXXXXXXX
31
+
28
32
  # legacy react-specific environment variables
29
33
  REACT_APP_KUMA_HOST="localhost:3000"
30
34
  REACT_APP_FXA_SIGNIN_URL="/users/fxa/login/authenticate/"
package/CHANGELOG.md CHANGED
@@ -1,5 +1,71 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.8.0](https://github.com/mdn/fred/compare/v1.7.0...v1.8.0) (2025-10-31)
4
+
5
+
6
+ ### Features
7
+
8
+ * **server:** add auto open browser when launching dev server ([#805](https://github.com/mdn/fred/issues/805)) ([89b1198](https://github.com/mdn/fred/commit/89b11982d34c0cda6b32d594996a0712060af9d8))
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **breadcrumbs-bar:** avoid overlap with Theme/Language dropdown ([#864](https://github.com/mdn/fred/issues/864)) ([fe569a0](https://github.com/mdn/fred/commit/fe569a0ed3013e189f474a48c7e7c58d44f57315))
14
+ * **ci:** add the gh token to the run-tests stage ([7b15761](https://github.com/mdn/fred/commit/7b15761a10178ef85d3a86fa13dfaad1ec41e4e6))
15
+ * **content-section:** add `<kbd>` style ([#1003](https://github.com/mdn/fred/issues/1003)) ([d6495dc](https://github.com/mdn/fred/commit/d6495dccf4d6a321d8b30558f99a9333b2bfb997))
16
+ * **content-section:** loosen restrictions on heading ids ([#1008](https://github.com/mdn/fred/issues/1008)) ([d473156](https://github.com/mdn/fred/commit/d4731566badf9ef2b215253bfe85d802f0b8873c))
17
+ * **content-section:** use white img bg-color for all themes ([#934](https://github.com/mdn/fred/issues/934)) ([e4a22f1](https://github.com/mdn/fred/commit/e4a22f181561ae9f853a5947c5a072ca1f1d967e))
18
+ * **search-modal:** disable autocompletions on search input ([#993](https://github.com/mdn/fred/issues/993)) ([1242fd4](https://github.com/mdn/fred/commit/1242fd4d39d0b868c4a6f51ba5581ad35b442600))
19
+ * **search-modal:** fix unexpected autocompletions from search input ([1242fd4](https://github.com/mdn/fred/commit/1242fd4d39d0b868c4a6f51ba5581ad35b442600))
20
+
21
+
22
+ ### Miscellaneous
23
+
24
+ * **deps-dev:** bump @mdn/browser-compat-data from 7.1.14 to 7.1.15 ([#953](https://github.com/mdn/fred/issues/953)) ([64151d6](https://github.com/mdn/fred/commit/64151d6030a5f5660419fddb1a4d1c391b9dd515))
25
+ * **deps-dev:** bump @mdn/browser-compat-data from 7.1.15 to 7.1.16 ([#999](https://github.com/mdn/fred/issues/999)) ([b4dc524](https://github.com/mdn/fred/commit/b4dc5242a5353902412db50f655c643aa5611a95))
26
+ * **deps-dev:** bump @mdn/browser-compat-data from 7.1.16 to 7.1.17 ([#1015](https://github.com/mdn/fred/issues/1015)) ([126d6ff](https://github.com/mdn/fred/commit/126d6ff93a877f5f990305e1532b74da0bf947f1))
27
+ * **deps-dev:** bump @types/express from 5.0.4 to 5.0.5 in the dev group ([#1009](https://github.com/mdn/fred/issues/1009)) ([2636ff3](https://github.com/mdn/fred/commit/2636ff3cfc4712a202f53d9b9e72d600f3bf2cfc))
28
+ * **deps-dev:** bump eslint-plugin-jsdoc from 55.0.3 to 61.1.4 ([2d50777](https://github.com/mdn/fred/commit/2d50777d71b76e605dad3c086225bac43bfd7eae))
29
+ * **deps-dev:** bump eslint-plugin-jsdoc from 55.0.3 to 61.1.4 ([#918](https://github.com/mdn/fred/issues/918)) ([2d50777](https://github.com/mdn/fred/commit/2d50777d71b76e605dad3c086225bac43bfd7eae))
30
+ * **deps-dev:** bump eslint-plugin-unicorn from 61.0.2 to 62.0.0 ([#998](https://github.com/mdn/fred/issues/998)) ([bdf76af](https://github.com/mdn/fred/commit/bdf76af48db723447d9377479b1a0ccb8b205253))
31
+ * **deps-dev:** bump lefthook from 1.13.6 to 2.0.0 ([#949](https://github.com/mdn/fred/issues/949)) ([8b5c31b](https://github.com/mdn/fred/commit/8b5c31b0b6d3f112751ffc529b91141305b80199))
32
+ * **deps-dev:** bump the dev group with 5 updates ([#958](https://github.com/mdn/fred/issues/958)) ([78ffe61](https://github.com/mdn/fred/commit/78ffe61f0415c2229a96bfd203bd4f7f6b0d78d6))
33
+ * **deps-dev:** bump the dev group with 5 updates ([#996](https://github.com/mdn/fred/issues/996)) ([e32d4c1](https://github.com/mdn/fred/commit/e32d4c1cc215d4fa405189e4ee2390946b881a90))
34
+ * **deps-dev:** migrate from `@typescript-eslint/eslint-plugin` to `typescript-eslint` ([#946](https://github.com/mdn/fred/issues/946)) ([2d50777](https://github.com/mdn/fred/commit/2d50777d71b76e605dad3c086225bac43bfd7eae))
35
+ * **deps:** bump @mdn/rari from 0.1.53 to 0.1.54 ([#1010](https://github.com/mdn/fred/issues/1010)) ([03480ae](https://github.com/mdn/fred/commit/03480aea9914f8b1450d3567d990ed0065e915d7))
36
+ * **deps:** bump @mdn/watify from 1.1.3 to 1.1.4 ([#1014](https://github.com/mdn/fred/issues/1014)) ([baafc43](https://github.com/mdn/fred/commit/baafc4373fb9f7762b086a81db0c1f61c01dde97))
37
+ * **deps:** bump @mdn/watify from 1.1.4 to 1.1.5 ([#1043](https://github.com/mdn/fred/issues/1043)) ([9dc734b](https://github.com/mdn/fred/commit/9dc734bb9787ce563d408929cf512b707c87ffc7))
38
+ * **l10n:** localize more strings ([#893](https://github.com/mdn/fred/issues/893)) ([8fd8227](https://github.com/mdn/fred/commit/8fd822729c16c75eabb59c28236b5f481870a07e))
39
+ * **menu:** improve Learn items ([#942](https://github.com/mdn/fred/issues/942)) ([32442b2](https://github.com/mdn/fred/commit/32442b2fa21af6b3c6089ab55d027879f95bb8ec))
40
+ * **menu:** update Layout Cookbook slugs ([#1023](https://github.com/mdn/fred/issues/1023)) ([d2d89ae](https://github.com/mdn/fred/commit/d2d89aef8ce72487b8e52085901f8153bd2b444e))
41
+ * migrate GitHub team references ([#1002](https://github.com/mdn/fred/issues/1002)) ([6f59543](https://github.com/mdn/fred/commit/6f5954333be011e38e9f9c49428d1465c1146e5f))
42
+ * **npm:** migrate to Trusted Publishing ([#1019](https://github.com/mdn/fred/issues/1019)) ([a4414ad](https://github.com/mdn/fred/commit/a4414adcef346860854e2193fcbb355b3fd8bfec))
43
+
44
+ ## [1.7.0](https://github.com/mdn/fred/compare/v1.6.2...v1.7.0) (2025-10-21)
45
+
46
+
47
+ ### Features
48
+
49
+ * **menu:** convert content to data + manage missing with script ([#861](https://github.com/mdn/fred/issues/861)) ([e9be891](https://github.com/mdn/fred/commit/e9be891e1972ebecd4160e6e6b9f6e34aa491616))
50
+ * **telemetry:** port Google Analytics ([#905](https://github.com/mdn/fred/issues/905)) ([e88d977](https://github.com/mdn/fred/commit/e88d977effe722f5619aebd9cdac64e796ceb530))
51
+
52
+
53
+ ### Bug Fixes
54
+
55
+ * **live-sample-result:** use code hash as subdomain ([#922](https://github.com/mdn/fred/issues/922)) ([db48f7b](https://github.com/mdn/fred/commit/db48f7b8f9a858a2c85b6ea3727d9e6468374b49))
56
+ * **windows:** remove fdir from ssr bundle ([#926](https://github.com/mdn/fred/issues/926)) ([f724bff](https://github.com/mdn/fred/commit/f724bff89278402e958da1a7a90e5d4a5e2dcb6b))
57
+
58
+
59
+ ### Miscellaneous
60
+
61
+ * **deps-dev:** bump @mdn/browser-compat-data from 7.1.12 to 7.1.13 ([#916](https://github.com/mdn/fred/issues/916)) ([81b9966](https://github.com/mdn/fred/commit/81b99662edbdd0abb1da8641a6491d7010a3adf0))
62
+ * **deps-dev:** bump @mdn/browser-compat-data from 7.1.13 to 7.1.14 ([#938](https://github.com/mdn/fred/issues/938)) ([411240f](https://github.com/mdn/fred/commit/411240f96714cf6c5404645cdc913e637ed72809))
63
+ * **deps-dev:** bump the dev group across 1 directory with 6 updates ([#943](https://github.com/mdn/fred/issues/943)) ([2911855](https://github.com/mdn/fred/commit/29118556f9d618fa41c860de781d54064a03d34e))
64
+ * **deps:** bump @mdn/rari from 0.1.52 to 0.1.53 ([#932](https://github.com/mdn/fred/issues/932)) ([42d79e4](https://github.com/mdn/fred/commit/42d79e42187698697d080d2d5d7de721e96220e8))
65
+ * **l10n:** update french localization strings for various features ([#767](https://github.com/mdn/fred/issues/767)) ([be247ea](https://github.com/mdn/fred/commit/be247eafcbf5dc48dc300919c8bd5be6fac846d5))
66
+ * **menu:** adjust case of "CSS values and units" links ([#910](https://github.com/mdn/fred/issues/910)) ([236a727](https://github.com/mdn/fred/commit/236a7275dcaf3e98a657674f72b8628743774338))
67
+ * update ill cased links ([236a727](https://github.com/mdn/fred/commit/236a7275dcaf3e98a657674f72b8628743774338))
68
+
3
69
  ## [1.6.2](https://github.com/mdn/fred/compare/v1.6.1...v1.6.2) (2025-10-13)
4
70
 
5
71
 
package/CONTRIBUTING.md CHANGED
@@ -46,7 +46,7 @@ If you want to contribute but don't know where to start or can't find a suitable
46
46
 
47
47
  Once you find an issue you'd like to work on, please post a comment saying you want to work on it.
48
48
  Something like "I want to work on this" is fine.
49
- Also, mention the community team using the `@mdn/mdn-community-engagement` handle to ensure someone will get back to you.
49
+ Also, mention the community team using the `@mdn/community` handle to ensure someone will get back to you.
50
50
 
51
51
  ## Asking for help
52
52
 
@@ -54,7 +54,7 @@ The best way to reach us with a question when contributing is to use the followi
54
54
 
55
55
  - [Start a discussion](https://github.com/orgs/mdn/discussions)
56
56
  - Ask your question or highlight your discussion on [Matrix](https://matrix.to/#/#mdn:mozilla.org).
57
- - File an issue and tag the community team using the `@mdn/mdn-community-engagement` handle.
57
+ - File an issue and tag the community team using the `@mdn/community` handle.
58
58
 
59
59
  ## Pull request process
60
60
 
package/README.md CHANGED
@@ -4,7 +4,12 @@ MDN's next fr(ont)e(n)d.
4
4
 
5
5
  ## Getting started
6
6
 
7
- 1. Copy `.env-dist` to `.env` and update
7
+ 1. Copy `.env-dist` to `.env` and update values as needed. The file contains comments for guidance:
8
+
9
+ ```bash
10
+ cp .env-dist .env
11
+ ```
12
+
8
13
  2. Install dependencies `npm install`
9
14
  3. Bring up the dev environment with `npm run start`
10
15
 
@@ -41,6 +46,30 @@ This is useful to test changes on mobile, tablets and other platforms.
41
46
 
42
47
  ## Development principles
43
48
 
49
+ ### Supported Browsers
50
+
51
+ _tl;dr_ For visitors to MDN, we support the _Baseline widely available browser set_, with some minor modifications.
52
+
53
+ #### Browsers
54
+
55
+ The [_Baseline widely available browser set_](https://developer.mozilla.org/en-US/docs/Glossary/Baseline/Compatibility) is defined as browsers from the _Core browser set_ whose initial release date is on or before 30 months prior to today's date, plus long-term support releases.
56
+
57
+ MDN supports these browsers, along with Firefox for iOS and all currently active Firefox ESR versions:
58
+
59
+ - Apple Safari (iOS, macOS) — released within the last 2½ years
60
+ - Google Chrome (Android, Desktop) — released within the last 2½ years
61
+ - Microsoft Edge (Desktop) — released within the last 2½ years
62
+ - Mozilla Firefox (Android, Desktop, iOS) — released within the last 2½ years
63
+ - Mozilla Firefox ESR — currently supported by Mozilla
64
+
65
+ #### "Supported"
66
+
67
+ In this context, _supported_ means that any issues with rendering or functionality are considered bugs and will be addressed as soon as reasonably possible.
68
+
69
+ For issues encountered while using unsupported browsers, we decide on a case-by-case assessment of whether the issue will be addressed; however, these issues may have lower priority. Issues with screen readers and other accessibility aids are likely to carry higher levels of importance.
70
+
71
+ We make our best efforts to design MDN to degrade gracefully; however, there are no guarantees of any level of functionality outside the supported browser set.
72
+
44
73
  ### Environment variables
45
74
 
46
75
  See [the environment variables README](./components/env/README.md).
@@ -72,7 +101,7 @@ Logs a CSP hash for the source of the file during the production build.
72
101
  Most commonly used alongside `?source` to import the source of a file for inlining in a component, which needs to be allowlisted in our CSP:
73
102
 
74
103
  ```js
75
- import inlineScript from "./inline.js?source&csp=true`;
104
+ import inlineScript from "./inline.js?source&csp=true";
76
105
  ```
77
106
 
78
107
  ### Layout
@@ -1,6 +1,6 @@
1
1
  import path from "node:path";
2
2
 
3
- import { toCamelCase } from "./utils.js";
3
+ import { camelToKebabCase } from "../utils/name-transformation.js";
4
4
 
5
5
  /** @type {import("eslint").ESLint.Plugin} */
6
6
  export default {
@@ -26,7 +26,9 @@ export default {
26
26
  });
27
27
  }
28
28
 
29
- const expectedDir = toCamelCase(className.replace(/^MDN/, ""));
29
+ const expectedDir = camelToKebabCase(
30
+ className.replace(/^MDN/, ""),
31
+ );
30
32
  const expectedPath = path.join(
31
33
  "components",
32
34
  expectedDir,
@@ -57,7 +59,7 @@ export default {
57
59
  const [className, superClassName] = getClassNames(node);
58
60
 
59
61
  if (superClassName === "ServerComponent") {
60
- const expectedDir = toCamelCase(className);
62
+ const expectedDir = camelToKebabCase(className);
61
63
  const expectedPath = path.join(
62
64
  "components",
63
65
  expectedDir,
@@ -95,7 +97,7 @@ export default {
95
97
  });
96
98
  }
97
99
 
98
- const expectedDir = toCamelCase(
100
+ const expectedDir = camelToKebabCase(
99
101
  className.replace(/Sandbox$/, ""),
100
102
  );
101
103
  const expectedPath = path.join(
@@ -1,7 +1,8 @@
1
1
  import fs from "node:fs/promises";
2
2
  import path from "node:path";
3
3
 
4
- import { crawl, toPascalCase } from "../utils.js";
4
+ import { kebabToPascalCase } from "../../utils/name-transformation.js";
5
+ import { crawl } from "../utils.js";
5
6
 
6
7
  /**
7
8
  * @import { Compiler } from "@rspack/core"
@@ -26,7 +27,7 @@ export class GenerateElementMapPlugin {
26
27
  path.relative(compiler.context, filePath).replaceAll("\\", "/");
27
28
  const folderName = relPath.split("/").at(-2);
28
29
  const tagName = `mdn-${folderName}`;
29
- const className = toPascalCase(tagName);
30
+ const className = kebabToPascalCase(tagName);
30
31
  return `"${tagName}": import("${relPath}").${className};`;
31
32
  });
32
33
 
package/build/utils.js CHANGED
@@ -1,28 +1,5 @@
1
1
  import { fdir } from "fdir";
2
2
 
3
- const ACRONYMS = new Set(["MDN", "IX"]);
4
-
5
- /** @param {string} name */
6
- export function toPascalCase(name) {
7
- return name
8
- .split("-")
9
- .map((word) => {
10
- if (ACRONYMS.has(word.toUpperCase())) {
11
- return word.toUpperCase();
12
- }
13
- return word.charAt(0).toUpperCase() + word.slice(1);
14
- })
15
- .join("");
16
- }
17
-
18
- /** @param {string} name */
19
- export function toCamelCase(name) {
20
- return name
21
- .replaceAll(/([a-z0-9])([A-Z])/g, "$1-$2")
22
- .replaceAll(/([A-Z])([A-Z][a-z])/g, "$1-$2")
23
- .toLowerCase();
24
- }
25
-
26
3
  /**
27
4
  * @param {string} root
28
5
  * @param {(path: string, isDirectory: boolean) => boolean} filter
@@ -31,6 +31,18 @@
31
31
  display: none;
32
32
  }
33
33
 
34
+ mdn-color-theme,
35
+ mdn-language-switcher {
36
+ display: flex;
37
+ }
38
+
39
+ mdn-color-theme,
40
+ mdn-language-switcher,
41
+ mdn-color-theme::part(button),
42
+ mdn-language-switcher::part(button) {
43
+ height: 100%;
44
+ }
45
+
34
46
  @media (--screen-layout-1-sidebar-or-less) {
35
47
  &:has(mdn-toggle-sidebar) {
36
48
  padding-left: 0;
@@ -63,6 +63,7 @@ export class MDNColorTheme extends L10nMixin(LitElement) {
63
63
  return html`<div class="color-theme">
64
64
  <mdn-dropdown>
65
65
  <button
66
+ part="button"
66
67
  slot="button"
67
68
  class="color-theme__button"
68
69
  data-mode=${this._mode}
@@ -14,24 +14,6 @@ import styles from "./element.css?lit";
14
14
  * @typedef {"outdated"|"incomplete"|"code_examples"|"technical"|"consistency"|"incomprehensible"|"linguistic"|"other"} FeedbackReason
15
15
  */
16
16
 
17
- /** @type {Partial<Record<FeedbackReason, string>>} */
18
- const FEEDBACK_REASONS = {
19
- outdated: "Content is out of date",
20
- incomplete: "Missing information",
21
- code_examples: "Code examples not working as expected",
22
- other: "Other",
23
- };
24
-
25
- /** @type {Partial<Record<FeedbackReason, string>>} */
26
- const FEEDBACK_REASONS_DE = {
27
- technical: "Übersetzung enthält fachliche Fehler",
28
- consistency: "Begriffe sind inkonsistent übersetzt",
29
- incomprehensible: "Übersetzung ist nicht verständlich",
30
- linguistic: "Übersetzung enthält sprachliche Fehler",
31
- code_examples: "Code-Beispiele funktionieren nicht",
32
- other: "Sonstige",
33
- };
34
-
35
17
  export class MDNContentFeedback extends L10nMixin(LitElement) {
36
18
  static styles = styles;
37
19
 
@@ -70,6 +52,60 @@ export class MDNContentFeedback extends L10nMixin(LitElement) {
70
52
  gleanClick(`article_footer: feedback -> ${this._reason}`);
71
53
  }
72
54
 
55
+ /**
56
+ * Get list of feedback reasons with localized labels
57
+ * @returns {Array<{key: FeedbackReason, label: import("@lit").L10nResult}>}
58
+ */
59
+ _getFeedbackReasons() {
60
+ if (this.locale === "de") {
61
+ return [
62
+ {
63
+ key: "technical",
64
+ label: "Übersetzung enthält fachliche Fehler",
65
+ },
66
+ {
67
+ key: "consistency",
68
+ label: "Begriffe sind inkonsistent übersetzt",
69
+ },
70
+ {
71
+ key: "incomprehensible",
72
+ label: "Übersetzung ist nicht verständlich",
73
+ },
74
+ {
75
+ key: "linguistic",
76
+ label: "Übersetzung enthält sprachliche Fehler",
77
+ },
78
+ {
79
+ key: "code_examples",
80
+ label: "Code-Beispiele funktionieren nicht",
81
+ },
82
+ {
83
+ key: "other",
84
+ label: "Sonstige",
85
+ },
86
+ ];
87
+ }
88
+
89
+ return [
90
+ {
91
+ key: "outdated",
92
+ label: this.l10n`Content is out of date`,
93
+ },
94
+ {
95
+ key: "incomplete",
96
+ label: this.l10n`Missing information`,
97
+ },
98
+ {
99
+ key: "code_examples",
100
+ label: this.l10n`Code examples not working as expected`,
101
+ },
102
+ {
103
+ key: "other",
104
+ label: this.l10n`Other`,
105
+ },
106
+ ];
107
+ }
108
+
73
109
  _renderVote() {
74
110
  return html`<label
75
111
  >${this.l10n(
@@ -107,15 +143,15 @@ export class MDNContentFeedback extends L10nMixin(LitElement) {
107
143
  }
108
144
  };
109
145
 
146
+ const reasons = this._getFeedbackReasons();
147
+
110
148
  return html`<label
111
149
  >${this.l10n(
112
150
  "content-feedback-reason",
113
151
  )`Why was this page not helpful to you?`}</label
114
152
  >
115
- ${Object.entries(
116
- this.locale === "de" ? FEEDBACK_REASONS_DE : FEEDBACK_REASONS,
117
- ).map(
118
- ([key, label]) =>
153
+ ${reasons.map(
154
+ ({ key, label }) =>
119
155
  html`<div class="content-feedback--radios">
120
156
  <input
121
157
  type="radio"
@@ -119,7 +119,20 @@
119
119
 
120
120
  code {
121
121
  padding: 0.125em 0.25em;
122
- border-radius: 0.25em;
122
+ border-radius: var(--radius-normal);
123
+ }
124
+
125
+ kbd {
126
+ padding: 0.0625em 0.125em;
127
+
128
+ font-family: var(--font-family-code);
129
+
130
+ color: var(--color-text-secondary);
131
+
132
+ background-color: var(--color-background-primary);
133
+ border: 1px solid var(--color-border-primary);
134
+ border-bottom-width: 2px;
135
+ border-radius: var(--radius-normal);
123
136
  }
124
137
 
125
138
  img {
@@ -127,7 +140,7 @@
127
140
 
128
141
  margin: 2rem auto;
129
142
 
130
- background-color: var(--color-background-secondary);
143
+ background-color: var(--color-white);
131
144
  border: 1px solid var(--color-border-primary);
132
145
  border-radius: 0.25rem;
133
146
  }
@@ -93,6 +93,7 @@
93
93
 
94
94
  background: var(--curriculum-bg-color);
95
95
  border-radius: 1em;
96
+
96
97
  text-rendering: optimizelegibility;
97
98
  }
98
99
  }
@@ -111,6 +111,7 @@
111
111
 
112
112
  background: var(--curriculum-bg-color);
113
113
  border-radius: 1em;
114
+
114
115
  text-rendering: optimizelegibility;
115
116
  }
116
117
  }
@@ -8,6 +8,9 @@ export const PLAYGROUND_LOCAL = parseBool("PLAYGROUND_LOCAL", false, {
8
8
  runtime: true,
9
9
  });
10
10
  export const PORT = parseInt("PORT", 3000, { runtime: true });
11
+ export const OPEN_BROWSER_ON_START = parseBool("OPEN_BROWSER_ON_START", false, {
12
+ runtime: true,
13
+ });
11
14
  export const PLAYGROUND_PORT = parseInt("PLAYGROUND_PORT", 3001, {
12
15
  runtime: true,
13
16
  });
@@ -21,6 +24,9 @@ export const FXA_SIGNOUT_URL = parseString(
21
24
  "/users/fxa/login/logout/",
22
25
  );
23
26
 
27
+ export const GA_ENABLED = parseBool("GA_ENABLED", false);
28
+ export const GA_MEASUREMENT_ID = parseString("GA_MEASUREMENT_ID", "");
29
+
24
30
  /** Set to non-prod default, because we don't want glean to run without explicitly enabling. */
25
31
  export const GLEAN_ENABLED = parseBool("GLEAN_ENABLED", false);
26
32
  /** Set to non-prod default, because we don't want glean to run without explicitly enabling. */
@@ -129,7 +129,7 @@ const mozillaLinks = (context) => [
129
129
  external: true,
130
130
  },
131
131
  {
132
- text: context.l10n`Cookies`,
132
+ text: context.l10n`Telemetry Settings`,
133
133
  href: "https://www.mozilla.org/en-US/privacy/websites/data-preferences/",
134
134
  external: true,
135
135
  },
@@ -11,8 +11,6 @@ export class HeadingAnchor extends ServerComponent {
11
11
  * @param {string} title
12
12
  */
13
13
  render(level, id, title) {
14
- // remove leading numbers, dots, underscores, and commas to form a valid element id
15
- id = id ? id.replace(/^[0-9._,]+/, "") : id;
16
14
  return id
17
15
  ? hh`<${unsafeStatic("h" + level)} id=${ifDefined(id)} class="heading"><a class="heading-anchor" href="#${id}">${unsafeStatic(title)}</a></${unsafeStatic("h" + level)}>`
18
16
  : nothing;
@@ -1,8 +1,10 @@
1
1
  import { LitElement, html, nothing } from "lit";
2
2
 
3
+ import { L10nMixin } from "../../l10n/mixin.js";
4
+
3
5
  import styles from "./element.css?lit";
4
6
 
5
- export class MDNIssuesTable extends LitElement {
7
+ export class MDNIssuesTable extends L10nMixin(LitElement) {
6
8
  static styles = styles;
7
9
 
8
10
  static properties = {
@@ -58,7 +60,7 @@ export class MDNIssuesTable extends LitElement {
58
60
 
59
61
  render() {
60
62
  if (this._isLoading) {
61
- return html`loading issues…`;
63
+ return html`${this.l10n`loading issues…`}`;
62
64
  }
63
65
  if (this._error) {
64
66
  return html`${this._error}`;
@@ -71,8 +73,8 @@ export class MDNIssuesTable extends LitElement {
71
73
  <table>
72
74
  <thead>
73
75
  <tr>
74
- <th>Title</th>
75
- <th>Repository</th>
76
+ <th>${this.l10n`Title`}</th>
77
+ <th>${this.l10n`Repository`}</th>
76
78
  </tr>
77
79
  </thead>
78
80
  <tbody>
@@ -82,6 +82,7 @@ export class MDNLanguageSwitcher extends L10nMixin(LitElement) {
82
82
  return html`<div class="language-switcher">
83
83
  <mdn-dropdown>
84
84
  <button
85
+ part="button"
85
86
  slot="button"
86
87
  class="language-switcher__button"
87
88
  type="button"
@@ -113,6 +113,7 @@ export class MDNLiveSampleResult extends L10nMixin(LitElement) {
113
113
  ...new Set(["allow-modals", ...(this.sandbox?.split(" ") || [])]),
114
114
  ].join(" ")}
115
115
  .srcPrefix=${this.srcPrefix}
116
+ permalink
116
117
  style=${styleMap({
117
118
  height: this.height
118
119
  ? `${this.height}${/[0-9]$/.test(this.height) ? "px" : ""}`
@@ -158,7 +158,6 @@
158
158
 
159
159
  .menu__panel-icon {
160
160
  display: inline-flex;
161
- column-gap: 0.5rem;
162
161
  align-items: center;
163
162
 
164
163
  &::before {
@@ -167,6 +166,8 @@
167
166
  width: 1.25rem;
168
167
  height: 1.25rem;
169
168
 
169
+ margin-inline-end: 0.5rem;
170
+
170
171
  content: "";
171
172
 
172
173
  background-color: currentcolor;