@mdn/fred 2.4.3 → 2.6.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.
- package/.nvmrc +1 -1
- package/CHANGELOG.md +48 -0
- package/README.md +2 -0
- package/components/a11y-menu/server.js +2 -2
- package/components/baseline-indicator/server.js +86 -32
- package/components/breadcrumbs/server.js +6 -1
- package/components/collection-save-button/element.js +15 -0
- package/components/color-theme/element.js +17 -1
- package/components/compat-section/server.js +45 -0
- package/components/compat-table/element.js +10 -1
- package/components/compat-table/utils.js +10 -0
- package/components/compat-table-lazy/element.js +2 -5
- package/components/content-section/server.css +5 -0
- package/components/content-section/server.js +4 -22
- package/components/curriculum/sidebar.css +1 -1
- package/components/curriculum-landing/server.js +4 -1
- package/components/dropdown/element.js +12 -1
- package/components/env/index.js +1 -1
- package/components/featured-articles/server.js +10 -3
- package/components/footer/server.js +6 -1
- package/components/generic-about/server.js +1 -0
- package/components/generic-toc/server.js +6 -1
- package/components/language-always-redirect-button/element.js +2 -0
- package/components/language-switcher/element.js +5 -0
- package/components/latest-news/server.js +10 -3
- package/components/left-sidebar/server.css +1 -1
- package/components/login-button/element.js +1 -1
- package/components/menu/server.js +3 -1
- package/components/observatory-form/element.js +3 -0
- package/components/observatory-results/element.js +6 -1
- package/components/observatory-results/rating.js +6 -1
- package/components/outer-layout/server.js +3 -3
- package/components/placement-top/element.js +16 -4
- package/components/playground/element.js +17 -4
- package/components/recent-contributions/server.js +4 -1
- package/components/reference-toc/server.js +5 -1
- package/components/scrim-inline/element.js +13 -1
- package/components/server/index.js +4 -0
- package/components/sidebar-filter/element.js +11 -0
- package/components/sidebar-filter/sidebar-filterer.js +4 -2
- package/components/specifications-list/server.js +72 -0
- package/components/translation-banner/server.js +4 -1
- package/components/user-menu/element.js +1 -0
- package/components/viewed-controller/viewed-controller.js +15 -59
- package/components/viewed-controller/viewed-observer.js +79 -0
- package/hooks/glean-init.js +49 -6
- package/l10n/locales/zh-CN.ftl +317 -1
- package/out/service-worker.js +1 -1
- package/out/static/client/{2173.c74593faf7e14cbc.js → 2173.a662dd40657c8426.js} +2 -2
- package/out/static/client/{2173.c74593faf7e14cbc.js.map → 2173.a662dd40657c8426.js.map} +1 -1
- package/out/static/client/{251.db6a4b10ef58ad3a.js → 251.f498960ce719d884.js} +6 -6
- package/out/static/client/251.f498960ce719d884.js.map +1 -0
- package/out/static/client/{2868.b09544148fff25a1.js → 2868.03299f12d5927ed2.js} +2 -2
- package/out/static/client/{2868.b09544148fff25a1.js.map → 2868.03299f12d5927ed2.js.map} +1 -1
- package/out/static/client/{291.91650ffed3a60424.js → 291.c90e43b3c10a9a1f.js} +27 -16
- package/out/static/client/291.c90e43b3c10a9a1f.js.map +1 -0
- package/out/static/client/{3259.ac8a5539251c647a.js → 3259.c4b809cd884ad515.js} +29 -24
- package/out/static/client/3259.c4b809cd884ad515.js.map +1 -0
- package/out/static/client/{3775.c64e09b2fc1d9b21.js → 3775.cf93e968f166d25a.js} +2 -1
- package/out/static/client/{3775.c64e09b2fc1d9b21.js.map → 3775.cf93e968f166d25a.js.map} +1 -1
- package/out/static/client/{4060.9a7bb116e3112c13.js → 4060.a23acd149888555c.js} +2 -2
- package/out/static/client/{4060.9a7bb116e3112c13.js.map → 4060.a23acd149888555c.js.map} +1 -1
- package/out/static/client/4249.19f86ee6b57a13b0.js +2 -0
- package/out/static/client/4249.19f86ee6b57a13b0.js.map +1 -0
- package/out/static/client/{4759.8981c79d33088d8f.js → 4759.5852733a45132491.js} +2 -2
- package/out/static/client/{4759.8981c79d33088d8f.js.map → 4759.5852733a45132491.js.map} +1 -1
- package/out/static/client/{4920.033c028023478df5.js → 4920.929203da4613c89a.js} +3 -2
- package/out/static/client/4920.929203da4613c89a.js.map +1 -0
- package/out/static/client/{5183.6c532a6e7b0d0bbb.js → 5183.48a6059ffe2931f0.js} +12 -12
- package/out/static/client/5183.48a6059ffe2931f0.js.map +1 -0
- package/out/static/client/{5408.a0622390fa1726dc.css → 5408.77c9b71d6a5df982.css} +2 -2
- package/out/static/client/{5408.a0622390fa1726dc.css.map → 5408.77c9b71d6a5df982.css.map} +1 -1
- package/out/static/client/{544.1ed814181b24bcc8.js → 544.2ccdc928c5292631.js} +3 -3
- package/out/static/client/544.2ccdc928c5292631.js.map +1 -0
- package/out/static/client/{5667.332b2c6c10792ad6.js → 5667.edd77c81ec38a7e2.js} +5 -4
- package/out/static/client/5667.edd77c81ec38a7e2.js.map +1 -0
- package/out/static/client/5685.d30658d4c274ac13.js +4 -0
- package/out/static/client/5685.d30658d4c274ac13.js.map +1 -0
- package/out/static/client/6002.bb83fdc66501b6e4.js +167 -0
- package/out/static/client/6002.bb83fdc66501b6e4.js.map +1 -0
- package/out/static/client/{6067.a60fb66b75579c98.js → 6067.169a9ec1f47871ae.js} +3 -3
- package/out/static/client/6067.169a9ec1f47871ae.js.map +1 -0
- package/out/static/client/6216.2a29b5ce2a1bf6f6.js +2 -0
- package/out/static/client/6216.2a29b5ce2a1bf6f6.js.map +1 -0
- package/out/static/client/{8364.13d1d6770264c970.js → 8364.f7862244a6ff6a1b.js} +3 -3
- package/out/static/client/8364.f7862244a6ff6a1b.js.map +1 -0
- package/out/static/client/{9204.f8aa5d9f8a79f3d4.js → 9204.f45896951abfbd28.js} +3 -3
- package/out/static/client/{9204.f8aa5d9f8a79f3d4.js.map → 9204.f45896951abfbd28.js.map} +1 -1
- package/out/static/client/9324.9646c5839948c8ff.js +27 -0
- package/out/static/client/9324.9646c5839948c8ff.js.map +1 -0
- package/out/static/client/9456.a17794342ff9086a.js +319 -0
- package/out/static/client/9456.a17794342ff9086a.js.map +1 -0
- package/out/static/client/index.c41c45d10cf2b50b.js +221 -0
- package/out/static/client/index.c41c45d10cf2b50b.js.map +1 -0
- package/out/static/client/{runtime.8ebca7827bf4c35c.js → runtime.796d2e8ab20fb93f.js} +2 -2
- package/out/static/client/runtime.796d2e8ab20fb93f.js.map +1 -0
- package/out/static/client/stats.json +142 -142
- package/out/static/client/{styles-content-section.049c2352791fac9b.css → styles-content-section.cd5635d274b730e9.css} +2 -2
- package/out/static/client/{styles-content-section.049c2352791fac9b.css.map → styles-content-section.cd5635d274b730e9.css.map} +1 -1
- package/out/static/client/{styles-global.445b59e1ff23f88c.js → styles-global.2a17ab4cc47bca1f.js} +1 -1
- package/out/static/client/{styles-global.3da376739551015c.css → styles-global.79b14873ea7ab386.css} +2 -2
- package/out/static/client/{styles-global.3da376739551015c.css.map → styles-global.79b14873ea7ab386.css.map} +1 -1
- package/out/static/client/{styles-left-sidebar.6f954e8939555f77.css → styles-left-sidebar.517b9efefbdeed1d.css} +2 -2
- package/out/static/client/{styles-left-sidebar.6f954e8939555f77.css.map → styles-left-sidebar.517b9efefbdeed1d.css.map} +1 -1
- package/out/static/legacy/6753.072394f4f09652a0.js +27 -0
- package/out/static/legacy/6753.072394f4f09652a0.js.map +1 -0
- package/out/static/legacy/asset-manifest.json +5 -5
- package/out/static/legacy/{index.85161ba7fe682ee8.html → index.c05c933009dda5b3.html} +1 -1
- package/out/static/legacy/stats.json +9 -9
- package/out/static/legacy/{yari.01d97d56e30935ec.js → yari.e457418f21984506.js} +3 -3
- package/out/static/legacy/{yari.01d97d56e30935ec.js.map → yari.e457418f21984506.js.map} +1 -1
- package/out/static/ssr/9456.js +317 -1
- package/out/static/ssr/9456.js.map +1 -1
- package/out/static/ssr/index.js +315 -235
- package/out/static/ssr/index.js.map +1 -1
- package/out/static/ssr/stats.json +4 -4
- package/package.json +14 -8
- package/components/specifications-list/index.js +0 -60
- package/out/static/client/251.db6a4b10ef58ad3a.js.map +0 -1
- package/out/static/client/291.91650ffed3a60424.js.map +0 -1
- package/out/static/client/3259.ac8a5539251c647a.js.map +0 -1
- package/out/static/client/4920.033c028023478df5.js.map +0 -1
- package/out/static/client/5183.6c532a6e7b0d0bbb.js.map +0 -1
- package/out/static/client/544.1ed814181b24bcc8.js.map +0 -1
- package/out/static/client/5649.00f25ce181894101.js +0 -2
- package/out/static/client/5649.00f25ce181894101.js.map +0 -1
- package/out/static/client/5667.332b2c6c10792ad6.js.map +0 -1
- package/out/static/client/5685.46c8d178d072b8ac.js +0 -4
- package/out/static/client/5685.46c8d178d072b8ac.js.map +0 -1
- package/out/static/client/6067.a60fb66b75579c98.js.map +0 -1
- package/out/static/client/6216.f526aaf8b3dedd72.js +0 -2
- package/out/static/client/6216.f526aaf8b3dedd72.js.map +0 -1
- package/out/static/client/718.3a790c4c45336906.js +0 -167
- package/out/static/client/718.3a790c4c45336906.js.map +0 -1
- package/out/static/client/8364.13d1d6770264c970.js.map +0 -1
- package/out/static/client/9324.9bb064ea7377127e.js +0 -26
- package/out/static/client/9324.9bb064ea7377127e.js.map +0 -1
- package/out/static/client/9456.dd8c12ddf52e2a7d.js +0 -3
- package/out/static/client/9456.dd8c12ddf52e2a7d.js.map +0 -1
- package/out/static/client/index.b2ccf995e945e9dc.js +0 -221
- package/out/static/client/index.b2ccf995e945e9dc.js.map +0 -1
- package/out/static/client/runtime.8ebca7827bf4c35c.js.map +0 -1
- package/out/static/legacy/6753.811fcf40c897d487.js +0 -27
- package/out/static/legacy/6753.811fcf40c897d487.js.map +0 -1
- /package/out/static/client/{291.91650ffed3a60424.js.LICENSE.txt → 291.c90e43b3c10a9a1f.js.LICENSE.txt} +0 -0
- /package/out/static/client/{5183.6c532a6e7b0d0bbb.js.LICENSE.txt → 5183.48a6059ffe2931f0.js.LICENSE.txt} +0 -0
- /package/out/static/client/{6067.a60fb66b75579c98.js.LICENSE.txt → 6067.169a9ec1f47871ae.js.LICENSE.txt} +0 -0
- /package/out/static/client/{8364.13d1d6770264c970.js.LICENSE.txt → 8364.f7862244a6ff6a1b.js.LICENSE.txt} +0 -0
- /package/out/static/client/{index.b2ccf995e945e9dc.js.LICENSE.txt → index.c41c45d10cf2b50b.js.LICENSE.txt} +0 -0
- /package/out/static/legacy/{6753.811fcf40c897d487.js.LICENSE.txt → 6753.072394f4f09652a0.js.LICENSE.txt} +0 -0
- /package/out/static/legacy/{yari.01d97d56e30935ec.js.LICENSE.txt → yari.e457418f21984506.js.LICENSE.txt} +0 -0
|
@@ -186,6 +186,7 @@ export class Footer extends ServerComponent {
|
|
|
186
186
|
rel="noopener"
|
|
187
187
|
aria-label=${item.ariaLabel}
|
|
188
188
|
data-icon=${item.icon}
|
|
189
|
+
data-glean-id=${`footer: social -> ${item.icon}`}
|
|
189
190
|
></a>
|
|
190
191
|
</li>
|
|
191
192
|
`,
|
|
@@ -206,6 +207,7 @@ export class Footer extends ServerComponent {
|
|
|
206
207
|
class=${link.external ? "external" : ""}
|
|
207
208
|
target=${link.external ? "_blank" : undefined}
|
|
208
209
|
rel=${link.external ? "noopener" : undefined}
|
|
210
|
+
data-glean-id=${`footer: link -> ${link.href}`}
|
|
209
211
|
>
|
|
210
212
|
${link.text}
|
|
211
213
|
</a>
|
|
@@ -230,7 +232,10 @@ export class Footer extends ServerComponent {
|
|
|
230
232
|
${mozillaLinks(context).map(
|
|
231
233
|
(item) => html`
|
|
232
234
|
<li>
|
|
233
|
-
<a
|
|
235
|
+
<a
|
|
236
|
+
href=${item.href}
|
|
237
|
+
class=${item.external ? "external" : ""}
|
|
238
|
+
data-glean-id=${`footer: mozilla -> ${item.href}`}
|
|
234
239
|
>${item.text}</a
|
|
235
240
|
>
|
|
236
241
|
</li>
|
|
@@ -25,7 +25,12 @@ export class GenericToc extends ServerComponent {
|
|
|
25
25
|
${context.hyData.toc.map(
|
|
26
26
|
({ id, text }) =>
|
|
27
27
|
html`<li class="generic-toc__item">
|
|
28
|
-
<a
|
|
28
|
+
<a
|
|
29
|
+
class="generic-toc__link"
|
|
30
|
+
href="#${id}"
|
|
31
|
+
data-glean-id="toc_click: #${id}"
|
|
32
|
+
>${text}</a
|
|
33
|
+
>
|
|
29
34
|
</li>`,
|
|
30
35
|
)}
|
|
31
36
|
</ul>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { LitElement, html } from "lit";
|
|
2
2
|
|
|
3
|
+
import { gleanClick } from "../../utils/glean.js";
|
|
3
4
|
import { setPreferredLocale } from "../preferred-locale/utils.js";
|
|
4
5
|
|
|
5
6
|
export class MDNLanguageAlwaysRedirectButton extends LitElement {
|
|
@@ -15,6 +16,7 @@ export class MDNLanguageAlwaysRedirectButton extends LitElement {
|
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
_handleClick() {
|
|
19
|
+
gleanClick(`language: ${this.locale} -> ${this.to} (always)`);
|
|
18
20
|
setPreferredLocale(this.to);
|
|
19
21
|
const url = document.location.pathname.replace(
|
|
20
22
|
`/${this.locale}/`,
|
|
@@ -2,6 +2,7 @@ import { Task } from "@lit/task";
|
|
|
2
2
|
import { LitElement, html, nothing } from "lit";
|
|
3
3
|
|
|
4
4
|
import { L10nMixin } from "../../l10n/mixin.js";
|
|
5
|
+
import { gleanClick } from "../../utils/glean.js";
|
|
5
6
|
|
|
6
7
|
import infoIcon from "../icon/info.svg?lit";
|
|
7
8
|
import { getEnglishDoc } from "../not-found/utils.js";
|
|
@@ -63,12 +64,15 @@ export class MDNLanguageSwitcher extends L10nMixin(LitElement) {
|
|
|
63
64
|
|
|
64
65
|
_togglePreferredLocale() {
|
|
65
66
|
if (this.notFound) return;
|
|
67
|
+
const oldValue = this._preferredLocale ?? "0";
|
|
66
68
|
if (this._isLocalePreferred) {
|
|
67
69
|
resetPreferredLocale();
|
|
68
70
|
this._preferredLocale = undefined;
|
|
71
|
+
gleanClick(`language_remember: ${oldValue} -> 0`);
|
|
69
72
|
} else {
|
|
70
73
|
setPreferredLocale(this.locale);
|
|
71
74
|
this._preferredLocale = this.locale;
|
|
75
|
+
gleanClick(`language_remember: ${oldValue} -> ${this.locale}`);
|
|
72
76
|
}
|
|
73
77
|
}
|
|
74
78
|
|
|
@@ -160,6 +164,7 @@ export class MDNLanguageSwitcher extends L10nMixin(LitElement) {
|
|
|
160
164
|
`/${notFound ? "en-US" : locale}/`,
|
|
161
165
|
`/${translation.locale}/`,
|
|
162
166
|
)}
|
|
167
|
+
data-glean-id=${`language: ${locale} -> ${translation.locale}`}
|
|
163
168
|
>${translation.native}</a
|
|
164
169
|
>
|
|
165
170
|
</li>
|
|
@@ -14,16 +14,23 @@ export class LatestNews extends ServerComponent {
|
|
|
14
14
|
|
|
15
15
|
return html`<ul class="latest-news">
|
|
16
16
|
${items.map(
|
|
17
|
-
(item) =>
|
|
17
|
+
(item, index) =>
|
|
18
18
|
html`<li>
|
|
19
19
|
<article class="latest-news__item">
|
|
20
20
|
${item.source
|
|
21
|
-
? html`<a
|
|
21
|
+
? html`<a
|
|
22
|
+
class="latest-news__source"
|
|
23
|
+
href=${item.source.url}
|
|
24
|
+
data-glean-id=${`homepage: news_source ${index + 1} -> ${item.source.url}`}
|
|
22
25
|
>${item.source.name}</a
|
|
23
26
|
>`
|
|
24
27
|
: nothing}
|
|
25
28
|
<h3 class="latest-news__title">
|
|
26
|
-
<a
|
|
29
|
+
<a
|
|
30
|
+
href=${item.url}
|
|
31
|
+
data-glean-id=${`homepage: news ${index + 1} -> ${item.url}`}
|
|
32
|
+
>${item.title}</a
|
|
33
|
+
>
|
|
27
34
|
</h3>
|
|
28
35
|
<time class="latest-news__date" datetime=${item.published_at}>
|
|
29
36
|
${rtf.format(
|
|
@@ -16,7 +16,7 @@ export class MDNLoginButton extends L10nMixin(LitElement) {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
render() {
|
|
19
|
-
return html`<mdn-button href=${this._loginUrl}
|
|
19
|
+
return html`<mdn-button href=${this._loginUrl} data-glean-id="login_button"
|
|
20
20
|
>${this.l10n("login-button-login")`Login`}</mdn-button
|
|
21
21
|
>`;
|
|
22
22
|
}
|
|
@@ -71,7 +71,9 @@ export class Menu extends ServerComponent {
|
|
|
71
71
|
data-glean-id=${`menu_click_link: top-level -> ${tab.href}`}
|
|
72
72
|
>${tab.buttonText}</a
|
|
73
73
|
>`
|
|
74
|
-
: html`<mdn-dropdown
|
|
74
|
+
: html`<mdn-dropdown
|
|
75
|
+
data-glean-toggle-open=${`menu_toggle: ${tab.id}`}
|
|
76
|
+
>
|
|
75
77
|
<button class="menu__tab-button" type="button" slot="button">
|
|
76
78
|
${typeof tab.buttonText === "string"
|
|
77
79
|
? html`<span class="menu__tab-label"
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { LitElement, html, nothing } from "lit";
|
|
2
2
|
import { createRef, ref } from "lit/directives/ref.js";
|
|
3
3
|
|
|
4
|
+
import { gleanClick } from "../../utils/glean.js";
|
|
4
5
|
import { OBSERVATORY_API_URL } from "../env/index.js";
|
|
5
6
|
import "../progress-bar/element.js";
|
|
6
7
|
import "../button/element.js";
|
|
@@ -61,6 +62,7 @@ export class MDNObservatoryForm extends LitElement {
|
|
|
61
62
|
this._hostname = host;
|
|
62
63
|
}
|
|
63
64
|
this._queryRunning = true;
|
|
65
|
+
gleanClick("observatory: scan");
|
|
64
66
|
try {
|
|
65
67
|
const apiUrl = new URL(
|
|
66
68
|
OBSERVATORY_API_URL +
|
|
@@ -77,6 +79,7 @@ export class MDNObservatoryForm extends LitElement {
|
|
|
77
79
|
} catch (error) {
|
|
78
80
|
// @ts-expect-error
|
|
79
81
|
this._errorMessage = `${ERROR_MAP[error.name] || "message" in error ? error["message"] : error}`;
|
|
82
|
+
gleanClick(`observatory: error -> ${this._errorMessage}`);
|
|
80
83
|
} finally {
|
|
81
84
|
this._queryRunning = false;
|
|
82
85
|
}
|
|
@@ -2,6 +2,7 @@ import { Task } from "@lit/task";
|
|
|
2
2
|
import { LitElement, html } from "lit";
|
|
3
3
|
import { nothing } from "lit";
|
|
4
4
|
|
|
5
|
+
import { gleanClick } from "../../utils/glean.js";
|
|
5
6
|
import { OBSERVATORY_API_URL } from "../env/index.js";
|
|
6
7
|
|
|
7
8
|
import styles from "./element.css?lit";
|
|
@@ -62,7 +63,9 @@ export class MDNObservatoryResults extends LitElement {
|
|
|
62
63
|
}
|
|
63
64
|
return await res.json();
|
|
64
65
|
} catch (error) {
|
|
65
|
-
|
|
66
|
+
const message = "Observatory API request for scan data failed";
|
|
67
|
+
gleanClick(`observatory: error -> ${message}`);
|
|
68
|
+
throw new Error(message, {
|
|
66
69
|
cause: error,
|
|
67
70
|
});
|
|
68
71
|
}
|
|
@@ -116,6 +119,7 @@ export class MDNObservatoryResults extends LitElement {
|
|
|
116
119
|
if (!this.host) {
|
|
117
120
|
return;
|
|
118
121
|
}
|
|
122
|
+
gleanClick("observatory: rescan");
|
|
119
123
|
this._usePostInApi = true;
|
|
120
124
|
this._apiTask.run();
|
|
121
125
|
}
|
|
@@ -127,6 +131,7 @@ export class MDNObservatoryResults extends LitElement {
|
|
|
127
131
|
*/
|
|
128
132
|
_handleTabSelect(index, key) {
|
|
129
133
|
this.selectedTab = index;
|
|
134
|
+
gleanClick(`observatory: tab -> ${key}`);
|
|
130
135
|
globalThis.history.replaceState(
|
|
131
136
|
"",
|
|
132
137
|
"",
|
|
@@ -65,7 +65,12 @@ export function Rating({ result, host, rescan }) {
|
|
|
65
65
|
@click=${rescan}
|
|
66
66
|
></mdn-observatory-rescan-button>
|
|
67
67
|
<div class="scan-another">
|
|
68
|
-
<a
|
|
68
|
+
<a
|
|
69
|
+
href="/en-US/observatory"
|
|
70
|
+
data-glean-id="observatory: scan-another"
|
|
71
|
+
>
|
|
72
|
+
Scan another website
|
|
73
|
+
</a>
|
|
69
74
|
</div>
|
|
70
75
|
</section>
|
|
71
76
|
</section>
|
|
@@ -6,7 +6,7 @@ import { unsafeHTML } from "lit/directives/unsafe-html.js";
|
|
|
6
6
|
import inlineScript from "../../entry.inline.js?source&csp=true";
|
|
7
7
|
import {
|
|
8
8
|
ROBOTS_GLOBAL_ALLOW,
|
|
9
|
-
|
|
9
|
+
TRANSCEND_AIRGAP_URL,
|
|
10
10
|
WRITER_MODE,
|
|
11
11
|
} from "../env/index.js";
|
|
12
12
|
import { RUNTIME_ENV, runtimeVariables } from "../env/runtime.js";
|
|
@@ -116,12 +116,12 @@ export class OuterLayout extends ServerComponent {
|
|
|
116
116
|
fetchpriority="low"
|
|
117
117
|
/>`,
|
|
118
118
|
)}
|
|
119
|
-
${
|
|
119
|
+
${TRANSCEND_AIRGAP_URL &&
|
|
120
120
|
html`<script
|
|
121
121
|
data-cfasync="false"
|
|
122
122
|
data-report-only="on"
|
|
123
123
|
data-prompt="0"
|
|
124
|
-
src=${
|
|
124
|
+
src=${TRANSCEND_AIRGAP_URL}
|
|
125
125
|
></script>`}
|
|
126
126
|
${scripts?.map(
|
|
127
127
|
(path) => html`<script src=${path} type="module"></script>`,
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { LitElement, html, nothing } from "lit";
|
|
2
|
-
import { ref } from "lit/directives/ref.js";
|
|
2
|
+
import { createRef, ref } from "lit/directives/ref.js";
|
|
3
3
|
import { styleMap } from "lit/directives/style-map.js";
|
|
4
4
|
|
|
5
|
+
import { gleanClick } from "../../utils/glean.js";
|
|
6
|
+
import { PlacementMixin } from "../placement/mixin.js";
|
|
7
|
+
import { ViewedController } from "../viewed-controller/viewed-controller.js";
|
|
8
|
+
|
|
5
9
|
import "../placement-note/element.js";
|
|
6
10
|
import "../placement-no/element.js";
|
|
7
11
|
|
|
8
|
-
import { PlacementMixin } from "../placement/mixin.js";
|
|
9
|
-
|
|
10
12
|
import styles from "./element.css?lit";
|
|
11
13
|
|
|
12
14
|
/**
|
|
@@ -17,6 +19,16 @@ import styles from "./element.css?lit";
|
|
|
17
19
|
export class MDNPlacementTop extends PlacementMixin(LitElement) {
|
|
18
20
|
static styles = styles;
|
|
19
21
|
|
|
22
|
+
/** @type {import("lit/directives/ref.js").Ref<HTMLElement>} */
|
|
23
|
+
_fallbackRef = createRef();
|
|
24
|
+
|
|
25
|
+
constructor() {
|
|
26
|
+
super();
|
|
27
|
+
new ViewedController(this, this._fallbackRef, () => {
|
|
28
|
+
gleanClick("banner_scrimba_view");
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
20
32
|
/**
|
|
21
33
|
*
|
|
22
34
|
* @returns {TemplateResult | symbol}
|
|
@@ -27,7 +39,7 @@ export class MDNPlacementTop extends PlacementMixin(LitElement) {
|
|
|
27
39
|
|
|
28
40
|
renderFallback() {
|
|
29
41
|
return html`
|
|
30
|
-
<div class="fallback">
|
|
42
|
+
<div ${ref(this._fallbackRef)} class="fallback">
|
|
31
43
|
<p class="fallback__copy">
|
|
32
44
|
Learn frontend, backend, and AI from our course partner
|
|
33
45
|
<a
|
|
@@ -342,6 +342,7 @@ ${"```"}`,
|
|
|
342
342
|
@click=${this._share}
|
|
343
343
|
?disabled=${!hasCode}
|
|
344
344
|
data-id="share"
|
|
345
|
+
data-glean-id="playground: share-click"
|
|
345
346
|
>${this.l10n("playground-share")`Share`}</mdn-button
|
|
346
347
|
>
|
|
347
348
|
<mdn-button
|
|
@@ -356,6 +357,7 @@ ${"```"}`,
|
|
|
356
357
|
variant="secondary"
|
|
357
358
|
@click=${this._reset}
|
|
358
359
|
?disabled=${!isResettable}
|
|
360
|
+
data-glean-id="playground: reset-click"
|
|
359
361
|
>${this.l10n("playground-reset")`Reset`}</mdn-button
|
|
360
362
|
>`
|
|
361
363
|
: nothing}
|
|
@@ -391,6 +393,7 @@ ${"```"}`,
|
|
|
391
393
|
@click=${this._reportOpen}
|
|
392
394
|
variant="secondary"
|
|
393
395
|
.icon=${warningIcon}
|
|
396
|
+
data-glean-id="playground: flag-click"
|
|
394
397
|
>
|
|
395
398
|
${this.l10n(
|
|
396
399
|
"playground-seeing-something-inappropriate",
|
|
@@ -437,8 +440,14 @@ ${"```"}`,
|
|
|
437
440
|
)`Share your code via Permalink`}
|
|
438
441
|
</h2>
|
|
439
442
|
${this._user.render({
|
|
440
|
-
initial: () =>
|
|
441
|
-
|
|
443
|
+
initial: () =>
|
|
444
|
+
html`<mdn-login-button
|
|
445
|
+
data-glean-id="playground: banner-login"
|
|
446
|
+
></mdn-login-button>`,
|
|
447
|
+
pending: () =>
|
|
448
|
+
html`<mdn-login-button
|
|
449
|
+
data-glean-id="playground: banner-login"
|
|
450
|
+
></mdn-login-button>`,
|
|
442
451
|
complete: (user) =>
|
|
443
452
|
user.isAuthenticated
|
|
444
453
|
? this._permalink && !isResettable
|
|
@@ -453,12 +462,16 @@ ${"```"}`,
|
|
|
453
462
|
)`Copy to clipboard`}</mdn-button
|
|
454
463
|
>
|
|
455
464
|
`
|
|
456
|
-
: html`<mdn-button
|
|
465
|
+
: html`<mdn-button
|
|
466
|
+
@click=${this._createPermalink}
|
|
467
|
+
data-glean-id="playground: share-permalink"
|
|
457
468
|
>${this.l10n(
|
|
458
469
|
"playground-create-link",
|
|
459
470
|
)`Create link`}</mdn-button
|
|
460
471
|
>`
|
|
461
|
-
: html`<mdn-login-button
|
|
472
|
+
: html`<mdn-login-button
|
|
473
|
+
data-glean-id="playground: banner-login"
|
|
474
|
+
></mdn-login-button>`,
|
|
462
475
|
})}
|
|
463
476
|
</section>
|
|
464
477
|
</mdn-modal>
|
|
@@ -33,7 +33,10 @@ export class RecentContributions extends ServerComponent {
|
|
|
33
33
|
)}
|
|
34
34
|
</time>
|
|
35
35
|
<div class="recent-contributions__title">
|
|
36
|
-
<a
|
|
36
|
+
<a
|
|
37
|
+
class="external"
|
|
38
|
+
href=${contribution.url}
|
|
39
|
+
data-glean-id=${`homepage: contribution ${index + 1} -> ${contribution.url}`}
|
|
37
40
|
>${contribution.title}</a
|
|
38
41
|
>
|
|
39
42
|
</div>
|
|
@@ -21,7 +21,11 @@ export class ReferenceToc extends ServerComponent {
|
|
|
21
21
|
<ul>
|
|
22
22
|
${toc?.map(
|
|
23
23
|
({ id, text }) =>
|
|
24
|
-
html`<li
|
|
24
|
+
html`<li>
|
|
25
|
+
<a href="#${id}" data-glean-id="toc_click: #${id}"
|
|
26
|
+
>${unsafeHTML(text)}</a
|
|
27
|
+
>
|
|
28
|
+
</li>`,
|
|
25
29
|
)}
|
|
26
30
|
</ul>
|
|
27
31
|
</nav>`;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { LitElement, html, nothing } from "lit";
|
|
2
2
|
import { ifDefined } from "lit/directives/if-defined.js";
|
|
3
|
+
import { createRef, ref } from "lit/directives/ref.js";
|
|
3
4
|
import { styleMap } from "lit/directives/style-map.js";
|
|
4
5
|
|
|
5
6
|
import { L10nMixin } from "../../l10n/mixin.js";
|
|
7
|
+
import { gleanClick } from "../../utils/glean.js";
|
|
8
|
+
import { ViewedController } from "../viewed-controller/viewed-controller.js";
|
|
6
9
|
|
|
7
10
|
import playSvg from "./assets/scrim-play.svg?lit";
|
|
8
11
|
import styles from "./element.css?lit";
|
|
@@ -20,6 +23,9 @@ export class MDNScrimInline extends L10nMixin(LitElement) {
|
|
|
20
23
|
_scrimLoaded: { state: true },
|
|
21
24
|
};
|
|
22
25
|
|
|
26
|
+
/** @type {import("lit/directives/ref.js").Ref<HTMLElement>} */
|
|
27
|
+
_bodyRef = createRef();
|
|
28
|
+
|
|
23
29
|
constructor() {
|
|
24
30
|
super();
|
|
25
31
|
/** @type {string | undefined} */
|
|
@@ -41,6 +47,12 @@ export class MDNScrimInline extends L10nMixin(LitElement) {
|
|
|
41
47
|
this._fullscreen = false;
|
|
42
48
|
/** @type {boolean} */
|
|
43
49
|
this._scrimLoaded = false;
|
|
50
|
+
|
|
51
|
+
new ViewedController(this, this._bodyRef, () => {
|
|
52
|
+
if (this._scrimId) {
|
|
53
|
+
gleanClick(`curriculum: scrim view id:${this._scrimId}`);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
44
56
|
}
|
|
45
57
|
|
|
46
58
|
/**
|
|
@@ -109,7 +121,7 @@ export class MDNScrimInline extends L10nMixin(LitElement) {
|
|
|
109
121
|
>
|
|
110
122
|
</a>
|
|
111
123
|
</div>
|
|
112
|
-
<div class="body">
|
|
124
|
+
<div class="body" ${ref(this._bodyRef)}>
|
|
113
125
|
${this._scrimLoaded
|
|
114
126
|
? html`
|
|
115
127
|
<iframe
|
|
@@ -13,6 +13,9 @@ export class ServerComponent {
|
|
|
13
13
|
/** @type {string | undefined} */
|
|
14
14
|
static inlineScript;
|
|
15
15
|
|
|
16
|
+
/** `true` if we're rendering in a renderSimplified context */
|
|
17
|
+
simplifiedMode = false;
|
|
18
|
+
|
|
16
19
|
/**
|
|
17
20
|
* @template {typeof ServerComponent} T
|
|
18
21
|
* @this {T}
|
|
@@ -28,6 +31,7 @@ export class ServerComponent {
|
|
|
28
31
|
const component = new this();
|
|
29
32
|
|
|
30
33
|
if ("renderSimplified" in asyncStore) {
|
|
34
|
+
component.simplifiedMode = true;
|
|
31
35
|
return component.renderSimplified(...args);
|
|
32
36
|
}
|
|
33
37
|
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { LitElement, html } from "lit";
|
|
6
6
|
|
|
7
7
|
import { L10nMixin } from "../../l10n/mixin.js";
|
|
8
|
+
import { gleanClick } from "../../utils/glean.js";
|
|
8
9
|
import cancelIcon from "../icon/cancel.svg?lit";
|
|
9
10
|
|
|
10
11
|
import styles from "./element.css?lit";
|
|
@@ -91,6 +92,7 @@ class MDNSidebarFilter extends L10nMixin(LitElement) {
|
|
|
91
92
|
// Mark that the user has typed if the query is non-empty.
|
|
92
93
|
if (this.query && this.query.trim().length > 0 && !this.hasTyped) {
|
|
93
94
|
this.hasTyped = true;
|
|
95
|
+
gleanClick("sidebar_filter_typed");
|
|
94
96
|
}
|
|
95
97
|
|
|
96
98
|
if (this._quicklinks) {
|
|
@@ -116,6 +118,14 @@ class MDNSidebarFilter extends L10nMixin(LitElement) {
|
|
|
116
118
|
}
|
|
117
119
|
}
|
|
118
120
|
|
|
121
|
+
/**
|
|
122
|
+
* Event handler for focus events on the text field.
|
|
123
|
+
* @private
|
|
124
|
+
*/
|
|
125
|
+
_onFocus() {
|
|
126
|
+
gleanClick("sidebar_filter_focus");
|
|
127
|
+
}
|
|
128
|
+
|
|
119
129
|
/**
|
|
120
130
|
* Event handler for input events on the text field.
|
|
121
131
|
* @param {Event} event The input event.
|
|
@@ -152,6 +162,7 @@ class MDNSidebarFilter extends L10nMixin(LitElement) {
|
|
|
152
162
|
type="text"
|
|
153
163
|
placeholder=${this.l10n("sidebar-filter-filter")`Filter`}
|
|
154
164
|
.value=${this.query}
|
|
165
|
+
@focus=${this._onFocus}
|
|
155
166
|
@input=${this._onInput}
|
|
156
167
|
/>
|
|
157
168
|
${this.matchCount === undefined
|
|
@@ -154,7 +154,9 @@ export class SidebarFilterer {
|
|
|
154
154
|
* @param {HTMLAnchorElement} link The link element to reset.
|
|
155
155
|
*/
|
|
156
156
|
resetHighlighting(link) {
|
|
157
|
-
const nodes = [
|
|
157
|
+
const nodes = [
|
|
158
|
+
...link.querySelectorAll("span.sidebar-filter-mark-container, mark"),
|
|
159
|
+
];
|
|
158
160
|
const parents = new Set();
|
|
159
161
|
for (const node of nodes) {
|
|
160
162
|
const parent = node.parentElement;
|
|
@@ -250,7 +252,7 @@ export class SidebarFilterer {
|
|
|
250
252
|
);
|
|
251
253
|
|
|
252
254
|
const span = this.replaceChildNode(node, "span");
|
|
253
|
-
span.className = "
|
|
255
|
+
span.className = "sidebar-filter-mark-container";
|
|
254
256
|
|
|
255
257
|
/** @type {Text|undefined} */
|
|
256
258
|
const initialRest = [...span.childNodes].find(
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { html } from "@lit-labs/ssr";
|
|
2
|
+
import { join } from "lit/directives/join.js";
|
|
3
|
+
|
|
4
|
+
import { ServerComponent } from "../server/index.js";
|
|
5
|
+
|
|
6
|
+
export class SpecificationsList extends ServerComponent {
|
|
7
|
+
/**
|
|
8
|
+
* @param {import("@fred").Context} context
|
|
9
|
+
* @param {import("@rari").Specification[]} specifications
|
|
10
|
+
*/
|
|
11
|
+
render(context, specifications) {
|
|
12
|
+
if (specifications.length === 0) {
|
|
13
|
+
return html`${context.l10n(
|
|
14
|
+
"specifications-list-this-feature-does-not-appear-to",
|
|
15
|
+
)`This feature does not appear to be defined in any specification.`}`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** @type {Map<string, string[]>} */
|
|
19
|
+
const urlsByTitle = new Map();
|
|
20
|
+
for (const { title, bcdSpecificationURL: url } of specifications) {
|
|
21
|
+
const urls = urlsByTitle.get(title) ?? [];
|
|
22
|
+
urls.push(url);
|
|
23
|
+
urlsByTitle.set(title, urls);
|
|
24
|
+
}
|
|
25
|
+
const links = urlsByTitle
|
|
26
|
+
.entries()
|
|
27
|
+
.flatMap(([title, urls]) =>
|
|
28
|
+
urls.map((url) => this.renderLink(url, title)),
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
if (this.simplifiedMode) {
|
|
32
|
+
return html`<ul>
|
|
33
|
+
${links.map((link) => html`<li>${link}</li>`)}
|
|
34
|
+
</ul>`;
|
|
35
|
+
}
|
|
36
|
+
return html`<table>
|
|
37
|
+
<thead>
|
|
38
|
+
<tr>
|
|
39
|
+
<th scope="col">
|
|
40
|
+
${context.l10n("specifications-list-specification")`Specification`}
|
|
41
|
+
</th>
|
|
42
|
+
</tr>
|
|
43
|
+
</thead>
|
|
44
|
+
<tbody>
|
|
45
|
+
${links.map(
|
|
46
|
+
(link) =>
|
|
47
|
+
html`<tr>
|
|
48
|
+
<td>${link}</td>
|
|
49
|
+
</tr>`,
|
|
50
|
+
)}
|
|
51
|
+
</tbody>
|
|
52
|
+
</table>`;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @param {string} url
|
|
57
|
+
* @param {string} [title]
|
|
58
|
+
*/
|
|
59
|
+
renderLink(url, title) {
|
|
60
|
+
const hash = url.split("#")[1];
|
|
61
|
+
|
|
62
|
+
const label = [
|
|
63
|
+
title && html`${title}`,
|
|
64
|
+
title && hash && html`<br />`,
|
|
65
|
+
hash && html`# ${hash}`,
|
|
66
|
+
].filter(Boolean);
|
|
67
|
+
|
|
68
|
+
return html`<a class="external" href=${url} rel="noopener" target="_blank"
|
|
69
|
+
>${join(label, "")}</a
|
|
70
|
+
>`;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -99,7 +99,10 @@ export class TranslationBanner extends ServerComponent {
|
|
|
99
99
|
// Note: Do not translate, this is intentionally in English.
|
|
100
100
|
|
|
101
101
|
return html`<p class="translation-banner__switch" lang="en-US">
|
|
102
|
-
<mdn-button
|
|
102
|
+
<mdn-button
|
|
103
|
+
data-variant="secondary"
|
|
104
|
+
href=${url}
|
|
105
|
+
data-glean-id=${`language: ${context.locale} -> en-US (view)`}
|
|
103
106
|
>View in English</mdn-button
|
|
104
107
|
>
|
|
105
108
|
<mdn-language-always-redirect-button locale=${context.locale} to="en-US"
|