08-24-2008, 04:47 AM
|
#1
|
|
Resu Deretsiger
Join Date: Jul 2005
Location: St-Petersburg, Russia
Posts: 2,329
|
JSTextReader: Workaround for wmode=transparent text input bug.
Many of you have come accross the horrendous bug that happens with text input in flash when the swf is embedded with wmode="transparent". It has been much discussed ( Firefox Bugzilla entry for this bug, Adobe Forum discussion, etc.), but it seems that in all the years that this bug has existed nothing much has been done.
Well, I got pretty tired of it and implemented the following workaround: the AnalogCode JSTextReader. Please go to the page for more details. Currently only in AS2, and some more complicated languages like Japanese will not work, but it works pretty well for most others.
It is still in beta, so if you find it useful please test the heck out of it on as many browsers as you can and post the results.
__________________
overstream.net: add subtitles to online videos (youtube, vimeo, blip.tv...).
Last edited by astgtciv; 09-10-2008 at 09:46 PM.
|
|
|
09-25-2009, 01:36 AM
|
#2
|
|
Registered User
Join Date: Feb 2009
Posts: 31
|
tanx
|
|
|
12-16-2009, 10:38 AM
|
#3
|
|
Member
Join Date: Jun 2006
Posts: 91
|
Hey tjere, i'm trying to use JSTextReader with greek characters and it reckognizes most of the characters (which is already a huge improvement). But i need the missing ones. Is there anything i can do?
Thanx and congrats for your work
|
|
|
02-08-2010, 02:55 PM
|
#4
|
|
Registered User
Join Date: Feb 2010
Posts: 1
|
Great!!!
Man , it's really working , even in Hebrew (even no problem with right-to-left issue) !!! Thanx Thanx Thanx!!!!
|
|
|
02-09-2010, 04:39 PM
|
#5
|
|
Resu Deretsiger
Join Date: Jul 2005
Location: St-Petersburg, Russia
Posts: 2,329
|
Wow, that's great - I certainly didn't test it with RTL languages, so that's a nice bonus
__________________
overstream.net: add subtitles to online videos (youtube, vimeo, blip.tv...).
|
|
|
07-25-2010, 11:38 AM
|
#6
|
|
Resu Deretsiger
Join Date: Jul 2005
Location: St-Petersburg, Russia
Posts: 2,329
|
I've suddenly discovered that JSTextReader started to work on Chrome (v5)! The keyboard input bug manifests there the same way as it did on Firefox, and the workaround works as designed, so it's still useful in this case.
Apparently I was not completely correct in identifying the problem with the keypress event not being fired as a WebKit problem (since presumably Safari and Chrome run off the same WebKit build?), it (understandably) also depends on the javascript engine there.
__________________
overstream.net: add subtitles to online videos (youtube, vimeo, blip.tv...).
|
|
|
08-16-2010, 03:04 PM
|
#7
|
|
Registered User
Join Date: Aug 2010
Posts: 1
|
Man , I wanna say to : Thanx Thanx Thanx!!!!, but as you know as2 is old,
so I tried to migrate it into as3, it worked, but I found out that in chrome not. Maybe somebody else will have a luck to find out chrome issue.
So I am posting here your code migrated to as3:
ActionScript Code:
package
{
import flash.display.*;
import flash.events.*;
import flash.events.KeyboardEvent;
import flash.external.ExternalInterface;
import flash.system.Capabilities;
import flash.ui.Keyboard;
import mx.controls.TextInput;
import mx.managers.FocusManager;
public class WmodeInput extends TextInput
{
private var _pasting:Boolean = false;
private var _jsInitialized:Boolean = false;
private var _jsPrefix:String = '';
private var _lastText:String = '';
private var _curText:String = '';
public function WmodeInput()
{
super();
if(stage){
init();
}else{
addEventListener(Event.ADDED_TO_STAGE, init);
}
}
private function init(e:Event = null):void
{
if(hasEventListener(Event.ADDED_TO_STAGE)) removeEventListener(Event.ADDED_TO_STAGE, init);
if (initJS()) {
stage.addEventListener(KeyboardEvent.KEY_DOWN, handleKeyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, handleKeyUp);
_lastText = this.text;
//addEventListener(MouseEvent.CLICK, onTextChanged);
addEventListener(TextEvent.TEXT_INPUT, onTextChanged);
}
}
private function onTextChanged(e:Event):void {
//removeEventListener(MouseEvent.CLICK, onTextChanged);
_curText = this.textField.text; //e.text
trace("cur text: " + _curText + toCharCodes(_curText));
var ignore:Boolean = false;
var insert:String = '';
trace("isPasting(): " +isPasting())
if (!isPasting()) {
insert = getKeyboardInputFromJS();
}
var caretIndex:Number = this.textField.caretIndex;
var numCharsInserted:Number = _curText.length - _lastText.length;
trace("caretIndex: " + caretIndex + ", numCharsInserted: " + numCharsInserted );
if ((!insert) && (numCharsInserted==0)) {
ignore = true;
} else if (numCharsInserted <= 0) {
var lastJSChar:String = insert.substr(insert.length-1);
if ((!insert) || (lastJSChar == "\u0008") || (lastJSChar == "\u002E")) {
ignore = true;
} else {
numCharsInserted = computeNumberOfDifferingChars();
}
} else if (isIE() && (numCharsInserted==1)) {
numCharsInserted = computeNumberOfDifferingChars();
}
trace("isIE: " + isIE() + ", numCharsInserted=" + numCharsInserted);
if (!ignore) {
insert = processKeyboardInput(insert, numCharsInserted);
var prefix:String = _curText.substr(0, caretIndex-numCharsInserted);
var origTFInsert:String = _curText.substr(caretIndex-numCharsInserted, numCharsInserted);
var suffix:String = _curText.substr(caretIndex);
if (!insert) {
insert = origTFInsert;
}
trace("prefix: " + prefix + ", insert: " + insert + ", suffix: " + suffix + " " + toCharCodes(suffix) + ", origTFInsert: " + origTFInsert);
this.textField.text = prefix+insert+suffix; //e.text
if (insert.length != origTFInsert.length) {
var cursorPos:Number = (prefix+insert).length;
this.setSelection(cursorPos, cursorPos); //e.currentTarget
}
}
_lastText = this.textField.text;//e.text;
trace("new lastTextLength: " + _lastText.length);
}
private function handleKeyDown(e:KeyboardEvent):void
{
if(e.ctrlKey && (e.keyCode == 86)){
_pasting = true;
}else{
_pasting = false;
}
}
private function handleKeyUp(e:KeyboardEvent):void
{
_pasting = false;
}
private function computeNumberOfDifferingChars():Number {
var numCharsInserted:Number;
var leftInsertIndex:Number;
var rightInsertIndex:Number;
for (var i:Number=0;i<_curText.length;i++) {
if (isNaN(leftInsertIndex)) {
if (_lastText.charAt(i) != _curText.charAt(i)) {
leftInsertIndex = i;
}
}
if (isNaN(rightInsertIndex)) {
if (_lastText.charAt(_lastText.length-i-1) != _curText.charAt(_curText.length-i-1)) {
rightInsertIndex = _curText.length-i-1;
}
}
if (!isNaN(leftInsertIndex) && !isNaN(rightInsertIndex)) {
break;
}
}
trace("leftInsertIndex: " + leftInsertIndex + ", " + "rightInsertIndex: " + rightInsertIndex);
if (!isNaN(leftInsertIndex) && !isNaN(rightInsertIndex)) {
numCharsInserted = (rightInsertIndex - leftInsertIndex) + 1;
} else {
numCharsInserted = 0;
}
return numCharsInserted;
}
private function executeJS(s:String, noFunc:Boolean = false):String {
var js:String = s;
if (!noFunc) {
js = "function() {"+js+"}";
}
return ExternalInterface.call(js);
}
private function getKeyboardInputFromJS():String {
var keyboardInput:String = executeJS("if("+unique("popKeyboardInput")+"()) return "+unique("popKeyboardInput")+"()");
trace("keyboardInput ------------>" +keyboardInput)
if(keyboardInput){
var codes:Array = keyboardInput.split(',');
keyboardInput = '';
for (var i:Number=0; i<codes.length; i++) {
keyboardInput += String.fromCharCode(Number(codes[i]));
}
}
// trace("keyboardInput from JS: " + keyboardInput + " " + toCharCodes(keyboardInput));
return keyboardInput;
}
private function processKeyboardInput(keyboardInput:String, numChars:Number):String {
var removable:Array = ["\u0008", "\u00C0"];
for (var i:Number=0; i<removable.length; i++) {
trace("processing " + removable[i] + " (" + removable[i].charCodeAt(0) + ")");
keyboardInput = keyboardInput.split(removable[i]).join("");
}
keyboardInput = keyboardInput.substr(keyboardInput.length-numChars);
return keyboardInput;
}
private function initJS():Boolean {
if (!isJSAvailable()) {
trace("Javascript not available.");
return false;
} else if (!getId()) {
trace("Cannot obtain EmbedObject id.");
return false;
}
if (_jsInitialized) {
return true;
}
executeJS(unique("onKey")+" = function (e) {" +
"if (!"+unique("keyboardInput")+") { "+unique("keyboardInput")+" = '';}" +
"if ("+unique("popKeyboardInputTimeout")+") { clearTimeout("+unique("popKeyboardInputTimeout")+"); "+unique("popKeyboardInputTimeout")+"='';}" +
"var evtobj = window.event? event : e;" +
"var unicode = evtobj.charCode? evtobj.charCode : evtobj.keyCode;" +
unique("keyboardInput")+" += ("+unique("keyboardInput")+"?',':'')+unicode;" +
unique("popKeyboardInputTimeout")+" = setTimeout("+unique("popKeyboardInput") + ", 1000);" +
"}");
executeJS(unique("popKeyboardInput") + " = function() {" +
"var ret="+unique("keyboardInput")+";" +
unique("keyboardInput")+"='';" +
"return ret;" +
"}");
executeJS("var embedObject = document.getElementById('"+getId()+"');" +
"embedObject.onkeypress = "+unique("onKey")+";"
);
_jsInitialized = true;
return true;
}
private function toCharCodes(s:String):String {
var r:String = "[";
for (var i:Number=0;i<s.length;i++) {
r+=s.charCodeAt(i) +" ";
}
return r + "]";
}
private function isJSAvailable():Boolean {
return (ExternalInterface.available && executeJS("return true;"));
}
private function unique(s:String):String {
if (!_jsPrefix) {
_jsPrefix = "_jstr_" + Math.floor(Math.random()*10000) + "_";
}
trace("window." + _jsPrefix + s)
return "window." + _jsPrefix + s;
}
private function isPasting():Boolean {
return _pasting;
}
private function isIE():Boolean {
return (Capabilities.playerType=='ActiveX');
}
private function getId():String {
return "flashContent";
}
}
}
|
|
|
08-16-2010, 09:44 PM
|
#8
|
|
Resu Deretsiger
Join Date: Jul 2005
Location: St-Petersburg, Russia
Posts: 2,329
|
Cool! Another AS3 port of JSTextReader is here.
__________________
overstream.net: add subtitles to online videos (youtube, vimeo, blip.tv...).
|
|
|
| Thread Tools |
|
|
| Display Modes |
Rate This Thread |
Linear Mode
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT. The time now is 09:12 PM.
///
|
|