From dc603e9fb1cb0ba4f6e5d4dd3f349c32aa9b4e2f Mon Sep 17 00:00:00 2001 From: Margaret Leibovic Date: Fri, 11 Nov 2011 13:43:38 -0800 Subject: [PATCH] Bug 701305 - Refactor DoorHanger code to make it easier to support persistence/timeout options. r=mfinkle --- embedding/android/DoorHanger.java | 13 ++- embedding/android/DoorHangerPopup.java | 133 +++++++++---------------- embedding/android/GeckoApp.java | 58 ++++------- embedding/android/Tab.java | 5 +- mobile/chrome/content/browser.js | 11 +- 5 files changed, 82 insertions(+), 138 deletions(-) diff --git a/embedding/android/DoorHanger.java b/embedding/android/DoorHanger.java index b93a7a716cae..9f0d61fdab3c 100644 --- a/embedding/android/DoorHanger.java +++ b/embedding/android/DoorHanger.java @@ -69,7 +69,7 @@ public class DoorHanger extends LinearLayout implements Button.OnClickListener { LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); inflater.inflate(R.layout.doorhanger, this); - hidePopup(); + hide(); mTextView = (TextView) findViewById(R.id.doorhanger_title); mChoicesLayout = (LinearLayout) findViewById(R.id.doorhanger_choices); @@ -90,15 +90,18 @@ public class DoorHanger extends LinearLayout implements Button.OnClickListener { public void onClick(View v) { GeckoEvent e = new GeckoEvent("Doorhanger:Reply", v.getTag().toString()); GeckoAppShell.sendEventToGecko(e); - hidePopup(); - GeckoApp.mDoorHangerPopup.removeDoorHanger(mTab, mValue); + mTab.removeDoorHanger(mValue); + + // This will hide the doorhanger (and hide the popup if there are no + // more doorhangers to show) + GeckoApp.mDoorHangerPopup.updatePopupForTab(mTab); } - public void showPopup() { + public void show() { setVisibility(View.VISIBLE); } - public void hidePopup() { + public void hide() { setVisibility(View.GONE); } diff --git a/embedding/android/DoorHangerPopup.java b/embedding/android/DoorHangerPopup.java index d59ec28a919e..745824d1abb7 100644 --- a/embedding/android/DoorHangerPopup.java +++ b/embedding/android/DoorHangerPopup.java @@ -51,6 +51,10 @@ import android.widget.LinearLayout; import android.widget.LinearLayout.LayoutParams; import android.widget.RelativeLayout; +import org.json.JSONArray; +import org.json.JSONObject; +import org.json.JSONException; + public class DoorHangerPopup extends PopupWindow { private Context mContext; private LinearLayout mContent; @@ -69,72 +73,73 @@ public class DoorHangerPopup extends PopupWindow { setContentView(layout); } - public DoorHanger addDoorHanger(Tab tab, String value) { + public void addDoorHanger(String message, String value, JSONArray buttons, Tab tab) { Log.i("DoorHangerPopup", "Adding a DoorHanger to Tab: " + tab.getId()); + // Replace the doorhanger if it already exists DoorHanger dh = tab.getDoorHanger(value); if (dh != null) { - dh.hidePopup(); tab.removeDoorHanger(value); } - dh = new DoorHanger(mContent.getContext(), value); + + // Set the doorhanger text and buttons + dh.setText(message); + for (int i = 0; i < buttons.length(); i++) { + try { + JSONObject buttonObject = buttons.getJSONObject(i); + String label = buttonObject.getString("label"); + int callBackId = buttonObject.getInt("callback"); + dh.addButton(label, callBackId); + } catch (JSONException e) { + Log.i("DoorHangerPopup", "JSON throws " + e); + } + } + dh.setTab(tab); tab.addDoorHanger(value, dh); mContent.addView(dh); - - return dh; + + updatePopupForTab(tab); } - public void removeDoorHanger(Tab tab, String value) { - Log.i("DoorHangerPopup", "Removing a DoorHanger from Tab: " + tab.getId()); - tab.removeDoorHanger(value); - - if (tab.getDoorHangers().size() == 0) - hide(); - else - fixBackgroundForFirst(); - } - - public void showDoorHanger(DoorHanger dh) { - if (dh == null) + // Updates popup contents to show doorhangers associated with tab + public void updatePopupForTab(Tab tab) { + if (tab == null) { + hidePopup(); return; - - dh.showPopup(); - show(); - } - - public void hideDoorHanger(DoorHanger dh) { - if (dh == null) - return; - - dh.hidePopup(); - show(); - } - - public void hideAllDoorHangers() { - hideAllDoorHangersExcept(null); - } - - public void hideAllDoorHangersExcept(Tab tab) { - for (int i=0; i < mContent.getChildCount(); i++) { + } + + // Hide old doorhangers + for (int i = 0; i < mContent.getChildCount(); i++) { DoorHanger dh = (DoorHanger) mContent.getChildAt(i); - if (dh.getTab() != tab) - dh.hidePopup(); + dh.hide(); + } + + Log.i("DoorHangerPopup", "Showing all doorhangers for tab: " + tab.getId()); + HashMap doorHangers = tab.getDoorHangers(); + // Hide the popup if there aren't any doorhangers to show + if (doorHangers == null || doorHangers.size() == 0) { + hidePopup(); + return; } - if (tab == null) - hide(); + // Show the doorhangers for the tab + for (DoorHanger dh : doorHangers.values()) { + dh.show(); + } + + showPopup(); } - - public void hide() { + + public void hidePopup() { if (isShowing()) { - Log.i("DoorHangerPopup", "Dismissing the DoorHangerPopup"); + Log.i("DoorHangerPopup", "Hiding the DoorHangerPopup"); dismiss(); } } - public void show() { + public void showPopup() { Log.i("DoorHangerPopup", "Showing the DoorHangerPopup"); fixBackgroundForFirst(); @@ -144,46 +149,6 @@ public class DoorHangerPopup extends PopupWindow { showAsDropDown(GeckoApp.mBrowserToolbar.mFavicon); } - public void removeForTab(Tab tab) { - Log.i("DoorHangerPopup", "Removing all doorhangers for tab: " + tab.getId()); - tab.removeAllDoorHangers(); - } - - public void showForTab(Tab tab) { - Log.i("DoorHangerPopup", "Showing all doorhangers for tab: " + tab.getId()); - HashMap doorHangers = tab.getDoorHangers(); - - if (doorHangers == null) { - hide(); - return; - } - - hideAllDoorHangersExcept(tab); - - Iterator keys = doorHangers.keySet().iterator(); - while (keys.hasNext()) { - ((DoorHanger) doorHangers.get(keys.next())).showPopup(); - } - - if (doorHangers.size() > 0) - show(); - else - hide(); - } - - public void hideForTab(Tab tab) { - Log.i("DoorHangerPopup", "Hiding all doorhangers for tab: " + tab.getId()); - HashMap doorHangers = tab.getDoorHangers(); - - if (doorHangers == null) - return; - - Iterator keys = doorHangers.keySet().iterator(); - while (keys.hasNext()) { - ((DoorHanger) doorHangers.get(keys.next())).hidePopup(); - } - } - private void fixBackgroundForFirst() { for (int i=0; i < mContent.getChildCount(); i++) { DoorHanger dh = (DoorHanger) mContent.getChildAt(i); diff --git a/embedding/android/GeckoApp.java b/embedding/android/GeckoApp.java index f66ad15e5e51..8c6af5baee52 100644 --- a/embedding/android/GeckoApp.java +++ b/embedding/android/GeckoApp.java @@ -573,7 +573,9 @@ abstract public class GeckoApp tab.updateFavicon(null); tab.updateFaviconURL(null); tab.updateSecurityMode("unknown"); - mDoorHangerPopup.removeForTab(tab); + + // TODO: check persistence and timeout options before removing doorhangers + tab.removeAllDoorHangers(); mMainHandler.post(new Runnable() { public void run() { @@ -581,7 +583,7 @@ abstract public class GeckoApp mBrowserToolbar.setTitle(uri); mBrowserToolbar.setFavicon(null); mBrowserToolbar.setSecurityMode("unknown"); - mDoorHangerPopup.hideAllDoorHangers(); + mDoorHangerPopup.updatePopupForTab(tab); } } }); @@ -734,8 +736,7 @@ abstract public class GeckoApp Log.i(LOG_NAME, "Switched to tab: " + tabId); handleSelectTab(tabId); } else if (event.equals("Doorhanger:Add")) { - int tabId = message.getInt("tabID"); - handleDoorHanger(message, tabId); + handleDoorHanger(message); } else if (event.equals("Preferences:Data")) { JSONArray jsonPrefs = message.getJSONArray("preferences"); GeckoPreferences.refresh(jsonPrefs); @@ -771,40 +772,20 @@ abstract public class GeckoApp } } - void handleDoorHanger(JSONObject geckoObject, final int tabId) throws JSONException { - final String msg = geckoObject.getString("message"); + void handleDoorHanger(JSONObject geckoObject) throws JSONException { + final String message = geckoObject.getString("message"); final String value = geckoObject.getString("value"); - Log.i(LOG_NAME, "DoorHanger received for tab " + tabId - + ", msg:" + msg); final JSONArray buttons = geckoObject.getJSONArray("buttons"); + final int tabId = geckoObject.getInt("tabID"); + + Log.i(LOG_NAME, "DoorHanger received for tab " + tabId + ", msg:" + message); mMainHandler.post(new Runnable() { - public void run() { - Tab tab = Tabs.getInstance().getTab(tabId); - DoorHanger dh = mAppContext.mDoorHangerPopup.addDoorHanger(tab, value); - - for (int i = 0; i < buttons.length(); i++) { - JSONObject jo; - String label; - int callBackId; - try { - jo = buttons.getJSONObject(i); - label = jo.getString("label"); - callBackId = jo.getInt("callback"); - Log.i(LOG_NAME, "Label: " + label - + " CallbackId: " + callBackId); - dh.addButton(label, callBackId); - } catch (JSONException e) { - Log.i(LOG_NAME, "JSON throws " + e); - } - } - dh.setText(msg); - - // Show doorhanger if it is on the active tab - if (Tabs.getInstance().isSelectedTab(tab)) - mAppContext.mDoorHangerPopup.showDoorHanger(dh); - } - }); + public void run() { + Tab tab = Tabs.getInstance().getTab(tabId); + mAppContext.mDoorHangerPopup.addDoorHanger(message, value, buttons, tab); + } + }); } void handleAddTab(final int tabId, final String uri, final boolean selected) { @@ -817,7 +798,7 @@ abstract public class GeckoApp public void run() { if (selected && Tabs.getInstance().isSelectedTab(tab)) { onTabsChanged(); - mDoorHangerPopup.showForTab(tab); + mDoorHangerPopup.updatePopupForTab(tab); } mBrowserToolbar.updateTabs(Tabs.getInstance().getCount()); } @@ -827,13 +808,13 @@ abstract public class GeckoApp void handleCloseTab(final int tabId) { final Tab tab = Tabs.getInstance().getTab(tabId); Tabs.getInstance().removeTab(tabId); - mDoorHangerPopup.removeForTab(tab); + tab.removeAllDoorHangers(); mMainHandler.post(new Runnable() { public void run() { onTabsChanged(); mBrowserToolbar.updateTabs(Tabs.getInstance().getCount()); - mDoorHangerPopup.hideForTab(tab); + mDoorHangerPopup.updatePopupForTab(tab); } }); } @@ -850,7 +831,7 @@ abstract public class GeckoApp mBrowserToolbar.setFavicon(tab.getFavicon()); mBrowserToolbar.setSecurityMode(tab.getSecurityMode()); mBrowserToolbar.setProgressVisibility(tab.isLoading()); - mDoorHangerPopup.showForTab(tab); + mDoorHangerPopup.updatePopupForTab(tab); } } }); @@ -1516,7 +1497,6 @@ abstract public class GeckoApp if (tab == null) return false; - mDoorHangerPopup.hideAllDoorHangers(); return tab.doReload(); } diff --git a/embedding/android/Tab.java b/embedding/android/Tab.java index f81ac32e3485..db104c0c46d1 100644 --- a/embedding/android/Tab.java +++ b/embedding/android/Tab.java @@ -215,7 +215,6 @@ public class Tab { return false; GeckoEvent e = new GeckoEvent("Session:Reload", ""); GeckoAppShell.sendEventToGecko(e); - removeAllDoorHangers(); return true; } @@ -225,7 +224,6 @@ public class Tab { } GeckoEvent e = new GeckoEvent("Session:Back", ""); GeckoAppShell.sendEventToGecko(e); - removeAllDoorHangers(); return true; } @@ -239,7 +237,6 @@ public class Tab { } GeckoEvent e = new GeckoEvent("Session:Forward", ""); GeckoAppShell.sendEventToGecko(e); - removeAllDoorHangers(); return true; } @@ -263,7 +260,7 @@ public class Tab { return mDoorHangers.get(value); return null; - } + } public HashMap getDoorHangers() { return mDoorHangers; diff --git a/mobile/chrome/content/browser.js b/mobile/chrome/content/browser.js index 56cbf6bec4aa..e6e1fcf5dc7c 100644 --- a/mobile/chrome/content/browser.js +++ b/mobile/chrome/content/browser.js @@ -678,9 +678,8 @@ var NativeWindow = { _callbacks: {}, _callbacksId: 0, _promptId: 0, - show: function(aMessage, aValue, aButtons, aTab) { - // use the current tab if none is provided - let tabID = aTab ? aTab : BrowserApp.selectedTab.id; + + show: function(aMessage, aValue, aButtons, aTabID) { aButtons.forEach((function(aButton) { this._callbacks[this._callbacksId] = { cb: aButton.callback, prompt: this._promptId }; aButton.callback = this._callbacksId; @@ -692,10 +691,10 @@ var NativeWindow = { gecko: { type: "Doorhanger:Add", message: aMessage, - severity: "PRIORITY_WARNING_MEDIUM", + value: aValue, buttons: aButtons, - tabID: tabID, - value: aValue + // use the current tab if none is provided + tabID: aTabID || BrowserApp.selectedTab.id } }; sendMessageToJava(json);