I[★]
@@ -2,24 +2,33 @@
* @title greed quote star feat. Proxy
* @description 引用になってなくても引用スターできるようにします
* @include http://*
- * @license MIT License
+ * @include https://*
+ * @contributor Hatena inc. https://s.hatena.ne.jp/images/add.gif
+ * @contributor a-kuma3 http://let.hatelabo.jp/a-kuma3/let/hJmc_YyG8sE-
+ * @nitpicker noromanba
+ * @license MIT License https://opensource.org/licenses/MIT
* @javascript_url
*/
+
(() => {
+ 'use strict';
+
// make star add button's color gold
function change_button_color(img) {
// change color with canvas
// https://developer.mozilla.org/ja/docs/Web/Guide/HTML/Canvas_tutorial/Pixel_manipulation_with_canvas
let canvas;
- document.querySelectorAll('img.hatena-star-add-button[src*="s.hatena.ne.jp"').forEach(target => {
+ document.body.querySelectorAll([
+ 'img.hatena-star-add-button[src*="s.hatena.ne.jp"]',
+ ]).forEach(button => {
if (! canvas) {
- canvas = Object.assign(document.createElement("canvas"), {
+ canvas = Object.assign(document.createElement('canvas'), {
width: img.width,
height: img.height,
});
- let ctx = canvas.getContext('2d');
+ const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
- let imageData = ctx.getImageData(0, 0, img.width, img.height);
+ const imageData = ctx.getImageData(0, 0, img.width, img.height);
let data = imageData.data;
for (let i = 0 ; i < data.length ; i += 4) {
if (data[i] < 200) {
@@ -32,35 +41,35 @@
}
ctx.putImageData(imageData, 0, 0);
}
- target.src = canvas.toDataURL();
- target.title = target.title + " (force quote)";
+ button.src = canvas.toDataURL();
+ button.title = button.title + ' (force quote)';
});
}
- document.body.appendChild(Object.assign(document.createElement("img"), {
- // http://s.hatena.ne.jp/images/add.gif
+ document.body.appendChild(Object.assign(document.createElement('img'), {
+ // https://s.hatena.ne.jp/images/add.gif
+ // XXX check term of use
src: 'data:image/gif;base64,R0lGODlhEAAQAIABALrJ9f///yH5BAEAAAEALAAAAAAQABAAAAIojI+pm+APYQCIMlfZtLOvSEkexhmchXkjaHYlGpLpqrZNqbngnvd+AQA7',
// https://stackoverflow.com/questions/17035106/context-getimagedata-operation-is-insecure
- crossOrigin: "anonymous",
- onload: function() {
+ crossOrigin: 'anonymous',
+ onload() {
change_button_color(this);
},
}));
-
// http://q.hatena.ne.jp/1487227736#a1262105
- function convert_numeric_reference_quote(url /* string */) {
+ function convert_numeric_reference_quote(url_string) {
// https://developer.mozilla.org/en-US/docs/Web/API/URL
// https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
- const u = new URL(url); /* string -> URL */
- let param = u.searchParams; /* URLSearchParams */
- let quote = param.get("quote");
+ const url = new URL(url_string);
+ const param = url.searchParams;
+ let quote = param.get('quote');
if (quote) {
// to numeric reference
quote = (s => {
- let o = "", i = 0;
+ let o = '', i = 0;
while (i < s.length) {
- let code = s.codePointAt(i);
+ const code = s.codePointAt(i);
o += code < 128 ? String.fromCharCode(code) : `&#${code};`;
i += 1;
if (code > 0xffff) { // for surrogate pair
@@ -69,29 +78,28 @@
}
return o;
})(quote);
- param.set("quote", quote);
- u.search = "?" + param.toString();
- url = u.href;
+ param.set('quote', quote);
+ url_string = url.href;
}
- return url;
+ return url_string;
}
- const re_addstar = new RegExp(String.raw`^https?://s\.hatena\.ne\.jp/star\.add\.json`);
+ const Ten = window.Ten;
+ if (!Ten) return;
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
Ten.JSONP = new Proxy(Ten.JSONP, {
construct: (target, args) => {
+ const re_addstar = /^https?:\/\/s\.hatena\.ne\.jp\/star\.add\.json/;
let url = args[0];
if (re_addstar.test(url)) {
url = convert_numeric_reference_quote(url);
args[0] = url;
}
- let obj = Reflect.construct(target, args);
- return obj;
+ return Reflect.construct(target, args);
},
});
})();
-
/*
* @title greed quote star feat. Proxy
* @description 引用になってなくても引用スターできるようにします
* @include http://*
* @include https://*
* @contributor Hatena inc. https://s.hatena.ne.jp/images/add.gif
* @contributor a-kuma3 http://let.hatelabo.jp/a-kuma3/let/hJmc_YyG8sE-
* @nitpicker noromanba
* @license MIT License https://opensource.org/licenses/MIT
* @javascript_url
*/
(() => {
'use strict';
// make star add button's color gold
function change_button_color(img) {
// change color with canvas
// https://developer.mozilla.org/ja/docs/Web/Guide/HTML/Canvas_tutorial/Pixel_manipulation_with_canvas
let canvas;
document.body.querySelectorAll([
'img.hatena-star-add-button[src*="s.hatena.ne.jp"]',
]).forEach(button => {
if (! canvas) {
canvas = Object.assign(document.createElement('canvas'), {
width: img.width,
height: img.height,
});
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
const imageData = ctx.getImageData(0, 0, img.width, img.height);
let data = imageData.data;
for (let i = 0 ; i < data.length ; i += 4) {
if (data[i] < 200) {
// gold : rgb(255,215,0)
data[i] = 255; // red
data[i + 1] = 215; // green
data[i + 2] = 0; // blue
// data[i + 3] = 255; // opacity
}
}
ctx.putImageData(imageData, 0, 0);
}
button.src = canvas.toDataURL();
button.title = button.title + ' (force quote)';
});
}
document.body.appendChild(Object.assign(document.createElement('img'), {
// https://s.hatena.ne.jp/images/add.gif
// XXX check term of use
src: 'data:image/gif;base64,R0lGODlhEAAQAIABALrJ9f///yH5BAEAAAEALAAAAAAQABAAAAIojI+pm+APYQCIMlfZtLOvSEkexhmchXkjaHYlGpLpqrZNqbngnvd+AQA7',
// https://stackoverflow.com/questions/17035106/context-getimagedata-operation-is-insecure
crossOrigin: 'anonymous',
onload() {
change_button_color(this);
},
}));
// http://q.hatena.ne.jp/1487227736#a1262105
function convert_numeric_reference_quote(url_string) {
// https://developer.mozilla.org/en-US/docs/Web/API/URL
// https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
const url = new URL(url_string);
const param = url.searchParams;
let quote = param.get('quote');
if (quote) {
// to numeric reference
quote = (s => {
let o = '', i = 0;
while (i < s.length) {
const code = s.codePointAt(i);
o += code < 128 ? String.fromCharCode(code) : `&#${code};`;
i += 1;
if (code > 0xffff) { // for surrogate pair
i += 1;
}
}
return o;
})(quote);
param.set('quote', quote);
url_string = url.href;
}
return url_string;
}
const Ten = window.Ten;
if (!Ten) return;
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
Ten.JSONP = new Proxy(Ten.JSONP, {
construct: (target, args) => {
const re_addstar = /^https?:\/\/s\.hatena\.ne\.jp\/star\.add\.json/;
let url = args[0];
if (re_addstar.test(url)) {
url = convert_numeric_reference_quote(url);
args[0] = url;
}
return Reflect.construct(target, args);
},
});
})();
- Permalink
- このページへの個別リンクです。
- RAW
- 書かれたコードへの直接のリンクです。
- Packed
- 文字列が圧縮された書かれたコードへのリンクです。
- Userscript
- Greasemonkey 等で利用する場合の .user.js へのリンクです。
- Loader
- @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
- Metadata
- コード中にコメントで @xxx と書かれたメタデータの JSON です。