Bug 717787 - Suggestions from <datalist> are not shown in Native Fennec. r=mbrubeck

This commit is contained in:
Margaret Leibovic 2012-03-06 13:56:16 -08:00
parent 22c79d10e2
commit f6cdf26ec3
2 changed files with 93 additions and 10 deletions

View File

@ -44,7 +44,10 @@ import android.content.Context;
import android.util.Log; import android.util.Log;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation; import android.view.animation.Animation;
import android.view.animation.AnimationUtils; import android.view.animation.AnimationUtils;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
@ -91,8 +94,10 @@ public class FormAssistPopup extends ListView implements GeckoEventListener {
setOnItemClickListener(new OnItemClickListener() { setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parentView, View view, int position, long id) { public void onItemClick(AdapterView<?> parentView, View view, int position, long id) {
if (mTypeShowing.equals(PopupType.AUTOCOMPLETE)) { if (mTypeShowing.equals(PopupType.AUTOCOMPLETE)) {
// Use the value stored with the autocomplete view, not the label text,
// since they can be different.
TextView textView = (TextView) view; TextView textView = (TextView) view;
String value = textView.getText().toString(); String value = (String) textView.getTag();
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("FormAssist:AutoComplete", value)); GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("FormAssist:AutoComplete", value));
hide(); hide();
} }
@ -149,13 +154,8 @@ public class FormAssistPopup extends ListView implements GeckoEventListener {
} }
private void showAutoCompleteSuggestions(JSONArray suggestions, JSONArray rect, double zoom) { private void showAutoCompleteSuggestions(JSONArray suggestions, JSONArray rect, double zoom) {
ArrayAdapter<String> adapter = new ArrayAdapter<String>(mContext, R.layout.autocomplete_list_item); AutoCompleteListAdapter adapter = new AutoCompleteListAdapter(mContext, R.layout.autocomplete_list_item);
try { adapter.populateSuggestionsList(suggestions);
for (int i = 0; i < suggestions.length(); i++)
adapter.add(suggestions.get(i).toString());
} catch (JSONException e) {
Log.e(LOGTAG, "JSONException: " + e);
}
setAdapter(adapter); setAdapter(adapter);
if (positionAndShowPopup(rect, zoom)) if (positionAndShowPopup(rect, zoom))
@ -266,4 +266,48 @@ public class FormAssistPopup extends ListView implements GeckoEventListener {
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("FormAssist:Hidden", null)); GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("FormAssist:Hidden", null));
} }
} }
private class AutoCompleteListAdapter extends ArrayAdapter<Pair<String, String>> {
private LayoutInflater mInflater;
private int mTextViewResourceId;
public AutoCompleteListAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mTextViewResourceId = textViewResourceId;
}
// This method takes an array of autocomplete suggestions with label/value properties
// and adds label/value Pair objects to the array that backs the adapter.
public void populateSuggestionsList(JSONArray suggestions) {
try {
for (int i = 0; i < suggestions.length(); i++) {
JSONObject suggestion = (JSONObject) suggestions.get(i);
String label = suggestion.getString("label");
String value = suggestion.getString("value");
add(new Pair<String, String>(label, value));
}
} catch (JSONException e) {
Log.e(LOGTAG, "JSONException: " + e);
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null)
convertView = mInflater.inflate(mTextViewResourceId, null);
Pair<String, String> item = getItem(position);
TextView itemView = (TextView) convertView;
// Set the text with the suggestion label
itemView.setText(item.first);
// Set a tag with the suggestion value
itemView.setTag(item.second);
return convertView;
}
}
} }

View File

@ -2966,7 +2966,41 @@ var FormAssistant = {
if (value == aSearchString) if (value == aSearchString)
continue; continue;
suggestions.push(value); // Supply a label and value, since they can differ for datalist suggestions
suggestions.push({ label: value, value: value });
}
return suggestions;
},
/**
* (Copied from mobile/xul/chrome/content/forms.js)
* This function is similar to getListSuggestions from
* components/satchel/src/nsInputListAutoComplete.js but sadly this one is
* used by the autocomplete.xml binding which is not in used in fennec
*/
_getListSuggestions: function _getListSuggestions(aElement) {
if (!(aElement instanceof HTMLInputElement) || !aElement.list)
return [];
let suggestions = [];
let filter = !aElement.hasAttribute("mozNoFilter");
let lowerFieldValue = aElement.value.toLowerCase();
let options = aElement.list.options;
let length = options.length;
for (let i = 0; i < length; i++) {
let item = options.item(i);
let label = item.value;
if (item.label)
label = item.label;
else if (item.text)
label = item.text;
if (filter && label.toLowerCase().indexOf(lowerFieldValue) == -1)
continue;
suggestions.push({ label: label, value: item.value });
} }
return suggestions; return suggestions;
@ -2991,7 +3025,12 @@ var FormAssistant = {
if (!this._isAutoComplete(aElement)) if (!this._isAutoComplete(aElement))
return false; return false;
let suggestions = this._getAutoCompleteSuggestions(aElement.value, aElement); let autoCompleteSuggestions = this._getAutoCompleteSuggestions(aElement.value, aElement);
let listSuggestions = this._getListSuggestions(aElement);
// On desktop, we show datalist suggestions below autocomplete suggestions,
// without duplicates removed.
let suggestions = autoCompleteSuggestions.concat(listSuggestions);
// Return false if there are no suggestions to show // Return false if there are no suggestions to show
if (!suggestions.length) if (!suggestions.length)