<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns="http://purl.org/rss/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel rdf:about="https://let.hatelabo.jp/Lhankor_Mhy/rss">
    <link>https://let.hatelabo.jp/Lhankor_Mhy/rss</link>
    <description></description>
    <title>Bookmarklets from Lhankor_Mhy</title>
    <items>
      <rdf:Seq>
        <rdf:li rdf:resource="https://let.hatelabo.jp/Lhankor_Mhy/let/lbOrqOfegqAA"/>
        <rdf:li rdf:resource="https://let.hatelabo.jp/Lhankor_Mhy/let/lbKIiYmqgOAA"/>
        <rdf:li rdf:resource="https://let.hatelabo.jp/Lhankor_Mhy/let/lbKGu5jsgaAA"/>
        <rdf:li rdf:resource="https://let.hatelabo.jp/Lhankor_Mhy/let/laGdx-DigsAA"/>
        <rdf:li rdf:resource="https://let.hatelabo.jp/Lhankor_Mhy/let/jo3aqcTggKAA"/>
        <rdf:li rdf:resource="https://let.hatelabo.jp/Lhankor_Mhy/let/jun3wcKygeAA"/>
        <rdf:li rdf:resource="https://let.hatelabo.jp/Lhankor_Mhy/let/jrLIsPyegeAA"/>
        <rdf:li rdf:resource="https://let.hatelabo.jp/Lhankor_Mhy/let/hLHX8qPqyax_"/>
        <rdf:li rdf:resource="https://let.hatelabo.jp/Lhankor_Mhy/let/kpTi_IGaguAA"/>
        <rdf:li rdf:resource="https://let.hatelabo.jp/Lhankor_Mhy/let/kc329cjkgqAA"/>
        <rdf:li rdf:resource="https://let.hatelabo.jp/Lhankor_Mhy/let/jtaB0fa4gYAA"/>
        <rdf:li rdf:resource="https://let.hatelabo.jp/Lhankor_Mhy/let/kLOm3rHEgeAA"/>
        <rdf:li rdf:resource="https://let.hatelabo.jp/Lhankor_Mhy/let/kOGSsI-SgsAA"/>
        <rdf:li rdf:resource="https://let.hatelabo.jp/Lhankor_Mhy/let/kNe6m5vsgKAA"/>
        <rdf:li rdf:resource="https://let.hatelabo.jp/Lhankor_Mhy/let/j9W6maaGgKAA"/>
        <rdf:li rdf:resource="https://let.hatelabo.jp/Lhankor_Mhy/let/j9W5qIj-gKAA"/>
        <rdf:li rdf:resource="https://let.hatelabo.jp/Lhankor_Mhy/let/j7qesMCUgYAA"/>
        <rdf:li rdf:resource="https://let.hatelabo.jp/Lhankor_Mhy/let/jr-yw7yCgMAA"/>
        <rdf:li rdf:resource="https://let.hatelabo.jp/Lhankor_Mhy/let/jLrKiqvEgoAA"/>
        <rdf:li rdf:resource="https://let.hatelabo.jp/Lhankor_Mhy/let/hLHVoNuA3dNN"/>
      </rdf:Seq>
    </items>
  </channel>
  <item rdf:about="https://let.hatelabo.jp/Lhankor_Mhy/let/lbOrqOfegqAA">
    <link>https://let.hatelabo.jp/Lhankor_Mhy/let/lbOrqOfegqAA</link>
    <dc:date>2026-08-26T09:56:20Z</dc:date>
    <description>「シェア」で出てくるOGP画像のことです</description>
    <dc:creator>Lhankor_Mhy</dc:creator>
    <title>[Let] はてなパークスでメェメェ画像を表示</title>
    <content:encoded>&lt;a href="javascript:%7Balert%28%27%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88%E3%82%92%E3%82%AF%E3%83%AA%E3%83%83%E3%82%AF%E3%81%99%E3%82%8B%E3%81%A8%E7%94%BB%E5%83%8F%E3%82%92%E8%A1%A8%E7%A4%BA%E3%81%97%E3%81%BE%E3%81%99%27%29%3Bdocument.body.addEventListener%28%27click%27%2C%28function%28event%29%7Bconst%20baabaa%3Dconfirm%28%27%E3%83%A1%E3%82%A7%E3%83%A1%E3%82%A7%EF%BC%9F%27%29%3F%27%27%3A%27%3Fm%3Draw%27%3Bconst%20commentId%3Devent.target.closest%28%27%5Bdata-comment-block-id%5D%27%29%3F.getAttribute%28%27data-comment-block-id%27%29%3Bconst%20url%3D%60https%3A%2F%2Fp.hatena.ne.jp%2Fog%2Freplies%2F%24%7BcommentId%7D%24%7Bbaabaa%7D%60%3Bwindow.open%28url%2C%27_blank%27%2C%27noopener%2Cnoreferrer%27%29%7D%29%2C%7Bonce%3Atrue%7D%29%7D"&gt;はてなパークスでメェメェ画像を表示&lt;/a&gt;&lt;pre&gt;/*
 * @title はてなパークスでメェメェ画像を表示
 * @description 「シェア」で出てくるOGP画像のことです
 * @include https://p.hatena.ne.jp
 * @license CC0
 * @javascript_url 
 */

{
    alert('コメントをクリックすると画像を表示します');
    document.body.addEventListener('click', function (event) {
        const baabaa = confirm('メェメェ？') ? '' : '?m=raw';
        const commentId = event.target.closest('[data-comment-block-id]')?.getAttribute('data-comment-block-id');
        const url = `https://p.hatena.ne.jp/og/replies/${commentId}${baabaa}`;
        window.open(url, '_blank', 'noopener,noreferrer');
    }, { once: true });
}
&lt;/pre&gt;</content:encoded>
  </item>
  <item rdf:about="https://let.hatelabo.jp/Lhankor_Mhy/let/lbKIiYmqgOAA">
    <link>https://let.hatelabo.jp/Lhankor_Mhy/let/lbKIiYmqgOAA</link>
    <dc:date>2026-08-25T01:36:51Z</dc:date>
    <description>はてブで https://bookmarker-encyclopedia.netlify.app のキャッチフレーズをツールチップで表示します。アイコンの上で2秒ぐらいホバーしてください。 see: https://p.hatena.ne.jp/p/1539910495903944704/t/1540379794804314112#_r_1541393591480356864</description>
    <dc:creator>Lhankor_Mhy</dc:creator>
    <title>[Let] ブックマーカー図鑑ツールチップ（はてなパークス版）</title>
    <content:encoded>&lt;a href="javascript:%22https%3A%2F%2Flet.st-hatelabo.com%2FLhankor_Mhy%2Flet%2FlbKIiYmqgOAA.bookmarklet.js%20%28arg%29%22.replace%28%2F%28%5CS%2B%29%5Cs%2B%28%5CS%2A%29%2F%2Cfunction%28s%2Curl%2Carg%29%7Bs%3Ddocument.createElement%28%22script%22%29%3Bs.charset%3D%22utf-8%22%3Bs.src%3Durl%2B%22%3Fs%3D%22%2BencodeURIComponent%28arg%29%3Bdocument.body.appendChild%28s%29%7D%29%3Bvoid%280%29%3B"&gt;ブックマーカー図鑑ツールチップ（はてなパークス版）&lt;/a&gt;&lt;pre&gt;// ==UserScript==
// @name         ブックマーカー図鑑ツールチップ（はてなパークス版）
// @title        ブックマーカー図鑑ツールチップ（はてなパークス版）
// @namespace    https://let.hatelabo.jp/Lhankor_Mhy/let/lbKIiYmqgOAA
// @version      0.1
// @description  はてブで https://bookmarker-encyclopedia.netlify.app のキャッチフレーズをツールチップで表示します。アイコンの上で2秒ぐらいホバーしてください。 see: https://p.hatena.ne.jp/p/1539910495903944704/t/1540379794804314112#_r_1541393591480356864
// @author       Lhankor_Mhy
// @match        https://p.hatena.ne.jp/*
// @icon         https://p.hatena.ne.jp/icon.png?v=1787561803
// @license      CC0
// @noframes
// @grant        none
// ==/UserScript==

