@@ -386,6 +386,7 @@ class WebViewInputConnection extends BaseInputConnection {
386386 private boolean mIsAutoFillable ;
387387 private boolean mIsAutoCompleteEnabled ;
388388 private String mName ;
389+ private int mBatchLevel ;
389390
390391 public WebViewInputConnection () {
391392 super (mWebView , true );
@@ -404,6 +405,24 @@ public void setAutoFillable(int queryId) {
404405 }
405406 }
406407
408+ @ Override
409+ public boolean beginBatchEdit () {
410+ if (mBatchLevel == 0 ) {
411+ beginTextBatch ();
412+ }
413+ mBatchLevel ++;
414+ return false ;
415+ }
416+
417+ @ Override
418+ public boolean endBatchEdit () {
419+ mBatchLevel --;
420+ if (mBatchLevel == 0 ) {
421+ commitTextBatch ();
422+ }
423+ return false ;
424+ }
425+
407426 public boolean getIsAutoFillable () {
408427 return mIsAutoFillable ;
409428 }
@@ -879,6 +898,8 @@ private int deltaToTextScroll(int oldScroll, int contentSize,
879898 Rect mEditTextContent = new Rect ();
880899 int mEditTextLayerId ;
881900 boolean mIsEditingText = false ;
901+ ArrayList <Message > mBatchedTextChanges = new ArrayList <Message >();
902+ boolean mIsBatchingTextChanges = false ;
882903
883904 private static class OnTrimMemoryListener implements ComponentCallbacks2 {
884905 private static OnTrimMemoryListener sInstance = null ;
@@ -5095,8 +5116,8 @@ public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
50955116 // send complex characters to webkit for use by JS and plugins
50965117 if (keyCode == KeyEvent .KEYCODE_UNKNOWN && event .getCharacters () != null ) {
50975118 // pass the key to DOM
5098- mWebViewCore . sendMessage (EventHub .KEY_DOWN , event );
5099- mWebViewCore . sendMessage (EventHub .KEY_UP , event );
5119+ sendBatchableInputMessage (EventHub .KEY_DOWN , 0 , 0 , event );
5120+ sendBatchableInputMessage (EventHub .KEY_UP , 0 , 0 , event );
51005121 // return true as DOM handles the key
51015122 return true ;
51025123 }
@@ -5162,7 +5183,7 @@ public boolean onKeyDown(int keyCode, KeyEvent event) {
51625183 // if an accessibility script is injected we delegate to it the key handling.
51635184 // this script is a screen reader which is a fully fledged solution for blind
51645185 // users to navigate in and interact with web pages.
5165- mWebViewCore . sendMessage (EventHub .KEY_DOWN , event );
5186+ sendBatchableInputMessage (EventHub .KEY_DOWN , 0 , 0 , event );
51665187 return true ;
51675188 } else {
51685189 // Clean up if accessibility was disabled after loading the current URL.
@@ -5289,7 +5310,7 @@ public boolean onKeyUp(int keyCode, KeyEvent event) {
52895310 // if an accessibility script is injected we delegate to it the key handling.
52905311 // this script is a screen reader which is a fully fledged solution for blind
52915312 // users to navigate in and interact with web pages.
5292- mWebViewCore . sendMessage (EventHub .KEY_UP , event );
5313+ sendBatchableInputMessage (EventHub .KEY_UP , 0 , 0 , event );
52935314 return true ;
52945315 } else {
52955316 // Clean up if accessibility was disabled after loading the current URL.
@@ -7543,7 +7564,7 @@ public boolean requestChildRectangleOnScreen(View child,
75437564 arg .mNewEnd = newEnd ;
75447565 mTextGeneration ++;
75457566 arg .mTextGeneration = mTextGeneration ;
7546- mWebViewCore . sendMessage (EventHub .REPLACE_TEXT , oldStart , oldEnd , arg );
7567+ sendBatchableInputMessage (EventHub .REPLACE_TEXT , oldStart , oldEnd , arg );
75477568 }
75487569
75497570 /* package */ void passToJavaScript (String currentText , KeyEvent event ) {
@@ -8512,7 +8533,7 @@ public void handleMessage(Message msg) {
85128533 break ;
85138534
85148535 case KEY_PRESS :
8515- mWebViewCore . sendMessage (EventHub .KEY_PRESS , msg .arg1 );
8536+ sendBatchableInputMessage (EventHub .KEY_PRESS , msg .arg1 , 0 , null );
85168537 break ;
85178538
85188539 case RELOCATE_AUTO_COMPLETE_POPUP :
@@ -8898,6 +8919,31 @@ private void scrollEditText(int scrollX, int scrollY) {
88988919 TEXT_SCROLL_ANIMATION_DELAY_MS );
88998920 }
89008921
8922+ private void beginTextBatch () {
8923+ mIsBatchingTextChanges = true ;
8924+ }
8925+
8926+ private void commitTextBatch () {
8927+ if (mWebViewCore != null ) {
8928+ mWebViewCore .sendMessages (mBatchedTextChanges );
8929+ }
8930+ mBatchedTextChanges .clear ();
8931+ mIsBatchingTextChanges = false ;
8932+ }
8933+
8934+ private void sendBatchableInputMessage (int what , int arg1 , int arg2 ,
8935+ Object obj ) {
8936+ if (mWebViewCore == null ) {
8937+ return ;
8938+ }
8939+ Message message = Message .obtain (null , what , arg1 , arg2 , obj );
8940+ if (mIsBatchingTextChanges ) {
8941+ mBatchedTextChanges .add (message );
8942+ } else {
8943+ mWebViewCore .sendMessage (message );
8944+ }
8945+ }
8946+
89018947 // Class used to use a dropdown for a <select> element
89028948 private class InvokeListBox implements Runnable {
89038949 // Whether the listbox allows multiple selection.
@@ -9296,7 +9342,7 @@ private void sendKeyEvent(KeyEvent event) {
92969342 mWebView .playSoundEffect (sound );
92979343 }
92989344 }
9299- mWebViewCore . sendMessage (eventHubAction , direction , event );
9345+ sendBatchableInputMessage (eventHubAction , direction , 0 , event );
93009346 }
93019347
93029348 /**
0 commit comments