@@ -5,9 +5,13 @@ const prettier = require('prettier');
55main ( ) ;
66
77async function main ( ) {
8+ const patchVersion = '2' ;
89 const flagFile = path . resolve ( __dirname , '../platforms/android/.flag_done' ) ;
910 if ( fs . existsSync ( flagFile ) ) {
10- return ;
11+ const appliedVersion = fs . readFileSync ( flagFile , 'utf8' ) . trim ( ) ;
12+ if ( appliedVersion === patchVersion ) {
13+ return ;
14+ }
1115 }
1216
1317 const base = path . resolve ( __dirname , `../platforms/android/CordovaLib/src/org/apache/cordova` ) ;
@@ -31,6 +35,18 @@ async function main() {
3135 ] ,
3236 } ;
3337
38+ const nativeContextMenuInterfaceMethod = {
39+ name : 'setNativeContextMenuDisabled' ,
40+ modifier : 'public' ,
41+ returnType : 'void' ,
42+ params : [
43+ {
44+ type : 'boolean' ,
45+ name : 'disabled' ,
46+ }
47+ ] ,
48+ } ;
49+
3450 const setInputTypeMethod = {
3551 name : 'setInputType' ,
3652 modifier : 'public' ,
@@ -44,12 +60,31 @@ async function main() {
4460 body : [ 'webView.setInputType(type);' ] ,
4561 } ;
4662
63+ const setNativeContextMenuDisabledMethod = {
64+ name : 'setNativeContextMenuDisabled' ,
65+ modifier : 'public' ,
66+ returnType : 'void' ,
67+ params : [
68+ {
69+ type : 'boolean' ,
70+ name : 'disabled' ,
71+ }
72+ ] ,
73+ body : [ 'webView.setNativeContextMenuDisabled(disabled);' ] ,
74+ } ;
75+
4776 const contentToAdd = {
4877 'SystemWebView.java' : {
4978 'import' : [
79+ 'android.graphics.Rect' ,
80+ 'android.os.Build' ,
5081 'android.text.InputType' ,
82+ 'android.view.ActionMode' ,
5183 'android.view.inputmethod.InputConnection' ,
5284 'android.view.inputmethod.EditorInfo' ,
85+ 'android.view.Menu' ,
86+ 'android.view.MenuItem' ,
87+ 'android.view.View' ,
5388 ] ,
5489 'fields' : [
5590 {
@@ -70,12 +105,30 @@ async function main() {
70105 modifier : 'private' ,
71106 value : '1' ,
72107 } ,
108+ {
109+ type : 'boolean' ,
110+ name : 'nativeContextMenuDisabled' ,
111+ modifier : 'private' ,
112+ value : 'false' ,
113+ } ,
73114 ] ,
74115 methods : [
75116 {
76117 ...setInputTypeMethod ,
77118 body : [ `this.type = type;` ]
78119 } ,
120+ {
121+ name : 'setNativeContextMenuDisabled' ,
122+ modifier : 'public' ,
123+ returnType : 'void' ,
124+ params : [
125+ {
126+ type : 'boolean' ,
127+ name : 'disabled' ,
128+ }
129+ ] ,
130+ body : [ `this.nativeContextMenuDisabled = disabled;` ] ,
131+ } ,
79132 {
80133 name : 'onCreateInputConnection' ,
81134 modifier : 'public' ,
@@ -102,28 +155,215 @@ async function main() {
102155 ] ,
103156 notation : '@Override' ,
104157 } ,
158+ {
159+ name : 'startActionMode' ,
160+ modifier : 'public' ,
161+ returnType : 'ActionMode' ,
162+ params : [
163+ {
164+ type : 'ActionMode.Callback' ,
165+ name : 'callback' ,
166+ }
167+ ] ,
168+ body : [
169+ `return suppressActionMode(super.startActionMode(wrapActionModeCallback(callback)));` ,
170+ ] ,
171+ notation : '@Override' ,
172+ } ,
173+ {
174+ name : 'startActionMode' ,
175+ modifier : 'public' ,
176+ returnType : 'ActionMode' ,
177+ params : [
178+ {
179+ type : 'ActionMode.Callback' ,
180+ name : 'callback' ,
181+ } ,
182+ {
183+ type : 'int' ,
184+ name : 'type' ,
185+ }
186+ ] ,
187+ body : [
188+ `return suppressActionMode(super.startActionMode(wrapActionModeCallback(callback), type));` ,
189+ ] ,
190+ notation : '@Override' ,
191+ } ,
192+ {
193+ name : 'startActionModeForChild' ,
194+ modifier : 'public' ,
195+ returnType : 'ActionMode' ,
196+ params : [
197+ {
198+ type : 'View' ,
199+ name : 'originalView' ,
200+ } ,
201+ {
202+ type : 'ActionMode.Callback' ,
203+ name : 'callback' ,
204+ }
205+ ] ,
206+ body : [
207+ `return suppressActionMode(super.startActionModeForChild(originalView, wrapActionModeCallback(callback)));` ,
208+ ] ,
209+ notation : '@Override' ,
210+ } ,
211+ {
212+ name : 'startActionModeForChild' ,
213+ modifier : 'public' ,
214+ returnType : 'ActionMode' ,
215+ params : [
216+ {
217+ type : 'View' ,
218+ name : 'originalView' ,
219+ } ,
220+ {
221+ type : 'ActionMode.Callback' ,
222+ name : 'callback' ,
223+ } ,
224+ {
225+ type : 'int' ,
226+ name : 'type' ,
227+ }
228+ ] ,
229+ body : [
230+ `return suppressActionMode(super.startActionModeForChild(originalView, wrapActionModeCallback(callback), type));` ,
231+ ] ,
232+ notation : '@Override' ,
233+ } ,
234+ {
235+ name : 'wrapActionModeCallback' ,
236+ modifier : 'private' ,
237+ returnType : 'ActionMode.Callback' ,
238+ params : [
239+ {
240+ type : 'ActionMode.Callback' ,
241+ name : 'callback' ,
242+ }
243+ ] ,
244+ body : [
245+ `if (!nativeContextMenuDisabled || callback == null) {
246+ return callback;
247+ }
248+ return new ActionMode.Callback2() {
249+ @Override
250+ public boolean onCreateActionMode(ActionMode mode, Menu menu) {
251+ boolean created = callback.onCreateActionMode(mode, menu);
252+ if (created) {
253+ suppressActionModeUi(mode, menu);
254+ }
255+ return created;
256+ }
257+
258+ @Override
259+ public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
260+ boolean prepared = callback.onPrepareActionMode(mode, menu);
261+ suppressActionModeUi(mode, menu);
262+ return prepared;
263+ }
264+
265+ @Override
266+ public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
267+ return callback.onActionItemClicked(mode, item);
268+ }
269+
270+ @Override
271+ public void onDestroyActionMode(ActionMode mode) {
272+ callback.onDestroyActionMode(mode);
273+ }
274+
275+ @Override
276+ public void onGetContentRect(ActionMode mode, View view, Rect outRect) {
277+ if (callback instanceof ActionMode.Callback2) {
278+ ((ActionMode.Callback2) callback).onGetContentRect(mode, view, outRect);
279+ return;
280+ }
281+ super.onGetContentRect(mode, view, outRect);
282+ }
283+ };` ,
284+ ] ,
285+ } ,
286+ {
287+ name : 'suppressActionMode' ,
288+ modifier : 'private' ,
289+ returnType : 'ActionMode' ,
290+ params : [
291+ {
292+ type : 'ActionMode' ,
293+ name : 'mode' ,
294+ }
295+ ] ,
296+ body : [
297+ `if (mode == null || !nativeContextMenuDisabled) {
298+ return mode;
299+ }
300+ suppressActionModeUi(mode, mode.getMenu());
301+ return mode;` ,
302+ ] ,
303+ } ,
304+ {
305+ name : 'suppressActionModeUi' ,
306+ modifier : 'private' ,
307+ returnType : 'void' ,
308+ params : [
309+ {
310+ type : 'ActionMode' ,
311+ name : 'mode' ,
312+ } ,
313+ {
314+ type : 'Menu' ,
315+ name : 'menu' ,
316+ }
317+ ] ,
318+ body : [
319+ `if (mode == null || !nativeContextMenuDisabled || menu == null) {
320+ return;
321+ }
322+ menu.clear();
323+ mode.setTitle(null);
324+ mode.setSubtitle(null);
325+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
326+ post(() -> {
327+ if (!nativeContextMenuDisabled) {
328+ return;
329+ }
330+ try {
331+ mode.hide(0);
332+ } catch (Throwable ignored) {
333+ }
334+ });
335+ }` ,
336+ ] ,
337+ } ,
105338 ]
106339 } ,
107340 'SystemWebViewEngine.java' : {
108341 methods : [
109- setInputTypeMethod
342+ setInputTypeMethod ,
343+ setNativeContextMenuDisabledMethod ,
110344 ]
111345 } ,
112346 'CordovaWebViewEngine.java' : {
113347 methods : [
114- interfaceMethod
348+ interfaceMethod ,
349+ nativeContextMenuInterfaceMethod ,
115350 ]
116351 } ,
117352 'CordovaWebView.java' : {
118353 methods : [
119- interfaceMethod
354+ interfaceMethod ,
355+ nativeContextMenuInterfaceMethod ,
120356 ]
121357 } ,
122358 'CordovaWebViewImpl.java' : {
123359 methods : [
124360 {
125361 ...setInputTypeMethod ,
126362 body : [ `engine.setInputType(type);` ]
363+ } ,
364+ {
365+ ...setNativeContextMenuDisabledMethod ,
366+ body : [ `engine.setNativeContextMenuDisabled(disabled);` ]
127367 }
128368 ]
129369 }
@@ -198,7 +438,7 @@ async function main() {
198438 } ) ;
199439 }
200440
201- fs . writeFile ( flagFile , '' , err => {
441+ fs . writeFile ( flagFile , patchVersion , err => {
202442 if ( err ) {
203443 console . log ( err ) ;
204444 process . exit ( 1 ) ;
@@ -254,4 +494,4 @@ async function main() {
254494 function removeComments ( content ) {
255495 return content . replace ( / \/ \* [ \s \S ] * ?\* \/ | ( [ ^ \\ : ] | ^ ) \/ \/ .* $ / gm, '' ) ;
256496 }
257- }
497+ }
0 commit comments