Avoid losing a quote star
by
a-kuma3
2017-02-17 [2017/02/17 21:31:07]
人力検索などで引用スターに失敗するのを回避します。【注意】カラースターの対応ができてません (´・ω・`)
-
/*
* @title Avoid losing a quote star
* @description 人力検索などで引用スターに失敗するのを回避します。【注意】カラースターの対応ができてません (´・ω・`)
* @include http://*
* @include https://*
* @license MIT License
*/
/*
http://q.hatena.ne.jp/1487227736#a1262105
引用に失敗したっぽいときに
- もう一度試す(最初の空振りしたスターは消す)
- 引用は数値参照にする
*/
(() => {
const jsonp = (() => {
var count = 0;
return function(url, callback) {
var callbackName = 'akuma3_jsonp'+count++;
var script = document.createElement('script');
script.src = url.replace(/[=]\?(&|$)/g, '='+callbackName+'$1');
window[callbackName] = function(data) {
if (callback)
callback(data);
window[callbackName] = undefined;
try { delete window[callbackName]; } catch(e) {}
document.body.removeChild(script);
};
document.body.appendChild(script);
};
})();
const StarRequest = function(url) {
let a = url.split("?")
this.__api__ = a[0]
// parse parameter
a[1].split("&").forEach(s => {
let index = s.indexOf("=")
if (index != -1) {
let k = s.slice(0, index), v = s.slice(index + 1)
this[k] = v
} else {
// maybe timestamp
this.timestamp = s
}
})
// method
Object.assign(this, {
to_parameter_string: function(p) {
let a = [
"uri=" + this.uri,
"rks=" + this.rks,
"timestamp=" + new Date().getTime(),
]
for (k in p) {
a.push(k + "=" + p[k])
}
return a.join("&")
},
add_url: function(q) {
return this.__api__ + "?" + this.to_parameter_string({
title : this.title ,
quote : (q ? q : this.quote) ,
location : this.location ,
callback : "?",
})
},
del_url: function(name) {
return "http://s.hatena.ne.jp/star.delete.json?" + this.to_parameter_string({
name : encodeURIComponent(name),
})
},
do_callback: function(json) {
let func = new Function("a", this.callback + "(a)")
func.call(null, json)
},
numeric_reference_quote: function() {
let s = decodeURIComponent(this.quote)
let o = "", i = 0
while (i < s.length) {
let code = s.codePointAt(i)
if (code > 128) {
o += "&#" + code + ";"
if (code > 0xffff) { // for surrogate pair
i += 1
}
} else {
o += s.charAt(i)
}
i += 1
}
return encodeURIComponent(o)
},
})
}
const enhanced_add_star = (url) => {
const req = new StarRequest(url)
if (req.quote) {
jsonp(req.add_url(), (data) => {
if (data.quote == "") { // has quote, but lose it !
// remove no quote star
jsonp(req.del_url(encodeURIComponent(data.name)))
// retry and use numeric character reference
jsonp(req.add_url(req.numeric_reference_quote()), (data) => {
console.log("a-kuma3: repair quote star. ", data)
req.do_callback(data)
})
} else {
req.do_callback(data)
}
})
} else {
// no quote
jsonp(url)
}
}
const head = document.querySelector("head")
const re_add_star = /s\.hatena\.ne\.jp\/star\.add\.json\?/
head.appendChild = function(e) {
if (e.tagName == 'SCRIPT' && re_add_star.test(e.src)) {
enhanced_add_star(e.src)
} else {
// I believe e.nodeType == 1
e.appendChild.call(this, e)
}
}
})();
-
- Permalink
- このページへの個別リンクです。
- RAW
- 書かれたコードへの直接のリンクです。
- Packed
- 文字列が圧縮された書かれたコードへのリンクです。
- Userscript
- Greasemonkey 等で利用する場合の .user.js へのリンクです。
- Loader
- @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
- Metadata
- コード中にコメントで @xxx と書かれたメタデータの JSON です。