MDN の埋め込みデモコードが壊れているので修正するよ

# はじめに

この記事は [2023 年の MDN 翻訳 Advent Calendar](https://qiita.com/advent-calendar/2023/mdn-translation-community-japan) 向けに作成したものです。

こんにちは。debiru です。好きな次世代 grep は ag (the-silver-searcher) です。次世代 grep を利用してない？そんな人がいるんですか！

さて、今日は、MDN の記事を読んでいるときに記事中のプレビューが表示されないなどの不具合を見つけたらどうすべきかについて解説していきます。

# 記事に埋め込まれたデモコードのプレビュー

MDN でこのような記事を見たことはあるでしょうか。

![MDN の記事に「Try it」というセクションがあり、デモコードのプレビューが利用できる。](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178936/3852428f-561e-ad97-582c-e14b4a2625cb.png)

"Try it" というセクションに JavaScript Demo が埋め込まれていて、実際のコードの動作結果を確認することができるようになっています。

MDN ではデモコードの埋め込みにはいくつか種類があり、上記のような実際に動作確認ができるタイプのデモコードは **`Interactive Example`** と呼ばれています。

## 埋め込みに失敗しているデモコード

![埋め込まれたデモコードが "Error" と表示されている。](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178936/a2977b26-edc4-6104-17f9-ad4a98dc3ef9.png)

たまたまページを閲覧していたら、日本語訳の [Null 合体代入 (??=)](https://developer.mozilla.org/ja/docs/web/javascript/reference/operators/nullish_coalescing_assignment) のページで埋め込みに失敗しているデモコードを見つけました。

## そこで私は何をしたか

修正したいわけですが、ここで私は次のことを考えました。

- なんでデモコード動いてないの……。
- 英語版はどうなっているだろう。
- [interactive-examples](https://github.com/mdn/interactive-examples) リポジトリの変更履歴はどうなっているのだろう。
    - 変更したなら参照しているコンテンツ側も書き換えないとダメだろうに何考えてるんだ（おこ）。
- **同様に埋め込みに失敗しているページは他に何があるだろうか。**

そうなのです。このページだけを修正すれば済む話ではないのです。MDN のドキュメント整備というのは体系的に行われるべきなのです。同様の問題が起こっている箇所を全て洗い出しましょう。

### 埋め込みデモコード（マクロ）の種類

- **EmbedInteractiveExample** - `{{EmbedInteractiveExample("pages/js/array-push.html")}} `
    - [https://developer.mozilla.org/ja/docs/web/javascript/reference/global_objects/array/push](https://developer.mozilla.org/ja/docs/web/javascript/reference/global_objects/array/push#%E8%A9%A6%E3%81%97%E3%81%A6%E3%81%BF%E3%81%BE%E3%81%97%E3%82%87%E3%81%86)
- **EmbedLiveSample** - `{{EmbedLiveSample("Examples")}}`
    - [https://developer.mozilla.org/ja/docs/Glossary/Inline-level_content](https://developer.mozilla.org/ja/docs/Glossary/Inline-level_content#%E4%BE%8B)
- **EmbedGHLiveSample** - `{{EmbedGHLiveSample("learning-area/html/forms/range-example/index.html", '100%', 200)}}`
    - [https://developer.mozilla.org/ja/docs/learn/forms/html5_input_types](https://developer.mozilla.org/ja/docs/learn/forms/html5_input_types#%E3%82%B9%E3%83%A9%E3%82%A4%E3%83%80%E3%83%BC%E3%82%B3%E3%83%B3%E3%83%88%E3%83%AD%E3%83%BC%E3%83%AB)
- **EmbedYoutube** - `{{EmbedYouTube("IK97XMibEws")}}`
    - [https://developer.mozilla.org/ja/docs/learn/accessibility/what_is_accessibility](https://developer.mozilla.org/ja/docs/learn/accessibility/what_is_accessibility#%E8%A6%96%E8%A6%9A%E9%9A%9C%E7%A2%8D%E8%80%85)
- **JSFiddleEmbed** - `{{JSFiddleEmbed("https://jsfiddle.net/rybr720u/","","350")}}`
    - [https://developer.mozilla.org/ja/docs/games/techniques/3d_on_the_web/building_up_a_basic_demo_with_three.js](https://developer.mozilla.org/ja/docs/games/techniques/3d_on_the_web/building_up_a_basic_demo_with_three.js#%E5%85%89%E6%BA%90)

この中で、MDN リソースとしてデモコードが正常に埋め込まれているのかを検証可能なのは **EmbedInteractiveExample** と **EmbedGHLiveSample** だけです。

**EmbedLiveSample** は外部ファイルからの読み込みではなく同一ページ中にあるコードを利用してデモを展開するので読み込みに失敗するということがありません。**EmbedYoutube** と **JSDiddleEmbed** は MDN 外の外部リソースなので読み込もうとしているリソースの存在有無を確認することが容易にはできません。

今回は、スコープを広げる理由も特にないので **EmbedInteractiveExample** に絞って調査することにしました。

#### 関連ページ

- [https://developer.mozilla.org/ja/docs/MDN/Writing_guidelines/Page_structures/Code_examples](https://developer.mozilla.org/ja/docs/MDN/Writing_guidelines/Page_structures/Code_examples#%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%83%96%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%81%AE%E3%83%87%E3%83%A2)
- [https://developer.mozilla.org/ja/docs/MDN/Writing_guidelines/Howto/Images_media](https://developer.mozilla.org/ja/docs/MDN/Writing_guidelines/Howto/Images_media#%E5%9F%8B%E3%82%81%E8%BE%BC%E3%81%BF)
- https://github.com/mdn/yari/blob/main/kumascript/macros/JSFiddleEmbed.ejs

### EmbedInteractiveExample マクロのフォーマット

マクロが正常に読み込めるかどうかを検証するために、まずマクロのフォーマットを確認する必要があります。

- `{{EmbedInteractiveExample("pages/css/grid.html")}}`
- `{{EmbedInteractiveExample("pages/tabbed/dl.html", "tabbed-standard")}}`
- `{{EmbedInteractiveExample("pages/js/string-slice.html", "taller")}}`

適当に [translated-content](https://github.com/mdn/translated-content) リポジトリの中を `ag (grep)` したところ、上記のようなマクロを見つけました。第 2 引数はなんだろう。

ということで[実装](https://github.com/mdn/yari/blob/main/kumascript/macros/EmbedInteractiveExample.ejs)を読むわけです。すると、埋め込みウィジェットの高さを決定するための引数であることがわかりました。つまり埋め込みの可否自体には関係ありません。

ということで第 1 引数を検証していけばよいことが分かりました。

### 対応する Interactive Example の実体

Interactive Example の実体は [interactive-examples](https://github.com/mdn/interactive-examples/tree/main/live-examples) リポジトリで管理されています。

`pages/tabbed/dl.html` という指定に対して、実体が存在するかどうかを確認するにはどうすればよいのでしょうか。ということで `tabbed` などと `ag (grep)` してみると、`meta.json` ファイルにその記述があることが分かりました。

```json
{
  "pages": {
    "blockquote": {
      "exampleCode": "./live-examples/html-examples/text-content/blockquote.html",
      "cssExampleSrc": "./live-examples/html-examples/text-content/css/blockquote.css",
      "fileName": "blockquote.html",
      "title": "HTML Demo: <blockquote>",
      "type": "tabbed",
      "height": "tabbed-standard"
    },
    "dd": {
      "exampleCode": "./live-examples/html-examples/text-content/dd.html",
      "cssExampleSrc": "./live-examples/html-examples/text-content/css/dd.css",
      "fileName": "dd.html",
      "title": "HTML Demo: <dd>",
      "type": "tabbed",
      "height": "tabbed-standard"
    },
    ...
}
```

[interactive-examples](https://github.com/mdn/interactive-examples/tree/main/live-examples) リポジトリ内にある `meta.json` をパースして `type` プロパティと `fileName` プロパティの値を拾ってやれば検証できそうな雰囲気が出てきました。

### `meta.json` をパースして、実際のドキュメント内のマクロと照合する

照合して一覧表を出力します。

これは実装したものです。

https://github.com/debiru/mdn-translation-docs/commit/497649f805dfdf55e2bc050eef067304cedd4ead

そして、一覧表はこちらです。

https://mdn.lavoscore.org/?not_regex_examples_ja=%5E%28null%7C%7Cfalse%29$

|URL|不正なマクロ|
|:---|:---:|
|https://developer.mozilla.org/ja/docs/web/api/reporterror|pages/js/self-reporterror.html|
|https://developer.mozilla.org/ja/docs/web/javascript/reference/global_objects/intl/segmenter/segment/segments|pages/js/intl-segments-prototype-containing.html|
|https://developer.mozilla.org/ja/docs/web/javascript/reference/global_objects/intl/segmenter/segment/segments/containing|pages/js/intl-segments-prototype-containing.html|
|https://developer.mozilla.org/ja/docs/web/javascript/reference/global_objects/map/groupby|pages/js/array-groupbytomap.html|
|https://developer.mozilla.org/ja/docs/web/javascript/reference/global_objects/string/@@iterator|pages/js/string-iterator.html|
|https://developer.mozilla.org/ja/docs/web/javascript/reference/operators/nullish_coalescing_assignment|pages/js/expressions-logical-nullish-assignment.html|

不正な Interactive Example マクロを記述しているページが 6 件見つかりました。このうち 2 件は、マクロは記述されているもののコメントアウトされていて影響がないページです。というわけで実質問題があるページは 4 件でした。

### 不正なマクロの修正を開始する

実はここまでは予備調査でした。この調査内容がなくても「適切な」修正自体は可能なはずです。「適切な」というのは、修正すべき箇所を網羅的に修正するという意味です。[interactive-examples](https://github.com/mdn/interactive-examples/tree/main/live-examples) リポジトリでマクロのキーが変更された時点で、英語版でどのように修正されているのかを追えばよいのです。

### 不正なマクロに関する英語版の修正履歴

interactive-examples リポジトリでのキーの変更は https://github.com/mdn/interactive-examples/pull/2589 のコミットで行われています。

英語版の記事を管理する [content](https://github.com/mdn/content/) リポジトリでは、https://github.com/mdn/content/pull/28724 のコミットで修正が行われていたことが分かります。

これと同様の修正を日本語版に取り込むべきだったのです。それが漏れていたのが今回の問題の原因でした。これだけが原因かどうかを判断するのに「予備調査」が必要だったわけです。不正なマクロのあった問題のあるページと、このコミットで変更されたページが一致していますよね。

では修正を始めましょう。

すると、なんか一部修正されていることも分かりました。`git blame` で追ってみると、https://github.com/mdn/translated-content/pull/15489 のコミットがあることが分かりました。

そんなこんなで、実際に修正した Pull-Req がこちらです。

https://github.com/mdn/translated-content/pull/17390

# ちょっと待てよ…？

修正したのはいいけど、いま修正したのは「不正なマクロがあるページ」だけでした。

もしかしたら、「あるべきマクロが記述されていない日本語ページ」が存在するかもしれません。ということに気づきました。よし、追加で調査してみましょう。

## 一覧表をもういっちょ魔改造

https://github.com/debiru/mdn-translation-docs/commit/57883c22db309bfb135f8908784e2f47478edbbc

英語版のページで使われている Interactive Example マクロの一覧を追加しました。

「英語版にマクロが記述されており、日本語版にマクロが記述されていないページ」の一覧は次の通りです。

https://mdn.lavoscore.org/?regex_examples_en=%5Efalse$&regex_examples_ja=%5Enull$

## Interactive Example マクロが抜けているページを修正しました

https://github.com/mozilla-japan/translation/issues/731

122 ページほどありました。マクロの追加位置を自動的に決定できないので手作業で追加しました。ちょっと疲れました。

# さいごに

ちょっと記事が長くなってしまいましたね。最後まで読んでいただいた方はありがとうございます。

いかがでしたか。私はこんなことをしながら MDN ドキュメントを日々メンテナンスしています。少しは雰囲気が伝わったでしょうか。

またネタを考えながら明日以降も記事が書けたらよいなと思っていますが、それよりも他の方に [2023 年の MDN 翻訳 Advent Calendar](https://qiita.com/advent-calendar/2023/mdn-translation-community-japan) に参加していただけたら嬉しいなと思っています。

ということで、MDN のドキュメントを整備するお話でした。

おわり。