Bug 725018 - FormAssistant should reposition itself on viewport changes. r=kats,mleibovic

This commit is contained in:
Wes Johnston 2013-01-09 11:37:01 -08:00
parent 91378178cb
commit f1da34eb65
5 changed files with 48 additions and 22 deletions

View File

@ -249,6 +249,8 @@ abstract public class GeckoApp
// Fall through...
case SELECTED:
invalidateOptionsMenu();
if (mFormAssistPopup != null)
mFormAssistPopup.hide();
break;
}
}
@ -646,11 +648,6 @@ abstract public class GeckoApp
outState.putString(SAVED_STATE_PRIVATE_SESSION, mPrivateBrowsingSession);
}
public void hideFormAssistPopup() {
if (mFormAssistPopup != null)
mFormAssistPopup.hide();
}
void handleSecurityChange(final int tabId, final JSONObject identityData) {
final Tab tab = Tabs.getInstance().getTab(tabId);
if (tab == null)

View File

@ -133,7 +133,6 @@ public class Tabs implements GeckoEventListener {
mSelectedTab = tab;
mActivity.runOnUiThread(new Runnable() {
public void run() {
mActivity.hideFormAssistPopup();
if (isSelectedTab(tab)) {
notifyListeners(tab, TabEvents.SELECTED);

View File

@ -133,10 +133,6 @@ public class LayerView extends FrameLayout {
if (event.getActionMasked() == MotionEvent.ACTION_DOWN)
requestFocus();
/** We need to manually hide FormAssistPopup because it is not a regular PopupWindow. */
if (GeckoApp.mAppContext != null)
GeckoApp.mAppContext.hideFormAssistPopup();
return mTouchEventHandler == null ? false : mTouchEventHandler.handleEvent(event);
}

View File

@ -140,7 +140,10 @@ public class PanZoomController
}
private void setState(PanZoomState state) {
mState = state;
if (state != mState) {
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("PanZoom:StateChange", state.toString()));
mState = state;
}
}
private ImmutableViewportMetrics getMetrics() {
@ -515,7 +518,7 @@ public class PanZoomController
}
/* Performs a bounce-back animation to the given viewport metrics. */
private void bounce(ImmutableViewportMetrics metrics) {
private void bounce(ImmutableViewportMetrics metrics, PanZoomState state) {
stopAnimationTimer();
ImmutableViewportMetrics bounceStartMetrics = getMetrics();
@ -524,6 +527,8 @@ public class PanZoomController
return;
}
setState(state);
// At this point we have already set mState to BOUNCE or ANIMATED_ZOOM, so
// getRedrawHint() is returning false. This means we can safely call
// setAnimationTarget to set the new final display port and not have it get
@ -534,8 +539,7 @@ public class PanZoomController
/* Performs a bounce-back animation to the nearest valid viewport metrics. */
private void bounce() {
setState(PanZoomState.BOUNCE);
bounce(getValidViewportMetrics());
bounce(getValidViewportMetrics(), PanZoomState.BOUNCE);
}
/* Starts the fling or bounce animation. */
@ -1024,7 +1028,6 @@ public class PanZoomController
* pixels.
*/
private boolean animatedZoomTo(RectF zoomToRect) {
setState(PanZoomState.ANIMATED_ZOOM);
final float startZoom = getMetrics().zoomFactor;
RectF viewport = getMetrics().getViewport();
@ -1060,7 +1063,7 @@ public class PanZoomController
// clamped down to prevent overscroll, over-zoom, and other bad conditions.
finalMetrics = getValidViewportMetrics(finalMetrics);
bounce(finalMetrics);
bounce(finalMetrics, PanZoomState.ANIMATED_ZOOM);
return true;
}

View File

@ -989,7 +989,7 @@ var BrowserApp = {
});
},
scrollToFocusedInput: function(aBrowser, aAllowZoom = true) {
getFocusedInput: function(aBrowser, aOnlyInputElements = false) {
let doc = aBrowser.contentDocument;
if (!doc)
return;
@ -1000,9 +1000,13 @@ var BrowserApp = {
focused = doc.activeElement;
}
if ((focused instanceof HTMLInputElement && focused.mozIsTextField(false))
|| (focused instanceof HTMLTextAreaElement)
|| (focused.isContentEditable)) {
if (focused instanceof HTMLInputElement && focused.mozIsTextField(false))
return focused;
if (aOnlyInputElements)
return null;
if (focused instanceof HTMLTextAreaElement || focused.isContentEditable) {
if (focused instanceof HTMLBodyElement) {
// we are putting focus into a contentEditable frame. scroll the frame into
@ -1010,7 +1014,14 @@ var BrowserApp = {
// results in a better user experience
focused = focused.ownerDocument.defaultView.frameElement;
}
return focused;
}
return null;
},
scrollToFocusedInput: function(aBrowser, aAllowZoom = true) {
let focused = this.getFocusedInput(aBrowser);
if (focused) {
// _zoomToElement will handle not sending any message if this input is already mostly filling the screen
BrowserEventHandler._zoomToElement(focused, -1, false, aAllowZoom);
}
@ -4820,6 +4831,7 @@ var FormAssistant = {
Services.obs.addObserver(this, "FormAssist:Blocklisted", false);
Services.obs.addObserver(this, "FormAssist:Hidden", false);
Services.obs.addObserver(this, "invalidformsubmit", false);
Services.obs.addObserver(this, "PanZoom:StateChange", false);
// We need to use a capturing listener for focus events
BrowserApp.deck.addEventListener("focus", this, true);
@ -4833,6 +4845,7 @@ var FormAssistant = {
Services.obs.removeObserver(this, "FormAssist:Blocklisted");
Services.obs.removeObserver(this, "FormAssist:Hidden");
Services.obs.removeObserver(this, "invalidformsubmit");
Services.obs.removeObserver(this, "PanZoom:StateChange");
BrowserApp.deck.removeEventListener("focus", this);
BrowserApp.deck.removeEventListener("click", this);
@ -4842,6 +4855,24 @@ var FormAssistant = {
observe: function(aSubject, aTopic, aData) {
switch (aTopic) {
case "PanZoom:StateChange":
// If the user is just touching the screen and we haven't entered a pan or zoom state yet do nothing
if (aData == "TOUCHING" || aData == "WAITING_LISTENERS")
break;
if (aData == "NOTHING") {
// only look for input elements, not contentEditable or multiline text areas
let focused = BrowserApp.getFocusedInput(BrowserApp.selectedBrowser, true);
if (!focused)
break;
if (this._showValidationMessage(focused))
break;
this._showAutoCompleteSuggestions(focused);
} else {
// temporarily hide the form assist popup while we're panning or zooming the page
this._hideFormAssistPopup();
}
break;
case "FormAssist:AutoComplete":
if (!this._currentInputElement)
break;
@ -4906,9 +4937,9 @@ var FormAssistant = {
// only be available if an invalid form was submitted)
if (this._showValidationMessage(currentElement))
break;
this._showAutoCompleteSuggestions(currentElement);
if (!this._showAutoCompleteSuggestions(currentElement))
this._hideFormAssistPopup();
break;
case "input":
currentElement = aEvent.target;