Bug 1369168 - Fix GeckoView multiple select prompt; r=droeh
authorJim Chen <nchen@mozilla.com>
Fri, 02 Jun 2017 16:16:11 -0400
changeset 362164 6a99686b566a55298d7fe38a97717f1731aa740a
parent 362163 949bae6eaa96e9590aa7b1eba2c36398d3caece3
child 362165 14a0b9d0edfffc4c2a87da1cc462f60a860dce98
push id31961
push userarchaeopteryx@coole-files.de
push dateSat, 03 Jun 2017 18:15:59 +0000
treeherdermozilla-central@130efc657df7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdroeh
bugs1369168
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1369168 - Fix GeckoView multiple select prompt; r=droeh 1) Fix a crash when sending back prompt results. 2) Restrict results to <option> elements. 3) Correctly report invalid results. 4) Correctly pre-check selected items. 5) Display Ok/Cancel buttons. MozReview-Commit-ID: H15ZygbBdXv
mobile/android/components/geckoview/GeckoViewPrompt.js
mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/BasicGeckoViewPrompt.java
--- a/mobile/android/components/geckoview/GeckoViewPrompt.js
+++ b/mobile/android/components/geckoview/GeckoViewPrompt.js
@@ -135,36 +135,37 @@ PromptFactory.prototype = {
       // Cancel: !result
       if (!result || result.choices === undefined) {
         return;
       }
 
       let dispatchEvents = false;
       if (!aElement.multiple) {
         let elem = map[result.choices[0]];
-        if (elem) {
+        if (elem && elem instanceof win.HTMLOptionElement) {
           dispatchEvents = !elem.selected;
           elem.selected = true;
         } else {
           Cu.reportError("Invalid id for select result: " + result.choices[0]);
         }
       } else {
         for (let i = 0; i < id; i++) {
           let elem = map[i];
           let index = result.choices.indexOf(String(i));
-          if (elem.selected != (index >= 0)) {
+          if (elem instanceof win.HTMLOptionElement &&
+              elem.selected !== (index >= 0)) {
             // Current selected is not the same as the new selected state.
             dispatchEvents = true;
             elem.selected = !elem.selected;
-            result.choices[index] = undefined;
           }
+          result.choices[index] = undefined;
         }
         for (let i = 0; i < result.choices.length; i++) {
           if (result.choices[i] !== undefined && result.choices[i] !== null) {
-            Cu.reportError("Invalid id for select result: " + result.choices[0]);
+            Cu.reportError("Invalid id for select result: " + result.choices[i]);
             break;
           }
         }
       }
 
       if (dispatchEvents) {
         this._dispatchEvents(aElement);
       }
--- a/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/BasicGeckoViewPrompt.java
+++ b/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/BasicGeckoViewPrompt.java
@@ -299,16 +299,21 @@ final class BasicGeckoViewPrompt impleme
         final Activity activity = getActivity(view);
         if (activity == null) {
             callback.dismiss();
             return;
         }
         final AlertDialog.Builder builder = new AlertDialog.Builder(activity);
         addStandardLayout(builder, title, msg, callback);
 
+        final ListView list = new ListView(builder.getContext());
+        if (type == CHOICE_TYPE_MULTIPLE) {
+            list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
+        }
+
         final ArrayAdapter<GeckoBundle> adapter = new ArrayAdapter<GeckoBundle>(
                 builder.getContext(), android.R.layout.simple_list_item_1) {
             private static final int TYPE_MENU_ITEM = 0;
             private static final int TYPE_MENU_CHECK = 1;
             private static final int TYPE_SEPARATOR = 2;
             private static final int TYPE_GROUP = 3;
             private static final int TYPE_SINGLE = 4;
             private static final int TYPE_MULTIPLE = 5;
@@ -385,32 +390,34 @@ final class BasicGeckoViewPrompt impleme
                     view = mInflater.inflate(layoutId, parent, false);
                 }
 
                 final GeckoBundle item = getItem(position);
                 final TextView text = (TextView) view;
                 text.setEnabled(!item.getBoolean("disabled"));
                 text.setText(item.getString("label"));
                 if (view instanceof CheckedTextView) {
-                    ((CheckedTextView) view).setChecked(item.getBoolean("selected"));
+                    final boolean selected = item.getBoolean("selected");
+                    if (itemType == TYPE_MULTIPLE) {
+                        list.setItemChecked(position, selected);
+                    } else {
+                        ((CheckedTextView) view).setChecked(selected);
+                    }
                 }
                 return view;
             }
         };
         addChoiceItems(type, adapter, choices, /* indent */ null);
 
-        final ListView list = new ListView(builder.getContext());
         list.setAdapter(adapter);
-        if (type == CHOICE_TYPE_MULTIPLE) {
-            list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
-        }
         builder.setView(list);
 
-        final AlertDialog dialog = builder.create();
+        final AlertDialog dialog;
         if (type == CHOICE_TYPE_SINGLE || type == CHOICE_TYPE_MENU) {
+            dialog = builder.create();
             list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                 @Override
                 public void onItemClick(final AdapterView<?> parent, final View v,
                                         final int position, final long id) {
                     final GeckoBundle item = adapter.getItem(position);
                     if (type == CHOICE_TYPE_MENU) {
                         final GeckoBundle[] children = item.getBundleArray("items");
                         if (children != null) {
@@ -444,19 +451,20 @@ final class BasicGeckoViewPrompt impleme
                     final int len = adapter.getCount();
                     ArrayList<String> items = new ArrayList<>(len);
                     for (int i = 0; i < len; i++) {
                         final GeckoBundle item = adapter.getItem(i);
                         if (item.getBoolean("selected")) {
                             items.add(item.getString("id"));
                         }
                     }
-                    callback.confirm(items.toArray(new GeckoBundle[items.size()]));
+                    callback.confirm(items.toArray(new String[items.size()]));
                 }
             });
+            dialog = builder.create();
         } else {
             throw new UnsupportedOperationException();
         }
         dialog.show();
     }
 
     private static int parseColor(final String value, final int def) {
         try {