(async function () {
    'use strict';
    const ID = &amp;quot;bookmarkerEncyclopediaTooltip&amp;quot;;

    // polyfill for interestfor
    const supported = Object.hasOwn(
        HTMLButtonElement.prototype,
        &amp;quot;interestForElement&amp;quot;,
    );
    if (!supported) {
        await import('https://cdn.jsdelivr.net/npm/interestfor@1.0.8/src/interestfor.min.js');
    }

    const { default: localforage } = await import('https://cdn.jsdelivr.net/npm/localforage@1.10.0/+esm');
    const store = localforage.createInstance({
        name: ID,
        storeName: ID,
    });

    // insert tooltip elements and styles
    document.body.insertAdjacentHTML('beforeend', `
        &amp;lt;div id=&amp;quot;${ID}&amp;quot; popover interestfor=&amp;quot;ideologyTooltip&amp;quot;&amp;gt;...&amp;lt;/div&amp;gt;
        &amp;lt;style&amp;gt;
        #${ID} {
            --ink: #1c1a17;
            --paper: #f5f0e6;
            --card: #fffdf7;
            --gold: #b8893a;
            --gold-soft: #e8d9b5;
            --accent: #2f6f6b;
            --danger: #b14a3b;
            --muted: #8a8071;
            --line: #d8cdb4;

            font-size: 0.8rem;
            font-weight: 700;
            color: var(--gold);

            max-width: 700px;
            margin: -7px;
            padding: 0px;
            background: var(--card);
            border: 3px solid var(--ink);
            border-width: 0px;
            border-radius: 7px;
            box-shadow: 0px 0px 0 rgba(28, 26, 23, .18);

            width: fit-content;
            height: 0px;
            overflow: hidden;
            position-area: center span-right;
            align-self: start;

            transition: all .3s .5s allow-discrete, box-shadow .3s 1.1s allow-discrete, translate .3s 1.1s allow-discrete;
            interpolate-size: allow-keywords;
            translate: 10px 12px;

            &amp;amp;:popover-open {
                box-shadow: 10px 12px 0 rgba(28, 26, 23, .18);
                translate: 0px 0px;
                height: auto;
                padding: 3.5px;
                border-width: 3px;
                @starting-style {
                    height: 0px;
                    box-shadow: 0px 0px 0 rgba(28, 26, 23, .18);
                    translate: 10px 12px;
                    // border-radius: 0px;
                    padding: 0px;
                    border-width: 0px;
                }
            }
        }
        #ideologyTooltip{
            font-size: 0.6rem;
            color: var(--ink);
            max-width: 700px;
            margin: 0;
            background: var(--card);
            border: 1px solid var(--line);
            border-radius: 7px;

            width: fit-content;
            position-area: bottom center;
            align-self: start;
        }
        [interestfor=&amp;quot;${ID}&amp;quot;] {
            interest-delay: 1.5s .1s;
            --interest-delay: 1.5s .1s;
            img{
                transition: rotate .3s .5s,scale .3s .5s;
                &amp;amp;:hover{
                    rotate: -10deg;
                    scale: 1.2;
                }
            }
        }
        [interestfor=&amp;quot;ideologyTooltip&amp;quot;] {
            interest-delay: 3s .1s;
            --interest-delay: 3s .1s;
        }
        &amp;lt;/style&amp;gt;
        `);
    const tooltip = document.getElementById(ID);

    function init() {
        // add interest invokers
        document.querySelectorAll('a[class^=&amp;quot;_authorAvatar&amp;quot;],a[class^=&amp;quot;_avatar&amp;quot;]').forEach(icon =&amp;gt; {
            icon.setAttribute('interestfor', tooltip.id);
        })
    }

    // add interest event listener
    tooltip.addEventListener(&amp;quot;interest&amp;quot;, async (e) =&amp;gt; {
        const icon = e.source;
        const userId = icon.getAttribute('href').split('/').at(-1).toLowerCase();

        let profile = await store.getItem(`${userId}`);

        async function callAPI() {
            const response = await fetch(`https://bookmarker-encyclopedia.netlify.app/api/profiles/${userId}.json`);
            const profile = {
                profile: response.ok ? JSON.parse(await response.text()) : null,
                expired: new Date().getTime() + 1000 * 60 * 60 * 24 * 7
            }; // expire in 7 days
            await store.setItem(`${userId}`, profile);
            return profile;
        }

        if (!profile || !(new Date().getTime() &amp;lt; profile?.expired)) {
            profile = await callAPI();
        }

        if (!profile?.profile) {
            tooltip.textContent = &amp;quot;プロフィールが見つかりませんでした。&amp;quot;;
            return;
        }
        const { profile: { generated: { catchphrase, ideologyProse } } } = profile;
        tooltip.textContent = catchphrase;
        const clonedIcon = icon.cloneNode(true);
        clonedIcon.removeAttribute('interestfor');
        // [...clonedIcon.attributes].forEach(attr =&amp;gt; {
        //     clonedIcon.removeAttribute(attr.name);
        // });
        clonedIcon.setAttribute('href', `https://bookmarker-encyclopedia.netlify.app/profiles/${userId}`);
        const ideologyTooltip = document.createElement('div');
        ideologyTooltip.setAttribute('id', `ideologyTooltip`);
        ideologyTooltip.textContent = ideologyProse;
        ideologyTooltip.setAttribute('popover', '');
        tooltip.insertAdjacentElement('beforeend', ideologyTooltip);
        tooltip.insertAdjacentElement('afterbegin', clonedIcon);
    });
    tooltip.addEventListener(&amp;quot;loseinterest&amp;quot;, (e) =&amp;gt; {
        tooltip.textContent = &amp;quot;...&amp;quot;;
    });

    // add mutation observer for lazy-loaded bookmarks
    const targetNode = document.body;

    const mutationConfig = { childList: true };
    const mutationCallback = function (mutationsList, observer) {
        for (const mutation of mutationsList) {
            if (mutation.type === 'childList') {
                init();
            }
        }
    };
    const mutationObserver = new MutationObserver(mutationCallback);
    mutationObserver.observe(targetNode, mutationConfig);

    init();
})();&lt;/pre&gt;</content:encoded>
  </item>
  <item rdf:about="https://let.hatelabo.jp/Lhankor_Mhy/let/lbKGu5jsgaAA">
    <link>https://let.hatelabo.jp/Lhankor_Mhy/let/lbKGu5jsgaAA</link>
    <dc:date>2026-08-24T10:07:14Z</dc:date>
    <description>はてなパークスのシェアリンクをブクマすると上手くリンクしない問題の修正をする。see: https://p.hatena.ne.jp/p/1539910495903944704/t/1540379794804314112#_r_1541388268463984640</description>
    <dc:creator>Lhankor_Mhy</dc:creator>
    <title>[Let] はてなパークスのシェアリンク修正</title>
    <content:encoded>&lt;a href="javascript:%7Bconst%20url%3Dnew%20URL%28location%29%3Blocation.href%3D%60%24%7Burl.origin%7D%24%7Burl.pathname%7D%23_r_%24%7Burl.searchParams.get%28%27r%27%29%7D%60%7D"&gt;はてなパークスのシェアリンク修正&lt;/a&gt;&lt;pre&gt;/*
 * @title はてなパークスのシェアリンク修正
 * @description はてなパークスのシェアリンクをブクマすると上手くリンクしない問題の修正をする。see: https://p.hatena.ne.jp/p/1539910495903944704/t/1540379794804314112#_r_1541388268463984640
 * @include https://p.hatena.ne.jp/
 * @license CC0
 * @javascript_url
 */

{
    const url = new URL(location);
    location.href=`${url.origin}${url.pathname}#_r_${url.searchParams.get('r')}`;
}&lt;/pre&gt;</content:encoded>
  </item>
  <item rdf:about="https://let.hatelabo.jp/Lhankor_Mhy/let/laGdx-DigsAA">
    <link>https://let.hatelabo.jp/Lhankor_Mhy/let/laGdx-DigsAA</link>
    <dc:date>2026-08-10T08:38:17Z</dc:date>
    <description>はてブで https://bookmarker-encyclopedia.netlify.app のキャッチフレーズをツールチップで表示します。アイコンの上で2秒ぐらいホバーしてください。</description>
    <dc:creator>Lhankor_Mhy</dc:creator>
    <title>[Let] ブックマーカー図鑑ツールチップ</title>
    <content:encoded>&lt;a href="javascript:%22https%3A%2F%2Flet.st-hatelabo.com%2FLhankor_Mhy%2Flet%2FlaGdx-DigsAA.bookmarklet.js%20%28arg%29%22.replace%28%2F%28%5CS%2B%29%5Cs%2B%28%5CS%2A%29%2F%2Cfunction%28s%2Curl%2Carg%29%7Bs%3Ddocument.createElement%28%22script%22%29%3Bs.charset%3D%22utf-8%22%3Bs.src%3Durl%2B%22%3Fs%3D%22%2BencodeURIComponent%28arg%29%3Bdocument.body.appendChild%28s%29%7D%29%3Bvoid%280%29%3B"&gt;ブックマーカー図鑑ツールチップ&lt;/a&gt;&lt;pre&gt;// ==UserScript==
// @name         ブックマーカー図鑑ツールチップ
// @title         ブックマーカー図鑑ツールチップ
// @namespace    https://let.hatelabo.jp/Lhankor_Mhy/let/laGdx-DigsAA
// @version      0.3
// @description  はてブで https://bookmarker-encyclopedia.netlify.app のキャッチフレーズをツールチップで表示します。アイコンの上で2秒ぐらいホバーしてください。
// @author       Lhankor_Mhy
// @match        https://b.hatena.ne.jp/entry/*
// @icon         https://b.hatena.ne.jp/favicon.ico
// @license      CC0
// @noframes
// @grant        none
// ==/UserScript==

(async function () {
    'use strict';
    const ID = &amp;quot;bookmarkerEncyclopediaTooltip&amp;quot;;

    // polyfill for interestfor
    const supported = Object.hasOwn(
        HTMLButtonElement.prototype,
        &amp;quot;interestForElement&amp;quot;,
    );
    if (!supported) {
        await import('https://cdn.jsdelivr.net/npm/interestfor@1.0.8/src/interestfor.min.js');
    }

    const { default: localforage } = await import('https://cdn.jsdelivr.net/npm/localforage@1.10.0/+esm');
    const store = localforage.createInstance({
        name: ID,
        storeName: ID,
    });

    // insert tooltip elements and styles
    document.body.insertAdjacentHTML('beforeend', `
        &amp;lt;div id=&amp;quot;${ID}&amp;quot; popover interestfor=&amp;quot;ideologyTooltip&amp;quot;&amp;gt;...&amp;lt;/div&amp;gt;
        &amp;lt;style&amp;gt;
        #${ID} {
            --ink: #1c1a17;
            --paper: #f5f0e6;
            --card: #fffdf7;
            --gold: #b8893a;
            --gold-soft: #e8d9b5;
            --accent: #2f6f6b;
            --danger: #b14a3b;
            --muted: #8a8071;
            --line: #d8cdb4;

            font-size: 0.8rem;
            font-weight: 700;
            color: var(--gold);

            max-width: 700px;
            margin: -7px;
            padding: 0px;
            background: var(--card);
            border: 3px solid var(--ink);
            border-width: 0px;
            border-radius: 7px;
            box-shadow: 0px 0px 0 rgba(28, 26, 23, .18);

            width: fit-content;
            height: 0px;
            overflow: hidden;
            position-area: center span-right;
            align-self: start;

            transition: all .3s .5s allow-discrete, box-shadow .3s 1.1s allow-discrete, translate .3s 1.1s allow-discrete;
            interpolate-size: allow-keywords;
            translate: 10px 12px;

            &amp;amp;:popover-open {
                box-shadow: 10px 12px 0 rgba(28, 26, 23, .18);
                translate: 0px 0px;
                height: auto;
                padding: 3.5px;
                border-width: 3px;
                @starting-style {
                    height: 0px;
                    box-shadow: 0px 0px 0 rgba(28, 26, 23, .18);
                    translate: 10px 12px;
                    // border-radius: 0px;
                    padding: 0px;
                    border-width: 0px;
                }
            }
        }
        #ideologyTooltip{
            font-size: 0.6rem;
            color: var(--ink);
            max-width: 700px;
            margin: 0;
            background: var(--card);
            border: 1px solid var(--line);
            border-radius: 7px;

            width: fit-content;        
            position-area: bottom center;
            align-self: start;
        }
        [interestfor=&amp;quot;${ID}&amp;quot;] {
            interest-delay: 1.5s .1s;
            --interest-delay: 1.5s .1s;
            img{
                transition: rotate .3s .5s,scale .3s .5s;
                &amp;amp;:hover{
                    rotate: -10deg;
                    scale: 1.2;
                }
            }
        }
        [interestfor=&amp;quot;ideologyTooltip&amp;quot;] {
            interest-delay: 3s .1s;
            --interest-delay: 3s .1s;
        }
        &amp;lt;/style&amp;gt;
        `);
    const tooltip = document.getElementById(ID);

    function init() {
        // add interest invokers
        document.querySelectorAll('.entry-user-icon').forEach(icon =&amp;gt; {
            icon.setAttribute('interestfor', tooltip.id);
        })
    }

    // add interest event listener
    tooltip.addEventListener(&amp;quot;interest&amp;quot;, async (e) =&amp;gt; {
        const icon = e.source;
        const userId = icon.getAttribute('href').split('/')[1].toLowerCase();

        let profile = await store.getItem(`${userId}`);

        async function callAPI() {
            const response = await fetch(`https://bookmarker-encyclopedia.netlify.app/api/profiles/${userId}.json`);
            const profile = {
                profile: response.ok ? JSON.parse(await response.text()) : null,
                expired: new Date().getTime() + 1000 * 60 * 60 * 24 * 7
            }; // expire in 7 days
            await store.setItem(`${userId}`, profile);
            return profile;
        }

        if (!profile || !(new Date().getTime() &amp;lt; profile?.expired)) {
            profile = await callAPI();
        }

        if (!profile?.profile) {
            tooltip.textContent = &amp;quot;プロフィールが見つかりませんでした。&amp;quot;;
            return;
        }
        const { profile: { generated: { catchphrase, ideologyProse } } } = profile;
        tooltip.textContent = catchphrase;
        const clonedIcon = icon.cloneNode(true);
        clonedIcon.setAttribute('interestfor', null);
        clonedIcon.setAttribute('href', `https://bookmarker-encyclopedia.netlify.app/profiles/${userId}`);
        const ideologyTooltip = document.createElement('div');
        ideologyTooltip.setAttribute('id', `ideologyTooltip`);
        ideologyTooltip.textContent = ideologyProse;
        ideologyTooltip.setAttribute('popover', '');
        tooltip.insertAdjacentElement('beforeend', ideologyTooltip);
        tooltip.insertAdjacentElement('afterbegin', clonedIcon);
    });
    tooltip.addEventListener(&amp;quot;loseinterest&amp;quot;, (e) =&amp;gt; {
        tooltip.textContent = &amp;quot;...&amp;quot;;
    });

    // add mutation observer for lazy-loaded bookmarks
    const targetNode = document.querySelector('.js-bookmarks-recent');

    const mutationConfig = { childList: true };
    const mutationCallback = function (mutationsList, observer) {
        for (const mutation of mutationsList) {
            if (mutation.type === 'childList') {
                init();
            }
        }
    };
    const mutationObserver = new MutationObserver(mutationCallback);
    mutationObserver.observe(targetNode, mutationConfig);

    init();
})();&lt;/pre&gt;</content:encoded>
  </item>
  <item rdf:about="https://let.hatelabo.jp/Lhankor_Mhy/let/jo3aqcTggKAA">
    <link>https://let.hatelabo.jp/Lhankor_Mhy/let/jo3aqcTggKAA</link>
    <dc:date>2026-06-17T04:18:05Z</dc:date>
    <description>CSRF対策がされた？　使用できなくなりました。</description>
    <dc:creator>Lhankor_Mhy</dc:creator>
    <title>[Let] Amazon から Kinoppy</title>
    <content:encoded>&lt;a href="javascript:%22https%3A%2F%2Flet.st-hatelabo.com%2FLhankor_Mhy%2Flet%2Fjo3aqcTggKAA.bookmarklet.js%20%28arg%29%22.replace%28%2F%28%5CS%2B%29%5Cs%2B%28%5CS%2A%29%2F%2Cfunction%28s%2Curl%2Carg%29%7Bs%3Ddocument.createElement%28%22script%22%29%3Bs.charset%3D%22utf-8%22%3Bs.src%3Durl%2B%22%3Fs%3D%22%2BencodeURIComponent%28arg%29%3Bdocument.body.appendChild%28s%29%7D%29%3Bvoid%280%29%3B"&gt;Amazon から Kinoppy&lt;/a&gt;&lt;pre&gt;/*
 * @title Amazon から Kinoppy
 * @description CSRF対策がされた？　使用できなくなりました。
 * @include http://*
 * @license MIT License
 * @require 
 */


