Actionscript 3 选择InputTextField会在AdobeAIR中加载的swf中引发安全沙盒冲突

Actionscript 3 选择InputTextField会在AdobeAIR中加载的swf中引发安全沙盒冲突,actionscript-3,air,Actionscript 3,Air,我有一个swf,加载到AdobeAIR 1.5中的非应用程序沙盒中(shell已经与我们的用户一起安装,因此我无法更新到版本2+) 在swf的舞台上有按钮、电影嘴唇、动画等等——所有这些都很好 当我们添加输入TextField时,选择此TextField会导致安全沙盒冲突 错误消息(在调试模式下)是(我已经编辑了实际的文件名): 然后,用户无法在文本字段中输入文本。应用程序的其余部分不受影响 FDB stacktrace仅显示: this = [Object 57216577, class='f

我有一个swf,加载到AdobeAIR 1.5中的非应用程序沙盒中(shell已经与我们的用户一起安装,因此我无法更新到版本2+)

在swf的舞台上有按钮、电影嘴唇、动画等等——所有这些都很好

当我们添加输入TextField时,选择此TextField会导致安全沙盒冲突

错误消息(在调试模式下)是(我已经编辑了实际的文件名):

然后,用户无法在文本字段中输入文本。应用程序的其余部分不受影响

FDB stacktrace仅显示:

this = [Object 57216577, class='flash.utils::Timer'].Timer/tick() at <null>:0
或者当鼠标落下时的类似情况

在加载的主权财富基金中,似乎也无法访问键盘事件,因此我想把“字段”变成一个按钮,然后通过听键盘事件来控制输入,但这一想法毫无根据


现在看看是否将事件中继到通过父沙盒桥传递的回调,或者最小的comp是否可以拯救我的屁股。

好的,我有一个疯狂的解决方法,但它非常可靠。我将在这里发布它的全部内容,不过我可能会将它变得通用,并在某个时候将其上传到github

在我的shell中,我有一个mediator视图(我使用机器人腿),我称之为EventRelayer和EventRelayerMediator

视图的唯一目的是让调解人能够进入舞台

我在parentSandboxBridge上公开了一些函数:

public function requestKeyboardEventRelay(eventType:String, callback:Function):void;

public function requestMouseEventRelay(eventType:String, callback:Function):void;

public function cancelKeyboardEventRelay(eventType:String, callback:Function):void;

public function cancelMouseEventRelay(eventType:String, callback:Function):void;
我的沙箱桥总是转换为强类型事件,因此这些火灾事件如下:

RelayEvent(RelayEvent.START_RELAY_REQUESTED, KeyboardEvent, eventType, callback);

RelayEvent(RelayEvent.CANCEL_RELAY_REQUESTED, MouseEvent, eventType, callback);
这些由EventRelayerMediator拾取,并转换为eventMap中的处理程序:

override public function onRegister():void
{           
    createRelayHandlerFactories();
    eventMap.mapListener(eventDispatcher, RelayEvent.START_RELAY_REQUESTED, startRelay);
}

protected function startRelay(e:RelayEvent):void
{
    var handler:Function = createRelayHandler(e.relayEventClass, e.callback);
    eventMap.mapListener(view.stage, e.relayEventType, handler, e.relayEventClass);
}

protected function createRelayHandler(relayEventClass:Class, callback:Function):Function
{
    var handler:Function = relayHandlerFactoriesByEventClass[relayEventClass](callback);

    return handler;
    }                  

protected function createRelayHandlerFactories():void
{
    relayHandlerFactoriesByEventClass = new Dictionary();
    relayHandlerFactoriesByEventClass[KeyboardEvent] = createKeyboardEventRelayHandler;
    relayHandlerFactoriesByEventClass[MouseEvent] = createMouseEventRelayHandler;
}                                                                                      

protected function createKeyboardEventRelayHandler(callback:Function):Function
{
    var handler:Function = function(e:KeyboardEvent):void
    {            
        trace("Relaying from shell: " + e.toString());
        // passing an object because the sandbox bridge doesn't allow strong typed values, only primitives
        var o:Object = {};
        o.type = e.type;
        o.charCode = e.charCode;
        o.keyCode = e.keyCode;
        o.altKey = e.altKey; 
        o.ctrlKey = e.ctrlKey;
        o.shiftKey = e.shiftKey;
        // no point adding other props as we can't pass them
        // to the constructor of the KeyboardEvent
        callback(o)
    } 

    return handler;
} 
加载的swf传递一个回调,该回调只是重新组装和重新分派事件

我的输入文本字段现在只是一个动态字段,带有一个单击处理程序,该处理程序在swf根目录上激活键盘事件监听,然后相应地更新动态字段

目前这是非常粗糙的,但我将把它分解成一个健壮的、经过测试的类,现在我知道它可以工作了

我使用了一个字典来管理处理程序,因为我确信内存泄漏将接踵而至,我希望必须中继FocusEvents以停止输入文本

我需要测试内存泄漏,从parentSandboxBridge函数返回一个绑定,这样我就可以确保我不会两次添加同一个处理程序等等,但是Adobe-你没有调用这个函数并提供内置的中继机制,这太糟糕了

RelayEvent(RelayEvent.START_RELAY_REQUESTED, KeyboardEvent, eventType, callback);

RelayEvent(RelayEvent.CANCEL_RELAY_REQUESTED, MouseEvent, eventType, callback);
override public function onRegister():void
{           
    createRelayHandlerFactories();
    eventMap.mapListener(eventDispatcher, RelayEvent.START_RELAY_REQUESTED, startRelay);
}

protected function startRelay(e:RelayEvent):void
{
    var handler:Function = createRelayHandler(e.relayEventClass, e.callback);
    eventMap.mapListener(view.stage, e.relayEventType, handler, e.relayEventClass);
}

protected function createRelayHandler(relayEventClass:Class, callback:Function):Function
{
    var handler:Function = relayHandlerFactoriesByEventClass[relayEventClass](callback);

    return handler;
    }                  

protected function createRelayHandlerFactories():void
{
    relayHandlerFactoriesByEventClass = new Dictionary();
    relayHandlerFactoriesByEventClass[KeyboardEvent] = createKeyboardEventRelayHandler;
    relayHandlerFactoriesByEventClass[MouseEvent] = createMouseEventRelayHandler;
}                                                                                      

protected function createKeyboardEventRelayHandler(callback:Function):Function
{
    var handler:Function = function(e:KeyboardEvent):void
    {            
        trace("Relaying from shell: " + e.toString());
        // passing an object because the sandbox bridge doesn't allow strong typed values, only primitives
        var o:Object = {};
        o.type = e.type;
        o.charCode = e.charCode;
        o.keyCode = e.keyCode;
        o.altKey = e.altKey; 
        o.ctrlKey = e.ctrlKey;
        o.shiftKey = e.shiftKey;
        // no point adding other props as we can't pass them
        // to the constructor of the KeyboardEvent
        callback(o)
    } 

    return handler;
}