I[★]

    @@ -11,34 +11,51 @@ // TBD .com handling // TBC spec and behavior + +// e.g. +// http://let.hatelabo.jp/noromanba/let/hLHU9eKAqvUD +// https://s.hatena.ne.jp/mobile/entry?uri=http%3A%2F%2Flet.hatelabo.jp%2Fnoromanba%2Flet%2FhLHU9eKAqvUD (() => { 'use strict'; - document.body.querySelectorAll([ - 'img.hatena-star-add-button[src*="s.hatena.ne.jp"]', - ]).forEach(button => { - // https://developer.mozilla.org/en-US/docs/Web/CSS/filter - // NOTE order sensitive - button.style.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 - // - // gold | rgb(255,215,0) | hex #ffd700 - 'invert(74%)', - 'sepia(56%)', - 'saturate(811%)', - 'hue-rotate(0deg)', - 'brightness(106%)', - 'contrast(103%)', - ].join(' '); + const change_star_icon_attr = (ctx) => { + ctx.querySelectorAll([ + 'img.hatena-star-add-button[src*="s.hatena.ne.jp"]', + ]).forEach(button => { + // https://developer.mozilla.org/en-US/docs/Web/CSS/filter + // NOTE order sensitive and multi effective + button.style.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(' '); - button.title += ' (force quote)'; - }); + button.alt = button.title = 'Add Star (force quote)'; + }); + }; + change_star_icon_attr(document.body); + + // infinite scrolling + // TBD use Proxy/Reflect, slightly speedup and completely capsulization + new MutationObserver(records => { + records.forEach(record => { + change_star_icon_attr(record.target); + }); + }).observe(document.body, { childList: true, subtree: true }); // http://q.hatena.ne.jp/1487227736#a1262105 const to_numeric_reference = (str) => { @@ -55,6 +72,7 @@ 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 @@ -64,7 +82,6 @@ } const safed = to_numeric_reference(quote); - url.searchParams.set('quote', safed); return url.href; @@ -84,6 +101,8 @@ return Reflect.construct(target, args); }, }); - + // TBD quote handling when delete + // https://s.hatena.ne.jp/star.delete.json + // https://s.hatena.ne.jp/star.deletable.json })();
  • /*
     * @title I[★]
     * @description greedy quoted 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/hLHU9eKAqvUD
    //  https://s.hatena.ne.jp/mobile/entry?uri=http%3A%2F%2Flet.hatelabo.jp%2Fnoromanba%2Flet%2FhLHU9eKAqvUD
    (() => {
        'use strict';
    
        const change_star_icon_attr = (ctx) => {
            ctx.querySelectorAll([
                'img.hatena-star-add-button[src*="s.hatena.ne.jp"]',
            ]).forEach(button => {
                // https://developer.mozilla.org/en-US/docs/Web/CSS/filter
                // NOTE order sensitive and multi effective
                button.style.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(' ');
    
                button.alt = button.title = 'Add Star (force quote)';
            });
        };
        change_star_icon_attr(document.body);
    
        // infinite scrolling
        // TBD use Proxy/Reflect, slightly speedup and completely capsulization
        new MutationObserver(records => {
            records.forEach(record => {
                change_star_icon_attr(record.target);
            });
        }).observe(document.body, { childList: true, subtree: true });
    
        // 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>, <CALLBACK>, <HTTP_METHOD>)
        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
        // https://s.hatena.ne.jp/star.delete.json
        //  https://s.hatena.ne.jp/star.deletable.json
    })();
    
    
  • Permalink
    このページへの個別リンクです。
    RAW
    書かれたコードへの直接のリンクです。
    Packed
    文字列が圧縮された書かれたコードへのリンクです。
    Userscript
    Greasemonkey 等で利用する場合の .user.js へのリンクです。
    Loader
    @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
    Metadata
    コード中にコメントで @xxx と書かれたメタデータの JSON です。

History

  1. 2018/06/14 09:52:29 - 2018-06-14
  2. 2018/06/14 08:17:15 - 2018-06-14
  3. 2018/06/14 08:06:46 - 2018-06-14
  4. 2018/06/14 07:57:46 - 2018-06-14
  5. 2018/06/14 07:01:51 - 2018-06-14
  6. 2018/06/14 04:57:55 - 2018-06-14
  7. 2018/06/12 09:02:29 - 2018-06-12
  8. 2018/06/12 08:48:28 - 2018-06-12
  9. 2018/06/12 02:29:25 - 2018-06-12
  10. 2018/06/11 08:22:32 - 2018-06-11
  11. 2018/06/11 08:21:40 - 2018-06-11