いろいろ検索したつもりでしたが、実は :18:59 timezone と検索することで先人の方々のサイトがヒットし、Google先生がいれば誰でも天才ということで表題の件は簡単に速攻で解決できたことがわかりました。しかしせっかく書いたので恥ずかしながら公開しておきます…
カテゴリー: Programming
「初めてのWindowsガジェット」ソースコード解説
「【ランチタイムラーニング】 初めてのWindowsガジェット」という記事(冒頭の「注」もお読みください)で、お昼を食べながら踏み出す、ガジェット作成の第一歩について説明しました。
この記事では、その記事に掲載したソースコードについて、少し詳しく解説します。
JavaScriptでのタイマー機能の実装
最初はHTMLの開始と、CSSのスタイルの定義です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<html> <head> <title></title> <style type="text/css"> body { margin: 0; width:130px; height:100px; font-family:Georgia, "Times New Roman", Times, serif; font-weight:bold; } #gadgetContent { margin-top:20px; width:130px; vertical-align:middle; text-align:center; overflow:hidden; } #nowTime { text-align:left; font-size:x-large; } #setTime { text-align:right; } </style> |
7行目で、bodyの幅を130pxに設定しています。ガジェットがWindows Vistaのサイドバーに貼り付いている状態を「ドッキング」と言いますが、このドッキングの状態では、ガジェットの最大の幅は130pxです。
また、ガジェットをサイドバーに貼り付けず、単独でデスクトップに表示する状態にすることができ、この状態を「アンドック」と言います。
アンドックした状態では、ガジェットの幅は130px以上に設定することができます。多くのガジェットでこの設定を利用して、ドッキングの状態では簡易的なビュー、アンドックした状態ではリッチなインターフェイスを持ったビュー、というようなビューの切り替えを提供しています。ただし、アンドックした状態でも、ガジェットのサイズは縦横共400pxを超えないことをMicrosoftは勧めているそうです。
さて次にHTMLを見てみましょう。
|
1 2 3 4 5 6 7 8 9 10 11 |
<body onload="init()"> <g:background id="imgBackground"> <span id="gadgetContent"> <span id="nowTime">00:00</span><br /> <input id="setTime" type="text" size="5" id="time" value="55" /> min <br /> <input type="button" value="Start" onclick="startTimer()" /> <input type="button" value="Stop" onclick="finish()" /> </span> </g:background> </body> </html> |
4行目が経過時間を表示するエリア(nowTime)です。そして、5行目に設定時間を入力するフィールド(setTime)があり、6行目、7行目がタイマーを開始、停止するためのボタンです。開始するにはJavaScriptで記述したstartTimer()ファンクション、停止するにはfinish()ファンクションをそれぞれ呼ぶようになっています。
1行目で、このHTMLがロードされたときにJavaScriptで記述したinit()ファンクションを呼ぶようになっていますが、後で出てくるように、今回のガジェットではこのinit()ファンクションは何もしないので、このHTMLがロードされたときは特別な処理は行われません。しかし、今後タイマーの背景画像を変えたりするなどカスタマイズするときに、HTMLがロードされるタイミングでJavaScriptのファンクションを呼ぶ、ということを覚えておきましょう。
最後にJavaScriptを見てみましょう。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
<script type="text/jscript" language="jscript"> var startTime; var secTimerId; var timerId; function init() { // var oBackground = document.getElementById("imgBackground"); // oBackground.src = "url(images/background.png)"; } function startTimer() { startTime = new Date(); doTimer(); } function doSecTimer() { var diffSec = Math.floor(((new Date()).getTime() - startTime.getTime())/1000); var nextTime; var iMin=Math.floor(diffSec/60); var iSec=diffSec%60; var strMin=("0" + iMin); strMin = strMin.substr(strMin.length - 2, 2); var strSec=("0" + iSec); strSec=strSec.substr(strSec.length - 2, 2); document.getElementById('nowTime').innerHTML=strMin + ":" + strSec; nextTime = (startTime + 1000 * (1 + diffSec)) - (new Date()).getTime(); if (0 < nextTime) { secTimerId=setTimeout("doSecTimer()", nextTime); } else { secTimerId=setTimeout("doSecTimer()", 100); } } function doTimer() { var time = Math.abs(document.getElementById('setTime').value * 60 * 1000); doSecTimer(); timerId=setTimeout("finish()", time - ((new Date()).getTime() - startTime.getTime())); } function finish() { clearTimeout(secTimerId); clearTimeout(timerId); } </script> |
ここでは経過時間の常時を更新し(26行目)、毎秒JavaScriptのsetTimeout()でつぎのちょうどの秒にdoSecTimerを呼び出します(30行目)。念のため高負荷がかかっていて表示の次のちょうどの秒が過ぎてしまった場合には単に0.1秒後に再度更新するようにします(32行目)。これをsetTimeout()で設定時間までの時間を計る(39行目,44行目)ことでタイマーを実装しています。
表示の更新は、その時点での時間と開始時間の差分をとって、何秒経過したかを計算します。もちろん1秒ごとに1を足すのが一番簡単ですが、タイマーイベントがジャストの時間に発生しなかったり、そのほかの計算での時間も足されてしまうのでどんどんどんどん遅れることになり、やめたほうが良いでしょう。
また、前述の通りこのガジェットではHTMLがロードされたときに呼ばれるinit()ファンクションでは何もしませんが、7行目、8行目でコメントアウトしてある行のコメントをはずして、背景画像を表示することができるでしょう。
ガジェットでのalertの実装
さてタイマーはこれで実装できるのですが、そもそもタイマーは、指定時間が経過したことを「ぴぴっ」とか言いながら教えてくれてこそ、その本領を発揮できると言うものでしょう。なのにこのタイマーにはアラーム機能がありません。まるで人ごとのように書いてしまいましたが、このセクションでは簡単なアラーム機能を実装しましょう。
そもそも何故このタイマーガジェットはalert()ファンクションを使って、ひょいっとポップアップさせることさえしないのか。それは、alert()ファンクションやconfirm()ファンクションで出てくるポップアップがWindows Vista User Experience Guidelines for the Sidebarに則っていないということでサイドバーガジェットでは無効化されているからです。
それでもとりあえず簡単にポップアップを出したいときもあるではないですか。デバッグするときなんか特に。MSDN Magazineの記事に、そんな開発者の心の叫びに応えた、alert()やconfirm()と同等の機能を実装するやり方(ガジェットプラットフォームが脆弱である一因)が掲載されています。以下が今回のタイマーガジェットにそのやり方を適用する方法です。
ステップ1: ファンクションを準備する
作業フォルダに新しく「Timer.vbs」というファイルを作成して、次のように記述し保存します。
|
1 2 3 |
sub myAlert(msg) MsgBox msg, 48 , "Message from Timer" end sub |
ステップ2: タイマーガジェットから呼び出す
Timer.htmlの中で、前述のCSSの直後、JavaScriptの直前に次の行を書きます。
|
1 |
<script src="Timer.vbs" type="text/vbscript"></script> |
同じくTimer.htmlの中の、finish()ファンクションの最初か最後に次の行を書きます。
|
1 |
myAlert("時間です"); |
これで簡単なアラーム機能ができました。
参照情報
【ランチタイムラーニング】 初めてのWindowsガジェット – お昼を食べながらガジェットを作ってみよう – Windows 7 デスクトップおよびVista サイドバー
「ガジェット」という言葉を聞くと、昔のアニメ、Inspector Gadgetの決め台詞、”Go-Go-Gadget!”と叫びたくなります。この台詞と共に、体のあちこちからわらわらとガジェットが出てくる様は、さながら洋風ドラえもんといったところです。
GUIを伴うアプリケーション作成は数年前まではちょっと敷居が高いものでしたが、現在ではエディターと初歩的なHTMLやJavaScriptの知識があれば、便利な「ガジェット」がいとも簡単に作れるようになりました。しかも作ったガジェットを世界中の人たちと共有できる環境があるので、その便利さや自分の作品を公開し使ってもらえる楽しさから、文字通り老若男女が挑戦しています。
最初の一歩はお昼を食べながら踏み出せるくらいの手軽さです。明日のお昼にでも、ちょっと作ってみませんか?
注: 脆弱なガジェットをインストールした場合に遠隔からコードを実行させることができてしまうプラットフォームである(KB2719662)との理由でWindows 8以降での機能実装の打ち切り、およびガジェットを無効にするように薦めています(理由は不明ですがガジェットを無効にするためのお手軽Fix it 50906の提供が中断か終了したようなので、無効にする場合は上記記事の中のSuggested Actionsの抜粋 Windows サイドバー ガジェットの悪用から Windows Vista および Windows 7 コンピューターを保護する方法 を参照してください)。ガジェットはお手軽ですが、動作させることはexeを動作させているのと同じ危険性を持つので、由来のわからないものや、由来がわかっていても脆弱かもしれないという意識が必要です。またローカルファイルにアクセスする権限やコードの実行権限があるので、脆弱なものを作ったりインストールしたりしたら大変なことに、しかも管理者権限でログインしていたらOSまるごと乗っ取られるかもしれませんよ、ということになります。以上、当たり前な話であるわけですが、テキストエディタだけでお気楽に作れる分余計に注意が必要、ということでしょうか。メールに添付されたzipの内のjsファイルを実行してしまってファイルを軒並み暗号化されて、復号のためにはbitcoin払えと表示されて涙、と似たようなものです(こちらはOSによる注意のダイアログが出る分少しましかも知れないですが、見慣れていて結局そのままOK押してしまうかも)。
何を作るか
Windows サイドバー ガジェット開発者ガイドには、”Hello, World!”と出てくるガジェットの作り方が掲載されています。”Hello, World!”はチュートリアルの王道ではありますが、もう少し実用性のあるガジェットを作ったほうがより楽しく作れるでしょう。
例えばタイマーなどは便利な上に簡単です。最近、仕事を効率よく進めるコツとして「ライフハック」という言葉が使われていますが、いくつかのライフハックの中で1日の時間を分割して効率良く作業を進める方法を取り上げています。ただ、時間を気にしながら作業をしても集中できないので、タイマーがあると便利です。それにタイマーはエンジニアの友であるカップ麺を作る時にも重宝します。
そこで今回は簡単なタイマーを自作します。この簡単なタイマーを改造していけば、自分好みのタイマーを作ることができます。
材料を準備しましょう
【材料】
- お気に入りのエディタ (Windowsのメモ帳(notepad.exe)で十分)
- ブラウザ
以上です。そうです、今この記事をご覧になっているのであれば標準的にコンピュータに入っているもので作れてしまうのです。それがガジェット作りの手軽さなのです。
もちろんJavaScriptやHTMLのリファレンスが手元にあると便利ではありますので、お好みでご利用ください。
さっそくガジェットを作りましょう
手順と成果物の概要
ではさっそくガジェットを作りましょう。その手順は以下の通りです。
- %LOCALAPPDATA%\Microsoft\Windows Sidebar\Gadgetsにフォルダーを作る→「○○.gadget」フォルダー
- JavaScriptを含んだHTMLを記述する→「○○.html」ファイル
- マニフェストを記述する→「gadget.xml」ファイル
以上、簡潔な3ステップです。
ステップ1: 作業フォルダの作成
%LOCALAPPDATA%\Microsoft\Windows Sidebar\Gadgets (C:\Users\<ユーザー名>\AppData\Local\Microsoft\Windows Sidebar\Gadgets)に「Timer.gadget」フォルダー(以降、作業フォルダーと呼びます)を作成します。
|
1 |
mkdir "%LOCALAPPDATA%\Microsoft\Windows Sidebar\Gadgets\Timer.gadget" |
ステップ2: JavaScriptを含んだHTMLを記述する
作業フォルダーに、新しく「Timer.html」というファイルを作成して、次のように記述し保存します。(このHTMLファイルの内容の詳しい解説は、『ソースコード解説』に記述しましたので、必要に応じて参照してください。)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
<html> <head> <title></title> <style type="text/css"> body { margin: 0; width:130px; height:100px; font-family:Georgia, "Times New Roman", Times, serif; font-weight:bold; } #gadgetContent { margin-top:20px; width:130px; vertical-align:middle; text-align:center; overflow:hidden; } #nowTime { text-align:left; font-size:x-large; } #setTime { text-align:right; } </style> <script type="text/jscript" language="jscript"> var startTime; var secTimerId; var timerId; function init() { // var oBackground = document.getElementById("imgBackground"); // oBackground.src = "url(images/background.png)"; } function startTimer() { startTime = new Date(); doTimer(); } function doSecTimer() { var diffSec = Math.floor(((new Date()).getTime() - startTime.getTime())/1000); var nextTime; var iMin=Math.floor(diffSec/60); var iSec=diffSec%60; var strMin=("0" + iMin); strMin = strMin.substr(strMin.length - 2, 2); var strSec=("0" + iSec); strSec=strSec.substr(strSec.length - 2, 2); document.getElementById('nowTime').innerHTML=strMin + ":" + strSec; nextTime = (startTime + 1000 * (1 + diffSec)) - (new Date()).getTime(); if (0 < nextTime) { secTimerId=setTimeout("doSecTimer()", nextTime); } else { secTimerId=setTimeout("doSecTimer()", 100); } } function doTimer() { var time = Math.abs(document.getElementById('setTime').value * 60 * 1000); doSecTimer(); timerId=setTimeout("finish()", time - ((new Date()).getTime() - startTime.getTime())); } function finish() { clearTimeout(secTimerId); clearTimeout(timerId); } </script> </head> <body onload="init()"> <g:background id="imgBackground"> <span id="gadgetContent"> <span id="nowTime">00:00</span><br /> <input id="setTime" type="text" size="5" id="time" value="55" /> min <br /> <input type="button" value="Start" onclick="startTimer()" /> <input type="button" value="Stop" onclick="finish()" /> </span> </g:background> </body> </html> |
ステップ3: マニフェストを記述する
作業フォルダーに新しく「gadget.xml」というファイルを作成します。
作成したファイルに次のように記述し保存します。Shift_JISの代わりにUTF-8で保存できるエディタの場合はencoding=”…”の部分は不要です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<?xml version="1.0" encoding="Shift_JIS" ?> <gadget> <name>Simple Timer</name> <version>1.0.0.0</version> <author name="【あなたの名前】"> <info url="" /> </author> <copyright>【あなたのコピーライト】</copyright> <description>A simple timer</description> <hosts> <host name="sidebar"> <base type="HTML" apiVersion="1.0.0" src="Timer.html" /> <permissions>Full</permissions> <platform minPlatformVersion="1.0" /> </host> </hosts> </gadget> |
ガジェットを動かしましょう
Windows Vistaの場合
サイドバーを右クリックで「ガジェットを追加」を選びます。
Windows 7の場合
Windows 7の場合はデスクトップの右クリックで「ガジェット」を選びます。
するとガジェットのリストに、「Simple Timer」が出てくるので、それを選びます。
パッケージを作る場合
作成した「Timer.html」「gadget.xml」の2つのファイルをzipにまとめます。zipにフォルダ名が保存されないように(zipファイルをダブルクリックした際に、フォルダではなくて2つのファイルが見える状態)、作成してください。そしてできあがったzipファイルを、「Timer.gadget」という名前に変更します。出来上がった「Timer.gadget」ファイルをダブルクリックしてインストールできるパッケージができます。
さあ、いかがですか?ちょっと見た目が悪いタイマーっぽいものが出てきましたね?
そして自分好みのタイマーに
今回作成したタイマーは、ガジェットの作り方の基本だけなので装飾していません。自分好みの背景画像や、色、フォント、さらにアニメーションを加えて、自分好みのタイマーに育ててみましょう。それがアプリケーション作りの醍醐味のひとつです。
また、このタイマーには指定時間が経過したことを通知するアラーム機能がありません。簡単なアラーム機能に関しては、上記のHTMLファイルを解説した「『初めてのWindowsサイドバーガジェット』ソースコード解説」という記事に記述しましたので、必要に応じて追記してみてください。
そうしているうちにガジェットのJavaScriptは原型を留めないほど変わるでしょう。その頃にはタイマーに限らず、自分の好きなガジェットが作れるようになっているはずです。楽しいガジェットを作って、世界に向けて発信しましょう!
参照資料
ActionScript3.0のDataGridでCheckboxを使いたい [AS3] – Checkbox CellRendererを作る
Using a CheckBox in a DataGrid in ActionScript 3.0 [AS3](⇐ In English)
ビジネスアプリケーションにとってデータの操作は基本中の基本。だから、GUIコンポーネントを提供する言語だったら、データをリスト表示したり並べ替えたりする機能やコンポーネントがある、と想定してもおかしくありません。ActionScript3.0にもあります。
今回はActionScript3.0で、そのリスト表示の中にチェックボックスを表示する方法について、Adobe社のオンラインドキュメントに掲載されているサンプルに追加機能を加えながら解説します。これができると、例えば社員教育の受講管理で、リスト上で受講ステータスチェックボックスにチェックを入れればその人を受講済みにできたり、複数のレコードを選択して処理する場合に、処理チェックボックスにチェックが入っている行だけ処理をする、などということができます。もちろんコントロールキーを押しながらクリックして複数選択する、という手もありますが、「これってユーザに優しくないよね」と常日頃思っている人には、チェックボックスのほうが良いかもしれません。
データのリスト表示や操作をするコンポーネントは一般的に、データ部分を提供するものと、そのデータの表示の仕方を指定して操作するものとに分ける、というパターンを使って作られていますが、ActionScript3.0もそのパターンで、データをグリッド(grid)表示するDataGrid、そのDataGridにデータを提供(provide)するのがDataProvider、そして、DataGridのそれぞれの列やセルの表示/描画の仕方を指示する(render)のがCellRenderer、という組み合わせになっています。デフォルトではデータをテキスト表示をするCellRendererが提供されています。
このDataGridのひとつの列をCheckboxにするには、fl.controls.CheckBoxクラスを拡張してfl.controls.listClasses.ICellRendererインターフェイスを実装した新しいクラスを定義し、チェックボックスにしたい列のcellRendererプロパティに、そのクラスを指定します。詳細なやり方はActionScript3.0のマニュアル「カスタムCellRendererクラスの定義」の「ICellRendererインターフェイスを実装するクラスを使用してカスタムCellRendererを定義するには」のセクションに記載されています。しかし、このページに掲載されているサンプルは動かすとエラーになるので、その代わりに、「DataGridCellEditorのオンラインマニュアルの(なぜか)コメント欄に記載されているコード例が一番参考になるでしょう。CellRendererを作成するのが初めてのかたは、まずはこのコード例を、そのまま試してみることをおすすめします。
このコード例ではDataGridの選択状況がチェックボックスと連動する作りになっています。今回、著者はチェックボックスが独立して機能するようにしたかったので、この記事ではこのコード例をベースに、その変更点について解説します。
では変更点を見ていきましょう。まずはfunction set selected()です。Adobe社のコード例では、ここでチェックボックスの選択状況をセットしていますが、このメソッドは、DataGridの行が選択された際に呼び出されます。一番最初にDataGridを表示した時点では、このメソッドは呼び出されないので、セルの値がチェックボックスにチェックに反映されず、チェックボックスは常にチェックが入っていない状態で表示されます。セルをクリックして初めてセルの値がチェックボックスに反映されます。また、ここでチェックボックスの選択状況をセットすると、DataGridの選択状況とチェックボックスの選択状況を連動させることになるため、ショッピングカートや冒頭で例示したような「社員教育受講管理」など、チェックボックスが単独で機能しないといけない場合に対応できません。DataGridの行を選択したらチェックが入るのではなく、チェックボックスをクリックしたらチェックが入ったりはずれたりして欲しいのです。なので、このロジックは後述のfunction set listData()とtoggleSelected()で実装します。ただし_rowSelected属性をセットしている部分は、DataGridを選択した際に表示色などを変えるときに使うので、残しておきます。
|
1 2 3 |
override public function set selected(value:Boolean):void { _rowSelected = value; } |
次にtoggleSelected()ですが、Adobe社のコード例では”don’t set selected or dispatch change event.” (selected属性に値をセットしたり、CHANGEイベントを送出しないように)と書いてありますが、上記のset selected()で記述した理由で、selected属性はここでセットします。
|
1 2 3 4 5 6 |
override protected function toggleSelected(event:MouseEvent):void { var dg:DataGrid = this.parent.parent.parent as DataGrid; var fName:String = dg.getColumnAt(_listData.column).dataField; var newStatus:Boolean = (_data[fName] == true || _data[fName] == "true" || _data[fName] == 1); super.selected = _data[fName] = newStatus; } |
これで、DataGridの選択状況とは関係なく、チェックボックスをクリックすれば正しい値がセットされる、チェックボックスらしい動きになります。もう一つやりたかったのは、DataGridを最初に表示したときにセルのBooleanの状況を正しくチェックボックスに反映することです。それがもう一箇所の変更点set listData()になります。set listData()は、DataProviderがDataGridにセットされるタイミングと、DataGridで何か変更が起きるタイミングの2箇所で呼び出されます(DataGrid.selectable=trueのとき)。その前者のタイミングを利用したいので、上記のset selected()で実装するはずだったロジックをこちらに移動するわけです。
|
1 2 3 4 5 6 7 8 |
public function set listData(ld:ListData):void { _listData = ld; var dg:DataGrid = this.parent.parent.parent as DataGrid; var fName:String = dg.getColumnAt(_listData.column).dataField; var newStatus:Boolean = (_data[fName] == true || _data[fName] == "true" || _data[fName] == 1); super.selected = newStatus; } |
これでDataGridの初期値がDataProviderのデータで埋まったときに、チェックボックスがセルの値を正しく表すようになります。
上記の変更を加えたCellRendererをDataGridのカラムにセットすれば、”true”や”false”という文字列の代わりにチェックボックスが表示されるようになります。このままでも使えますが、もしDataGridのListEvent.ITEM_CLICKイベントを拾って処理をするアプリケーションに使う場合は、最後にもう一工夫必要です。それはチェックボックスのCLICKイベントがListEvent.ITEM_CLICKEDに変換されるのを止めることです。なぜなら、今回実装しようとしている、DataGridとは連動せず単独に動作するチェックボックスの場合、チェックボックスをクリックするという行為の目的は、チェックボックスの値を変えることであり、DataGridの行を選択する、という目的ではないからです。
|
1 2 3 4 5 6 7 8 |
public function CheckBoxCellRenderer() { super(); this.addEventListener(MouseEvent.CLICK, handleClick, false, 0, true); } private function handleClick(ev:Event):void { ev.stopImmediatePropagation(); } |
これでOKです。
ところで、どこかのフォーラムの書き込みで、Adobe社のサンプルを見て「こんなに長いコードを書かないといけないの?!」と驚いている人を見かけました。確かにぱっと見ただけですと、ただチェックボックスを表示したいだけのわりには長く見えるかもしれませんが、要点はこの記事に書いた点だけで、他の6~7割のコードは全て表示スタイルに関するものです。まずは表示スタイルは何もいじらずそのままにして使ってみると、見た目ほど複雑ではないことに気が付かれると思います。
なお、このコードは著者がアプリケーション開発の過程で試行錯誤の結果導き出した一つの手法であり、皆様の参考用に掲載しているものです。ご
利用の条件につきましては、「サイトのご利用条件」をご一読ください。また、このコードは弊社が開発しているアプリケーションで実際に使われています。したがいまして、今後改善やバグ修正がされる可能性がありますが、変更が入りましたら随時この記事を更新します。
プログラムを作るプログラムを作れ – プログラムを自動生成せよ
2013/8/9 追記: 右脳左脳うそ説やプラナリアの記憶の場所など興味深い話がある中で、右脳プログラミング環境だそうです。どうなっていくでしょう。
何の文脈も無く「プログラムを作るプログラムを作れ」と言われた場合、まずそれを言われた方のITスキルやバックグラウンドを知らないと延々と禅問答が続いてしまいそうです。プログラムとはコンピュータへの命令のことなので、それを作るプログラムとなるとコンピュータへの命令を作るコンピュータへの命令を作ることになりますね。最初から直接命令すればよいじゃん、となってしまいます。
各種言語のコンパイラはプログラムを出力するプログラムですし、古くからあるlexとyaccあたりで新しく構文を解釈してプログラムを出力するプログラムを作れば、lexとyaccはプログラムを作るプログラムを作るプログラムでしょうか。
program to create programなどのフレーズでいろいろ検索してみます。Visual Basicのようにコンポーネントをたくさん準備しておきそれらを配置、接続していくもの、イベントに対するアクションもあらかじめ複数準備し、視覚をベースにプログラミングするものがまず目に付きます。準備しなければいけないものは無数ですが、多くの作成者を満足できるレベルになれば便利です。あとは各種言語用のエディタも出てきます。確かにプログラムを組むため(ソースコードを書くため)のプログラムです。そして決められた形式の設計書に基づいて各種言語のソースコードを自動生成と称して出力するプログラムもたくさん登場してきます。UMLとJavaがその典型でしょうか。自動生成されたソースコードは設計書に書かれた枠だけができるため、実際に必要なロジック、つまりほとんどの部分は自力で追記していくことになります。
もしコンピュータへの命令の仕方を知らない方が言った言葉であるとすると、きっと自分で理解できる命令の仕方を作って欲しい、つまり自分にも使えるプログラミング言語、あるいはプログラミング言語までにも至らないプログラムする方式を作って欲しいということなのかと想像できます。自分で理解ができる命令の仕方という意味で考えてみると、最善はしゃべった言葉をそのまま理解して実行してくれるということになるでしょう。サイロン、ターミネーターがそんな感じだと思われます。
かつて自分が小学生であった頃、親に「マイコン」を買ってもらうための殺し文句に「英語の勉強になる」というものがありました。残念ながら自分の親は共にホストコンピュータを触っているような人達だったのでそれはまったく通じませんでしたが、知らない人にはコンピュータは英語で動作していると思われていたのかもしれません。そしてそのような古き良き時代、日本語を入出力できる日本語BASICならぬ、日本語で動作するBASICなるものがマイコン雑誌の広告に出ていたりしたものです。日本語であればプログラムができると思う層を取り込む試みだったと思われますが、1,2年もしないうちに見なくなったと記憶しています。
もし I < 100 ならば I = I + 1900
半べそです。そもそも知らない人にはIFやらTHENやらが日本語になったところで I = I + 1900 で、そんなアホな、です。実際には英語も含めて自然言語を完全に理解するプログラムはいまだにできていません。言語は進化することを考えると言語の進化も取り込めるようにする必要もあるでしょうし、自然言語は前後の文脈が無いと理解不可能な場合が頻繁にあります。受け身や敬語のように前後の文脈どころか発言者の立場までわかっていないといけない場合もあるでしょう。人間の脳は小さい頃からお勉強してそれらを学んできたのですね。
現在でも日本語でプログラムを書けるようなプログラミング言語は作られているようですが、みな教育用のようです。英語と日本語が大きな壁になる場合には有効な教育方法だと思われます。一方、実際のプログラミング言語で予約されている「英単語」は数十の場合が多いので数十単語覚える方が早いのかもしれません。利用したわけではないので時間があれば「パソコン」を買ってもらえた今、実際に日本語プログラミング言語を使って楽しみながら確認してみたいです。
日本語英語の壁を考えないとして、現在の自分で理解ができる命令の仕方となると、やはり何かしらのプログラミング言語、あるいはプログラミング言語のソースコードを作成するためのかなり限定的な枠組み、ということになるでしょうか。プログラムを作るプログラムがあってもプログラミングができる人間の脳は必要とされている状態で、ロボコップがそんな感じです。
ターミネーターはストーリーにはもう大分できていないといけないくらいの時期だったかと思いますが、スカイネット様への納期を死守するには越えなければいけない高い山が続々とあるようです。あれ、スカイネット様をまず納品しないといけないのでしたっけ。
以上は飲み屋でMetaMojiという会社の記事から始まってまだ世の中はロボコップかねぇという話になるまでを思い出しながら書いたもので、とりとめが無いです。お後がよろしゅう。
文書に記述する際の説明用/例示用のドメイン名、IPアドレス、MACアドレス RFC6890,RFC5737,RFC3849,RFC2606,RFC6761,RFC7042 IANAなどなど
説明書などでドメイン名を例示するときに、 hoge とか foo とか bar とか chome などにを適当なTLDをつなげたり、最近ではTLDとして使ってしまうと自分のドメインでない場合や、自分のドメインでも更新しなかった場合などに問題になる可能性があります。IPアドレスもしかりです。そのままコピペされたり検索エンジンにインデックスされて他人に迷惑をかけないためにも、文書に記述するときに使ってよいドメイン名、IPアドレス、MACアドレス(EUI-48)が決まっています。
RFC6890によって RFC5735 はobsoleteにされました。(RFC5735によって RFC3330 はobsoleteにされました。参考: IPv4枯渇)
- 2025-03-03 RFC9637追記
- 2016-06-28 MACアドレス関連追記
- 2013-10-11 RFC6890関連追記(Documentation用IPアドレスの変更はありません)
- 2011-02-10 .lg.jp関連追記
- 2011-01-26 .テスト などTLD関連追記
- 2010-03-17 .jp関連追記
| 192.0.2.0/24 | 192.0.2.0 – 192.0.2.255 | TEST-NET-1 (TEST-NET) | RFC5737 RFC6890(RFC5735 RFC3330) |
| 198.51.100.0/24 | 198.51.100.0 – 198.51.100.255 | TEST-NET-2 | RFC5737 RFC6890(RFC5735 RFC3330) |
| 203.0.113.0/24 | 203.0.113.0 – 203.0.113.255 | TEST-NET-3 | RFC5737 RFC6890(RFC5735) |
| 2001:db8::/32 | 2001:db8:: – 2001:db8:ffff:ffff:ffff:ffff:ffff:ffff | Documentation Prefix | RFC3849 RFC6890(RFC5156) |
| 3fff::/20 | 3fff:: – 3fff:0fff:ffff:ffff:ffff:ffff:ffff:ffff | Documentation Prefix | RFC9637 RFC3849 |
| 00-00-5E-00-53- | 00-00-5E-00-53-00 – 00-00-5E-00-53-FF | EUI-48 (MAC addresses) Documentation Values | RFC7042 2.1.2 (2.1.1) |
| 00-00-5E-EF-10-00-00- 他 | 00-00-5E-EF-10-00-00-00 – 00-00-5E-EF-10-00-00-FF | EUI-64 (unmodified 64-bit MAC addresses) Documentation Values | RFC7042 2.2.3 |
| .test | recommended for use in testing | TLDs for Testing, & Documentation Examples | RFC2606 RFC6761 |
| .测试(.XN–0ZWM56D) .परीक्षा(.XN–11B5BS3A9AJ6G) .испытание(.XN–80AKHBYKNJ4F) .테스트(.XN–9T4B11YI5A) .測試(.XN–G6W251D) .பரிட்சை(.XN–HLCJ6AYA9ESC7A) .δοκιμή(.XN–JXALPDLP) .テスト(.XN–ZCKZAH) .טעסט (.XN–DEBA0AD) .آزمایشی (.XN–HGBK6AJ7F53BBA) .إختبار (.XN–KGBECHTV) | e.g. ほげ.テスト (xn--18j4d.xn--zckzah) | Reserved for testing internationalised domain names | Root Zone Database |
| .example | recommended for use in documentation or as examples e.g. hoge.example | TLDs for Testing, & Documentation Examples | RFC2606 RFC6761 |
| .invalid | intended for use in online construction of domain names that are sure to be invalid | TLDs for Testing, & Documentation Examples | RFC2606 RFC6761 |
| .localhost | having an A record(DNS) pointing to the loop back IP address and is reserved for such use | TLDs for Testing, & Documentation Examples | RFC2606 RFC6761 |
| example.com | e.g. hoge.example.com, example.com | Reserved Example Second Level Domain Names | RFC2606 RFC6761 |
| example.net | e.g. hoge.example.net, example.net | Reserved Example Second Level Domain Names | RFC2606 RFC6761 |
| example.org | e.g. hoge.example.org, example.org | Reserved Example Second Level Domain Names | RFC2606 RFC6761 |
| example.jp example0.jp example1.jp … example9.jp ドメイン名例.jp (xn--eckwd4c7cu47r2wf.jp) | e.g. hoge.example.jp, example7.jp, ほげ.ドメイン名例.jp (xn--18j4d.xn--eckwd4c7cu47r2wf.jp) | 汎用 JP ドメイン名における予約ドメイン名の3 JPRS FAQ | |
| example.<属性ラベル>.jp example0.<属性ラベル>.jp … example9.<属性ラベル>.jp example.<市区町村ラベル>.<都道府県ラベル>.jp … example.<都道府県属性ラベル>.<都道府県ラベル>.jp … example.<市区町村属性ラベル>.<市区町村ラベル>.<都道府県ラベル>.jp … など詳細は右記技術細則にて | e.g. hoge.example3.ed.jp, example7.city.shibuya.tokyo.jp | 属性型(組織種別型)・地域型JPドメイン名登録等に関する技術細則の4.4 JPRS FAQ | |
| example.lg.jp example0.lg.jp … example9.lg.jp | e.g. city.example8.lg.jp | LG ドメイン名登録等に関する技術細則の3.4 JPRS FAQ |
CodeZine:「動けばいいってもんじゃない」 脆弱性を作り込まないコーディング
良いタイトルですね。CodeZineの記事です:『脆弱性体質の改善』。『バッファーオーバーフロー等の脆弱性をうっかり作り込んでしまったがために、数千万円ものコストをかけて、ユーザに告知し、製品を回収して、工場でファームウェアをアップデートする事態に陥ったり、あるいは脆弱性を放置してユーザを危険にさらし、それが明るみに出て「世間を騒がす」ことになったりしなくても済むように』を読んでぐっと来ました。不景気だからと「とにかく安い」や「オフショアにやらせとけ」で痛い目に遭ってる人がいるんですよー、と。もっとも安くないところに頼んでも、スタートインから何週間も動かなかったり、ウィルス撒いたりしてしまうところもあるようなので、こういう啓蒙活動は良いことです。もちろん単なる脅しではなく、かつ内容が正確である必要があります。
ポインタの加減算での誤り、本当に言語仕様ならではの誤りです。エンベッドの世界、高速に動作させなければいけないプログラムを作るとき、いろいろなOSで動作させなければいけないプログラムを使うときなどなど、高級言語として比較的機械語寄りのことができる思想のCはバリバリの現役で進化を続けています。記事はまだ2回目、続きも期待して待ってます。
ばっちり書けてますかhref= 特に&(&)などを含む場合 属性値としてのCDATA
追記(2016/8/31)
最近ではAccelerated Mobile Pages(AMP)を有効にするパラメータとして本当にampが使われてamp=1とかを利用するプラグインなどが出てきました。今時ではXHTMLも使わないでしょうし& + ;以外の記号 でもエラー部分を消さずに &amp + ;以外の記号 相当とみなしてパースが進行するようになっているので気にする必要もないかもしれません。
- <link rel=”amphtml” href=”/hoge?amp=1″ /> OK
- <link rel=”amphtml” href=”/hoge?param1=1&amp=1″ /> OK
- <link rel=”amphtml” href=”/hoge?param1=1&=1″ /> NG
とはいえ、amphtml以外のpathが/ampで終わらないようにできるのであれば、 /amp を query string の amp=1 に、例えばmod_rewriteならば
|
1 |
RewriteRule ^/?(.*)/amp$ /$1?amp=1 [QSA,L] |
のようにwebサーバ側でrewiteする方が気にすることも減って無難かもしれません。
追記終了
複数の変数/パラメータを渡したい場合、その変数/パラメータの名前がampだったり、値に&が含まれている場合を考えていきます。
書くまでも無い当たり前なネタなのかもしれませんが、AdobeサイトのFlashVars解説にも誤記が あったり、「表示」⇒「ページのソース」だけで学んでいる人は気づかなかったりするかもしれないので、関連仕様書を一まとめにしておく意味でも書いておき ます。大きな問題であるわけでもなく気にしなければしないですませられますが、実体参照と同じ名前の変数を使いたい場合のように機能的に困る場合があります。
クイズです。次のHTMLをノートパッドなどのテキストエディタで作成してhoge.html等適当な名前で保存します。
|
1 2 3 4 5 6 7 8 |
<html> <head><title></title></head> <body> <p> <a href="/?hoge=123&=567">Copy me!</a><!-- Wrong version --> </p> </body> </html> |
次にこのファイルをお好きなwebブラウザでこのHTMLファイルを開き、アンカーのリンク先を右クリック等ででクリップボードにコピーし、テキストエディタにペーストします。どうなるか予想できましたでしょうか。
Windowsの実験機で試した結果は以下の通りです。
| FF3⇒notepad | file:///?hoge=123&=567 |
| Safari4⇒notepad | file:///?hoge=123&=567 |
| Opera10⇒notepad | file://localhost/?hoge=123&=567 |
| IE8⇒notepad | file:///D:/?hoge=123&=567 |
| IE7⇒notepad | file:///D:/?hoge=123&=567 |
| IE6⇒notepad | file:///D:/?hoge=123&=567 |
| IE5.5⇒notepad | file:///D:/?hoge=123&=567 |
hostのあるものやpathにドライブのあるものなどいろいろ面白いですが、今回の本題は123の右です。どこにもampがありません。これは「不幸に も多くのHTMLユーザエージェントは変な実体参照でも適当に問題をシカトして先に進んでしまう。(下記参照)」からです。&=の部分を& amp;quot=や©=などに変えたり、先頭に
|
1 2 |
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
を付けたりして(ローカルのファイルでもXML宣言を見てこれをエラーにするブラウザは有りましたか?)いろいろ試してみてください。quotやcopy等では&すら出てこなくなるので間違いにすぐに気づくかもしれません。今まで気づいていなかった方にはとても違和感があるかもしれませんが、パラメータampに値567を渡したい場合の正解は
|
1 |
<a href="/?hoge=123&amp=567">Copy me!</a> |
になります。Flash PlayerにFlashVarsを<object>の中の<param>で渡したい場合はどうでしょうか。HTMLやXHTMLの世界での話なので、変数p1,p2,ampにそれぞれ値を渡したい場合は
|
1 |
HTML: <param name="FlashVars" value="p1=foo&p2=bar&amp=baz"> |
|
1 |
XHTML: <param name="FlashVars" value="p1=foo&p2=bar&amp=baz" /> |
といったものが正しい書き方になります。あとは=前後の%エンコード(Percent-Encoding)(FlashVarsの説明ではURL encodingと書かれていますが、各種のURLencode()のような関数やapplication/x-www-form-urlencodedで使われるエンコードではあの記号はそのまま、この記号は%エンコードという奇々怪々な仕組みも含まれる場合があるので素直に%エンコードと呼び、かつFlashVarsの値はECMAScriptのencodeURIComponent()相当の符号化、つまりUTF-8以外の場合はUTF-8に変換をしてから英数以外は積極的に%エンコードする、というのがさまざまな場合で無難だと思います)もお忘れなく。具体的にはもしFlashVarsで変数p1,p2,ampに&が含まれている値を渡したい場合は次のようになります。(%26はUS- ASCIIのスーパーセットの文字セット-文字符号化では&になります。)
|
1 |
HTML: <param name="FlashVars" value="p1=H%26M&p2=H%26M&amp=H%26M"> |
|
1 |
XHTML: <param name="FlashVars" value="p1=H%26M&p2=H%26M&amp=H%26M" /> |
変数側に記号を入れてみたりするのも面白いかもしれません(例外的にNULは文字列終端扱いである模様で、例えば
|
1 |
<param name="FlashVars" value="hoge%00hoge=hero%00hero"> |
ではswfのhogeにheroが渡されました。実装された詳細仕様は不明です)。href=での%エンコードの話は、サーバ側、アプリケーション側がどうなっているかに依存する、つまりwebサーバやアプリケーションサーバ、CGIもからんできて、単純にこうだとは書くことができません。
では
|
1 2 3 4 5 6 7 8 9 10 11 |
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> ... <body> ... <object ...> <param name="FlashVars" value="p1=foo&p2=bar&=baz"><!-- Wrong version --> </object> ... </body> <html> |
のように、HTMLとしては期待されていない処理を誘発し、XHTMLとしてはエラーになる属性値(value=の部分)の場合、swfに何が渡ってくるでしょうか(IEはobject要素がparam以外の要素を持てないのでコメント要素は取り除きます)。Flash Player 10.0.42.34との組み合わせで以下の通りです。もっとも、HTMLを解釈してFlash Playerに渡すまでの作業はwebブラウザ(HTMLユーザエージェント、HTMLパーサ)の仕事であり、もしFlash Playerのバージョンで変わるとすればそれはFlashVars自体の仕様の変化となります。また、XHTMLとしてちゃんとエラー扱いになった場合はそもそもFlash Playerが起動しません。
| FF3 | swfのampの内容は空 |
| Safari4 | swfのampの内容は空 |
| Opera10 | swfのampの内容は空 |
| IE8 | swfのampの内容は空 |
同時に&amp=bazで正しくswfのampにbazが渡ってくること、そして残念ながら世の中に氾濫している&xxx=bazでも、エラー扱いではなくかつxxxが文字実体参照や数値文字参照にぶつかっていないものはbazが渡ってくることも確認しました。上の href=と同じ状況で予想通りです。
ところでこれはHTMLやXHTMLの世界での話なので、HTML内での記述ではなくて別の外部ファイル(.js等)に分けて、
|
1 |
Content-Type: application/JavaScript (text/JavaScriptとか。機会があればエントリ作成) |
などで提供される分にはまったく当てはまりません。パラメータhoge,p1,p2,ampにそれぞれ値を渡したい場合はそのまま
|
1 |
"/?hoge=123&p1=foo&p2=bar&=baz" |
というような文字リテラルでOKです。
HTML内でのonclick=などの属性値ではContent-Script-Typeがapplication/javascript(text/javascript)の場合
|
1 2 3 |
<... onclick="x="/?hoge=123&amp=567"">とか <... onclick="x='/?hoge=123&amp=567';">とか <... onclick='x="/?hoge=123&amp=567";'> |
のようになります。<script>で記述する場合は内容モデルがHTMLではCDATA, XHTMLでは#PCDATA(下記参照)という別な話が登場して終わらなくなってしまいますので機会があれば別途。とにかく外部ファイルにしてしまうと 決めていれば稀な場合でも大きな問題にならないはずです。
優れたバリデータは文法エラーは当然のこと、誤った処理をさせる部分を検出して警告してくれるので活用されると良いかもしれません。
なお、弊社遊び場の中のFlashアプリの ページでは、ActiveX用とNetscape式plugin用さらにはSWFObject用に同じパラメータを何度も書かなければいけないという問題 とSWFObjectだけではJavaScript依存にしてしまうという問題を解決し、かつActiveXでなくても古いFlash Playerが入っていればExpress Installationが起動するというちょっと素敵なやり方をしています。機会があればご紹介します。
長くなりましたが、以下に根拠となる仕様書(一部ですが)のリンクと、簡単な説明をまとめてみました。ぜひご自身でも読み解いて、上に書かれていることが本当か確認してください。間違いがあったらぜひコメントをお願いします。
<param>要素のvaue=属性の値に関する仕様書の一部の超訳
- HTML 4.01:CDATAです。: http://www.w3.org/TR/1999/REC-html401-19991224/struct/objects.html#edef-PARAM
- XHTML 1.0 Strict:CDATAです。: http://www.w3.org/TR/2002/REC-xhtml1-20020801/dtds.html#dtdentry_xhtml1-strict.dtd_param
<a>要素,<link>要素のhref=属性の値に関する仕様書の一部の超訳
-
- <a>要素のhref=属性
- HTML 4.01:%URIです。: http://www.w3.org/TR/1999/REC-html401-19991224/struct/links.html#edef-A
- <link>要素のhref=属性
- HTML 4.01:%URIです。: http://www.w3.org/TR/1999/REC-html401-19991224/struct/links.html#edef-LINK
- HTML 4.01:%URIはCDATAです。: http://www.w3.org/TR/1999/REC-html401-19991224/sgml/dtd.html#URI
- XHTML 1.0 Strict:%URIです。: http://www.w3.org/TR/2002/REC-xhtml1-20020801/dtds.html#dtdentry_xhtml1-strict.dtd_a
- XHTML 1.0 Strict:%URIはCDATAです。: http://www.w3.org/TR/2002/REC-xhtml1-20020801/dtds.html#dtdentry_xhtml1-strict.dtd_URI
属性値の場合のCDATAに関連する仕様書の一部の超訳
- HTML 4.01:CDATAは文書文字集合のシーケンスで、文字実体を含むことができる。ユーザエージェントは属性値を次のように解釈するべきである。文字実体を文字で置きかえる。LFを無視する。CRやTABは各々SPに置き換える。: http://www.w3.org/TR/1999/REC-html401-19991224/types.html#h-6.2
- HTML 4.01(SGML tutorial):属性値はダブルクォートかシングルクォートで括る。決められた文字だけの場合は括らなくてもいいけど。数値文字参照を利用し て"でダブルクォート、'でシングルクォートを値に含められるし、ダブルクォートで括られている場合は文字実体参照を利 用して"でシングルクォートを値に含められる。: http://www.w3.org/TR/1999/REC-html401-19991224/intro/sgmltut.html#h-3.2.2
- XML 1.0: ダブルクォートかシングルクォートで括る。<と&と括り始めのクォート以外の文字、あるいは「参照」で構成される。: http://www.w3.org/TR/2008/REC-xml-20081126/#NT-AttValue
- XML 1.0: 参照は、実体参照(例:")か、文字参照(例:",")である。: http://www.w3.org/TR/2008/REC-xml-20081126/#NT-Reference
- XHTML 1.0: SGMLでもXMLでも&(ampersand character)は実体参照の開始宣言であるが、不幸にも多くのHTMLユーザエージェントは変な実体参照でも問題をシカトして先に進んでしまう。 XMLユーザエージェントはこの不正な使用を認められない: http://www.w3.org/TR/2002/REC-xhtml1-20020801/#C_12
- HTML 5 (右は訳ではなくて注釈):今までのHTMLではそのものすばりと書かれていなかったようだけど、ついにどうやって間違った文法(前出のHTMLの場合で は&=を&y=にしたり、©=を©dayo=にするといった悲しくも不正な回避方法が使わ れてしまった場合)をパースし続けるかが定義(恐るべし膨大なレガシー資産パワー!)される模様。: (このリンク先はレンダリングするのに結構リソース消費します。クリックするときは注意してください)http://dev.w3.org/html5/spec/Overview.html#tokenizing-character-references
<script>要素に関する仕様書の一部の超訳(参考)
- HTML 4.01:「内容モデル(要は<script>と</script>の間)」は%Scriptです。: http://www.w3.org/TR/1999/REC-html401-19991224/interact/scripts.html#h-18.2.1
- HTML 4.01:%ScriptはCDATAです。: http://www.w3.org/TR/1999/REC-html401-19991224/sgml/dtd.html#Script
- XHTML 1.0 Strict:内容モデルは#PCDATAです。: http://www.w3.org/TR/2002/REC-xhtml1-20020801/dtds.html#dtdentry_xhtml1-strict.dtd_script
要素内容の場合のCDATAに関連する仕様書の一部の超訳(参考)
- HTML 4.01:<style>と<script>では、</が登場するまでを生のまま(数字文字参照や文字実体参照は解釈されません)でアプリケーションに渡してね。: http://www.w3.org/TR/1999/REC-html401-19991224/types.html#h-6.2
- XML 1.0 (参考。CDATA自体の説明ではありません): CDATA sectionは<![CDATA[で始まって、]]>が出てくるまでの中身をマークアップと解釈しない。: http://www.w3.org/TR/2008/REC-xml-20081126/#sec-cdata-sect
- XML 1.0 (参考。CDATA自体の説明でありません): 文字データとマークアップについて: http://www.w3.org/TR/2008/REC-xml-20081126/#syntax
Adobe.comでの説明(頻繁にURLが変わりpermalinkも無いのでたまに修正していますがリンク切れの場合がしょちゅうあります)(参考) (サンプルは適切でないです。修正されることはなさそうです。)
- TechNote (Knowledge Base): <PARAM NAME=FlashVars VALUE=”foo=Hello%20Worldgraph=first+line%0Dsecond+line”> の部分はおそらく
VALUE="foo=Hello%20World&paragraph=first+line%0Dsecond+line"の意図で書かれたものと思われますが、graphの前に&すらなくなってしまっているのでサンプルの意味がとてもあいまいになってしまっています(2010/1/14時点)。Macromediaからのお引っ越しの際にでも発生したエラーでしょうか: Using FlashVars to pass variables to a SWF - Flex 4: この説明文の<param>等のHTMLでFlashVarsを使用しているもののうち、&lastname=の部分(2010/1 /14時点)は、勝手にlastnameが文字実態参照に使われないことを暗黙のうちにリザーブしています。lastname部分をampやquotやcopyやnbspやltやgtや…にした場合は動作しないことを記載するか、あるいは普通にXHTMLでもHTMLでもampやquotやcopyという変数を渡したいときでも百万が一にも文字実体参照に&lastname;が追加された場合も使えるサンプルにするためにも、
&lastname=を使用するのが妥当と考えられます: Passing request data with flashVars properties – Communicating with the wrapper - Developer Connection: ユーザの入力を動的にFlashVarsに渡すような場合、%エンコードすることの重要性やURLのような場合はスキーマやホストの確認なども重要であることが書かれています。一読をお勧めします。: Creating more secure SWF web applocations
2010/4/13 文章校正(項目の順序入れ替え)
PivotXのユーザ登録で”_”(アンダースコア)が使えない
PivotXのマニュアルやヘルプによるとアンダースコアが使えるはずなのですが、Administration → Usersから登録しようとすると、入力時にアンダースコアが”-“(ハイフン)に自動的に置換されてしまいます。
pivotx/includes/js/pivotx.jsのsetSafename()を修正すれば良いのですが、サーバー側のコードのバリデーションが足りないことにも気付きました。JavaScriptの修正と合わせて、2009/5/19のpivotx-latest.tgzとsvnリリース2278用にパッチを作って報告してみました。
