Хорошо, у меня безумный обходной путь, но он довольно солидный. Я собираюсь опубликовать это почти полностью здесь, хотя я, вероятно, сделаю его универсальным и в какой-то момент загрузлю его на github.
В моей оболочке у меня есть средство просмотра с посредником (я использую роботизированные ножки), которое я вызываю 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 и транслируются в обработчики в карте событий:
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 передает обратный вызов, который просто повторно собирает и повторно отправляет события.
Мой ввод TextField теперь является просто динамическим полем с обработчиком щелчка, который активирует прослушивание событий клавиатуры в корне swf, а затем соответствующим образом обновляет динамическое поле.
В данный момент это супер-грубо, но я разбью его на надежный, проверенный класс, теперь я знаю, что это работает.
Я использовал словарь для управления обработчиками, потому что я уверен, что за этим последует адская утечка памяти, и я ожидаю, что придется передать FocusEvents, чтобы прекратить ввод текста.
Мне нужно проверить утечку памяти, вернуть привязку из функции parentSandboxBridge, чтобы я мог убедиться, что я не добавляю один и тот же обработчик дважды и т. Д. И т. Д., Но Adobe - вас отвратительно, если вы не вызываете это и не предоставляете встроенный релейный механизм.