/* * ActionScript3.0 マニュアル検索 * * 入力エリアに探したいクラス名の一部を入力すると、候補が下のエリアに出てきます。 * 矢印キーで選択し、リターンでリファレンスマニュアルのページへジャンプ出来ます。 * マウスでジャンプしたいクラスをクリックしてもジャンプ出来ます。 * * Yahoo! Pipes * http://pipes.yahoo.com/pipes/pipe.info?_id=68fa588146242e845cbac5f0ce3804a2 * * 全クラス一覧 * http://livedocs.adobe.com/flash/9.0_jp/ActionScriptLangRefV3/class-summary.html * * やりたいこと * (済)マニュアルへのリンクを貼る * (済)謎の'detail'は表示しない * (済)高速化(余分な探索をやめる) * (済)名前空間等、補足情報も表示する * (済)名前、リンク先が重複しているものがあれば削除 * (済)リンクへのジャンプショートカット(Ctrl+数字キーとか) * (済)起動時にキーワード指定無しで起動 * (済)カーソルが表示されていない状態を作る * (済)数が多い場合は最大表示数を絞る? * (済)キーワードに変化が無い場合は再探索を行わない(矢印キーを押した時など) * * スペースはand検索扱いにする * 正規表現を使用可能に * 大文字が一つでも入った場合は完全一致検索に切り替える * 起動時にフォーカスを検索フィールドへ * 検索ヒット数を出す * 検索対象が1ページ以上ある場合のスクロール機能 * パラメータの整理 * * Tweener等の外部ライブラリも対象に含める * * (保)ショートカットキーに Ctrl+j, Ctrl+k * (保)メソッド検索まで出来たら最高!! * */ package { import flash.display.*; import flash.events.*; import flash.geom.Matrix; import flash.net.URLLoader; import flash.net.URLRequest; import flash.text.*; import net.wonderfl.utils.SequentialLoader; [SWF(width=465, height=465, backgroundColor="0x000000")] public class Main extends Sprite { private var classSearch_:ClassSearch; private var result_:ResultList; private var searchWord_:String = ""; private var imageArray:Array=[]; public function Main() { SequentialLoader.loadImages(["http://assets.wonderfl.net/images/related_images/9/95/9521/9521a32ed3c63d23deee86cbdc2939f65c135a90"], imageArray, onLoaded); } private function onLoaded():void { var loader:Loader=imageArray.pop(); var temp:BitmapData = new BitmapData(465, 556, true, 0x00FFFFFF); temp.draw(loader); var searchBMPD:BitmapData = new BitmapData(465, 48, false); searchBMPD.draw(temp); var searchBMP:Bitmap = new Bitmap(searchBMPD); addChild(searchBMP); var searchFocusBMPD:BitmapData = new BitmapData(465, 48, false); var matrix:Matrix = new Matrix(); matrix.ty = -48; searchFocusBMPD.draw(temp, matrix); var searchFocusBMP:Bitmap = new Bitmap(searchFocusBMPD); searchFocusBMP.alpha = 0; addChild(searchFocusBMP); stage.addEventListener(MouseEvent.MOUSE_MOVE, function():void { if (mouseY <= 48) { searchFocusBMP.alpha += (1 - searchFocusBMP.alpha) * 0.1; } else { searchFocusBMP.alpha += (0 - searchFocusBMP.alpha) * 0.1; } }); var backgroundBMPD:BitmapData = new BitmapData(465, 416); matrix = new Matrix(); matrix.ty = -96; backgroundBMPD.draw(temp, matrix); var backgroundBMP:Bitmap = new Bitmap(backgroundBMPD); backgroundBMP.y = 48; addChild(backgroundBMP); var resultBMPD:BitmapData = new BitmapData(465, 43, true, 0x00FFFFFF); matrix = new Matrix(); matrix.ty = -513; resultBMPD.draw(temp, matrix); // クラス検索 classSearch_ = new ClassSearch(onLoadEnd); //テキスト入力欄 var title:TextField = new TextField(); title.defaultTextFormat = new TextFormat("_ゴシック", 20); title.text = ""; title.width = 386; title.height = 26; title.x = 54; title.y = 11; title.border = false; title.background = false; title.textColor = 0x000000/*param.title.textColor*/; title.type = TextFieldType.INPUT; title.addEventListener(KeyboardEvent.KEY_UP, onKeyUp); title.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown); addChild(title); //結果表示 result_ = new ResultList(resultBMPD); addChild(result_); } private function onLoadEnd(e:Event):void { var r:Array = classSearch_.search(""); result_.update(r); } private function onKeyDown(e:KeyboardEvent):void { // ロード完了するまでは何もしない if (!classSearch_.isLoad()) return; // 上へ if (e.keyCode == 38) { result_.up(); return; } // 下へ if (e.keyCode == 40) { result_.down(); return; } } private function onKeyUp(e:KeyboardEvent):void { // ロード完了するまでは何もしない if (!classSearch_.isLoad()) return; // リンク先へジャンプ if (e.keyCode == 13) { result_.browser(); return; } //検索(キーワードに変化があった時に検索) if (searchWord_ != e.currentTarget.text) { var r:Array = classSearch_.search(e.currentTarget.text); result_.update(r); searchWord_ = e.currentTarget.text; } } } } import flash.display.*; import flash.events.*; import flash.net.*; import flash.text.*; import flash.geom.*; import com.adobe.serialization.json.JSON; class ClassSearch { private var data_:Array = []; private var isLoad_:Boolean = false; public function ClassSearch(listener:Function) { // テキストの読み込み var myURLLoader:URLLoader = new URLLoader(); myURLLoader.addEventListener(Event.COMPLETE, onCompleteJSON); myURLLoader.addEventListener(Event.COMPLETE, listener); //YahooPipesの汎用feedPage var jsonURL:String = "http://pipes.yahooapis.com/pipes/pipe.run?_id=68fa588146242e845cbac5f0ce3804a2&_render=json&url="; //encodeURIComponentでエスケープして、feedProxyにくっつける。 jsonURL += encodeURIComponent("http://livedocs.adobe.com/flash/9.0_jp/ActionScriptLangRefV3/class-summary.html"); //アドレスを変えるとrubyのリファレンスマニュアルになる //jsonURL += encodeURIComponent("http://doc.okkez.net/static/192/library/_builtin.html"); myURLLoader.load(new URLRequest(jsonURL)); } private function onCompleteJSON(e:Event):void { // jsonとして受け取る var json:Object = JSON.decode(e.target.data); // 検索用テキスト var text:String = json.value.items[0].content; // リンクを収集 var pattern:RegExp = /<a.+?href="(.+?)">(.+?)<\/a>/ig; var match:Object = pattern.exec(text); while (match != null) { // trace(match[1], match[2]); var obj:Object = new Object(); obj["name"] = match[2]; obj["link"] = match[1]; //trace(obj.name, obj.link); data_.push(obj); match = pattern.exec(text); } // リンクの重複削除 var tmp:Array = []; for each (var d:Object in data_) { // クロージャってやつ var isEqual:Function = function callback(item:*, index:int, array:Array):Boolean { return d.name == item.name && d.link == item.link; }; // 最初の一回目に見つかったもののみ登録 if (!tmp.some(isEqual)) tmp.push(d); } data_ = tmp; // ロード完了 isLoad_ = true; } public function search(input:String):Array { var results:Array = []; if (input != ""){ var keywords:Array = input.split(" "); for each (var d:Object in data_) { var isMatch:Boolean = true; for each (var keyword:String in keywords) { if (d.name.search(new RegExp(keyword, "i")) == -1) { isMatch = false; } } if (isMatch) { results.push(d); } } } return results; } public function isLoad():Boolean { return isLoad_; } } class ResultList extends Sprite { private var results_:Array = []; private var cursorPos_:int = -1; private const LINE_NUM:int = 12; private var bitmapData:BitmapData; public function ResultList(bmpd:BitmapData) { y = 48; bitmapData = bmpd; /*graphics.lineStyle(1, 0x000000); graphics.beginFill(0xA6CAF0); graphics.drawRect(0, 0, 455, 426); graphics.endFill();*/ } public function clear():void { for each (var r:Result in results_) { removeChild(r); } results_ = []; cursorPos_ = -1; } public function update(data:Array):void { clear(); var num:int = Math.min(data.length, LINE_NUM); for (var i:int = 0; i < num; i++) { var result:Result = new Result(data[i], bitmapData); result.x = 0; result.y = 34 * i; results_.push(result); addChild(result); } } public function up():void { if (cursorPos_ == -1) { cursorPos_ = 0; } else { results_[cursorPos_].unfocus(); cursorPos_ -= 1; if (cursorPos_ < 0) { cursorPos_ = Math.max(results_.length - 1, 0); } } results_[cursorPos_].focus(); } public function down():void { if (cursorPos_ == -1) { cursorPos_ = 0; } else { results_[cursorPos_].unfocus(); cursorPos_ += 1; if (cursorPos_ > results_.length - 1) { cursorPos_ = 0; } } results_[cursorPos_].focus(); } public function browser():void { results_[cursorPos_].browser(); } } class Result extends Sprite { private var data_:Object; private var textField_:TextField; public function Result(data:Object, bmpd:BitmapData) { buttonMode = true; data_ = data; var bmp:Bitmap = new Bitmap(bmpd); addChild(bmp); var bmp2:Bitmap = new Bitmap(bmpd); bmp2.alpha = 0.5; addChild(bmp2); textField_ = new TextField(); textField_.width = 426; textField_.height = 20; textField_.x = 2; textField_.y = 1; textField_.text = data.name; textField_.mouseEnabled = false; textField_.background = false; var textField2_:TextField = new TextField(); textField2_.width = 426; textField2_.height = 20; textField2_.x = 2; textField2_.y = 2; textField2_.alpha = 0.5; textField2_.text = data.name; textField2_.mouseEnabled = false; textField2_.background = false; textField2_.textColor = 0xFFFFFF; addChild(textField2_); addChild(textField_); addEventListener(MouseEvent.ROLL_OVER, function():void { bmp2.alpha = 1; }); addEventListener(MouseEvent.ROLL_OUT, function():void { bmp2.alpha = 0.5; }); addEventListener(MouseEvent.CLICK, function():void { navigateToURL(new URLRequest(data_.link), "_blank"); }); } } (見た目変えただけ)AS3のリファレンスマニュアルを検索