Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
スクロールバーにページの全貌を表示する
// ==UserScript==
// @name DocumentMap.uc.js
// @description スクロールバーにページの全貌を表示する
// @namespace http://d.hatena.ne.jp/Griever/
// @author Griever
// @license MIT License
// @compatibility Firefox 11
// @charset UTF-8
// @include main
// @version 下書き1
// @note SmartScrollbar.uc.js とは併用不可
// ==/UserScript==
/*
既知の問題点
・中央寄せのサイトで左側を背景にしても意味がない
対策取るとリロード時にスクロール位置がリセットされる問題がある
・縦に長いサイトでスクロールが重くなる
どうしようもない\(^o^)/
・多分ボツ
*/
(function(CSS){
if (window.gDocumentMap) {
window.gDocumentMap.destroy();
delete window.gDocumentMap;
}
window.gDocumentMap = {
nnn: Array.apply(null, Array(50)).map(function(u,i) i) ,
sss: Cc['@mozilla.org/content/style-sheet-service;1'].getService(Ci.nsIStyleSheetService),
get cssuri() {
var src = CSS;
this.nnn.forEach(function(n){
src += '\nwww|html[documentmapleft="'+ n +'"] > scrollbar[orient="vertical"]' +
' { background-position: '+ n +'% top !important; }';
}, this);
delete this.cssuri;
return this.cssuri = Services.io.newURI('data:text/css;charset=utf-8,' +
encodeURIComponent(src), null, null);
},
init: function() {
if (this.sss.sheetRegistered(this.cssuri, this.sss.AGENT_SHEET))
this.sss.unregisterSheet(this.cssuri, this.sss.AGENT_SHEET);
this.sss.loadAndRegisterSheet(this.cssuri, this.sss.AGENT_SHEET);
gBrowser.mPanelContainer.addEventListener("DOMContentLoaded", this, false);
window.addEventListener("unload", this, false);
},
uninit: function() {
if (this.sss.sheetRegistered(this.cssuri, this.sss.AGENT_SHEET))
this.sss.unregisterSheet(this.cssuri, this.sss.AGENT_SHEET);
gBrowser.mPanelContainer.removeEventListener("DOMContentLoaded", this, false);
window.removeEventListener("unload", this, false);
},
destroy: function() {
[].forEach(function(id){
var elem = $(id);
if (elem) elem.parentNode.removeChild(elem);
}, this);
this.uninit();
},
handleEvent: function(event) {
switch(event.type){
case "DOMContentLoaded":
var doc = event.target;
var win = doc.defaultView;
if (doc.body instanceof HTMLFrameSetElement ||
win.frameElement && !(win.frameElement instanceof HTMLFrameElement))
return;
this.setBgImage(doc, win);
break;
case "unload":
this.uninit();
break;
}
},
setBgImage: function(doc, win) {
win || (win = doc.defaultView);
var root = doc.documentElement;
doc.mozSetImageElement('documentMapImage', root);
return;
// pageElement を探して背景位置を決める
// スクロールバーの再描画に問題があるので保留
var pageElement;
if ('uAutoPagerize' in window) {
pageElement = this.getPageElement(uAutoPagerize.MY_SITEINFO, doc) ||
this.getPageElement(uAutoPagerize.SITEINFO, doc);
}
if (!pageElement) {
pageElement = doc.querySelector('#main, #content, #contents, section');
}
var nearest = 0;
if (pageElement) {
var left = Math.round(pageElement.getBoundingClientRect().left / root.scrollWidth * 100);
this.nnn.some(function(n){
if (left < n) return true;
nearest = n;
});
} else {
nearest = 2;
}
root.setAttribute('documentmapleft', nearest);
//スクロールバーを再描画させる。スクロール位置がリセットされるので使えない…
//root.style.overflowY = 'auto';
//win.setTimeout(function() { root.style.overflowY = ''; }, 10);
},
getPageElement: function (list, doc) {
if (!list || !doc) return null;
var locationHref = doc.location.href;
for (let [index, info] in Iterator(list)) {
try {
var exp = info.url_regexp || Object.defineProperty(info, "url_regexp", {
enumerable: false,
value: new RegExp(info.url)
}).url_regexp;
if ( !exp.test(locationHref) ) continue;
var pageElement = doc.evaluate(info.pageElement, doc, null,
XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
if (!pageElement) continue;
return pageElement;
} catch(e) { }
}
return null;
},
};
window.gDocumentMap.init();
})(<![CDATA[
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
@namespace www url("http://www.w3.org/1999/xhtml");
www|html > scrollbar[orient="vertical"] {
-moz-appearance: none !important;
background-color: -moz-dialog !important;
background-image: -moz-element(#documentMapImage) !important;
background-position: 2% top;
background-repeat: no-repeat !important;
background-size: cover !important;
width: 21px !important;
}
www|html > scrollbar[orient="vertical"] > slider {
-moz-appearance: none !important;
}
www|html > scrollbar[orient="vertical"] > slider > thumb {
-moz-appearance: none !important;
border: none !important;
background-color: rgba(0,0,255,.2) !important;
}
www|html > scrollbar[orient="vertical"] > scrollbarbutton { display: none }
]]>.toString());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.