Jun 13

发现了个调试WEB-flash的小宝贝“FlashFireBug”,可以抛弃“xray”了

ActionScript3.0
重装系统后,要下载firebug,无意发现个插件叫“FlashFireBug”,看名字是FLASH调试插件,于是安装看看
效果相当好,下面说说安装步骤和使用说明

一、先安装插件地址
二、然后下载as3的FlashFireBug类库,怎么引用包不用讲了吧

压缩包里有com.adobe的类库,有用到json。 还有包 ominds 和 utility。
我在想为什么不把他们放在一起,估计utility里的CharacterEntity类不是作者原创,所以..........
三、把ominds.Firebug 类替换为如下代码

package ominds{

  import flash.display.*;
  import flash.events.*;
  import flash.geom.*;
  import flash.utils.*;
  import flash.net.*;
  import flash.xml.XMLNode;
  import flash.external.ExternalInterface;
  import flash.system.Security;
  import com.adobe.serialization.json.*;
  import flash.filters.GlowFilter;
  import utility.CharacterEntity;
  
  public class Firebug extends MovieClip {

    private static  var root:*;
    private static  var id:String;
    private static  var  name:String = "";
    private static  var  url:String = "";
    private static  var  swfVersion:String = "";
    private static  var overlay:MovieClip;
    private static  var overlayBitmap:Bitmap;
    private static  var selectedObject;    
    private static  var isReady;    
    private static  var  currentVersion:String = "1.3.0";  
    private static  var  latestVersion:String = "";
    private static  var  versionURL:String = "http://www.o-minds.com/products/flashfirebug/version";
    
    public function Firebug() {
      trace("flash for firebug is a static class and should not be instantiated.");
    }

    //------------------------------------------------ inspect functions

    public static function startInspect(mainObject:Object) {// activate auto inspect 
      mainObject.addEventListener(MouseEvent.MOUSE_OVER,inspect_selected);
    }
    public static function stopInspect(mainObject) {// de-activate auto inspect 
      mainObject.removeEventListener(MouseEvent.MOUSE_OVER,inspect_selected);
    }
    private static function inspect_selected(evt:MouseEvent) {
      if (evt.target!=evt.currentTarget) {
        inspect(evt.target);
      }
    }
    public static function inspect(obj:Object) {
      //***************************** Object inspect functions
      trace("name: "+obj.name);
      trace("************************ class");
      inspect_class(obj);
      inspect_inherit(obj);
      trace("************************ properties");
      inspect_properties(obj);
      trace("************************ methods");
      inspect_methods(obj);
    }

    public static function inspect_properties(_obj:*) {
      var _description:XML = describeType(_obj);
      var _properties:Array = new Array();
      for each (var prop:XML in _description.accessor) {
        var _property:Object = new Object();
        _property.name = String(prop.@name);
        _property.type = String(simple_type(prop.@type));
        _property.access = String(prop.@access);
        try {
          if (_property.type == "ByteArray"){
            _property.value = "ByteArray";
          }else{
            _property.value = CharacterEntity.encode(String(_obj[_property.name]));
          }
        } catch (e) {
          _property.value = "" ;
        }
        _properties.push(_property)
      }
      _properties.sortOn("name");
      return _properties;
    }

    public static function inspect_methods(_obj:*) {
      var _description:XML=describeType(_obj);
      for each (var _method:XML in _description.method) {
        var _method_name:String=_method.@name;
        var _method_type:String=_method.@returnType;
        var _method_parm:String="";

        var _method_parms:Array=new Array;
        for each (var param:XML in _method.parameter) {
          _method_parms.push(param.@optional=="false"?simple_type(param.@type):"["+simple_type(param.@type)+"]");
        }
        _method_parm=_method_parms.join(",");
        trace(_method_name+"("+_method_parm+"):"+simple_type(_method_type));
      }
    }


    public static function inspect_inherit(_obj:*) {
      var _description:XML=describeType(_obj);
      var inheritance:String="";
      var inheritances:Array=new Array;
      for each (var exclass:XML in _description.extendsClass) {
        inheritances.push(simple_type(exclass.@type));
      }
      inheritance = inheritances.join(" ► ");
      return inheritance;
    }

    public static function inspect_class(_obj:*) {
      var _description:XML    = describeType(_obj);
      var _classInfo:Object   = new Object();

      _classInfo.packageName  = String(_description.@name).split("::")[0];
      _classInfo.className    = String(_description.@name).split("::")[1];
      _classInfo.isDynamic    = Boolean(_description.@isDynamic);
      _classInfo.isStatic     = Boolean(_description.@isStatic);
      _classInfo.isFinal      = Boolean(_description.@isFinal);

      return _classInfo;
    }
    
    public static function inspect_constantValues(className:String) {
      var ValidValues:Class = getDefinitionByName(className) as Class;  
      var _description:XMLList = describeType(ValidValues).constant;
      var _constants:Array = new Array();
      for each (var _cons in _description) {
        var _constant:Object = new Object();
        _constant.type = _cons.@type;
        _constant.name = _cons.@name;
        _constant.value = ValidValues[_cons.@name];
        _constants.push(_constant);
      }
      return _constants;
    }    
    public static function traceOut(... arguments) {
      for (var i:uint = 0; i < arguments.length; i++) {
            arguments[i] = CharacterEntity.encode(arguments[i]);
        }
      sendToFlashFirebug({command:"traceOut",args:arguments});
    }
    public static function clearOut() {
      sendToFlashFirebug({command:"clearOut"});
    }    
    //---------------------------------------------- children tree and target object 

    public static function getDisplayTree(dispObj:*) {
      var treeObj:Array = new Array();
      if (dispObj.numChildren) {
        for (var i:int=0; i < dispObj.numChildren; i++) {
          var obj:* = dispObj.getChildAt(i);
          var object:Object = new Object();
          if (obj is DisplayObjectContainer) {
            object.isContainer = true;
            object.hasChildren = (obj.numChildren > 0);
          }
          object.name = obj.name;
          object.index = i;
          object.className = inspect_class(obj).className;
          object.packageName = inspect_class(obj).packageName;
          treeObj[i]  = object;
        }
      }
      return treeObj;
    }

    private static function getDisplayObject(absName:String) {
      if (absName=="root") {
        return root;
      }
      var absNameArray:Array = absName.split(".");
      var myObject:* = root;
      for (var i = 0; i< absNameArray.length; i++) {
        myObject = myObject.getChildAt(absNameArray[i]);
      }
      return myObject;
    }
    public static function displayObjectPath(avDisplayObject : DisplayObject){
      var lvPath:String = "";
      do{
        if( avDisplayObject.name ) lvPath = avDisplayObject.name + ( lvPath == "" ? "" : "." + lvPath );
      } while( avDisplayObject = avDisplayObject.parent );
      return lvPath;
    }    
    //---------------------------------------------- private functions

    private static function simple_type(_type:String) {
      var lastIndex=_type.lastIndexOf("::");
      _type=lastIndex>0?_type.substr(lastIndex+2):_type;
      return _type;
    }
    //---------------------------------------------- start connection
    public static function connect(scope:*) { 
      if(!root){ // if root then it's already connected
        // remove domain security
        Security.allowInsecureDomain("*");
  
        // adding the interface 
        if (ExternalInterface.available) {
          ExternalInterface.addCallback('fromFlashFirebug',getFromFlashFirebug);
        }
        // set the scope root
        root = scope;
  
        // inite inspector overlay
        overlay = new MovieClip();
        overlay.filters = [new GlowFilter()];
        overlayBitmap = new Bitmap(new BitmapData(root.stage.width,root.stage.height,true,0x000000),'auto',true);
        overlay.addChild(overlayBitmap);
        overlay.alpha = 0.5;
        overlay.mouseEnabled = false;
        overlay.target = null;
        root.parent.addChild(overlay);
        
        // get the latest version info
        loadLatestVersion();
        
        // add the eventlisteners 
        root.loaderInfo.addEventListener(Event.COMPLETE, onLoaded);
      }
    }
    
    private static function onLoaded(evt:Event) {
      root.addEventListener(Event.ENTER_FRAME,update);
    }
    
    private static function ifReady() {
      if(id && latestVersion){
        isReady = true;
        name = (root.loaderInfo.url).split("/").pop();
        url = root.loaderInfo.url;
        swfVersion = root.loaderInfo.swfVersion;
        sendToFlashFirebug({command:"ready",name:name,url:url,current:getCurrentVersion(),latest:getLatestVersion()});
        getTree({target:"root"});
      }else if(!id){
        sendToFlashFirebug({command:"refreshIds"});
      }
    }
    
    private static function update(evt:Event) {
      // ------------------------------- update get Ready
      if(!isReady){
        ifReady();
      }
      // ------------------------------- update Overlay
      cleanOverlay();
      if (overlay.target != null ){
        var overlayColorTransform:ColorTransform = overlay.target.transform.colorTransform;        
        overlayColorTransform.color = 0x9FD8EF;
        overlayBitmap.bitmapData.draw(overlay.target,overlay.target.transform.concatenatedMatrix,overlayColorTransform ,null,null,true);
      }
    }
    
    //---------------------------------------------- externalInterface
    private static function sendToFlashFirebug(data:*) {
      data.id = id;
      data = JSON.encode(data);
      if (ExternalInterface.available) {
        ExternalInterface.call('toFlashFirebug',data);
      }
    }
    private static function getFromFlashFirebug(data:*) {
      data = JSON.decode(data);
      var command = data.command;
      var listenerId = data.id;
      if (Firebug[command] && ( id == listenerId || listenerId == null || command=="setId") ) {
        Firebug[command](data);// dynamic functions ;)
      }
    }
    // --------------------------------------------- dynamic connector functions
    private static function setId(data) {
      id = data.id;
    }
    private static function getTree(data) {
      try{
        var displayObject = getDisplayObject(data.target);
        var displayTree = getDisplayTree(displayObject);
        var target_path = data.target;
        sendToFlashFirebug({command:"setTree",tree:displayTree,target:target_path});
      }catch(e){
        // catch get tree errors
      }
    }
    private static function selectObject(data) {
      selectedObject = getDisplayObject(data.target);
      var inherit_info = inspect_inherit(selectedObject);  
      var class_info = inspect_class(selectedObject);
      var target_path = displayObjectPath(selectedObject);
      var  target_name = selectedObject.name;
      var target_properties:Array = inspect_properties(selectedObject);
      sendToFlashFirebug({command:"displayGeneralInfo",inheritInfo:inherit_info,classInfo:class_info,targetName:target_name,targetPath:target_path});
      sendToFlashFirebug({command:"displayProperties",targetProperties:target_properties,target:(data.target)});      
    }
    private static function selectSwf(data) {
      var target_properties:Array = inspect_properties(root.loaderInfo);
      sendToFlashFirebug({command:"displaySwfGeneralInfo",swfName:name,swfUrl:url,swfVersion:swfVersion,currentVersion:getCurrentVersion(),latestVersion:getLatestVersion()});
      sendToFlashFirebug({command:"displayProperties",targetProperties:target_properties});
    }    
    // ------------------------------------------------------------ versions functions  
    public static function getCurrentVersion() {
      return currentVersion;
    }    
    
    public static function getLatestVersion() {
      return latestVersion;
    }
        
    private static function loadLatestVersion() {
      latestVersion = "1.0.0"
    }
    
    private static function latestVersionLoaded(evt:Event) {    
      var versionData:XML = XML(evt.target.data);
      latestVersion = versionData.text();
    }
    
    private static function latestVersionField(evt:IOErrorEvent) {
      latestVersion = "0.0.0";
    }
    // ------------------------------------------------------- overlay functions
    private static function overlayObject(data) {
      var displayObject = getDisplayObject(data.target);      
      // add the overlay
      overlay.target = displayObject;
    }
    private static function removeOverlay(data) {
      overlay.target = null;
      }
    private static function cleanOverlay() {
      overlayBitmap.bitmapData.fillRect(overlayBitmap.bitmapData.rect, 0);
      }
    // ----------------------------------------------------    
    private static function setPropertyValue(data) {
      try{
        if(selectedObject){
          switch (data.propType){
            case "Boolean":
            selectedObject[data.propName] = (data.propValue == "true")? true : false;  
            break;
            case "String":
            selectedObject[data.propName] = CharacterEntity.decode(data.propValue);
            break;
            default:
            selectedObject[data.propName] = data.propValue;  
          }
        }
      }catch(e){
      
      }
    }
    private static function getPropertyValue(data) { 
      
    }    
  }
}


