ブックマークレットの統合

【1】と【2】を場合分けして1つのJavaScriptにまとめたい。

【1】

javascript:(function(){var t=document.title.normalize('NFC').replace(/ヨドバシ\.com - (.*?) 通販【全品無料配達】/g,'$1').replace(/ - YouTube/g,'').replace(/[\u0000-\u0008\u000B-\u001F\u007F-\u009F\u200B-\u200F\u202A-\u202E\u2060-\u206F\uFE00-\uFE0F\uFEFF]/g,'');t=t.replace(/[\r\n]/g,'▼');t=t.replace(/https?:\/\/[^\s]+/g,function(m){return m.replace(/:/g,':');});var u=location.href.replace(/http:\/\/localhost:1313/g,'').replace(/https:\/\/benkyosukisuki.com/g,'').replace(/https:\/\/netjuku.net/g,'').replace(/search\?.*\&q=/g,'search?&q=').replace(/\&stick=([^&|"]+)/g,'').replace(/\&ved=([^&|"]+)/g,'').replace(/\&biw=([^&|"]+)/g,'').replace(/\&bih=([^&|"]+)/g,'').replace(/\?frm_src=thumb_module/g,'').replace(/\&feature=youtu.be\&t=(\d+)m(\d+)s/g,'').replace(/time_continue=\d+\&/g,'').replace(/\#t=(\d+)m(\d+)s/g,'').replace(/\/\/www.youtube.com\/watch\?(.*?)v=(.{11})(.*)/g,'//youtu.be/$2?t=00m00s').replace(/\/\/www.amazon.co.jp\/.*\/dp\/(.{10}).*/g,'//www.amazon.co.jp/dp/$1').replace(/\/\/vimeo.com\/([\w/:%#\$&\?\(\)~\.=\+\-]+)/g,'//vimeo.com/$1#t=00m00s').replace(/moz\-extension:(.*?)(.{24})$/g,'https://www.youtube.com/channel/$2');prompt('HTML link','■<a href="'+u+'" target="_blank" rel="nofollow">'+t.replace(/&/g,'&amp;').replace(/"/g,'&quot;').replace(/'/g,'&apos;').replace(/</g,'&lt;').replace(/>/g,'&gt;')+'</a><br>')})();

【2】

javascript:(function(){const article=document.querySelector('article.js-entryWrapper');if(!article){alert('This bookmarklet should be run on an Ameblo entry page.');return}const title=article.getAttribute('data-unique-entry-title');if(!title){alert('Could not find the entry title.');return}const url=location.href;let blogName=document.querySelector('title[data-react-helmet="true"]')?.textContent|| (window.blogMap&&Object.keys(window.blogMap)[0]?window.blogMap[Object.keys(window.blogMap)[0]].blog_title:'') || document.title.split(' | ')[1]||'Unknown Blog';blogName=blogName.trim().replace(/\u3000/g,' ');const linkText=`${title} | ${blogName}`.normalize('NFC').replace(/[-\u0008\u000B-\u001F\u007F-\u009F\u200B-\u200F\u202A-\u202E\u2060-\u206F\uFE00-\uFE0F\uFEFF]/g,'').replace(/[\r\n]/g,'▼');const html=`■<a href="${url}" target="_blank" rel="nofollow">${linkText.replace(/&/g,'&amp;').replace(/"/g,'&quot;').replace(/'/g,'&apos;').replace(/</g,'&lt;').replace(/>/g,'&gt;')}</a><br>`;prompt('Copy the following link HTML:',html)})();

まとめた結果が以下であるけれども、エラーが出るので、完全にデバッグして一行表示で出力してほしい。

javascript:(function(){
  const article = document.querySelector('article.js-entryWrapper');
  if (article) {
    // アメブロ記事ページの場合
    const title = article.getAttribute('data-unique-entry-title');
    if (!title) {
      alert('Could not find the entry title.');
      return;
    }
    const url = location.href;
    let blogName = document.querySelector('title[data-react-helmet="true"]')?.textContent ||
      (window.blogMap && Object.keys(window.blogMap)[0] ? window.blogMap[Object.keys(window.blogMap)[0]].blog_title : '') ||
      document.title.split(' | ')[1] || 'Unknown Blog';
    blogName = blogName.trim().replace(/\u3000/g, ' ');
    const linkText = `${title} | ${blogName}`.normalize('NFC')
      .replace(/[-\u0008\u000B-\u001F\u007F-\u009F\u200B-\u200F\u202A-\u202E\u2060-\u206F\uFE00-\uFE0F\uFEFF]/g, '')
      .replace(/[\r\n]/g, '▼');
    const html = `■<a href="${url}" target="_blank" rel="nofollow">${linkText.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/'/g, '&apos;').replace(/</g, '&lt;').replace(/>/g, '&gt;')}</a><br>`;
    prompt('Copy the following link HTML:', html);
  } else {
    // アメブロ以外のページの場合
    var t = document.title.normalize('NFC')
      .replace(/ヨドバシ\.com - (.*?) 通販【全品無料配達】/g, '$1')
      .replace(/ - YouTube/g, '')
      .replace(/[-\u0008\u000B-\u001F\u007F-\u009F\u200B-\u200F\u202A-\u202E\u2060-\u206F\uFE00-\uFE0F\uFEFF]/g, '');
    t = t.replace(/[\r\n]/g, '▼');
    t = t.replace(/https?:\/\/[^\s]+/g, function(m) { return m.replace(/:/g, ':'); });
    var u = location.href
      .replace(/http:\/\/localhost:1313/g, '')
      .replace(/https:\/\/benkyosukisuki.com/g, '')
      .replace(/https:\/\/netjuku.net/g, '')
      .replace(/search\?.*\&q=/g, 'search?&q=')
      .replace(/\&stick=([^&|"]+)/g, '')
      .replace(/\&ved=([^&|"]+)/g, '')
      .replace(/\&biw=([^&|"]+)/g, '')
      .replace(/\&bih=([^&|"]+)/g, '')
      .replace(/\?frm_src=thumb_module/g, '')
      .replace(/\&feature=youtu.be\&t=(\d+)m(\d+)s/g, '')
      .replace(/time_continue=\d+\&/g, '')
      .replace(/\#t=(\d+)m(\d+)s/g, '')
      .replace(/\/\/www.youtube.com\/watch\?(.*?)v=(.{11})(.*)/g, '//youtu.be/$2?t=00m00s')
      .replace(/\/\/www.amazon.co.jp\/.*\/dp\/(.{10}).*/g, '//www.amazon.co.jp/dp/$1')
      .replace(/\/\/vimeo.com\/([\w/:%#\$&\?\(\)~\.=\+\-]+)/g, '//vimeo.com/$1#t=00m00s')
      .replace(/moz\-extension:(.*?)(.{24})$/g, 'https://www.youtube.com/channel/$2');
    prompt('HTML link', `■<a href="${u}" target="_blank" rel="nofollow">${t.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/'/g, '&apos;').replace(/</g, '&lt;').replace(/>/g, '&gt;')}</a><br>`);
  }
})();

統合されたブックマークレット

javascript:(function(){
  const article = document.querySelector('article.js-entryWrapper');
  if (article) {
    const title = article.getAttribute('data-unique-entry-title');
    if (!title) { alert('Could not find the entry title.'); return; }
    const url = location.href;
    let blogName = document.querySelector('title[data-react-helmet="true"]')?.textContent ||
      (window.blogMap && Object.keys(window.blogMap)[0] ? window.blogMap[Object.keys(window.blogMap)[0]].blog_title : '') ||
      document.title.split(' | ')[1] || 'Unknown Blog';
    blogName = blogName.trim().replace(/\u3000/g, ' ');
    const linkText = `${title} | ${blogName}`.normalize('NFC')
      .replace(/[-\u0008\u000B-\u001F\u007F-\u009F\u200B-\u200F\u202A-\u202E\u2060-\u206F\uFE00-\uFE0F\uFEFF]/g, '')
      .replace(/[\r\n]/g, '▼');
    const html = `■<a href="${url}" target="_blank" rel="nofollow">${linkText.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/'/g, '&apos;').replace(/</g, '&lt;').replace(/>/g, '&gt;')}</a><br>`;
    prompt('Copy the following link HTML:', html);
  } else {
    var t = document.title.normalize('NFC')
      .replace(/ヨドバシ\.com - (.*?) 通販【全品無料配達】/g, '$1')
      .replace(/ - YouTube/g, '')
      .replace(/[-\u0008\u000B-\u001F\u007F-\u009F\u200B-\u200F\u202A-\u202E\u2060-\u206F\uFE00-\uFE0F\uFEFF]/g, '')
      .replace(/[\r\n]/g, '▼')
      .replace(/https?:\/\/[^\s]+/g, function(m) { return m.replace(/:/g, ':'); });
    var u = location.href
      .replace(/http:\/\/localhost:1313/g, '')
      .replace(/https:\/\/benkyosukisuki.com/g, '')
      .replace(/https:\/\/netjuku.net/g, '')
      .replace(/search\?.*\&q=/g, 'search?&q=')
      .replace(/\&stick=([^&|"]+)/g, '')
      .replace(/\&ved=([^&|"]+)/g, '')
      .replace(/\&biw=([^&|"]+)/g, '')
      .replace(/\&bih=([^&|"]+)/g, '')
      .replace(/\?frm_src=thumb_module/g, '')
      .replace(/\&feature=youtu.be\&t=(\d+)m(\d+)s/g, '')
      .replace(/time_continue=\d+\&/g, '')
      .replace(/\#t=(\d+)m(\d+)s/g, '')
      .replace(/\/\/www.youtube.com\/watch\?(.*?)v=(.{11})(.*)/g, '//youtu.be/$2?t=00m00s')
      .replace(/\/\/www.amazon.co.jp\/.*\/dp\/(.{10}).*/g, '//www.amazon.co.jp/dp/$1')
      .replace(/\/\/vimeo.com\/([\w/:%#\$&\?\(\)~\.=\+\-]+)/g, '//vimeo.com/$1#t=00m00s')
      .replace(/moz\-extension:(.*?)(.{24})$/g, 'https://www.youtube.com/channel/$2');
    prompt('HTML link', '■<a href="' + u + '" target="_blank" rel="nofollow">' + t.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/'/g, '&apos;').replace(/</g, '&lt;').replace(/>/g, '&gt;') + '</a><br>');
  }
})();

一行表示

javascript:(function(){const article=document.querySelector('article.js-entryWrapper');if(article){const title=article.getAttribute('data-unique-entry-title');if(!title){alert('Could not find the entry title.');return;}const url=location.href;let blogName=document.querySelector('title[data-react-helmet="true"]')?.textContent||(window.blogMap&&Object.keys(window.blogMap)[0]?window.blogMap[Object.keys(window.blogMap)[0]].blog_title:'')||document.title.split(' | ')[1]||'Unknown Blog';blogName=blogName.trim().replace(/\u3000/g,' ');const linkText=`${title} | ${blogName}`.normalize('NFC').replace(/[\u0000-\u0008\u000B-\u001F\u007F-\u009F\u200B-\u200F\u202A-\u202E\u2060-\u206F\uFE00-\uFE0F\uFEFF]/g,'').replace(/[\r\n]/g,'▼');const html=`■<a href="${url}" target="_blank" rel="nofollow">${linkText.replace(/&/g,'&amp;').replace(/"/g,'&quot;').replace(/'/g,'&apos;').replace(/</g,'&lt;').replace(/>/g,'&gt;')}</a><br>`;prompt('Copy the following link HTML:',html);}else{var t=document.title.normalize('NFC').replace(/ヨドバシ\.com - (.*?) 通販【全品無料配達】/g,'$1').replace(/ - YouTube/g,'').replace(/[\u0000-\u0008\u000B-\u001F\u007F-\u009F\u200B-\u200F\u202A-\u202E\u2060-\u206F\uFE00-\uFE0F\uFEFF]/g,'').replace(/[\r\n]/g,'▼').replace(/https?:\/\/[^\s]+/g,function(m){return m.replace(/:/g,':');});var u=location.href.replace(/http:\/\/localhost:1313/g,'').replace(/https:\/\/benkyosukisuki.com/g,'').replace(/https:\/\/netjuku.net/g,'').replace(/search\?.*\&q=/g,'search?&q=').replace(/\&stick=([^&|"]+)/g,'').replace(/\&ved=([^&|"]+)/g,'').replace(/\&biw=([^&|"]+)/g,'').replace(/\&bih=([^&|"]+)/g,'').replace(/\?frm_src=thumb_module/g,'').replace(/\&feature=youtu.be\&t=(\d+)m(\d+)s/g,'').replace(/time_continue=\d+\&/g,'').replace(/\#t=(\d+)m(\d+)s/g,'').replace(/\/\/www.youtube.com\/watch\?(.*?)v=(.{11})(.*)/g,'//youtu.be/$2?t=00m00s').replace(/\/\/www.amazon.co.jp\/.*\/dp\/(.{10}).*/g,'//www.amazon.co.jp/dp/$1').replace(/\/\/vimeo.com\/([\w/:%#\$&\?\(\)~\.=\+\-]+)/g,'//vimeo.com/$1#t=00m00s').replace(/moz\-extension:(.*?)(.{24})$/g,'https://www.youtube.com/channel/$2');prompt('HTML link','■<a href="'+u+'" target="_blank" rel="nofollow">'+t.replace(/&/g,'&amp;').replace(/"/g,'&quot;').replace(/'/g,'&apos;').replace(/</g,'&lt;').replace(/>/g,'&gt;')+'</a><br>');}})();

アメブロの記事タイトル取得における齟齬の原因と解決策

アメブロ〔Amebaブログ〕の記事ページでは、通常のブックマークレットで取得した[URL+記事タイトル]〔以下、【1】〕が、画面に表示される現行の記事タイトルと異なる場合があります。 一方、アメブロの仕様に対応したブックマークレット〔以下、【2】〕では、正しい現行タイトルを取得できます。 以下はその例です。

  • 【1】通常のブックマークレットで取得した結果:
    • ■<a href="https://ameblo.jp/tsukitoshinpi9/entry-12937779360.html" target="_blank" rel="nofollow">パニック障害不安症巫病パニックHSP |月と神秘巫女龍女ヒーラー</a>
  • 【2】アメブロの仕様に対応したブックマークレットで取得した結果:
    • ■<a href="https://ameblo.jp/tsukitoshinpi9/entry-12937779360.html" target="_blank" rel="nofollow">不安な時のお守り〔天然石〕|月と神秘巫女龍女ヒーラー</a>

アメブロの記事タイトル取得における齟齬の原因と解決策

  • アメブロの記事ページでは通常のブックマークレットで取得した【1】記事タイトルが画面表示の現行タイトルと異なる場合がある。
  • アメブロの仕様に対応したブックマークレット【2】を使用すれば正しい現行タイトルを取得することが可能である。

問題の原因:アメブロのタイトル管理仕様

  • アメブロは記事公開時に設定した初期タイトルを固有URLに紐づくメタ情報〔<title>タグやOGPタグ〕に保存しシステム内部で固定している。
  • 初期タイトルは記事タイトルを編集しても更新されず通常のブックマークレットや外部サービスは固定された初期タイトルを参照する。
  • 現行タイトルは記事編集でタイトルを変更した際に記事ページの<h1>タグなどの画面表示用の要素にのみ適用される。
  • 現行タイトルはHTMLのメタ情報には反映されないため通常のブックマークレット【1】が現行タイトルと異なる初期タイトルを取得する齟齬が生じる。

検証:アメブロの仕様と取得方法

  • 記事の固有URL〔例:entry-12937779360.html〕は変更不可で初期タイトルがこのURLに紐づくメタ情報として固定される。
  • タイトル変更後、画面表示用の要素〔例:<h1>タグ〕に現行タイトル〔不安な時のお守り〔天然石〕〕が反映されるが<title>タグやOGPタグは初期タイトル〔パニック障害不安症巫病パニックHSP〕のままである。
  • 通常のブックマークレットは<title>タグやOGPタグを参照するため固定された初期タイトルを取得し変更後の現行タイトルを取得できない。
  • アメブロ対応ブックマークレット【2】は画面表示用の現行タイトルが格納されているDOM要素を直接参照するよう設計され現行タイトルを取得可能である。

現象のまとめ

  • タイトル変更後もHTMLメタ情報〔<title>/OGP〕は初期タイトル〔パニック障害…〕が固定され通常のブックマークレットはこれを取得する。
  • タイトル変更後の画面表示のタイトル〔<h1>など〕は現行タイトル〔不安な時のお守り〔天然石〕〕となりアメブロ対応ブックマークレットがこれを取得する。

解決策:JavaScriptでの現行タイトル取得

  • ブックマークレットで現行タイトルを取得するにはJavaScriptで画面表示用のDOM要素〔例:<h1>タグやクラス名.articleTitle〕を参照する必要がある。
  • アメブロ対応ブックマークレットのコード例ではdocument.querySelector〔'.articleTitle'〕?.textContentで現行タイトルを取得しdocument.titleをフォールバックとして使用する。
  • SNSや外部サービスが初期タイトルを表示する場合はアメブロのメタ情報固定が原因であり根本的な解決は難しい場合がある。

結論

  • アメブロの記事ページは初期タイトル〔メタ情報に固定〕と現行タイトル〔画面表示用〕を別々に保持する仕様により通常のブックマークレットでは初期タイトルしか取得できない。
  • この問題はキャッシュではなくアメブロのシステムが初期タイトルを<title>タグやOGPタグに固定する仕様に起因する。
  • 解決策としてJavaScriptで画面表示用のDOM要素〔例:<h1>や.articleTitle〕を参照するブックマークレットを使用することで現行タイトルを正確に取得する。

記事の書き手側の対応策|[タイトル]に齟齬を生じさせないために

  • 初回投稿時にSEOキーワードと記事テーマを確定させ慎重なタイトル設計を行うべきである。
  • タイトルに齟齬が生じた場合には記事を再発行することも解決策の一つとして考えられる。

はてなブログとnoteでは、アメブロのような問題は生じない

  • アメブロで指摘された記事タイトル変更後も初期タイトルがメタ情報に固定される問題ははてなブログとnoteでは基本的に生じない。
  • はてなブログとnoteはタイトル変更時にメタ情報も連動して更新される設計となっており画面表示と外部取得の齟齬が起きにくい。
  • ただしSNSのキャッシュによる一時的な遅延はどのブログサービスでも起こり得る一般的な現象である。

1. はてなブログの場合

  • はてなブログでは公開済み記事のタイトルを編集すると画面表示のタイトル<h1>タグ相当の要素、<title>タグ、OGPタグがすべて即時または短時間で更新される。
  • はてなブログはタイトル編集がメタ情報に反映される仕様であり通常のブックマークレットで現行タイトルを取得可能で古いタイトルが固定される問題は報告されていない。
  • SNSのキャッシュで一時的に古いタイトルが表示される場合があるがアメブロの仕様問題ではなく外部サービスの挙動である。
  • アメブロのような初期タイトル固定の仕様はなくJavaScriptでのDOM参照変更は不要であり変更後すぐに正しいタイトルが外部で取得される。

2. noteの場合

  • noteでは記事編集でタイトルを変更すると画面表示のタイトルとOGPタグ〔og:title〕が更新され特別なメタ情報固定はない。
  • 通常のブックマークレットで現行タイトルを取得できリンクプレビューでも変更が反映されるがTwitterのCard Validatorでキャッシュクリアが必要な場合がある。
  • 古いタイトルが固定される報告はなくタイトル変更後の反映がスムーズでTwitter共有時のプレビュー遅延はキャッシュによるものである。
  • アメブロのような問題は生じずタイトル変更がメタ情報に即反映されキャッシュクリアツールで外部表示を調整すれば問題ない。

アメブロvs. はてなブログvs. note

  • アメブロはタイトル変更時も初期タイトルが<title>/OGPに固定されるがはてなブログとnoteでは即時更新される。
  • ブックマークレットでの取得はアメブロでは古いタイトルとなりDOM参照変更が必要だがはてなブログとnoteでは標準で現行タイトルを取得可能である。
  • 外部プレビュー〔SNS〕はアメブロでは古いタイトルが固定されるがはてなブログとnoteでは更新が反映されキャッシュによる稀な遅延がある。
  • 解決策としてアメブロではJavaScriptでDOM〔<h1>など〕参照変更が必要だがはてなブログやnoteでは不要である。
  • 全体としてアメブロの初期タイトル固定の仕様ははてなブログとnoteにはなくユーザー体験は優れている。