Mastodon Misskey Share button https://web.gnusocial.jp/post/2024/02/26/10363/

SENOO, Ken ea60fd6e19 アクセス解析用にbutton->a要素に変更 9 mesi fa
README.md ea60fd6e19 アクセス解析用にbutton->a要素に変更 9 mesi fa
image.jpg ea60fd6e19 アクセス解析用にbutton->a要素に変更 9 mesi fa
index.html ea60fd6e19 アクセス解析用にbutton->a要素に変更 9 mesi fa

README.md

MaMiShare

About

image

MaMiShareはMastodon/Misskeyに対応したSNSへの共有ボタンだ。

左側のテキストボックにサーバーホスト名を入力して [MaMiShare] を選ぶと、QP <記事タイトル> <URL> の形式のテキストで編集画面が開かれワンクリックで投稿できる。

以下が特徴となる。

  1. 中継サーバーを使わない最低限の依存関係。
  2. わずか数KB、数十行以内のシンプルな軽量実装。自己改変も簡単。
  3. 画面遷移なしのワンクリック共有。
  4. localStorageを利用した前回の選択サーバーの記憶。

Service - GNU social JP Wiki」に記した通り、既存の類似共有ボタンを検討した結果、以下の点で満足いかなかったので自作した。

  • 外部サーバー依存。
  • モーダルなどの余計な画面遷移。
  • ファイルサイズ。
  • 無駄に長くて複雑な実装。

mastodon-share-button-scalajsは基本的な考え方は問題なかったのだが、モーダルの余計な画面遷移と利用時のmstdn-share.jsのファイルサイズ (1 MB!以上) が気に入らなかったので自作した。

本質的にはせいぜい100行以内程度の処理のために1 MB以上の巨大ファイルは大袈裟過ぎる。

なお、MaMiShareの名前の由来は、Mastodon Misskey Share button。長いので最低限意味が分かる範囲で短縮しただけ。

MastodonもMisskeyも <host>/share?text= のWeb Intent URLのパスが共通していることを利用している。

Usage

1 index.htmlに記載している以下のコード (main要素内部) を共有ボタンを設置したい場所にHTMLとして記述する (iframeで参照するのもあり)。WordPressだとWidgetの [Custom HTML] などで配置できる。

<fieldset>
  <style>
  /* @scope { */
    fieldset input, fieldset a {
      width: 100%;
      color: white;
      font-size: 2em;
      text-align: center;
    }
    fieldset div {
      display: flex;
    }
  /* } */
  </style>
  <legend>Share</legend>
  <div>
    <a style="background-color:#333"
      onclick="navigator.clipboard.writeText(
        document.title+' '+location.href);">Copy</a>
    <a style="background-color:#2c6ebd"
      href="https://b.hatena.ne.jp/entry/s/"
      onmousedown="this.href='https://b.hatena.ne.jp/entry/s/'
        +location.host+'/'+location.pathname">Hatena</a>
    <a style="background-color:#3b5998"
      href="https://www.facebook.com/sharer/sharer.php?t="
      onmousedown="this.href='https://www.facebook.com/sharer/sharer.php?t='
        +encodeURIComponent('QP '+document.title)
        +'&u='+encodeURIComponent(location.href);">Facebook</a>
    <a style="background-color:#1da1f2"
      href="https://twitter.com/intent/tweet?text="
      onmousedown="this.href='https://twitter.com/intent/tweet?text='
        +encodeURIComponent('QP '+document.title)
        +'&url='+encodeURIComponent(location.href);">X/Twitter</a>
    <a style="background-color:black"
      href="https://www.threads.net/intent/post?text="
      onmousedown="this.href='https://www.threads.net/intent/post?text='
        +encodeURIComponent('QP '
        +document.title+' '+location.href);">Threads</a>
  </div>
  <div>
    <input id="MaMiShare.host" list="MaMiList" type="email" inputmode="email"
      autocomplete="on" autocorrect="off" autocapitalize="off"
      formnovalidate='formnovaildate' placeholder="mstdn.jp misskey.io"
      style="background-color:rgb(158,194,63)" />
    <a style="background-color:rgb(99,100,255);"
      href="https://mamishare.jp"
      onmousedown="localStorage.setItem('MaMiShare.host',
        this.previousElementSibling.value);
        this.href=`https://${this.previousElementSibling.value}/share?text=QP `
          +encodeURIComponent(document.title+' '+location.href);
      ">MaMiShare</a>
    <script>
      window.addEventListener('load', () => {
        document.getElementById('MaMiShare.host').value =
          localStorage.getItem('MaMiShare.host');
      });
    </script>
    <datalist id="MaMiList">
      <option value="fedibird.com"></option>
      <option value="gp.tsukimi.club"></option>
      <option value="mastodon.social"></option>
      <option value="mattyaski.co"></option>
      <option value="meisskey.one"></option>
      <option value="misskey-square.net"></option>
      <option value="misskey.04.si"></option>
      <option value="misskey.backspace.fm"></option>
      <option value="misskey.cloud"></option>
      <option value="misskey.gg"></option>
      <option value="misskey.io"></option>
      <option value="misskey.niri.la"></option>
      <option value="misskey.one"></option>
      <option value="misskey.secinet.jp"></option>
      <option value="misskey.systems"></option>
      <option value="mk2.toyoko.in"></option>
      <option value="msk.ilnk.info"></option>
      <option value="mstdn.jp"></option>
      <option value="nijimiss.moe"></option>
      <option value="novelskey.tarbin.net"></option>
      <option value="pawoo.net"></option>
      <option value="submarin.online"></option>
      <option value="sushi.ski"></option>
    </datalist>
  </div>
