Back out 7 changesets (bug 1147064) for NullPointerExceptions

Backed out changeset 1e9ce9823fd0 (bug 1147064)
Backed out changeset 17d997c1e1dc (bug 1147064)
Backed out changeset cb76155407ab (bug 1147064)
Backed out changeset 3194afdcbb92 (bug 1147064)
Backed out changeset 87af8d27e784 (bug 1147064)
Backed out changeset fd6e15eb81c3 (bug 1147064)
Backed out changeset 1175733ce0bb (bug 1147064)
This commit is contained in:
Phil Ringnalda 2015-06-01 21:40:01 -07:00
parent 14435bd19d
commit f7ea504b6d
22 changed files with 302 additions and 318 deletions

View File

@ -9,7 +9,6 @@ import java.util.HashSet;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONArray;
import org.mozilla.gecko.AppConstants.Versions;
import org.mozilla.gecko.util.GeckoEventListener;
import org.mozilla.gecko.util.ThreadUtils;
@ -114,21 +113,9 @@ public class DoorHangerPopup extends AnchoredPopup
final DoorhangerConfig config = new DoorhangerConfig(tabId, id, doorhangerType, this);
config.setMessage(json.getString("message"));
config.appendButtonsFromJSON(json.getJSONArray("buttons"));
config.setOptions(json.getJSONObject("options"));
final JSONArray buttonArray = json.getJSONArray("buttons");
int numButtons = buttonArray.length();
if (numButtons > 2) {
Log.e(LOGTAG, "Doorhanger can have a maximum of two buttons!");
numButtons = 2;
}
for (int i = 0; i < numButtons; i++) {
final JSONObject buttonJSON = buttonArray.getJSONObject(i);
final boolean isPositive = buttonJSON.optBoolean("positive", false);
config.setButton(buttonJSON.getString("label"), buttonJSON.getInt("callback"), isPositive);
}
return config;
}

View File

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false">
<shape>
<solid android:color="@color/toolbar_menu_dark_grey" />
</shape>
</item>
<item android:state_pressed="true">
<shape>
<solid android:color="@color/toolbar_grey_pressed" />
</shape>
</item>
</selector>

View File

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false">
<shape>
<solid android:color="@color/link_blue"/>
</shape>
</item>
<item android:state_pressed="true">
<shape>
<solid android:color="@color/link_blue_pressed" />
</shape>
</item>
</selector>

View File

@ -1,30 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView android:id="@+id/doorhanger_message"
android:focusable="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.DoorHanger.Medium"/>
<LinearLayout android:id="@+id/doorhanger_inputs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="@dimen/doorhanger_section_padding_small"
android:gravity="right"
android:visibility="gone"/>
<CheckBox android:id="@+id/doorhanger_checkbox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/doorhanger_section_padding_small"
android:checked="true"
android:textColor="@color/placeholder_active_grey"
android:visibility="gone"/>
</merge>

View File

@ -5,42 +5,52 @@
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout android:layout_width="match_parent"
<LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="@dimen/doorhanger_padding">
<ImageView android:id="@+id/doorhanger_icon"
android:layout_width="@dimen/doorhanger_icon_size"
android:layout_height="@dimen/doorhanger_icon_size"
android:layout_gravity="center_horizontal"
android:paddingRight="@dimen/doorhanger_section_padding_small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="@dimen/doorhanger_padding"
android:visibility="gone"/>
<ViewStub android:id="@+id/content"
<TextView android:id="@+id/doorhanger_message"
android:focusable="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button android:id="@+id/doorhanger_button_negative"
style="@style/Widget.Doorhanger.Button"
android:textColor="@android:color/black"
android:background="@drawable/action_bar_button_negative"
android:visibility="gone"/>
<Button android:id="@+id/doorhanger_button_positive"
style="@style/Widget.Doorhanger.Button"
android:textColor="@android:color/white"
android:background="@drawable/action_bar_button_positive"
android:visibility="gone"/>
android:textAppearance="@style/TextAppearance.DoorHanger.Medium"/>
</LinearLayout>
<LinearLayout android:id="@+id/doorhanger_inputs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="right"
android:paddingLeft="@dimen/doorhanger_padding"
android:visibility="gone"/>
<CheckBox android:id="@+id/doorhanger_checkbox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:checked="true"
android:textColor="@color/placeholder_active_grey"
android:visibility="gone"/>
<View android:id="@+id/divider_buttons"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/divider_light"
android:visibility="gone"/>
<LinearLayout android:id="@+id/doorhanger_buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="gone"/>
<View android:id="@+id/divider_doorhanger"
android:layout_width="match_parent"
android:layout_height="1dp"

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="48dip"
android:textColor="@color/placeholder_active_grey"
android:textSize="14sp"
android:background="@drawable/action_bar_button"/>

