DevoのActionをさらに追加してみた 続き

見ているページのはてなブックマーク数を表示する

Keyword
hatebu.count(ユニークであればなんでも可)
Param
不要
Description
任意に
Code
var c=gBrowser.selectedBrowser.contentDocument;
var b = c.body;
var d = b.appendChild(c.createElement('div'));
d.id="hatebcnt";
d.innerHTML="

";
表示イメージ

http://img.skitch.com/20080723-fdqtitigb8kmr4g8pmjuw3u1xq.png

Twitterで呼び出せるAPIの残り回数を表示

Keyword
twitter.limit(ユニークであればなんでも可)
Param
なし
Description
Show remaining number of API requests(任意に)
Code
$.getJSON("http://twitter.com/account/rate_limit_status.json",
function(data){
alert(data.remaining_hits+"/"+data.hourly_limit+"\n"+data.reset_time);
});
表示イメージ(OSX版なので他のOS版とは表示が異なる場合があります)

http://img.skitch.com/20080723-jpfcmmy48tcg5fkuneqg6g8xph.png

その他

そもそも今100Req/hなので必要性は?
Twitterは元々jQuery.jsを読み込んでいるのでなにも考えずにすらすら記述可能

その他
var c=gBrowser.selectedBrowser.contentDocument;
var b = c.body;
var s=c.createElement('script');
s.src='http://jqueryjs.googlecode.com/files/jquery-1.2.6.min.js';
b.appendChild(s);

なんて書いておけば普通にjQuery.jsが使える。
ただし、console.log(hoge)と書いてもFireBugのコンソールはおろかエラーコンソールにも表示できないのでテストが面倒

備考

とりあえず続くかどうかは未定です

DevoのActionをさらに追加してみた

Wassr投稿用

Keyword
wassr
Param
status
Description
任意に
Code
devo_newTab("http://wassr.jp/my/?message=hoge" + devo_param)
備考

入力した文字列を投稿フォームにセットした状態でwassrを開くところまでは問題ないのだけれど、投稿ボタンをクリックした後も投稿フォームに文字列が残ってしまうという問題が発生

見ているページをはてブする

Keyword
hatena.bookmark
Param
なし
Description
任意に
Code
devo_newTab('http://b.hatena.ne.jp/add?mode=confirm&title='
+ escape(document.title)+'&url='
+ escape(window.content.document.location.href));
備考

&summary=devo_paramとすればコメントも予め入力出来るのかな?と試しましたがダメですね。ブックマーク登録画面を開いた時にコメント欄にカーソルがあるのでそこで入力して下さい

TIPS的な

デフォルトのActionの検索エンジンが日本向けではないので追加する必要がある
actions.jsがこうなっているので

function devo_newSearch(engine,keyword){
    
    keyword = escape(keyword.toString());

    if(engine == "google"){
            devo_newTab("http://www.google.com/search?q=" + keyword);
    }
    else if(engine == "yahoo"){
            devo_newTab("http://search.yahoo.com/search?&p=" + keyword);
    }
〜 略 〜
}

ActionのCodeをこれから

devo_newSearch('google', devo_param)

これに修正する必要がある(もしくは別に追加する)

devo_newTab("http://www.google.co.jp/search?q=" + devo_param)

yahooも.comから.co.jpにすると正常に検索できます

その他

action.jsでこんな事をやっているので必要な時だけボタンを追加とか外部JS(jQuery)を読み込んで外部データを表示なども出来るかもしれません

function devo_sharedcopy(){

    var u="http://sharedcopy.com";
    var c=gBrowser.selectedBrowser.contentDocument;
    var b = c.body;
    var d = b.appendChild(c.createElement('div'));
    d.id="k_deleteme";
    d.innerHTML="<h1 style='position:absolute;top:"+((b.scrollTop||c.documentElement.scrollTop)+10)+"px;background-color:#eee'><img src='"+u+"/images/loading.gif?V0' />LOADING..</h1>";
    var s=c.createElement('script');
    s.id='k_script';
    s.src=u+'/javascripts/k.js?v=1'+ ('%s'==('%'+'s')?'':'&t=%s')+'&r='+Math.random();
    b.appendChild(s);

}

FirefoxのアドオンのDevoが便利過ぎる件

