PukiWikiの添付ファイル使用時、ローカルファイルをドラッグ&ドロップしたい(残念賞版)
突然ですが、WikiWikiって便利ですよね。
自分は、個人的なメモは PukiWikiにメモっています。今だったら、Google DocumentとかにEvernoteにメモるというのもアリなんでしょうけど、貧弱なマシンには ちとリッチ過ぎるし、アクセス管理も自分で管理できるので、よく使っています。
で、よく使うPukiWikiなんですが、時折「うぎゃ〜」と叫ぶ事があります。
それは、添付ファイルのパス指定の時なんです。
…何で、アップロードするファイルを、ファイル入力欄にドラッグ&ドロップさせてくれないの?
1 posted by (C)wacky
セキュリティとか言われたら、まぁ納得するしか無いんですが、Googleのウェブアルバムでは、ドロップエリアにファイルをドラッグ&ドロップして、アップロード出来るんですね。
2 posted by (C)wacky
そうだよ。これがやりたいんだよ!
一々ファイルダイアログを開いて、アップロードするファイルをヘコヘコ選択していくなんて、前時代的な真似は やりたくないんだよ。
ついでに言うと、今使っているブラウザで、それがやりたいんだよ。
HTML5なら〜とか、足切りは勘弁してちょーだい。
という訳で、どうやれば出来るか、奮闘してみました。
情報収集
余談ですが、このファイル入力欄へのドラッグ&ドロップですが、Chromeだとデフォルトで出来ちゃいます。
なので、今回のネタはIEオンリーです。(FireFoxも、最新版だと出来るみたいだし〜)
まずは、Googleのウェブアルバムですが、ソースを眺めてみると、どうやらドロップエリアは、ActiveXコントロールっぽいです。
他に方法が無いのか?と言うと、↓このWeb siteでの検証では、ActiveXとFTP、クリップボードぐらいしか無い模様。
- ブラウザUIにおける効率のよいファイルアップロード|blog|たたみラボ
http://www.tatamilab.jp/rnd/archives/000127.html
FTPの代わりに、WebDAVを使う自作プラグインが、PukiWikiのオフィシャルサイトにあります。
- 自作プラグイン/dav.php - PukiWiki-official
http://pukiwiki.sourceforge.jp/?%E8%87%AA%E4%BD%9C%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3%2Fdav.php
他には、オフィシャルサイトに、複数ファイルをアーカイブしたファイルをアップロードする事で、サーバー先で展開して格納してくれる。という自作プラグインもあるようです。これは、考え方の勝利という奴ですね。
方針決定
先のオフィシャルサイトの自作プラグインを検討したのですが、やっぱり「ドラッグ&ドロップしたい」んじゃぁ。という事で、ActiveXを貼り付けて、そこからパスをゲットする方法を検討します。
暫くググると、そのものズバリなものが見つかりました。
- Tip: Drag & Drop Files into I.E. (JScript/OLE) - CodingForums.com
http://codingforums.com/showthread.php?t=36896
コードのキモは、objectタグでActiveXコントロールを貼り付ける際、OleDropMode プロパティを有効に設定する事と、OLEDragDropイベントでキャッチしたら、パス情報を取得する所みたいです。
<object id="IAnimation" classid="clsid:B09DE715-87C1-11D1-8BE3-0000F8754DA1"> <param name="OleDropMode" value="1"> </object> <script type="text/JScript"> function IAnimation::OLEDragDrop(Data){ if(Data.GetFormat(15)){ var O = ""; var e = new Enumerator(Data.Files); while(!e.atEnd()){ O += e.item() + "\n"; e.moveNext(); } output.value = O; BackColor=0x80000003;} }
↑上で使っているActiveXはAnimationコントロールのようです。が、調べていくと、最近のWindowsのパッチで、このコントロールがWeb上で使えないよう Kill Bit指定されているようです。
他に、OleDropModeできるようなActiveXが無いものか?と調べていくと、某掲示板でグッドな情報が記載されています。うまうま。
833 :デフォルトの名無しさん:2008/05/29(木) 23:01:44 ああスマン Clipboard.HTAってウィンドウにD&Dしたファイルをクリップボードにコピーするスクリプトなんだけど その「D&Dしたファイルを拾う方法」以外に無いの? って事 Clipboard.HTAから最低限必要な部分だけを切り取ると <object id="dd_1c" classid="CLSID:8E3867A3-8586-11D1-B16A-00C0F0283628" > <PARAM NAME="OLEDropMode" VALUE="1"><PARAM NAME="Style" VALUE="1"><PARAM NAME="Simpletext" VALUE="ここにD&D"> </object> function dd_1c::OLEDragDrop(Data,e){ //Data.Files.;DDしたファイルの数 //Data.Files.Item(n);n=1〜でDDしたファイルのフルパス if(e==7){ //こっちはファイルです }else{ //こっちはファイル以外の何か } } で、objectにファイルをD&DするとData.Files.Item(n)にD&Dしたファイルのパスが取得出来るんだけど この方法、「オブジェクトにD&Dしたファイルを拾う」事しか出来ないから、 「このテキストボックスにファイルをD&Dしたら…」って事は出来ないんだよ だから他の方法無いかなって
上の情報を組み合わせてみると、ローカルファイルを、IEにドラッグ&ドロップしてファイルパスを得られる事が判りました。
越えられない壁
ファイルパスを得られたら、INPUTタグのファイル入力欄に、スクリプトで書き込めば完了だ。と思ったのですよ。
が、そうは問屋が卸さないようで、TYPE='FILE'指定のかかったものは、スクリプトで設定出来ない模様。
確かに、直接ファイル入力欄にキー入力しようとしても、入力すらさせてくれない…。
調べていくと、昔はクリップボード経由でINPUTタグに入れる事も出来たようですが、現在は それも適わない模様。
セキュリティ厳しいなぁ。…まぁ、当然か。
TYPE='TEXT'指定に変えて、逃げる手も考えたのですが、他に弄らないといけないコードが多い事に気付いて、もう八方塞りに陥りました。orz
(PHPの言語仕様知らないし〜)
挫折
という訳で、
までは、実現する事にし、その後は
- 人間の手で貼り付け&閉じる&アップロードを行ってもらう。
という中途半端な対応となりました。
以下に、plugin/attach.inc.php プラグインに対する、パッチコードを示します。(1.4.7で確認済み)
--- F:\Wacky\Test\pukiwiki\attach.inc.php 2010-09-05 17:07:25.281250000 +0900 +++ F:\Wacky\Test\pukiwiki\attach.inc.php.new 2010-09-05 17:07:33.578125000 +0900 @@ -419,11 +419,32 @@ <span class="small"> $msg_maxsize </span><br /> - <label for="_p_attach_file">{$_attach_messages['msg_file']}:</label> <input type="file" name="attach_file" id="_p_attach_file" /> + <label for="_p_attach_file">{$_attach_messages['msg_file']}:</label> <input type="file" name="attach_file" id="_p_attach_file"/> $pass <input type="submit" value="{$_attach_messages['btn_upload']}" /> </div> </form> +<!-- IE only --> +<object id="DnD_Box" classid="clsid:8E3867A3-8586-11D1-B16A-00C0F0283628" width="350" height="100"> + <param name="OleDropMode" value="1"> + <param name="Style" value="1"> + <param name="SimpleText" value="In this area, please do Drag & Drop of a file."> + <param name="allowScriptAccess" value="always"> +</object> +<script type="text/JScript"> +function DnD_Box::OLEDragDrop(Data){ + if(Data.GetFormat(15)){ + var O = ""; + var e = new Enumerator(Data.Files); + O = e.item(); + //alert(O); + DnD_Box.SimpleText = O; + clipboardData.setData("Text", O); // ファイルパスをクリップボードへ + //document.getElementById("_p_attach_file").value = clipboardData.getData("Text"); + document.getElementById("_p_attach_file").click(); // ファイルダイアログを開くだけ + } +} +</script> EOD; }
最後に
という訳で、今回は途中挫折という結果に陥りました。
もし、HTMLに詳しい方が居られましたら、完全版を作って頂けないかな?と思う次第であります。まる。