@mdn/fred 2.5.0 → 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/CHANGELOG.md +21 -0
- package/components/a11y-menu/server.js +2 -2
- 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-table/element.js +10 -1
- package/components/content-section/server.css +5 -0
- package/components/curriculum-landing/server.js +4 -1
- package/components/dropdown/element.js +12 -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/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/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/sidebar-filter/element.js +11 -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/{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/{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.60280d36f6ea71ff.js → 6002.bb83fdc66501b6e4.js} +27 -27
- 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/{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.61778c81f15bcebc.js.map → 9324.9646c5839948c8ff.js.map} +1 -1
- 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.5a92d4f860d6d798.js → runtime.796d2e8ab20fb93f.js} +2 -2
- package/out/static/client/{runtime.5a92d4f860d6d798.js.map → runtime.796d2e8ab20fb93f.js.map} +1 -1
- package/out/static/client/stats.json +134 -134
- 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.64aa0c760d2688b4.js → styles-global.2a17ab4cc47bca1f.js} +1 -1
- package/out/static/client/styles-global.79b14873ea7ab386.css +2 -0
- package/out/static/client/{styles-global.274bf4a7ba3e88ae.css.map → styles-global.79b14873ea7ab386.css.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 +209 -145
- package/out/static/ssr/index.js.map +1 -1
- package/out/static/ssr/stats.json +4 -4
- package/package.json +6 -6
- 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/6002.60280d36f6ea71ff.js.map +0 -1
- package/out/static/client/6067.a60fb66b75579c98.js.map +0 -1
- package/out/static/client/8364.13d1d6770264c970.js.map +0 -1
- package/out/static/client/9324.61778c81f15bcebc.js +0 -26
- package/out/static/client/9456.dd8c12ddf52e2a7d.js +0 -3
- package/out/static/client/9456.dd8c12ddf52e2a7d.js.map +0 -1
- package/out/static/client/index.ae68bec0e2489b62.js +0 -221
- package/out/static/client/index.ae68bec0e2489b62.js.map +0 -1
- package/out/static/client/styles-global.274bf4a7ba3e88ae.css +0 -2
- /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.ae68bec0e2489b62.js.LICENSE.txt → index.c41c45d10cf2b50b.js.LICENSE.txt} +0 -0
|
@@ -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
|
|
@@ -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
|
|
@@ -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"
|
|
@@ -3,86 +3,42 @@
|
|
|
3
3
|
* @import { Ref } from "lit/directives/ref.js";
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
threshold: 0.5,
|
|
8
|
-
};
|
|
6
|
+
import { ViewedObserver } from "./viewed-observer.js";
|
|
9
7
|
|
|
10
8
|
export class ViewedController {
|
|
11
9
|
#host;
|
|
10
|
+
/** @type {ViewedObserver | null} */
|
|
11
|
+
observer = null;
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* @param {LitElement} host
|
|
15
15
|
* @param {Ref<Element>} target
|
|
16
16
|
* @param {Function} callback
|
|
17
|
-
* @param {IntersectionObserverInit} [
|
|
17
|
+
* @param {IntersectionObserverInit} [observerOptions]
|
|
18
18
|
*/
|
|
19
|
-
constructor(host, target, callback,
|
|
19
|
+
constructor(host, target, callback, observerOptions) {
|
|
20
20
|
this.#host = host;
|
|
21
21
|
this.#host.addController(this);
|
|
22
22
|
|
|
23
23
|
this.target = target;
|
|
24
24
|
this.callback = callback;
|
|
25
|
-
this.
|
|
26
|
-
|
|
27
|
-
this._visible = !globalThis.document?.hidden;
|
|
28
|
-
this._timer = null;
|
|
29
|
-
this._hasViewed = false;
|
|
30
|
-
this._onVisibilityChange = this.onVisibilityChange.bind(this);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
hostConnected() {
|
|
34
|
-
document.addEventListener("visibilitychange", this._onVisibilityChange);
|
|
25
|
+
this.observerOptions = observerOptions;
|
|
35
26
|
}
|
|
36
27
|
|
|
37
28
|
hostDisconnected() {
|
|
38
|
-
this.
|
|
39
|
-
|
|
29
|
+
this.observer?.disconnect();
|
|
30
|
+
this.observer = null;
|
|
40
31
|
}
|
|
41
32
|
|
|
42
33
|
hostUpdated() {
|
|
43
34
|
const target = this.target.value;
|
|
44
|
-
if (target) {
|
|
45
|
-
this.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
this.
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
disconnectObserver() {
|
|
55
|
-
if (this._observer) {
|
|
56
|
-
this._observer.disconnect();
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
onVisibilityChange() {
|
|
61
|
-
this._visible = !document.hidden;
|
|
62
|
-
this._checkAndSetTimer();
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* If the page is visible and the element is intersecting, start a 1-second timer
|
|
67
|
-
* to dispatch the "view" event.
|
|
68
|
-
*
|
|
69
|
-
* If conditions are not met before the timer fires, clear the timer.
|
|
70
|
-
*
|
|
71
|
-
* @param {boolean} isIntersecting
|
|
72
|
-
*/
|
|
73
|
-
_checkAndSetTimer(isIntersecting = false) {
|
|
74
|
-
if (!this._hasViewed && this._visible && isIntersecting) {
|
|
75
|
-
if (this._timer === null) {
|
|
76
|
-
this._timer = globalThis.setTimeout(() => {
|
|
77
|
-
this._hasViewed = true;
|
|
78
|
-
this.callback();
|
|
79
|
-
}, 1000);
|
|
80
|
-
}
|
|
81
|
-
} else {
|
|
82
|
-
if (this._timer !== null) {
|
|
83
|
-
clearTimeout(this._timer);
|
|
84
|
-
this._timer = null;
|
|
85
|
-
}
|
|
35
|
+
if (target && !this.observer) {
|
|
36
|
+
this.observer = new ViewedObserver(
|
|
37
|
+
target,
|
|
38
|
+
this.callback,
|
|
39
|
+
this.observerOptions,
|
|
40
|
+
);
|
|
41
|
+
this.observer.connect();
|
|
86
42
|
}
|
|
87
43
|
}
|
|
88
44
|
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
const OPTIONS = {
|
|
2
|
+
threshold: 0.5,
|
|
3
|
+
};
|
|
4
|
+
|
|
5
|
+
export class ViewedObserver {
|
|
6
|
+
#element;
|
|
7
|
+
#callback;
|
|
8
|
+
#options;
|
|
9
|
+
|
|
10
|
+
/** @type {IntersectionObserver | null} */
|
|
11
|
+
#observer = null;
|
|
12
|
+
/** @type {ReturnType<typeof setTimeout> | null} */
|
|
13
|
+
#timer = null;
|
|
14
|
+
#hasViewed = false;
|
|
15
|
+
#visible = !globalThis.document?.hidden;
|
|
16
|
+
#onVisibilityChange = this.#handleVisibilityChange.bind(this);
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @param {Element} element
|
|
20
|
+
* @param {Function} callback
|
|
21
|
+
* @param {IntersectionObserverInit} [options]
|
|
22
|
+
*/
|
|
23
|
+
constructor(element, callback, options = OPTIONS) {
|
|
24
|
+
this.#element = element;
|
|
25
|
+
this.#callback = callback;
|
|
26
|
+
this.#options = options;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
connect() {
|
|
30
|
+
document.addEventListener("visibilitychange", this.#onVisibilityChange);
|
|
31
|
+
this.#observer = new IntersectionObserver((entries) => {
|
|
32
|
+
for (const entry of entries) {
|
|
33
|
+
this.#checkAndSetTimer(entry.isIntersecting);
|
|
34
|
+
}
|
|
35
|
+
}, this.#options);
|
|
36
|
+
this.#observer.observe(this.#element);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
disconnect() {
|
|
40
|
+
if (this.#observer) {
|
|
41
|
+
this.#observer.disconnect();
|
|
42
|
+
this.#observer = null;
|
|
43
|
+
}
|
|
44
|
+
if (this.#timer !== null) {
|
|
45
|
+
clearTimeout(this.#timer);
|
|
46
|
+
this.#timer = null;
|
|
47
|
+
}
|
|
48
|
+
document.removeEventListener("visibilitychange", this.#onVisibilityChange);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
#handleVisibilityChange() {
|
|
52
|
+
this.#visible = !document.hidden;
|
|
53
|
+
this.#checkAndSetTimer();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* If the page is visible and the element is intersecting, start a 1-second timer
|
|
58
|
+
* to dispatch the "view" event.
|
|
59
|
+
*
|
|
60
|
+
* If conditions are not met before the timer fires, clear the timer.
|
|
61
|
+
*
|
|
62
|
+
* @param {boolean} isIntersecting
|
|
63
|
+
*/
|
|
64
|
+
#checkAndSetTimer(isIntersecting = false) {
|
|
65
|
+
if (!this.#hasViewed && this.#visible && isIntersecting) {
|
|
66
|
+
if (this.#timer === null) {
|
|
67
|
+
this.#timer = globalThis.setTimeout(() => {
|
|
68
|
+
this.#hasViewed = true;
|
|
69
|
+
this.#callback();
|
|
70
|
+
}, 1000);
|
|
71
|
+
}
|
|
72
|
+
} else {
|
|
73
|
+
if (this.#timer !== null) {
|
|
74
|
+
clearTimeout(this.#timer);
|
|
75
|
+
this.#timer = null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
package/hooks/glean-init.js
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
GLEAN_DEBUG,
|
|
6
6
|
GLEAN_ENABLED,
|
|
7
7
|
} from "../components/env/index.js";
|
|
8
|
+
import { ViewedObserver } from "../components/viewed-controller/viewed-observer.js";
|
|
8
9
|
import { gleanClick } from "../utils/glean.js";
|
|
9
10
|
import { userIsOptedOut } from "../utils/telemetry-opt-out.js";
|
|
10
11
|
|
|
@@ -23,16 +24,49 @@ Glean.initialize(GLEAN_APP_ID, uploadEnabled, {
|
|
|
23
24
|
channel: GLEAN_CHANNEL,
|
|
24
25
|
});
|
|
25
26
|
|
|
27
|
+
// data-glean-toggle-open
|
|
28
|
+
document.addEventListener("toggle", (event) => {
|
|
29
|
+
const composedPath = event.composedPath();
|
|
30
|
+
for (const el of composedPath) {
|
|
31
|
+
if (
|
|
32
|
+
el instanceof HTMLElement &&
|
|
33
|
+
typeof el.dataset.gleanToggleOpen === "string" &&
|
|
34
|
+
"open" in el &&
|
|
35
|
+
el.open
|
|
36
|
+
) {
|
|
37
|
+
gleanClick(el.dataset.gleanToggleOpen);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// data-glean-view
|
|
43
|
+
for (const element of /** @type {NodeListOf<HTMLElement>} */ (
|
|
44
|
+
document.querySelectorAll("[data-glean-view]")
|
|
45
|
+
)) {
|
|
46
|
+
// Excludes shadow DOM, and elements added after page load.
|
|
47
|
+
// For custom elements, use `ViewedController()` instead.
|
|
48
|
+
const gleanId = element.dataset.gleanView;
|
|
49
|
+
if (gleanId) {
|
|
50
|
+
const observer = new ViewedObserver(element, () => {
|
|
51
|
+
gleanClick(gleanId);
|
|
52
|
+
observer.disconnect();
|
|
53
|
+
});
|
|
54
|
+
observer.connect();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// data-glean-id
|
|
26
59
|
document.addEventListener("click", (event) => {
|
|
27
|
-
const
|
|
60
|
+
const composedPath = event.composedPath();
|
|
61
|
+
const composedTarget = composedPath?.[0];
|
|
28
62
|
if (composedTarget !== event.target && composedTarget instanceof Element) {
|
|
29
63
|
// Workaround for automatic click events in shadow DOM.
|
|
30
64
|
// See: https://bugzil.la/1988206
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if (gleanId) {
|
|
35
|
-
gleanClick(gleanId);
|
|
65
|
+
|
|
66
|
+
// Measure click for all `data-glean-id`s along the path.
|
|
67
|
+
for (const el of composedPath) {
|
|
68
|
+
if (el instanceof HTMLElement && typeof el.dataset.gleanId === "string") {
|
|
69
|
+
gleanClick(el.dataset.gleanId);
|
|
36
70
|
}
|
|
37
71
|
}
|
|
38
72
|
}
|
|
@@ -49,5 +83,14 @@ document.addEventListener("click", (event) => {
|
|
|
49
83
|
) {
|
|
50
84
|
gleanClick(`external-link: ${anchor.href}`);
|
|
51
85
|
}
|
|
86
|
+
|
|
87
|
+
// Sidebar click measurement.
|
|
88
|
+
if (anchor instanceof HTMLAnchorElement && anchor.href) {
|
|
89
|
+
const sidebar = anchor.closest(".left-sidebar");
|
|
90
|
+
if (sidebar) {
|
|
91
|
+
const href = anchor.getAttribute("href") || anchor.href;
|
|
92
|
+
gleanClick(`sidebar_click: sidebar ${href}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
52
95
|
}
|
|
53
96
|
});
|
package/l10n/locales/zh-CN.ftl
CHANGED
|
@@ -1 +1,317 @@
|
|
|
1
|
-
|
|
1
|
+
article-footer-last-modified = 此页面最后更新于 <time data-l10n-name="date">{ $date }</time>,由 <a data-l10n-name="contributors">MDN 贡献者</a>更新。
|
|
2
|
+
article-footer-source-title = 文件夹:{ $folder }(在新标签页中打开)
|
|
3
|
+
baseline-asterisk = 此特性的某些部分的支持程度可能有所不同。
|
|
4
|
+
baseline-high-extra = 自 { $date } 起,此特性已在主流浏览器中得到支持,可在大多数设备和浏览器版本中正常使用。
|
|
5
|
+
baseline-low-extra = 自 { $date } 起,此特性已在最新浏览器中得到支持。但在较旧的设备或浏览器中可能无法运行。
|
|
6
|
+
baseline-not-extra = 此特性不属于基线,因为它尚未在主流浏览器中得到支持。
|
|
7
|
+
baseline-supported-in = 在 { $browsers } 中得到广泛支持
|
|
8
|
+
baseline-unsupported-in = 在 { $browsers } 中未被广泛支持
|
|
9
|
+
baseline-supported-and-unsupported-in = 在 { $supported } 中得到广泛支持,但在 { $unsupported } 中未被广泛支持
|
|
10
|
+
homepage-hero-title = 开发者的资源,<br>由开发者打造
|
|
11
|
+
homepage-hero-description = 自 2005 年以来,持续记录 <a data-l10n-name="css">CSS</a>、<a data-l10n-name="html">HTML</a> 和 <a data-l10n-name="js">JavaScript</a>。
|
|
12
|
+
not-found-title = 找不到页面
|
|
13
|
+
not-found-description = 抱歉,找不到页面 <code data-l10n-name="url">{ $url }</code>。
|
|
14
|
+
not-found-fallback-english = <strong data-l10n-name="strong">好消息:</strong>您请求的页面存在<em data-l10n-name="em">英文版本</em>。
|
|
15
|
+
not-found-fallback-search = 您请求的页面不存在,但您可以尝试站内搜索:
|
|
16
|
+
not-found-back = 返回首页
|
|
17
|
+
footer-mofo = 访问 <a data-l10n-name="moco">Mozilla 公司</a>的非营利母机构 <a data-l10n-name="mofo">Mozilla 基金会</a>。
|
|
18
|
+
footer-copyright = 本内容的部分版权归 mozilla.org 贡献者所有,©1998–{ $year }。内容依据<a data-l10n-name="cc">知识共享许可协议</a>提供。
|
|
19
|
+
search-modal-site-search = 站内搜索 <em>{ $query }</em>
|
|
20
|
+
site-search-search-stats = 找到 { $results } 个文档。
|
|
21
|
+
site-search-suggestion-matches =
|
|
22
|
+
{ $relation ->
|
|
23
|
+
[gt]
|
|
24
|
+
超过 { $matches ->
|
|
25
|
+
[one] { $matches } 个匹配项
|
|
26
|
+
*[other] { $matches } 个匹配项
|
|
27
|
+
}
|
|
28
|
+
*[eq]
|
|
29
|
+
{ $matches ->
|
|
30
|
+
[one] { $matches } 个匹配项
|
|
31
|
+
*[other] { $matches } 个匹配项
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
blog-time-to-read =
|
|
35
|
+
{ $minutes ->
|
|
36
|
+
[one] 阅读需 { $minutes } 分钟
|
|
37
|
+
*[other] 阅读需 { $minutes } 分钟
|
|
38
|
+
}
|
|
39
|
+
-brand-name-obs = HTTP Observatory
|
|
40
|
+
obs-report = 报告
|
|
41
|
+
obs-title = { -brand-name-obs }
|
|
42
|
+
obs-landing-intro = { -brand-name-obs } 于 2016 年推出,通过分析网站对安全最佳实践的符合情况来提升 Web 安全性。它已通过 4700 万次扫描为超过 690 万个网站提供了洞察。
|
|
43
|
+
obs-assessment = 由 Mozilla 开发的 { -brand-name-obs } 会对网站的 HTTP 标头及其他关键安全配置进行深入分析。
|
|
44
|
+
obs-scanning = 其自动化扫描流程会为开发者和网站管理员提供详细且可执行的反馈,重点在于识别并解决潜在的安全漏洞。
|
|
45
|
+
obs-security = 在不断发展的数字环境中,该工具对于帮助开发者和网站管理员提升网站抵御常见安全威胁的能力至关重要。
|
|
46
|
+
obs-mdn = { -brand-name-obs } 依托 Mozilla 的专业知识及其对更安全互联网的承诺,并基于成熟的趋势和指南,提供有效的安全洞察。
|
|
47
|
+
compat-browser-version-date = { $browser } { $version }——发布日期:{ $date }
|
|
48
|
+
compat-browser-version-released = 发布日期:{ $date }
|
|
49
|
+
compat-link-source-title = 文件:{ $filename }
|
|
50
|
+
compat-support-prefix = 使用了厂商前缀实现:{ $prefix }
|
|
51
|
+
compat-support-altname = 备用名称:{ $altname }
|
|
52
|
+
compat-support-removed = 已在 { $version } 及更高版本中移除
|
|
53
|
+
compat-support-see-impl-url = 参见 <a data-l10n-name="impl_url">{ $label }</a>
|
|
54
|
+
compat-support-flags =
|
|
55
|
+
{ NUMBER($has_added) ->
|
|
56
|
+
[one] 自版本 { $version_added } 起
|
|
57
|
+
*[other] { "" }
|
|
58
|
+
}{ $has_last ->
|
|
59
|
+
[one]
|
|
60
|
+
{ NUMBER($has_added) ->
|
|
61
|
+
*[zero] 截至 { $versionLast },用户
|
|
62
|
+
[one] { " " }截至 { $versionLast },用户
|
|
63
|
+
}
|
|
64
|
+
*[zero]
|
|
65
|
+
{ NUMBER($has_added) ->
|
|
66
|
+
*[zero] 用户
|
|
67
|
+
[one] { " " }用户
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
{ " " }必须显式将 <code data-l10n-name="name">{ $flag_name }</code>{ " " }
|
|
71
|
+
{ $flag_type ->
|
|
72
|
+
*[preference] 首选项
|
|
73
|
+
[runtime_flag] 运行时标志
|
|
74
|
+
}{ NUMBER($has_value) ->
|
|
75
|
+
[one] { " " }设置为 <code data-l10n-name="value">{ $flag_value }</code>
|
|
76
|
+
*[other] { "" }
|
|
77
|
+
}{ "。" }
|
|
78
|
+
{ NUMBER($has_pref_url) ->
|
|
79
|
+
[one]
|
|
80
|
+
{ $flag_type ->
|
|
81
|
+
[preference] 要更改 { $browser_name } 中的首选项,请访问 { $browser_pref_url }。
|
|
82
|
+
*[other] { "" }
|
|
83
|
+
}
|
|
84
|
+
*[other] { "" }
|
|
85
|
+
}
|
|
86
|
+
compat-legend-yes = { compat-support-full }
|
|
87
|
+
compat-legend-partial = { compat-support-partial }
|
|
88
|
+
compat-legend-preview = 开发中。在预发布版本中受支持。
|
|
89
|
+
compat-legend-no = { compat-support-no }
|
|
90
|
+
compat-legend-unknown = 兼容性未知
|
|
91
|
+
compat-legend-experimental = { compat-experimental }。预计未来行为可能会发生变化。
|
|
92
|
+
compat-legend-nonstandard = { compat-nonstandard }。使用前请检查跨浏览器支持情况。
|
|
93
|
+
compat-legend-deprecated = { compat-deprecated }。不建议在新网站中使用。
|
|
94
|
+
compat-legend-footnote = 参见实现说明。
|
|
95
|
+
compat-legend-disabled = 用户必须显式启用此特性。
|
|
96
|
+
compat-legend-altname = 使用了非标准名称。
|
|
97
|
+
compat-legend-prefix = 使用时需要厂商前缀或不同名称。
|
|
98
|
+
compat-legend-more = 含有更多兼容性信息。
|
|
99
|
+
placement-note = 广告
|
|
100
|
+
placement-no = 不想看到广告?
|
|
101
|
+
pagination-next = 下一页
|
|
102
|
+
pagination-prev = 上一页
|
|
103
|
+
pagination-current = 当前页
|
|
104
|
+
pagination-goto = 前往第 { $page } 页
|
|
105
|
+
logout = 退出登录
|
|
106
|
+
login = 登录
|
|
107
|
+
example-play-button-label = 运行
|
|
108
|
+
example-play-button-title = 在 MDN 演练场中运行示例(将在新标签页中打开)
|
|
109
|
+
writer-reload-polling = 每 { $seconds } 秒轮询一次
|
|
110
|
+
a11y-menu-skip-to-main-content = 跳转到主要内容
|
|
111
|
+
a11y-menu-skip-to-search = 跳转到搜索
|
|
112
|
+
article-footer-title = 帮助改进 MDN
|
|
113
|
+
article-footer-learn-how-to-contribute = 了解如何参与贡献
|
|
114
|
+
article-footer-view-this-page-on-github = 在 GitHub 上查看此页面
|
|
115
|
+
article-footer-this-will-take-you-to-github-to = 这将带您前往 GitHub 提交新问题。
|
|
116
|
+
article-footer-report-a-problem-with-this-conte = 报告此内容的问题
|
|
117
|
+
baseline-indicator-baseline-cross = 基线(不可用)
|
|
118
|
+
baseline-indicator-baseline-check = 基线(可用)
|
|
119
|
+
baseline-indicator-limited-availability = 有限可用
|
|
120
|
+
baseline-indicator-baseline = 基线
|
|
121
|
+
baseline-indicator-widely-available = 广泛可用
|
|
122
|
+
baseline-indicator-newly-available = 最近可用
|
|
123
|
+
baseline-indicator-check = 可用
|
|
124
|
+
baseline-indicator-cross = 不可用
|
|
125
|
+
baseline-indicator-learn-more = 了解更多
|
|
126
|
+
baseline-indicator-see-full-compatibility = 查看完整兼容性
|
|
127
|
+
baseline-indicator-report-feedback = 提交反馈
|
|
128
|
+
blog-previous = 上一篇文章
|
|
129
|
+
blog-next = 下一篇文章
|
|
130
|
+
blog-index-blog-it-better = Blog it better
|
|
131
|
+
reference-toc-header = 本文内容
|
|
132
|
+
blog-post-not-found = 找不到博客文章。
|
|
133
|
+
collection-save-button-save-in-collection = 保存到收藏集
|
|
134
|
+
collection-save-button-remove = 移除
|
|
135
|
+
collection-save-button-save = 保存
|
|
136
|
+
collection-save-button-add-to-collection = 添加到收藏集
|
|
137
|
+
collection-save-button-collection = 收藏集:
|
|
138
|
+
collection-save-button-saved-articles = 已收藏文章
|
|
139
|
+
collection-save-button-new-collection = 新建收藏集
|
|
140
|
+
collection-save-button-name = 名称:
|
|
141
|
+
collection-save-button-note = 备注:
|
|
142
|
+
collection-save-button-saving = 正在保存……
|
|
143
|
+
collection-save-button-cancel = 取消
|
|
144
|
+
collection-save-button-deleting = 正在删除……
|
|
145
|
+
collection-save-button-delete = 删除
|
|
146
|
+
theme-default = 跟随系统
|
|
147
|
+
color-theme-light = 浅色
|
|
148
|
+
color-theme-dark = 深色
|
|
149
|
+
color-theme-switch-color-theme = 切换主题颜色
|
|
150
|
+
color-theme-theme = 主题
|
|
151
|
+
compat-link-report-issue-title = 报告此兼容性数据中的问题
|
|
152
|
+
compat-link-report-issue = 报告此兼容性数据的问题
|
|
153
|
+
compat-link-source = 在 GitHub 上查看数据
|
|
154
|
+
compat-experimental = 实验性
|
|
155
|
+
compat-deprecated = 已弃用
|
|
156
|
+
compat-nonstandard = 非标准
|
|
157
|
+
compat-support-partial = 部分支持
|
|
158
|
+
compat-support-preview-browser = 预览版浏览器支持
|
|
159
|
+
compat-support-full = 完全支持
|
|
160
|
+
compat-support-no = 不支持
|
|
161
|
+
compat-support-unknown = 支持情况未知
|
|
162
|
+
compat-yes = 是
|
|
163
|
+
compat-partial = 部分
|
|
164
|
+
compat-no = 否
|
|
165
|
+
compat-support-preview = 预览支持
|
|
166
|
+
compat-legend = 图例
|
|
167
|
+
compat-legend-tip = 提示:您可以点击/轻触单元格以获取更多信息。
|
|
168
|
+
compat-link-report-missing-title = 报告缺失的兼容性数据
|
|
169
|
+
compat-link-report-missing = 报告此问题
|
|
170
|
+
compat-js-required = 启用 JavaScript 以查看此浏览器兼容性表。
|
|
171
|
+
compat-loading = 加载中……
|
|
172
|
+
content-feedback-content-is-out-of-date = 内容已过时
|
|
173
|
+
content-feedback-missing-information = 缺少信息
|
|
174
|
+
content-feedback-code-examples-not-working-as-exp = 代码示例未按预期工作
|
|
175
|
+
content-feedback-other = 其他
|
|
176
|
+
content-feedback-question = 此页面对您有帮助吗?
|
|
177
|
+
content-feedback-yes = 是
|
|
178
|
+
content-feedback-no = 否
|
|
179
|
+
content-feedback-reason = 为什么此页面对您没有帮助?
|
|
180
|
+
content-feedback-submit = 提交
|
|
181
|
+
content-feedback-thanks = 感谢您的反馈!
|
|
182
|
+
contributor-spotlight-want-to-be-part-of-the-journey = 想成为这段旅程的一部分吗?
|
|
183
|
+
contributor-spotlight-our-constant-quest-for-innovatio = 我们对创新的不懈追求始于此,也始于您。MDN 的每一部分(文档、演示以及网站本身)都源于我们了不起的开放开发者社区。欢迎加入我们!
|
|
184
|
+
contributor-spotlight-get-involved = 参与进来
|
|
185
|
+
contributor-spotlight-contributor-profile = 贡献者资料
|
|
186
|
+
copy-button-copied = 已复制
|
|
187
|
+
copy-button-copy-failed = 复制失败!
|
|
188
|
+
copy-button-copy = 复制
|
|
189
|
+
footer-mdn-on-github = MDN GitHub 主页
|
|
190
|
+
footer-mdn-on-bluesky = MDN Bluesky 账号
|
|
191
|
+
footer-mdn-on-x = MDN X 账号
|
|
192
|
+
footer-mdn-on-mastodon = MDN Mastodon 账号
|
|
193
|
+
footer-mdn-blog-rss-feed = MDN 博客 RSS 订阅源
|
|
194
|
+
footer-mdn = MDN
|
|
195
|
+
footer-about = 关于
|
|
196
|
+
footer-blog = 博客
|
|
197
|
+
footer-mozilla-careers = Mozilla 招聘
|
|
198
|
+
footer-advertise-with-us = 与我们合作投放广告
|
|
199
|
+
footer-mdn-plus = MDN Plus
|
|
200
|
+
footer-product-help = 产品帮助
|
|
201
|
+
footer-contribute = 参与贡献
|
|
202
|
+
footer-mdn-community = MDN 社区
|
|
203
|
+
footer-community-resources = 社区资源
|
|
204
|
+
footer-writing-guidelines = 写作指南
|
|
205
|
+
footer-mdn-discord = MDN Discord
|
|
206
|
+
footer-developers = 开发者
|
|
207
|
+
footer-web-technologies = Web 技术
|
|
208
|
+
footer-learn-web-development = 学习 Web 开发
|
|
209
|
+
footer-guides = 指南
|
|
210
|
+
footer-tutorials = 教程
|
|
211
|
+
footer-glossary = 术语表
|
|
212
|
+
footer-hacks-blog = Hacks 博客
|
|
213
|
+
footer-website-privacy-notice = 网站隐私声明
|
|
214
|
+
footer-telemetry-settings = 遥测设置
|
|
215
|
+
footer-legal = 法律声明
|
|
216
|
+
footer-community-participation-guidelin = 社区参与准则
|
|
217
|
+
footer-mdn-logo = MDN 标志
|
|
218
|
+
footer-tagline = 构建更美好互联网的蓝图。
|
|
219
|
+
footer-mozilla-logo = Mozilla 标志
|
|
220
|
+
generic-toc__header = 本文内容
|
|
221
|
+
homepage-body-featured-articles = 精选文章
|
|
222
|
+
homepage-body-latest-news = 最新消息
|
|
223
|
+
homepage-body-recent-contributions = 最近贡献
|
|
224
|
+
homepage-contributor-spotlight-contributor-spotlight = 贡献者聚焦
|
|
225
|
+
homepage-contributor-spotlight-get-involved = 参与进来
|
|
226
|
+
homepage-search-search-the-site = 搜索本站
|
|
227
|
+
homepage-search-search = 搜索
|
|
228
|
+
interactive-example-reset = 重置
|
|
229
|
+
interactive-example-value-select = 值选择
|
|
230
|
+
interactive-example-the-current-value-is-not-support = 当前值不受您的浏览器支持。
|
|
231
|
+
interactive-example-run-example-and-show-console-ou = 运行示例并显示控制台输出
|
|
232
|
+
interactive-example-run = 运行
|
|
233
|
+
interactive-example-reset-example-and-clear-console = 重置示例并清空控制台输出
|
|
234
|
+
interactive-example-console-output = 控制台输出
|
|
235
|
+
interactive-example-output = 输出
|
|
236
|
+
issues-table-loading-issues = 正在加载问题……
|
|
237
|
+
issues-table-title = 标题
|
|
238
|
+
issues-table-repository = 仓库
|
|
239
|
+
language-switcher-remember-language = 记住语言
|
|
240
|
+
language-switcher-enable-this-setting-to-always-sw = 启用此设置后,在当前语言可用时将始终切换到该语言。(点击了解更多。)
|
|
241
|
+
language-switcher-learn-more = 了解更多
|
|
242
|
+
login-button-login = 登录
|
|
243
|
+
modal-exit-modal = 关闭对话框
|
|
244
|
+
navigation-toggle-navigation = 切换导航
|
|
245
|
+
obs-about-title = 关于 HTTP Observatory
|
|
246
|
+
observatory-landing-read-our-faq = 阅读我们的常见问题解答
|
|
247
|
+
observatory-landing-report-feedback = 提交反馈
|
|
248
|
+
observatory-rescan-button-rescan = 重新扫描
|
|
249
|
+
observatory-rescan-button-wait-a-minute-to-rescan = 请稍等一分钟后再重新扫描
|
|
250
|
+
observatory-results-report-feedback = 提交反馈
|
|
251
|
+
observatory-results-faq = 常见问题解答
|
|
252
|
+
observatory-tests-and-scores-loading-tests-and-scoring-data = 正在加载测试和评分数据……
|
|
253
|
+
observatory-tests-and-scores-see = 参见
|
|
254
|
+
observatory-tests-and-scores-for-guidance = 获取指导
|
|
255
|
+
observatory-tests-and-scores-test-result = 测试结果
|
|
256
|
+
observatory-tests-and-scores-description = 说明
|
|
257
|
+
observatory-tests-and-scores-modifier = 分数调整
|
|
258
|
+
observatory-tests-and-scores-failed-to-load-tests-and-scoring = 加载测试和评分数据失败,请稍后再试。
|
|
259
|
+
brand-web-docs = MDN Web Docs
|
|
260
|
+
blog-rss-title = MDN 博客 RSS 订阅源
|
|
261
|
+
meta-description = MDN Web Docs 网站提供有关开放 Web 技术的信息,包括 HTML、CSS 以及适用于网站和渐进式 Web 应用的 API。
|
|
262
|
+
logo-alt = MDN 标志
|
|
263
|
+
pagination-pagination = 分页
|
|
264
|
+
playground-do-you-really-want-to-clear-ever = 您确定要清空所有内容吗?
|
|
265
|
+
playground-do-you-really-want-to-revert-you = 您确定要撤销您的更改吗?
|
|
266
|
+
playground-playground = 演练场
|
|
267
|
+
playground-format = 格式化
|
|
268
|
+
playground-run = 运行
|
|
269
|
+
playground-share = 分享
|
|
270
|
+
playground-clear = 清空
|
|
271
|
+
playground-reset = 重置
|
|
272
|
+
playground-seeing-something-inappropriate = 看到不当内容?
|
|
273
|
+
playground-console = 控制台
|
|
274
|
+
playground-share-markdown = 分享 Markdown
|
|
275
|
+
playground-copy-markdown-to-clipboard = 复制 Markdown 到剪贴板
|
|
276
|
+
playground-share-data-url = 分享 Data URL
|
|
277
|
+
playground-copy-data-url-to-clipboard = 复制 Data URL 到剪贴板
|
|
278
|
+
playground-share-your-code-via-permalink = 通过永久链接分享您的代码
|
|
279
|
+
playground-copy-to-clipboard = 复制到剪贴板
|
|
280
|
+
playground-create-link = 创建链接
|
|
281
|
+
playground-report-this-malicious-or-inappro = 举报此恶意或不当的共享演练场内容。
|
|
282
|
+
playground-can-you-please-share-some-detail = 您能否详细说明此内容存在的问题?
|
|
283
|
+
playground-cancel = 取消
|
|
284
|
+
playground-report = 举报
|
|
285
|
+
recently-visited-recently-visited = 最近访问
|
|
286
|
+
scrim-inline-clicking-will-load-content-from = 点击后将从 scrimba.com 加载内容
|
|
287
|
+
scrim-inline-toggle-fullscreen = 切换全屏
|
|
288
|
+
scrim-inline-open-on-scrimba = 在 Scrimba 上打开
|
|
289
|
+
scrim-inline-load-scrim-and-open-dialog = 加载 Scrimba 并打开对话框
|
|
290
|
+
search-button-search-the-site = 搜索本站
|
|
291
|
+
search-modal-loading-search-index = 正在加载搜索索引……
|
|
292
|
+
search-modal-search = 搜索
|
|
293
|
+
search-modal-exit-search = 退出搜索
|
|
294
|
+
sidebar-filter-filter-sidebar = 筛选侧边栏
|
|
295
|
+
sidebar-filter-filter = 筛选
|
|
296
|
+
sidebar-filter-clear-filter-input = 清除筛选输入
|
|
297
|
+
site-search-search = 搜索
|
|
298
|
+
site-search-previous = 上一页
|
|
299
|
+
site-search-next = 下一页
|
|
300
|
+
site-search-suggestions-text = 您是否在找……
|
|
301
|
+
site-search-searching = 搜索中……
|
|
302
|
+
site-search-language = 语言
|
|
303
|
+
site-search-both = 两者
|
|
304
|
+
specifications-list-this-feature-does-not-appear-to = 此特性似乎未在任何规范中定义。
|
|
305
|
+
specifications-list-specification = 规范
|
|
306
|
+
survey-hide-this-survey = 隐藏此调查
|
|
307
|
+
survey-take-survey-opens-in-a-new-tab = 参与调查(在新标签页中打开)
|
|
308
|
+
toggle-sidebar-toggle-sidebar = 切换侧边栏
|
|
309
|
+
user-menu-ai-help = AI 助手
|
|
310
|
+
user-menu-collections = 收藏集
|
|
311
|
+
user-menu-updates = 更新
|
|
312
|
+
user-menu-settings = 我的设置
|
|
313
|
+
user-menu-help = 帮助
|
|
314
|
+
user-menu-feedback = 反馈
|
|
315
|
+
user-menu-user = 用户
|
|
316
|
+
writer-open-editor-open-in-editor = 在编辑器中打开
|
|
317
|
+
writer-toolbar-view-on-mdn = 在 MDN 上查看
|