四、以上三步为准备工作,怎么使用呢
在你的项目的主类 如 Main.as 中
导入Firebug类

import ominds.Firebug;


然后在初始化的构造函数中 写

Firebug.connect(this);

假如在其他子集里要写

Firebug.connect(root);


然后用 静态方法

Firebug.traceOut("helle")//去代替传统的 trace();

不知道为什么作者不直接修改trace的原型,那样在FLASH开发工具和这里都可以调试了

看看效果吧:



不仅trace可以在浏览器中查看,连FLASH的层级结构和每一个对象的属性都一览无余
还记得xray吗?以前我为了在网页中调试FLASH 都是自己写js来输出,现在好啦,真是福音啊,嘎嘎

PS:还发现个叫 Flashbug 的插件,我也安装了,它直接修改了trace原型,无需引入任何类库,直接可以trace
但是功能貌似仅此而已。不如这个功能多。各位看官根据自己的需要来选择吧



tags:

to "发现了个调试WEB-flash的小宝贝“FlashFireBug”,可以抛弃“xray”了"

  1. fareed Says:

    hi , the AS3 doesn't have prototype to override the trace function , in the AS3 you can override the main trace function by creating function with the same name trace in the document class for your project or in the first frame and this could not be through another class because user class so it's could be by include not import,
    in the flashfirebug you can override the trace function by add overrideTrace.as
    goto flash firebug homepage :
    http://www.o-minds.com/products/flashfirebug
    then goto
    Miscellaneous

  2. emment Says:

    oh~thank you
    include "ominds/overrideTrace.as", i see
    My carelessness

  3. fareed Says:

    no problem ,
    anyway thank you for writing about my extension ;)

  4. emment Says:

    please give me your msn, i would like to make friend with you Adore
    my msn is.... passoicq@hotmail.com

  5. budong Says:

    能说的通俗点不?看不懂~

  6. 米粒儿 Says:

    类库下载页面不行啊

  7. 米粒儿 Says:

    类库下载不了呀

  8. 米粒儿 Says:

    这都是1年以前的了。能说的通俗详细点不,谢谢呀

    马甲 于 2011-12-24 22:04:25 回复
    现在不需要这个了,有更好的插件可以用
    看这个 http://www.imemment.com/post/122.html

Leave a Reply