非公開 TxRxs

    @@ -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 です。

History

  1. 2022/01/03 03:19:45 - 2022-01-03
  2. 2018/07/25 07:58:22 - 2018-07-25
  3. 2018/07/24 09:11:46 - 2018-07-24
  4. 2018/07/24 09:10:04 - 2018-07-24
  5. 2018/07/23 06:29:05 - 2018-07-23
  6. 2018/07/22 08:20:30 - 2018-07-22
  7. 2018/07/22 08:16:36 - 2018-07-22
  8. 2018/05/31 00:33:21 - 2018-05-31
  9. 2018/05/31 00:32:16 - 2018-05-31
  10. 2018/05/30 07:50:21 - 2018-05-30
  11. 2018/05/19 17:41:09 - 2018-05-19
  12. 2018/05/19 17:35:13 - 2018-05-19
  13. 2018/05/19 17:22:58 - 2018-05-19
  14. 2018/05/11 05:48:13 - 2018-05-11
  15. 2018/05/11 05:16:41 - 2018-05-11
  16. 2018/05/11 05:08:50 - 2018-05-11