mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 704879 - (5/6) Add form validation messages. r=lucasr
This commit is contained in:
parent
d15e231c7e
commit
775ec3156f
@ -74,6 +74,11 @@ public class FormAssistPopup extends ListView implements GeckoEventListener {
|
||||
private static final int POPUP_MIN_WIDTH_IN_DPI = 200;
|
||||
private static final int POPUP_ROW_HEIGHT_IN_DPI = 32;
|
||||
|
||||
private static enum PopupType { NONE, AUTOCOMPLETE, VALIDATION };
|
||||
|
||||
// Keep track of the type of popup we're currently showing
|
||||
private PopupType mTypeShowing = PopupType.NONE;
|
||||
|
||||
public FormAssistPopup(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mContext = context;
|
||||
@ -85,13 +90,17 @@ public class FormAssistPopup extends ListView implements GeckoEventListener {
|
||||
|
||||
setOnItemClickListener(new OnItemClickListener() {
|
||||
public void onItemClick(AdapterView<?> parentView, View view, int position, long id) {
|
||||
String value = ((TextView) view).getText().toString();
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("FormAssist:AutoComplete", value));
|
||||
hide();
|
||||
if (mTypeShowing.equals(PopupType.AUTOCOMPLETE)) {
|
||||
TextView textView = (TextView) view;
|
||||
String value = textView.getText().toString();
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("FormAssist:AutoComplete", value));
|
||||
hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
GeckoAppShell.registerGeckoEventListener("FormAssist:AutoComplete", this);
|
||||
GeckoAppShell.registerGeckoEventListener("FormAssist:ValidationMessage", this);
|
||||
GeckoAppShell.registerGeckoEventListener("FormAssist:Hide", this);
|
||||
}
|
||||
|
||||
@ -99,6 +108,8 @@ public class FormAssistPopup extends ListView implements GeckoEventListener {
|
||||
try {
|
||||
if (event.equals("FormAssist:AutoComplete")) {
|
||||
handleAutoCompleteMessage(message);
|
||||
} else if (event.equals("FormAssist:ValidationMessage")) {
|
||||
handleValidationMessage(message);
|
||||
} else if (event.equals("FormAssist:Hide")) {
|
||||
handleHideMessage(message);
|
||||
}
|
||||
@ -113,15 +124,22 @@ public class FormAssistPopup extends ListView implements GeckoEventListener {
|
||||
final double zoom = message.getDouble("zoom");
|
||||
GeckoApp.mAppContext.mMainHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
// Don't show autocomplete popup when using fullscreen VKB
|
||||
InputMethodManager imm =
|
||||
(InputMethodManager) GeckoApp.mAppContext.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
if (!imm.isFullscreenMode())
|
||||
show(suggestions, rect, zoom);
|
||||
showAutoCompleteSuggestions(suggestions, rect, zoom);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void handleValidationMessage(JSONObject message) throws JSONException {
|
||||
final String validationMessage = message.getString("validationMessage");
|
||||
final JSONArray rect = message.getJSONArray("rect");
|
||||
final double zoom = message.getDouble("zoom");
|
||||
GeckoApp.mAppContext.mMainHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
showValidationMessage(validationMessage, rect, zoom);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void handleHideMessage(JSONObject message) {
|
||||
GeckoApp.mAppContext.mMainHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
@ -130,18 +148,38 @@ public class FormAssistPopup extends ListView implements GeckoEventListener {
|
||||
});
|
||||
}
|
||||
|
||||
public void show(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);
|
||||
for (int i = 0; i < suggestions.length(); i++) {
|
||||
try {
|
||||
try {
|
||||
for (int i = 0; i < suggestions.length(); i++)
|
||||
adapter.add(suggestions.get(i).toString());
|
||||
} catch (JSONException e) {
|
||||
Log.i(LOGTAG, "JSONException: " + e);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
Log.e(LOGTAG, "JSONException: " + e);
|
||||
}
|
||||
|
||||
setAdapter(adapter);
|
||||
|
||||
if (positionAndShowPopup(rect, zoom))
|
||||
mTypeShowing = PopupType.AUTOCOMPLETE;
|
||||
}
|
||||
|
||||
// TODO: style the validation message popup differently (bug 731654)
|
||||
private void showValidationMessage(String validationMessage, JSONArray rect, double zoom) {
|
||||
ArrayAdapter<String> adapter = new ArrayAdapter<String>(mContext, R.layout.autocomplete_list_item);
|
||||
adapter.add(validationMessage);
|
||||
setAdapter(adapter);
|
||||
|
||||
if (positionAndShowPopup(rect, zoom))
|
||||
mTypeShowing = PopupType.VALIDATION;
|
||||
}
|
||||
|
||||
// Returns true if the popup is successfully shown, false otherwise
|
||||
public boolean positionAndShowPopup(JSONArray rect, double zoom) {
|
||||
// Don't show the form assist popup when using fullscreen VKB
|
||||
InputMethodManager imm =
|
||||
(InputMethodManager) GeckoApp.mAppContext.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
if (imm.isFullscreenMode())
|
||||
return false;
|
||||
|
||||
if (!isShown()) {
|
||||
setVisibility(View.VISIBLE);
|
||||
startAnimation(mAnimation);
|
||||
@ -193,7 +231,7 @@ public class FormAssistPopup extends ListView implements GeckoEventListener {
|
||||
listLeft = (int) (viewport.width - listWidth);
|
||||
}
|
||||
|
||||
listHeight = sRowHeight * adapter.getCount();
|
||||
listHeight = sRowHeight * getAdapter().getCount();
|
||||
|
||||
// The text box doesnt fit below
|
||||
if ((listTop + listHeight) > viewport.height) {
|
||||
@ -217,11 +255,14 @@ public class FormAssistPopup extends ListView implements GeckoEventListener {
|
||||
mLayout.setMargins(listLeft, listTop, 0, 0);
|
||||
setLayoutParams(mLayout);
|
||||
requestLayout();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
if (isShown()) {
|
||||
setVisibility(View.GONE);
|
||||
mTypeShowing = PopupType.NONE;
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("FormAssist:Hidden", null));
|
||||
}
|
||||
}
|
||||
|
@ -2832,20 +2832,31 @@ var ErrorPageEventHandler = {
|
||||
};
|
||||
|
||||
var FormAssistant = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIFormSubmitObserver]),
|
||||
|
||||
// Used to keep track of the element that corresponds to the current
|
||||
// autocomplete suggestions
|
||||
_currentInputElement: null,
|
||||
|
||||
// Keep track of whether or not an invalid form has been submitted
|
||||
_invalidSubmit: false,
|
||||
|
||||
init: function() {
|
||||
Services.obs.addObserver(this, "FormAssist:AutoComplete", false);
|
||||
Services.obs.addObserver(this, "FormAssist:Hidden", false);
|
||||
Services.obs.addObserver(this, "invalidformsubmit", false);
|
||||
|
||||
BrowserApp.deck.addEventListener("input", this, false);
|
||||
BrowserApp.deck.addEventListener("pageshow", this, false);
|
||||
},
|
||||
|
||||
uninit: function() {
|
||||
Services.obs.removeObserver(this, "FormAssist:AutoComplete");
|
||||
Services.obs.removeObserver(this, "FormAssist:Hidden");
|
||||
Services.obs.removeObserver(this, "invalidformsubmit");
|
||||
|
||||
BrowserApp.deck.removeEventListener("input", this);
|
||||
BrowserApp.deck.removeEventListener("pageshow", this);
|
||||
},
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
@ -2865,15 +2876,43 @@ var FormAssistant = {
|
||||
}
|
||||
},
|
||||
|
||||
notifyInvalidSubmit: function notifyInvalidSubmit(aFormElement, aInvalidElements) {
|
||||
if (!aInvalidElements.length)
|
||||
return;
|
||||
|
||||
// Ignore this notificaiton if the current tab doesn't contain the invalid form
|
||||
if (BrowserApp.selectedBrowser.contentDocument !=
|
||||
aFormElement.ownerDocument.defaultView.top.document)
|
||||
return;
|
||||
|
||||
this._invalidSubmit = true;
|
||||
|
||||
let currentElement = aInvalidElements.queryElementAt(0, Ci.nsISupports);
|
||||
if (this._showValidationMessage(currentElement))
|
||||
currentElement.focus();
|
||||
},
|
||||
|
||||
handleEvent: function(aEvent) {
|
||||
switch (aEvent.type) {
|
||||
case "input":
|
||||
let currentElement = aEvent.target;
|
||||
|
||||
// Since we can only show one popup at a time, prioritze autocomplete
|
||||
// suggestions over a form validation message
|
||||
if (this._showAutoCompleteSuggestions(currentElement))
|
||||
break;
|
||||
if (this._showValidationMessage(currentElement))
|
||||
break;
|
||||
|
||||
// If we're not showing autocomplete suggestions, hide the form assist popup
|
||||
this._hideFormAssistPopup();
|
||||
break;
|
||||
|
||||
// Reset invalid submit state on each pageshow
|
||||
case "pageshow":
|
||||
let target = aEvent.originalTarget;
|
||||
if (target == content.document || target.ownerDocument == content.document)
|
||||
this._invalidSubmit = false;
|
||||
}
|
||||
},
|
||||
|
||||
@ -2953,6 +2992,39 @@ var FormAssistant = {
|
||||
return true;
|
||||
},
|
||||
|
||||
// Only show a validation message if the user submitted an invalid form,
|
||||
// there's a non-empty message string, and the element is the correct type
|
||||
_isValidateable: function _isValidateable(aElement) {
|
||||
if (!this._invalidSubmit ||
|
||||
!aElement.validationMessage ||
|
||||
!(aElement instanceof HTMLInputElement ||
|
||||
aElement instanceof HTMLTextAreaElement ||
|
||||
aElement instanceof HTMLSelectElement ||
|
||||
aElement instanceof HTMLButtonElement))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
// Sends a validation message and position data for an element to the Java UI.
|
||||
// Returns true if there's a validation message to show, false otherwise.
|
||||
_showValidationMessage: function _sendValidationMessage(aElement) {
|
||||
if (!this._isValidateable(aElement))
|
||||
return false;
|
||||
|
||||
let positionData = this._getElementPositionData(aElement);
|
||||
sendMessageToJava({
|
||||
gecko: {
|
||||
type: "FormAssist:ValidationMessage",
|
||||
validationMessage: aElement.validationMessage,
|
||||
rect: positionData.rect,
|
||||
zoom: positionData.zoom
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
_hideFormAssistPopup: function _hideFormAssistPopup() {
|
||||
sendMessageToJava({
|
||||
gecko: { type: "FormAssist:Hide" }
|
||||
|
Loading…
Reference in New Issue
Block a user