View File

@ -5,25 +5,64 @@
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView android:id="@+id/doorhanger_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/doorhanger_section_padding_small"
android:textAppearance="@style/TextAppearance.DoorHanger.Medium.Light"/>
<LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingTop="@dimen/doorhanger_section_padding_small"
android:paddingLeft="@dimen/doorhanger_section_padding_small">
<TextView android:id="@+id/doorhanger_message"
android:focusable="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/doorhanger_section_padding_large"
android:textAppearance="@style/TextAppearance.DoorHanger.Medium"/>
<ImageView android:id="@+id/doorhanger_icon"
android:layout_width="@dimen/doorhanger_icon_size"
android:layout_height="@dimen/doorhanger_icon_size"
android:layout_gravity="center_horizontal"
android:paddingRight="@dimen/doorhanger_section_padding_small"
android:src="@drawable/icon_key"/>
<TextView android:id="@+id/doorhanger_link"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.DoorHanger.Medium"
android:textColor="@color/link_blue"
android:layout_marginBottom="@dimen/doorhanger_section_padding_small"
android:visibility="gone"/>
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView android:id="@+id/doorhanger_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/doorhanger_section_padding_small"
android:textAppearance="@style/TextAppearance.DoorHanger.Medium.Light"/>
<TextView android:id="@+id/doorhanger_message"
android:focusable="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/doorhanger_section_padding_large"
android:textAppearance="@style/TextAppearance.DoorHanger.Medium"/>
<TextView android:id="@+id/doorhanger_link"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.DoorHanger.Medium"
android:textColor="@color/link_blue"
android:paddingBottom="@dimen/doorhanger_section_padding_large"
android:visibility="gone"/>
</LinearLayout>
</LinearLayout>
<View android:id="@+id/divider_buttons"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/divider_light"
android:visibility="gone"/>
<LinearLayout android:id="@+id/doorhanger_buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="gone"/>
<View android:id="@+id/divider_doorhanger"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/divider_light"
android:visibility="gone"/>
</merge>

View File

@ -25,6 +25,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/doorhanger_login_edit_toggle"
android:layout_marginTop="@dimen/doorhanger_padding"/>
android:paddingTop="@dimen/doorhanger_padding"/>
</LinearLayout>

View File

@ -48,7 +48,7 @@
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.DoorHanger.Medium.Light"
android:text="@string/identity_run_by"
android:layout_marginTop="@dimen/doorhanger_section_padding_small"/>
android:paddingTop="@dimen/doorhanger_section_padding_small"/>
<TextView android:id="@+id/owner"
android:layout_width="wrap_content"
@ -60,7 +60,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.DoorHanger.Medium.Light"
android:layout_marginTop="@dimen/doorhanger_section_padding_small"/>
android:paddingTop="@dimen/doorhanger_section_padding_small"/>
</LinearLayout>
<TextView android:id="@+id/site_settings_link"
@ -68,8 +68,8 @@
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.DoorHanger.Medium"
android:textColor="@color/link_blue"
android:layout_marginTop="@dimen/doorhanger_section_padding_large"
android:layout_marginBottom="@dimen/doorhanger_padding"
android:paddingTop="@dimen/doorhanger_section_padding_large"
android:paddingBottom="@dimen/doorhanger_padding"
android:text="@string/contextmenu_site_settings"/>
</LinearLayout>
</LinearLayout>

