Bug 701305 - Refactor DoorHanger code to make it easier to support persistence/timeout options. r=mfinkle

This commit is contained in:
Margaret Leibovic 2011-11-11 13:43:38 -08:00
Родитель 0b2548c730
Коммит dc603e9fb1
5 изменённых файлов: 82 добавлений и 138 удалений

Просмотреть файл

@ -69,7 +69,7 @@ public class DoorHanger extends LinearLayout implements Button.OnClickListener {
LayoutInflater inflater = LayoutInflater inflater =
(LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.doorhanger, this); inflater.inflate(R.layout.doorhanger, this);
hidePopup(); hide();
mTextView = (TextView) findViewById(R.id.doorhanger_title); mTextView = (TextView) findViewById(R.id.doorhanger_title);
mChoicesLayout = (LinearLayout) findViewById(R.id.doorhanger_choices); mChoicesLayout = (LinearLayout) findViewById(R.id.doorhanger_choices);
@ -90,15 +90,18 @@ public class DoorHanger extends LinearLayout implements Button.OnClickListener {
public void onClick(View v) { public void onClick(View v) {
GeckoEvent e = new GeckoEvent("Doorhanger:Reply", v.getTag().toString()); GeckoEvent e = new GeckoEvent("Doorhanger:Reply", v.getTag().toString());
GeckoAppShell.sendEventToGecko(e); GeckoAppShell.sendEventToGecko(e);
hidePopup(); mTab.removeDoorHanger(mValue);
GeckoApp.mDoorHangerPopup.removeDoorHanger(mTab, 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); setVisibility(View.VISIBLE);
} }
public void hidePopup() { public void hide() {
setVisibility(View.GONE); setVisibility(View.GONE);
} }

Просмотреть файл

@ -51,6 +51,10 @@ import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams; import android.widget.LinearLayout.LayoutParams;
import android.widget.RelativeLayout; import android.widget.RelativeLayout;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONException;
public class DoorHangerPopup extends PopupWindow { public class DoorHangerPopup extends PopupWindow {
private Context mContext; private Context mContext;
private LinearLayout mContent; private LinearLayout mContent;
@ -69,72 +73,73 @@ public class DoorHangerPopup extends PopupWindow {
setContentView(layout); 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()); Log.i("DoorHangerPopup", "Adding a DoorHanger to Tab: " + tab.getId());
// Replace the doorhanger if it already exists
DoorHanger dh = tab.getDoorHanger(value); DoorHanger dh = tab.getDoorHanger(value);
if (dh != null) { if (dh != null) {
dh.hidePopup();
tab.removeDoorHanger(value); tab.removeDoorHanger(value);
} }
dh = new DoorHanger(mContent.getContext(), 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); dh.setTab(tab);
tab.addDoorHanger(value, dh); tab.addDoorHanger(value, dh);
mContent.addView(dh); mContent.addView(dh);
return dh; updatePopupForTab(tab);
} }
public void removeDoorHanger(Tab tab, String value) { // Updates popup contents to show doorhangers associated with tab
Log.i("DoorHangerPopup", "Removing a DoorHanger from Tab: " + tab.getId()); public void updatePopupForTab(Tab tab) {
tab.removeDoorHanger(value); if (tab == null) {
hidePopup();
if (tab.getDoorHangers().size() == 0)
hide();
else
fixBackgroundForFirst();
}
public void showDoorHanger(DoorHanger dh) {
if (dh == null)
return; return;
}
dh.showPopup();
show(); // Hide old doorhangers
} for (int i = 0; i < mContent.getChildCount(); i++) {
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++) {
DoorHanger dh = (DoorHanger) mContent.getChildAt(i); DoorHanger dh = (DoorHanger) mContent.getChildAt(i);
if (dh.getTab() != tab) dh.hide();
dh.hidePopup(); }
Log.i("DoorHangerPopup", "Showing all doorhangers for tab: " + tab.getId());
HashMap<String, DoorHanger> 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) // Show the doorhangers for the tab
hide(); for (DoorHanger dh : doorHangers.values()) {
dh.show();
}
showPopup();
} }
public void hide() { public void hidePopup() {
if (isShowing()) { if (isShowing()) {
Log.i("DoorHangerPopup", "Dismissing the DoorHangerPopup"); Log.i("DoorHangerPopup", "Hiding the DoorHangerPopup");
dismiss(); dismiss();
} }
} }
public void show() { public void showPopup() {
Log.i("DoorHangerPopup", "Showing the DoorHangerPopup"); Log.i("DoorHangerPopup", "Showing the DoorHangerPopup");
fixBackgroundForFirst(); fixBackgroundForFirst();
@ -144,46 +149,6 @@ public class DoorHangerPopup extends PopupWindow {
showAsDropDown(GeckoApp.mBrowserToolbar.mFavicon); 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<String, DoorHanger> 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<String, DoorHanger> doorHangers = tab.getDoorHangers();
if (doorHangers == null)
return;
Iterator keys = doorHangers.keySet().iterator();
while (keys.hasNext()) {
((DoorHanger) doorHangers.get(keys.next())).hidePopup();
}
}
private void fixBackgroundForFirst() { private void fixBackgroundForFirst() {
for (int i=0; i < mContent.getChildCount(); i++) { for (int i=0; i < mContent.getChildCount(); i++) {
DoorHanger dh = (DoorHanger) mContent.getChildAt(i); DoorHanger dh = (DoorHanger) mContent.getChildAt(i);

Просмотреть файл

@ -573,7 +573,9 @@ abstract public class GeckoApp
tab.updateFavicon(null); tab.updateFavicon(null);
tab.updateFaviconURL(null); tab.updateFaviconURL(null);
tab.updateSecurityMode("unknown"); tab.updateSecurityMode("unknown");
mDoorHangerPopup.removeForTab(tab);
// TODO: check persistence and timeout options before removing doorhangers
tab.removeAllDoorHangers();
mMainHandler.post(new Runnable() { mMainHandler.post(new Runnable() {
public void run() { public void run() {
@ -581,7 +583,7 @@ abstract public class GeckoApp
mBrowserToolbar.setTitle(uri); mBrowserToolbar.setTitle(uri);
mBrowserToolbar.setFavicon(null); mBrowserToolbar.setFavicon(null);
mBrowserToolbar.setSecurityMode("unknown"); mBrowserToolbar.setSecurityMode("unknown");
mDoorHangerPopup.hideAllDoorHangers(); mDoorHangerPopup.updatePopupForTab(tab);
} }
} }
}); });
@ -734,8 +736,7 @@ abstract public class GeckoApp
Log.i(LOG_NAME, "Switched to tab: " + tabId); Log.i(LOG_NAME, "Switched to tab: " + tabId);
handleSelectTab(tabId); handleSelectTab(tabId);
} else if (event.equals("Doorhanger:Add")) { } else if (event.equals("Doorhanger:Add")) {
int tabId = message.getInt("tabID"); handleDoorHanger(message);
handleDoorHanger(message, tabId);
} else if (event.equals("Preferences:Data")) { } else if (event.equals("Preferences:Data")) {
JSONArray jsonPrefs = message.getJSONArray("preferences"); JSONArray jsonPrefs = message.getJSONArray("preferences");
GeckoPreferences.refresh(jsonPrefs); GeckoPreferences.refresh(jsonPrefs);
@ -771,40 +772,20 @@ abstract public class GeckoApp
} }
} }
void handleDoorHanger(JSONObject geckoObject, final int tabId) throws JSONException { void handleDoorHanger(JSONObject geckoObject) throws JSONException {
final String msg = geckoObject.getString("message"); final String message = geckoObject.getString("message");
final String value = geckoObject.getString("value"); final String value = geckoObject.getString("value");
Log.i(LOG_NAME, "DoorHanger received for tab " + tabId
+ ", msg:" + msg);
final JSONArray buttons = geckoObject.getJSONArray("buttons"); 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() { mMainHandler.post(new Runnable() {
public void run() { public void run() {
Tab tab = Tabs.getInstance().getTab(tabId); Tab tab = Tabs.getInstance().getTab(tabId);
DoorHanger dh = mAppContext.mDoorHangerPopup.addDoorHanger(tab, value); mAppContext.mDoorHangerPopup.addDoorHanger(message, value, buttons, tab);
}
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);
}
});
} }
void handleAddTab(final int tabId, final String uri, final boolean selected) { void handleAddTab(final int tabId, final String uri, final boolean selected) {
@ -817,7 +798,7 @@ abstract public class GeckoApp
public void run() { public void run() {
if (selected && Tabs.getInstance().isSelectedTab(tab)) { if (selected && Tabs.getInstance().isSelectedTab(tab)) {
onTabsChanged(); onTabsChanged();
mDoorHangerPopup.showForTab(tab); mDoorHangerPopup.updatePopupForTab(tab);
} }
mBrowserToolbar.updateTabs(Tabs.getInstance().getCount()); mBrowserToolbar.updateTabs(Tabs.getInstance().getCount());
} }
@ -827,13 +808,13 @@ abstract public class GeckoApp
void handleCloseTab(final int tabId) { void handleCloseTab(final int tabId) {
final Tab tab = Tabs.getInstance().getTab(tabId); final Tab tab = Tabs.getInstance().getTab(tabId);
Tabs.getInstance().removeTab(tabId); Tabs.getInstance().removeTab(tabId);
mDoorHangerPopup.removeForTab(tab); tab.removeAllDoorHangers();
mMainHandler.post(new Runnable() { mMainHandler.post(new Runnable() {
public void run() { public void run() {
onTabsChanged(); onTabsChanged();
mBrowserToolbar.updateTabs(Tabs.getInstance().getCount()); mBrowserToolbar.updateTabs(Tabs.getInstance().getCount());
mDoorHangerPopup.hideForTab(tab); mDoorHangerPopup.updatePopupForTab(tab);
} }
}); });
} }
@ -850,7 +831,7 @@ abstract public class GeckoApp
mBrowserToolbar.setFavicon(tab.getFavicon()); mBrowserToolbar.setFavicon(tab.getFavicon());
mBrowserToolbar.setSecurityMode(tab.getSecurityMode()); mBrowserToolbar.setSecurityMode(tab.getSecurityMode());
mBrowserToolbar.setProgressVisibility(tab.isLoading()); mBrowserToolbar.setProgressVisibility(tab.isLoading());
mDoorHangerPopup.showForTab(tab); mDoorHangerPopup.updatePopupForTab(tab);
} }
} }
}); });
@ -1516,7 +1497,6 @@ abstract public class GeckoApp
if (tab == null) if (tab == null)
return false; return false;
mDoorHangerPopup.hideAllDoorHangers();
return tab.doReload(); return tab.doReload();
} }

