はてなブックマークメタブ展開
by
Lhankor_Mhy
03/28 [2024/03/28 12:21:28]
コメントメタブと2階ブクマを展開します。説明→https://realtor-readyabooks.hatenablog.com/entry/2022/12/28/153626
@@ -1,7 +1,7 @@
// ==UserScript==
// @name はてなブックマークメタブ展開
// @title はてなブックマークメタブ展開
-// @namespace http://tampermonkey.net/
+// @namespace https://let.hatelabo.jp/Lhankor_Mhy/let/jtaB0fa4gYAA
// @version 0.1
// @description コメントメタブと2階ブクマを展開します。
// @author Lhankor_Mhy
@@ -9,11 +9,15 @@
// @include https://b.hatena.ne.jp/entry/*
// @icon https://b.hatena.ne.jp/favicon.ico
// @license CC0
+// @noframes
// @grant none
// ==/UserScript==
(async () => {
+ const APIURL = 'https://b.hatena.ne.jp/entry/jsonlite/?url='
+
+
// ブクマ展開(x-template再利用)
const addBookmark = function (targetElement, bookmark, eid) {
targetElement.insertAdjacentHTML(
@@ -33,19 +37,20 @@
.replaceAll('{{#enable_button}} is-enabled{{/enable_button}}', 'is-enabled')
)
- };
+ }
// 2階ブクマAPIコール
- const targetURLs = [location.href], bookmarksList = []
+ const targetURLs = [location.href], upstairsBookmarksList = []
for (const targetURL of targetURLs) {
- const { bookmarks, entry_url, eid } = (await (await fetch('https://b.hatena.ne.jp/entry/jsonlite/?url=' + encodeURIComponent(targetURL))).json()) ?? { bookmarks: [], entry_url: null, eid: undefined }
- if (entry_url) targetURLs.push(entry_url)
- bookmarksList.push([bookmarks, eid])
+ 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) {
- bookmarksList.forEach(([bookmarks, eid]) => {
+ upstairsBookmarksList.forEach(([bookmarks, eid]) => {
bookmarks.forEach(bookmark => {
const targetUserBookmark = targetElements.find(element => element.dataset?.userName === bookmark.user)
if (!targetUserBookmark) return undefined
@@ -59,9 +64,8 @@
function addMetaBookmark(targetElements) {
targetElements.forEach(async element => {
const targetURL = element.querySelector('[data-gtm-label="entry-recent-permalink"]').href
- const { bookmarks, entry_url, eid } = (await (await fetch('https://b.hatena.ne.jp/entry/jsonlite/?url=' + encodeURIComponent(targetURL))).json()) ?? { bookmarks: [], entry_url: null }
- if (!bookmarks.length) return undefined
- // console.log(bookmarks, eid, entry_url)
+ const { bookmarks, entry_url, eid } = (await (await fetch(`${APIURL}${encodeURIComponent(targetURL)}`)).json()) ?? { entry_url: null }
+ if (!entry_url) return undefined
bookmarks.forEach(
bookmark => {
addBookmark(element, bookmark, eid)
@@ -99,7 +103,4 @@
const metaBookmarkMutationObserver = new MutationObserver(metaBookmarkMutationCallback);
metaBookmarkMutationObserver.observe(targetNode, metaBookmarkMutationConfig);
-})()
-
-
-
+})()
// ==UserScript==
// @name はてなブックマークメタブ展開
// @title はてなブックマークメタブ展開
// @namespace https://let.hatelabo.jp/Lhankor_Mhy/let/jtaB0fa4gYAA
// @version 0.1
// @description コメントメタブと2階ブクマを展開します。
// @author Lhankor_Mhy
// @match https://b.hatena.ne.jp/entry/*
// @include https://b.hatena.ne.jp/entry/*
// @icon https://b.hatena.ne.jp/favicon.ico
// @license CC0
// @noframes
// @grant none
// ==/UserScript==
(async () => {
const APIURL = 'https://b.hatena.ne.jp/entry/jsonlite/?url='
// ブクマ展開(x-template再利用)
const addBookmark = function (targetElement, bookmark, eid) {
targetElement.insertAdjacentHTML(
'beforeend',
document.getElementById('autoloader-bookmark-item').textContent
.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}}}', `<li>${bookmark.tags.join('<li>')}`)
.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')
)
}
// 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) {
upstairsBookmarksList.forEach(([bookmarks, eid]) => {
bookmarks.forEach(bookmark => {
const targetUserBookmark = targetElements.find(element => element.dataset?.userName === bookmark.user)
if (!targetUserBookmark) return undefined
const targetElement = [targetUserBookmark, ...targetUserBookmark.querySelectorAll(`[data-user-name="${bookmark.user}"]`)].pop()
addBookmark(targetElement, bookmark, eid)
})
})
}
// メタブをHTMLに展開
function addMetaBookmark(targetElements) {
targetElements.forEach(async element => {
const targetURL = element.querySelector('[data-gtm-label="entry-recent-permalink"]').href
const { bookmarks, entry_url, eid } = (await (await fetch(`${APIURL}${encodeURIComponent(targetURL)}`)).json()) ?? { entry_url: null }
if (!entry_url) return undefined
bookmarks.forEach(
bookmark => {
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 => 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 => node.dataset?.userName))
}
}
};
const metaBookmarkMutationObserver = new MutationObserver(metaBookmarkMutationCallback);
metaBookmarkMutationObserver.observe(targetNode, metaBookmarkMutationConfig);
})()
- Permalink
- このページへの個別リンクです。
- RAW
- 書かれたコードへの直接のリンクです。
- Packed
- 文字列が圧縮された書かれたコードへのリンクです。
- Userscript
- Greasemonkey 等で利用する場合の .user.js へのリンクです。
- Loader
- @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
- Metadata
- コード中にコメントで @xxx と書かれたメタデータの JSON です。