void (
//  location.href=&amp;quot;https://www.kinokuniya.co.jp/disp/CSfDispListPage_001.jsp?qs=true&amp;amp;ptk=01&amp;amp;q=&amp;quot;+JSON.parse(document.querySelector('[data-show-all-offers-display]').dataset.showAllOffersDisplay).asin
  location.href=&amp;quot;https://www.kinokuniya.co.jp/disp/CSfDispListPage_001.jsp?qs=true&amp;amp;ptk=03&amp;amp;q=&amp;quot;+encodeURIComponent(productTitle.textContent.trim())
)&lt;/pre&gt;</content:encoded>
  </item>
  <item rdf:about="https://let.hatelabo.jp/Lhankor_Mhy/let/jun3wcKygeAA">
    <link>https://let.hatelabo.jp/Lhankor_Mhy/let/jun3wcKygeAA</link>
    <dc:date>2025-12-01T05:19:34Z</dc:date>
    <description>メールを開いてブックマークレットを使ってからページをクリックすると、メールのパーマリンクをクリップボードにコピーします。</description>
    <dc:creator>Lhankor_Mhy</dc:creator>
    <title>[Let] Gmailのパーマリンク取得</title>
    <content:encoded>&lt;a href="javascript:%28async%28%29%3D%3E%7Bconst%20targetDataAttributeName%3D%22data-message-id%22%3Bconst%20waitForEvent%3D%28eventTarget%2CeventType%29%3D%3Enew%20Promise%28%28%28resolve%2Creject%29%3D%3EeventTarget.addEventListener%28eventType%2Cresolve%2C%7Bonce%3Atrue%2Csignal%3AAbortSignal.timeout%281e4%29%7D%29%29%29%3Blet%20targetElement%3Ddocument.querySelector%28%60%5B%24%7BtargetDataAttributeName%7D%5D%60%29%3Bif%28%21targetElement%29%7Balert%28%22%E3%83%A1%E3%83%BC%E3%83%AB%E3%82%92%E9%96%8B%E3%81%84%E3%81%A6%E3%81%8B%E3%82%89%E3%83%96%E3%83%83%E3%82%AF%E3%83%9E%E3%83%BC%E3%82%AF%E3%83%AC%E3%83%83%E3%83%88%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84%22%29%3Breturn%7Dconst%20e%3Dawait%20waitForEvent%28document%2C%27mousedown%27%29%3BtargetElement%3De.target.closest%28%60%5B%24%7BtargetDataAttributeName%7D%5D%60%29%3F%3FtargetElement%3Bconst%20threadId%3DBigInt%28targetElement%3F.getAttribute%28targetDataAttributeName%29.split%28%27%3A%27%29%5B1%5D%29.toString%2816%29%3Bnavigator.clipboard.writeText%28%60https%3A%2F%2Fmail.google.com%2Fmail%2Fu%2F0%2F%23all%2F%24%7BencodeURIComponent%28threadId%29%7D%60%29.then%28%28%28%29%3D%3Ealert%28%22%E3%83%A1%E3%83%BC%E3%83%AB%E3%81%AE%E3%83%91%E3%83%BC%E3%83%9E%E3%83%AA%E3%83%B3%E3%82%AF%E3%82%92%E3%82%AF%E3%83%AA%E3%83%83%E3%83%97%E3%83%9C%E3%83%BC%E3%83%89%E3%81%AB%E3%82%B3%E3%83%94%E3%83%BC%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F%22%29%29%29.catch%28%28err%3D%3E%7Bconsole.error%28%22%E3%82%AF%E3%83%AA%E3%83%83%E3%83%97%E3%83%9C%E3%83%BC%E3%83%89%E3%81%B8%E3%81%AE%E3%82%B3%E3%83%94%E3%83%BC%E3%81%AB%E5%A4%B1%E6%95%97%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F%22%2Cerr%29%3Balert%28%22%E3%82%AF%E3%83%AA%E3%83%83%E3%83%97%E3%83%9C%E3%83%BC%E3%83%89%E3%81%B8%E3%81%AE%E3%82%B3%E3%83%94%E3%83%BC%E3%81%AB%E5%A4%B1%E6%95%97%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F%22%29%7D%29%29%7D%29%28%29%3B"&gt;Gmailのパーマリンク取得&lt;/a&gt;&lt;pre&gt;/*
 * @title Gmailのパーマリンク取得
 * @description メールを開いてブックマークレットを使ってからページをクリックすると、メールのパーマリンクをクリップボードにコピーします。
 * @include https://mail.google.com/
 * @license CC0
 * @javascript_url
 */

// HTML構造変わるの早い……

(async () =&amp;gt; {
    const targetDataAttributeName = &amp;quot;data-message-id&amp;quot;
    const waitForEvent = (eventTarget, eventType) =&amp;gt; new Promise((resolve, reject) =&amp;gt;
        eventTarget.addEventListener(eventType, resolve, { once: true, signal: AbortSignal.timeout(10000) })
    )

    let targetElement = document.querySelector(`[${targetDataAttributeName}]`);
    if (!targetElement) {
        alert(&amp;quot;メールを開いてからブックマークレットを使ってください&amp;quot;)
        return
    }

    const e = await waitForEvent(document, 'mousedown')
    targetElement = e.target.closest(`[${targetDataAttributeName}]`) ?? targetElement;
    const threadId = BigInt(targetElement?.getAttribute(targetDataAttributeName).split(':')[1]).toString(16)
    navigator.clipboard.writeText(`https://mail.google.com/mail/u/0/#all/${encodeURIComponent(threadId)}`)
        .then(() =&amp;gt; alert(&amp;quot;メールのパーマリンクをクリップボードにコピーしました&amp;quot;))
        .catch(err =&amp;gt; {
            console.error(&amp;quot;クリップボードへのコピーに失敗しました&amp;quot;, err)
            alert(&amp;quot;クリップボードへのコピーに失敗しました&amp;quot;)
        });

})()

&lt;/pre&gt;</content:encoded>
  </item>
  <item rdf:about="https://let.hatelabo.jp/Lhankor_Mhy/let/jrLIsPyegeAA">
    <link>https://let.hatelabo.jp/Lhankor_Mhy/let/jrLIsPyegeAA</link>
    <dc:date>2025-11-28T09:31:53Z</dc:date>
    <description>はてなブックマークにログインしていれば、n年前のブクマページに移動します。IEでは動作せず。</description>
    <dc:creator>Lhankor_Mhy</dc:creator>
    <title>[Let] n年前のブクマを見る</title>
    <content:encoded>&lt;a href="javascript:const%20n%3D1%3Bconst%20nYearBefore%3Dnew%20Date%3BnYearBefore.setFullYear%28%28new%20Date%29.getFullYear%28%29-n%29%3Blocation.href%3D%60https%3A%2F%2Fb.hatena.ne.jp%2Fmy%2F%24%7BnYearBefore.toLocaleDateString%28%27ja-JP%27%2C%7Byear%3A%27numeric%27%2Cmonth%3A%272-digit%27%2Cday%3A%272-digit%27%7D%29.split%28%27%2F%27%29.join%28%27%27%29%7D%60%3B"&gt;n年前のブクマを見る&lt;/a&gt;&lt;pre&gt;/*
 * @title n年前のブクマを見る
 * @description はてなブックマークにログインしていれば、n年前のブクマページに移動します。IEでは動作せず。
 * @include http://*
 * @license CC0
 * @javascript_url
 */

const n=1 // n=1は1年前

const nYearBefore = new Date()
nYearBefore.setFullYear(new Date().getFullYear()-n)

location.href = 
    `https://b.hatena.ne.jp/my/${nYearBefore.toLocaleDateString('ja-JP', {
        year: 'numeric',
        month: '2-digit',
        day: '2-digit',
    }).split('/').join('')}`
&lt;/pre&gt;</content:encoded>
  </item>
  <item rdf:about="https://let.hatelabo.jp/Lhankor_Mhy/let/hLHX8qPqyax_">
    <link>https://let.hatelabo.jp/Lhankor_Mhy/let/hLHX8qPqyax_</link>
    <dc:date>2025-01-30T03:15:30Z</dc:date>
    <description>ページ内にある～.PDFというリンクすべてからPDFファイルを取得して、zipして一括ダウンロードします（ドメインの壁は越えられません）。保存名はファイル名またはリンクテキスト.pdfの選択です。</description>
    <dc:creator>Lhankor_Mhy</dc:creator>
    <title>[Let] リンクのPDFファイルをzipしてダウンロード</title>
    <content:encoded>&lt;a href="javascript:%28async%28%29%3D%3E%7Bconst%20sleep%3Dtime%3D%3Enew%20Promise%28%28resolve%3D%3EsetTimeout%28resolve%2Ctime%29%29%29%3Bawait%20import%28%27https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fjszip%2F3.2.0%2Fjszip.min.js%27%29%3Bconst%7Bdefault%3A%7BsaveAs%3AsaveAs%7D%7D%3Dawait%20import%28%27https%3A%2F%2Fcdn.jsdelivr.net%2Fnpm%2Ffile-saver%402.0.5%2F%2Besm%27%29%3Bconst%20zip%3Dnew%20JSZip%3Bconst%20path%3D%27files%27%2BNumber%28new%20Date%29%2B%27%2F%27%3Basync%20function%20downloader%28element%29%7Bconst%20response%3Dawait%20fetch%28element.href%29%3Belement.style.backgroundColor%3D%27gray%27%3Bconst%20fileName%3DdecodeURIComponent%28%28isUseFileName%3Felement.href.match%28%2F%28%3F%3D%5B%5E%5C%2F%5D%2B%5C.pdf%29%5B%5E%5C%2F%5D%2B%5C.pdf%2F%29%3Aelement.textContent.match%28%2F%28%3F%3D%5B%5E%5C%2F%5D%2B%5C.pdf%29%5B%5E%5C%2F%5D%2B%5C.pdf%2F%29%29%3F%3Felement.textContent.trim%28%29%2B%22.pdf%22%29%3Bawait%20sleep%282e3%29%3Bif%28zip.file%28path%2BfileName%29%29%7BfileName%3DNumber%28new%20Date%29%2B%27_%27%2BfileName%7Dzip.file%28path%2BfileName%2Cawait%20response.blob%28%29%29%7Dconst%20isUseFileName%3Dconfirm%28%27URL%E3%81%AE%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%90%8D%E3%81%A7%E4%BF%9D%E5%AD%98%E3%81%97%E3%81%BE%E3%81%99%27%29%3Bfor%28let%20target%20of%20document.querySelectorAll%28%27a%5Bhref%2A%3D%22.pdf%22%5D%20%27%29%29%7Bawait%20downloader%28target%29.catch%28%28%28%29%3D%3E%7B%7D%29%29%7Dfor%28let%20target%20of%5B...document.querySelectorAll%28%27a%3Anot%28%5Bhref%2A%3D%22.pdf%22%5D%29%27%29%5D.filter%28%28e%3D%3Ee.textContent.includes%28%27pdf%27%29%7C%7Ce.textContent.includes%28%27PDF%27%29%29%29%29%7Bawait%20downloader%28target%29.catch%28%28e%3D%3E%7Bthrow%20e%7D%29%29%7Dconst%20content%3Dawait%20zip.generateAsync%28%7Btype%3A%22blob%22%7D%29%3BsaveAs%28content%2C%27files.zip%27%29%7D%29%28%29%3B"&gt;リンクのPDFファイルをzipしてダウンロード&lt;/a&gt;&lt;pre&gt;/*
 * @title リンクのPDFファイルをzipしてダウンロード
 * @description ページ内にある～.PDFというリンクすべてからPDFファイルを取得して、zipして一括ダウンロードします（ドメインの壁は越えられません）。保存名はファイル名またはリンクテキスト.pdfの選択です。
 * @include http://*
 * @license MIT License
 * @javascript_url
 */


(async () =&amp;gt; {
    const sleep = time =&amp;gt; new Promise(resolve =&amp;gt; setTimeout(resolve, time));
    await import('https://cdnjs.cloudflare.com/ajax/libs/jszip/3.2.0/jszip.min.js');
    const { default: { saveAs } } = await import('https://cdn.jsdelivr.net/npm/file-saver@2.0.5/+esm');

    const zip = new JSZip();

    const path = 'files' + Number(new Date()) + '/';

    async function downloader(element) {
        const response = await fetch(
            element.href,
        );
        element.style.backgroundColor = 'gray';
        const fileName = decodeURIComponent(
            (isUseFileName ?
                element.href.match(/(?=[^\/]+\.pdf)[^\/]+\.pdf/) :
                element.textContent.match(/(?=[^\/]+\.pdf)[^\/]+\.pdf/))
            ?? element.textContent.trim() + &amp;quot;.pdf&amp;quot;
        );
        await sleep(2000);

        if (zip.file(path + fileName)) { fileName = Number(new Date()) + '_' + fileName };
        zip.file(path + fileName, await response.blob());

    };

    const isUseFileName = confirm('URLのファイル名で保存します')

    for (let target of document.querySelectorAll('a[href*=&amp;quot;.pdf&amp;quot;] ')) { await downloader(target).catch(() =&amp;gt; { }) };
    for (let target of [...document.querySelectorAll('a:not([href*=&amp;quot;.pdf&amp;quot;])')].filter(e =&amp;gt; e.textContent.includes('pdf') || e.textContent.includes('PDF'))) { await downloader(target).catch(e =&amp;gt; { throw e }) };
    const content = await zip.generateAsync({ type: &amp;quot;blob&amp;quot; });
    saveAs(content, 'files.zip');

})()&lt;/pre&gt;</content:encoded>
  </item>
  <item rdf:about="https://let.hatelabo.jp/Lhankor_Mhy/let/kpTi_IGaguAA">
    <link>https://let.hatelabo.jp/Lhankor_Mhy/let/kpTi_IGaguAA</link>
    <dc:date>2024-11-20T09:52:13Z</dc:date>
    <description>b.hatena.ne.jp ドメイン上で使用してください</description>
    <dc:creator>Lhankor_Mhy</dc:creator>
    <title>[Let] あなたのファーストブクマはこれ</title>
    <content:encoded>&lt;a href="javascript:void%28async%28%29%3D%3E%7Bconst%20pageCount%3DMath.ceil%28Number%28%28new%20DOMParser%29.parseFromString%28await%28await%20fetch%28%60https%3A%2F%2Fb.hatena.ne.jp%2Fmy%2Fbookmark%60%29%29.text%28%29%2C%27text%2Fhtml%27%29.getElementsByClassName%28%27userprofile-status-count%27%29%5B0%5D.textContent.replace%28%2F%2C%2Fg%2C%27%27%29%29%2F20%29%3Blocation.href%3D%5B...%28new%20DOMParser%29.parseFromString%28await%28await%20fetch%28%60https%3A%2F%2Fb.hatena.ne.jp%2Fmy%2Fbookmark%3Fpage%3D%24%7BpageCount%7D%60%29%29.text%28%29%2C%27text%2Fhtml%27%29.querySelectorAll%28%27%5Bdata-gtm-click-label%3D%22user-my-reaction-permalink%22%5D%27%29%5D.at%28-1%29.href%7D%29%28%29%3B"&gt;あなたのファーストブクマはこれ&lt;/a&gt;&lt;pre&gt;/*
 * @title あなたのファーストブクマはこれ
 * @description b.hatena.ne.jp ドメイン上で使用してください
 * @include https://b.hatena.ne.jp/
 * @license CC0
 * @javascript_url
 */

void (async () =&amp;gt; {
    const pageCount = Math.ceil(Number(
        new DOMParser().parseFromString(
            await (await fetch(`https://b.hatena.ne.jp/my/bookmark`)).text(),
            'text/html'
        ).getElementsByClassName('userprofile-status-count')[0].textContent.replace(/,/g, '')
    ) / 20)
    location.href = [...new DOMParser().parseFromString(
        await (await fetch(`https://b.hatena.ne.jp/my/bookmark?page=${pageCount}`)).text(),
        'text/html'
    ).querySelectorAll('[data-gtm-click-label=&amp;quot;user-my-reaction-permalink&amp;quot;]')].at(-1).href
})()
&lt;/pre&gt;</content:encoded>
  </item>
  <item rdf:about="https://let.hatelabo.jp/Lhankor_Mhy/let/kc329cjkgqAA">
    <link>https://let.hatelabo.jp/Lhankor_Mhy/let/kc329cjkgqAA</link>
    <dc:date>2024-10-16T07:49:53Z</dc:date>
    <description>ページ内カタカナをア段に変換します。元ネタ→https://anond.hatelabo.jp/20240801082705</description>
    <dc:creator>Lhankor_Mhy</dc:creator>
    <title>[Let] *印度化計画</title>
    <content:encoded>&lt;a href="javascript:%22https%3A%2F%2Flet.st-hatelabo.com%2FLhankor_Mhy%2Flet%2Fkc329cjkgqAA.bookmarklet.js%20%28arg%29%22.replace%28%2F%28%5CS%2B%29%5Cs%2B%28%5CS%2A%29%2F%2Cfunction%28s%2Curl%2Carg%29%7Bs%3Ddocument.createElement%28%22script%22%29%3Bs.charset%3D%22utf-8%22%3Bs.src%3Durl%2B%22%3Fs%3D%22%2BencodeURIComponent%28arg%29%3Bdocument.body.appendChild%28s%29%7D%29%3Bvoid%280%29%3B"&gt;*印度化計画&lt;/a&gt;&lt;pre&gt;/*
 * @title *印度化計画
 * @description ページ内カタカナをア段に変換します。元ネタ→https://anond.hatelabo.jp/20240801082705
 * @include http://*
 * @license CC0
 * @require 
 */

