プログラミング」カテゴリーアーカイブ

導入から公開まで13時間!Chrome拡張機能の開発[1of6]

先日本ブログにて公開した「ハロワ求人情報検索ページの設定を容易にする」ブックマークレットですが、これをChrome拡張機能として実装してみました。公開も。以下その経験談です。

ブックマークレットは作成も導入も敷居が高い

先日本ブログにて公開したブックマークレットについてですが、「作る」にも「使う」にも、やはり結構敷居が高いなあと感じました。

グーグルの「Chrome」ブラウザであればブックマークをPCとスマホで同期できるので、Android系スマホはまだいいのですが、iOS系の「Safari」にいたってはブックマークレットをそう簡単には導入できません。
私自身は、結構前からiPhoneでも「Chrome」ブラウザに乗り換えましたので、今は特にそうした苦悩はありませんが、PCにしてもスマホにしてもブックマークレットの場合、実装できるコード量や使える機能が限られるので自由度が低いと正直思いました。

それに比べるとChrome拡張機能と呼ばれるアプリ(?)の場合、できそうなことがいっぱいありそうです。逆にできないことって何があるだろうと考えるくらいです。

前々から「プラグインのようなものの開発」に憧れが...

前々から「プラグインのようなものの開発」に憧れていたこともあり、Chrome拡張機能についてちょっと勉強してみました。

「Chrome拡張機能」については使う側としての知識しかありませんでした。しかも1、2個使う程度でしたので、2,3個使っているブックマークレットの方が使う側としても上でした。そこで、まず、「Chrome拡張機能とは何?」というところからのスタート。Google先生んちを訪ねても、系統だったものどころか、あまりまとまった情報を扱っていないように感じていたところに、

Chrome Extensions API リファレンス

のページに出会い、理解が一気に深まりました。情報がちょっと古いような感もありますが、ここ秀逸です。「Chrome拡張機能とは」から「コンテントスクリプトと拡張ページのメッセージ通信」まで丁寧な説明があります。

ブックマークレット方式の欠点を改善してくれる

そのページ中の、ページアクションの説明のところで、対象ページに対して情報を抽出したり情報を書き込んだりできることが書かれており、これは正に先日ブックマークレットにして公開した機能そのもので「本当はこういうふうにしたかったんですよ!」でした。

もともとブックマークレット方式には、パソコン初心者の方等に使っていただくには、大きな欠点があります。

  1. 設定情報の編集からブックマークレット化までの処理が煩雑
  2. リアルタイムで設定情報を更新できない。一つ目のポイントのように、予め固定的な情報のみを編集してもらってそれをブックマークレットに変換後登録して使う、というものなので当然といえば当然ですけれど。

等になります。

Chrome拡張機能だと、非常に制約が少なく、逆にコンテントスクリプトのように拡張部分と処理対象ページとの3者が独立していてコード作成上の副作用が少ないように感じました。

13時間掛けてChrome拡張を開発しWEBストアへ公開した

結局13時間掛けてChrome拡張機能の開発方法デバッグ方法について調べながら、

ちょっとは楽になったかも!?「ハローワークの求人情報検索」ページ簡単設定[1 of 3]

にあるようなブックマークレットで実装した機能(+アルファ)をChrome拡張機能として実装してみました。

HWISCooker_300x210

Chrome拡張機能リンク先:Chrome ウェブストア – HWISCooker

HWISはハローワークインタネットサービスの略。Cookerは設定情報の保存方式として最初Cookieで実装できないか考えていたのでCookerとしましたが、パソコンへの保存方式としては結局HTML5のlocalStorageを使っています。「Cookie」ではなく「Cooker」としましたが、ちょっと違ったかも。

苦労したポイントは、当初ネットでまとまった情報がなかなか得られなかったこと以外に、

  • 生のjavascriptではなく、jQueryを使えるようにするにはどうすればいい?
  • 既存ページの内容を変更する方法は?contentscriptによる方法とexecuteScriptがある?
  • backgroundを含む拡張部分とcontentscriptとはDOMを共有しないので変数や関数が互いに参照できない。その場合の通信方法はどうするの?
  • デバッグ方法。background.jsを含む拡張部分。contentscript部分。

などがありましたが、上記に紹介したページが本当に参考になりました。
(つづく>>>)

関連する記事

導入から公開まで13時間!Chrome拡張機能の開発[1of6]
導入から公開まで13時間!Chrome拡張機能の開発[2of6]
導入から公開まで13時間!Chrome拡張機能の開発[3of6]
導入から公開まで13時間!Chrome拡張機能の開発[4of6]
導入から公開まで13時間!Chrome拡張機能の開発[5of6]
導入から公開まで13時間!Chrome拡張機能の開発[6of6]
ちょっとは楽になったかも!?「ハローワークの求人情報検索」ページ簡単設定[1 of 3]

お世話になったリンク

Chrome Extensions API リファレンス
Sample Extensions – Google Chrome Extensions
ぷりんすの開発メモ: Chrome拡張機能のマニフェストVesrsion2対応についてのメモ
ChromeExtensionを作ってみる | ぼんぼるにっき
Chrome Extension でデバッグを行う – 日頃の行い
ハローワークの「求人情報検索」ページ

