Last active
September 3, 2015 17:45
-
-
Save Milly/186367 to your computer and use it in GitHub Desktop.
pixiv to dynamic greasemonkey script
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 pixiv ajaxer | |
// @namespace http://d.hatena.ne.jp/MillyC/ | |
// @include http://www.pixiv.net/* | |
// @grant GM_addStyle | |
// @grant GM_xmlhttpRequest | |
// @author Milly | |
// @version 1.0.20130315 | |
// ==/UserScript== | |
var pixivAjaxer = { | |
defs : [ | |
// add illust bookmark | |
{ | |
href : /\bbookmark_add\.php\?.*\btype=illust\b/, | |
listener : function(target) { | |
GM_xmlhttpRequest({ | |
method : 'GET', | |
url : target.href, | |
onload : function(r) { | |
var html = r.responseText; | |
var form = pixivAjaxer.parseHtml(html, '//form[@action="bookmark_add.php"]'); | |
if (!form) return; | |
pixivAjaxer.loadStylesInHtml(html); | |
var win = pixivAjaxer.openWindow('bookmark_add', 'ブックマークに追加', form, 'tag'); | |
pixivAjaxer.loadScriptsInHtml(html); | |
pixivAjaxer.dispatchPage('bookmark_add'); | |
pixivAjaxer.dispatchPage('*/bookmark_add'); | |
pixivAjaxer.hookFormSubmit({ | |
form : form, | |
onsubmit : function() { win.close(); }, | |
onload : function(r) { | |
var html = r.responseText; | |
var content = pixivAjaxer.parseHtml(html, '//div[@id="content3"]/div[contains(@style,"border")]'); | |
if (!content) return; | |
content.style.width = ''; | |
var win = pixivAjaxer.openWindow('bookmark_add', 'ブックマークに追加', content); | |
} | |
}); | |
} | |
}); | |
} | |
} | |
], | |
init : function() { | |
window.addEventListener('click', pixivAjaxer.captureClick, true); | |
}, | |
captureClick : function(event) { | |
if (event.ctrlKey || event.altKey) return; | |
var link = pixivAjaxer.evaluateFirst('ancestor-or-self::a', event.target); | |
if (!link) return; | |
var href = link.getAttribute('href'); | |
if (!href) return; | |
for each (var def in pixivAjaxer.defs) { | |
if (href.match(def.href)) { | |
event.preventDefault(); | |
event.stopPropagation(); | |
def.listener(link); | |
break; | |
} | |
} | |
}, | |
initStyle : function() { | |
pixivAjaxer.initStyle = function() {}; | |
GM_addStyle([ | |
'.pixivajaxer-window {', | |
'position: absolute;', | |
'background: white;', | |
'border: 1px solid #88a;', | |
'padding: 0;', | |
'z-index: 11000000;', | |
'}', | |
'.pixivajaxer-window > h2 {', | |
'text-align: center;', | |
'line-height: 1.5em;', | |
'font-weight: bold;', | |
'}', | |
'.pixivajaxer-window > a {', | |
'position: absolute;', | |
'top: 0;', | |
'right: 0;', | |
'width: 1.5em;', | |
'height: 1.5em;', | |
'line-height: 1.5em;', | |
'border-left: 1px solid #88a;', | |
'border-bottom: 1px solid #88a;', | |
'-moz-border-radius-bottomleft: 10px;', | |
'background-color: #88a;', | |
'color: #fff;', | |
'text-align: center;', | |
'font-weight: bold;', | |
'cursor: pointer;', | |
'}', | |
'.pixivajaxer-window > a:before {', | |
'content: "\xd7";', | |
'}', | |
'.pixivajaxer-window > a:hover {', | |
'text-decoration: none;', | |
'}', | |
'.pixivajaxer-window > p {', | |
'padding: 8px;', | |
'}' | |
].join('\n')); | |
}, | |
checkEvent : function(event) { | |
if (event.ctrlKey || event.altKey) return false; | |
event.preventDefault(); | |
event.stopPropagation(); | |
return true; | |
}, | |
parseHtml : function(text, xpath) { | |
var innerBody = (text.match(/<body(?=[\s>])[^>]*>(?:.|\n)*<\/body>/i) || {})[0]; | |
if (innerBody) { | |
var parent = document.createElement('div'); | |
parent.innerHTML = innerBody.replace(/<(no)?script(?:.|\n)*?<\/\1script>/ig, ''); | |
return pixivAjaxer.evaluateFirst(xpath, parent); | |
} | |
return false; | |
}, | |
evaluateFirst : function (xpath, base) { | |
return document.evaluate(xpath, base || document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; | |
}, | |
loadScriptsInHtml : function(text) { | |
var reg = /<script(?=(?:[^>]|\n)*\bsrc="([^"]*)")(?:[^>]|\n)*>(.|\n)*?<\/script>/img; | |
for (var m; m = reg.exec(text);) { | |
var src = decodeURI(m[1].replace('&', '&')); | |
var script = m[2]; | |
if (src) { | |
pixivAjaxer.loadScript(src); | |
} else if (false /* disabled */ && script) { | |
try { | |
with (unsafeWindow) { eval(script); } | |
} catch (e) {} | |
} | |
} | |
}, | |
loadStylesInHtml : function(text) { | |
var reg = /<link(?=(?:[^>]|\n)*\brel="stylesheet")(?=(?:[^>]|\n)*\bhref="([^"]*)")(?:[^>]|\n)*>/img; | |
for (var m; m = reg.exec(text);) { | |
var href = decodeURI(m[1].replace('&', '&')); | |
if (href) { | |
pixivAjaxer.loadStyle(href); | |
} | |
} | |
}, | |
loadScript : function(src) { | |
var options = options || {}; | |
var xpath = '//script[@src="' + src + '"]' | |
if (!pixivAjaxer.evaluateFirst(xpath)) { | |
var script = document.createElement('script'); | |
script.type = 'text/javascript'; | |
script.charet = 'UTF-8'; | |
script.src = src; | |
document.getElementsByTagName('head')[0].appendChild(script); | |
} | |
}, | |
loadStyle : function(href) { | |
var xpath = '//link[@href="' + href + '"]' | |
if (!pixivAjaxer.evaluateFirst(xpath)) { | |
var link = document.createElement('link'); | |
link.type = 'text/css'; | |
link.rel = 'stylesheet'; | |
link.href = href; | |
document.getElementsByTagName('head')[0].appendChild(link); | |
} | |
}, | |
openWindow : function(id, title, content, focus) { | |
pixivAjaxer.initStyle(); | |
// title bar | |
var titleBar = document.createElement('h2'); | |
titleBar.appendChild(document.createTextNode(title)); | |
// close button | |
var closeButton = document.createElement('a'); | |
closeButton.addEventListener('click', function(e) { e.preventDefault(); win.close(); }, false); | |
// content area | |
var contentArea = document.createElement('p'); | |
contentArea.appendChild(content); | |
// window box | |
var win = document.createElement('div'); | |
win.setAttribute('id', id); | |
win.setAttribute('class', 'pixivajaxer-window'); | |
win.addEventListener('keydown', function(e) { if (27 == e.keyCode) { win.close(); } }, true); | |
win.appendChild(titleBar); | |
win.appendChild(closeButton); | |
win.appendChild(contentArea); | |
// add methods | |
win.close = function() { document.body.removeChild(win); }; | |
// centering window | |
var doc = document.documentElement; | |
win.style.visibility = 'hidden'; | |
document.body.appendChild(win); | |
win.style.top = Math.round(doc.scrollTop + Math.max(0, (doc.clientHeight - win.offsetHeight) / 2)) + 'px'; | |
win.style.left = Math.round(doc.scrollLeft + Math.max(0, (doc.clientWidth - win.offsetWidth ) / 2)) + 'px'; | |
win.style.visibility = 'visible'; | |
// set focus | |
var focusElement = | |
focus && pixivAjaxer.evaluateFirst('.//input[@name="' + focus + '"]', win) | |
|| pixivAjaxer.evaluateFirst('.//input[not(@type="hidden")]|.//a[@href]', win); | |
if (focusElement && focusElement.focus) | |
focusElement.focus(); | |
return win; | |
}, | |
hookFormSubmit : function(options) { | |
var form = options.form; | |
var request = { | |
method : form.method || 'GET', | |
url : form.action, | |
headers : {} | |
}; | |
// build request | |
for (var opt in options) | |
request[opt] = options[opt]; | |
request.method = request.method.toUpperCase(); | |
if ('POST' == request.method) | |
request.headers['Content-type'] = 'application/x-www-form-urlencoded'; | |
form.addEventListener('submit', function(e) { | |
e.preventDefault(); | |
e.stopPropagation(); | |
if (request.onsubmit) | |
request.onsubmit.call(form, e); | |
// build form data | |
var data = []; | |
for (var i = 0; i < form.elements.length; ++i) { | |
var input = form.elements[i]; | |
if (('radio' == input.type || 'checkbox' == input.type) && !input.checked) continue; | |
data.push(encodeURI(input.name) + '=' + encodeURI(input.value)); | |
} | |
request.url = request.url.replace(/\?.*$/, ''); | |
if ('GET' == request.method) { | |
request.url += '?' + data.join('&'); | |
} else { | |
request.data = data.join('&'); | |
} | |
GM_xmlhttpRequest(request); | |
}, false); | |
}, | |
dispatchPage : function(name, params) { | |
var action = unsafeWindow.pixiv.page[name]; | |
if (action) action.call(unsafeWindow, params); | |
} | |
}; | |
pixivAjaxer.init(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment