I[★] Fork

  • /*
     * @title I[★]
     * @description greedy quote Hatena Star
     * @include http://*
     * @include https://*
     * @contributor a-kuma3     http://let.hatelabo.jp/a-kuma3/let/hJmc_YyG8sE-
     * @nitpicker   noromanba
     * @license     MIT License https://opensource.org/licenses/MIT
     * @javascript_url
     */
    
    // TBD .com handling
    // TBC spec and behavior
    
    // e.g.
    // http://let.hatelabo.jp/noromanba/let/hJmc_7WUiuhh
    //  https://s.hatena.ne.jp/mobile/entry?uri=http%3A%2F%2Flet.hatelabo.jp%2Fnoromanba%2Flet%2FhJmc_7WUiuhh
    (() => {
        'use strict';
    
        const add_style = (() => {
            const wall = document.head || document.body || document.documentElement;
    
            const style = wall.appendChild(Object.assign(document.createElement('style'), {
                type: 'text/css',
                charset: 'utf-8',
            }));
    
            return (css) => {
                style.appendChild(document.createTextNode(css + '\n'));
            };
        })();
    
        add_style([
            'img.hatena-star-add-button[src*="s.hatena.ne.jp"] {',
            // https://developer.mozilla.org/en-US/docs/Web/CSS/filter
            // NOTE order sensitive and multi effective
            'filter:',
            // reset to black
            'grayscale(1) brightness(0)',
            // w/ black to hex CSS filter generator by Barrett Sonntag c.f.
            //  https://codepen.io/sosuke/pen/Pjoqqp
            //   https://codepen.io/sosuke/pen/Pjoqqp/license
            // via
            //  https://gist.github.com/barretts/e90d7e5251f36b183c67e02ba54c9ae1
            //
            // same as star-comment activated color
            // http://s.hatena.ne.jp/images/comment_active.gif
            // rgb(251, 208, 148) | #fbd094
            'invert(80%)',
            'sepia(60%)',
            'saturate(312%)',
            'hue-rotate(333deg)',
            'brightness(100%)',
            'contrast(98%)',
            '}',
        ].join(' '));
    
        // http://q.hatena.ne.jp/1487227736#a1262105
        const to_numeric_reference = (str) => {
            let letter = '', i = 0;
            while (i < str.length) {
                const code = str.codePointAt(i);
                letter += code < 128 ? String.fromCharCode(code) : `&#${code};`;
                i += 1;
                // for surrogate pair
                if (code > 0xffff) {
                    i += 1;
                }
            }
            return letter;
        };
    
        // http://q.hatena.ne.jp/1487227736#a1262105
        const enforce_quote = (url_string) => {
            const url = new URL(url_string);
            // https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
            const quote = url.searchParams.get('quote');
            if (!quote) {
                return url_string;
            }
    
            const safed = to_numeric_reference(quote);
            url.searchParams.set('quote', safed);
    
            return url.href;
        };
    
        // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
        // https://s.hatena.ne.jp/js/HatenaStar.js:111
        //      Ten.JSONP(<URL_STRING>, <JSON_CALLBACK> [,<METHOD_NAME>])
        window.Ten.JSONP = new Proxy(window.Ten.JSONP, {
            construct: (target, args) => {
                const url_string = args[0];
    
                if (url_string.includes('//s.hatena.ne.jp/star.add.json')) {
                    args[0] = enforce_quote(url_string);
                }
    
                return Reflect.construct(target, args);
            },
        });
        // TBD quote handling when delete surrogates from normal UI
        // https://s.hatena.ne.jp/star.delete.json
        //  https://s.hatena.ne.jp/star.deletable.json
    })();
    
    // DEV
    //
    // perhaps fork of in 2017
    // http://let.hatelabo.jp/a-kuma3/let/hLHWycCUqaF_
    
    
  • Permalink
    このページへの個別リンクです。
    RAW
    書かれたコードへの直接のリンクです。
    Packed
    文字列が圧縮された書かれたコードへのリンクです。
    Userscript
    Greasemonkey 等で利用する場合の .user.js へのリンクです。
    Loader
    @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
    Metadata
    コード中にコメントで @xxx と書かれたメタデータの JSON です。