(async () =&amp;gt; {
    await import('https://unpkg.com/wanakana')
    const indianize = str =&amp;gt;
        wanakana.toKana(
            wanakana.toRomaji(str, {
                convertLongVowelMark: false,
                upcaseKatakana: true
            }).replace(/[IUEO]/g, 'A')
        )

    const treeWalker = document.createTreeWalker(
        document.body,
        NodeFilter.SHOW_TEXT,
    );
    while (treeWalker.nextNode()) {
        const node = treeWalker.currentNode;
        node.data = node.data.replace(/\p{scx=Katakana}+/ug, indianize)
    }
})()&lt;/pre&gt;</content:encoded>
  </item>
  <item rdf:about="https://let.hatelabo.jp/Lhankor_Mhy/let/jtaB0fa4gYAA">
    <link>https://let.hatelabo.jp/Lhankor_Mhy/let/jtaB0fa4gYAA</link>
    <dc:date>2024-03-28T03:21:28Z</dc:date>
    <description>コメントメタブと2階ブクマを展開します。説明→https://realtor-readyabooks.hatenablog.com/entry/2022/12/28/153626</description>
    <dc:creator>Lhankor_Mhy</dc:creator>
    <title>[Let] はてなブックマークメタブ展開</title>
    <content:encoded>&lt;a href="javascript:%28async%28%29%3D%3E%7Bconst%20APIURL%3D%27https%3A%2F%2Fb.hatena.ne.jp%2Fentry%2Fjsonlite%2F%3Furl%3D%27%3Bdocument.body.insertAdjacentHTML%28%27beforeend%27%2C%60%5Cn%3Cstyle%3E%5Cn%5Bdata-metabu%5D%20%7B%5Cn%5Ctbackground-color%3A%20rgba%280%2C0%2C0%2C0.05%29%3B%5Cn%7D%5Cn%5Bdata-metabu%5D.focus%20%7B%5Cn%5Ctoutline%3Adotted%201px%3B%5Cn%7D%5Cn%23metahatebu-popover%7B%5Cn%20%20%20%20inset%3A%20auto%200%200%20auto%3B%5Cn%20%20%20%20opacity%3A%200.5%3B%5Cn%20%20%20%20border%3A%20none%3B%5Cn%20%20%20%20background-color%3A%20%23000%3B%5Cn%20%20%20%20color%3A%20%23fff%3B%5Cn%20%20%20%20position%3A%20fixed%3B%5Cn%7D%5Cn%3C%2Fstyle%3E%5Cn%3Cdialog%20popover%20id%3D%22metahatebu-popover%22%3E%E3%83%A1%E3%82%BF%E3%83%96%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%3Cbutton%20data-metabuprev%3E%E5%89%8D%3C%2Fbutton%3E%3Cbutton%20data-metabunext%3E%E6%AC%A1%3C%2Fbutton%3E%3C%2Fdialog%3E%5Cn%20%20%20%20%60%29%3Bdocument.querySelector%28%27.entry-comments%27%29.insertAdjacentHTML%28%27beforeend%27%2C%60%5Cn%3Cdiv%20class%3D%22entry-comment-contents%22%20id%3D%22upStairsSeat%22%3E%3C%2Fdiv%3E%5Cn%20%20%20%20%60%29%3Bconst%20metahatebuPopover%3Ddocument.getElementById%28%27metahatebu-popover%27%29%3BmetahatebuPopover.addEventListener%28%27click%27%2C%28%28i%3D-1%29%3D%3Eevent%3D%3E%7Bconst%20metabues%3Ddocument.querySelectorAll%28%27%5Bdata-metabu%5D%27%29%3Bif%28event.target.matches%28%27%5Bdata-metabuprev%5D%27%29%29i--%3Bif%28event.target.matches%28%27%5Bdata-metabunext%5D%27%29%29i%2B%2B%3Bi%3Dmetabues.length%3F%28i%2Bmetabues.length%29%25metabues.length%3A0%3Bmetabues%5Bi%5D.scrollIntoView%28%7Bbehavior%3A%22smooth%22%2Cblock%3A%22end%22%2Cinline%3A%22nearest%22%7D%29%3Bmetabues.forEach%28%28%28metabu%2Cj%29%3D%3Emetabu.classList.toggle%28%27focus%27%2Ci%3D%3Dj%29%29%29%7D%29%28%29%29%3Bconst%20metahatebuPopoverOpen%3D%28%29%3D%3E%7Bif%28HTMLElement.showPopover%29%7BmetahatebuPopover.showPopover%28%29%7Delse%7BmetahatebuPopover.show%28%29%7D%7D%3Bconst%20addBookmark%3Dfunction%28targetElement%2Cbookmark%2Ceid%29%7Bdocument.querySelector%28%60%5Bhref%3D%22%2Fentry%2F%24%7Beid%7D%2Fcomment%2F%24%7Bbookmark.user%7D%22%5D%60%29%3F.closest%28%27.entry-comment-contents%20%3E%20.entry-comment-contents%27%29.remove%28%29%3BtargetElement.insertAdjacentHTML%28%27beforeend%27%2Cdocument.getElementById%28%27autoloader-bookmark-item%27%29.textContent.replaceAll%28%27%3Cdiv%20class%3D%22entry-comment-contents%20%27%2C%27%3Cdiv%20data-metabu%3D%22metabu%22%20class%3D%22entry-comment-contents%20%27%29.replaceAll%28%27%7B%7Buser_name%7D%7D%27%2Cbookmark.user%29.replaceAll%28%27%7B%7Bbookmarked_url%7D%7D%27%2Cbookmark.url%29.replaceAll%28%27%7B%7Buser_page_path%7D%7D%27%2C%60%2F%24%7Bbookmark.user%7D%2F%60%29.replaceAll%28%27%7B%7B%20sort%20%7D%7D%27%2C%60recent%60%29.replaceAll%28%27%7B%7Bprofile_image_url%7D%7D%27%2C%60https%3A%2F%2Fcdn.profile-image.st-hatena.com%2Fusers%2F%24%7Bbookmark.user%7D%2Fprofile.png%60%29.replaceAll%28%27%7B%7B%20%23is_public%20%7D%7Dis-hidden%7B%7B%20%2Fis_public%20%7D%7D%27%2C%60is-hidden%60%29.replaceAll%28%27%7B%7B%7Bcomment_expanded%7D%7D%7D%27%2Cbookmark.comment%29.replaceAll%28%27%7B%7B%7Btags%7D%7D%7D%27%2C%60%3Cli%3E%24%7Bbookmark.tags.join%28%27%3Cli%3E%27%29%7D%60%29.replaceAll%28%27%7B%7Bcreated%7D%7D%27%2Cbookmark.timestamp%29.replaceAll%28%27%7B%7Bcomment_page_path%7D%7D%27%2C%60%2Fentry%2F%24%7Beid%7D%2Fcomment%2F%24%7Bbookmark.user%7D%60%29.replaceAll%28%27%7B%7B%23should_nofollow%7D%7Dnofollow%7B%7B%2Fshould_nofollow%7D%7D%27%2C%27nofollow%27%29.replaceAll%28%27%7B%7B%23enable_button%7D%7D%20is-enabled%7B%7B%2Fenable_button%7D%7D%27%2C%27is-enabled%27%29%29%3BmetahatebuPopoverOpen%28%29%7D%3Bconst%20targetURLs%3D%5Blocation.href%5D%2CupstairsBookmarksList%3D%5B%5D%3Bfor%28const%20targetURL%20of%20targetURLs%29%7Bconst%7Bbookmarks%3Abookmarks%2Centry_url%3Aentry_url%2Ceid%3Aeid%7D%3Dawait%28await%20fetch%28%60%24%7BAPIURL%7D%24%7BencodeURIComponent%28targetURL%29%7D%60%29%29.json%28%29%3F%3F%7Bentry_url%3Anull%7D%3Bif%28%21entry_url%29continue%3BtargetURLs.push%28entry_url%29%3BupstairsBookmarksList.push%28%5Bbookmarks%2Ceid%5D%29%7Dfunction%20addUpstairsBookmark%28targetElements%29%7Bif%28upstairsBookmarksList.length%29metahatebuPopoverOpen%28%29%3BupstairsBookmarksList.forEach%28%28upstairsBookmarks%3D%3E%7Bconst%5Bbookmarks%2Ceid%5D%3DupstairsBookmarks%3BupstairsBookmarks%5B0%5D%3Dbookmarks.filter%28%28bookmark%3D%3E%7Bconst%20targetUserBookmark%3DtargetElements.find%28%28element%3D%3Eelement.dataset%3F.userName%3D%3D%3Dbookmark.user%29%29%3Bif%28%21targetUserBookmark%29%7Bconst%20targetElement%3Ddocument.getElementById%28%27upStairsSeat%27%29%3BaddBookmark%28targetElement%2Cbookmark%2Ceid%29%3Breturn%20true%7Dconst%20targetElement%3D%5BtargetUserBookmark%2C...targetUserBookmark.querySelectorAll%28%60.entry-comment-contents%5Bdata-user-name%3D%22%24%7Bbookmark.user%7D%22%5D%60%29%5D.pop%28%29%3BaddBookmark%28targetElement%2Cbookmark%2Ceid%29%3Breturn%20false%7D%29%29%7D%29%29%7Dfunction%20addMetaBookmark%28targetElements%29%7BtargetElements.forEach%28%28async%20element%3D%3E%7Bconst%20targetURL%3Delement.querySelector%28%27%5Bdata-gtm-label%3D%22entry-recent-permalink%22%5D%27%29%3F.href%3Bif%28%21targetURL%29return%20undefined%3Bconst%7Bbookmarks%3Abookmarks%2Centry_url%3Aentry_url%2Ceid%3Aeid%7D%3Dawait%28await%20fetch%28%60%24%7BAPIURL%7D%24%7BencodeURIComponent%28targetURL%29%7D%60%29%29.json%28%29%3F%3F%7Bentry_url%3Anull%7D%3Bif%28%21entry_url%29return%20undefined%3Bbookmarks.forEach%28%28bookmark%3D%3E%7BaddBookmark%28element%2Cbookmark%2Ceid%29%7D%29%29%7D%29%29%7DaddUpstairsBookmark%28Array.from%28document.querySelectorAll%28%60.js-bookmarks-recent%20%5Bdata-user-name%5D%60%29%29%29%3BaddMetaBookmark%28Array.from%28document.querySelectorAll%28%60.js-bookmarks-recent%20%5Bdata-user-name%5D%60%29%29%29%3Bconst%20targetNode%3Ddocument.querySelector%28%27.js-bookmarks-recent%27%29%3Bconst%20upstairsBookmarkMutationConfig%3D%7BchildList%3Atrue%7D%3Bconst%20upstairsBookmarkMutationCallback%3Dfunction%28mutationsList%2Cobserver%29%7Bfor%28const%20mutation%20of%20mutationsList%29%7Bif%28mutation.type%3D%3D%3D%27childList%27%29%7BaddUpstairsBookmark%28Array.from%28mutation.addedNodes%29.filter%28%28node%3D%3Enode.dataset%3F.userName%29%29%29%7D%7D%7D%3Bconst%20upstairsBookmarkMutationObserver%3Dnew%20MutationObserver%28upstairsBookmarkMutationCallback%29%3BupstairsBookmarkMutationObserver.observe%28targetNode%2CupstairsBookmarkMutationConfig%29%3Bconst%20metaBookmarkMutationConfig%3D%7BchildList%3Atrue%2Csubtree%3Atrue%7D%3Bconst%20metaBookmarkMutationCallback%3Dfunction%28mutationsList%2Cobserver%29%7Bfor%28const%20mutation%20of%20mutationsList%29%7Bif%28mutation.type%3D%3D%3D%27childList%27%29%7BaddMetaBookmark%28Array.from%28mutation.addedNodes%29.filter%28%28node%3D%3Enode.dataset%3F.userName%29%29%29%7D%7D%7D%3Bconst%20metaBookmarkMutationObserver%3Dnew%20MutationObserver%28metaBookmarkMutationCallback%29%3BmetaBookmarkMutationObserver.observe%28targetNode%2CmetaBookmarkMutationConfig%29%7D%29%28%29%3B"&gt;はてなブックマークメタブ展開&lt;/a&gt;&lt;pre&gt;// ==UserScript==
// @name         はてなブックマークメタブ展開
// @title        はてなブックマークメタブ展開
// @namespace    https://let.hatelabo.jp/Lhankor_Mhy/let/jtaB0fa4gYAA
// @version      0.13.2
// @description  コメントメタブと2階ブクマを展開します。説明→https://realtor-readyabooks.hatenablog.com/entry/2022/12/28/153626
// @author       Lhankor_Mhy
// @match        https://b.hatena.ne.jp/entry/*
// @icon         https://b.hatena.ne.jp/favicon.ico
// @license      CC0
// @noframes
// @grant        none
// @javascript_url
// ==/UserScript==


(async () =&amp;gt; {
    const APIURL = 'https://b.hatena.ne.jp/entry/jsonlite/?url='

    document.body.insertAdjacentHTML('beforeend', `
&amp;lt;style&amp;gt;
[data-metabu] {
	background-color: rgba(0,0,0,0.05);
}
[data-metabu].focus {
	outline:dotted 1px;
}
#metahatebu-popover{
    inset: auto 0 0 auto;
    opacity: 0.5;
    border: none;
    background-color: #000;
    color: #fff;
    position: fixed;
}
&amp;lt;/style&amp;gt;
&amp;lt;dialog popover id=&amp;quot;metahatebu-popover&amp;quot;&amp;gt;メタブあります&amp;lt;button data-metabuprev&amp;gt;前&amp;lt;/button&amp;gt;&amp;lt;button data-metabunext&amp;gt;次&amp;lt;/button&amp;gt;&amp;lt;/dialog&amp;gt;
    `)
    document.querySelector('.entry-comments').insertAdjacentHTML('beforeend', `
&amp;lt;div class=&amp;quot;entry-comment-contents&amp;quot; id=&amp;quot;upStairsSeat&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
    `)

    // メタブありますポップオーバーのイベント設定
    const metahatebuPopover = document.getElementById('metahatebu-popover');
    metahatebuPopover.addEventListener('click', ((i = -1) =&amp;gt; event =&amp;gt; {
        const metabues = document.querySelectorAll('[data-metabu]');
        if (event.target.matches('[data-metabuprev]')) i--;
        if (event.target.matches('[data-metabunext]')) i++;
        i = metabues.length ? (i + metabues.length) % metabues.length : 0;
        metabues[i].scrollIntoView({ behavior: &amp;quot;smooth&amp;quot;, block: &amp;quot;end&amp;quot;, inline: &amp;quot;nearest&amp;quot; });
        metabues.forEach((metabu, j) =&amp;gt; metabu.classList.toggle('focus', i == j));
    })())

    // ポップオーバーフォールバック
    const metahatebuPopoverOpen = () =&amp;gt; {
        if (HTMLElement.showPopover) {
            metahatebuPopover.showPopover()
        } else {
            metahatebuPopover.show()
        }
    }

    // ブクマ展開（x-template再利用）
    const addBookmark = function (targetElement, bookmark, eid) {
        document.querySelector(`[href=&amp;quot;/entry/${eid}/comment/${bookmark.user}&amp;quot;]`)?.closest('.entry-comment-contents &amp;gt; .entry-comment-contents').remove();
        targetElement.insertAdjacentHTML(
            'beforeend',
            document.getElementById('autoloader-bookmark-item').textContent
                .replaceAll('&amp;lt;div class=&amp;quot;entry-comment-contents ', '&amp;lt;div data-metabu=&amp;quot;metabu&amp;quot; class=&amp;quot;entry-comment-contents ')
                .replaceAll('{{user_name}}', bookmark.user)
                .replaceAll('{{bookmarked_url}}', bookmark.url)
                .replaceAll('{{user_page_path}}', `/${bookmark.user}/`)
                .replaceAll('{{ sort }}', `recent`)
                .replaceAll('{{profile_image_url}}', `https://cdn.profile-image.st-hatena.com/users/${bookmark.user}/profile.png`)
                .replaceAll('{{ #is_public }}is-hidden{{ /is_public }}', `is-hidden`)
                .replaceAll('{{{comment_expanded}}}', bookmark.comment)
                .replaceAll('{{{tags}}}', `&amp;lt;li&amp;gt;${bookmark.tags.join('&amp;lt;li&amp;gt;')}`)
                .replaceAll('{{created}}', bookmark.timestamp)
                .replaceAll('{{comment_page_path}}', `/entry/${eid}/comment/${bookmark.user}`)
                .replaceAll('{{#should_nofollow}}nofollow{{/should_nofollow}}', 'nofollow')
                .replaceAll('{{#enable_button}} is-enabled{{/enable_button}}', 'is-enabled')

        )
        metahatebuPopoverOpen()
    }

    // 2階ブクマAPIコール
    const targetURLs = [location.href], upstairsBookmarksList = []
    for (const targetURL of targetURLs) {
        const { bookmarks, entry_url, eid } = (await (await fetch(`${APIURL}${encodeURIComponent(targetURL)}`)).json()) ?? { entry_url: null }
        if (!entry_url) continue
        targetURLs.push(entry_url)
        upstairsBookmarksList.push([bookmarks, eid])
    }

    // 2階ブクマをHTMLに展開
    function addUpstairsBookmark(targetElements) {
        if (upstairsBookmarksList.length) metahatebuPopoverOpen()
        upstairsBookmarksList.forEach(upstairsBookmarks =&amp;gt; {
            const [bookmarks, eid] = upstairsBookmarks;
            upstairsBookmarks[0] = bookmarks.filter(bookmark =&amp;gt; {
                const targetUserBookmark = targetElements.find(element =&amp;gt; element.dataset?.userName === bookmark.user)
                if (!targetUserBookmark) {
                    const targetElement = document.getElementById('upStairsSeat');
                    addBookmark(targetElement, bookmark, eid);
                    return true // 遅延読み込み後に再処理するかもしれないのでリストに残す
                }
                const targetElement = [targetUserBookmark, ...targetUserBookmark.querySelectorAll(`.entry-comment-contents[data-user-name=&amp;quot;${bookmark.user}&amp;quot;]`)].pop()
                addBookmark(targetElement, bookmark, eid)
                return false // 遅延読み込み後に再処理しないのでリストから削除する
            })
        })
    }

    // メタブをHTMLに展開
    function addMetaBookmark(targetElements) {
        targetElements.forEach(async element =&amp;gt; {
            const targetURL = element.querySelector('[data-gtm-label=&amp;quot;entry-recent-permalink&amp;quot;]')?.href
            if (!targetURL) return undefined
            const { bookmarks, entry_url, eid } = (await (await fetch(`${APIURL}${encodeURIComponent(targetURL)}`)).json()) ?? { entry_url: null }
            if (!entry_url) return undefined
            bookmarks.forEach(
                bookmark =&amp;gt; {
                    addBookmark(element, bookmark, eid)
                }
            )
        })
    }

    // 初回呼び出し
    addUpstairsBookmark(Array.from(document.querySelectorAll(`.js-bookmarks-recent [data-user-name]`)))
    addMetaBookmark(Array.from(document.querySelectorAll(`.js-bookmarks-recent [data-user-name]`)))

    // ブクマ遅延読み込み監視
    const targetNode = document.querySelector('.js-bookmarks-recent');

    const upstairsBookmarkMutationConfig = { childList: true };
    const upstairsBookmarkMutationCallback = function (mutationsList, observer) {
        for (const mutation of mutationsList) {
            if (mutation.type === 'childList') {
                addUpstairsBookmark(Array.from(mutation.addedNodes).filter(node =&amp;gt; node.dataset?.userName))
            }
        }
    };
    const upstairsBookmarkMutationObserver = new MutationObserver(upstairsBookmarkMutationCallback);
    upstairsBookmarkMutationObserver.observe(targetNode, upstairsBookmarkMutationConfig);

    const metaBookmarkMutationConfig = { childList: true, subtree: true };
    const metaBookmarkMutationCallback = function (mutationsList, observer) {
        for (const mutation of mutationsList) {
            if (mutation.type === 'childList') {
                addMetaBookmark(Array.from(mutation.addedNodes).filter(node =&amp;gt; node.dataset?.userName))
            }
        }
    };
    const metaBookmarkMutationObserver = new MutationObserver(metaBookmarkMutationCallback);
    metaBookmarkMutationObserver.observe(targetNode, metaBookmarkMutationConfig);

})()

&lt;/pre&gt;</content:encoded>
  </item>
  <item rdf:about="https://let.hatelabo.jp/Lhankor_Mhy/let/kLOm3rHEgeAA">
    <link>https://let.hatelabo.jp/Lhankor_Mhy/let/kLOm3rHEgeAA</link>
    <dc:date>2024-03-12T03:15:07Z</dc:date>
    <description>Pocket のリンクから ?utm_source=pocket_saves などを外します。</description>
    <dc:creator>Lhankor_Mhy</dc:creator>
    <title>[Let] Pocket のトラッキングURLパラメータを外す</title>
    <content:encoded>&lt;a href="javascript:%22https%3A%2F%2Flet.st-hatelabo.com%2FLhankor_Mhy%2Flet%2FkLOm3rHEgeAA.bookmarklet.js%20%28arg%29%22.replace%28%2F%28%5CS%2B%29%5Cs%2B%28%5CS%2A%29%2F%2Cfunction%28s%2Curl%2Carg%29%7Bs%3Ddocument.createElement%28%22script%22%29%3Bs.charset%3D%22utf-8%22%3Bs.src%3Durl%2B%22%3Fs%3D%22%2BencodeURIComponent%28arg%29%3Bdocument.body.appendChild%28s%29%7D%29%3Bvoid%280%29%3B"&gt;Pocket のトラッキングURLパラメータを外す&lt;/a&gt;&lt;pre&gt;// ==UserScript==
// @name         Pocket のトラッキングURLパラメータを外す
// @title        Pocket のトラッキングURLパラメータを外す
// @namespace    https://let.hatelabo.jp/Lhankor_Mhy/let/kLOm3rHEgeAA
// @version      0.1.2
// @description  Pocket のリンクから ?utm_source=pocket_saves などを外します。
// @author       Lhankor_Mhy
// @license      CC0
// @match        https://getpocket.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&amp;amp;domain=getpocket.com
// @run-at       document-idle
// @grant        none
// ==/UserScript==

{
    let timerId;
    new MutationObserver((mutationList, observer) =&amp;gt; {
        mutationList.forEach((mutation) =&amp;gt; {
            switch (mutation.type) {
                case &amp;quot;childList&amp;quot;:
                    clearTimeout(timerId);
                    timerId = setTimeout(omitTrackingParameter, 500)
                    break;
            }
        });
    }).observe(document.body, {
        childList: true,
        subtree: true,
    });
    const omitTrackingParameter = () =&amp;gt;
        document.querySelectorAll('a:where([data-testid=&amp;quot;image-link&amp;quot;],[data-testid=&amp;quot;content-block&amp;quot;],[data-testid=&amp;quot;view-original&amp;quot;],[data-testid=&amp;quot;publisher-link&amp;quot;])').forEach(el =&amp;gt; {
            const url = new URL(el.href);
            const searchPrams = url.searchParams;
            searchPrams.delete('utm_source');
            url.search = searchPrams.toString();
            el.href = url.href;
        })
}&lt;/pre&gt;</content:encoded>
  </item>
  <item rdf:about="https://let.hatelabo.jp/Lhankor_Mhy/let/kOGSsI-SgsAA">
    <link>https://let.hatelabo.jp/Lhankor_Mhy/let/kOGSsI-SgsAA</link>
    <dc:date>2024-02-15T08:44:55Z</dc:date>
    <description>canonical URLではない場合にページ移動します。</description>
    <dc:creator>Lhankor_Mhy</dc:creator>
    <title>[Let] canonical URL に移動</title>
    <content:encoded>&lt;a href="javascript:%7Bconst%20canonical%3Ddocument.querySelector%28%27%5Brel%3Dcanonical%5D%27%29.href%3Bif%28location.href%21%3D%3Dcanonical%29location.href%3Dcanonical%3Bvoid%200%7D"&gt;canonical URL に移動&lt;/a&gt;&lt;pre&gt;/*
 * @title canonical URL に移動
 * @description canonical URLではない場合にページ移動します。
 * @include http://*
 * @license CC0
 * @javascript_url 
 */

{
    const canonical = document.querySelector('[rel=canonical]').href;
    if (location.href !== canonical) location.href = canonical;
    void 0;
}
&lt;/pre&gt;</content:encoded>
  </item>
  <item rdf:about="https://let.hatelabo.jp/Lhankor_Mhy/let/kNe6m5vsgKAA">
    <link>https://let.hatelabo.jp/Lhankor_Mhy/let/kNe6m5vsgKAA</link>
    <dc:date>2024-01-31T08:34:19Z</dc:date>
    <description>はてなグリーンスターに縁をつけます。via: https://b.hatena.ne.jp/entry/4748592896526814671/comment/murlock</description>
    <dc:creator>Lhankor_Mhy</dc:creator>
    <title>[Let] はてなグリーンスターに縁をつける</title>
    <content:encoded>&lt;a href="javascript:%7Blet%20timerId%3Bnew%20MutationObserver%28%28%28mutationList%2Cobserver%29%3D%3E%7BmutationList.forEach%28%28mutation%3D%3E%7Bswitch%28mutation.type%29%7Bcase%22childList%22%3AclearTimeout%28timerId%29%3BtimerId%3DsetTimeout%28replaceGreenStar%2C500%29%3Bbreak%7D%7D%29%29%7D%29%29.observe%28document.body%2C%7BchildList%3Atrue%2Csubtree%3Atrue%7D%29%3Bconst%20replaceGreenStar%3D%28%29%3D%3E%7Bdocument.querySelectorAll%28%27.hatena-star-star.green%20span%27%29%3F.forEach%28%28e%3D%3Ee.style.backgroundImage%3D%60url%28%22data%3Aimage%2Fsvg%2Bxml%2C%253Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%2711%27%20height%3D%2710.299%27%20viewBox%3D%270%200%2011%2010.299%27%253E%253Cpath%20d%3D%27M-4785.954%2C1552.838l2.935%2C2.125-1.127%2C3.381a.352.352%2C0%2C0%2C0%2C.538.393l2.815-1.961h0l.2-.14%2C3.009%2C2.1a.353.353%2C0%2C0%2C0%2C.533-.4l-1.036-3.128v0l-.079-.24.2-.15%2C0%2C0%2C2.712-1.971a.352.352%2C0%2C0%2C0-.207-.638h-3.651l-.079-.238%2C0%2C0-1.075-3.218a.352.352%2C0%2C0%2C0-.667-.005l-1.167%2C3.464h-3.653A.353.353%2C0%2C0%2C0-4785.954%2C1552.838Z%27%20transform%3D%27translate%284786.096%20-1548.503%29%27%20fill%3D%27%252300d200%27%20stroke%3D%27%2523000%27%2F%253E%253C%2Fsvg%253E%22%29%60%29%29%7D%3BreplaceGreenStar%28%29%7D"&gt;はてなグリーンスターに縁をつける&lt;/a&gt;&lt;pre&gt;// ==UserScript==