View File

@ -9,7 +9,6 @@
<color name="action_orange">#E66000</color>
<color name="action_orange_pressed">#DC5600</color>
<color name="link_blue">#0096DD</color>
<color name="link_blue_pressed">#0082C6</color>
<color name="private_browsing_purple">#CF68FF</color>
<color name="placeholder_active_grey">#222222</color>

View File

@ -281,14 +281,6 @@
<item name="android:textSize">18sp</item>
</style>
<style name="Widget.Doorhanger.Button" parent="Widget.BaseButton">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_weight">1</item>
<item name="android:minHeight">48dp</item>
<item name="android:textSize">14sp</item>
</style>
<!--
TextAppearance
Note: Gecko uses light theme as default, while Android uses dark.

View File

@ -202,8 +202,8 @@ public class SiteIdentityPopup extends AnchoredPopup implements GeckoEventListen
final DoorhangerConfig config = new DoorhangerConfig(DoorHanger.Type.LOGIN, buttonClickListener);
// Set buttons.
config.setButton(mContext.getString(R.string.button_cancel), ButtonType.CANCEL.ordinal(), false);
config.setButton(mContext.getString(R.string.button_copy), ButtonType.COPY.ordinal(), true);
config.appendButton(mContext.getString(R.string.button_cancel), ButtonType.CANCEL.ordinal());
config.appendButton(mContext.getString(R.string.button_copy), ButtonType.COPY.ordinal());
// Set message.
String username = ((JSONObject) logins.get(0)).getString("username");
@ -361,10 +361,10 @@ public class SiteIdentityPopup extends AnchoredPopup implements GeckoEventListen
private void addNotificationButtons(DoorhangerConfig config, boolean blocked) {
if (blocked) {
config.setButton(mContext.getString(R.string.disable_protection), ButtonType.DISABLE.ordinal(), false);
config.setButton(mContext.getString(R.string.keep_blocking), ButtonType.KEEP_BLOCKING.ordinal(), true);
config.appendButton(mContext.getString(R.string.disable_protection), ButtonType.DISABLE.ordinal());
config.appendButton(mContext.getString(R.string.keep_blocking), ButtonType.KEEP_BLOCKING.ordinal());
} else {
config.setButton(mContext.getString(R.string.enable_protection), ButtonType.ENABLE.ordinal(), true);
config.appendButton(mContext.getString(R.string.enable_protection), ButtonType.ENABLE.ordinal());
}
}

View File

