Z.OOL.ネット信託統治領 はてな諸島

こちらは "Z.OOL.ネット信託統治領 はてな諸島" です。

mstdn.jp の toot を Web ページに埋め込む際の問題を回避する手法

現在うだうだ中。身体的にも精神的にも疲労感と全身倦怠感が蓄積し、
睡眠障害も頻発している状況である。

はじめに

本稿は、 ”mstdn 諸島” の toot を他の Web ページに埋め込む際に toot の縦幅が自動調整されない問題が発生する件について、当該問題を回避する手法を投稿した "mstdn.maud.io 群島" の toot を纏めた上で、補足的な内容について加筆を行なったものです。

mstdn.jp

mstdn.maud.io


mstdn.jp の toot の埋め込みに問題が発生する件

概要

インスタンス mstdn.jp にある toot をブログ等の別の Web ページに埋め込む際に toot の縦幅が正常に調整されず、 Web ページへの埋め込みに失敗する問題が発生します。

この問題は、インスタンス mstdn.jp において提供されている toot 埋め込みスクリプト embed.js のバージョンが古く、 最新の Firefox 等の Web ブラウザに対応しないことが原因と考えられます。

そこで、 mstdn.jp の toot を埋め込む際に、インスタンス mstdn.jp において提供されている embed.js に代えて、 Mastodon の最新の embed.js を使用することにより、正常に mstdn.jp の toot を埋め込む事が可能となりました。

問題回避の手法

まず、インスタンス mstdn.jp にある toot をブログ等の別の Web ページに埋め込む為の HTML のコード片は以下のようになっています。

<iframe src="https://mstdn.jp/@z80oolong/103535945865822064/embed" class="mastodon-embed" style="max-width: 100%; border: 0" width="400" allowfullscreen="allowfullscreen"></iframe><script src="https://mstdn.jp/embed.js" async="async"></script>

しかし、上記の HTML のコード片において、 インスタンス mstdn.jp で使用されている embed.js は、Github にて toot の縦幅が拡張されない不具合が報告されています。

github.com

即ち、前述した toot の縦幅が拡張されない問題を回避するには、上記 HTML のコード片において、 <script src="https://mstdn.jp/embed.js" async="async"></script> に代えて、前述の不具合が修正された embed.js を使用すれば良いことが判ります。

ここで、不具合が修正された embed.js は、 Mastodon の commit 6e736f2 における embed.js であり、以下のコードであることが判ります。

github.com

従って、 mstdn.jp の toot を Web ページに埋め込む際には、下記の HTML コードを使用することにより、前述の問題を回避することが出来ます。

<iframe src="https://mstdn.jp/@z80oolong/103535945865822064/embed" class="mastodon-embed" style="max-width: 100%; border: 0" width="400" allowfullscreen="allowfullscreen">
<script async="async">
/**
 * (以下の通りに、不具合が修正された embed.js のコードを script タグ内に copy & paste する)
 */
// @ts-check

(function() {
  'use strict';

  /**
   * @param {() => void} loaded
   */
  var ready = function(loaded) {
    if (['interactive', 'complete'].indexOf(document.readyState) !== -1) {
      loaded();
    } else {
      document.addEventListener('DOMContentLoaded', loaded);
    }
  };

  ready(function() {
    /** @type {Map<number, HTMLIFrameElement>} */
    var iframes = new Map();

    window.addEventListener('message', function(e) {
      var data = e.data || {};

      if (typeof data !== 'object' || data.type !== 'setHeight' || !iframes.has(data.id)) {
        return;
      }

      var iframe = iframes.get(data.id);

      if ('source' in e && iframe.contentWindow !== e.source) {
        return;
      }

      iframe.height = data.height;
    });

    [].forEach.call(document.querySelectorAll('iframe.mastodon-embed'), function(iframe) {
      // select unique id for each iframe
      var id = 0, failCount = 0, idBuffer = new Uint32Array(1);
      while (id === 0 || iframes.has(id)) {
        id = crypto.getRandomValues(idBuffer)[0];
        failCount++;
        if (failCount > 100) {
          // give up and assign (easily guessable) unique number if getRandomValues is broken or no luck
          id = -(iframes.size + 1);
          break;
        }
      }

      iframes.set(id, iframe);

      iframe.scrolling      = 'no';
      iframe.style.overflow = 'hidden';

      iframe.onload = function() {
        iframe.contentWindow.postMessage({
          type: 'setHeight',
          id: id,
        }, '*');
      };

      iframe.onload();
    });
  });
})();
</script>

なお、 <script> タグの src 属性に、前述の不具合が解消された他のインスタンスembed.js を指定しても問題回避が可能ですが、この場合は mstdn.jp と無関係な他のインスタンスに負荷がかかる状況となる事に留意する必要があります。

もし、 mastodon の toot の貼り付け先がブログであって、ブログの設定に任意のヘッダが記述できる場合は、ヘッダの設定に上記の <script> 要素を記述することも考慮に入れて下さい。

まとめ

mstdn.jp の toot の Web ページへの埋め込みにおいて、 toot の縦幅の調整の不具合により、 toot の埋め込みが失敗する問題について、 当該問題が、インスタンス mstdn.jp に置かれている embed.js が古いことが原因であり、 Web ページに toot を埋め込むための HTML のコード片において、 <script> 要素内に不具合が修正された embed.js を用いることにより、 mstdn.jp の toot の埋め込みに失敗する問題を回避することが出来ました。

なお、この問題回避の手法は、他の古い embed.js が置かれているインスタンスにおいても、有効であることが考えられます。