@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
@@ -4,7 +4,7 @@ import { ifDefined } from "lit/directives/if-defined.js";
4
4
 
5
5
  import { ServerComponent } from "../server/index.js";
6
6
 
7
- import { MISSING_DOCS } from "./constants.js";
7
+ import { MISSING_DOCS, TABS } from "./constants.js";
8
8
 
9
9
  export class Menu extends ServerComponent {
10
10
  /**
@@ -12,11 +12,11 @@ export class Menu extends ServerComponent {
12
12
  */
13
13
  render(context) {
14
14
  /**
15
- * Holds the id of the section being rendered.
15
+ * Holds the id of the tab being rendered.
16
16
  *
17
17
  * @type {string|null}
18
18
  */
19
- let currentSection = null;
19
+ let currentTab = null;
20
20
 
21
21
  /**
22
22
  * Generates a Glean ID for menu/submenu links.
@@ -27,7 +27,7 @@ export class Menu extends ServerComponent {
27
27
  * @returns {string} the Glean ID.
28
28
  */
29
29
  const gleanId = (href, { primary = false } = {}) =>
30
- `${primary ? "menu_click_menu" : "menu_click_submenu"}: ${currentSection ?? "?"} -> ${href}`;
30
+ `${primary ? "menu_click_menu" : "menu_click_submenu"}: ${currentTab ?? "?"} -> ${href}`;
31
31
 
32
32
  /**
33
33
  * Renders a link to a page.
@@ -59,662 +59,83 @@ export class Menu extends ServerComponent {
59
59
  >`;
60
60
  };
61
61
 
62
- const sections = [
63
- {
64
- id: "html",
65
- render: () =>
66
- html`<mdn-dropdown>
67
- <button class="menu__tab-button" type="button" slot="button">
68
- <span class="menu__tab-label">HTML</span>
69
- </button>
70
- <div class="menu__panel" slot="dropdown">
71
- <p class="menu__panel-title">
72
- ${link("Web/HTML", "HTML: Markup language", { primary: true })}
73
- </p>
74
- <div class="menu__panel-content">
75
- <dl>
76
- <dt>HTML reference</dt>
77
- <dd>
78
- <ul>
79
- <li>
80
- ${link("Web/HTML/Reference/Elements", "Elements")}
81
- </li>
82
- <li>
83
- ${link(
84
- "Web/HTML/Reference/Global_attributes",
85
- "Global attributes",
86
- )}
87
- </li>
88
- <li>
89
- ${link("Web/HTML/Reference/Attributes", "Attributes")}
90
- </li>
91
- <li>
92
- ${link("Web/HTML/Reference", "See all…", {
93
- label: "See all HTML references",
94
- })}
95
- </li>
96
- </ul>
97
- </dd>
98
- </dl>
99
- <dl>
100
- <dt>HTML guides</dt>
101
- <dd>
102
- <ul>
103
- <li>
104
- ${link(
105
- "Web/HTML/Guides/Responsive_images",
106
- "Responsive images",
107
- )}
108
- </li>
109
- <li>
110
- ${link("Web/HTML/Guides/Cheatsheet", "HTML cheatsheet")}
111
- </li>
112
- <li>
113
- ${link(
114
- "Web/HTML/Guides/Date_and_time_formats",
115
- "Date & time formats",
116
- )}
117
- </li>
118
- <li>
119
- ${link("Web/HTML/Guides", "See all…", {
120
- label: "See all HTML guides",
121
- })}
122
- </li>
123
- </ul>
124
- </dd>
125
- </dl>
126
- <dl>
127
- <dt>Markup languages</dt>
128
- <dd>
129
- <ul>
130
- <li>${link("Web/SVG", "SVG")}</li>
131
- <li>${link("Web/MathML", "MathML")}</li>
132
- <li>${link("Web/XML", "XML")}</li>
133
- </ul>
134
- </dd>
135
- </dl>
136
- </div>
137
- </div>
138
- </mdn-dropdown>`,
139
- },
140
- {
141
- id: "css",
142
- render: () =>
143
- html`<mdn-dropdown>
144
- <button class="menu__tab-button" type="button" slot="button">
145
- <span class="menu__tab-label">CSS</span>
146
- </button>
147
- <div class="menu__panel" slot="dropdown">
148
- <p class="menu__panel-title">
149
- ${link("Web/CSS", "CSS: Styling language", { primary: true })}
150
- </p>
151
- <div class="menu__panel-content">
152
- <dl>
153
- <dt>CSS reference</dt>
154
- <dd>
155
- <ul>
156
- <li>${link("Web/CSS/Properties", "Properties")}</li>
157
- <li>${link("Web/CSS/CSS_selectors", "Selectors")}</li>
158
- <li>${link("Web/CSS/CSS_syntax/At-rule", "At-rules")}</li>
159
- <li>
160
- ${link(
161
- "Web/CSS/CSS_values_and_units",
162
- "Values & units",
163
- )}
164
- </li>
165
- <li>
166
- ${link("Web/CSS/Reference", "See all…", {
167
- label: "See all CSS references",
168
- })}
169
- </li>
170
- </ul>
171
- </dd>
172
- </dl>
173
- <dl>
174
- <dt>CSS guides</dt>
175
- <dd>
176
- <ul>
177
- <li>
178
- ${link(
179
- "Web/CSS/CSS_box_model/Introduction_to_the_CSS_box_model",
180
- "Box model",
181
- )}
182
- </li>
183
- <li>
184
- ${link(
185
- "Web/CSS/CSS_animations/Using_CSS_animations",
186
- "Animations",
187
- )}
188
- </li>
189
- <li>
190
- ${link(
191
- "Web/CSS/CSS_flexible_box_layout/Basic_concepts_of_flexbox",
192
- "Flexbox",
193
- )}
194
- </li>
195
- <li>${link("Web/CSS/CSS_colors", "Colors")}</li>
196
- <li>
197
- ${link("Web/CSS/Guides", "See all…", {
198
- label: "See all CSS guides",
199
- })}
200
- </li>
201
- </ul>
202
- </dd>
203
- </dl>
204
- <dl>
205
- <dt>Layout cookbook</dt>
206
- <dd>
207
- <ul>
208
- <li>
209
- ${link(
210
- "Web/CSS/Layout_cookbook/Column_layouts",
211
- "Column layouts",
212
- )}
213
- </li>
214
- <li>
215
- ${link(
216
- "Web/CSS/Layout_cookbook/Center_an_element",
217
- "Centering an element",
218
- )}
219
- </li>
220
- <li>
221
- ${link(
222
- "Web/CSS/Layout_cookbook/Card",
223
- "Card component",
224
- )}
225
- </li>
226
- <li>${link("Web/CSS/Layout_cookbook", "See all…")}</li>
227
- </ul>
228
- </dd>
229
- </dl>
230
- </div>
231
- </div>
232
- </mdn-dropdown>`,
233
- },
234
- {
235
- id: "javascript",
236
- render: () =>
237
- html`<mdn-dropdown>
238
- <button class="menu__tab-button" type="button" slot="button">
239
- <span class="menu__tab-label" data-type="long">JavaScript</span>
240
- <span class="menu__tab-label" data-type="short">JS</span>
241
- </button>
242
- <div class="menu__panel" slot="dropdown">
243
- <p class="menu__panel-title">
244
- ${link("Web/JavaScript", "JavaScript: Scripting language", {
245
- primary: true,
246
- })}
247
- </p>
248
- <div class="menu__panel-content">
249
- <dl>
250
- <dt>JS reference</dt>
251
- <dd>
252
- <ul>
253
- <li>
254
- ${link(
255
- "Web/JavaScript/Reference/Global_Objects",
256
- "Standard built-in objects",
257
- )}
258
- </li>
259
- <li>
260
- ${link(
261
- "Web/JavaScript/Reference/Operators",
262
- "Expressions & operators",
263
- )}
264
- </li>
265
- <li>
266
- ${link(
267
- "Web/JavaScript/Reference/Statements",
268
- "Statements & declarations",
269
- )}
270
- </li>
271
- <li>
272
- ${link(
273
- "Web/JavaScript/Reference/Functions",
274
- "Functions",
275
- )}
276
- </li>
277
- <li>
278
- ${link("Web/JavaScript/Reference", "See all…", {
279
- label: "See all JavaScript references",
280
- })}
281
- </li>
282
- </ul>
283
- </dd>
284
- </dl>
285
- <dl>
286
- <dt>JS guides</dt>
287
- <dd>
288
- <ul>
289
- <li>
290
- ${link(
291
- "Web/JavaScript/Guide/Control_flow_and_error_handling",
292
- "Control flow & error handing",
293
- )}
294
- </li>
295
- <li>
296
- ${link(
297
- "Web/JavaScript/Guide/Loops_and_iteration",
298
- "Loops and iteration",
299
- )}
300
- </li>
301
- <li>
302
- ${link(
303
- "Web/JavaScript/Guide/Working_with_objects",
304
- "Working with objects",
305
- )}
306
- </li>
307
- <li>
308
- ${link(
309
- "Web/JavaScript/Guide/Using_classes",
310
- "Using classes",
311
- )}
312
- </li>
313
- <li>
314
- ${link("Web/JavaScript/Guide", "See all…", {
315
- label: "See all JavaScript guides",
316
- })}
317
- </li>
318
- </ul>
319
- </dd>
320
- </dl>
321
- </div>
322
- </div>
323
- </mdn-dropdown>`,
324
- },
325
- {
326
- id: "webapis",
327
- render: () =>
328
- html`<mdn-dropdown>
329
- <button class="menu__tab-button" type="button" slot="button">
330
- <span class="menu__tab-label">Web APIs</span>
331
- </button>
332
- <div class="menu__panel" slot="dropdown">
333
- <p class="menu__panel-title">
334
- ${link("Web/API", "Web APIs: Programming interfaces", {
335
- primary: true,
336
- })}
337
- </p>
338
- <div class="menu__panel-content">
339
- <dl>
340
- <dt>Web API reference</dt>
341
- <dd>
342
- <ul>
343
- <li>
344
- ${link("Web/API/File_System_API", "File system API")}
345
- </li>
346
- <li>${link("Web/API/Fetch_API", "Fetch API")}</li>
347
- <li>
348
- ${link("Web/API/Geolocation_API", "Geolocation API")}
349
- </li>
350
- <li>${link("Web/API/HTML_DOM_API", "HTML DOM API")}</li>
351
- <li>${link("Web/API/Push_API", "Push API")}</li>
352
- <li>
353
- ${link(
354
- "Web/API/Service_Worker_API",
355
- "Service worker API",
356
- )}
357
- </li>
358
- <li>
359
- ${link("Web/API", "See all…", {
360
- label: "See all Web API guides",
361
- })}
362
- </li>
363
- </ul>
364
- </dd>
365
- </dl>
366
- <dl>
367
- <dt>Web API guides</dt>
368
- <dd>
369
- <ul>
370
- <li>
371
- ${link(
372
- "Web/API/Web_Animations_API/Using_the_Web_Animations_API",
373
- "Using the Web animation API",
374
- )}
375
- </li>
376
- <li>
377
- ${link(
378
- "Web/API/Fetch_API/Using_Fetch",
379
- "Using the Fetch API",
380
- )}
381
- </li>
382
- <li>
383
- ${link(
384
- "Web/API/History_API/Working_with_the_History_API",
385
- "Working with the History API",
386
- )}
387
- </li>
388
- <li>
389
- ${link(
390
- "Web/API/Web_Speech_API/Using_the_Web_Speech_API",
391
- "Using the Web speech API",
392
- )}
393
- </li>
394
- <li>
395
- ${link(
396
- "Web/API/Web_Workers_API/Using_web_workers",
397
- "Using web workers",
398
- )}
399
- </li>
400
- </ul>
401
- </dd>
402
- </dl>
403
- </div>
404
- </div>
405
- </mdn-dropdown>`,
406
- },
407
- {
408
- id: "all",
409
- render: () =>
410
- html`<mdn-dropdown>
411
- <button class="menu__tab-button" type="button" slot="button">
412
- <span class="menu__tab-label">All</span>
413
- </button>
414
- <div class="menu__panel" slot="dropdown">
415
- <p class="menu__panel-title">
416
- ${link("Web", "All web technology", { primary: true })}
417
- </p>
418
- <div class="menu__panel-content">
419
- <dl>
420
- <dt>Technologies</dt>
421
- <dd>
422
- <ul>
423
- <li>${link("Web/Accessibility", "Accessibility")}</li>
424
- <li>${link("Web/HTTP", "HTTP")}</li>
425
- <li>${link("Web/URI", "URI")}</li>
426
- <li>
427
- ${link(
428
- "Mozilla/Add-ons/WebExtensions",
429
- "Web extensions",
430
- )}
431
- </li>
432
- <li>${link("WebAssembly", "WebAssembly")}</li>
433
- <li>${link("Web/WebDriver", "WebDriver")}</li>
434
- <li>
435
- ${link("Web", "See all…", {
436
- label: "See all web technology references",
437
- })}
438
- </li>
439
- </ul>
440
- </dd>
441
- </dl>
442
- <dl>
443
- <dt>Topics</dt>
444
- <dd>
445
- <ul>
446
- <li>${link("Web/Media", "Media")}</li>
447
- <li>${link("Web/API/Performance", "Performance")}</li>
448
- <li>${link("Web/Privacy", "Privacy")}</li>
449
- <li>${link("Web/Security", "Security")}</li>
450
- <li>
451
- ${link(
452
- "Web/Progressive_web_apps",
453
- "Progressive web apps",
454
- )}
455
- </li>
456
- </ul>
457
- </dd>
458
- </dl>
459
- </div>
460
- </div>
461
- </mdn-dropdown>`,
462
- },
463
- {
464
- id: "learn",
465
- render: () =>
466
- html`<mdn-dropdown>
467
- <button class="menu__tab-button" type="button" slot="button">
468
- <span class="menu__tab-label">Learn</span>
469
- </button>
470
- <div class="menu__panel" slot="dropdown">
471
- <p class="menu__panel-title">
472
- ${link("Learn_web_development", "Learn web development", {
473
- primary: true,
474
- })}
475
- </p>
476
- <div class="menu__panel-content">
477
- <dl>
478
- <dt>Frontend developer course</dt>
479
- <dd>
480
- <ul>
481
- <li>
482
- ${link(
483
- "Learn_web_development/Getting_started",
484
- "Getting started",
485
- )}
486
- </li>
487
- <li>
488
- ${link(
489
- "Learn_web_development/Howto",
490
- "Common questions",
491
- )}
492
- </li>
493
- <li>
494
- <a
495
- class=${ifDefined(
496
- context.locale === "en-US"
497
- ? undefined
498
- : "only-in-en-us",
499
- )}
500
- href="/en-US/curriculum/"
501
- data-glean-id=${gleanId("/en-US/curriculum/")}
502
- >Curriculum</a
503
- >
504
- </li>
505
- </ul>
506
- </dd>
507
- </dl>
508
- <dl>
509
- <dt>Learn HTML</dt>
510
- <dd>
511
- <ul>
512
- <li>
513
- ${link(
514
- "Learn_web_development/Core/Structuring_content",
515
- "Introduction to HTML",
516
- )}
517
- </li>
518
- <li>
519
- ${link(
520
- "Learn_web_development/Core/Structuring_content/Basic_HTML_syntax",
521
- "Getting started with HTML",
522
- )}
523
- </li>
524
- </ul>
525
- </dd>
526
- </dl>
527
- <dl>
528
- <dt>Learn CSS</dt>
529
- <dd>
530
- <ul>
531
- <li>
532
- ${link(
533
- "Learn_web_development/Core/Styling_basics/What_is_CSS",
534
- "What is CSS",
535
- )}
536
- </li>
537
- <li>
538
- ${link(
539
- "Learn_web_development/Core/Styling_basics/Getting_started",
540
- "Getting started with CSS",
541
- )}
542
- </li>
543
- </ul>
544
- </dd>
545
- </dl>
546
- <dl>
547
- <dt>Learn JavaScript</dt>
548
- <dd>
549
- <ul>
550
- <li>
551
- ${link(
552
- "Web/HTML/How_to/Use_data_attributes",
553
- "How to use data attributes",
554
- )}
555
- </li>
556
- <li>
557
- ${link(
558
- "Web/HTML/How_to/Add_JavaScript_to_your_web_page",
559
- "Add JavaScript to your web page",
560
- )}
561
- </li>
562
- </ul>
563
- </dd>
564
- </dl>
565
- </div>
566
- </div>
567
- </mdn-dropdown>`,
568
- },
569
- {
570
- id: "tools",
571
- render: () =>
572
- html`<mdn-dropdown>
573
- <button class="menu__tab-button" type="button" slot="button">
574
- <span class="menu__tab-label">Tools</span>
575
- </button>
576
- <div class="menu__panel" slot="dropdown">
577
- <p class="menu__panel-title">Discover our tools</p>
578
- <div class="menu__panel-content">
579
- <ul>
580
- <li>
581
- <a
582
- class="menu__panel-icon"
583
- data-icon="circle-play"
584
- href=${`/en-US/play`}
585
- data-glean-id=${gleanId("/en-US/play/")}
586
- >
587
- Playground
588
- </a>
589
- </li>
590
- <li>
591
- <a
592
- class="menu__panel-icon"
593
- data-icon="shield-check"
594
- href=${`/en-US/observatory`}
595
- data-glean-id=${gleanId("/en-US/observatory/")}
596
- >
597
- HTTP Observatory
598
- </a>
599
- </li>
600
- </ul>
601
- <ul>
602
- <li>
603
- ${link(
604
- "Web/CSS/CSS_backgrounds_and_borders/Border-image_generator",
605
- "Border-image generator",
606
- )}
607
- </li>
608
- <li>
609
- ${link(
610
- "Web/CSS/CSS_backgrounds_and_borders/Border-radius_generator",
611
- "Border-radius generator",
612
- )}
613
- </li>
614
- <li>
615
- ${link(
616
- "Web/CSS/CSS_backgrounds_and_borders/Box-shadow_generator",
617
- "Box-shadow generator",
618
- )}
619
- </li>
620
- <li>
621
- ${link(
622
- "Web/CSS/CSS_colors/Color_format_converter",
623
- "Color format converter",
624
- )}
625
- </li>
626
- <li>
627
- ${link("Web/CSS/CSS_colors/Color_mixer", "Color mixer")}
628
- </li>
629
- <li>
630
- ${link(
631
- "Web/CSS/CSS_shapes/Shape_generator",
632
- "Shape generator",
633
- )}
634
- </li>
635
- </ul>
636
- </div>
637
- </div>
638
- </mdn-dropdown>`,
639
- },
640
- {
641
- id: "about",
642
- render: () =>
643
- html`<mdn-dropdown>
644
- <button class="menu__tab-button" type="button" slot="button">
645
- <span class="menu__tab-label">About</span>
646
- </button>
647
- <div class="menu__panel" slot="dropdown">
648
- <p class="menu__panel-title">Get to know MDN better</p>
649
- <div class="menu__panel-content">
650
- <ul>
651
- <li>
652
- <a
653
- class="menu__panel-icon"
654
- data-icon="mdn-m"
655
- href=${`/en-US/about`}
656
- data-glean-id=${gleanId("/en-US/about")}
657
- >
658
- About MDN
659
- </a>
660
- </li>
661
- <li>
662
- <a
663
- class="menu__panel-icon"
664
- data-icon="chart-no-axes-combined"
665
- href=${`/en-US/advertising`}
666
- data-glean-id=${gleanId("/en-US/advertising")}
667
- >
668
- Advertise with us
669
- </a>
670
- </li>
671
- </ul>
672
- <ul>
673
- <li>
674
- <a
675
- class="menu__panel-icon"
676
- data-icon="users"
677
- href=${`/en-US/community`}
678
- data-glean-id=${gleanId("/en-US/community")}
679
- >
680
- Community
681
- </a>
682
- </li>
683
- <li>
684
- <a
685
- class="menu__panel-icon"
686
- data-icon="github"
687
- href="https://github.com/mdn"
688
- data-glean-id=${gleanId("https://github.com/mdn")}
689
- >
690
- MDN on GitHub
691
- </a>
692
- </li>
693
- </ul>
694
- </div>
695
- </div>
696
- </mdn-dropdown>`,
697
- },
698
- {
699
- id: "blog",
700
- render: () =>
701
- html`<a
702
- class="menu__tab-link"
703
- href=${`/en-US/blog/`}
704
- data-glean-id=${`menu_click_link: top-level -> /en-US/blog/`}
705
- >Blog</a
706
- >`,
707
- },
708
- ];
709
-
710
62
  return html`
711
63
  <nav class="menu">
712
- ${sections.map((section) => {
713
- currentSection = section.id;
714
- const result = html`<div class="menu__tab" data-section=${section.id}>
715
- ${section.render()}
64
+ ${TABS.map((tab) => {
65
+ currentTab = tab.id;
66
+ const result = html`<div class="menu__tab" data-section=${tab.id}>
67
+ ${"href" in tab
68
+ ? html`<a
69
+ class="menu__tab-link"
70
+ href=${tab.href}
71
+ data-glean-id=${`menu_click_link: top-level -> ${tab.href}`}
72
+ >${tab.buttonText}</a
73
+ >`
74
+ : html`<mdn-dropdown>
75
+ <button class="menu__tab-button" type="button" slot="button">
76
+ ${typeof tab.buttonText === "string"
77
+ ? html`<span class="menu__tab-label"
78
+ >${tab.buttonText}</span
79
+ >`
80
+ : html`<span class="menu__tab-label" data-type="long"
81
+ >${tab.buttonText.long}</span
82
+ ><span class="menu__tab-label" data-type="short"
83
+ >${tab.buttonText.short}</span
84
+ >`}
85
+ </button>
86
+ <div class="menu__panel" slot="dropdown">
87
+ <p class="menu__panel-title">
88
+ ${tab.panelTitle.slug
89
+ ? link(tab.panelTitle.slug, tab.panelTitle.text, {
90
+ primary: true,
91
+ })
92
+ : tab.panelTitle.text}
93
+ </p>
94
+ <div class="menu__panel-content">
95
+ ${tab.panelGroups.map((group) => {
96
+ const items = html`<ul>
97
+ ${group.items.map(
98
+ (item) =>
99
+ html`<li>
100
+ ${"render" in item
101
+ ? item.render()
102
+ : "slug" in item
103
+ ? link(item.slug, item.text, {
104
+ label: item.label,
105
+ })
106
+ : html`<a
107
+ class=${ifDefined(
108
+ [
109
+ item.icon && "menu__panel-icon",
110
+ context.locale !== "en-US" &&
111
+ "only-in-en-us",
112
+ ]
113
+ .filter(Boolean)
114
+ .join(" "),
115
+ )}
116
+ data-icon=${ifDefined(item.icon)}
117
+ href=${item.href}
118
+ aria-label=${ifDefined(item.label)}
119
+ title=${ifDefined(item.label)}
120
+ data-glean-id=${gleanId(item.href)}
121
+ >${item.text}</a
122
+ >`}
123
+ </li>`,
124
+ )}
125
+ </ul>`;
126
+
127
+ return "title" in group
128
+ ? html`<dl>
129
+ <dt>${group.title}</dt>
130
+ <dd>${items}</dd>
131
+ </dl>`
132
+ : items;
133
+ })}
134
+ </div>
135
+ </div>
136
+ </mdn-dropdown>`}
716
137
  </div>`;
717
- currentSection = null;
138
+ currentTab = null;
718
139
  return result;
719
140
  })}
720
141
  </nav>