ultra blue http://blog.livedoor.jp/tzifa/ 主にウェブ関係、たまに日常、かもしれないブログ ja
  • JavaScript : はてなハイク閲覧用スクリプト http://blog.livedoor.jp/tzifa/archives/50939997.html これは何? ハイクをキー操作で見られるようにするスクリプト。 各ハイクごとの付加情報や、継ぎ足されたページへのリンクを表示したりもする。 こんなやつ。 ダウンロード haiku_rewinder.user.js 使い方 j : 下のハイクにフォーカス k : 上のハイク... tzifa 2008-03-16T18:40:32+09:00 JavaScript <![CDATA[

    これは何?

    ハイクをキー操作で見られるようにするスクリプト。

    各ハイクごとの付加情報や、継ぎ足されたページへのリンクを表示したりもする。

    こんなやつ。

    ダウンロード

    haiku_rewinder.user.js

    使い方

    • j : 下のハイクにフォーカス
    • k : 上のハイクにフォーカス
    • z : メニューの出し入れ
    • e : リプライの展開(*)
    • c : スターコメントの表示・非表示
    • a : オートモード

    (*)リプライの展開は expandrepliestree.user.js (by cho45 さん)がインストールされてる場合のみ。( Opera と Safari な人は os0x さんの方。)

    それからスターコメントが表示されてるときは、 space キーでスクロールできるようになってる。

    j と k の機能はそれぞれ f と d でも同じく使えるようにした。個人的な好みで。片手で操作できるように。

    オートモード中は自動でスクロールされる。パラパラパラって。上のハイクから下のハイクに移るまでの時間と文字数の差で速度が更新されてる。これは左のメニューから見られる。ただし 500 ms が最短。もう一回 a キーを押すか、 j や k を押すかで止まる。

    その他

    Firefox の拡張や LDRize を使いたくなかった。なのでこれは LDRize と干渉する。そのあたりは 適当に @exclude とかで…。ゴメンナサイ。

    Opera と Safari でも動く。これ大事。けど Safari (の GreaseKit )はロードのタイミングがずれたり、なんかヘンなときが…。(だれか対処法おしえてください ><)

    f や d などのキーが気に入らない人は、ソースの setup() を見てください。

    それからイベント駆動な感じの設計になっていて、あとで書き足したりしやすくなってる(と思う)。 setup() の終わりあたりで w.HatenaRewinder= HR; みたいにすれば、他のスクリプトからも呼べるようになる。

    ]]>
    install step failed: run postflight script の対処法 http://blog.livedoor.jp/tzifa/archives/50916278.html VMware Fusion のインストールで失敗した Install Fails: Postflight script doesn't run にあるとおりなんだけど、結論だけ紹介。 VMware Fusion をアンインストール ( /Library/Application Support/VMware Fusion/Uninstall VMware Fusion ) フォルダ /Library/App... tzifa 2008-02-15T02:50:45+09:00 その他 <![CDATA[

    VMware Fusion のインストールで失敗した

    Install Fails: Postflight script doesn't run にあるとおりなんだけど、結論だけ紹介。

    1. VMware Fusion をアンインストール
      ( /Library/Application Support/VMware Fusion/Uninstall VMware Fusion )
    2. フォルダ /Library/Application Support/VMware Fusion を削除
    3. ファイル ~/Library/Preferences/com.vmware.fusion.plist を削除
    4. フォルダ ~/Library/Preferences/VMware Fusion を削除
    5. 再起動

    あとはもう一度インストールするだけ!

    Contact the software manufacturer for assistance.

    なんて言われたりしてビビるんだけど気にしない気にしない。

    フュージョンすごいよフュージョン

    参考

    http://twitter.com/poafag/statuses/710061482

    ]]>
    JavaScript : ラップしやすい関数を作る http://blog.livedoor.jp/tzifa/archives/50912643.html サンプル var F= function(fn){ var tmp= function(){ return fn.apply(this,arguments); }; tmp.wrap= function(callback){ var prev= fn; fn= function(){ return callback.apply(prev,arguments); };... tzifa 2008-02-10T02:10:22+09:00 JavaScript <![CDATA[

    サンプル

    var F= function(fn){
        var tmp= function(){
            return fn.apply(this,arguments);
        };
        tmp.wrap= function(callback){
            var prev= fn;
            fn= function(){
                return callback.apply(prev,arguments);
            };
        };
        return tmp;
    };
    
    var my_func= F(function(str){
        return '<'+str+'>';
    });
    my_func('hogege'); // <hogege> ← 普通に呼べる
    
    my_func.wrap(function(str){
        return '* '+this(str)+' *'; // いつでも呼べる
    });
    my_func.wrap(function(str){
        return '* '+this(str)+' *'; // 何回でも包める
    });
    my_func('fofofo'); // * * <fofofo> * *
    
    

    元の関数を直接ラップするような書き方ができる。とてもいい。

    よくない

    これだと、一つ一つの関数ごとに wrap を持つことになってしまう。

    でも、 Function.prototype はいじりたくない。

    関数オブジェクトから継承してみたら?

    call とかそのまま使えるかと思って、やってみた。結論。

    var F= function(){};
    F.prototype= function(){};
    F.prototype.valueOf= function(){
        return function(){
            alert('valueOf called');
        };
    };
        var tmp= new F;
        tmp.call(); // valueOf called
    

    valueOf が呼ばれるのは Firefox 限定らしい。

    tmp.call は存在するのに、他のブラウザでは Type error で呼ぶことができないという結果。妙だ。残念。

    ]]>
    JavaScript : self-currying http://blog.livedoor.jp/tzifa/archives/50911364.html 以前作った関数の続き。 カリー化との絡みがおもしろかったので追加記事 関数 F はプロトタイプに加えておく。便宜上、名前も curry に変更しよう。 var sum= function(){ var result=0; for(var i=0, n=arguments.length; i<n; i++){ result += arg... tzifa 2008-02-08T12:00:42+09:00 JavaScript <![CDATA[以前作った関数の続き。

    カリー化との絡みがおもしろかったので追加記事

    関数 F はプロトタイプに加えておく。便宜上、名前も curry に変更しよう。

    var sum= function(){
        var result=0;
        for(var i=0, n=arguments.length; i<n; i++){
            result += arguments[i];
        }
        return result;
    };
    Function.prototype.curry= function(args){
        var fn= this, self= arguments.callee, args= args || [];
        return function(){
            if( !arguments.length) return fn.apply(this,args);
            else return [].push.apply(args,arguments), self.call(fn,args);
        };
    };
    sum= sum.curry();
    sum(1)(2)(3)(); // 6
    

    が、しかし!
    関数が定義された時点での引数の個数は、(固定されていれば) this.length から得られるので

    var adder= function(a,b,c){
        return a+b+c;
    }
    Function.prototype.curry= function(args){
        var fn= this, self= arguments.callee, args= args || [];
        return function(){
            [].push.apply(args,arguments);
            if( args.length >= fn.length) return fn.apply(this,args);
            else return self.call(fn,args);
        };
    };
    var add= adder.curry();
        add(1)(2)(3); // 6 ← カッコがいらない!
    

    なんて書きかたもできるぜ、 ということを Self-currying JavaScript functions から知った。偶然。おお。

    短いコードなのでそのまま引用してしまおう。たぶん問題ないだろう。たぶん…。

    Function.prototype.toSelfCurrying = function(n) {
        n = n || this.length;
        var method = this;
        return function() {
            if (arguments.length >= n) return method.apply(this, arguments);
            return method.curry.apply(arguments.callee, arguments);
        };
    };
    var add = adder.toSelfCurrying();
        add(1)(2)(3)  // --> 6
        add(7,8)(23)  // --> 38
    

    ただし、これは prototype.js の Function.prototype.curry を使ってる。こんなやつ。

    Function.prototype.curry= function() {
        if (!arguments.length) return this;
        var __method = this, args = $A(arguments);
        return function() {
            return __method.apply(this, args.concat($A(arguments)));
        }
    }
    

    ちなみにこれと同じ、

    Function.prototype.curry = function () {
        var args = arguments;
        var self = this;
        return function () {
            Array.prototype.unshift.apply(arguments, args);
            return self.apply(this, arguments);
        };
    };
    

    という curry までなら、前に JavaScript でのカリー化が流行ったときに、 nanto_vi さんが書いている

    まとめ

    カッコをつなげて書けるのが新しい。

    参照記事では、これを self-currying と言っていた。

    奇しくも、任意の個数の引数に対応する形なら、あの最初に作った「変な関数」は間違いでもなかった。

    JavaScript ++

    ]]>
    JavaScript : 変な関数を作った http://blog.livedoor.jp/tzifa/archives/50902812.html 例 サンプルとして、引数全部を合計して返す関数を使う。 function sum(){ var result=0; for(var i=0, n=arguments.length; i<n; i++){ result += arguments[i]; } return result; } sum(1,2,3,4,5); // 15 これを、 var ... tzifa 2008-01-28T19:47:20+09:00 JavaScript <![CDATA[

    サンプルとして、引数全部を合計して返す関数を使う。

    function sum(){
        var result=0;
        for(var i=0, n=arguments.length; i<n; i++){
            result += arguments[i];
        }
        return result;
    }
    sum(1,2,3,4,5); // 15
    

    これを、

    var sum2= F(sum);
        sum2= sum2(1)(2)(3)(4)(5);
    
    sum2(); // 15
    

    と呼べるようになる。引数はいくつでも渡せるから、

    var sum3= F(sum);
        sum3= sum3(1,2,3);
        sum3= sum3(4,5,6);
        sum3= sum3(7,8,9);
    
    sum3(); // 45
    

    とも書ける。

    ソース

    var F= function(fn){
        return function(args){
            var self= arguments.callee;
            return function(){
                if(arguments.length){
                    [].push.apply(args,arguments);
                    return self(args);
                }
                else return fn.apply(this,args);
            }
        }([]);
    };
    

    まとめ

    楽しい。何の役に立つかはサッパリわからない。

    補足記事

    self-currying

    ]]>
    JavaScript : LDR : キーイベントのパッチ http://blog.livedoor.jp/tzifa/archives/50889620.html Mac の Opera で LDR を使ってるみなさんへ ページの「戻る」が割り当てられている delete キーをうっかり押したばかりにアワワワワという事態を、これが防ぎます。 また、クリップブラウザ( shift+c で出てくるやつ)でのクリップの削除も出来るようにします。 ... tzifa 2008-01-10T00:34:10+09:00 JavaScript <![CDATA[

    Mac の Opera で LDR を使ってるみなさんへ

    ページの「戻る」が割り当てられている delete キーをうっかり押したばかりにアワワワワという事態を、これが防ぎます。

    また、クリップブラウザ( shift+c で出てくるやつ)でのクリップの削除も出来るようにします。

    追記:Sat, 12 Jan 2008 00:52:58 +0900 (JST)

    ちなみに Firefox では、 about:config の Browser.backspace_action を 1 にすれば delete キーを scroll-up に変更できます。

    ユーザースクリプト

    ldr_key_patch.js

    といっても必要なのは、 delete キーのキーコードが 8 であることと、 「ページを戻す」デフォルトイベントは抑止できるということ、 の 2 つだけです。

    最初は

    キー操作で購読停止ができるようになるよ!って書きたかったんだけど、 さっきやってみたら実は fn+delete でも操作できました 。 keyCode が変化してて…(´・ω・`)

    まあでもこっちのほうが楽です。

    LDR でページを戻すことなんてないので、これは最初から対応してほしいところです。理屈は Safari でも同じなので。

    ふたたび追記

    参考に。Sat, 02 Feb 2008 00:32:53 +0900 (JST)

    Fastladderのviモードにunsubscribeする"delete"コマンドを追加するuserjs

    でも私のほうは Fastladder での動作は確認してませんスミマセン。たぶんスクリプトは同じなので @include の変更だけで動くと思います ><

    ]]>
    JavaScript : Autoscroll.js http://blog.livedoor.jp/tzifa/archives/50879428.html つかいかた // マウスイベントの監視を Autoscroll.start(); // 開始 Autoscroll.stop(); // やめる 動作確認 Opera 9 Firefox 2 Safari 3 IE 6 / 7 デモ → sample_autoscroll.html shift キーを押しながらマウスポインタを... tzifa 2007-12-27T18:34:11+09:00 JavaScript <![CDATA[

    つかいかた

    // マウスイベントの監視を
    Autoscroll.start(); // 開始
    Autoscroll.stop(); // やめる
    

    動作確認

    • Opera 9
    • Firefox 2
    • Safari 3
    • IE 6 / 7

    デモ

    sample_autoscroll.html

    shift キーを押しながらマウスポインタを動かすと開始!

    手を離せばそのままスクロールされ続ける。 1 ピクセルでも動かせば止まる。

    ( shift 押しながら)対象の要素の、外側にいくほど速度アップ。

    ソース

    Autoscroll.js

    グリモン

    autoscroll.user.js

    上に挙げたうちの IE を除くブラウザで。

    左下にマウスポインタを持っていくとオンとオフが切り替わるようになってる。

    追記:色々なサイトで試してみたら…

    Safari や Opera では残念ながら、上のような「模範的な都合のいい例」以外のデザインで、うまくいかないことが多々ありました。 でもせっかくなのでアップしておきます。

    他にも、スクロールできそうなところを勝手に最優先するので…まあその、ええと、察して下さい。

    body 要素の縦スクロールに限ると話は至極簡単ですが、それでは何もおもしろくないので、たぶん作りかえないと思います。

    ctrl 押しで body 要素、 shift ならその他、というように、そのうち操作を分けるかもしれません。それなら煩雑ではありますが、ある程度は確実です。

    オートスクロールってなにさ

    あの、マウスの真ん中のボタンで、びよーんってできるようになるやつ。

    手を離しても自動でスクロールを進めてくれるから、 誰かの tumblr を眺めたり長文のテキスト系サイトを一定速度で読みたいといったときに、 Autopagerize と一緒に使うと便利だった。

    でも、ノートパソコンでマウスがないと、できなかった。

    雑感

    かなり(縦に)長めのページでは特に、少しバーを触っただけで画面が移動しすぎるということがなくなって、とてもいい。

    上下キーやトラックパッドの二本指でちまちまスクロールしたくなかった。 pageUP/Down でもいいんだけど、それはそれでページの途中で見失うことがあったりした。

    (Opera とか)ブラウザによってはデフォルトのオートスクロールが body 要素にしか効かないこともあるので、マウスの繋がってるときでも使えると思う。

    (でもレトロなフレームデザインや妙なボックスデザインとかでは、 動いたり動かなかったり…><)

    さりげなく LDR と相性がいい気がする。フォルダの中にたくさんフィードがあって手動で一つを選びたいときとか、バババババって滑らかにスクロールできるのが楽しい。

    コードの中身

    shift 押下で mousemove という操作は、 意外なことにまだ割り当てられていないので、 特に他と干渉するということもない、はず、たぶん。 もし気に入らなかったら、適当にソースの変更を。

    関数 check_key() で例えば、 e.shiftKey && e.ctrlKey に変えるといったように。

    マウスポインタの速度は人によって好みが違うので、 いじる場合には関数 calc() 以下を。

    パラメータ化はしてない。逆にコードが汚くなってしまったので。

    check_position() は Safari 対策。 一つ前と比較して位置に変化がないイベントは除外するように。 私の環境では、 mousemove イベントがなぜか shift キーなどで発生してしまっていたので。

    check_time() は、 125 ms 以上の間隔でイベントを処理するための関数。 全ての mousemove イベントでは無駄に計算をしすぎるため。

    履歴

    スクロールの量を可変にする。 マウスポインタの位置で速度が変わるように。

    時間の間隔も動的に変わるようにする。数ピクセル単位でゆっくりスクロールさせたくて。 これによって、縦と横とで別々にタイマーを起動させることになった。

    スクロールの量がゼロのときにはタイマーが止まるようにした。

    IE 7 での動作を確認。ここで ver.1.0.0 に。

    バグ修正。対象が html 要素のときは body 要素をスクロールするように変更。

    ]]>
    Greasemonkey : LDR - Drive の Safari と Opera 対応バージョン http://blog.livedoor.jp/tzifa/archives/50864621.html brazil さんの LDR - Drive は本当に便利なのに、 Safari と Opera で使えないのが残念な感じでした。 書きかえるところ 少しだけです。まずは最初をこんなふうに。 // Opera, Firefox if( typeof Keybind == typeof void 0 ){ window.addEventListener('lo... tzifa 2007-12-08T23:57:59+09:00 JavaScript <![CDATA[

    brazil さんの LDR - Drive は本当に便利なのに、 Safari と Opera で使えないのが残念な感じでした。

    書きかえるところ

    少しだけです。まずは最初をこんなふうに。

    // Opera, Firefox
    if( typeof Keybind == typeof void 0 ){
        window.addEventListener('load', init_ldr_drive, true);
    }
    else init_ldr_drive();
    // Safari
    
    function init_ldr_drive() {
        var w = typeof unsafeWindow == typeof void 0 ?
                window: unsafeWindow;
        
        w.Keybind.remove('j');
        w.Keybind.remove('k');
        
        keyTapper('J', function(e, repeat){
            w.Control.scroll_next_item()
        });
        
        keyTapper('K', function(e, repeat){
            w.Control.scroll_prev_item();
        });
    }
    

    あとは Opera のために、ハッシュの最後の値からカンマを抜いて、forEach を入れかえてください。keyTapper も前に手を加えたコードから変わっているので、新しくこちらを使うのがオススメです。

    ソース

    ldrdrive.user.js

    (また)(勝手に)あげておきました。

    ひとことふたこと

    Opera なら無名関数でくくるべきです。でも init_ldr_drive なんて関数は必要にならないと思うのでほうっておきます。

    Safari では GreaseKit が必要です。スクリプトをロードするタイミングが違うために、あのような分岐が必要となっています。 GreaseKit は load イベントが過ぎてから、各ユーザースクリプトを実行しているようです。

    ]]>
    Greasemonkey : はてなダイアリーのプレビューを Opera でも http://blog.livedoor.jp/tzifa/archives/50850126.html 追記 Mon, 26 Nov 2007 01:12:58 +0900 既に id:takef さんが一年以上前に やってました 。 あああああ恥ずかしい。 真摯に BeforeScript イベントでスクリプトを書き換えていて、あちらのほうが楽しいです。 さらに追記 : Thu, 27 Dec 2007 17:40:57 +09... tzifa 2007-11-23T22:04:34+09:00 JavaScript <![CDATA[

    追記

    Mon, 26 Nov 2007 01:12:58 +0900

    既に id:takef さんが一年以上前に やってました 。 あああああ恥ずかしい。

    真摯に BeforeScript イベントでスクリプトを書き換えていて、あちらのほうが楽しいです。

    さらに追記 : Thu, 27 Dec 2007 17:40:57 +0900 (JST)

    でもこちらの方法なら Safari 3 でも動いたりします。

    ソース

    if(Element.show){
       Element.show('tab');
       $('preview-tab').style.cursor = 'pointer';
    }
    

    これだけで Firefox と全く同じように動きます。

    ダウンロード

    hateda_preview.user.js

    もしも

    特別な理由もなく Opera を除外していたとしたら、はてなのスタッフは気をつけたほうがいいかもしれませんね。斧やビール瓶が飛んで来ないように。

    ]]>
    JavaScript : aaa-greasemonkey-functions.user.js の GM_getValue がバグってる件 http://blog.livedoor.jp/tzifa/archives/50838810.html Opera のアレ どっちでも該当 aaa-greasemonkey-functions.user.js aa-gm-functions.js 使ってる人結構いると思うんだけどな。ググってみても出てこなかった。 2 年前に書かれたらしいのに。 Opera さびしー。 修正箇所 これだけでいいっぽい。 function ... tzifa 2007-11-13T13:20:38+09:00 JavaScript <![CDATA[

    Opera のアレ

    どっちでも該当

    使ってる人結構いると思うんだけどな。ググってみても出てこなかった。 2 年前に書かれたらしいのに。

    Opera さびしー。

    修正箇所

    これだけでいいっぽい。

    function GM_getValue( cookieName, oDefault ) {
       var cookieJar = document.cookie.split( "; " );
       for( var x = 0; x < cookieJar.length; x++ ) {
          var oneCookie = cookieJar[x].split( "=" );
          if( oneCookie[0] == escape( cookieName ) ) {
    //         try {
    //            eval('var footm = '+unescape( oneCookie[1] ));
    //         } catch(e) { return oDefault; }
    //         return footm;
             return unescape(oneCookie[1]);
          }
       }
       return oDefault;
    }
    

    下手に return unescape(oneCookie[1]) || oDefault; みたいに書くと空文字を取れなくなる。 これで、存在しないキーのときに undefined を返してくれる。

    わざわざ eval をあてる必要がよく分かりませんでした。誰か教えてください><

    追記 : Tue, 13 Nov 2007 13:54:25 +0900
    どこがバグか書いてなかった。

    たとえば "foo bar" という文字列を GM_getValue() で取り出そうとすると、 eval 'var footm = foo bar' をパースすることになって、 必ずエラーが発生してた。そのせいでいつも catch 節から oDefault が返されてた、という挙動。

    でもどうせ

    クッキーがドメインで制限されるので、値の出し入れが不便です。

    文字列長の上限がひどく低いので、使いどころに困ります。

    Opera のシェアが低すぎるので、ほとんどの人には関係ありません。あなかなしや。

    ]]>
    JavaScript : 関数から関数を呼ぶ関数を作る関数 http://blog.livedoor.jp/tzifa/archives/50828560.html こんなふうに書けるようになるよ この tz.$F_list を使って、例えば var Sequence= tz.$F_list.$struct({ _call_next: function(obj,next,args){ var self= this; setTimeout( function(){ // 関数を実行して、戻り値を「次」に渡す ... tzifa 2007-11-04T17:27:09+09:00 JavaScript <![CDATA[

    こんなふうに書けるようになるよ

    この tz.$F_list を使って、例えば

    var Sequence= tz.$F_list.$struct({
       _call_next: function(obj,next,args){
          var self= this;
          setTimeout( function(){
             // 関数を実行して、戻り値を「次」に渡す
             // next(obj.apply(this,args)); でも同じ
             self.$super._call_next(obj,next,args);
          },this.interval());
       },
       interval: function(){
          return 500;
       }
    });
    
    のようなオブジェクトを用意しておけば、
    var $n=111;
    var fn= Sequence.from(
       function f1(i){
          console.log(i); // 111
          return 1;
       },
       function f2(i){
          console.log(i); // 1
          return [2,3,4];
       },
       function f3(i){
          console.log(i); // [2,3,4]
       }
    );
    // 500ms の間隔を空けて、f1, f2, f3 を順番に実行
    fn($n);
    
    というように書ける。

    もうすこし複雑な指定

    上の例までだとそんなに嬉しいことはなくて、次にこう書いてみる。

    var Sequence2= tz.$F_list.$struct({
       _call_next: function(obj,next,args){
          if(typeof obj=='function'){
             this.$super._call_next(obj,next,args);
          }
          else{
             var self= this;
             setTimeout( function(){
                self.$super._call_next(obj.callback,next,args);
             },obj.interval);
          }
       }
    });
    
    これでこんな感じに書けるようになる。中では自動で関数を入れ子にしてくれる。
    var tmp= [1,2,3];
    var ls= Sequence2.from(
       {
          interval: 250,
          callback: function(i){
             console.log(i); // 1,2,3
             return 1;
          }
       },
       function(i){
          console.log(i); // 1
          return 1.5;
       },
       {
          interval: 500,
          callback: function(i){
             console.log(i); // 1.5
             return 2;
          }
       },
       {
          interval: 1000,
          callback: function(i){
             console.log(i); // 2
          }
       }
    );
    ls(tmp);
    
    250 ms 後に実行を開始して、 1個目が終わったらすぐに次の関数を実行して、今度は 500ms 待ってから、というぐあいで、あとは、なんとなく分かると思うので省略。一回ずつ間隔を指定できるのと、途中で関数が混ざってても大丈夫になったというのがポイント。

    ついでに

    こう書くことで、

    var Sequence3= Sequence2.$struct({
       foobar: function(){
          console.log('foobar');
       }
    });
    
    Sequence2 の各メソッドに加えて、 Sequence3.foobar が呼べるようになる。(あまり意味ないけどさ!)

    元々は GM_xmlhttpRequest でクロスドメイン通信を多用するときのために考えた。ネストを並列に記述できるから、すごくソースがスッキリする。(でもグローバルにこれを使うとセキュリティが、以下略。)あと GUI のイベント処理とかで、あれが終わるまでこれをロックして次に少し待ったらこっちを呼んで、みたいなパターンも書きやすくなる。

    それから Object.prototype にオブジェクトを足しまくってるとちょっとマズいんだけど、それは省略。

    ソース

    この $struct() というメソッドを使うと (コンストラクタじゃなくて)ただのオブジェクトで継承みたいなのができるようになって面白いかも、とか思って始めたんだけど、なんかもう色々…書いてる本人は楽しいんだけど…。

    追記:Tue, 06 Nov 2007 21:35:47 +0900

    更に追記:Mon, 28 Jan 2008 19:48:49 +0900 (JST)

    前にちょっとマズいとか書いたけど、そんなにマズくなかったです。m(_ _)m

    tz.Struct_0.js

    まとめ

    それから、 setTimeout()GM_xmlhttpRequest() などの関数スタックは他のと少し違うので、 関数の中から再度これらを呼び出すことで 1つの連続した関数を生成するという案そのものは、 悪くはないと思います。たぶん。

    ]]>
    JavaScript : keyTapper を Opera でエミュレートした http://blog.livedoor.jp/tzifa/archives/50824007.html 言及先 「 キーをタップしリピート間隔を変更する、タップ&ゴー 」 Opera で動かなかったため、 forEach などを書き換えて 5行ほど追加した。 サンプル sample_keyTapper.html 完全な対応ではない。そこが移植ではなくエミュレートの由縁。リピート開始まで... tzifa 2007-10-30T23:29:36+09:00 JavaScript <![CDATA[

    言及先

    キーをタップしリピート間隔を変更する、タップ&ゴー

    Opera で動かなかったため、 forEach などを書き換えて 5行ほど追加した。

    サンプル

    sample_keyTapper.html

    完全な対応ではない。そこが移植ではなくエミュレートの由縁。リピート開始までのラグが異なる。

    追記 : Thu, 01 Nov 2007 11:04:36 +0900
    本家では、

    40msぐらいにリピート間隔を縮めると、1度押しただけで連打になってしまうことがあったため
    リピートが始まるまでの時間を「デフォルトどおりの動作」にしているが、 これが再現できなかったので固定してしまった。 不恰好だが更新前よりは近い挙動になっている。 40ms や 16ms といった短い時間での予期しない連打は、やはり防ぐに越したことはない。

    駄文

    これはリピート間隔の変更に加えて、リピートができること自体にも、実は価値がある。Opera ではキーを押しっぱなしにしても、 keydown ではイベントの実行は一回きりだからだ。では keypress を用いればいいかというと、そうでもない。keypress では例えば r キーと F3 キーとを区別できないのだ。(ちなみに Firefox では e.keyCode と e.charCode との違いによって可能。)しかし一方で keypress を避ければ、今度は * などの shift+ で入力するキーを検出できなくなる。堂々巡りだ。

    ここでシンプルな、しかし強力な解決策がある。 keyTapper のとった、キーコードの直書きとタイマー処理だ。これで無事に keydown に絞れる。

    ただし、まだオチがある。このままでは US 配列において拡張キーが機能しないのだ。 キーボードの配列ごとにマッピングする必要が生じる。また、ここまで書いて今更だが、keypress 無しにはデフォルトのイベントを抑止できないため、F5 , a, s などでは意図したようには機能しないはずである。

    まとめ

    キーイベントの統一的な解決策はない。現状、この keyTapper は素晴らしい。

    ]]>
    Greasemonkey : はてなダイアリーの公開デザイン一覧から横幅固定を自動除去していくスクリプト http://blog.livedoor.jp/tzifa/archives/50820948.html 玉石混淆 → この一覧ページ。数は揃っていても、ありすぎてよく分からない。 で、次の条件のいずれかに該当するようなデザインは、見ないことにした。 主なテキストを含む要素の、 width が .*px min-width が .*px text-align がなぜか right 全て探す... tzifa 2007-10-28T02:40:06+09:00 JavaScript <![CDATA[

    玉石混淆

    → この一覧ページ。数は揃っていても、ありすぎてよく分からない。

    で、次の条件のいずれかに該当するようなデザインは、見ないことにした。

    主なテキストを含む要素の、

    • width が .*px
    • min-width が .*px
    • text-align がなぜか right

    全て探すことには変わりないんだけど、これだけでも半分くらいが消えて、だいぶ手間が省ける。楽々♪

    デモ

    fixed_width_remover.htm

    見てのとおり、クリックすると 20個から 7個まで候補を減らしてくれる。コーヒーでもすすりながらのんびり待ちましょう。

    動作

    Firefox2 と Opera9 で。

    一覧を読み込むとページの見出し部分に extract というボタンが現れるので、それを押せば OK。

    一画面には 20 のデザインがあって、それを 3秒間隔で開いていく。 開いたら上のチェックにかけて、当てはまればその直後に勝手に閉じる。あとは残ったサンプルに目を通せばいい。

    ポップアップだから、「タブで開く」オプションをチェックしておかないと大変なことになる、かも。

    ちなみに Opera で No images を設定すれば、かなりサクサク走る。あとは Shift+I で適当に。

    ダウンロード

    fixed_width_remover.user.js

    setInterval の引数を変えれば 3 秒より短くすることは簡単ですが、あまりやりすぎるとプチ dos アタックみたいになるので、やめておいたほうがいいと思います。

    ]]>
    日本語訳 : Google Notebook Data API Reference Guide http://blog.livedoor.jp/tzifa/archives/50819427.html 以下、このページ より。 対象 Google Notebook を利用したアプリケーションを設計するプログラマへ。 このドキュメントは、あくまで developer's guide を前提としたリファレンスであり、さらに広範には Google data APIs プロトコルの概念を背景としたものである。... tzifa 2007-10-26T16:45:57+09:00 ブログの設計 <![CDATA[以下、このページ より。

    対象

    Google Notebook を利用したアプリケーションを設計するプログラマへ。

    このドキュメントは、あくまで developer's guide を前提としたリファレンスであり、さらに広範には Google data APIs プロトコルの概念を背景としたものである。

    フィードの形式

    Google Notebook は公開データにアクセスするために、2種類のフィードを用意している。

    1 つは、特定のユーザを単位にしてノートブックの一覧を得るための、メタフィードである。 この中で、それぞれのエントリが各々のノートブックに対応する。
    このフィードは以下の URI をとる。

    GET http://www.google.com/notebook/feeds/userID

    もう 1 つは個々のノートブックを単位とするものである。これはノートというエントリによって構成され、ノートごとに全てのメタデータ( URL や作成日など)が含まれている。
    URI は以下の形式である。

    GET http://www.google.com/notebook/feeds/userID/notebooks/notebookID

    クエリのパラメータ

    Google Notebook は両方のフィードで、以下に示す GData 標準のパラメータに対応している。

    • updated-min, updated-max
    • alt
    • start-index
    • max-results
    • entryID

    さらにノートブック単位のフィードにおいては、 GData Protocol Reference のカテゴリ指定が可能である。ここでいうカテゴリとはノートブックのセクション ( section ) にあたり、例えば "Netherfield Park" というタイトルのセクションを取り出したいのなら、以下のような URL となる。

    http://www.google.com/notebook/feeds
          /userID/notebooks/notebookID/-/Netherfield%20Park
    

    エントリの作成者 ( author ) と全文検索 ( q ) のクエリには対応していない。ちなみに「作成者」は意味を成さない。なぜなら他のユーザと共有することはできても、公開したノートブックの所有者はただ一人となるためである。ノートブック内の全てのエントリについて、作成者は同一である。

    標準パラメータの詳細については GData Protocol Reference を参照のこと。

    以上に加えて、 Notebook data API ではもう 1 つパラメータが存在する。

    orderby
    ソートの種類を指定する。
    このパラメータはノートブック単位のフィードのみで有効。 フィード内のエントリは、デフォルトでは更新された順で、新しいノートを先頭にソートされる。 この orderby パラメータに値 position を指定することで、 ソートをノートブック内のノートと同じ順序にすることができる。

    要素のリファレンス

    Google Notebook data API は GData 標準の要素のみを用いている。 更なる詳細は Atom の仕様と、 Common Elements document を参照されたい。

    ]]>
    JavaScript : 標準 DOM でノードを生成、目に優しく、お手軽に http://blog.livedoor.jp/tzifa/archives/50816635.html ちょっと便利かもしれない .user.js にコピペシリーズ第 2 弾。 before : var ul= document.body.appendChild(document.createElement('ul')); ul.setAttribute('class','menu'); var li= ul.appendChild(document.createElement('li')); li.setAttribute('c... tzifa 2007-10-24T01:07:23+09:00 JavaScript <![CDATA[

    ちょっと便利かもしれない .user.js にコピペシリーズ第 2 弾。

    before :

    var ul= document.body.appendChild(document.createElement('ul'));
       ul.setAttribute('class','menu');
    var li= ul.appendChild(document.createElement('li'));
       li.setAttribute('class','item');
       li.appendChild(document.createTextNode('textA'));
       li.appeeeeくぁwせdr!!!
    

    after :

    var tmp=
       ['ul class=menu',
          ['li class=item',
             'textA',
             ['a href=exampleA.php class=sample id=foo1', 'hoge1']
          ],
          ['li class=item',
             ['a href=exampleB.html class=sample id=foo2', 'hoge2']
          ],
          ['li class=item',
             'text1', ['br'],
             ['a href=/foo/exampleC1 class=sample id=foo3-1', 'hoge3-1'],
             ['a href=/bar/exampleC2 class=sample id=foo3-2', 'hoge3-2'],
             'text2',
             'text3',
             ['a href= exampleC3 class = sample id = foo3-3', 'hoge3-3']
          ],
       ];
    var ul= to.element(tmp);
    document.body.appendChild(ul);
    

    ソース

    実にコンパクト。相互再帰。

    var to={
       element: function(arr){
          var str=arr[0], extract= function(reg1,reg2,tmp){
                str=str.replace( reg1, function(tgt){ return tmp=tgt,''});
                return tmp.match(reg2);
             },
             elem= document.createElement( extract(/^\s*\S+\s*/, /\S+/));
          for(var val,attr; str.length; elem.setAttribute(attr,val)){
             val= extract(/[^=]*$/, /[^\s].*[^\s]/);
             attr= extract(/\S+\s*=$/, /[^\s^=]*/);
          }
          return this.children( arr.slice(1), elem);
       },
       children: function(arr,to){
          (typeof to !='object') && (to=document.createElement(to||'div'))
          for(var i=0; i<arr.length; i++)
             to.appendChild( typeof arr[i]=='string'?
                document.createTextNode(arr[i]): this.element(arr[i]) );
          return to;
       }
    }
    

    もう一つの使い方

    var tmp= [
       'hoge',
       ['a href=http://example.com/','click here!'],
       'hoge2'
       ];
    var span= to.children(tmp,'span');
    

    to.children() の第2引数には、親ノードか、もしくは親ノードとなる要素のタグ名を渡す。 省略すると div 要素が作られる。 この例では、[ テキスト hoge、要素 a、テキスト hoge2 ] の3つを子要素とする、 span 要素を返す。

    欠点・仕様

    属性とその値の区切りに空白を用いた。引用符のエスケープの手間を省きたかったため。

    このせいで属性値に空白とイコールを含められない。つまり例えばクラス名の複数指定ができない。

    その他

    入力の手間を省くだけなら、 「DOMコードジェネレータ @ZEROBASE BLOG」で既出。

    でもやっぱり、あれはソースの見た目がちょっと。。。

    ちゃんと真面目に作るなら、 JSON で汎用的に書いたり テンプレートエンジンを使ったりするんだろうけど、 ユーザースクリプトでそんな大げさなことしたくない。あるいは、 簡単なメニューを足したいだけなんだけど、 innerHTML で直書きはしたくない。 でも DOM はめんどい。もっと構造を見やすくしたい。みたいな人に、どうぞ。

    ]]>