LDRでFeedを眺めていたら旧・Macの手書き説明書 - FC2 BLOG パスワード認証という記事を発見。
説明に従ってインストールして好感触、自分でもJavascriptで拡張可能との事で色々試してみました。

試しに

    alert("hoge");

でメッセージボックスを表示した。

いま見ているWikipediaのタイトルとurlをTwitterのテキストボックスに差し込む

  • その1 タイトルを表示
alert(document.title);

問題無し

  • その2 ページのurlを表示
alert(location.href);

上手く取得できない

chrome://browser/content/browser.xul

もちろんこれでもNG

alert(document.location.href);

色々調べた結果

alert(window.content.document.location.href);

だと上手く取得出来る

  • その3 twitterのページに差し込む
devo_twitter(document.title + " " + window.content.document.location.href);

クジラが釣れてしまう
エンコードしてないから?と思って

devo_twitter(encodeURIComponent(document.title) + " " + window.content.document.location.href);

Twitterのページで文字化けに
よくよく調べてみると

function devo_twitter(status){
    
     devo_newTab("http://twitter.com/home?status=" + escape(status.toString()));
}

これじゃ化けるのは当たり前

devo_newTab("http://twitter.com/home?status="document.title + " " + window.content.document.location.href);
  • 完成系

Keyword(ユニークであれば適当に)

wt

Parameters(〃)

text(optional)

Description(〃)

Code

if (devo_param) {
    devo_newTab("http://twitter.com/home?status="
              + "調べてた:" + document.title + " "
              + devo_param + " " + window.content.document.location.href);
} else {
    devo_newTab("http://twitter.com/home?status="
              + "調べてた:" + document.title  + " "
              + window.content.document.location.href);
}

おまけ

  • 検索エンジンの追加なら全然簡単
    • 任意のユーザIDのふぁぼったーを表示

Keyword(ユニークであれば適当に)

favotter

Parameters(〃)

user id

Description(〃)

Code

devo_newTab("http://favotter.matope.com/user.php?user=" + devo_param)

Shift+x,f,tab,ユーザID,returnで表示

    • CPANモジュールを探す

Keyword(ユニークであれば適当に)

cpan

Parameters(〃)

module

Description(〃)

Code

devo_newTab("http://search.cpan.org/search?module=" + devo_param)

Shift+x,c,tab,モジュール名,returnで表示
ね、かんたんでしょ

JSON::XSに置き換える その後

とりあえずuse JSONしている所を全部use JSON::XSに書き換えてってJSON.pmアップデートしようぜ作戦が終了しました。
最初1日1県ずつ書き換えてったら6日で終わるんじゃね?と思って始めたのですが案の定同じ単純作業を2回したくない性格なので1県で飽きてしまいながらなんとか3県できたとこでこれ自分でやる必要ないんじゃとようやく気がついた。
はじめに置換するためのsedスクリプトを書いてテスト、次に対象となるスクリプトgrepして、先ほどのsedスクリプトに喰わせて別ディレクトリに吐くというスクリプトコマンドラインから生成して(awkで)、スクリプトを実行して書き換えたスクリプトをアップロードしてサーバでテストってとこ迄実質30分ぐらい。
最初にやっておけば良かった。
で、cpan>install JSONしてJSON.pmを置き換え。

これでWeb::Scraperスクレイピングする版にリプレースする作業に取りかかれる(んだけどタグが閉じられてなかったりheadがきてbodyの後にまたheadがある館とかあってまた泣かされる予定)

JSON::XSとかMacVimでちょっと調べた部分を忘れないためにメモ

しばらく前から図書館蔵書マップのサーバー側のスクリプトのHTMLをパースする部分をHTML::TagParserからWeb::Scraperに切り替えようと企んでいました。
ただWeb::ScraperJSONモジュールが2.0以降なので、まず現在動作しているスクリプト120個ぐらいを一斉に書き換えてからJSON.pmをUPDATEするというかなり面倒な手順になり半ば放置していました。
よくよく考えるとWeb::Scraperをインストールした時にJSONもUPDATEして(JSON.pmは前のに戻した)、XS版もインストールしていました。
それならば2.x用に書き換えたスクリプトでとりあえず明示的にXS版を指定しておけば(use JSON; ではなくuse JSON::XS;みたいな感じで)できた物からUPLOAD出来る事に気付きました。
例)
1.x版