@ -5,17 +5,9 @@
package org.mozilla.gecko.widget;
import android.text.Html;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.style.ForegroundColorSpan;
import android.text.style.URLSpan;
import android.util.Log;
import android.widget.Button;
import android.widget.TextView;
import org.mozilla.gecko.R;
import org.mozilla.gecko.Tabs;
import org.mozilla.gecko.prompts.PromptInput;
import org.json.JSONArray;
@ -37,15 +29,12 @@ public class DefaultDoorHanger extends DoorHanger {
private static int sSpinnerTextColor = -1;
private final TextView mMessage;
private List<PromptInput> mInputs;
private CheckBox mCheckBox;
public DefaultDoorHanger(Context context, DoorhangerConfig config, Type type) {
super(context, config, type);
mMessage = (TextView) findViewById(R.id.doorhanger_message);
if (sSpinnerTextColor == -1) {
sSpinnerTextColor = mResources.getColor(R.color.text_color_primary_disable_only);
}
@ -69,12 +58,7 @@ public class DefaultDoorHanger extends DoorHanger {
addLink(link.label, link.url, link.delimiter);
}
addButtonsToLayout(config);
}
@Override
protected int getContentResource() {
return R.layout.default_doorhanger;
setButtons(config);
}
private List<PromptInput> getInputs() {
@ -170,30 +154,6 @@ public class DefaultDoorHanger extends DoorHanger {
};
}
private void setMessage(String message) {
Spanned markupMessage = Html.fromHtml(message);
mMessage.setText(markupMessage);
}
private void addLink(String label, String url, String delimiter) {
String title = mMessage.getText().toString();
SpannableString titleWithLink = new SpannableString(title + delimiter + label);
URLSpan linkSpan = new URLSpan(url) {
@Override
public void onClick(View view) {
Tabs.getInstance().loadUrlInTab(getURL());
}
};
// Prevent text outside the link from flashing when clicked.
ForegroundColorSpan colorSpan = new ForegroundColorSpan(mMessage.getCurrentTextColor());
titleWithLink.setSpan(colorSpan, 0, title.length(), 0);
titleWithLink.setSpan(linkSpan, title.length() + 1, titleWithLink.length(), 0);
mMessage.setText(titleWithLink);
mMessage.setMovementMethod(LinkMovementMethod.getInstance());
}
private void styleInput(PromptInput input, View view) {
if (input instanceof PromptInput.MenulistInput) {
styleDropdownInputs(input, view);

View File

@ -7,14 +7,24 @@ package org.mozilla.gecko.widget;
import android.content.Context;
import android.content.res.Resources;
import android.text.Html;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.style.ForegroundColorSpan;
import android.text.style.URLSpan;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewStub;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.gecko.R;
import org.mozilla.gecko.Tabs;
public abstract class DoorHanger extends LinearLayout {
@ -36,13 +46,17 @@ public abstract class DoorHanger extends LinearLayout {
public void onButtonClick(JSONObject response, DoorHanger doorhanger);
}
protected static final LayoutParams sButtonParams;
static {
sButtonParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 1.0f);
}
private static final String LOGTAG = "GeckoDoorHanger";
// Divider between doorhangers.
private final View mDivider;
private final Button mNegativeButton;
private final Button mPositiveButton;
protected final LinearLayout mButtonsContainer;
protected final OnButtonClickListener mOnButtonClickListener;
// The tab this doorhanger is associated with.
@ -53,7 +67,8 @@ public abstract class DoorHanger extends LinearLayout {
protected final Type mType;
protected final ImageView mIcon;
private final ImageView mIcon;
private final TextView mMessage;
protected final Context mContext;
protected final Resources mResources;
@ -66,31 +81,34 @@ public abstract class DoorHanger extends LinearLayout {
protected DoorHanger(Context context, DoorhangerConfig config, Type type) {
super(context);
mContext = context;
mResources = context.getResources();
mTabId = config.getTabId();
mIdentifier = config.getId();
mType = type;
setOrientation(VERTICAL);
final ViewStub contentStub = (ViewStub) findViewById(R.id.content);
contentStub.setLayoutResource(getContentResource());
contentStub.inflate();
int resource;
switch (type) {
case LOGIN:
resource = R.layout.login_doorhanger;
break;
default:
resource = R.layout.doorhanger;
}
LayoutInflater.from(context).inflate(resource, this);
mDivider = findViewById(R.id.divider_doorhanger);
mIcon = (ImageView) findViewById(R.id.doorhanger_icon);
mMessage = (TextView) findViewById(R.id.doorhanger_message);
mNegativeButton = (Button) findViewById(R.id.doorhanger_button_negative);
mPositiveButton = (Button) findViewById(R.id.doorhanger_button_positive);
mType = type;
mButtonsContainer = (LinearLayout) findViewById(R.id.doorhanger_buttons);
mOnButtonClickListener = config.getButtonClickListener();
mDividerColor = mResources.getColor(R.color.divider_light);
setOrientation(VERTICAL);
}
protected abstract int getContentResource();
protected abstract void loadConfig(DoorhangerConfig config);
protected void setOptions(final JSONObject options) {
@ -107,20 +125,17 @@ public abstract class DoorHanger extends LinearLayout {
}
}
protected void addButtonsToLayout(DoorhangerConfig config) {
final DoorhangerConfig.ButtonConfig negativeButtonConfig = config.getNegativeButtonConfig();
final DoorhangerConfig.ButtonConfig positiveButtonConfig = config.getPositiveButtonConfig();
if (negativeButtonConfig != null) {
mNegativeButton.setText(negativeButtonConfig.label);
mNegativeButton.setOnClickListener(makeOnButtonClickListener(negativeButtonConfig.callback));
mNegativeButton.setVisibility(VISIBLE);
}
if (positiveButtonConfig != null) {
mPositiveButton.setText(positiveButtonConfig.label);
mPositiveButton.setOnClickListener(makeOnButtonClickListener(positiveButtonConfig.callback));
mPositiveButton.setVisibility(VISIBLE);
protected void setButtons(DoorhangerConfig config) {
final JSONArray buttons = config.getButtons();
for (int i = 0; i < buttons.length(); i++) {
try {
final JSONObject buttonObject = buttons.getJSONObject(i);
final String label = buttonObject.getString("label");
final int callbackId = buttonObject.getInt("callback");
addButtonToLayout(label, callbackId);
} catch (JSONException e) {
Log.e(LOGTAG, "Error creating doorhanger button", e);
}
}
}
@ -145,6 +160,61 @@ public abstract class DoorHanger extends LinearLayout {
mIcon.setVisibility(View.VISIBLE);
}
protected void setMessage(String message) {
Spanned markupMessage = Html.fromHtml(message);
mMessage.setText(markupMessage);
}
protected void addLink(String label, String url, String delimiter) {
String title = mMessage.getText().toString();
SpannableString titleWithLink = new SpannableString(title + delimiter + label);
URLSpan linkSpan = new URLSpan(url) {
@Override
public void onClick(View view) {
Tabs.getInstance().loadUrlInTab(getURL());
}
};
// Prevent text outside the link from flashing when clicked.
ForegroundColorSpan colorSpan = new ForegroundColorSpan(mMessage.getCurrentTextColor());
titleWithLink.setSpan(colorSpan, 0, title.length(), 0);
titleWithLink.setSpan(linkSpan, title.length() + 1, titleWithLink.length(), 0);
mMessage.setText(titleWithLink);
mMessage.setMovementMethod(LinkMovementMethod.getInstance());
}
/**
* Creates and adds a button into the DoorHanger.
* @param text Button text
* @param id Identifier associated with the button
*/
private void addButtonToLayout(String text, int id) {
final Button button = createButtonInstance(text, id);
if (mButtonsContainer.getChildCount() == 0) {
// If this is the first button we're adding, make the choices layout visible.
mButtonsContainer.setVisibility(View.VISIBLE);
// Make the divider above the buttons visible.
View divider = findViewById(R.id.divider_buttons);
divider.setVisibility(View.VISIBLE);
} else {
// Add a vertical divider between additional buttons.
Divider divider = new Divider(getContext(), null);
divider.setOrientation(Divider.Orientation.VERTICAL);
divider.setBackgroundColor(mDividerColor);
mButtonsContainer.addView(divider);
}
mButtonsContainer.addView(button, sButtonParams);
}
protected Button createButtonInstance(String text, int id) {
final Button button = (Button) LayoutInflater.from(getContext()).inflate(R.layout.doorhanger_button, null);
button.setText(text);
button.setOnClickListener(makeOnButtonClickListener(id));
return button;
}
protected abstract OnClickListener makeOnButtonClickListener(final int id);
/*

View File

@ -5,6 +5,9 @@
package org.mozilla.gecko.widget;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.gecko.widget.DoorHanger.Type;
@ -23,15 +26,6 @@ public class DoorhangerConfig {
}
}
public static class ButtonConfig {
public final String label;
public final int callback;
public ButtonConfig(String label, int callback) {
this.label = label;
this.callback = callback;
}
}
private static final String LOGTAG = "DoorhangerConfig";
private final int tabId;
@ -41,8 +35,7 @@ public class DoorhangerConfig {
private String message;
private JSONObject options;
private Link link;
private ButtonConfig positiveButtonConfig;
private ButtonConfig negativeButtonConfig;
private JSONArray buttons = new JSONArray();
public DoorhangerConfig(Type type, DoorHanger.OnButtonClickListener listener) {
// XXX: This should only be used by SiteIdentityPopup doorhangers which
@ -86,27 +79,39 @@ public class DoorhangerConfig {
return options;
}
public void setButton(String label, int callbackId, boolean isPositive) {
final ButtonConfig buttonConfig = new ButtonConfig(label, callbackId);
if (isPositive) {
positiveButtonConfig = buttonConfig;
} else {
negativeButtonConfig = buttonConfig;
/**
* Add buttons from JSON to the Config object.
* @param buttons JSONArray of JSONObjects of the form { label: <label>, callback: <callback_id> }
*/
public void appendButtonsFromJSON(JSONArray buttons) {
try {
for (int i = 0; i < buttons.length(); i++) {
this.buttons.put(buttons.get(i));
}
} catch (JSONException e) {
Log.e(LOGTAG, "Error parsing buttons from JSON", e);
}
}
public ButtonConfig getPositiveButtonConfig() {
return positiveButtonConfig;
}
public ButtonConfig getNegativeButtonConfig() {
return negativeButtonConfig;
public void appendButton(String label, int callbackId) {
final JSONObject button = new JSONObject();
try {
button.put("label", label);
button.put("callback", callbackId);
this.buttons.put(button);
} catch (JSONException e) {
Log.e(LOGTAG, "Error creating button", e);
}
}
public DoorHanger.OnButtonClickListener getButtonClickListener() {
return this.buttonClickListener;
}
public JSONArray getButtons() {
return buttons;
}
public void setLink(String label, String url, String delimiter) {
this.link = new Link(label, url, delimiter);
}

View File

@ -7,12 +7,12 @@ package org.mozilla.gecko.widget;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.text.Html;
import android.text.Spanned;
import android.text.method.PasswordTransformationMethod;
import android.util.Log;
import android.view.LayoutInflater;
@ -27,6 +27,7 @@ import ch.boye.httpclientandroidlib.util.TextUtils;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONArray;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.R;
import org.mozilla.gecko.favicons.Favicons;
import org.mozilla.gecko.favicons.OnFaviconLoadedListener;
@ -37,7 +38,6 @@ public class LoginDoorHanger extends DoorHanger {
private enum ActionType { EDIT, SELECT }
private final TextView mTitle;
private final TextView mMessage;
private final TextView mLink;
private int mCallbackID;
@ -45,31 +45,16 @@ public class LoginDoorHanger extends DoorHanger {
super(context, config, Type.LOGIN);
mTitle = (TextView) findViewById(R.id.doorhanger_title);
mMessage = (TextView) findViewById(R.id.doorhanger_message);
mLink = (TextView) findViewById(R.id.doorhanger_link);
mIcon.setImageResource(R.drawable.icon_key);
mIcon.setVisibility(View.VISIBLE);
loadConfig(config);
}
private void setMessage(String message) {
Spanned markupMessage = Html.fromHtml(message);
mMessage.setText(markupMessage);
}
@Override
protected void loadConfig(DoorhangerConfig config) {
setOptions(config.getOptions());
setMessage(config.getMessage());
// Store the positive callback id for nested dialogs that need the same callback id.
mCallbackID = config.getPositiveButtonConfig().callback;
addButtonsToLayout(config);
}
@Override
protected int getContentResource() {
return R.layout.login_doorhanger;
setButtons(config);
}
@Override
@ -104,6 +89,13 @@ public class LoginDoorHanger extends DoorHanger {
addActionText(actionText);
}
@Override
protected Button createButtonInstance(final String text, final int id) {
// HACK: Confirm button will the the rightmost/last button added. Bug 1147064 should add differentiation of the two.
mCallbackID = id;
return super.createButtonInstance(text, id);
}
@Override
protected OnClickListener makeOnButtonClickListener(final int id) {
return new Button.OnClickListener() {
@ -215,7 +207,7 @@ public class LoginDoorHanger extends DoorHanger {
public void onClick(DialogInterface dialog, int which) {
final JSONObject response = new JSONObject();
try {
response.put("callback", mCallbackID);
response.put("callback", SiteIdentityPopup.ButtonType.COPY.ordinal());
response.put("password", passwords[which]);
} catch (JSONException e) {
Log.e(LOGTAG, "Error making login select dialog JSON", e);

View File

@ -29,18 +29,17 @@ var OfflineApps = {
let strings = Strings.browser;
let buttons = [{
label: strings.GetStringFromName("offlineApps.allow"),
callback: function() {
OfflineApps.allowSite(aContentWindow.document);
}
},
{
label: strings.GetStringFromName("offlineApps.dontAllow2"),
callback: function(aChecked) {
if (aChecked)
OfflineApps.disallowSite(aContentWindow.document);
}
},
{
label: strings.GetStringFromName("offlineApps.allow"),
callback: function() {
OfflineApps.allowSite(aContentWindow.document);
},
positive: true
}];
let requestor = BrowserApp.manifest ? "'" + BrowserApp.manifest.name + "'" : host;

View File

@ -27,6 +27,16 @@ var PluginHelper = {
let message = Strings.browser.formatStringFromName("clickToPlayPlugins.message2",
[uri.host], 1);
let buttons = [
{
label: Strings.browser.GetStringFromName("clickToPlayPlugins.activate"),
callback: function(aChecked) {
// If the user checked "Don't ask again", make a permanent exception
if (aChecked)
Services.perms.add(uri, "plugins", Ci.nsIPermissionManager.ALLOW_ACTION);
PluginHelper.playAllPlugins(aTab.browser.contentWindow);
}
},
{
label: Strings.browser.GetStringFromName("clickToPlayPlugins.dontActivate"),
callback: function(aChecked) {
@ -36,17 +46,6 @@ var PluginHelper = {
// Other than that, do nothing
}
},
{
label: Strings.browser.GetStringFromName("clickToPlayPlugins.activate"),
callback: function(aChecked) {
// If the user checked "Don't ask again", make a permanent exception
if (aChecked)
Services.perms.add(uri, "plugins", Ci.nsIPermissionManager.ALLOW_ACTION);
PluginHelper.playAllPlugins(aTab.browser.contentWindow);
},
positive: true
}
];

View File

@ -113,8 +113,7 @@ var WebrtcUI = {
allowedDevices.AppendElement(videoDevices[videoId]);
Services.obs.notifyObservers(allowedDevices, "getUserMedia:response:allow", aCallID);
},
positive: true
}
}];
},

View File

@ -3064,8 +3064,7 @@ var LightWeightThemeWebInstaller = {
label: allowButtonText,
callback: function () {
LightWeightThemeWebInstaller._install(data);
},
positive: true
}
}];
NativeWindow.doorhanger.show(message, "Personas", buttons, BrowserApp.selectedTab.id);
@ -6260,8 +6259,7 @@ var XPInstallObserver = {
// Kick off the install
installInfo.install();
return false;
},
positive: true
}
}];
}
NativeWindow.doorhanger.show(message, aTopic, buttons, tab.id);
@ -6355,8 +6353,7 @@ var XPInstallObserver = {
let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup);
appStartup.quit(Ci.nsIAppStartup.eRestart | Ci.nsIAppStartup.eAttemptQuit);
}
},
positive: true
}
}];
let message = Strings.browser.GetStringFromName("notificationRestart.normal");
@ -6651,13 +6648,6 @@ var PopupBlockerObserver = {
.replace("#2", popupCount);
let buttons = [
{
label: strings.GetStringFromName("popup.dontShow"),
callback: function(aChecked) {
if (aChecked)
PopupBlockerObserver.allowPopupsForSite(false);
}
},
{
label: strings.GetStringFromName("popup.show"),
callback: function(aChecked) {
@ -6666,8 +6656,14 @@ var PopupBlockerObserver = {
PopupBlockerObserver.allowPopupsForSite(true);
PopupBlockerObserver.showPopupsForSite();
},
positive: true
}
},
{
label: strings.GetStringFromName("popup.dontShow"),
callback: function(aChecked) {
if (aChecked)
PopupBlockerObserver.allowPopupsForSite(false);
}
}
];
@ -6769,7 +6765,13 @@ var IndexedDB = {
observer.observe(null, responseTopic, Ci.nsIPermissionManager.UNKNOWN_ACTION);
}
let buttons = [
let buttons = [{
label: strings.GetStringFromName("offlineApps.allow"),
callback: function() {
clearTimeout(timeoutId);
observer.observe(null, responseTopic, Ci.nsIPermissionManager.ALLOW_ACTION);
}
},
{
label: strings.GetStringFromName("offlineApps.dontAllow2"),
callback: function(aChecked) {
@ -6777,14 +6779,6 @@ var IndexedDB = {
let action = aChecked ? Ci.nsIPermissionManager.DENY_ACTION : Ci.nsIPermissionManager.UNKNOWN_ACTION;
observer.observe(null, responseTopic, action);
}
},
{
label: strings.GetStringFromName("offlineApps.allow"),
callback: function() {
clearTimeout(timeoutId);
observer.observe(null, responseTopic, Ci.nsIPermissionManager.ALLOW_ACTION);
},
positive: true
}];
let options = { checkbox: Strings.browser.GetStringFromName("offlineApps.dontAskAgain") };

View File

@ -99,16 +99,6 @@ ContentPermissionPrompt.prototype = {
let entityName = kEntities[perm.type];
let buttons = [{
label: browserBundle.GetStringFromName(entityName + ".dontAllow"),
callback: function(aChecked) {
// If the user checked "Don't ask again", make a permanent exception
if (aChecked)
Services.perms.addFromPrincipal(request.principal, access, Ci.nsIPermissionManager.DENY_ACTION);
request.cancel();
}
},
{
label: browserBundle.GetStringFromName(entityName + ".allow"),
callback: function(aChecked) {
// If the user checked "Don't ask again", make a permanent exception
@ -120,8 +110,17 @@ ContentPermissionPrompt.prototype = {
}
request.allow();
},
positive: true
}
},
{
label: browserBundle.GetStringFromName(entityName + ".dontAllow"),
callback: function(aChecked) {
// If the user checked "Don't ask again", make a permanent exception
if (aChecked)
Services.perms.addFromPrincipal(request.principal, access, Ci.nsIPermissionManager.DENY_ACTION);
request.cancel();
}
}];
let requestor = chromeWin.BrowserApp.manifest ? "'" + chromeWin.BrowserApp.manifest.name + "'" : request.principal.URI.host;

View File

@ -225,8 +225,7 @@ LoginManagerPrompter.prototype = {
}
pwmgr.addLogin(aLogin);
promptHistogram.add(PROMPT_ADD);
},
positive: true
}
}
];
@ -283,8 +282,7 @@ LoginManagerPrompter.prototype = {
callback: function() {
self._updateLogin(aOldLogin, aNewPassword);
promptHistogram.add(PROMPT_UPDATE);
},
positive: true
}
}
];