Bug 884075 - Add a javascript api for button toasts. r=margaret

This commit is contained in:
Wes Johnston 2013-07-16 01:33:06 -07:00
parent c1770f641b
commit 47c86eb614
3 changed files with 71 additions and 11 deletions

View File

@ -113,7 +113,6 @@ abstract public class BrowserApp extends GeckoApp
}
private Vector<MenuItemInfo> mAddonMenuItemsCache;
private ButtonToast mToast;
private PropertyAnimator mMainLayoutAnimator;
private static final Interpolator sTabsInterpolator = new Interpolator() {
@ -395,8 +394,6 @@ abstract public class BrowserApp extends GeckoApp
mBrowserToolbar = (BrowserToolbar) findViewById(R.id.browser_toolbar);
mToast = new ButtonToast(findViewById(R.id.toast));
((GeckoApp.MainLayout) mMainLayout).setTouchEventInterceptor(new HideTabsTouchListener());
((GeckoApp.MainLayout) mMainLayout).setMotionEventInterceptor(new MotionEventInterceptor() {
@Override

View File

@ -25,6 +25,7 @@ import org.mozilla.gecko.util.GeckoEventResponder;
import org.mozilla.gecko.util.HardwareUtils;
import org.mozilla.gecko.util.ThreadUtils;
import org.mozilla.gecko.util.UiAsyncTask;
import org.mozilla.gecko.widget.ButtonToast;
import org.json.JSONArray;
import org.json.JSONException;
@ -44,6 +45,7 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.Sensor;
@ -187,6 +189,7 @@ abstract public class GeckoApp
protected DoorHangerPopup mDoorHangerPopup;
protected FormAssistPopup mFormAssistPopup;
protected TabsPanel mTabsPanel;
protected ButtonToast mToast;
// Handles notification messages from javascript
protected NotificationHelper mNotificationHelper;
@ -545,8 +548,16 @@ abstract public class GeckoApp
try {
if (event.equals("Toast:Show")) {
final String msg = message.getString("message");
final String duration = message.getString("duration");
handleShowToast(msg, duration);
final JSONObject button = message.optJSONObject("button");
if (button != null) {
final String label = button.optString("label");
final String icon = button.optString("icon");
final String id = button.optString("id");
showButtonToast(msg, label, icon, id);
} else {
final String duration = message.getString("duration");
showNormalToast(msg, duration);
}
} else if (event.equals("log")) {
// generic log listener
final String msg = message.getString("msg");
@ -810,20 +821,42 @@ abstract public class GeckoApp
});
}
void handleShowToast(final String message, final String duration) {
public void showNormalToast(final String message, final String duration) {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
Toast toast;
if (duration.equals("long"))
if (duration.equals("long")) {
toast = Toast.makeText(GeckoApp.this, message, Toast.LENGTH_LONG);
else
} else {
toast = Toast.makeText(GeckoApp.this, message, Toast.LENGTH_SHORT);
}
toast.show();
}
});
}
void showButtonToast(final String message, final String buttonText,
final String buttonIcon, final String buttonId) {
BitmapUtils.getDrawable(GeckoApp.this, buttonIcon, new BitmapUtils.BitmapLoader() {
public void onBitmapFound(Drawable d) {
mToast.show(false, message, buttonText, d, new ButtonToast.ToastListener() {
@Override
public void onButtonClicked() {
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Toast:Click", buttonId));
}
@Override
public void onToastHidden(ButtonToast.ReasonHidden reason) {
if (reason == ButtonToast.ReasonHidden.TIMEOUT) {
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Toast:Hidden", buttonId));
}
}
});
}
});
}
private void addFullScreenPluginView(View view) {
if (mFullScreenPluginView != null) {
Log.w(LOGTAG, "Already have a fullscreen plugin view");
@ -1278,6 +1311,7 @@ abstract public class GeckoApp
// Set up tabs panel.
mTabsPanel = (TabsPanel) findViewById(R.id.tabs_panel);
mNotificationHelper = new NotificationHelper(this);
mToast = new ButtonToast(findViewById(R.id.toast));
// Check if the last run was exited due to a normal kill while
// we were in the background, or a more harsh kill while we were

View File

@ -204,6 +204,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "Rect",
"resource://gre/modules/Geometry.jsm");
function resolveGeckoURI(aURI) {
if (!aURI)
throw "Can't resolve an empty uri";
if (aURI.startsWith("chrome://")) {
let registry = Cc['@mozilla.org/chrome/chrome-registry;1'].getService(Ci["nsIChromeRegistry"]);
return registry.convertChromeURL(Services.io.newURI(aURI, null, null)).spec;
@ -1553,6 +1556,8 @@ var NativeWindow = {
Services.obs.addObserver(this, "PageActions:Clicked", false);
Services.obs.addObserver(this, "PageActions:LongClicked", false);
Services.obs.addObserver(this, "Doorhanger:Reply", false);
Services.obs.addObserver(this, "Toast:Click", false);
Services.obs.addObserver(this, "Toast:Hidden", false);
this.contextmenus.init();
},
@ -1561,6 +1566,8 @@ var NativeWindow = {
Services.obs.removeObserver(this, "PageActions:Clicked");
Services.obs.removeObserver(this, "PageActions:LongClicked");
Services.obs.removeObserver(this, "Doorhanger:Reply");
Services.obs.removeObserver(this, "Toast:Click", false);
Services.obs.removeObserver(this, "Toast:Hidden", false);
this.contextmenus.uninit();
},
@ -1580,12 +1587,26 @@ var NativeWindow = {
},
toast: {
show: function(aMessage, aDuration) {
sendMessageToJava({
_callbacks: {},
show: function(aMessage, aDuration, aOptions) {
let msg = {
type: "Toast:Show",
message: aMessage,
duration: aDuration
});
};
if (aOptions && aOptions.button) {
msg.button = {
label: aOptions.button.label,
id: uuidgen.generateUUID().toString(),
// If the caller specified a button, make sure we convert any chrome urls
// to jar:jar urls so that the frontend can show them
icon: aOptions.button.icon ? resolveGeckoURI(aOptions.button.icon) : null,
};
this._callbacks[msg.button.id] = aOptions.button.callback;
}
sendMessageToJava(msg);
}
},
@ -1721,6 +1742,14 @@ var NativeWindow = {
} else if (aTopic == "PageActions:LongClicked") {
if (this.pageactions._items[aData].longClickCallback)
this.pageactions._items[aData].longClickCallback();
} else if (aTopic == "Toast:Click") {
if (this.toast._callbacks[aData]) {
this.toast._callbacks[aData]();
delete this.toast._callbacks[aData];
}
} else if (aTopic == "Toast:Hidden") {
if (this.toast._callbacks[aData])
delete this.toast._callbacks[aData];
} else if (aTopic == "Doorhanger:Reply") {
let data = JSON.parse(aData);
let reply_id = data["callback"];