IT戦記

プログラミング、起業などについて書いているプログラマーのブログです😚

はてスタの引用をまとめる Greasemonkey を書きました。

このように

引用機能を使って伝えたいことを表現するときってありますよね><









でも、いちいちマウスを横に動かしてくのがプルプルするんです!プルプルするんです!

というわけで

以下のようにまとめてくれるグリモン書いた

ご自由にお使いください

// ==UserScript==
// @name           Quote Matome
// @namespace      http://d.hatena.ne.jp/amachang/
// @include        http://*
// ==/UserScript==

(function(f) {

    // Greasemonkey から prototype をいじるトリック
    unsafeWindow.location.href = 'javascript:(' + f + ')();void(0);' 

})(function() {

    // はてスタ使ってないページ
    if (!window.Hatena || !Hatena.Star) return;

    // uri から Hatena.Star.Entry のインスタンスを取得するための辞書
    Hatena.Star._entryMap = {};

    // Hatena.Star.Star の quote プロパティを _quote プロパティに変える
    Hatena.Star.EntryLoader.entries.forEach(function(e) {

        // ついでに辞書に登録
        Hatena.Star._entryMap[e.uri] = e;

        e.stars.forEach(function(s) {
            s._quote = s.quote;
            delete s.quote;
        });
    });

    // Hatena.Star.Star に quote セッターを作る
    Hatena.Star.Star.prototype.__defineSetter__('quote', function(quote) {
        return this._quote = quote;
    });

    // Hatena.Star.Star にゲッターを作る
    Hatena.Star.Star.prototype.__defineGetter__('quote', function() {

        // 自分自身が所属する Hatena.Star.Entry を取得する
        return Hatena.Star._entryMap[this.entry.uri].

                   // スターを取得
                   stars.

                   // 同じ名前のスターだけ抽出
                   filter(function(s) { return s.screen_name == this.screen_name }, this).

                   // 引用を持っているスターを抽出
                   filter(function(s) { return s._quote }).

                   // 引用文字の抽出
                   map(function(s) { return s._quote }).

                   // 結合
                   join(' ');
    });

});

Safari や Chrome ではてなスターの引用ができない問題が修正されたみたい。

ソースはこちら

http://s.hatena.ne.jp/js/HatenaStar.js
onmouseover で、コピーかー。そっかー。頭いいなあ。クリックの前にはマウスオーバーするもんなあ絶対。
勉強になりました。
hatena++

新ブックマークレットを使っていなくても、ブクマ時に画像を指定できるようにする方法

ブックマークレットでは

ブックマーク時に画像を指定できるみたいですね。

この右側の画像をクリックすると出来るみたいです。
詳しくは以下の「画像を設定・変更する」を参照
ブックマークレットの使い方 - はてなブックマークヘルプ
で、これが出来ると結構うれしいです

何がうれしいか

ホッテントリとかに出たときに以下のように画像も一緒に表示されるんです。

キャッチーな画像だとやっぱり読みたくなりますしね!

でも、新ブックマークレットじゃないとそれができない

><かなしい!
だって、自分もやりたいじゃないですか!

というわけで

ブックマークレットで出来るようにする方法を紹介します。
以下のように form#add-form 要素に image という名前の input 要素を作ってそこに画像の URL を書いて送信すればいいみたいです

(document.getElementById('add-form') || document.getElementById('bookmarklet-form')).appendChild(Ten.Element('input',{name:'image'}))

ブックマークレットにするなら

こんな感じで

javascript:(document.getElementById('add-form') || document.getElementById('bookmarklet-form')).appendChild(Ten.Element('input',{name:'image'})); void(0);

ぐりもんにするなら

こんな感じですかね

// (ぐりもんの定義、略)

var form = (document.getElementById('add-form') || document.getElementById('bookmarklet-form'));

if (form){
    form.appendChild(unsafeWindow.Ten.Element('input',{name:'image'}));
}

Safari や Google Chrome でもはてなスターで選択範囲を引用できるようにする Bookmarklet

今まで

Google Chrome ではてスタしても、選択範囲の引用ができなかった><

というわけで

ブックマークレット作った。
以下のブックマークレットを実行してから、テキストを選択して、はてスタすると引用できるようになる。

javascript:window._gs = window.getSelection; document.onselectstart = document.ondblclick = function() { window._s = _gs()+'' }; window.getSelection = function() { return window._s || '' }; void(0);

この方法だと、 getSelection を上書きしてるので、グリモン的に自動読み込みでやるのはお勧めしない。
もし、 HatenaStar.js を直すとしたら。 以下、

    // ハンドラーを定義
    handleSelection: function() {
        Ten.DOM._selectedText = getSelection()+'';
    },

    getSelectedText: function() {

        // WebKit 用の判定追加
        if (navigator.userAgent.match(/AppleWebKit/))
            return (Ten.DOM._selectedText || '');


        else if (window.getSelection)
            return '' + (window.getSelection() || '');
        else if (document.getSelection)
            return document.getSelection();
        else if (document.selection)
            return document.selection.createRange().text;
        else
            return '';
    },

:
:

    // 以下のようにイベント追加
    if (navigator.userAgent.match(/AppleWebKit/)) {
        new Ten.Observer(document, 'onselectstart', Ten.DOM, 'handleSelection');
        new Ten.Observer(document, 'ondblclick', Ten.DOM, 'handleSelection');
    }

って感じ。

(追記)

id:jkondo 「したい」

はてなアイデア

やった!

Google Chrome ではてなスターコメントの出現位置がおかしい件とその原因

Google Chromeはてなスターコメントの出現位置がおかしい


こんな感じ

原因は Ten.js の以下の箇所

    getMousePosition: function(pos) {
        // pos should have clientX, clientY same as mouse event
        if ((navigator.userAgent.indexOf('Safari') > -1) &&
            (navigator.userAgent.indexOf('Version/') < 0)) {
            return {
                x: pos.clientX,
                y: pos.clientY
            };
        } else {
            var scroll = Ten.Geometry.getScroll();
            return {
                x: pos.clientX + scroll.x,
                y: pos.clientY + scroll.y
            };
        }
    },

この if 文は、 Safari 2 系かどうかを見ているんだが、 'Safari' という文字列があって 'Version/' という文字列がないかどうかを判断基準にしてしまっている。
そして、 Google Chrome には Version/ という文字列が含まれていない(僕の環境では)。
なので、 Google Chrome = Safar 2 系という判定をされて、 event.client[XY] を意図しない値として扱う。
これはいけない><

レンダリングエンジンを見るべき

オープンソースなブラウザでは、ブラウザのバージョンで判定してはいけない。
レンダリングエンジンのバージョンで判定すべきだ。(自戒も込めて)
なので、 Safari という文字を見てはいけない。あくまでレンダリングエンジン AppleWebKit という文字を見るべき。
なので、 Safari 2 以前かどうかを知りたければ以下のようにするのがいい。

var m;
if ((m = navigator.userAgent.match(/AppleWebKit\/(\d+(\.\d+)?)/)) && m[1] < 500) {
    alert('Safari 2 Compat');
}
else {
    alert('Modern');
}

バージョン判定は uai.js が参考になる

http://homepage2.nifty.com/magicant/sjavascript/uai-spec.html
JavaScript-XPath でもお世話になっています

あと

この例の場合に限っては、 page[XY] があったらそっち使うって判定を入れてもいい気がする。ただ、保守性の問題か。