ユーザーインターフェース
Up one level初エントリへの長い道
ありえるえりあのシステムが新しくなりました。
Blogに何か書こうと思い、とりあえずログインしてみます。
ナビゲーションに、anakaとかマイフォルダといったそれっぽいメニューが表示されます。どうやら、ここからエントリを追加できるようです。
anaka(ユーザー名)とマイフォルダの違いはよく分かりませんでした。Plone作者の仕掛けた間違い探しなのかも知れませんが、気にしません。
とりあえずマイフォルダをクリックすると、「新規アイテムを追加」というメニューが出てきました。
押すと、何が追加されるのか分かりません。間違って変なフォルダとか作っちゃったら神様が怖いのですが、気にしないことにして押してみます。
追加するアイテムの種類を選べと言われました。選ぶも何も、エントリの追加以外ないのですが、気にせずに唯一のボタンを押します。
これで編集画面が表示されました。本文の領域が右にはみ出しているような気がしますが、気にしないのが世界のルールというものです。
後はタイトルと本文を書くだけです。
あれ?本文の領域をクリックしてもカーソルが表示されない…。
どうやら、IEでの入力を許さないシステムのようです。まぁ、Firefoxで書けば済む話なので気にしません。
改めてFirefox1.0.7を起動してログインします。Firefoxの起動が遅くていらいらしたのは、たぶん気のせいです。
編集画面で、「Kupuはこのブラウザでは使えないよ」と言われたのも、気の迷いが見せた幻です。
ここまで書いてスクリーンショットを付けることを思いつきました。
Kupuの画像追加ボタンを押し、ローカルのファイルを選んでOKボタンを押します。
…画像のタイトルを入れろと言われました。
うんうん、alt属性は必須だからね。それじゃ、タイトルを入れようか。
…タイトルのエディットボックスをクリックしても、カーソルが現れません。まぁ、カーソルはなくても入力はできるので、気にしないことにします。
これで、画像を貼り付けることに成功しました。
ここで、ふと思いつきます。タイトルにカーソルが表示されないのはFirefoxが古いためではなかろうか?
早速Firefox1.5をダウンロードしてインストールします。
バージョンアップに伴うブラウザの再起動で書きかけのテキストが失われるのは困るので、下書き保存する方法を探しますが見つかりません。
ProjectAの編集画面に退避してなんとかなったので、もちろん気にしていませんが。
で、Firefox1.5で画像追加画面を表示したら、タイトルにちゃんとカーソルが表示されました。
最後に保存ボタンを押して終わりです。…カテゴリを指定しろと怒られました。
なんでカテゴリが必須なのか理解に苦しみますが、やはり気にしません。適当なカテゴリを追加して解決しました。
結論: coreblog2を使うにはFirefox1.5が必要だけど気にしてはいけない。
- Category(s)
- ユーザーインターフェース
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/anaka/521d30a830f330c830ea3078306e957730449053/tbping
ウィンドウサイズに連動して大きさの変わるテキストボックス
MultiScheduler v4.1.1-05の編集画面では、ウィンドウの高さが変わると内容エディットボックスの高さもそれに合わせて変化します。
実装としては、onresizeのイベントをハンドルしてエディットボックスのスタイルを変えているだけです。
HTML上はこんな感じ(実際はXSLT)。
<textarea name="description" rows="10" cols="*" wrap="virtual" class="input-data1 ime-active ResizableWidget" height-min="50">
イベントハンドラがありません。
また、height-minという、HTMLにはない属性も見えます。
ナニコレ。
まぁ、onloadでtextareaにハンドラを設定しているだけなんですけどね。
ちょっとフレームワークっぽい作りにしていて、こんな感じでハンドラを設定しています。
function applyFunctionByClass(map) {
var children = document.getElementsByTagName('*') || document.all;
for (var i = 0; i < children.length; i++) {
var child = children[i];
var classNames = child.className.split(' ');
for (var j = 0; j < classNames.length; j++) {
var className = classNames[j];
if (map[className]) {
map[className](child);
break;
}
}
}
}
var _WIDGET_MAP_ = {};
window.onload = function() {
applyFunctionByClass(_WIDGET_MAP_);
if (initialize) {
initialize();
}
}
クラス名で検索して、そのクラス名に対応した関数を呼び出し、その関数内でゴニョゴニョやると。
呼び出される関数とクラス名の対応付けはこんなのになります。
var ResizableWidget = {
registerHandler: function(elem) {
// ゴニョゴニョ
}
};
_WIDGET_MAP_ ["ResizableWidget"] = ResizableWidget.registerHandler;
こうやって関連づけておくことで、onload時に適切な関数が適切なコンテキストで呼び出されます。
これで何が嬉しいのか?
Widgetっぽいじゃん!
こうすると、JavaScriptとHTMLのごった煮にならなくて済むというのもありますが、それ以上にUI部品的な扱いができるため、UIを作りやすくなります。
ちなみに、Widgetにプロパティを渡すこともできます。ResizableWidgetであれば、height-min="50"というのがそれです。
HTMLの要素に適当な属性を付けておくことで、JavaScript側がその値を参照できるわけです。
#ResizableWidgetのheight-minは、高さの最小値です。
#ウィンドウを極端に小さくすると、高さが1ピクセルになったりするので、その防止用。
勝手な属性を付けるのはHTML的にvalidじゃないのでどうかという気もしますが、XHTMLなら大丈夫なようにできるんだっけ?
以下、余談。
(HTMLに)何か適当な宣言(クラス名とかプロパティとか)を加えることで振る舞いが変化するというのは、アスペクト指向的というか.NETの属性的というか、Javaのannotation的というか、とにかく変な魅力があります。
思えば、プログラミング言語はより宣言的な方向へと進んできたわけです。例を挙げるとこんなの。
アセンブラ | 高級言語 |
演算を命令の組み合わせで表現 | 演算子の導入 |
初期の高級言語(FOTRANとか) | 構造化言語 |
ジャンプの組み合わせで制御構造(分岐やループ)を表現 | 構造をキーワード(ifやfor)と、ブロックで表現 |
構造化言語 | オブジェクト指向言語 |
データとコードの組み合わせはプログラマが管理(命名で表現することが多かった) | クラスやオブジェクトの形で結びつきを明示的に表現 |
つまり、宣言的な方向に流れるのは歴史的必然であるということですね。
- Category(s)
- ユーザーインターフェース
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/anaka/5927304d3055306e5909308f308b30c630ad30b930c830c330af30b9/tbping
Re:ウィンドウサイズに連動して大きさの変わるテキストボックス
画像も縦に並んじゃうし…。
Re:ウィンドウサイズに連動して大きさの変わるテキストボックス
reStructuredTextを使うのが良いと思います(JDEEのエントリはなかなかうまく行かず5,6回編集しましたが)。
http://www.planewave.org/translations/rst/quickref.html
「アスペクト指向入門 -Java ・ オブジェクト指向から AspectJプログラミングへ」を読んだので
javascriptでAOPするaspect.jsというのを考えてみた。
方針はこんな感じ。
- advice(aspectで実行されるコード本体、という説明で合ってるのかな)は普通の関数として定義する
- weaving(aspectの合成)は動的に実行する
マクロ展開レベルのcode generatorを作ってもいいけど、javascriptらしくないよね - 使用できるjoinpoint(adviceを注入できる場所というか時というか)は、関数の実行(execute)のみ
クラスフィールド関連のjoinpointは不要だし、変数の参照・代入をどうにかするのは無理っぽい
とりあえず、関数呼び出しのaround advice(joinpointの前後に実行されるadvice)が書ければ、後はなんとでもなりそうなので、その方法を考える。
例えば、Fooオブジェクトのbar()関数(Foo.bar())があるとして、これにaround adviceを追加するには、
Foo.original_bar = Foo.bar;
Foo.bar = function() { // この名前なし関数全体がaround advice
// ここがbefore相当
Foo.original_bar.apply(this, arguments);
// ここがafter相当
}
といった感じで実装できる。汎用的にやるには色々と手間が必要だけど、まぁなんとかなりそうだ。
次にpointcut(joinpointの集合)を指定する方法だけど、for (var key in object) {}してやればオブジェクトが持っている関数名を文字列として取得できるので、後は正規表現かなにかでmatchingさせればいい。オブジェクトさえ指定されていればweavingにそれほど時間がかからず、あまりパフォーマンスが落ちない形で実装できると思う。
問題は、任意のオブジェクトにのある関数、というpointcutの指定をどう処理するかである。
AspectJで言えば、call(*.set*())みたいなのは、動的にやるのが厳しい。ここまで極端な例はあまり使わないかも知れないが、call(*Widget.initialize())程度の指定ならありそうで、かつ全く同じ問題があるので、なんとかしないといけない。
原理的には、rootとなるオブジェクト(windowとか)から全てのオブジェクトに到達可能なので、指定自体は可能である。
が、オブジェクト数が多い場合、この方法ではweavingに時間がかかりすぎて実用的なパフォーマンスが出ないような気がする。
ここだけ静的に処理します、というのも格好悪いしなぁ。う~ん。
ちなみに、「アスペクト指向入門」はこれ↓
http://www.amazon.co.jp/exec/obidos/ASIN/4774125814/
読みやすいのでお勧め。
- Category(s)
- ユーザーインターフェース
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/anaka/300c30a230b930af30c86307541151659580-java-30fb-30aa30a730af30c863075411304b3089-aspectj30ed30e930df30f33078300d30928aad3093306e/tbping
Re:初エントリへの長い道
# 一度保存しようとしたら、メールアドレスとURLが必須だと怒られて保存できませんでした。
# 個人設定で変更できるので、変更した方が良いと思います。
> 下書き保存する方法を探しますが見つかりません
同じく困りました。
一度保存すると、状態変更メニューで「非公開にする」があるのですが。
来週、神様に聞く予定です。
Re:初エントリへの長い道
作成者だけの入力でいけるはず。
引用するつもりで井上さんのコメントをマウスで選択しようとしたら、うまく選択できません(IE)。
引用ボタンか何か欲しいですが、とりあえず気にしないことにします。
Re:初エントリへの長い道
神様は年明けまで安息日を取ってたような気がします。
Re:初エントリへの長い道