script.aculo.us の InPlaceEditor で submitOnBlur だと Safari が落ちる

script.aculo.usInPlaceEditor を試している。

設定でカスタマイズできる部分がけっこうある割に、必要なものがなかったりして(特にコールバック系)微妙に使いづらいんだが、Safari だと不意にクラッシュする、という問題もあったり。

色々調べてみると、どうやら submitOnBlur を設定して、フォーカスリング(テキストフィールドのフォーカス時に、フィールドの周囲に出る青い線)をクリックするとお亡くなりになるらしい。

まあ、普通に Safari のバグだと思うんだが、onblur の処理を適当に遅延させると大丈夫なようなので、ticket:3717パッチを送っておいた。

JavaScript でコードを色づけしてくれるライブラリ google-code-prettify

Ruby のコードを色づけしてくれる Syntax を試しているうちに、このブログでもコードの色づけ(いわゆるシンタックス・ハイライト。はてなダイアリーのスーパー pre 記法みたいなやつね)をやってみたくなった。

誰でも普段は、エディタで色づけされたコードを見慣れてるわけで、やっぱり黒べったりは読みづらいといえば読みづらい。

JavaScript によるコード色づけ

ただ、このブログは WordPress で動作している。

WordPress といえば、あれか ... PHP か。なので、Ruby の Syntax ライブラリは使えない。それに、そもそも Syntax は Ruby の字句解析ライブラリとしての用途に重きを置いているためか、デフォルトで対応している言語が少ない(Ruby と XML, YAML だけ)。そのへんの不満もある。

色々迷った末(五分くらい)、JavaScript によるコード色づけを試してみることにした(WordPress のプラグインはですね、種類が多すぎて比較する気にもなれませんでした)。

問題はどのライブラリを使うか。検索してみると、Google Code にいくつか見つかった。

syntaxhighlighter対応言語は申し分ないのだが、ちょっとオーバースペック気味だ。行番号表示やクリップボードへのコピーとかは、とりあえずいらないだろう。

一方の google-code-prettify はシンプルでいい感じ。早速、試してみることにする。

google-code-prettify

使い方は README を読めば問題ないと思う。このブログでは prototype.js を使って、こんなふうに組み込んだ。

<script src="http://metareal.org/javascripts/prototype.js" type="text/javascript" charset="utf-8"></script>
<script src="http://metareal.org/javascripts/prettify.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
  Event.observe(window, 'load', function() {
    prettyPrint();
  });
</script>

この通り、HTML も色づけしてくれる。HTML に埋め込んだ JavaScript も認識されてるのはすごいな。しかも、コード部分の指定は pre 要素か code 要素の class 属性に prettyprint を指定するだけ。シンプル。

おまけ: Ruby コードの色づけ

ちなみに、Ruby コードの色づけはどうだろう。

冒頭にあげた Syntax のコードで試してみよう。

syntax-1.0.0/lib/syntax/convertors/abstract.rb

require 'syntax'

module Syntax
  module Convertors

    # The abstract ancestor class for all convertors. It implements a few
    # convenience methods to provide a common interface for all convertors.
    class Abstract

      # A reference to the tokenizer used by this convertor.
      attr_reader :tokenizer

      # A convenience method for instantiating a new convertor for a
      # specific syntax.
      def self.for_syntax( syntax )
        new( Syntax.load( syntax ) )
      end

      # Creates a new convertor that uses the given tokenizer.
      def initialize( tokenizer )
        @tokenizer = tokenizer
      end

    end

  end
end

十分だな。シンボルは色づけされてないようだけど、インスタンス変数は認識されている。

Google の検索履歴を記録する JavaScript を読んでみた

Google 検索履歴では、検索クエリーの履歴だけではなく、検索結果で実際にどのページをクリックしたか、も記録している。

検索結果ページのソースコードを読んでみると、履歴の保存は JavaScript で行われているようだ。

改行やインデントを加えて読みやすくしたソースコードを基に、履歴を保存する処理や興味深い部分を紹介する。

検索クエリーの保存

if (document.images) {
  new Image().src="/url?sa=Q&client=safari&rls=ja-jp&q=...";
}

まずは冒頭。新しい Image を生成することで http://www.google.com/url/ にアクセスさせている。

URL から推測するに検索クエリーを保存しているのだろう。

クリックされたページの URL を保存

クリックされたページの URL を保存する処理は、各リンクの onmousedown に JavaScript を仕込むことで実現している。

<a href="..." class=l onmousedown="return asq(event,this,'','','res','1','&amp;sig2=...')">

リンクをクリックすると asq 関数が実行されたのち、ページに遷移する、というわけだ。

asq 関数の実装

では、asq 関数はどのような実装になっているのだろう。それなりに長いので些末な部分は削除したソースは以下の通り。

window.asq = function(d,a,f,g,k,l,m) {
  if (window.XMLHttpRequest) {
    var c = window.encodeURIComponent ? encodeURIComponent : escape;
    var h = "", i = "";
    var b = new XMLHttpRequest;
    var e = d.altKey || d.metaKey;

    b.open(
      "GET",
      "/url?&url="+c(a.href.replace(/#.*/,"")).replace(/\+/g,"%2B")+"&ei=..."+m,
      true);

    if (!e) {
      b.onreadystatechange = function() {
        if (b.readyState == 4) {
          clearTimeout(j);
          a.dispatchEvent(d)
        }
      };
      var j = setTimeout(function() {
                b.abort();
                a.dispatchEvent(d)
              },
              2000);
    }

    b.send(null);
    return e
  }
  return true
};

XMLHttpRequest を使って、クリックされたページの URL を非同期送信している。強調した部分では、setTimeout でタイムアウト処理をしているようだ。

IE 6 以下の場合は?

見ての通り、asq 関数の実装は XMLHttpRequest オブジェクトがあるかどうかに依存している。

では、XMLHttpRequest オブジェクトではなく、ActiveXObject 経由で非同期通信を行う IE 6 などではどうするのだろう?

実は IE 6 などでアクセスすると、asq 関数ではなく、clk 関数というものが定義されるようになっている。この関数では検索クエリーの保存と同じように、Image オブジェクトによるアクセスが行われている。

JSON はみんなが思ってるほど安全ではない

del.icio.us 経由で今日読んだ記事。

script による CSRF と JavaScript のハック的手法を組み合わせることで、たとえログイン必須にしている JSON データであっても盗まれるかもしれない、という話。

たとえば、

<script type='text/javascript' src='http://example.com/jsonservice'></script>

という script で JSON を読み込めたとする。

このままだと読み込んだ JSON のデータが評価されるだけで、どんなコードも実行されないのでそれほど問題にはならない (評価された JSON のデータはどんな変数にも代入されてないので参照できない)。

しかし、元記事に紹介されている方法で、たとえば Array のコンストラクタを再定義してやると、JSON が評価されるときに 任意のコード(どこかにデータを送信するなど)を実行できてしまう。

Firefox の <canvas> 要素バグ

Firefox の <canvas> 要素で width, height 属性を指定せず、スタイルシートで width, height を指定すると、JavaScript での描画で座標がおかしくなる。Firefox 2.0.0.1 で確認。

width, height 属性を指定すれば大丈夫。

  1. 1
  2. 2
  3. 3
  4. 4
(20 記事)

Want fries with that?

Open Source Projects