以上です。

iOSのメモ帳のように表示画面と編集画面をシームレスに切り替える

iOSデバイスのメモ帳は見た目もUIも洗練されていてとてもいいと思います(Android系のメモ帳はあまり使いませんでしたのでよく分かりません。今はかなり洗練されているんでしょうね)。

  • メモの一行目に書いた内容がそのままタイトルとして見えること
  • 起動時は単なるViewerのように見えるのにタッチすると編集モードになってくれ、表示画面と編集画面がシームレス(つぎはぎがない)に切り替えられること

が特長と思います。特に2つ目がいいです。

ios_device_memoapp

ある開発案件に関連して、これをAndroidアプリで実現したいと思いいろいろ調べてみました。

やりたいことは

  • 起動時EditText部品からFocusを外してTextView部品のように見せる
  • タッチ(またはクリック)するとFocusが現れて編集できるようにする
  • 編集を完了する(確認ボタンを押す等)とEditText部品から再度Focusが外れる

です。

調べた結果そのものズバリの質問はありませんでした(もしくは質問はあっても回答がなかった)。

それじゃ自分で解決するしかないと思い海外サイトを含め下記内容のあわせ技で実現させました。

  1. edittext – How to replicate android:editable=”false” in code? – Stack Overflow
  2. たかがフォーカス,されどフォーカス – 愚鈍人
  3. ユーザがTextViewに文字を手入力できるようにしたい。 – Google グループ

解決方法はひとことでいうと、TextView部品ではなくEditText部品を使い、他部品にFocusを退避しておき、必要時にrequestFocusメソッドでFocusを戻す、です。

レイアウトに各部品とその属性(オプション)を設定する

<?xml version=”1.0″ encoding=”utf-8″?>
<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
android:id=”@+id/entire”
android:focusable=”true”
android:focusableInTouchMode=”true”>

<Button android:id=”@+id/confirm”
android:text=”@string/view”/>

<EditText
android:id=”@+id/edit”
android:hint=”@string/hint”
android:inputType=”textMultiLine”
android:scrollbars=”vertical”
android:focusable=”true”
android:focusableInTouchMode=”true”/>

</LinearLayout>

ここでは部品が3つ定義されています。上から背景部品、ボタン部品、EditText部品です。ボタン部品やEditText部品の属性はほぼ省略値そのものですが、背景部品の属性だけ通常と異なります。

ポイントは、背景部品(LinearLayout)に

android:focusable=”true”

を設定します。

背景部品は編集機能を持たずFocusする意味は、通常は、ありません。ここではFocusを退避させられるように故意に設定しています。Focusを退避させられる別部品があればそこに設定しても構いません。ただし編集機能のありそうな(?)部品の場合には困ることがあります。例えばTextView部品があってそこにFocusさせるとEditText部品のような動作になってしまったりします。

JavaプログラムにFocusに関する制御コードを書く

public class AppMain extends Activity {
    private static LinearLayout mBgView;// 背景のLinearLayout部品
    private static EditText mBodyText;// EditText部品

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mBgView = (LinearLayout) findViewById(R.id.entire);
        mBgView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (hasFocus == false) {
                // Focusが来たときに何かさせるならここにコードを
                }else{
                // Focusが外れたときに何かさせるならここにコードを
                }
            }
        });

        mConfirmButton = (Button) findViewById(R.id.confirm);
        mConfirmButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                mBgView.requestFocus();// これでEditTextにあったFocusが外れ、背景部品に移る
            }
        });

        mBgView.requestFocus();// 起動時、背景部品にFocusを退避しておく

    }
}

これで、起動時あたかもTextView部品のように見えていたものが、タッチもしくはクリックするとEditText部品のように編集でき、確認ボタンで再びTextView部品のように見せることができるようになりました。

以上です。

GalaxyのGoogleChromeでparseIntがおかしな動作をしますね

「10秒で10年日記 逆日記帳」というWEBアプリを開発しています。
そのテスト中に、Javascriptの機種差(というかバグ?)に遭遇しましたので、
ここに記載しておきます。

文字列から整数に変換するparseInt()という関数でテスト機中
Galaxy S3 Progre(AU)だけが おかしな動作をします。

遭遇したのは、桁数をあわせるために左を0で埋めた日付けや時刻をあらわす
文字列から整数に変換する処理でした。

parseInt("09") => 0 (9)
parseInt("08") => 0 (8)
parseInt("07") => 7
parseInt("06") => 6
parseInt("05") => 5
parseInt("04") => 4
parseInt("03") => 3
parseInt("02") => 2
parseInt("01") => 1
parseInt("00") => 0

のように、08と09のみがうまく変換できません。

で対処方法はというと、

parseInt("09",10) => 9
parseInt("08",10) => 8

のように、(省略できる)進数のパラメータを明示するだけの簡単なものでした。

こうしたことに対処しようと省略パラメータを明示するのも手ですが、そういうものは
膨大に存在するので、大変になりますね。

テスト機のChromeのバージョン:18.0.1025308

以上です。