【JavaScript】フォト蔵のアルバム画面を整形する、Greasemonkeyスクリプト
概要
フォト蔵のアルバム画面で色々操作しにくいところがあったので、Greasemonkeyのスクリプトを書きました。
こんな不満を解消
- サムネイルが小さくて見えない
- 視力悪くてディスプレイが遠いと辛い
- 「次へ」ボタンを連打するのが面倒
- 写真をダウンロードするまでの手順が面倒
コード
[expand_photozou_album_photos.user.js]
This file contains hidden or 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 expand_photozou_album_photos | |
// @namespace kunst1080 | |
// @description フォト蔵のアルバム画面を整形して見やすくする。 | |
// @include http://photozou.jp/photo/list/*/* | |
// @grant GM_xmlhttpRequest | |
// @grant GM_getValue | |
// @grant GM_setValue | |
// @version 1 | |
// ==/UserScript== | |
var DOMParser = new (new XPCNativeWrapper(window, "DOMParser()")).DOMParser(); | |
var MAX_PAGE = 100; | |
function $(a_id){ | |
return document.getElementById(a_id); | |
} | |
function $$(a_classname){ | |
return document.getElementsByClassName(a_classname); | |
} | |
if (document.querySelectorAll('li[class="thumbnail"]').length > 0){ | |
var url_org = document.location.href; | |
var url_root = url_org.split("?")[0]; | |
var url_page = url_org.split("?").length > 1 ? url_org.split("?")[1].split("=")[1] : 1; | |
var page_count_max = (function(){ | |
// org_text … n件中1件~16件 | |
var org_text = $$('pageindex')[1].textContent.replace(/\s/g, ""); | |
var arr = org_text.replace("件中",",").replace("件~",",").replace("件",",").split(","); | |
return Math.ceil(arr[0]/(arr[2] - arr[1] + 1)); | |
})(); | |
var output_area = $$('thumbrow autopagerize_page_element')[0]; | |
var log_area = $('side'); | |
output_area.innerHTML = ""; | |
log_area.innerHTML = "<h1>< LOG AREA ></h1><p> --- 計 " + page_count_max + " ページ --- </p>"; | |
// load pages recursive | |
(function rec_load_pages(root, page){ | |
var new_url = root + "?page=" + page; | |
GM_xmlhttpRequest({ | |
method: "GET", | |
url: new_url, | |
onload: function(res) { | |
var body = DOMParser.parseFromString(res.responseText, "text/html").getElementById('main'); | |
if(page > MAX_PAGE || body.querySelectorAll('li[class="thumbnail"]').length < 1){ | |
return; | |
} | |
log_area.innerHTML += "<p>" | |
+ new_url | |
+ " … " + body.querySelectorAll('li[class="thumbnail"]').length + "枚" | |
+ " (" + page + "/" + page_count_max + "ページ)" | |
+ "</p>"; | |
expandPage(body, function(element){ | |
output_area.innerHTML += element.innerHTML; | |
}); | |
rec_load_pages(root, ++page); // recursive | |
} | |
}); | |
})(url_root,url_page, $('main')); | |
} | |
function expandPage(doc, callback){ | |
Array.forEach(doc.querySelectorAll('li[class="thumbnail"]'), function(e1) { | |
var child_url = e1.getElementsByTagName('A')[0].href; | |
var dummy_elment = document.createElement("div"); | |
var id = child_url.replace("http://","").split("/")[4]; | |
dummy_elment.innerHTML = "<div id=" + id + "></div>"; | |
// call back to callee | |
callback(dummy_elment); | |
// get big thumbnail and change dummy_elment | |
GM_xmlhttpRequest({ | |
method: "GET", | |
url: child_url, | |
onload: function(res) { | |
var body = DOMParser.parseFromString(res.responseText, "text/html"); | |
var new_thumbnail = body.getElementById("photo"); | |
// get original image url | |
var image_url = new_thumbnail.getElementsByTagName('img')[0].src; | |
var new_image_url = image_url.replace(/_.*\./, "_org."); | |
new_thumbnail.getElementsByTagName('A')[0].href = new_image_url; | |
// set html to dummy_elment | |
e1.getElementsByTagName('A')[0].innerHTML = ""; | |
$(id).innerHTML = e1.innerHTML + new_thumbnail.innerHTML + "<hr />" | |
} | |
}); | |
}); | |
} |
工夫した点
- 次ページの情報を取得する箇所で非同期のAjax処理を行なっているのだけれど、コールバックから再帰することで処理を直列化しました。
- ※これをやらないと写真の順番がぐちゃぐちゃになる
- ページの分析・展開処理にdocumentを渡すようにして、複数ページの読み込みをサポート。
DOM操作したのは久々。FireFoxだとquerySelectorとかあって便利ね!
あと、お手軽に無名関数書けるってやっぱいいな。JavaやCOBOLじゃぁこうはいかないもの。