// @name         はてなグリーンスターに縁をつける
// @title        はてなグリーンスターに縁をつける
// @namespace    https://let.hatelabo.jp/Lhankor_Mhy/let/kNe6m5vsgKAA
// @version      2024-01-31
// @description  はてなグリーンスターに縁をつけます。via: https://b.hatena.ne.jp/entry/4748592896526814671/comment/murlock
// @author       Lhankor_Mhy
// @match        https://b.hatena.ne.jp/entry/*
// @match        https://b.hatena.ne.jp/*/bookmark
// @icon         https://b.hatena.ne.jp/favicon.ico
// @license      CC0
// @noframes
// @grant        none
// @javascript_url
// ==/UserScript==

{
    let timerId;
    new MutationObserver((mutationList, observer) =&amp;gt; {
        mutationList.forEach((mutation) =&amp;gt; {
            switch (mutation.type) {
                case &amp;quot;childList&amp;quot;:
                    clearTimeout(timerId);
                    timerId = setTimeout(replaceGreenStar, 500)
                    break;
            }
        });
    }).observe(document.body, {
        childList: true,
        subtree: true,
    });

    const replaceGreenStar = () =&amp;gt; {
        document.querySelectorAll('.hatena-star-star.green span')?.forEach(e =&amp;gt;e.style.backgroundImage = `url(&amp;quot;data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='10.299' viewBox='0 0 11 10.299'%3E%3Cpath d='M-4785.954,1552.838l2.935,2.125-1.127,3.381a.352.352,0,0,0,.538.393l2.815-1.961h0l.2-.14,3.009,2.1a.353.353,0,0,0,.533-.4l-1.036-3.128v0l-.079-.24.2-.15,0,0,2.712-1.971a.352.352,0,0,0-.207-.638h-3.651l-.079-.238,0,0-1.075-3.218a.352.352,0,0,0-.667-.005l-1.167,3.464h-3.653A.353.353,0,0,0-4785.954,1552.838Z' transform='translate(4786.096 -1548.503)' fill='%2300d200' stroke='%23000'/%3E%3C/svg%3E&amp;quot;)`)
    }
    replaceGreenStar();
}

&lt;/pre&gt;</content:encoded>
  </item>
  <item rdf:about="https://let.hatelabo.jp/Lhankor_Mhy/let/j9W6maaGgKAA">
    <link>https://let.hatelabo.jp/Lhankor_Mhy/let/j9W6maaGgKAA</link>
    <dc:date>2023-07-13T08:46:09Z</dc:date>
    <description>https://teratail.com/questions/ncsqe99mif6af6#reply-2mcicqlromm4lp</description>
    <dc:creator>Lhankor_Mhy</dc:creator>
    <title>[Let] test bookmarklet</title>
    <content:encoded>&lt;a href="javascript:%22https%3A%2F%2Flet.st-hatelabo.com%2FLhankor_Mhy%2Flet%2Fj9W6maaGgKAA.bookmarklet.js%20%28arg%29%22.replace%28%2F%28%5CS%2B%29%5Cs%2B%28%5CS%2A%29%2F%2Cfunction%28s%2Curl%2Carg%29%7Bs%3Ddocument.createElement%28%22script%22%29%3Bs.charset%3D%22utf-8%22%3Bs.src%3Durl%2B%22%3Fs%3D%22%2BencodeURIComponent%28arg%29%3Bdocument.body.appendChild%28s%29%7D%29%3Bvoid%280%29%3B"&gt;test bookmarklet&lt;/a&gt;&lt;pre&gt;/*
 * @title test bookmarklet
 * @description https://teratail.com/questions/ncsqe99mif6af6#reply-2mcicqlromm4lp
 * @include http://*
 * @license MIT License
 * @require 
 */


void document.addEventListener('click',e=&amp;gt;alert(`${e.clientX},${e.clientY}`),{once:true})&lt;/pre&gt;</content:encoded>
  </item>
  <item rdf:about="https://let.hatelabo.jp/Lhankor_Mhy/let/j9W5qIj-gKAA">
    <link>https://let.hatelabo.jp/Lhankor_Mhy/let/j9W5qIj-gKAA</link>
    <dc:date>2023-07-13T08:30:41Z</dc:date>
    <description>https://teratail.com/questions/ncsqe99mif6af6</description>
    <dc:creator>Lhankor_Mhy</dc:creator>
    <title>[Let] test bookmarklet</title>
    <content:encoded>&lt;a href="javascript:%22https%3A%2F%2Flet.st-hatelabo.com%2FLhankor_Mhy%2Flet%2Fj9W5qIj-gKAA.bookmarklet.js%20%28arg%29%22.replace%28%2F%28%5CS%2B%29%5Cs%2B%28%5CS%2A%29%2F%2Cfunction%28s%2Curl%2Carg%29%7Bs%3Ddocument.createElement%28%22script%22%29%3Bs.charset%3D%22utf-8%22%3Bs.src%3Durl%2B%22%3Fs%3D%22%2BencodeURIComponent%28arg%29%3Bdocument.body.appendChild%28s%29%7D%29%3Bvoid%280%29%3B"&gt;test bookmarklet&lt;/a&gt;&lt;pre&gt;/*
 * @title test bookmarklet
 * @description https://teratail.com/questions/ncsqe99mif6af6
 * @include http://*
 * @license MIT License
 * @require 
 */



void document.elementFromPoint(400,0).click()
&lt;/pre&gt;</content:encoded>
  </item>
  <item rdf:about="https://let.hatelabo.jp/Lhankor_Mhy/let/j7qesMCUgYAA">
    <link>https://let.hatelabo.jp/Lhankor_Mhy/let/j7qesMCUgYAA</link>
    <dc:date>2023-06-03T03:09:48Z</dc:date>
    <description>メタブタイトルが「...のコメント」となってしまうところを、元ページのタイトルに変更する。自分が公開ブクマをしていることが条件。ブクマ後リロード推奨。</description>
    <dc:creator>Lhankor_Mhy</dc:creator>
    <title>[Let] コメントメタブタイトル修正</title>
    <content:encoded>&lt;a href="javascript:void%28async%28%29%3D%3E%7Bif%28%21document.querySelector%28%27.entry-edit%27%29%29%7Balert%28%27%E5%85%AC%E9%96%8B%E3%83%96%E3%82%AF%E3%83%9E%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84%E3%82%88%E3%81%86%E3%81%AA%E3%81%AE%E3%81%A7%E5%A4%89%E6%9B%B4%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%9B%E3%82%93%EF%BC%88%E3%83%96%E3%82%AF%E3%83%9E%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E5%A0%B4%E5%90%88%E3%81%AF%E3%83%AA%E3%83%AD%E3%83%BC%E3%83%89%E3%82%92%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B%E3%81%A8%E3%81%84%E3%81%84%E3%81%8B%E3%82%82%EF%BC%89%27%29%3Breturn%7D%7Bconst%20regexpEscape%3Ds%3D%3Es.replace%28%2F%5B%5C%5C%5E%24.%2A%2B%3F%28%29%5B%5C%5D%7B%7D%7C%5D%2Fg%2C%27%5C%5C%24%26%27%29%3Bconst%20regexp%3Dnew%20RegExp%28regexpEscape%28String.raw%60https%3A%2F%2Fb.hatena.ne.jp%2Fentry%2F%60%29%2BString.raw%60%5Cd%2B%2Fcomment%2F%60%29%3Bif%28%21regexp.test%28document.documentElement.dataset.entryUrl%29%29if%28%21confirm%28%27%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88%E3%83%A1%E3%82%BF%E3%83%96%E3%81%A7%E3%81%AF%E3%81%AA%E3%81%95%E3%81%9D%E3%81%86%E3%81%A7%E3%81%99%E3%81%8C%E3%82%BF%E3%82%A4%E3%83%88%E3%83%AB%E5%A4%89%E6%9B%B4%E3%81%97%E3%81%BE%E3%81%99%E3%81%8B%EF%BC%9F%27%29%29return%7Dconst%20pageTitle%3D%28new%20DOMParser%29.parseFromString%28await%28await%20fetch%28document.documentElement.dataset.entryUrl%29%29.text%28%29%2C%22text%2Fhtml%22%29.querySelector%28%27title%27%29.textContent%3Bif%28%21confirm%28%60%E3%82%BF%E3%82%A4%E3%83%88%E3%83%AB%E3%82%92%22%24%7BpageTitle%7D%22%E3%81%AB%E5%A4%89%E6%9B%B4%E3%81%97%E3%81%BE%E3%81%99%60%29%29return%3Bdocument.querySelector%28%27.entry-editModal-textInput%27%29.value%3DpageTitle%3Bdocument.querySelector%28%27.entry-editModal-decide%27%29.click%28%29%7D%29%28%29%3B"&gt;コメントメタブタイトル修正&lt;/a&gt;&lt;pre&gt;/*
 * @title コメントメタブタイトル修正
 * @description メタブタイトルが「...のコメント」となってしまうところを、元ページのタイトルに変更する。自分が公開ブクマをしていることが条件。ブクマ後リロード推奨。
 * @include https://b.hatena.ne.jp/entry/*comment/*
 * @license CC0
 * @javascript_url
 */


void (async () =&amp;gt; {
    if (!document.querySelector('.entry-edit')) {
        alert('公開ブクマされていないようなので変更できません（ブクマしている場合はリロードをしてみるといいかも）')
        return;
    }
    {
        const regexpEscape = s =&amp;gt; s.replace(/[\\^$.*+?()[\]{}|]/g, '\\$&amp;amp;')
        const regexp = new RegExp(regexpEscape(String.raw`https://b.hatena.ne.jp/entry/`) + String.raw`\d+/comment/`)
        if (!regexp.test(document.documentElement.dataset.entryUrl)) if (!confirm('コメントメタブではなさそうですがタイトル変更しますか？')) return;
    }

    const pageTitle = new DOMParser().parseFromString(await (await fetch(document.documentElement.dataset.entryUrl)).text(), &amp;quot;text/html&amp;quot;).querySelector('title').textContent
    if (!confirm(`タイトルを&amp;quot;${pageTitle}&amp;quot;に変更します`)) return;

    document.querySelector('.entry-editModal-textInput').value = pageTitle
    document.querySelector('.entry-editModal-decide').click()
})()


