Last active
March 2, 2018 04:35
-
-
Save khsk/bca459a16e214c4e26c353618249a7bd to your computer and use it in GitHub Desktop.
Qiitaのフィードのタグアイコンをホバー時ユーザーアイコンに切り替えついでに名前とかをポップアップするユーザースクリプト ref: https://qiita.com/khsk/items/9f806c0a16e12236ec56
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"articles_count": 114, | |
"contribution": 656, | |
"followed": false, | |
"id": 62354, | |
"name": "", | |
"profile_image_url": "https://qiita-image-store.s3.amazonaws.com/0/62354/profile-images/1473695923", | |
"url_name": "khsk" | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Qiita show user Icon to feed | |
// @namespace khsk | |
// @description フィードの記事アイコンをホバーしたとき、投稿者のアイコンに変更する | |
// @include http://qiita.com/ | |
// @include https://qiita.com/ | |
// @include http://qiita.com/items | |
// @include https://qiita.com/items | |
// @include http://qiita.com/stock | |
// @include https://qiita.com/stock | |
// @include http://qiita.com/mine | |
// @include https://qiita.com/mine | |
// @version 1 | |
// @grant none | |
// ==/UserScript== | |
console.time('hover icon'); | |
const ORIGINAL_CLASS = 'user-icon'; | |
const CUSTOM_CLASS = 'khsk-user-icon'; // IDより面倒だけど、複数作るのでクラスだよ。うっかりIDに書き換えそうになったので。 | |
const getUserName = elm => { | |
const link = elm.parentNode.parentNode.parentNode.querySelector('div.item-box-title > h1 > a'); | |
return link.href.match(/https?:\/\/qiita.com\/([^/]+)/)[1]; | |
}; | |
const getUserData = (username) => { | |
return new Promise((resolve, reject) => { | |
const xhr = new XMLHttpRequest(); | |
xhr.open('GET', 'https://qiita.com/api/internal/hovercard_users/' + username); | |
xhr.addEventListener('load', e => { | |
resolve(xhr.responseText); | |
}); | |
xhr.addEventListener('error', e => { | |
reject(xhr.responseText); | |
}); | |
xhr.send(); | |
}); | |
}; | |
const setPopover = (elm, data) => { | |
// Qiitaのhovercardはhovercard.jsではないのかもで諦め | |
// 最後に$(elm).tooltip() or popover()を実行するとタイトルがタグになる。謎。なので最初に設定 | |
// datasetでは効かないものがある | |
$(elm).popover({ | |
trigger : 'hover', | |
placement : 'top', // フィードは上から下へ見ると思うので | |
container : 'body', | |
html : true, | |
}); | |
elm.dataset.toggle = 'popover'; | |
elm.dataset.originalTitle = 'Author Info'; | |
// hovercardっぽさのためにアイコン画像は不要か… | |
//elm.dataset.content = '<img src="' + data.profile_image_url + '">' + '<br>\n' + (data.name || data.url_name) + '<br>\n' + data.contribution + ' Contribution'; | |
elm.dataset.content = (data.name || data.url_name) + '<br>\n' + data.contribution + ' Contribution'; | |
elm.dataset.placement = 'top'; // フィードは上から下へ見ると思うので | |
// 改行対策にデフォルト値 + nowrap | |
elm.dataset.viewport = "{ selector: 'body', padding: 0 , white-space: nowrap,}"; | |
}; | |
const createUserIcon = elm => { | |
return (async () => { | |
const username = getUserName(elm); | |
const userdata = JSON.parse(await getUserData(username)); | |
const user = elm.cloneNode(); | |
// 識別子 | |
user.className = user.className + ' ' + CUSTOM_CLASS; | |
user.src = userdata.profile_image_url; | |
setPopover(user, userdata); | |
elm.parentNode.insertBefore(user, elm); | |
return user; | |
})(); | |
}; | |
const showUser = elm => { | |
return (async elm => { | |
// ByClass()[0]とどっちがいいかなあ | |
let user = elm.parentNode.querySelector('.' + CUSTOM_CLASS); | |
if (!user) { | |
user = await createUserIcon(elm); | |
} | |
user.style.display = ''; | |
elm.style.display = 'none'; | |
})(elm); | |
}; | |
const hideUser = user => { | |
return (async user => { | |
// たぶんツールチップ表示が邪魔するので隣接セレクタではなく一般兄弟セレクタ(関節セレクタ)で取得する | |
const tag = user.parentNode.querySelector('.' + CUSTOM_CLASS + ' ~ img'); | |
tag.style.display = ''; | |
user.style.display = 'none'; | |
})(user); | |
}; | |
// ここ非jQueryでどうするか不明 | |
$(document).on({ | |
'mouseenter': e => { | |
console.log('mouseenter'); | |
// targetは目的のimgで、currentTargetがa | |
// targetのクラス名をチェックしないと、マウスでこすると想定外のelmが渡ることがあるので | |
if (e.target.className.indexOf(ORIGINAL_CLASS) != -1) { | |
showUser(e.target).catch(e => { | |
console.log('mouseenter catch : ' + e); | |
}); | |
} | |
}, | |
'mouseleave': e => { | |
console.info('mouseleave'); | |
// 順調ならe.targetが作ったuser imgになるよ | |
if (e.target.className.indexOf(ORIGINAL_CLASS) != -1) { | |
hideUser(e.target).catch(e => { | |
console.log('mouseleave catch : ' + e); | |
}); | |
} | |
} | |
}, '.action-user-icon.action > a'/* imgにイベントを設定すると、非表示時にmouseleaveが起き無限ループするので、親のaにする */); | |
console.timeEnd('hover icon'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment