TxRxs
by
noromanba
2022-01-03 [2022/01/03 03:19:45]
replace http to https
@@ -1,185 +1,54 @@
/*
- * @title H::H -spam
- * @description Hatena Haiku spam filter
- * @include *://h.hatena.ne.jp/*
- * @license The MIT License https://opensource.org/licenses/MIT
+ * @title TxRxs
+ * @description replace http to https
+ * @include http://*
+ * @include https://*
+ * @license MIT License https://opensource.org/licenses/MIT
* @javascript_url
+ * @private WIP
*/
-// nitpicking via
-// http://let.hatelabo.jp/austinburk/let/hLHU6PPgg9Ya
-// Proxy/Reflect ver
-// http://let.hatelabo.jp/a-kuma3/let/hJmc7ZTR7vBO
-
-// UserScript
-// https://gist.github.com/noromanba/e485c35ffba606ae8ecacac2c9a8da3c
-// https://gist.github.com/noromanba/e485c35ffba606ae8ecacac2c9a8da3c/raw/hatenahaiku-spam-filter.user.js
-
-
-// TODO
-// - handle "Related/Hot Keywords"
-// - http://let.hatelabo.jp/noromanba/let/hLHVltCFk5dw
-
-// non i18n similar services/software by id:tukihatu c.f.
-// Hatena Haiku a la mode (3rd party web services)
-// http://hh-alamode.fanweb.jp
-// http://h.hatena.ne.jp/target?word=%E3%81%AF%E3%81%A6%E3%81%AA%E3%83%8F%E3%82%A4%E3%82%AF%E3%82%A2%E3%83%A9%E3%83%A2%E3%83%BC%E3%83%89
-// Hatena Haiku Soldier (Chrome/ium Extensions)
-// https://chrome.google.com/webstore/detail/hhgejafgjjjfaocaopajkhgmdgaeimin
-// http://h.hatena.ne.jp/target?word=%E3%81%AF%E3%81%A6%E3%81%AA%E3%83%8F%E3%82%A4%E3%82%AF%E3%82%BD%E3%83%AB%E3%82%B8%E3%83%A3%E3%83%BC
-
-// e.g.
-// http://h.hatena.ne.jp
-(async () => {
- 'use strict';
-
- if (window.self !== window.top) return; // @noframes in Vanilla
-
- // timeout
- // https://gist.github.com/noromanba/7e76cd75d15e27b102007298a8156d8f
- // TBD Promise based functionize
- const controller = new AbortController();
- const signal = controller.signal;
- const TIMEOUT = 1000 * 10;
- signal.onabort = () => {
- console.error(`timeout: ${ TIMEOUT / 1000 } sec elapsed`);
- };
- const timer = setTimeout(() => controller.abort(), TIMEOUT);
-
- // Access-Control-Allow-Origin: http://h.hatena.ne.jp
- const USER_FILTER = 'https://haikuantispam.lightni.ng/api/recent_scores.json';
- // TBD CORS proxy c.f.
- // http://let.hatelabo.jp/noromanba/let/hJmc7rWIvsJj
- // for avoid web-beacon/bug and fingerprinting like risks
- // https://hacks.mozilla.org/2016/03/referrer-and-cache-control-apis-for-fetch/
- // https://html.spec.whatwg.org/#cors-settings-attributes
- const request = new Request(USER_FILTER, {
- // https://fetch.spec.whatwg.org/#request-headers
- // https://html.spec.whatwg.org/#initialise-the-document-object
- cache: 'no-cache',
- credentials: 'omit',
- mode: 'cors',
- // Referrer-Policy fallback
- referrer: '',
- // [^1] Referrer-Policy
- // https://developer.mozilla.org/en-US/docs/Web/API/Request/referrerPolicy
- // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
- referrerPolicy: 'no-referrer',
- signal,
- });
+(() => {
+ 'use strict';
- class ConnectionError extends Error {
- constructor(msg) {
- super(msg);
- this.name = this.constructor.name;
- }
- }
- class TimeoutError extends ConnectionError { }
-
- // TBD
- // - refresh filter when infinite scrolling
- // - small IIFE async scope
- // - try-catch-finally w/ await
- const blacklist = await fetch(request).then(res => {
- if (!res.ok || res.status !== 200) {
- // TBD Custom Error
- return Promise.reject(new Error([
- res.status, res.statusText, res
- ]));
- }
- return res.json();
- }).catch(err => {
- if (signal.aborted) {
- return Promise.reject(new TimeoutError(err));
- }
- // http://isup.me
- const isup = 'https://downforeveryoneorjustme.com/';
- return Promise.reject(new ConnectionError([
- 'check a network, location and server',
- isup + new URL(USER_FILTER).hostname,
- ].join('\n')));
- }).then(json => {
- const SPAM_THRESHOLD = 5;
- return new Map(
- Object.entries(json).filter(([, score]) => score >= SPAM_THRESHOLD)
- );
- }).catch(err => {
- console.error([
- 'Hatena::Haiku spam filter',
- err,
- //err.stack,
- ].join('\n'));
- }).finally(() => {
- clearTimeout(timer);
+ const wipe = (ctx) => {
+ ctx.querySelectorAll([
+ 'a[href^="http:"]',
+ ]).forEach(link => {
+ //*
+ link.protocol = 'https:';
+
+ alert(link.href.trim())
+ alert(link.textContent.trim())
+
+ if (link.href.trim() === link.textContent.trim()) {
+ link.textContent = link.href;
+ }
+ /*
+ const s = new URL(link.href);
+ s.href.protocol = 'https:';
+ s.href = s.href.trim();
+
+ if (link.href.trim() === link.textContent.trim()) {
+ link.textContent = s.href;
+ }
+
+ link.href = s.href;
+ */
+ });
+ };
+
+ wipe(document.body);
+
+ new MutationObserver(records => {
+ records.forEach(record => {
+ wipe(record.target);
});
- console.debug(blacklist);
-
- if (!blacklist || blacklist.size === 0) return;
-
- // TBD show indicator/throbber when wiping
- const wipeout = (ctx) => {
- if (!ctx.querySelectorAll) return;
-
- ctx.querySelectorAll([
- '.entry.tl-entry',
- ]).forEach(entry => {
- // permalink syntax;
- // <a href="http://h.hatena.ne.jp/{HATENA_ID}/" title="id:{HATENA_ID}">{SCREEN_NAME}</a>
- const poster = entry.querySelector('.username a[href][title^="id:"]');
- if (!poster) return;
-
- const id = poster.title.slice('id:'.length);
- if (blacklist.has(id)) {
- const USER_RECENT_STATS = 'https://haikuantispam.lightni.ng/id/';
- /*/
- entry.style.backgroundColor = 'red';
- entry.querySelectorAll([
- '.entry-body-content a[href]',
- ]).forEach(link => {
- link.style.pointerEvents = 'none';
- });
- /*/
- // TBD suppress Reflow/Layout
- entry.style.display = 'none';
- //entry.remove();
- // TODO reduce same users or other methods c.f.
- // https://developer.mozilla.org/en-US/docs/Web/API/Console
- //console.table({
- // id,
- // score: blacklist.get(id),
- // detail: USER_RECENT_STATS + id,
- //});
- console.warn([
- 'id:' + id,
- 'score: ' + blacklist.get(id),
- 'detail: ' + USER_RECENT_STATS + id,
- ].join('\t'));
- //*/
- }
- });
- };
- const timeline = document.body.querySelector('.entries');
- if (!timeline) return;
-
- wipeout(timeline);
-
- new MutationObserver(records => {
- records.forEach(record => {
- wipeout(record.target);
- });
- }).observe(timeline, { childList: true, subtree: true, });
+ }).observe(document.body, {
+ childList: true,
+ subtree: true,
+ });
})();
-// DEV
-//
-// [1]: Referrer-Policy
-// specs
-// https://w3c.github.io/webappsec-referrer-policy/#referrer-policies
-// https://fetch.spec.whatwg.org/#concept-request-referrer-policy
-//
-// test servers
-// https://api.github.com
-// https://httpstat.us
-// https://httpstat.us/404
-// https://httpstat.us/200?sleep=60000
+/* from *dumb* phone */
/*
* @title TxRxs
* @description replace http to https
* @include http://*
* @include https://*
* @license MIT License https://opensource.org/licenses/MIT
* @javascript_url
* @private WIP
*/
(() => {
'use strict';
const wipe = (ctx) => {
ctx.querySelectorAll([
'a[href^="http:"]',
]).forEach(link => {
//*
link.protocol = 'https:';
alert(link.href.trim())
alert(link.textContent.trim())
if (link.href.trim() === link.textContent.trim()) {
link.textContent = link.href;
}
/*
const s = new URL(link.href);
s.href.protocol = 'https:';
s.href = s.href.trim();
if (link.href.trim() === link.textContent.trim()) {
link.textContent = s.href;
}
link.href = s.href;
*/
});
};
wipe(document.body);
new MutationObserver(records => {
records.forEach(record => {
wipe(record.target);
});
}).observe(document.body, {
childList: true,
subtree: true,
});
})();
/* from *dumb* phone */
- Permalink
- このページへの個別リンクです。
- RAW
- 書かれたコードへの直接のリンクです。
- Packed
- 文字列が圧縮された書かれたコードへのリンクです。
- Userscript
- Greasemonkey 等で利用する場合の .user.js へのリンクです。
- Loader
- @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
- Metadata
- コード中にコメントで @xxx と書かれたメタデータの JSON です。