use JSON;
$JSON::Pretty = 1;      # 整形する
$JSON::Indent = 4;      # インデント幅を4に
$JSON::Delimiter = 2;   # セミコロンの前後に空白を開ける

print objToJson($obj, {keysort => 1});  #キー順にソートする

2.x版

use JSON::XS;               # 本当はuse JSON;で
my $json  = new JSON::XS;   # 同様にnew JSON;
   $json->pretty;

print $json->canonical->encode($obj);

試しに動かしてみると所蔵しているのに所蔵していないマーカが表示される、Firebugのコンソールで見る限りちゃんとレスポンスを取得出来ているように見えるのになぜ?という事で一旦term上で変更前後で吐いているJSONにdiffをかけてみると2.x用に修正した方はtrueとfalseがクォートされていることがわかった。
例)

//  1.x
{
    [
        'foo' : true,
        'bar' : false,
    ],
}
//  2.x
{
    [
        'foo' : 'true',
        'bar' : 'false',
    ],
}

よくよく調べてみると元々のスクリプトが正しくないのを1.x版だとよしなにしてくれていたようで、無い頭でPerlDocを読んでみると

other references

Other unblessed references are generally not allowed and will cause an exception to be thrown, except for references to the integers 0 and 1, which get turned into false and true atoms in JSON. You can also use JSON::false and JSON::true to improve readability.

       to_json [\0,JSON::true]      # yields [false,true]

JSON::true, JSON::false, JSON::null

とあるのでこんなふうに書けばいいのかと早速テストすると

$foo = 'true';      # 1.x
                    # $foo = true;はエラーになる
$foo = JSON::true;  # 2.x

Bareword "JSON::true" not allowed while "strict subs" in use at hogehore

直接JSON::XSしているからJSON::XS::trueと書かないとダメでした。

これでダラダラとJSON::XSを使うスクリプトに置き換えていってJSON.pmをUPDATEして、固有データをYAMLで定義して大幅にスクリプト数を減らしWeb::Scraperでパースする形に切り替えるのに一歩近づけたような気がします。*1

メモ

MacVimがバージョンアップして.gvimrcに追記した内容

    1. exコマンドモードの時に勝手に日本語入力になってしまうのを抑制するには
set iminsert=0
    1. 上部に余計なアイコンを表示させない(vim使うのにマウス使わないからできるだけ画面広く使いたいので)には
set guioptions-=T

フルスクリーンにするにはexコマンドモードで

:set fu

なんだけど、最初からフルスクリーンにするには.gvimrcにどう書けばよいのか調べる

set fullscreen

ではダメでした

*1:クライアント側もjQuery版にとっとと書き換えたいのですがね

Greasemonkey0.8の@requireを試してみた

自分なりに使い方が理解出来たのでメモ的にまとめてみた
たとえば以下のようなユーザスクリプト

// ==UserScript==
// @name          Amazon Iwaki City Lib linky for Greasemonkey
// @namespace     natu-n.com
// @description   Iwaki City Library Lookup from Amazon book listings.
// @include       http*://*.amazon.*
// @resource      config http://natu-n.com/data/iwaki1.js
// @require       http://natu-n.com/data/libsearch1.js
// ==/UserScript==

という形で定義ファイルを@resource、共通部を@requireで指定すると
@requireで指定したスクリプトが// ==UserScript==以降に展開され