&lt;/pre&gt;</content:encoded>
  </item>
  <item rdf:about="https://let.hatelabo.jp/Lhankor_Mhy/let/jr-yw7yCgMAA">
    <link>https://let.hatelabo.jp/Lhankor_Mhy/let/jr-yw7yCgMAA</link>
    <dc:date>2022-11-22T06:18:45Z</dc:date>
    <description>比較したいブコメページを入力→コメントを比較したテキストをはてな記法で出力</description>
    <dc:creator>Lhankor_Mhy</dc:creator>
    <title>[Let] 2つのブコメを比較（はてな記法版）</title>
    <content:encoded>&lt;a href="javascript:%28async%28%29%3D%3E%7Bconst%20regexpEscape%3Ds%3D%3Es.replace%28%2F%5B%5C%5C%5E%24.%2A%2B%3F%28%29%5B%5C%5D%7B%7D%7C%5D%2Fg%2C%27%5C%5C%24%26%27%29%3Bconst%20regexp%3Dnew%20RegExp%28regexpEscape%28%22https%3A%2F%2Fb.hatena.ne.jp%2Fentry%2F%22%29%2B%22%28s%2F%29%2A%28.%2B%29%22%29%3Bconst%20BtoURL%3Ds%3D%3Es.replace%28regexp%2C%28%28_%2Cp1%2Cp2%29%3D%3E%28p1%3F%22https%3A%2F%2F%22%3A%22http%3A%2F%2F%22%29%2Bp2%29%29%3Bconst%7Bbookmarks%3Abookmarks%2Ceid%3Aeid%7D%3Dawait%28await%20fetch%28%27https%3A%2F%2Fb.hatena.ne.jp%2Fentry%2Fjsonlite%2F%3Furl%3D%27%2BencodeURIComponent%28BtoURL%28prompt%28%27%E6%AF%94%E8%BC%83%E3%83%96%E3%82%AF%E3%83%9EURL%27%2C%27%27%29%29%29%29%29.json%28%29%3Bconst%7Bbookmarks%3AorigBookmarks%2Ceid%3AorigEid%7D%3Dawait%28await%20fetch%28%27https%3A%2F%2Fb.hatena.ne.jp%2Fentry%2Fjsonlite%2F%3Furl%3D%27%2BencodeURIComponent%28BtoURL%28location.href%29%29%29%29.json%28%29%3Bconst%20html%3Dbookmarks.flatMap%28%28bookmark%3D%3E%7Bconst%20origBookmark%3DorigBookmarks.find%28%28origBookmark%3D%3EorigBookmark.user%3D%3D%3Dbookmark.user%29%29%3Bif%28%21origBookmark%29return%5B%5D%3Breturn%5B%60%5Cn%3Cpre%3E%5Cn%2A%20%24%7Bbookmark.user%7D%5Cn%3E%3E%5Cn%24%7Bbookmark.comment%7D%5Cnhttps%3A%2F%2Fb.hatena.ne.jp%2Fentry%2F%24%7Beid%7D%2Fcomment%2F%24%7Bbookmark.user%7D%5Cn%3C%3C%5Cn%3E%3E%5Cn%24%7BorigBookmark.comment%7D%5Cnhttps%3A%2F%2Fb.hatena.ne.jp%2Fentry%2F%24%7BorigEid%7D%2Fcomment%2F%24%7BorigBookmark.user%7D%5Cn%3C%3C%5Cn%3C%2Fpre%3E%5Cn%20%20%20%20%20%20%20%20%60%5D%7D%29%29.join%28%27%27%29%3Bconst%20blob%3Dnew%20Blob%28%5Bhtml%5D%2C%7Btype%3A%22text%2Fhtml%3Bcharset%3Dutf-8%22%7D%29%3Bconst%20url%3DURL.createObjectURL%28blob%29%3Bwindow.open%28url%29%3BURL.revokeObjectURL%28url%29%7D%29%28%29%3B"&gt;2つのブコメを比較（はてな記法版）&lt;/a&gt;&lt;pre&gt;/*
 * @title 2つのブコメを比較（はてな記法版）
 * @description 比較したいブコメページを入力→コメントを比較したテキストをはてな記法で出力
 * @include https://b.hatena.ne.jp/entry/*
 * @license CC0
 * @javascript_url
 */

(async () =&amp;gt; {
    const regexpEscape = s =&amp;gt; s.replace(/[\\^$.*+?()[\]{}|]/g, '\\$&amp;amp;')
    const regexp = new RegExp(regexpEscape(&amp;quot;https://b.hatena.ne.jp/entry/&amp;quot;) + &amp;quot;(s/)*(.+)&amp;quot;)
    const BtoURL = s =&amp;gt; s.replace(regexp, (_, p1, p2) =&amp;gt; (p1 ? &amp;quot;https://&amp;quot; : &amp;quot;http://&amp;quot;) + p2)

    const { bookmarks, eid } = (await (await fetch('https://b.hatena.ne.jp/entry/jsonlite/?url=' + encodeURIComponent(BtoURL(prompt('比較ブクマURL', ''))))).json())
    const { bookmarks: origBookmarks, eid: origEid } = (await (await fetch('https://b.hatena.ne.jp/entry/jsonlite/?url=' + encodeURIComponent(BtoURL(location.href)))).json())

    const html = bookmarks.flatMap(bookmark =&amp;gt; {
        const origBookmark = origBookmarks.find(origBookmark=&amp;gt;origBookmark.user===bookmark.user)
        if (!origBookmark) return []
        return [`
&amp;lt;pre&amp;gt;
* ${bookmark.user}
&amp;gt;&amp;gt;
${bookmark.comment}
https://b.hatena.ne.jp/entry/${eid}/comment/${bookmark.user}
&amp;lt;&amp;lt;
&amp;gt;&amp;gt;
${origBookmark.comment}
https://b.hatena.ne.jp/entry/${origEid}/comment/${origBookmark.user}
&amp;lt;&amp;lt;
&amp;lt;/pre&amp;gt;
        `]
    }).join('')   

    const blob = new Blob([html], { type: &amp;quot;text/html;charset=utf-8&amp;quot; })
    const url = URL.createObjectURL(blob)
    window.open(url)
    URL.revokeObjectURL(url)
})()&lt;/pre&gt;</content:encoded>
  </item>
  <item rdf:about="https://let.hatelabo.jp/Lhankor_Mhy/let/jLrKiqvEgoAA">
    <link>https://let.hatelabo.jp/Lhankor_Mhy/let/jLrKiqvEgoAA</link>
    <dc:date>2022-11-18T09:09:55Z</dc:date>
    <description>比較したいブコメページを入力→コメントがユーザーごとに並ぶ</description>
    <dc:creator>Lhankor_Mhy</dc:creator>
    <title>[Let] 2つのブコメを比較</title>
    <content:encoded>&lt;a href="javascript:%28async%28%29%3D%3E%7Bdocument.documentElement.scrollTop%3Ddocument.documentElement.scrollHeight%3Bconst%20regexpEscape%3Ds%3D%3Es.replace%28%2F%5B%5C%5C%5E%24.%2A%2B%3F%28%29%5B%5C%5D%7B%7D%7C%5D%2Fg%2C%27%5C%5C%24%26%27%29%3Bconst%20regexp%3Dnew%20RegExp%28regexpEscape%28%22https%3A%2F%2Fb.hatena.ne.jp%2Fentry%2F%22%29%2B%22%28s%2F%29%2A%28.%2B%29%22%29%3Bconst%20BtoURL%3Ds%3D%3Es.replace%28regexp%2C%28%28_%2Cp1%2Cp2%29%3D%3E%28p1%3F%22https%3A%2F%2F%22%3A%22http%3A%2F%2F%22%29%2Bp2%29%29%3Bconst%7Bbookmarks%3Abookmarks%2Ceid%3Aeid%7D%3Dawait%28await%20fetch%28%27https%3A%2F%2Fb.hatena.ne.jp%2Fentry%2Fjsonlite%2F%3Furl%3D%27%2BencodeURIComponent%28BtoURL%28prompt%28%27%E6%AF%94%E8%BC%83%E3%83%96%E3%82%AF%E3%83%9EURL%27%2C%27%27%29%29%29%29%29.json%28%29%3Bbookmarks.forEach%28%28bookmark%3D%3E%7Bconst%20targetElement%3Ddocument.querySelector%28%60.is-active.bookmarks-sort-panel%20%5Bdata-user-name%3D%22%24%7Bbookmark.user%7D%22%5D%20.entry-comment-text%60%29%3BtargetElement%3F.insertAdjacentHTML%3F.%28%27beforeend%27%2C%60%3Ca%20href%3D%22%2Fentry%2F%24%7Beid%7D%2Fcomment%2F%24%7Bbookmark.user%7D%22%20class%3D%22entry-comment-text%20js-bookmark-comment%22%20target%3D%22_blank%22%20style%3D%22display%3Ablock%3Bbackground-color%3Awheat%22%3E%24%7Bbookmark.comment%7D%3C%2Fa%3E%60%29%7D%29%29%7D%29%28%29%3B"&gt;2つのブコメを比較&lt;/a&gt;&lt;pre&gt;/*
 * @title 2つのブコメを比較
 * @description 比較したいブコメページを入力→コメントがユーザーごとに並ぶ
 * @include https://b.hatena.ne.jp/entry/*
 * @license CC0
 * @javascript_url
 */

(async () =&amp;gt; {
    document.documentElement.scrollTop = document.documentElement.scrollHeight
    const regexpEscape = s =&amp;gt; s.replace(/[\\^$.*+?()[\]{}|]/g, '\\$&amp;amp;')
    const regexp = new RegExp(regexpEscape(&amp;quot;https://b.hatena.ne.jp/entry/&amp;quot;) + &amp;quot;(s/)*(.+)&amp;quot;)
    const BtoURL = s =&amp;gt; s.replace(regexp, (_, p1, p2) =&amp;gt; (p1 ? &amp;quot;https://&amp;quot; : &amp;quot;http://&amp;quot;) + p2)

    const {bookmarks,eid} = (await (await fetch('https://b.hatena.ne.jp/entry/jsonlite/?url=' + encodeURIComponent(BtoURL(prompt('比較ブクマURL', ''))))).json())

    bookmarks.forEach(bookmark =&amp;gt; {
        const targetElement = document.querySelector(`.is-active.bookmarks-sort-panel [data-user-name=&amp;quot;${bookmark.user}&amp;quot;] .entry-comment-text`)
        targetElement?.insertAdjacentHTML?.('beforeend', `&amp;lt;a href=&amp;quot;/entry/${eid}/comment/${bookmark.user}&amp;quot; class=&amp;quot;entry-comment-text js-bookmark-comment&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;display:block;background-color:wheat&amp;quot;&amp;gt;${bookmark.comment}&amp;lt;/a&amp;gt;`)
    })
})()
&lt;/pre&gt;</content:encoded>
  </item>
  <item rdf:about="https://let.hatelabo.jp/Lhankor_Mhy/let/hLHVoNuA3dNN">
    <link>https://let.hatelabo.jp/Lhankor_Mhy/let/hLHVoNuA3dNN</link>
    <dc:date>2022-09-07T02:04:29Z</dc:date>
    <description>エントリページで動作します。</description>
    <dc:creator>Lhankor_Mhy</dc:creator>
    <title>[Let] 俺にスターつけてくれた人のブコメはどれ？</title>
    <content:encoded>&lt;a href="javascript:document.querySelector%28%27.is-my-bookmark%20.hatena-star-inner-count%27%29%3F.click%3F.%28%29%3Bvoid%20setTimeout%28%28%28%29%3D%3E%7Bdocument.querySelectorAll%28%27.is-my-bookmark%20.hatena-star-star%27%29.forEach%28%28function%28e%29%7Bconst%20targetUserName%3De.href.split%28%27%2F%27%29%5B3%5D%3Bconsole.log%28targetUserName%29%3Bvar%20target%3Ddocument.querySelectorAll%28%60.js-bookmarks-sort-panels%20%5Bdata-user-name%3D%24%7BtargetUserName%7D%5D%60%29%3Bif%28target%29target.forEach%28%28el%3D%3Eel.style.backgroundColor%3D%27%23ff9%27%29%29%7D%29%29%7D%29%2C2e3%29%3B"&gt;俺にスターつけてくれた人のブコメはどれ？&lt;/a&gt;&lt;pre&gt;/*
 * @title 俺にスターつけてくれた人のブコメはどれ？
 * @description エントリページで動作します。
 * @include http://http://b.hatena.ne.jp/entry/*
 * @license MIT License
 * @javascript_url 
 */

document.querySelector('.is-my-bookmark .hatena-star-inner-count')?.click?.()
void setTimeout(()=&amp;gt;{
  document.querySelectorAll('.is-my-bookmark .hatena-star-star').forEach(function(e){
    const targetUserName = e.href.split('/')[3]
    console.log(targetUserName)
    var target = document.querySelectorAll(`.js-bookmarks-sort-panels [data-user-name=${targetUserName}]`)
    if (target) target.forEach(el=&amp;gt;el.style.backgroundColor = '#ff9')
  })
},2000)&lt;/pre&gt;</content:encoded>
  </item>
</rdf:RDF>
