はてなブックマークのタグをソートする Greasemonkey script
はてなブックマーク改造用Greasemonkey詰め合わせで
なんてものを見つけたので、改造してみた。
ソートに使う項目は以下:
- 今表示してるページのタグ数
- タグの世代(tag-latestとかってやつ)
- タグのサイズ(規模)
- タグ名
元ネタを作った小野マトペ様に感謝。
場所は以下:
yahoo breafcase/HatenaTagSort2.user.js
右クリして View user script source でインストール。
ソースを以下にも書いとく。
// ==UserScript== // @name HatenaTagSort2 // @namespace http://d.hatena.ne.jp/buzztaiki/ // @description Sort ?B taglist by various order. If you custmoize order, modify `sortOrder' variable. // @include http://b.hatena.ne.jp/* // ==/UserScript== // Original source: http://www.onomatope.2-d.jp/program/firefox/HatenaTagSort.user.js (function() { var sortOrder = [ 'compareCountTo', 'compareAgeTo', 'compareSizeTo', 'compareTagNameTo' ]; // ---------------------------------------------------------------- function getElementsByClassName(parent, className, tagName) { tagName = tagName || '*'; var elems = parent.getElementsByTagName(tagName); var targetElems = []; for (var i = 0; i < elems.length; i++) { var classNames = elems[i].className.split(/ +/); INNER: for (var j = 0; j < classNames.length; j++) { if (classNames[j] == className) { targetElems.push(elems[i]); break INNER; } } } return targetElems; } // ---------------------------------------------------------------- // Cache for store method value. function Cache() { this.value = null; } Cache.prototype.set = function(value) { this.value = value; return this.value; }; // ---------------------------------------------------------------- // Tag. // Hold sort method and reference of tag element. function Tag(tagElem) { this.tagElem = tagElem; this.count = 0; this.caches = {}; var cacheNames = [ 'aElem', 'size', 'tagName', 'age' ]; for (var i = 0; i < cacheNames.length; i++) { this.caches[cacheNames[i]] = new Cache(); } } Tag.prototype.aElem = function() { var cache = this.caches.aElem; if (cache.value) { return cache.value; } return cache.set(this.tagElem.getElementsByTagName('a')[0]); }; Tag.prototype.size = function() { var cache = this.caches.size; if (cache.value) { return cache.value; } var fontSize = this.aElem().style.fontSize; return cache.set(parseFloat(fontSize.replace(/pt$/, ''))); }; Tag.prototype.tagName = function() { var cache = this.caches.tagName; if (cache.value) { return cache.value; } return cache.set(this.aElem().firstChild.data); }; Tag.prototype.age = function() { var cache = this.caches.age; if (cache.value) { return cache.value; } var targetNames = [ 'tag-latest', 'tag-later', 'tag-earlier', 'tag-earliest' ]; var className = this.aElem().className; for (var i = 0; i < targetNames.length; i++) { if (targetNames[i] == className) { return cache.set(i); } } return cache.set(99); }; Tag.prototype.compareAgeTo = function(other) { return this.age() - other.age(); }; Tag.prototype.compareSizeTo = function(other) { return other.size() - this.size(); }; Tag.prototype.compareTagNameTo = function(other) { if (this.tagName() < other.tagName()) { return -1; } else if (this.tagName() > other.tagName()) { return 1; } else { return 0; } }; Tag.prototype.compareCountTo = function(other) { return other.count - this.count; }; Tag.compare = function(a, b) { for (var i = 0; i < sortOrder.length; i++) { var cmp = a[sortOrder[i]](b); if (cmp !== 0) { return cmp; } } return 0; }; // ---------------------------------------------------------------- function createTagCounts() { var tagCounts = {}; var bookmarkElems = getElementsByClassName(document, 'bookmarklist', 'dl'); for (var i = 0; i < bookmarkElems.length; i++) { var tagElems = getElementsByClassName(bookmarkElems[i], 'tag', 'span'); for (var j = 0; j < tagElems.length; j++) { var tag = tagElems[j].getElementsByTagName('a')[0].firstChild.data; if (!tagCounts[tag]) { tagCounts[tag] = 0; } tagCounts[tag] += 1; } } return tagCounts; } function createTags(tagCounts) { var taglistElem = document.getElementById('taglist'); var tagElems = taglistElem.getElementsByTagName('li'); var tags = []; for (var i = 0; i < tagElems.length; i++) { var tag = new Tag(tagElems[i]); tag.count = tagCounts[tag.tagName()] || 0; tags.push(tag); } return tags.sort(Tag.compare); } // ---------------------------------------------------------------- var tags = createTags(createTagCounts()); var spaceNode = document.createTextNode(' '); var taglistElem = document.getElementById('taglist'); var newTaglistElem = taglistElem.cloneNode(false); newTaglistElem.appendChild(spaceNode.cloneNode(false)); for (var i = 0; i < tags.length; i++) { var tagElem = tags[i].tagElem.cloneNode(true); if (tags[i].count > 0) { var countElem = document.createElement('span'); countElem.setAttribute('style', 'font-size: 8pt;'); countElem.appendChild(document.createTextNode(':' + tags[i].count)); tagElem.appendChild(countElem); } newTaglistElem.appendChild(tagElem); newTaglistElem.appendChild(spaceNode.cloneNode(false)); } taglistElem.parentNode.replaceChild(newTaglistElem, taglistElem); })();