mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
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:
parent
14435bd19d
commit
f7ea504b6d
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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"
|
||||
|
12
mobile/android/base/resources/layout/doorhanger_button.xml
Normal file
12
mobile/android/base/resources/layout/doorhanger_button.xml
Normal 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"/>
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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.
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -113,8 +113,7 @@ var WebrtcUI = {
|
||||
allowedDevices.AppendElement(videoDevices[videoId]);
|
||||
|
||||
Services.obs.notifyObservers(allowedDevices, "getUserMedia:response:allow", aCallID);
|
||||
},
|
||||
positive: true
|
||||
}
|
||||
}];
|
||||
},
|
||||
|
||||
|
@ -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") };
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user