</fieldset>
<fieldset>
  <legend>Follow</legend>
  <div>
    <a style="background-color:#f26522"
      href="https://web.gnusocial.jp/feed">
      RSS</a>
    <a style="background-color:#2bb24c"
      href="https://feedly.com/i/discover/sources/search/feed/https%3A%2F%2Fweb.gnusocial.jp">
      Feedly</a>
    <a style="background-color:#3b5998"
      href="https://www.facebook.com/profile.php?id=61556435340202">
      Facebook</a>
    <a style="background-color:#1da1f2"
      href="https://x.com/gnusocialjp">X/Twitter</a>
  </div>
  <div>
    <a style="background-color:black"
      href="https://www.threads.net/@gnusocialjp">
      Threads</a>
    <a style="background-color:rgb(0,112,255)"
      href="https://bsky.app/profile/did:plc:cgtlyuedd3qwmtycjv62xhma">
      Bluesky</a>
    <a style="background-color:#a22430"
      href="https://gnusocial.jp/gnusocialjp">
      GNU social</a>
  </div>
</fieldset>

以下の項目はなくても問題ない。

  1. datalist要素。
  2. div要素内のFacebookなどの共有ボタン。
  3. フォローボタン用の2個目のfieldset要素。

2 続いて、左側のフォームにMastodon/Misskeyサーバーのホスト名 (例: mstdn.jp) を記入し、[MaMiShare] を選ぶ。datalist要素で固定になるが候補サーバーの候補を必要に応じて設定しておくとユーザーには親切だろう。

3 選択したサーバーホスト/share?text=[QP ページタイトル URL] のURLを開くので、自分のアカウントでログインする。編集画面に該当文字列が入力された状態で開かれる。必要に応じて自分の意見などを追記編集して投稿する。

4 フォームに一度入力した内容はlocalStorageに保存されているので、次回表示時は入力された状態になっている。

必要に応じて、スタイルやHTMLコード片を修正して自分の用途に合わせる。

style要素内の@scopeは使えない環境もあるだろうから、被ることが少ないと思うfieldsetのセレクターをひとまず利用した。@scopeが使えるなら[fieldset input]の [fieldset ] の前置は不要になる。

Attribute

  • Author: SENOO, Ken
  • License: GPLv3 or late
  • Created: 2024-02-24 Sat

GPLの採用理由は他人の改善内容をこのコードに取り込みたいから。GPLの影響範囲はせいぜいfieldsetやform要素内がこのコードの範囲内の想定。それ以外の部分とは連結しているとは思っていないし、あまりうるさく言うつもりはない。

TODO

  • Bluesky。アプリ側でWeb Intent URL相当にそもそも対応していない。
  • Nostr。Bluesky対応時に一緒にv1.1.0で対応予定。Bluesky/Nostr対応時に名前を変えるかもしれない。
  • GNU social。たぶん実装がないので作る必要がある。

CHANGELOG

2024-02-26 Mon: v1.1.0

  • フォローボタンを追加。
  • アクセス解析ツールでの分析のためにbutton->a要素に変更。

    2024-02-25 Sun: v1.0.0

    2024-02-24 Sat: v0.0.0