AS3のリファレンスマニュアルをサジェスト機能付きで検索
ActionScript3.0 マニュアル検索
*
* 入力エリアに探したいクラス名の一部を入力すると、候補が下のエリアに出てきます。
* 矢印キーで選択し、リターンでリファレンスマニュアルのページへジャンプ出来ます。
* マウスでジャンプしたいクラスをクリックしてもジャンプ出来ます。
* [2009-01-14] スペースでつなげるとand検索出来ます
* [2009-01-14] ちょっとバグ修正しました
*
* 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
* (保)メソッド検索まで出来たら最高!!
*
/**
* Copyright ongaeshi ( http://wonderfl.net/user/ongaeshi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/3cWm
*/
/*
* ActionScript3.0 マニュアル検索
*
* 入力エリアに探したいクラス名の一部を入力すると、候補が下のエリアに出てきます。
* 矢印キーで選択し、リターンでリファレンスマニュアルのページへジャンプ出来ます。
* マウスでジャンプしたいクラスをクリックしてもジャンプ出来ます。
* [2009-01-14] スペースでつなげるとand検索出来ます
* [2009-01-14] ちょっとバグ修正しました
*
* 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.net.URLLoader;
import flash.net.URLRequest;
import flash.text.*;
[SWF(width=465, height=465, backgroundColor="0xE6F7FA")]
public class Main extends Sprite {
private var classSearch_:ClassSearch;
private var result_:ResultList;
private var searchWord_:String = "";
public function Main() {
// クラス検索
classSearch_ = new ClassSearch(onLoadEnd);
// 検索バー
var searchWord:TextField = new TextField();
searchWord.text = "検索:";
searchWord.width = 33;
searchWord.height = 18;
searchWord.x = 2;
searchWord.y = 2;
searchWord.textColor = 0x000000/*param.search.textColor*/;
addChild(searchWord);
//テキスト入力欄
var title:TextField = new TextField();
title.text = "";
title.width = 426;
title.height = 18;
title.x = 36;
title.y = 2;
title.border = true;
title.borderColor = 0x000000/*param.title.boarderColor*/;
title.background = true;
title.backgroundColor = 0xffffff/*param.title.bgColor*/;
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();
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 = [];
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 = 21;
public function ResultList() {
x = 5;
y = 25;
graphics.lineStyle(1, 0x000000);
graphics.beginFill(0xA6CAF0/*Main.param.result.bgColor*/);
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]);
result.x = 10;
result.y = 20 * 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_ == -1) ? 0 : cursorPos_].browser();
}
}
class Result extends Sprite {
private var data_:Object;
private var textField_:TextField;
public function Result(data:Object) {
data_ = data;
textField_ = new TextField();
textField_.width = 426;
textField_.height = 20;
textField_.x = 2;
textField_.htmlText = "<a href=\"" + data.link + "\">" + data.name + "</a>";
textField_.background = false;
textField_.backgroundColor = 0xFC928A/*Main.param.result.focusBgColor*/;
addChild(textField_);
}
public function focus():void {
textField_.background = true;
}
public function unfocus():void {
textField_.background = false;
}
public function browser():void {
navigateToURL(new URLRequest(data_.link));
}
}