-
-
Save gotomypc/5220282 to your computer and use it in GitHub Desktop.
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 Tfocus | |
// @namespace http://efcl.info/ | |
// @include http://* | |
// @include https://* | |
// @require https://github.com/hatena/extract-content-javascript/raw/master/lib/extract-content-all.js | |
// ==/UserScript== | |
(function(_doc) { | |
// DEBUG ON/OFF | |
var DEBUG = true; | |
var SHORTCUT_KEY = "S-b" | |
// ショートカットの設定関数 | |
// http://d.hatena.ne.jp/jimo1001/20090601/1243782686 を改変 | |
function ShortcutKey(win) { | |
this.list = []; | |
this.init(win || window); | |
} | |
ShortcutKey.prototype.keys = { | |
8: 'BS', | |
9: 'TAB', | |
10: 'Enter', | |
13: 'Enter', | |
32: 'SPC', | |
27: 'ESC', | |
33: 'PageUp', | |
34: 'PageDown', | |
35: 'End', | |
36: 'Home', | |
37: 'Left', | |
38: 'Up', | |
39: 'Right', | |
40: 'Down', | |
45: 'Insert', | |
46: 'Delete', | |
112: 'F1', | |
113: 'F2', | |
114: 'F3', | |
115: 'F4', | |
116: 'F5', | |
117: 'F6', | |
118: 'F7', | |
119: 'F8', | |
120: 'F9', | |
121: 'F10', | |
122: 'F11', | |
123: 'F12' | |
} | |
ShortcutKey.prototype.skeys = { | |
8: 'BS', | |
10: 'Enter', | |
13: 'Enter', | |
32: 'SPC' | |
} | |
ShortcutKey.prototype.mkeys = { | |
'altKey' : 'A', | |
'ctrlKey' : 'C', | |
'metaKey' : 'M', | |
'shiftKey' : 'S' | |
} | |
ShortcutKey.prototype.init = function(win) { | |
var self = this; | |
win.addEventListener('keydown', function(evt) { | |
var key = self.get(evt); | |
var inputReg = /^(?:input|textarea)$/; | |
self.list.forEach(function(a) { | |
if (a.key == key && (a.element == evt.target || a.element == evt.view) && !inputReg.test(evt.target.nodeName.toLowerCase())) { | |
a.func(); | |
} | |
}); | |
}, false); | |
} | |
ShortcutKey.prototype.add = function(elm, key, func) { | |
this.list.push( | |
{ | |
'element' : elm, | |
'key' : key, | |
'func' : func | |
}); | |
} | |
ShortcutKey.prototype.get = function(evt) { | |
var key = [], k = ''; | |
for (mk in this.mkeys) { | |
if (evt[mk]) | |
key.push(this.mkeys[mk]); | |
} | |
if (evt.which) { | |
k = this.keys[evt.which] || String.fromCharCode(evt.which).toLowerCase(); | |
key.push(key.length ? '-' + k : k); | |
} else if (evt.keyCode) { | |
k = this.keys[evt.keyCode]; | |
key.push(key.length ? '-' + k : k); | |
} | |
return key.join(""); | |
} | |
// フレームパネルの作成 | |
function makeFrame(callback/*(iframeTag, window, document)*/, name) { | |
function testInvasion() { | |
iframe.removeEventListener("load", done, true); | |
var message = ((new Date) - load.start) + "ms passed, "; | |
try { // probe for security violation error, in case mozilla struck a bug | |
var url = unsafeWindow.frames[framename].location.href; | |
message += url == "about:blank" ? "but we got the right document." : "and we incorrectly loaded " + url; | |
done(); | |
} | |
catch(e) { | |
document.body.removeChild(iframe); | |
makeFrame(callback, name); | |
} | |
} | |
function done() { | |
clearTimeout(load.timeout); | |
var win = iframe.contentWindow | |
var doc = iframe.contentWindow.document; | |
// 自分自身のiframeを閉じるボタン | |
var xImg = document.createElement("img"); | |
xImg.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAATElEQVQoka2RSQ4AIAgD+f+jp96M0aq49AgdUiB0qZCkONQ/EBAwDOrrU7A1uZqN2hodtNwRqNdz0VOg62+jzuDUcVzkf+/I6h28UQHjW25Gob5AIAAAAABJRU5ErkJggg==" | |
xImg.setAttribute("onclick", "document.getElementsByName(" + esframeName + ")[0].style.display='none';"); | |
xImg.setAttribute("style", "background-color:red;border:3px;position:fixed;top:0px;right:0px;z-index:9999;"); | |
doc.body.appendChild(xImg); | |
callback(iframe, win, doc); | |
} | |
var iframe = document.createElement("iframe"); | |
var framename = iframe.name = typeof name != "undefined" ? name : ("pane" + (makeFrame.id = (makeFrame.id || 0) - 1)); | |
iframe.setAttribute("style", "overflow:auto;z-index:1001; border:0; margin:0; padding:0;top:0; bottom:0; left:0;"); | |
iframe.src = "about:blank"; | |
iframe.addEventListener("load", done, true); | |
var frames = makeFrame.data || {}; | |
var load = frames[framename] || { | |
start: new Date, | |
sleepFor: 400 | |
}; | |
load.timeout = setTimeout(testInvasion, load.sleepFor); | |
load.sleepFor *= 1.5; | |
frames[framename] = load; | |
makeFrame.data = frames; | |
// 苦し紛れのエスケープ | |
var esframeName = "'" + framename + "'"; | |
document.body.appendChild(iframe); | |
} | |
// CSS装飾 | |
var readPanel = { | |
iframe : null, | |
doc : null, | |
getCss: function() { | |
return String(<> | |
<![CDATA[ | |
#tFocus{ | |
margin-left:auto!important; | |
margin-right:auto!important; | |
background-color:#FFFFE0; | |
color:#222222; | |
line-height:24px; | |
font-size:16px!important; | |
padding:1.2em 1.5em 1.5em!important; | |
left:auto; | |
width:40em!important; | |
overflow:auto; | |
position:relative; | |
z-index:999; | |
} | |
]]></>); | |
}, | |
create: function(ele) { | |
makeFrame(function(iframe, win, doc) { | |
readPanel.iframe = iframe; | |
readPanel.doc = doc; | |
readPanel.isShow = true; | |
iframe.width = iframe.height = "100%"; | |
iframe.style.width = "100%"; | |
iframe.style.position = "fixed"; | |
readPanel.hideListen(win); | |
ele.setAttribute("id", 'tFocus'); | |
readPanel.addCSS(doc, readPanel.getCss()); | |
doc.body.appendChild(ele); | |
doc.body.focus(); | |
}, "tFocus"); | |
}, | |
hideListen : function(win) { | |
win.addEventListener("keypress", function(e) { | |
var esc = (e.keyCode == 27); | |
if (esc) { | |
readPanel.toggle(); | |
} | |
}, true); | |
var shortcut_iframe = new ShortcutKey(win); | |
shortcut_iframe.add(win, SHORTCUT_KEY, function(evt) { | |
readPanel.toggle(); | |
}); | |
}, | |
show:function () { | |
readPanel.isShow = true; | |
readPanel.iframe.style.display = "block"; | |
readPanel.doc.body.focus(); | |
}, | |
hide:function () { | |
readPanel.isShow = false; | |
readPanel.iframe.style.display = "none"; | |
document.body.focus(); | |
}, | |
toggle :function(ele) { | |
if (readPanel.iframe) { | |
if (readPanel.isShow) { | |
this.hide(); | |
} else { | |
this.show(); | |
} | |
} | |
}, | |
addCSS : function(context, css) { | |
if (!context) context = document; | |
if (context.createStyleSheet) { // for IE | |
var sheet = context.createStyleSheet(); | |
sheet.cssText = css; | |
return sheet; | |
} else { | |
var sheet = context.createElement('style'); | |
sheet.type = 'text/css'; | |
var _root = context.getElementsByTagName('head')[0] || context.documentElement; | |
sheet.textContent = css; | |
return _root.appendChild(sheet).sheet; | |
} | |
} | |
} | |
/** | |
* Document構造分析 | |
*/ | |
var main = function() { | |
this.init.apply(this, arguments); | |
} | |
main.prototype.init = function(doc) { | |
this.document = this.extractDocument(doc); | |
this.mainNode; | |
if (this.document) { | |
this.isDocument = true; | |
this.mainNode = this.document.content.asNode().cloneNode(true); | |
} else { | |
this.isDocument = false; | |
} | |
} | |
// Documentの構造分析 | |
main.prototype.extractDocument = function(doc) { | |
if (!this.document) { | |
var ex = new ExtractContentJS.LayeredExtractor(); | |
ex.addHandler(ex.factory.getHandler('Heuristics')); | |
var res = ex.extract(doc); | |
if (res) { | |
return res; | |
} else { | |
return false; | |
} | |
} else { | |
return this.document; | |
} | |
} | |
// nodeを同じ大きさの空白ノードと置き換える。 | |
main.prototype.replaceNode = function(node) { | |
var div = document.createElement("div"); | |
div.id = "dummy_node"; | |
div.style.width = this.mainNode.clientWidth; | |
div.style.height = this.mainNode.clientHeight; | |
this.mainNode.parentNode.replaceChild(div, this.mainNode); | |
} | |
// ショートカットの定義 | |
var shortcut = new ShortcutKey(); | |
shortcut.add(window, SHORTCUT_KEY, function(evt) { | |
if (readPanel.iframe) { | |
readPanel.toggle(); | |
} else { | |
var res = new main(document); | |
if (res.isDocument) { | |
readPanel.create(res.mainNode); | |
} | |
} | |
}); | |
// DEBUG - true | |
function log(m) { | |
if (typeof DEBUG != 'undefined' && DEBUG) { | |
if (unsafeWindow.console) { | |
unsafeWindow.console.log.apply(this, arguments); | |
} else { | |
console.log.apply(this, arguments); | |
} | |
} | |
} | |
})(document); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment