2010-12-29

GreasemonkeyスクリプトをChromeに対応させる

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
図書館サイトを便利にするGreasemonkeyスクリプトである図書ぶらはFirefoxでしか動かなかったのですが、Chromeでも動くようにしてみました。

今回、Chromeで動かすためにやったことは以下のことです。

(1)jQueryの読み込み方法の変更
chromeで動くGresemonkeyスクリプトでjQueryを利用するを見てください。

(2)クロスドメインでXMLHttpRequestを利用できるようにする
Access-Control-Allow-Originをどこで出力すればよいのか迷ってみたを見てください。

(3)GM_*のラッパー関数を作成
図書ぶらでは、以下のGreasemonkeyで拡張されている関数を利用しています。
GM_setValue
GM_getValue
GM_xmlhttpRequest
これはchromeでは使えないので、以下のような関数を作成しました。
GM_setValue、GM_getValueは以下のような感じです。

function GM_setValue(key,value) {
 localStorage[ key ] = value;
}

function GM_getValue(key,def) {
 if( localStorage[ key ] == undefined && def != undefined ){
  GM_setValue( key , def );
 }
 return localStorage[ key ] ;
}
ここでの注意は、localStorageは文字列しか保存してくれない気配です。
GM_*のときはBooleanはBooleanで保存できていたのですが、localStorageではBooleanを文字列に変換していました。

GM_xmlhttpRequestの方は、完全互換でなくてGM_xmlhttpRequest風な以下のものを用意しました。
function GM_xmlhttpRequest(url,onload){
 var xhr=new XMLHttpRequest();
 xhr.open("get",url);
 onload&&(xhr.onload=function(){onload(this)});
 xhr.send();
}

そんなに使っていないので完全に置き換えてもよかったのですが、なんとなくこんなのを用意してみました。

とりあえずこんな感じでchromeでも動くGreasemonkeyスクリプト(chromeの場合はユーザスクリプトと言った方よいのかな)図書ぶらとなりました。

Access-Control-Allow-Originをどこで出力すればよいのか迷ってみた

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
今まで、普通のjavaスクリプトで行える通信はjavaスクリプトを読み込んだサイトに対してだけだと思っていました。

以下の図でいうとAから読み込んだHTMLに書かれているjavaスクリプトでXMLHttpRequestを利用して通信できるのはAだけでBとは通信できないという感じです。
|-----|     |-----|
|  A  |     |  B  |
|-----|     |-----|
   |           |
   |           ×
|--------|     |
|ブラウザ|-----|
|--------|

でも、どうやらXMLHttpRequest level2というのではBとも通信できるようになるらしいです。
それもjavaスクリプトの記述の仕方では特に変わったことをする必要はなくAと通信するXMLHttpRequestと同じような書き方でよいそうです。
Bと通信できるようにするには、httpのヘッダーに
Access-Control-Allow-Origin
が出力されればOKとのことです。

で、ここでこのAccess-Control-Allow-Originヘッダを出力するのは、AなのかBなのかよくわからなくなってみましたが、結論としてはBの方でした。

ちなみにGoogle App EngineでAccess-Control-Allow-Originヘッダを出力するには、以下のような感じです。
self.response.headers['Access-Control-Allow-Origin'] = '*'

*の部分は接続を許容する先を記述するところで、*と書くとどこからでもOKということになります。

すべてのブラウザで対応しているわけではなさそうですが、javaスクリプトでできることが増えそうです。

2010-12-27

chromeで動くGresemonkeyスクリプトでjQueryを利用する

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
jQueryがステキなのでGreasemonkeyスクリプトでもjQueryを利用しています。

Firefoxだけで動くGreasemonkeyスクリプトでは以下のように書いていました。
(function(d, func) {
    var check = function() {
        if (typeof unsafeWindow.jQuery == 'undefined') return false;
        func(unsafeWindow.jQuery); return true;
    }
    if (check()) return;
    var s = d.createElement('script');
    s.type = 'text/javascript';
    s.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js';
    d.getElementsByTagName('head')[0].appendChild(s);
    (function() {
        if (check()) return;
        setTimeout(arguments.callee, 100);
    })();
})(document, function($) {
    //ここに処理を書く
    alert("There are " + $('a').length + " links on this page.");
});

でもこれではChromeでは動かなかったのです。
理由はよくわかりませんが、
unsafeWindow.jQuery
がずっと
undefined
になっているせいのようです。

Chromeでも動くGreasemonkeyスクリプトでjQueryを利用するには以下のように書くとよい感じです。
function addJQuery(callback) {
  var script = document.createElement("script");
  script.setAttribute("src", "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js");
  script.addEventListener('load', function() {
    var script = document.createElement("script");
    script.textContent = "(" + callback.toString() + ")();";
    document.body.appendChild(script);
  }, false);
  document.body.appendChild(script);
}

function main() {
  //ここに処理を書く
  alert("There are " + $('a').length + " links on this page.");
}

addJQuery(main);

こちらは動きました。もちろんFirefoxでも動きます。
最初のFirefoxでしか動かない版だと、すでにjQueryが読み込まれていればjQueryの読み込み処理を行わないっぽいのでよい感じなのですが、FirefoxでもChromeでも動くというのを重視することにしてみました。


Railsでグローバルな定数を書くところ

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
Railsでグローバルな定数を定義する場所を検索したら、
config/environment.rb
に定義すればよいよ。みたいなことが見つかるのですが、
config/environment.rb
には、なんとなく必要となるライブラリとかをRailsのアプリケーションを動作させる
ための環境設定を記述するのがメインでなんとなくしっくりこないなぁとか思っていたところ、
config/initializers/constants.rb
というファイルを作って、これに定義するのもよいというのを見つけたので、こちらで利用することにしてみました。
定数だけを記述しているというのがなんとなく役割がはっきりしていて気に入りました。

config/initializers/constants.rb
にはモデルでもコントローラーでも利用することがある定数を定義することにしてみました。
コントローラーだけで利用するならば、
ApplicationController
に定義して、
モデルだけで利用するならば、定数を定義したモデルclassを用意して、それを継承するのがいいのかなぁとか思ってみました。

2010-12-24

Windows 7では管理者権限を持つユーザを2つ作っておくのがよい感じ

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
Windows 7を利用してログインしようとしたら

「User Profile Serviceサービスによるログオン処理に失敗しました。ユーザープロファイルを読み込めません」

と言われてログインできなくなりました。
過去にも一度、同じようなことになったことがあります。

これを直すには、
http://ameblo.jp/bomber1129/entry-10687686009.html

にあるように管理者権限がある別のユーザでログインして
システムの復元
をすれば再度ログインできるようになります。

管理者権限を持つユーザがひとつしかない場合、この情報を検索することもできません。
本当に急にログインできなくなるので、もしもに備えてWindows 7では、管理者権限を持つユーザを2つ用意しておいて、仮に管理者権限のユーザでログインできなくなってもなんとかなる状態にしておいた方がよい感じです。

2010-12-16

可変長プレフィックで重複が発生しないようにチェックするためのSQL

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
題名がよくわからない感じになってしまいましたが、内容としては以下のような感じです。

あるコード体系が
XXXXYYYY
のようになっていて、XXXXが親コードをあらわしてYYYYがその枝番を表しているようなコードがあり、さらにXXXX部分が固定長でないという既存コードをそのまま使いたいというケースです。
例えば、
親コードが
101
2001
とかになっていて
枝番も付与すると
10100001
20010001
みたい担っているコードです。
このような親コード部分をプレフィックスと今回、呼ばせてもらったのですが、このプレフィックス部分は、上記の例の場合
200(この枝番に2001が含まれる可能性があるため)---ケース1

1011(101の枝番とかぶる可能性があるため)---ケース2
も登録したくありません。

これをチェックする方法です。
MySQLのテーブルにプレフィックスが登録していあるとします。
テーブル名:pre
code
101
2001

まずは、ケース1をチェックします。
こちらは簡単。
select * from pre where code like '200%'
これで1件でも引っかかれば登録できないものとします。

ケース2の場合は以下のような感じです。
select * from pre where '1011' like concat(code,'%')
これで1件でも引っかかれば登録できないものとします。
こちらはデータ件数が多くなると遅くなるような気がするので注意が必要かもです。

上記2つをorで結合して以下のような感じで一気にやるのがよいかもしれないです。
select * from pre where code like '1011%' or '1011' like concat(code,'%')

2010-12-08

土偶の本

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
土偶ってすごく生命力あふれる感じがとてもステキなのです。

そんな土偶をいっぱい見ることができる本なのでオススメです。







個人的な好みとしては、縄文のビーナスと言われるいる土偶やみみずく型土偶とかが特にお気に入りです。
縄文後期の遮光器土偶や埴輪とかの中空のものもステキなのですが、なんとなくワイルド感というか力強さが若干ものたりないと思ったりしているのです。