(function(){
eval(GM_getResourceText("config"));
/**********************************************************************
メイン関数
**********************************************************************/
var FlgRes = false;

if (!document.getElementById("ASIN")) { return };
var header;
var isbn = document.getElementById("ASIN").value;
if (isbn.match(/(\d{9}[\d|X])/)) {
    if (header = document.evaluate("//div[@class='buying']//b[@class='sans']",
                 document, null,
                 XPathResult.FIRST_ORDERED_NODE_TYPE,
                 null).singleNodeValue || null) {
        checkLibrary(header, isbn);
    }
}

更に、eval(GM_getResourceText("config"))で以下のスクリプトが評価され変数としてアクセス出来る

//■検索ページのURL。プログラム内では、このURLにISBNを付加して呼び出します
const QUERY_URL_PREFIX
   = "https://library.city.iwaki.fukushima.jp/wehome/we/opac/kensakucheck.jsp?"
   + "kensaku.x=35&kensaku.y=22&sryskb0=1&allsryskb0=1&sryskb1=2&allsryskb1=2&"
   + "sryskb2=3&allsryskb2=3&sryskb_length=3&taisyokan1=0&kanmei_length=6&"
   + "max_kensu=10&KSKNO1=019&KEYWORD1=&ITTI1=1&f_kanzen1=0&ANDOR2=0&"
   + "KSKNO2=020&KEYWORD2=&ITTI2=1&f_kanzen2=0&ANDOR3=0&KSKNO3=005&KEYWORD3=&"
   + "ITTI3=1&f_kanzen3=0&ANDOR4=0&KSKNO4=070&KEYWORD4=&ITTI4=1&f_kanzen4=0&"
   + "tandoku=120&tandoku_keyword=";
const QUERY_URL_SUFFIX
   = "&siborikomi=040&hanni1=&hanni2=";
const DETAIL_URL
   = "https://library.city.iwaki.fukushima.jp/wehome/we/opac/";

//■検索結果の文字列。_1は英字、_2はUNICODEにエンコードされた全角文字を設定
const LIB_NAME_1 = "To Iwaki City Library";
const LIB_NAME_2 = "\u3044\u308f\u304d\u5e02\u7acb\u56f3\u66f8\u9928";
const ID = "iwaki";
//■ハイフンを付与するか否か  1:付けない  2:付ける
const DASH = 1;
//■書籍の有無の目印
const XPATH = "//p[3]/table/tbody/tr/td[3]/a";

なんて感じで動作して一見便利なようですが、一回resourceなりrequireで取得したスクリプトはクライアント側のプロファイル/gm_scripts/ユーザスクリプト名/配下に格納されてユーザスクリプトをアンインストールしない限り二度と更新する術がない*1
全く同じスクリプトでもユーザスクリプト別にそれぞれ持ってしまうのでかなり意味がない*2
ユーザスクリプト名のディレクトリを掘るのではなく、perlのrequire(use) foo::bar::buzzみたいにrequireで指定したurlでディレクトリを掘ってくれれば使い廻しが出来るのになというのが正直な感想でした

*1:手動で削除すれば可能ですかそこまで普通はやらない

*2:ユーザスクリプトを書く側にはメリットもありますが

そろそろFirefox3.0について(r

自分でFirefox3.0の環境で使っているアドオンについて纏めてみた

開発?で使っているアドオン

アドオン名 バージョン
Firebug 1.2.0b3
FireFTP 0.99.1
Live HTTP Header 0.14
Web Developer[日本語版] 1.1.5
XPath Checker 0.4.1

肝心のFirebugがabout:configでextensions.firebug.showChromeMessagesの値を"true"にしてもconsole.logが(GM_logを含めて)Firebugのコンソールに表示されず、普通のエラーコンソールに表示されてしまう。
about:configでextensions.firebugで始まるキーが大量に増えてるしサッパリわかりません。
でも、Firebugのコンソールの>>のところで直接console.log("hoge")とかconsole.info(dir($("side_ad_base")))とやるとちゃんと表示されるのでなおさらわかりません*1

使いやすくするためのアドオン

アドオン名 バージョン
Greasemonkey 0.8.20080609.0
Japanize 0.8.11
Tab Mix Plus 0.3.6.1.080416
ツリー型タブ 0.7.2008061901
Foxmarks Bookmarks Syncronizer 2.0.47.4

https://addons.mozilla.org/en-US/firefox/addon/2410GoogleBrowserSyncが残念な事になっていて、Firefoxの2と3をプロファイルを別にして併用している自分としてはかなり助かるアドオンになっています

その他

アドオン名 バージョン
TAGIRI Toolbar 1.6.1
netRocket 1.0

netRocketはhttp://www.netrocket.com用のアドオン、ようは「あとで読む」の催促される版で「あとで読む」のBookmarkletをクリックしただけで満足してしまう自分には必須アイテムwです

追記

Firebugのconsole.logの件、unsafeWindow.console.log("foo")と記述したら表示されました、こういうものだと割り切って使うしかないですね
あと、about:configで直さなくともオプションから変更できるようですね
1.05ja
http://img.skitch.com/20080620-j7aqt3hdd5h9bugdinnmx6bfe6.png
1.2.03b
http://img.skitch.com/20080620-dxsbqyekcse9xpbcadgb2bmce6.png

*1:最近知った機能