mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-13 17:47:12 -04:00
Properly use full text of HTML input, instead of hackily trying to check length difference to fake presses/backspaces.
This should fix text input not really working with firefox for android, and allow using autocomplete in chrome for android
This commit is contained in:
parent
ef5a0f64f3
commit
bece154d2b
128
src/Gui.c
128
src/Gui.c
@ -120,53 +120,6 @@ static void OnContextRecreated(void* obj) {
|
||||
}
|
||||
}
|
||||
|
||||
static void OnFontChanged(void* obj) { Gui_RefreshAll(); }
|
||||
|
||||
static void OnFileChanged(void* obj, struct Stream* stream, const String* name) {
|
||||
if (String_CaselessEqualsConst(name, "gui.png")) {
|
||||
Game_UpdateTexture(&Gui_GuiTex, stream, name, NULL);
|
||||
} else if (String_CaselessEqualsConst(name, "gui_classic.png")) {
|
||||
Game_UpdateTexture(&Gui_GuiClassicTex, stream, name, NULL);
|
||||
} else if (String_CaselessEqualsConst(name, "icons.png")) {
|
||||
Game_UpdateTexture(&Gui_IconsTex, stream, name, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void Gui_Init(void) {
|
||||
Event_RegisterVoid(&ChatEvents.FontChanged, NULL, OnFontChanged);
|
||||
Event_RegisterEntry(&TextureEvents.FileChanged, NULL, OnFileChanged);
|
||||
Event_RegisterVoid(&GfxEvents.ContextLost, NULL, OnContextLost);
|
||||
Event_RegisterVoid(&GfxEvents.ContextRecreated, NULL, OnContextRecreated);
|
||||
Gui_LoadOptions();
|
||||
Gui_ShowDefault();
|
||||
}
|
||||
|
||||
static void Gui_Reset(void) {
|
||||
/* TODO:Should we reset all screens here.. ? */
|
||||
}
|
||||
|
||||
static void Gui_Free(void) {
|
||||
Event_UnregisterVoid(&ChatEvents.FontChanged, NULL, OnFontChanged);
|
||||
Event_UnregisterEntry(&TextureEvents.FileChanged, NULL, OnFileChanged);
|
||||
Event_UnregisterVoid(&GfxEvents.ContextLost, NULL, OnContextLost);
|
||||
Event_UnregisterVoid(&GfxEvents.ContextRecreated, NULL, OnContextRecreated);
|
||||
|
||||
while (Gui_ScreensCount) Gui_Remove(Gui_Screens[0]);
|
||||
|
||||
Gfx_DeleteTexture(&Gui_GuiTex);
|
||||
Gfx_DeleteTexture(&Gui_GuiClassicTex);
|
||||
Gfx_DeleteTexture(&Gui_IconsTex);
|
||||
Gui_Reset();
|
||||
}
|
||||
|
||||
struct IGameComponent Gui_Component = {
|
||||
Gui_Init, /* Init */
|
||||
Gui_Free, /* Free */
|
||||
Gui_Reset, /* Reset */
|
||||
NULL, /* OnNewMap */
|
||||
NULL, /* OnNewMapLoaded */
|
||||
};
|
||||
|
||||
void Gui_RefreshAll(void) {
|
||||
OnContextLost(NULL);
|
||||
OnContextRecreated(NULL);
|
||||
@ -373,3 +326,84 @@ void TextAtlas_AddInt(struct TextAtlas* atlas, int value, VertexP3fT2fC4b** vert
|
||||
TextAtlas_Add(atlas, digits[i] - '0' , vertices);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*------------------------------------------------------Gui component------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static void OnFontChanged(void* obj) { Gui_RefreshAll(); }
|
||||
|
||||
static void OnFileChanged(void* obj, struct Stream* stream, const String* name) {
|
||||
if (String_CaselessEqualsConst(name, "gui.png")) {
|
||||
Game_UpdateTexture(&Gui_GuiTex, stream, name, NULL);
|
||||
} else if (String_CaselessEqualsConst(name, "gui_classic.png")) {
|
||||
Game_UpdateTexture(&Gui_GuiClassicTex, stream, name, NULL);
|
||||
} else if (String_CaselessEqualsConst(name, "icons.png")) {
|
||||
Game_UpdateTexture(&Gui_IconsTex, stream, name, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnKeyPress(void* obj, int keyChar) {
|
||||
struct Screen* s;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < Gui_ScreensCount; i++) {
|
||||
s = Gui_Screens[i];
|
||||
if (s->VTABLE->HandlesKeyPress(s, keyChar)) return;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CC_BUILD_TOUCH
|
||||
static void OnTextChanged(void* obj, const String* str) {
|
||||
struct Screen* s;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < Gui_ScreensCount; i++) {
|
||||
s = Gui_Screens[i];
|
||||
if (s->VTABLE->HandlesTextChanged(s, str)) return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void Gui_Init(void) {
|
||||
Event_RegisterVoid(&ChatEvents.FontChanged, NULL, OnFontChanged);
|
||||
Event_RegisterEntry(&TextureEvents.FileChanged, NULL, OnFileChanged);
|
||||
Event_RegisterVoid(&GfxEvents.ContextLost, NULL, OnContextLost);
|
||||
Event_RegisterVoid(&GfxEvents.ContextRecreated, NULL, OnContextRecreated);
|
||||
Event_RegisterInt(&InputEvents.Press, NULL, OnKeyPress);
|
||||
#ifdef CC_BUILD_TOUCH
|
||||
Event_RegisterString(&InputEvents.TextChanged, NULL, OnTextChanged);
|
||||
#endif
|
||||
Gui_LoadOptions();
|
||||
Gui_ShowDefault();
|
||||
}
|
||||
|
||||
static void Gui_Reset(void) {
|
||||
/* TODO:Should we reset all screens here.. ? */
|
||||
}
|
||||
|
||||
static void Gui_Free(void) {
|
||||
Event_UnregisterVoid(&ChatEvents.FontChanged, NULL, OnFontChanged);
|
||||
Event_UnregisterEntry(&TextureEvents.FileChanged, NULL, OnFileChanged);
|
||||
Event_UnregisterVoid(&GfxEvents.ContextLost, NULL, OnContextLost);
|
||||
Event_UnregisterVoid(&GfxEvents.ContextRecreated, NULL, OnContextRecreated);
|
||||
Event_UnregisterInt(&InputEvents.Press, NULL, OnKeyPress);
|
||||
#ifdef CC_BUILD_TOUCH
|
||||
Event_UnregisterString(&InputEvents.TextChanged, NULL, OnTextChanged);
|
||||
#endif
|
||||
|
||||
while (Gui_ScreensCount) Gui_Remove(Gui_Screens[0]);
|
||||
|
||||
Gfx_DeleteTexture(&Gui_GuiTex);
|
||||
Gfx_DeleteTexture(&Gui_GuiClassicTex);
|
||||
Gfx_DeleteTexture(&Gui_IconsTex);
|
||||
Gui_Reset();
|
||||
}
|
||||
|
||||
struct IGameComponent Gui_Component = {
|
||||
Gui_Init, /* Init */
|
||||
Gui_Free, /* Free */
|
||||
Gui_Reset, /* Reset */
|
||||
NULL, /* OnNewMap */
|
||||
NULL, /* OnNewMapLoaded */
|
||||
};
|
13
src/Input.c
13
src/Input.c
@ -992,7 +992,7 @@ static void HandleInputDown(void* obj, int key, cc_bool was) {
|
||||
/* Can't do this in KeyUp, because pressing escape without having */
|
||||
/* explicitly disabled mouse lock means a KeyUp event isn't sent. */
|
||||
/* But switching to pause screen disables mouse lock, causing a KeyUp */
|
||||
/* event to be sent, triggering the active->closable case which immediately
|
||||
/* event to be sent, triggering the active->closable case which immediately */
|
||||
/* closes the pause screen. Hence why the next KeyUp must be supressed. */
|
||||
suppressEscape = true;
|
||||
#endif
|
||||
@ -1033,23 +1033,12 @@ static void HandleInputUp(void* obj, int key) {
|
||||
if (key == KeyBinds[KEYBIND_PICK_BLOCK]) MouseStateRelease(MOUSE_MIDDLE);
|
||||
}
|
||||
|
||||
static void HandleKeyPress(void* obj, int keyChar) {
|
||||
struct Screen* s;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < Gui_ScreensCount; i++) {
|
||||
s = Gui_Screens[i];
|
||||
if (s->VTABLE->HandlesKeyPress(s, keyChar)) return;
|
||||
}
|
||||
}
|
||||
|
||||
void InputHandler_Init(void) {
|
||||
Event_RegisterMove(&PointerEvents.Moved, NULL, HandlePointerMove);
|
||||
Event_RegisterInt(&PointerEvents.Down, NULL, HandlePointerDown);
|
||||
Event_RegisterInt(&PointerEvents.Up, NULL, HandlePointerUp);
|
||||
Event_RegisterInt(&InputEvents.Down, NULL, HandleInputDown);
|
||||
Event_RegisterInt(&InputEvents.Up, NULL, HandleInputUp);
|
||||
Event_RegisterInt(&InputEvents.Press, NULL, HandleKeyPress);
|
||||
Event_RegisterFloat(&InputEvents.Wheel, NULL, HandleMouseWheel);
|
||||
|
||||
Event_RegisterVoid(&UserEvents.HackPermissionsChanged, NULL, InputHandler_CheckZoomFov);
|
||||
|
41
src/Menus.c
41
src/Menus.c
@ -812,6 +812,14 @@ static int EditHotkeyScreen_KeyPress(void* screen, char keyChar) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static int EditHotkeyScreen_TextChanged(void* screen, const String* str) {
|
||||
#ifdef CC_BUILD_TOUCH
|
||||
struct EditHotkeyScreen* s = (struct EditHotkeyScreen*)screen;
|
||||
InputWidget_SetAndSyncText(&s->input.base, str);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
static int EditHotkeyScreen_KeyDown(void* screen, int key) {
|
||||
struct EditHotkeyScreen* s = (struct EditHotkeyScreen*)screen;
|
||||
if (s->selectedI >= 0) {
|
||||
@ -887,7 +895,7 @@ static void EditHotkeyScreen_Init(void* screen) {
|
||||
|
||||
static const struct ScreenVTABLE EditHotkeyScreen_VTABLE = {
|
||||
EditHotkeyScreen_Init, EditHotkeyScreen_Render, Menu_CloseKeyboard,
|
||||
EditHotkeyScreen_KeyDown, Screen_TInput, EditHotkeyScreen_KeyPress, Screen_TText,
|
||||
EditHotkeyScreen_KeyDown, Screen_TInput, EditHotkeyScreen_KeyPress, EditHotkeyScreen_TextChanged,
|
||||
Menu_PointerDown, Screen_TPointer, Menu_PointerMove, Screen_TMouseScroll,
|
||||
Menu_Layout, EditHotkeyScreen_ContextLost, EditHotkeyScreen_ContextRecreated
|
||||
};
|
||||
@ -993,6 +1001,14 @@ static int GenLevelScreen_KeyPress(void* screen, char keyChar) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static int GenLevelScreen_TextChanged(void* screen, const String* str) {
|
||||
#ifdef CC_BUILD_TOUCH
|
||||
struct GenLevelScreen* s = (struct GenLevelScreen*)screen;
|
||||
if (s->selected) InputWidget_SetAndSyncText(&s->selected->base, str);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
static int GenLevelScreen_PointerDown(void* screen, int id, int x, int y) {
|
||||
struct GenLevelScreen* s = (struct GenLevelScreen*)screen;
|
||||
int i = Menu_DoPointerDown(screen, id, x, y);
|
||||
@ -1058,7 +1074,7 @@ static void GenLevelScreen_Init(void* screen) {
|
||||
|
||||
static const struct ScreenVTABLE GenLevelScreen_VTABLE = {
|
||||
GenLevelScreen_Init, MenuScreen_Render, Menu_CloseKeyboard,
|
||||
GenLevelScreen_KeyDown, Screen_TInput, GenLevelScreen_KeyPress, Screen_TText,
|
||||
GenLevelScreen_KeyDown, Screen_TInput, GenLevelScreen_KeyPress, GenLevelScreen_TextChanged,
|
||||
GenLevelScreen_PointerDown, Screen_TPointer, Menu_PointerMove, Screen_TMouseScroll,
|
||||
Menu_Layout, GenLevelScreen_ContextLost, GenLevelScreen_ContextRecreated
|
||||
};
|
||||
@ -1320,6 +1336,15 @@ static int SaveLevelScreen_KeyPress(void* screen, char keyChar) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static int SaveLevelScreen_TextChanged(void* screen, const String* str) {
|
||||
#ifdef CC_BUILD_TOUCH
|
||||
struct SaveLevelScreen* s = (struct SaveLevelScreen*)screen;
|
||||
SaveLevelScreen_RemoveOverwrites(s);
|
||||
InputWidget_SetAndSyncText(&s->input.base, str);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
static int SaveLevelScreen_KeyDown(void* screen, int key) {
|
||||
struct SaveLevelScreen* s = (struct SaveLevelScreen*)screen;
|
||||
if (Elem_HandlesKeyDown(&s->input.base, key)) {
|
||||
@ -1386,7 +1411,7 @@ static void SaveLevelScreen_Init(void* screen) {
|
||||
|
||||
static const struct ScreenVTABLE SaveLevelScreen_VTABLE = {
|
||||
SaveLevelScreen_Init, SaveLevelScreen_Render, Menu_CloseKeyboard,
|
||||
SaveLevelScreen_KeyDown, Screen_TInput, SaveLevelScreen_KeyPress, Screen_TText,
|
||||
SaveLevelScreen_KeyDown, Screen_TInput, SaveLevelScreen_KeyPress, SaveLevelScreen_TextChanged,
|
||||
Menu_PointerDown, Screen_TPointer, Menu_PointerMove, Screen_TMouseScroll,
|
||||
Menu_Layout, SaveLevelScreen_ContextLost, SaveLevelScreen_ContextRecreated
|
||||
};
|
||||
@ -1984,6 +2009,14 @@ static int MenuOptionsScreen_KeyPress(void* screen, char keyChar) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static int MenuOptionsScreen_TextChanged(void* screen, const String* str) {
|
||||
#ifdef CC_BUILD_TOUCH
|
||||
struct MenuOptionsScreen* s = (struct MenuOptionsScreen*)screen;
|
||||
if (s->activeI >= 0) InputWidget_SetAndSyncText(&s->input.base, str);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
static int MenuOptionsScreen_KeyDown(void* screen, int key) {
|
||||
struct MenuOptionsScreen* s = (struct MenuOptionsScreen*)screen;
|
||||
if (s->activeI >= 0) {
|
||||
@ -2185,7 +2218,7 @@ static void MenuOptionsScreen_ContextRecreated(void* screen) {
|
||||
|
||||
static const struct ScreenVTABLE MenuOptionsScreen_VTABLE = {
|
||||
MenuOptionsScreen_Init, MenuOptionsScreen_Render, MenuOptionsScreen_Free,
|
||||
MenuOptionsScreen_KeyDown, Screen_TInput, MenuOptionsScreen_KeyPress, Screen_TText,
|
||||
MenuOptionsScreen_KeyDown, Screen_TInput, MenuOptionsScreen_KeyPress, MenuOptionsScreen_TextChanged,
|
||||
Menu_PointerDown, Screen_TPointer, MenuOptionsScreen_PointerMove, Screen_TMouseScroll,
|
||||
MenuOptionsScreen_Layout, MenuOptionsScreen_ContextLost, MenuOptionsScreen_ContextRecreated
|
||||
};
|
||||
|
@ -32,7 +32,7 @@ int Screen_FPointer(void* s, int id, int x, int y) { return false; }
|
||||
|
||||
int Screen_TInput(void* s, int key) { return true; }
|
||||
int Screen_TKeyPress(void* s, char keyChar) { return true; }
|
||||
int Screen_TText(void* s, const String* str) { return false; }
|
||||
int Screen_TText(void* s, const String* str) { return true; }
|
||||
int Screen_TMouseScroll(void* s, float delta) { return true; }
|
||||
int Screen_TPointer(void* s, int id, int x, int y) { return true; }
|
||||
static void Screen_NullFunc(void* screen) { }
|
||||
@ -624,6 +624,17 @@ static int ChatScreen_KeyPress(void* screen, char keyChar) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static int ChatScreen_TextChanged(void* screen, const String* str) {
|
||||
#ifdef CC_BUILD_TOUCH
|
||||
struct ChatScreen* s = (struct ChatScreen*)screen;
|
||||
if (!s->grabsInput) return false;
|
||||
|
||||
InputWidget_SetAndSyncText(&s->input.base, str);
|
||||
ChatScreen_UpdateChatYOffsets(s);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
static int ChatScreen_KeyDown(void* screen, int key) {
|
||||
static const String slash = String_FromConst("/");
|
||||
struct ChatScreen* s = (struct ChatScreen*)screen;
|
||||
@ -813,7 +824,7 @@ static void ChatScreen_Free(void* screen) {
|
||||
|
||||
static const struct ScreenVTABLE ChatScreen_VTABLE = {
|
||||
ChatScreen_Init, ChatScreen_Render, ChatScreen_Free,
|
||||
ChatScreen_KeyDown, ChatScreen_KeyUp, ChatScreen_KeyPress, Screen_TText,
|
||||
ChatScreen_KeyDown, ChatScreen_KeyUp, ChatScreen_KeyPress, ChatScreen_TextChanged,
|
||||
ChatScreen_PointerDown, Screen_FPointer, Screen_FPointer, ChatScreen_MouseScroll,
|
||||
ChatScreen_Layout, ChatScreen_ContextLost, ChatScreen_ContextRecreated
|
||||
};
|
||||
@ -828,12 +839,7 @@ void ChatScreen_Show(void) {
|
||||
|
||||
void ChatScreen_OpenInput(const String* text) {
|
||||
struct ChatScreen* s = &ChatScreen_Instance;
|
||||
#ifdef CC_BUILD_TOUCH
|
||||
/* TODO: This is the wrong approach. need an event for all text input. */
|
||||
s->suppressNextPress = !Input_TouchMode;
|
||||
#else
|
||||
s->suppressNextPress = true;
|
||||
#endif
|
||||
s->grabsInput = true;
|
||||
Camera_CheckFocus();
|
||||
Window_OpenKeyboard();
|
||||
|
@ -1135,6 +1135,12 @@ void InputWidget_UpdateText(struct InputWidget* w) {
|
||||
InputWidget_UpdateCaret(w);
|
||||
}
|
||||
|
||||
void InputWidget_SetAndSyncText(struct InputWidget* w, const String* str) {
|
||||
InputWidget_Clear(w);
|
||||
InputWidget_AppendString(w, str);
|
||||
Window_SetKeyboardText(&w->text);
|
||||
}
|
||||
|
||||
static void InputWidget_Free(void* widget) {
|
||||
struct InputWidget* w = (struct InputWidget*)widget;
|
||||
Gfx_DeleteTexture(&w->inputTex.ID);
|
||||
|
@ -130,6 +130,11 @@ CC_NOINLINE void InputWidget_AppendString(struct InputWidget* w, const String* t
|
||||
CC_NOINLINE void InputWidget_Append(struct InputWidget* w, char c);
|
||||
/* Redraws text and recalculates associated state. */
|
||||
CC_NOINLINE void InputWidget_UpdateText(struct InputWidget* w);
|
||||
/* Shorthand for InputWidget_Clear followed by InputWidget_AppendString, */
|
||||
/* then calls Window_SetKeyboardText with the text in the input widget. */
|
||||
/* This way native text input state stays synchronised with the input widget. */
|
||||
/* (e.g. may only accept numerical input, so 'c' gets stripped from str) */
|
||||
CC_NOINLINE void InputWidget_SetAndSyncText(struct InputWidget* w, const String* str);
|
||||
|
||||
|
||||
struct MenuInputDesc;
|
||||
|
50
src/Window.c
50
src/Window.c
@ -3004,24 +3004,22 @@ static EM_BOOL Window_Key(int type, const EmscriptenKeyboardEvent* ev , void* da
|
||||
(key >= KEY_INSERT && key <= KEY_MENU) || (key >= KEY_ENTER && key <= KEY_NUMLOCK && key != KEY_SPACE);
|
||||
}
|
||||
|
||||
/* reused for touch keyboard input down in Window_OpenKeyboard */
|
||||
EMSCRIPTEN_KEEPALIVE void Window_ProcessKeyChar(int charCode) {
|
||||
char keyChar;
|
||||
if (Convert_TryUnicodeToCP437(charCode, &keyChar)) {
|
||||
Event_RaiseInt(&InputEvents.Press, keyChar);
|
||||
}
|
||||
}
|
||||
|
||||
static EM_BOOL Window_KeyPress(int type, const EmscriptenKeyboardEvent* ev, void* data) {
|
||||
Window_CorrectFocus();
|
||||
/* When on-screen keyboard is open, we don't want to intercept any key presses, */
|
||||
/* because they should be sent to the HTML text input instead. */
|
||||
/* If any keys are intercepted, this causes attempting to backspace all text */
|
||||
/* later to not actually backspace everything. (because the HTML text input */
|
||||
/* does not have these intercepted key presses in its text buffer) */
|
||||
/* (e.g. chrome for android sends keypresses sometimes for '0' to '9' keys) */
|
||||
/* (Chrome for android sends keypresses sometimes for '0' to '9' keys) */
|
||||
/* - If any keys are intercepted, this causes the HTML text input to become */
|
||||
/* desynchronised from the chat/menu input widget the user sees in game. */
|
||||
/* - This causes problems such as attempting to backspace all text later to */
|
||||
/* not actually backspace everything. (because the HTML text input does not */
|
||||
/* have these intercepted key presses in its text buffer) */
|
||||
if (keyboardOpen) return false;
|
||||
Window_ProcessKeyChar(ev->charCode);
|
||||
|
||||
char keyChar;
|
||||
if (Convert_TryUnicodeToCP437(ev->charCode, &keyChar)) {
|
||||
Event_RaiseInt(&InputEvents.Press, keyChar);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3200,9 +3198,14 @@ void Window_AllocFramebuffer(Bitmap* bmp) { }
|
||||
void Window_DrawFramebuffer(Rect2D r) { }
|
||||
void Window_FreeFramebuffer(Bitmap* bmp) { }
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void SendFakeBackspace(void) {
|
||||
Input_SetPressed(KEY_BACKSPACE, true);
|
||||
Input_SetPressed(KEY_BACKSPACE, false);
|
||||
EMSCRIPTEN_KEEPALIVE void Window_OnTextChanged(const char* src) {
|
||||
char buffer[800];
|
||||
int len;
|
||||
String str;
|
||||
|
||||
String_InitArray(str, buffer);
|
||||
String_AppendUtf8(&str, src, String_CalcLen(src, 800));
|
||||
Event_RaiseString(&InputEvents.TextChanged, &str);
|
||||
}
|
||||
|
||||
void Window_OpenKeyboard(void) {
|
||||
@ -3215,23 +3218,10 @@ void Window_OpenKeyboard(void) {
|
||||
if (!elem) {
|
||||
elem = document.createElement('textarea');
|
||||
elem.setAttribute('style', 'position:absolute; left:0; top:0; width:100%; height:100%; opacity:0.3; resize:none; pointer-events:none;');
|
||||
elem.setAttribute('autocomplete', 'off');
|
||||
elem.setAttribute('autocorrect', 'off');
|
||||
|
||||
var oldLen = 0|0;
|
||||
elem.addEventListener("input",
|
||||
function(ev) {
|
||||
var str = ev.target.value;
|
||||
if (str.length > oldLen) {
|
||||
for (var i = oldLen; i < str.length; i++) {
|
||||
ccall('Window_ProcessKeyChar', 'void', ['number'], [str.charCodeAt(i)]);
|
||||
}
|
||||
} else {
|
||||
for (var i = str.length; i < oldLen; i++) {
|
||||
ccall('SendFakeBackspace', 'void', [], []);
|
||||
}
|
||||
}
|
||||
oldLen = str.length;
|
||||
ccall('Window_OnTextChanged', 'void', ['string'], [ev.target.value]);
|
||||
}, false);
|
||||
|
||||
window.cc_inputElem = elem;
|
||||
|
Loading…
x
Reference in New Issue
Block a user