Просмотреть файл

@ -215,7 +215,6 @@ public class Tab {
return false; return false;
GeckoEvent e = new GeckoEvent("Session:Reload", ""); GeckoEvent e = new GeckoEvent("Session:Reload", "");
GeckoAppShell.sendEventToGecko(e); GeckoAppShell.sendEventToGecko(e);
removeAllDoorHangers();
return true; return true;
} }
@ -225,7 +224,6 @@ public class Tab {
} }
GeckoEvent e = new GeckoEvent("Session:Back", ""); GeckoEvent e = new GeckoEvent("Session:Back", "");
GeckoAppShell.sendEventToGecko(e); GeckoAppShell.sendEventToGecko(e);
removeAllDoorHangers();
return true; return true;
} }
@ -239,7 +237,6 @@ public class Tab {
} }
GeckoEvent e = new GeckoEvent("Session:Forward", ""); GeckoEvent e = new GeckoEvent("Session:Forward", "");
GeckoAppShell.sendEventToGecko(e); GeckoAppShell.sendEventToGecko(e);
removeAllDoorHangers();
return true; return true;
} }
@ -263,7 +260,7 @@ public class Tab {
return mDoorHangers.get(value); return mDoorHangers.get(value);
return null; return null;
} }
public HashMap<String, DoorHanger> getDoorHangers() { public HashMap<String, DoorHanger> getDoorHangers() {
return mDoorHangers; return mDoorHangers;

Просмотреть файл

@ -678,9 +678,8 @@ var NativeWindow = {
_callbacks: {}, _callbacks: {},
_callbacksId: 0, _callbacksId: 0,
_promptId: 0, _promptId: 0,
show: function(aMessage, aValue, aButtons, aTab) {
// use the current tab if none is provided show: function(aMessage, aValue, aButtons, aTabID) {
let tabID = aTab ? aTab : BrowserApp.selectedTab.id;
aButtons.forEach((function(aButton) { aButtons.forEach((function(aButton) {
this._callbacks[this._callbacksId] = { cb: aButton.callback, prompt: this._promptId }; this._callbacks[this._callbacksId] = { cb: aButton.callback, prompt: this._promptId };
aButton.callback = this._callbacksId; aButton.callback = this._callbacksId;
@ -692,10 +691,10 @@ var NativeWindow = {
gecko: { gecko: {
type: "Doorhanger:Add", type: "Doorhanger:Add",
message: aMessage, message: aMessage,
severity: "PRIORITY_WARNING_MEDIUM", value: aValue,
buttons: aButtons, buttons: aButtons,
tabID: tabID, // use the current tab if none is provided
value: aValue tabID: aTabID || BrowserApp.selectedTab.id
} }
}; };
sendMessageToJava(json); sendMessageToJava(json);